Source code for the Codeberg e.V. registration web service.
https://join.codeberg.org
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
281 lines
10 KiB
281 lines
10 KiB
package main |
|
|
|
import ( |
|
"net/http" |
|
"net/url" |
|
"reflect" |
|
"testing" |
|
) |
|
|
|
func Test_parseMoney(t *testing.T) { |
|
type args struct { |
|
strAmount string |
|
} |
|
tests := []struct { |
|
name string |
|
args args |
|
want float64 |
|
wantErr bool |
|
}{ |
|
{name: "test simple value", args: args{"42"}, want: 42.0}, |
|
{name: "test simple value with fraction", args: args{"42.23"}, want: 42.23}, |
|
{name: "test empty amount", args: args{""}, want: 0, wantErr: true}, |
|
{name: "test character amount", args: args{"fourtytwo"}, want: 0, wantErr: true}, |
|
{name: "test simple value with fraction separated by comma", args: args{"42,23"}, want: 42.23}, |
|
{name: "test simple value with fraction", args: args{"42.234"}, want: 42.0}, |
|
} |
|
for _, tt := range tests { |
|
t.Run(tt.name, func(t *testing.T) { |
|
got, err := parseMoney(tt.args.strAmount) |
|
if (err != nil) != tt.wantErr { |
|
t.Errorf("parseMoney() error = %v, wantErr %v", err, tt.wantErr) |
|
return |
|
} |
|
if got != tt.want { |
|
t.Errorf("parseMoney() got = %v, want %v", got, tt.want) |
|
} |
|
}) |
|
} |
|
} |
|
|
|
func Test_simpleLocaleResolver(t *testing.T) { |
|
type args struct { |
|
root string |
|
locale string |
|
domain string |
|
} |
|
tests := []struct { |
|
name string |
|
args args |
|
want string |
|
}{ |
|
{name: "test valid input", args: args{root: "locales", locale: "de", domain: "messages"}, want: "locales/de/messages.mo"}, |
|
{name: "test another valid input", args: args{root: "locales/foo", locale: "de", domain: "messages"}, want: "locales/foo/de/messages.mo"}, |
|
} |
|
for _, tt := range tests { |
|
t.Run(tt.name, func(t *testing.T) { |
|
if got := simpleLocaleResolver(tt.args.root, tt.args.locale, tt.args.domain); got != tt.want { |
|
t.Errorf("simpleLocaleResolver() = %v, want %v", got, tt.want) |
|
} |
|
}) |
|
} |
|
} |
|
|
|
func Test_getMailText(t *testing.T) { |
|
formData := map[string]string{ |
|
"iban": "DE00******************12 34", |
|
"membershipType": "activeMember", |
|
"skills": "Unit-Testing", |
|
"name": "Tester", |
|
"addr1": "Auf dem Holzweg 23", |
|
"skillsOther": "1", |
|
"frequency": "12", |
|
"bic": "HOLZHAUSEN42", |
|
"timestamp": "2022-04-11 11:07:44.196404137 +0200 CEST m=+453156.486723556", |
|
"registrationClientIP": "dead:beaf::1", |
|
"first-name": "Johnny", |
|
"country": "Deutschland", |
|
"memberType": "private", |
|
"contribution": "23,42", |
|
"email": "unit-test@jtester.local", |
|
"zipcode": "12345", |
|
"city": "Holzweghausen", |
|
} |
|
expected := "Hello Johnny!\n\nWe are happy to welcome you as a member of Codeberg e.V.\nThe following record will be stored in the membership database:\n\n" + |
|
" {\n" + |
|
" \"addr1\" : \"Auf dem Holzweg 23\", \n" + |
|
" \"bic\" : \"HOLZHAUSEN42\", \n" + |
|
" \"city\" : \"Holzweghausen\", \n" + |
|
" \"contribution\" : \"23,42\", \n" + |
|
" \"country\" : \"Deutschland\", \n" + |
|
" \"email\" : \"unit-test@jtester.local\", \n" + |
|
" \"first-name\" : \"Johnny\", \n" + |
|
" \"frequency\" : \"12\", /* 23,42 EUR contribution every 12 month(s) */\n" + |
|
" \"iban\" : \"DE00******************12 34\", /* hidden here for privacy reasons */\n" + |
|
" \"memberType\" : \"private\", \n" + |
|
" \"membershipType\" : \"activeMember\", \n" + |
|
" \"name\" : \"Tester\", \n" + |
|
" \"registrationClientIP\" : \"dead:beaf::1\", /* client IP address at registration. Used to detect and block abuse of online registration system */\n" + |
|
" \"skills\" : \"Unit-Testing\", \n" + |
|
" \"skillsOther\" : \"1\", \n" + |
|
" \"timestamp\" : \"2022-04-11 11:07:44.196404137 +0200 CEST m=+453156.486723556\", \n" + |
|
" \"zipcode\" : \"12345\", \n" + |
|
" }\n\nPlease review this data and let us know if anything went wrong.\n\n" + |
|
"The next SEPA transfer will be manually initiated in next few days.\nIf this won't work you will be notified, we can try other transfer methods\n" + |
|
"(members in US, Canada, New Zealand, etc contribute via paypal or wire transfer,\nin other non-EU countries like Switzerland SEPA works without problems).\n" + |
|
"\nPlease note that membership in the gitea account group \"Members\" on\ncodeberg.org is not automatic (this group enables access to Codeberg e.V.'s\n" + |
|
"internal repos and discussion between Codeberg e.V. members therein).\nFor privacy reasons we add members on request (your membership is visible\n" + |
|
"to other members). If you like to join, please send an email to codeberg@codeberg.org\nand tell us your username.\n\nCodeberg e.V.\n\n" |
|
|
|
type args struct { |
|
formData map[string]string |
|
} |
|
tests := []struct { |
|
name string |
|
args args |
|
want string |
|
}{ |
|
{"test message", args{formData: formData}, expected}, |
|
} |
|
for _, tt := range tests { |
|
t.Run(tt.name, func(t *testing.T) { |
|
if got := getMailText(tt.args.formData); got != tt.want { |
|
t.Errorf("getMailText() = %v, want %v", got, tt.want) |
|
} |
|
}) |
|
} |
|
} |
|
|
|
type mockResponseWriter struct{} |
|
|
|
func (mockResponseWriter) Header() http.Header { |
|
return nil |
|
} |
|
|
|
func (mockResponseWriter) Write([]byte) (int, error) { |
|
return 1, nil |
|
} |
|
|
|
func (mockResponseWriter) WriteHeader(int) {} |
|
|
|
func Test_validate(t *testing.T) { |
|
catalog := localeDomain.Locale([]string{"en"}...) |
|
request := new(http.Request) |
|
serverCtx := new(serverContext) |
|
serverCtx.writer = mockResponseWriter{} |
|
serverCtx.req = request |
|
serverCtx.locale = catalog |
|
|
|
// function providing copies of valid expected data |
|
getExpected := func() map[string]string { |
|
return map[string]string{ |
|
"iban": "DE00******************12 34", |
|
"membershipType": "activeMember", |
|
"skills": "Unit-Testing", |
|
"name": "Tester", |
|
"addr1": "Auf dem Holzweg 23", |
|
"skillsOther": "1", |
|
"payment-method": "sepa-yearly", |
|
"bic": "HOLZHAUSEN42", |
|
"timestamp": "2022-04-11 11:07:44.196404137 +0200 CEST m=+453156.486723556", |
|
"registrationClientIP": "", |
|
"firstName": "Johnny", |
|
"country": "Deutschland", |
|
"memberType": "private", |
|
"contribution": "66,42", |
|
"email": "unit-test@jtester.local", |
|
"zipcode": "12345", |
|
"city": "Holzweghausen", |
|
} |
|
} |
|
|
|
// function providing copies of valid input data |
|
getUrlValues := func() url.Values { |
|
return url.Values{ |
|
"iban": []string{"DE00******************12 34"}, |
|
"membershipType": []string{"activeMember"}, |
|
"skills": []string{"Unit-Testing"}, |
|
"name": []string{"Tester"}, |
|
"addr1": []string{"Auf dem Holzweg 23"}, |
|
"skillsOther": []string{"1"}, |
|
"payment-method": []string{"sepa-yearly"}, |
|
"bic": []string{"HOLZHAUSEN42"}, |
|
"timestamp": []string{"2022-04-11 11:07:44.196404137 +0200 CEST m=+453156.486723556"}, |
|
"registrationClientIP": []string{""}, |
|
"firstName": []string{"Johnny"}, |
|
"country": []string{"Deutschland"}, |
|
"memberType": []string{"private"}, |
|
"contribution": []string{"66,42"}, |
|
"email": []string{"unit-test@jtester.local"}, |
|
"zipcode": []string{"12345"}, |
|
"city": []string{"Holzweghausen"}, |
|
} |
|
} |
|
|
|
// TestCase 1: All values correct |
|
urlValues := getUrlValues() |
|
expected := getExpected() |
|
|
|
type args struct { |
|
serverCtx *serverContext |
|
postData url.Values |
|
} |
|
|
|
type testStruct struct { |
|
name string |
|
args args |
|
want map[string]string |
|
want1 map[string]string |
|
} |
|
|
|
tests := []testStruct{ |
|
{"simple test", args{serverCtx: serverCtx, postData: urlValues}, expected, map[string]string{}}, |
|
} |
|
|
|
// TestCase 2: 23,42 p.a. (too small) |
|
expected2 := getExpected() |
|
expected2["contribution"] = "23,42" |
|
|
|
urlValues2 := getUrlValues() |
|
urlValues2["contribution"] = []string{"23,42"} |
|
|
|
tests = append(tests, testStruct{"too small yearly contribution", args{serverCtx: serverCtx, postData: urlValues2}, expected2, map[string]string{"contribution": "Form error: contribution 23.42 (23.42 p.a.)"}}) |
|
|
|
// TestCase 3: 9,99 p.m. (too small) |
|
urlValues3 := getUrlValues() |
|
urlValues3["contribution"] = []string{"9,99"} |
|
urlValues3["payment-method"] = []string{"sepa-monthly"} |
|
|
|
expected3 := getExpected() |
|
expected3["payment-method"] = "sepa-monthly" |
|
expected3["contribution"] = "9,99" |
|
tests = append(tests, testStruct{"too small monthly contribution", args{serverCtx: serverCtx, postData: urlValues3}, expected3, map[string]string{"contribution": "Form error: contribution 9.99 (119.88 p.a.)"}}) |
|
|
|
// TestCase 4: no data |
|
tests = append(tests, testStruct{"no data", args{serverCtx: serverCtx, postData: url.Values{}}, map[string]string{"registrationClientIP": "", "timestamp": "automagic"}, map[string]string{"contribution": "Form error: contribution 0 (0 p.a.)"}}) |
|
|
|
// TestCase 5: empty value |
|
urlValues4 := getUrlValues() |
|
urlValues4["contribution"] = []string{} |
|
|
|
expected4 := getExpected() |
|
delete(expected4, "contribution") |
|
tests = append(tests, testStruct{"empty contribution", args{serverCtx: serverCtx, postData: urlValues4}, expected4, map[string]string{"contribution": "Form error: contribution 0 (0 p.a.)"}}) |
|
|
|
for _, tt := range tests { |
|
t.Run(tt.name, func(t *testing.T) { |
|
got, got1 := validate(tt.args.serverCtx, tt.args.postData) |
|
// the timestamp is always expected to be correct |
|
tt.want["timestamp"] = got["timestamp"] |
|
if !reflect.DeepEqual(got, tt.want) { |
|
t.Errorf("validate() got = %v, want %v", got, tt.want) |
|
} |
|
if !reflect.DeepEqual(got1, tt.want1) { |
|
t.Errorf("validate() got1 = %v, want %v", got1, tt.want1) |
|
} |
|
}) |
|
} |
|
} |
|
|
|
func Test_parseEmail(t *testing.T) { |
|
tests := []struct { |
|
input string |
|
ok bool |
|
}{ |
|
{input: "example@gmail.com", ok: true}, |
|
{input: "example+firstname+lastname@email.com", ok: true}, |
|
{input: "example@234.234.234.234", ok: true}, |
|
{input: "A special string!", ok: false}, |
|
} |
|
for _, tt := range tests { |
|
locale := localeDomain.Locale("en") |
|
t.Run(tt.input, func(t *testing.T) { |
|
err := checkEmail(locale, tt.input) |
|
if tt.ok && err != nil { |
|
t.Errorf("input is bad, expected to be good.") |
|
} else if !tt.ok && err == nil { |
|
t.Errorf("input is good, expected to be bad.") |
|
} |
|
}) |
|
} |
|
}
|
|
|