package calls import ( "strings" "testing" ) func TestSqidUsesOnlyTheReadableAlphabet(t *testing.T) { for i := 0; i < 50; i++ { s, err := newSqid() if err != nil { t.Fatal(err) } if len(s) != sqidLength || strings.Trim(s, sqidAlphabet) != "" { t.Fatalf("bad sqid %q", s) } } } // validSqid is what stands between a room id straight off the request // line and a rate-limiter key, a hub lookup and a log line (review Task // 5 item 1), so both of its branches are worth a table: the length, and // the alphabet. The alphabet branch is the one no other test reaches — // every id newSqid produces is in it by construction. func TestValidSqidChecksLengthAndAlphabet(t *testing.T) { good, err := newSqid() if err != nil { t.Fatal(err) } table := []struct { name string in string want bool }{ {"a minted id", good, true}, {"ten from the alphabet", "23456789ab", true}, {"the last character of the alphabet", "zzzzzzzzzz", true}, {"empty", "", false}, {"nine characters", "23456789a", false}, {"eleven characters", "23456789abc", false}, {"the letter o, which the alphabet drops", "2345678oab", false}, {"the letter l, which the alphabet drops", "2345678lab", false}, {"the digit one, which the alphabet drops", "23456781ab", false}, {"the digit zero, which the alphabet drops", "23456780ab", false}, {"uppercase", "23456789AB", false}, {"a hyphen", "2345678-ab", false}, {"a dot", "23456789.b", false}, {"a space", "23456789 b", false}, {"ten bytes of five multi-byte runes", strings.Repeat("é", 5), false}, } for _, tc := range table { t.Run(tc.name, func(t *testing.T) { if got := validSqid(tc.in); got != tc.want { t.Fatalf("validSqid(%q) = %v, want %v", tc.in, got, tc.want) } }) } } func TestLinkTokenHashIsSHA256Hex(t *testing.T) { tok, hash, err := newLinkToken() if err != nil { t.Fatal(err) } if len(hash) != 64 || hashLinkToken(tok) != hash { t.Fatalf("hash %q does not match token", hash) } }