Add contest director and school responsible

This commit is contained in:
Andrea Fazzi 2020-01-20 12:07:02 +01:00
parent d1a7d1a0db
commit 420eae4cf4
11 changed files with 680 additions and 886 deletions

View file

@ -8,15 +8,13 @@ import (
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"net/url" "net/url"
"reflect"
"strconv"
"strings"
"git.andreafazzi.eu/andrea/oef/i18n" "strconv"
"git.andreafazzi.eu/andrea/oef/orm" "git.andreafazzi.eu/andrea/oef/orm"
"git.andreafazzi.eu/andrea/oef/reflect"
"git.andreafazzi.eu/andrea/oef/renderer" "git.andreafazzi.eu/andrea/oef/renderer"
"github.com/jinzhu/gorm" "github.com/jinzhu/gorm"
"github.com/jinzhu/inflection"
) )
// A client represents a client connection to the Headmaster test // A client represents a client connection to the Headmaster test
@ -99,7 +97,7 @@ func (c *Client) SendRequest(method string, path string, data []byte) ([]byte, e
func (c *Client) ReadAll(model interface{}) error { func (c *Client) ReadAll(model interface{}) error {
var response renderer.JsonResponse var response renderer.JsonResponse
data, err := c.SendRequest("GET", fmt.Sprintf("/api/%s?format=json", pluralizedModelName(model)), nil) data, err := c.SendRequest("GET", fmt.Sprintf("/api/%s?format=json", reflect.ModelNameLowerPlural(model)), nil)
if err != nil { if err != nil {
return err return err
} }
@ -121,7 +119,7 @@ func (c *Client) ReadAll(model interface{}) error {
func (c *Client) Read(model orm.IDer) (interface{}, error) { func (c *Client) Read(model orm.IDer) (interface{}, error) {
var response renderer.JsonResponse var response renderer.JsonResponse
data, err := c.SendRequest("GET", fmt.Sprintf("/api/%s/%d?format=json", pluralizedModelName(model), model.GetID()), nil) data, err := c.SendRequest("GET", fmt.Sprintf("/api/%s/%d?format=json", reflect.ModelNameLowerPlural(model), model.GetID()), nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -147,7 +145,7 @@ func (c *Client) Create(model interface{}) (uint, error) {
return 0, err return 0, err
} }
resp, err := c.SendRequest("POST", fmt.Sprintf("/api/%s/create/?format=json", pluralizedModelName(model)), data) resp, err := c.SendRequest("POST", fmt.Sprintf("/api/%s/create/?format=json", reflect.ModelNameLowerPlural(model)), data)
if err != nil { if err != nil {
return 0, err return 0, err
} }
@ -175,7 +173,7 @@ func (c *Client) Delete(model orm.IDer) (uint, error) {
return 0, err return 0, err
} }
resp, err := c.SendRequest("DELETE", fmt.Sprintf("/api/%s/%d/delete?format=json", pluralizedModelName(model), model.GetID()), data) resp, err := c.SendRequest("DELETE", fmt.Sprintf("/api/%s/%d/delete?format=json", reflect.ModelNameLowerPlural(model), model.GetID()), data)
if err != nil { if err != nil {
return 0, err return 0, err
} }
@ -196,61 +194,61 @@ func (c *Client) Delete(model orm.IDer) (uint, error) {
return uint(id), nil return uint(id), nil
} }
func (c *Client) DeleteAllFunc(model interface{}, testFn func(interface{}) bool) error { // func (c *Client) DeleteAllFunc(model interface{}, testFn func(interface{}) bool) error {
err := c.ReadAll(model) // err := c.ReadAll(model)
if err != nil { // if err != nil {
return err // return err
} // }
switch reflect.TypeOf(model).Kind() { // switch reflect.TypeOf(model).Kind() {
case reflect.Ptr: // case reflect.Ptr:
s := reflect.ValueOf(model).Elem() // s := reflect.ValueOf(model).Elem()
// FIXME: Check whatever s is a slice before cycling through it! // // FIXME: Check whatever s is a slice before cycling through it!
for i := 0; i < s.Len(); i++ { // for i := 0; i < s.Len(); i++ {
// if callString(s.Index(i).Interface()) == name { // // if callString(s.Index(i).Interface()) == name {
// _, err := c.Delete(s.Index(i).Interface().(orm.IDer)) // // _, err := c.Delete(s.Index(i).Interface().(orm.IDer))
// if err != nil { // // if err != nil {
// return err // // return err
// } // // }
// } // // }
if testFn(s.Index(i).Interface()) { // if testFn(s.Index(i).Interface()) {
_, err := c.Delete(s.Index(i).Interface().(orm.IDer)) // _, err := c.Delete(s.Index(i).Interface().(orm.IDer))
if err != nil { // if err != nil {
return err // return err
} // }
} // }
} // }
} // }
return nil // return nil
} // }
func (c *Client) Exists(model orm.IDer) bool { func (c *Client) Exists(model orm.IDer) bool {
_, err := c.Read(model) _, err := c.Read(model)
return err != gorm.ErrRecordNotFound return err != gorm.ErrRecordNotFound
} }
// FIXME: refactor this (it's duplicated across the code) // // FIXME: refactor this (it's duplicated across the code)
func pluralizedModelName(value interface{}) string { // func pluralizedModelName(value interface{}) string {
return inflection.Plural(strings.ToLower(orm.ModelName(value))) // return inflection.Plural(strings.ToLower(reflect.ModelName(value)))
} // }
// FIXME: refactor this (it's duplicated across the code) // // FIXME: refactor this (it's duplicated across the code)
func callString(value interface{}) string { // func callString(value interface{}) string {
if value != nil { // if value != nil {
switch reflect.ValueOf(value).Kind() { // switch reflect.ValueOf(value).Kind() {
case reflect.String: // case reflect.String:
return value.(string) // return value.(string)
case reflect.Bool: // case reflect.Bool:
if value.(bool) { // if value.(bool) {
return i18n.Text["answerCorrect"]["it"] // return i18n.Text["answerCorrect"]["it"]
} // }
return "false" // return "false"
default: // default:
return reflect.ValueOf(value).MethodByName("String").Interface().(func() string)() // return reflect.ValueOf(value).MethodByName("String").Interface().(func() string)()
} // }
} else { // } else {
return "" // return ""
} // }
} // }

View file

@ -1,311 +0,0 @@
-- MariaDB dump 10.17 Distrib 10.4.8-MariaDB, for debian-linux-gnu (x86_64)
--
-- Host: localhost Database: oef_test
-- ------------------------------------------------------
-- Server version 10.4.8-MariaDB-1:10.4.8+maria~bionic
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Table structure for table `answers`
--
DROP TABLE IF EXISTS `answers`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `answers` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
`deleted_at` timestamp NULL DEFAULT NULL,
`text` varchar(255) DEFAULT NULL,
`correct` tinyint(1) DEFAULT NULL,
`question_id` int(10) unsigned DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_answers_deleted_at` (`deleted_at`)
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `answers`
--
LOCK TABLES `answers` WRITE;
/*!40000 ALTER TABLE `answers` DISABLE KEYS */;
INSERT INTO `answers` VALUES (1,'2019-11-13 15:44:39','2019-11-13 15:44:39',NULL,'la quantità di moneta che viene richiesta dalle imprese sotto forma di prestiti richiesti al sistema bancario',0,1),(2,'2019-11-14 11:48:06','2019-11-14 11:48:06',NULL,'la quantità di moneta richiesta dalla Banca Centrale quando mette in vendita dei titoli per ridurre la moneta in circolazione',0,1),(3,'2019-11-14 11:48:28','2019-11-14 11:48:28',NULL,'la quantità di moneta richiesta dalle famiglie per mantenere in forma liquida i loro risparmi',0,1),(4,'2019-11-14 11:49:05','2019-11-14 12:21:09',NULL,'la quantità di moneta richiesta dai soggetti del sistema economico per transazioni, per ragioni speculative o prudenziali o per altri motivi',1,1),(5,'2019-11-15 10:17:49','2019-11-15 10:17:49',NULL,'elevata differenziazione dei prodotti offerti',0,2),(6,'2019-11-15 10:18:14','2019-11-15 10:18:53',NULL,'trasparenza delle informazioni',1,2),(7,'2019-11-15 10:18:29','2019-11-15 10:18:29',NULL,'presenza di un solo consumatore',0,2),(8,'2019-11-15 10:18:44','2019-11-15 10:18:44',NULL,'presenza di un numero limitato di grandi produttori',0,2),(9,'2019-11-15 10:23:11','2019-11-15 10:23:11',NULL,'un ciclo economico',0,3),(10,'2019-11-15 10:23:24','2019-11-15 10:23:35',NULL,'l\'attività di trasformazione materiale di beni e servizi (input) in altri (output) al fine di accrescerne l\'utilità',1,3),(11,'2019-11-15 10:23:47','2019-11-15 10:23:47',NULL,'l\'insieme dei beni di produzione',0,3),(12,'2019-11-15 10:23:59','2019-11-15 10:23:59',NULL,'il risultato del lavoro dei dipendenti dell\'impresa',0,3);
/*!40000 ALTER TABLE `answers` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `categories`
--
DROP TABLE IF EXISTS `categories`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `categories` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
`deleted_at` timestamp NULL DEFAULT NULL,
`name` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_categories_deleted_at` (`deleted_at`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `categories`
--
LOCK TABLES `categories` WRITE;
/*!40000 ALTER TABLE `categories` DISABLE KEYS */;
INSERT INTO `categories` VALUES (1,'2019-12-09 08:28:52','2019-12-09 08:28:52',NULL,'Junior'),(2,'2019-12-09 08:28:52','2019-12-09 08:28:52',NULL,'Senior');
/*!40000 ALTER TABLE `categories` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `contests`
--
DROP TABLE IF EXISTS `contests`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `contests` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
`deleted_at` timestamp NULL DEFAULT NULL,
`name` varchar(255) DEFAULT NULL,
`category` varchar(255) DEFAULT NULL,
`start_date` timestamp NULL DEFAULT NULL,
`end_date` timestamp NULL DEFAULT NULL,
`start_time` timestamp NULL DEFAULT NULL,
`end_time` timestamp NULL DEFAULT NULL,
`date` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_contests_deleted_at` (`deleted_at`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `contests`
--
LOCK TABLES `contests` WRITE;
/*!40000 ALTER TABLE `contests` DISABLE KEYS */;
INSERT INTO `contests` VALUES (1,'2019-11-14 10:02:17','2019-12-07 11:35:55',NULL,'Regionale JUNIOR','','0000-00-00 00:00:00','0000-00-00 00:00:00','2020-04-01 10:00:00','2020-04-01 11:00:00','2020-04-01 10:00:00'),(2,'2019-11-15 10:15:57','2019-12-07 11:26:48',NULL,'Test Diagnostico','',NULL,NULL,'2019-11-15 13:00:00','2019-11-15 14:00:00','2019-11-15 13:00:00');
/*!40000 ALTER TABLE `contests` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `participants`
--
DROP TABLE IF EXISTS `participants`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `participants` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
`deleted_at` timestamp NULL DEFAULT NULL,
`firstname` varchar(255) DEFAULT NULL,
`lastname` varchar(255) DEFAULT NULL,
`username` varchar(255) DEFAULT NULL,
`password` varchar(255) DEFAULT NULL,
`role` varchar(255) DEFAULT NULL,
`user_id` int(10) unsigned DEFAULT NULL,
`fiscal_code` varchar(255) DEFAULT NULL,
`school_id` int(10) unsigned DEFAULT NULL,
`creator_id` varchar(255) DEFAULT NULL,
`creator_role` varchar(255) DEFAULT NULL,
`creator_ip` varchar(255) DEFAULT NULL,
`updater_id` varchar(255) DEFAULT NULL,
`updater_role` varchar(255) DEFAULT NULL,
`updater_ip` varchar(255) DEFAULT NULL,
`category_id` int(10) unsigned DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_participants_deleted_at` (`deleted_at`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `participants`
--
LOCK TABLES `participants` WRITE;
/*!40000 ALTER TABLE `participants` DISABLE KEYS */;
INSERT INTO `participants` VALUES (1,'2019-12-09 08:36:28','2019-12-09 08:36:28',NULL,'Mario','ROSSI',NULL,NULL,NULL,2,'RSSMRA80A01E815L',1,'1','school','127.0.0.1:37620','','','',1),(2,'2019-12-09 08:37:55','2019-12-09 08:37:55',NULL,'Margherita','BIANCHI',NULL,NULL,NULL,3,'BNCMGH03A41D643M',1,'1','school','127.0.0.1:37686','','','',2);
/*!40000 ALTER TABLE `participants` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `questions`
--
DROP TABLE IF EXISTS `questions`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `questions` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
`deleted_at` timestamp NULL DEFAULT NULL,
`text` varchar(255) DEFAULT NULL,
`contest_id` int(10) unsigned DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_questions_deleted_at` (`deleted_at`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `questions`
--
LOCK TABLES `questions` WRITE;
/*!40000 ALTER TABLE `questions` DISABLE KEYS */;
INSERT INTO `questions` VALUES (1,'2019-11-13 14:45:17','2019-11-14 12:21:09',NULL,'Cosa si intende per domanda di moneta?',1),(2,'2019-11-15 10:17:24','2019-11-15 10:18:53',NULL,'È una caratteristica della concorrenza perfetta',2),(3,'2019-11-15 10:21:14','2019-11-15 10:23:35',NULL,'La produzione è',2);
/*!40000 ALTER TABLE `questions` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `responses`
--
DROP TABLE IF EXISTS `responses`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `responses` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
`deleted_at` timestamp NULL DEFAULT NULL,
`name` varchar(255) DEFAULT NULL,
`participant_id` int(10) unsigned DEFAULT NULL,
`contest_id` int(10) unsigned DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_responses_deleted_at` (`deleted_at`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `responses`
--
LOCK TABLES `responses` WRITE;
/*!40000 ALTER TABLE `responses` DISABLE KEYS */;
/*!40000 ALTER TABLE `responses` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `schools`
--
DROP TABLE IF EXISTS `schools`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `schools` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
`deleted_at` timestamp NULL DEFAULT NULL,
`name` varchar(255) DEFAULT NULL,
`email` varchar(255) DEFAULT NULL,
`code` varchar(255) DEFAULT NULL,
`user_id` int(10) unsigned DEFAULT NULL,
`email_sent_date` timestamp NULL DEFAULT NULL,
`ip_address` varchar(255) DEFAULT NULL,
`creator_id` varchar(255) DEFAULT NULL,
`creator_role` varchar(255) DEFAULT NULL,
`creator_ip` varchar(255) DEFAULT NULL,
`updater_id` varchar(255) DEFAULT NULL,
`updater_role` varchar(255) DEFAULT NULL,
`updater_ip` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_schools_deleted_at` (`deleted_at`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `schools`
--
LOCK TABLES `schools` WRITE;
/*!40000 ALTER TABLE `schools` DISABLE KEYS */;
INSERT INTO `schools` VALUES (1,'2019-12-09 08:33:57','2019-12-09 08:33:57',NULL,'IIS \"Paolo Frisi\"','foo@foo.org','MIIS058007',1,'2019-12-09 08:33:57',NULL,'0','subscriber','127.0.0.1:37464','','','');
/*!40000 ALTER TABLE `schools` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `subscriptions`
--
DROP TABLE IF EXISTS `subscriptions`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `subscriptions` (
`participant_id` int(10) unsigned NOT NULL,
`contest_id` int(10) unsigned NOT NULL,
PRIMARY KEY (`participant_id`,`contest_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `subscriptions`
--
LOCK TABLES `subscriptions` WRITE;
/*!40000 ALTER TABLE `subscriptions` DISABLE KEYS */;
/*!40000 ALTER TABLE `subscriptions` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `users`
--
DROP TABLE IF EXISTS `users`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `users` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
`deleted_at` timestamp NULL DEFAULT NULL,
`username` varchar(255) DEFAULT NULL,
`password` varchar(255) DEFAULT NULL,
`role` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_users_deleted_at` (`deleted_at`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `users`
--
LOCK TABLES `users` WRITE;
/*!40000 ALTER TABLE `users` DISABLE KEYS */;
INSERT INTO `users` VALUES (1,'2019-12-09 08:33:57','2019-12-09 08:33:57',NULL,'MIIS058007','A8MNE1Vz','school'),(2,'2019-12-09 08:36:28','2019-12-09 08:36:28',NULL,'RSSMRA80A01E815L','9HGqL2Yr','participant'),(3,'2019-12-09 08:37:55','2019-12-09 08:37:55',NULL,'BNCMGH03A41D643M','c43VNIxp','participant');
/*!40000 ALTER TABLE `users` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2019-12-09 8:44:29

View file

@ -142,6 +142,10 @@ func (c *ConfigT) CreatePath(model interface{}, path, format string) string {
return path + "?" + c.query(model, CreateLabel, format).Encode() return path + "?" + c.query(model, CreateLabel, format).Encode()
} }
func (c *ConfigT) CreatePattern() PathPattern {
return c.Handlers.PathPatterns[actions[CreateLabel]]
}
func (c *ConfigT) ReadAllPattern() PathPattern { func (c *ConfigT) ReadAllPattern() PathPattern {
return c.Handlers.PathPatterns[actions[ReadAllLabel]] return c.Handlers.PathPatterns[actions[ReadAllLabel]]
} }

View file

@ -13,7 +13,12 @@ services:
- ./sql:/docker-entrypoint-initdb.d - ./sql:/docker-entrypoint-initdb.d
env_file: env_file:
- db.env - db.env
smtp:
image: digiplant/fake-smtp
ports:
- "1025:25"
volumes: volumes:
db: db:

View file

@ -6,6 +6,7 @@ import (
"io/ioutil" "io/ioutil"
"log" "log"
"net/http" "net/http"
"net/url"
"path/filepath" "path/filepath"
"runtime/debug" "runtime/debug"
"strconv" "strconv"
@ -142,7 +143,7 @@ func NewHandlers(config *config.ConfigT, renderer map[string]renderer.Renderer,
handlers.JWTHeaderMiddleware = jwtmiddleware.New(jwtmiddleware.Options{ handlers.JWTHeaderMiddleware = jwtmiddleware.New(jwtmiddleware.Options{
ValidationKeyGetter: func(token *jwt.Token) (interface{}, error) { ValidationKeyGetter: func(token *jwt.Token) (interface{}, error) {
return config.Keys.JWTSigningKey, nil return []byte(config.Keys.JWTSigningKey), nil
}, },
SigningMethod: jwt.SigningMethodHS256, SigningMethod: jwt.SigningMethodHS256,
}) })
@ -191,7 +192,7 @@ func (h *Handlers) NewReadRequest(model interface{}, path string, format string)
return http.NewRequest("GET", h.Config.ReadPath(model, path, format), nil) return http.NewRequest("GET", h.Config.ReadPath(model, path, format), nil)
} }
func (h *Handlers) NewCreateRequest(model interface{}, path string, format string, method string) (*http.Request, error) { func (h *Handlers) NewCreateRequest(model interface{}, path string, format string, method string, form url.Values) (*http.Request, error) {
var ( var (
request *http.Request request *http.Request
err error err error
@ -200,7 +201,7 @@ func (h *Handlers) NewCreateRequest(model interface{}, path string, format strin
case "GET": case "GET":
request, err = http.NewRequest("GET", h.Config.CreatePath(model, path, format), nil) request, err = http.NewRequest("GET", h.Config.CreatePath(model, path, format), nil)
case "POST": case "POST":
request, err = http.NewRequest("POST", h.Config.CreatePath(model, path, format), nil) request, err = http.NewRequest("POST", h.Config.CreatePath(model, path, format), strings.NewReader(form.Encode()))
} }
return request, err return request, err
} }
@ -366,6 +367,14 @@ func respondWithError(h *Handlers, w http.ResponseWriter, r *http.Request, err e
h.Renderer[respFormat].Render(w, r, h.CookieStore, err) h.Renderer[respFormat].Render(w, r, h.CookieStore, err)
} }
func (h *Handlers) Create(model interface{}) http.Handler {
fn := func(w http.ResponseWriter, r *http.Request) {
h.post(w, r, reflect.ModelNameLowerPlural(model), h.Config.CreatePattern())
}
return http.HandlerFunc(fn)
}
func (h *Handlers) ReadAll(model interface{}) http.Handler { func (h *Handlers) ReadAll(model interface{}) http.Handler {
fn := func(w http.ResponseWriter, r *http.Request) { fn := func(w http.ResponseWriter, r *http.Request) {
h.get(w, r, reflect.ModelNameLowerPlural(model), h.Config.ReadAllPattern()) h.get(w, r, reflect.ModelNameLowerPlural(model), h.Config.ReadAllPattern())

View file

@ -6,6 +6,7 @@ import (
"log" "log"
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
"net/url"
"strings" "strings"
"testing" "testing"
"time" "time"
@ -31,7 +32,6 @@ type testSuite struct {
} }
func login(request *http.Request, handlers *Handlers, username string, password string) (*http.Request, error) { func login(request *http.Request, handlers *Handlers, username string, password string) (*http.Request, error) {
tokenString := requestToken(handlers, username, password) tokenString := requestToken(handlers, username, password)
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) { token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
return []byte(handlers.Config.Keys.JWTSigningKey), nil return []byte(handlers.Config.Keys.JWTSigningKey), nil
@ -213,28 +213,79 @@ func (t *testSuite) TestReadContest() {
} }
func (t *testSuite) TestCreateSchoolAsSubscriber() { func (t *testSuite) TestGetSchoolSubscription() {
req, err := handlers.NewCreateRequest(&orm.School{}, "/create/", "html", "GET") req, err := handlers.NewCreateRequest(&orm.School{}, "/create/", "html", "GET", nil)
t.Nil(err) t.Nil(err)
req, err = login(req, handlers, "admin", "admin") req, err = login(req, handlers, "subscriber", "subscribe")
t.Nil(err)
rr := httptest.NewRecorder()
handlers.Read(&orm.School{}).ServeHTTP(rr, req)
t.Equal(http.StatusOK, rr.Code)
doc, err := goquery.NewDocumentFromReader(rr.Body)
if err != nil {
log.Fatal(err)
}
expected := []string{
"Denominazione dell'istituto",
"Codice meccanografico",
"Indirizzo dell'istituto",
"Regione",
"Cognome referente di sede",
"Nome referente di sede",
"Cognome responsabile di gara",
"Nome responsabile di gara",
"Cognome referente di sede",
"Nome referente di sede",
"Indirizzo email",
}
ok := true
doc.Find(".control-label").Each(func(i int, s *goquery.Selection) {
t.Equal(expected[i], s.Text())
if t.Failed() {
ok = false
}
})
t.True(ok)
}
func (t *testSuite) TestPostCreateSchoolFormAsSubscriber() {
form := url.Values{}
form.Add("Name", "FooSchool")
form.Add("Code", "123")
form.Add("Email", "foo@school.org")
req, err := handlers.NewCreateRequest(&orm.School{}, "/create/", "html", "POST", form)
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
t.Nil(err)
req, err = login(req, handlers, "subscriber", "subscribe")
t.Nil(err) t.Nil(err)
if !t.Failed() { if !t.Failed() {
rr := httptest.NewRecorder() rr := httptest.NewRecorder()
handlers.Read(&orm.Contest{}).ServeHTTP(rr, req) handlers.Create(&orm.School{}).ServeHTTP(rr, req)
t.Equal(http.StatusOK, rr.Code) t.Equal(http.StatusSeeOther, rr.Code)
if !t.Failed() { if !t.Failed() {
doc, err := goquery.NewDocumentFromReader(rr.Body) doc, err := goquery.NewDocumentFromReader(rr.Body)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
expected := "Denominazione Istituto" expected := []string{
"FooSchooll",
"123",
}
ok := true ok := true
doc.Find(".control-label").Each(func(i int, s *goquery.Selection) { doc.Find("dd").Each(func(i int, s *goquery.Selection) {
if !strings.Contains(s.Text(), expected) { log.Print(s)
t.Equal(expected[i], s.Text())
if t.Failed() {
ok = false ok = false
} }
}) })

View file

@ -15,3 +15,16 @@ orm:
admin: admin:
username: "admin" username: "admin"
password: "admin" password: "admin"
subscriber:
password: "subscribe"
smtp:
host: "localhost"
port: 1025
username: ""
password: ""
from: "no-reply@olimpiadi-economiaefinanza.it"
bcc: "bcc@fake.org"
subject: "[OEF2020] - Credenziali di accesso della scuola"

View file

@ -36,6 +36,7 @@ func NewDatabase(config *config.ConfigT, models []interface{}) (*Database, error
db := new(Database) db := new(Database)
db.Config = config db.Config = config
db.models = models
db.fns = make(map[string]func(*Database, map[string]string, http.ResponseWriter, *http.Request) (interface{}, error), 0) db.fns = make(map[string]func(*Database, map[string]string, http.ResponseWriter, *http.Request) (interface{}, error), 0)
db.mapHandlers(models) db.mapHandlers(models)

View file

@ -2,6 +2,7 @@ package orm
import ( import (
"fmt" "fmt"
"log"
"net/http" "net/http"
"strings" "strings"
"time" "time"
@ -46,11 +47,11 @@ type School struct {
Code string Code string
EmailSentDate time.Time EmailSentDate time.Time
SchoolResponsibleLastname string SchoolContactPersonLastname string
SchoolResponsibleFirstname string SchoolContactPersonFirstname string
ContestResponsibleLastname string ContestDirectorLastname string
ContestResponsibleFirstname string ContestDirectorFirstname string
UserID uint UserID uint
RegionID RegionID `schema:"region_id"` RegionID RegionID `schema:"region_id"`
@ -192,6 +193,7 @@ func (model *School) Read(db *Database, args map[string]string, w http.ResponseW
} }
if err := db._db.Preload("User").Preload("Region").Preload("Participants.Category").Preload("Participants").First(&school, id).Error; err != nil { if err := db._db.Preload("User").Preload("Region").Preload("Participants.Category").Preload("Participants").First(&school, id).Error; err != nil {
log.Println("ARGS", err)
return nil, err return nil, err
} }

File diff suppressed because it is too large Load diff

View file

@ -79,6 +79,28 @@
{{$options := ` { name: "Email",id: "school_email",label: "Indirizzo email",placeholder: "Inserire l'indirizzo di posta istituzionale",type: "email",required: "true"} `}} {{$options := ` { name: "Email",id: "school_email",label: "Indirizzo email",placeholder: "Inserire l'indirizzo di posta istituzionale",type: "email",required: "true"} `}}
{{template "input" dict "options" ($options|yaml) "value" (.Data|field "Email") "update" $update}} {{template "input" dict "options" ($options|yaml) "value" (.Data|field "Email") "update" $update}}
<div class="form-row">
<div class="col">
{{$options := ` { name: "SchoolContactPersonFirstname",id: "school_contact_person_firstname",label: "Nome del referente di sede",placeholder: "Inserire il nome del referente di sede",type: "text",required: "true"} `}}
{{template "input" dict "options" ($options|yaml) "value" (.Data|field "SchoolContactPersonFirstname") "update" $update}}
</div>
<div class="col">
{{$options := ` { name: "SchoolContactPersonLastname",id: "school_contact_person_lastname",label: "Cognome del referente di sede",placeholder: "Inserire il cognome del referente di sede",type: "text",required: "true"} `}}
{{template "input" dict "options" ($options|yaml) "value" (.Data|field "SchoolContactPersonLastname") "update" $update}}
</div>
</div>
<div class="form-row">
<div class="col">
{{$options := ` { name: "ContestDirectorFirstname",id: "school_contest_director_firstname",label: "Nome del responsabile di gara",placeholder: "Inserire il nome del responsabile di gara",type: "text",required: "true"} `}}
{{template "input" dict "options" ($options|yaml) "value" (.Data|field "ContestDirectorFirstname") "update" $update}}
</div>
<div class="col">
{{$options := ` { name: "ContestDirectorLastname",id: "school_contest_director_lastname",label: "Cognome del responsabile di gara",placeholder: "Inserire il cognome del responsabile di gara",type: "text",required: "true"} `}}
{{template "input" dict "options" ($options|yaml) "value" (.Data|field "ContestDirectorLastname") "update" $update}}
</div>
</div>
{{if .Claims|isSubscriber}} {{if .Claims|isSubscriber}}
{{$options := ` { saveTitle: "Invia iscrizione", model: "School" } `}} {{$options := ` { saveTitle: "Invia iscrizione", model: "School" } `}}
{{template "submit_cancel_buttons" dict "options" ($options|yaml) "id" (.Data|field "ID") "update" $update}} {{template "submit_cancel_buttons" dict "options" ($options|yaml) "id" (.Data|field "ID") "update" $update}}