hlfw.ca

webbing

Download patch

ref: 1b4520b8cf130ca34181064c5876cee2479dd9ea
parent: 4ca7a9ce4fe13f3561f09e9166aa9461e2be50e4
parent: c538333e4fb36451e119595cccc7cdde9ffefa16
author: Michael Misch <michaelmisch1985@gmail.com>
date: Tue Mar 31 04:50:10 PDT 2020

Merge pull request #7 from olmaxmedical/testing

Add tests/modifications

--- a/doctor/application.go
+++ b/doctor/application.go
@@ -24,44 +24,56 @@
 func application(r *http.Request, p *message.Printer) []string {
 	var errors []string
 
-	data, err := forms.Parse(r)
+	data, err := forms.ParseMax(r, r.ContentLength)
 	if err != nil {
-		errors = append(errors, fmt.Sprintf("Internal server error %v", err))
+		errors = append(errors, fmt.Sprintf("validation error %v", err))
 		return errors
 	}
+
 	val := data.Validator()
 	val.Require("gender").Message(p.Sprint("Please select a biological gender"))
+
 	if r.PostFormValue("gender") != "male" && r.PostFormValue("gender") != "female" {
 		val.AddError("gender", p.Sprint("Invalid selection for gender"))
 	}
+
 	val.RequireFile("cv").Message(p.Sprint("Empty or missing CV"))
-	val.AcceptFileExts("cv", "application/msword,applicationvnd.openxmlformats-officedocument.wordprocessingml.document,application/pdf").Message(p.Sprint("Unsupported filetype for CV"))
+	val.AcceptFileExts("cv", "application/msword,applicationvnd.openxmlformats-officedocument.wordprocessingml.document,application/pdf").Message(p.Sprint("unsupported filetype for cv"))
 	val.RequireFile("diploma").Message(p.Sprint("Empty or missing Diploma/Board Certification"))
-	val.AcceptFileExts("cv", "application/msword,applicationvnd.openxmlformats-officedocument.wordprocessingml.document,application/pdf").Message(p.Sprint("Unsupported filetype for Diploma/Board Certification"))
+	val.AcceptFileExts("diploma", "application/msword,applicationvnd.openxmlformats-officedocument.wordprocessingml.document,application/pdf").Message(p.Sprint("unsupported filetype for diploma"))
+
 	for i := 1; i < 12; i++ {
 		num := fmt.Sprintf("q%d", i)
+
 		sel, ok := r.Form[num]
 		if !ok {
 			val.AddError(num, p.Sprintf("No selection for question %d", i))
 			continue
 		}
+
 		if sel[0] == "Yes" || sel[0] == "yes" || sel[0] == "no" || sel[0] == "No" {
 			continue
 		}
+
 		val.AddError(num, p.Sprintf("Invalid selection for question %d", i))
 	}
+
 	val.Require("email").Message(p.Sprintf("Valid email required"))
 	val.MatchEmail("email").Message(p.Sprintf("Invalid email"))
 	val.Require("name").Message(p.Sprintf("Full name required"))
 	val.MinLength("name", 2).Message(p.Sprintf("Full name must be at least 2 characters"))
+
 	if r.PostFormValue("redFlag") != "on" {
 		val.AddError("redFlag", p.Sprint("Invalid selection for confirm element"))
 	}
+
 	if val.HasErrors() {
 		errors = append(errors, val.Messages()...)
 	}
+
 	r.Form["pagetitle"] = []string{"Application for doctor"}
 	r.Form["sendto"] = []string{"olmaxmedical@gmail.com"}
 	delete(r.Form, "redFlag")
+
 	return errors
 }
--- a/doctor/application_test.go
+++ b/doctor/application_test.go
@@ -1,125 +1,94 @@
 package forms
 
 import (
-	"bufio"
+	"bytes"
+	"errors"
+	"fmt"
+	"mime/multipart"
 	"net/http"
-	"strings"
 	"testing"
+
+	"github.com/olmaxmedical/forms/util"
+	"golang.org/x/text/message"
 )
 
-// This isn't quite right yet, we'll get a working test soon.
-var req = `POST /doctor/application.html HTTP/1.1
-Host: localhost
-User-Agent: Mozilla/5.0
-Accept: */*
-Connection: keep-alive
-Cache-Control: no-cache
-Content-Length: 2028
-Content-Type: multipart/form-data; boundary=--------------------
+func TestApplication(t *testing.T) {
+	fields := map[string]string{
+		"qs":      "no",
+		"gender":  "male",
+		"email":   "foo@bar.ca",
+		"name":    "Doctor Octopus",
+		"redFlag": "on",
+	}
 
---------------------------4ee5f9ad0b2d7899
-Content-Disposition: form-data; name="Specialty"
+	if e := testApplication(t, fields); e != nil {
+		t.Error(e)
+	}
 
-bariatric
---------------------------4ee5f9ad0b2d7899
-Content-Disposition: form-data; name="country"
+	fields["gender"] = "pineapple"
+	if e := testApplication(t, fields); e == nil {
+		t.Error("invalid field accepted")
+	}
 
-Albania
---------------------------4ee5f9ad0b2d7899
-Content-Disposition: form-data; name="email"
+	fields["gender"] = "male"
+	fields["email"] = "foo@bar@ca"
+	if e := testApplication(t, fields); e == nil {
+		t.Error("invalid field accepted")
+	}
 
-mee%40foo.ca
---------------------------4ee5f9ad0b2d7899
-Content-Disposition: form-data; name="gender"
+	fields["email"] = "foo@bar.ca"
+	fields["qs"] = "true"
+	if e := testApplication(t, fields); e == nil {
+		t.Error("invalid field accepted")
+	}
+}
 
-male
---------------------------4ee5f9ad0b2d7899
-Content-Disposition: form-data; name="name"
+func testApplication(t *testing.T, fields map[string]string) error {
+	var reqBody bytes.Buffer
 
-mememe
---------------------------4ee5f9ad0b2d7899
-Content-Disposition: form-data; name="pagetitle"
+	mpw := multipart.NewWriter(&reqBody)
+	files := map[string]string{
+		"cv":      "resume.pdf",
+		"diploma": "certificate.pdf",
+	}
 
-Application+for+doctor
---------------------------4ee5f9ad0b2d7899
-Content-Disposition: form-data; name="q1"
+	for key, value := range files {
+		if e := util.WriteFile(mpw, key, "../resources/"+value); e != nil {
+			panic(e)
+		}
+	}
 
-No
---------------------------4ee5f9ad0b2d7899
-Content-Disposition: form-data; name="q10"
+	for key, value := range fields {
+		if key == "qs" {
+			for i := 0; i < 12; i++ {
+				key = fmt.Sprintf("q%d", i)
+				if e := mpw.WriteField(key, value); e != nil {
+					panic(e)
+				}
+			}
+			continue
+		}
 
-No
---------------------------4ee5f9ad0b2d7899
-Content-Disposition: form-data; name="q11"
+		if e := mpw.WriteField(key, value); e != nil {
+			panic(e)
+		}
+	}
 
-No
---------------------------4ee5f9ad0b2d7899
-Content-Disposition: form-data; name="q2"
+	request := util.BuildMultiRequest(mpw, &reqBody)
+	printer := message.NewPrinter(message.MatchLanguage("en"))
+	return runTest(request, printer)
+}
 
-No
---------------------------4ee5f9ad0b2d7899
-Content-Disposition: form-data; name="q3"
+func runTest(request *http.Request, printer *message.Printer) error {
+	for _, err := range application(request, printer) {
+		switch err {
+		case "unsupported filetype for cv":
+		case "unsupported filetype for diploma":
+		default:
+			return errors.New(err)
+		}
 
-No
---------------------------4ee5f9ad0b2d7899
-Content-Disposition: form-data; name="q4"
-
-No
---------------------------4ee5f9ad0b2d7899
-Content-Disposition: form-data; name="q5"
-
-No
---------------------------4ee5f9ad0b2d7899
-Content-Disposition: form-data; name="q6"
-
-No
---------------------------4ee5f9ad0b2d7899
-Content-Disposition: form-data; name="q7"
-
-No
---------------------------4ee5f9ad0b2d7899
-Content-Disposition: form-data; name="q8"
-
-No
---------------------------4ee5f9ad0b2d7899
-Content-Disposition: form-data; name="q9"
-
-No
---------------------------4ee5f9ad0b2d7899
-Content-Disposition: form-data; name="sendto"
-
-olmaxmedical%40gmail.com
---------------------------4ee5f9ad0b2d7899
-Content-Disposition: form-data; name="cv"
-
-resume.pdf
---------------------------4ee5f9ad0b2d7899
-Content-Disposition: form-data; name="form"
-
-resume.pdf
---------------------------4ee5f9ad0b2d7899`
-
-func TestApplication(t *testing.T) {
-	// Build a POST request with a map of entries
-	rd := bufio.NewReader(strings.NewReader(req))
-
-	request, err := http.ReadRequest(rd)
-	if err != nil {
-		t.Errorf("test design error: bad request: %v", err)
-		return
 	}
 
-	if e := request.ParseMultipartForm(request.ContentLength); e != nil {
-		t.Error(e)
-	}
-	/*
-		printer := message.NewPrinter(message.MatchLanguage("en"))
-
-		resp := application(request, printer)
-		if len(resp) > 0 {
-			for _, err := range resp {
-				t.Errorf("%s", err)
-			}
-		}
-	*/
+	return nil
 }
--- a/doctor/profile.go
+++ b/doctor/profile.go
@@ -23,7 +23,7 @@
 
 func profile(r *http.Request, p *message.Printer) []string {
 	var errors []string
-	data, err := forms.Parse(r)
+	data, err := forms.ParseMax(r, r.ContentLength)
 	if err != nil {
 		errors = append(errors, "Internal server error")
 		return errors
--- a/go.mod
+++ b/go.mod
@@ -3,7 +3,7 @@
 go 1.14
 
 require (
-	github.com/albrow/forms v0.3.3
+	github.com/albrow/forms v0.3.4-0.20170215231405-c4277021bca2
 	github.com/olmaxmedical/plugins v0.0.1
 	github.com/olmaxmedical/router v0.0.1
 	golang.org/x/text v0.3.2
--- a/go.sum
+++ b/go.sum
@@ -1,5 +1,5 @@
-github.com/albrow/forms v0.3.3 h1:+40fCsDyS2lU97IEeed7bnUGENvlVzppQGBGy6kd77E=
-github.com/albrow/forms v0.3.3/go.mod h1:jvrM3b0gPuIRiY1E/KmKfPk2XXDEKj7yFB+g9g0BItQ=
+github.com/albrow/forms v0.3.4-0.20170215231405-c4277021bca2 h1:SnKbJhjY6YOX6cC0JL19DzxJ4nMZoTFqRJ006tgpclw=
+github.com/albrow/forms v0.3.4-0.20170215231405-c4277021bca2/go.mod h1:jvrM3b0gPuIRiY1E/KmKfPk2XXDEKj7yFB+g9g0BItQ=
 github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
--- a/patient/offer.go
+++ b/patient/offer.go
@@ -15,7 +15,7 @@
 		Access:    router.PatientAuth,
 		Path:      "patient/offer",
 		Validator: offer,
-		After:     plugins.Search | plugins.Services,
+		After:     plugins.Search | plugins.Services, //|plugins.Offer
 		Redirect:  "results.html",
 	}
 	router.AddPost(b)
@@ -23,7 +23,7 @@
 
 func offer(r *http.Request, p *message.Printer) []string {
 	var errors []string
-	data, err := forms.Parse(r)
+	data, err := forms.ParseMax(r, r.ContentLength)
 	if err != nil {
 		errors = append(errors, p.Sprint("Internal server error"))
 		return errors
@@ -45,7 +45,7 @@
 	if err != nil {
 		val.AddError("endDate", p.Sprint("Invalid end-date entered"))
 	}
-	val.Require("")
+
 	if val.HasErrors() {
 		errors = append(errors, val.Messages()...)
 	}
--- a/patient/symptoms.go
+++ b/patient/symptoms.go
@@ -23,32 +23,44 @@
 
 func symptoms(r *http.Request, p *message.Printer) []string {
 	var errors []string
+
 	data, err := forms.Parse(r)
 	if err != nil {
 		errors = append(errors, p.Sprint("Internal server error"))
 		return errors
 	}
+
 	val := data.Validator()
-	// TODO(halfwit): Date must be in a reasonable range
+
+	// NOTE(halfwit) This is the current record oldest person
+	// Anything older than this is most definitely invalid
+	oldest := time.Date(1901, 1, 1, 0, 0, 0, 0, time.UTC)
+
+	// NOTE(halfwit) There's potential that symptoms started that day
+	// and the client is in a different time zone, use our tomorrow as a gate
+	youngest := time.Now().Add(time.Hour * 24)
+
 	val.Require("bday").Message(p.Sprint("Birth date required"))
-	_, err = time.Parse("2006-01-02T15:04:05", r.Form.Get("bday"))
-	if err != nil {
+	if d, e := time.Parse("2006-01-02T15:04:05", r.Form.Get("bday")); e != nil || oldest.After(d) || youngest.Before(d) {
 		val.AddError("bday", p.Sprint("Invalid birth date"))
 	}
+
 	val.Require("onset").Message(p.Sprint("Please enter the date and time your symptoms started"))
-	_, err = time.Parse("2006-01-02T15:04:05", r.Form.Get("onset"))
-	if err != nil {
+	if d, e := time.Parse("2006-01-02T15:04:05", r.Form.Get("onset")); e != nil || oldest.After(d) || youngest.Before(d) {
 		val.AddError("bday", p.Sprint("Invalid date"))
 	}
+
 	val.Require("gender").Message(p.Sprint("Please select a biological gender"))
 	if r.PostFormValue("gender") != "male" && r.PostFormValue("gender") != "female" {
 		val.AddError("gender", p.Sprint("Invalid selection for gender"))
 	}
+
 	val.GreaterOrEqual("duration", 0).Message(p.Sprint("Invalid value entered for how long symptoms have lasted"))
 	val.Require("reason").Message(p.Sprint("Please provide the reason for visit"))
 	val.Require("location").Message(p.Sprint("Please list the area the symptom(s) appear"))
 	val.Require("characteristic").Message(p.Sprint("Please provide a description of your symptoms"))
 	val.Require("aggreAlevi").Message(p.Sprint("Please note anything which improves/worsens your symptoms"))
+
 	for _, i := range []string{
 		"feversChills",
 		"wtGainLoss",
@@ -66,11 +78,14 @@
 			val.AddError(i, p.Sprintf("No selection for %s", i))
 			continue
 		}
+
 		if sel[0] == "Yes" || sel[0] == "yes" || sel[0] == "no" || sel[0] == "No" {
 			continue
 		}
+
 		val.AddError(i, p.Sprintf("Invalid selection for %s", i))
 	}
+
 	r.Form["pagetitle"] = []string{"Client symptoms"}
 	if val.HasErrors() {
 		errors = append(errors, val.Messages()...)