oficina / home Public

Clone
git clone https://amadan.net/oficina/home

Plain git — no account needed to clone.

Download

Download this file

1package home
2
3import (
4 "strings"
5 "testing"
6)
7
8func TestPersonRefIsOpaqueAndUnique(t *testing.T) {
9 seen := map[string]bool{}
10 for i := 0; i < 1000; i++ {
11 ref, err := NewPersonRef()
12 if err != nil {
13 t.Fatalf("NewPersonRef: %v", err)
14 }
15 if seen[ref] {
16 t.Fatalf("duplicate person ref %q after %d draws", ref, i)
17 }
18 seen[ref] = true
19 if !ValidPersonRef(ref) {
20 t.Fatalf("NewPersonRef produced %q, which ValidPersonRef rejects", ref)
21 }
22 }
23}
24
25func TestPersonRefDoesNotEmbedInput(t *testing.T) {
26 ref, err := NewPersonRef()
27 if err != nil {
28 t.Fatalf("NewPersonRef: %v", err)
29 }
30 if strings.Contains(ref, "@") {
31 t.Fatalf("person ref %q contains an @", ref)
32 }
33}
34
35// NewPersonRef takes no argument, and that is the point rather than an
36// oversight: a ref derived from the address would put the address back
37// at rest in a reversible form under another name. This test is the
38// reminder, since a future signature change is exactly how that would
39// arrive.
40func TestPersonRefTakesNoInput(t *testing.T) {
41 var f func() (string, error) = NewPersonRef
42 if f == nil {
43 t.Fatal("NewPersonRef does not have the signature func() (string, error)")
44 }
45}
46
47func TestValidPersonRefRejectsRubbish(t *testing.T) {
48 for _, bad := range []string{
49 "",
50 "person@example.invalid",
51 "../etc",
52 strings.Repeat("a", 500),
53 "pr_", // prefix only
54 "pr_" + strings.Repeat("a", 25), // one short
55 "pr_" + strings.Repeat("a", 27), // one long
56 strings.Repeat("a", 26), // no prefix
57 "PR_" + strings.Repeat("a", 26), // wrong-case prefix
58 "pr_" + strings.Repeat("A", 26), // wrong-case body
59 "pr_" + strings.Repeat("1", 26), // 1 is not in base32's alphabet
60 "pr_" + strings.Repeat("a", 25) + "=", // padding
61 "pr_" + strings.Repeat("a", 25) + "/", // path separator
62 "pr_" + strings.Repeat("a", 25) + "\n", // a log-line break
63 } {
64 if ValidPersonRef(bad) {
65 t.Errorf("ValidPersonRef(%q) = true", bad)
66 }
67 }
68}
69
70// The ref appears in log lines by design — §3.4: "Errors carry person
71// refs and codes" — so it must be safe there and in a URL path.
72func TestPersonRefIsSafeInLogsAndPaths(t *testing.T) {
73 ref, err := NewPersonRef()
74 if err != nil {
75 t.Fatal(err)
76 }
77 if strings.ContainsAny(ref, " \t\r\n\"'/\\?#&=%") {
78 t.Fatalf("person ref %q contains a character that needs escaping", ref)
79 }
80}
81