1// SPDX-License-Identifier: AGPL-3.0-or-later
2
3package domain_test
4
5import (
6 "strings"
7 "testing"
8
9 "github.com/stretchr/testify/assert"
10 "github.com/stretchr/testify/require"
11
12 "bnema.dev/ermite/internal/domain"
13)
14
15func TestNormalizeTopics(t *testing.T) {
16 t.Parallel()
17 many := func(n int) []string {
18 var out []string
19 for i := range n {
20 out = append(out, "t"+strings.Repeat("x", i))
21 }
22 return out
23 }
24 tests := []struct {
25 name string
26 in []string
27 want []string
28 bad bool
29 }{
30 {name: "nil", in: nil, want: nil},
31 {name: "empty", in: []string{}, want: nil},
32 {name: "lowercased", in: []string{"Go"}, want: []string{"go"}},
33 {name: "sorted", in: []string{"zig", "c", "go"}, want: []string{"c", "go", "zig"}},
34 {name: "deduplicated after lowercasing", in: []string{"Go", "go", "GO"}, want: []string{"go"}},
35 {name: "digits and hyphens", in: []string{"3d-printing", "0"}, want: []string{"0", "3d-printing"}},
36 {name: "50 characters", in: []string{strings.Repeat("a", 50)}, want: []string{strings.Repeat("a", 50)}},
37 {name: "exactly 20", in: many(20), want: many(20)},
38 {name: "duplicates do not count twice", in: append(many(20), "t", "tx"), want: many(20)},
39 {name: "21", in: many(21), bad: true},
40 {name: "51 characters", in: []string{strings.Repeat("a", 51)}, bad: true},
41 {name: "empty topic", in: []string{""}, bad: true},
42 {name: "leading hyphen", in: []string{"-go"}, bad: true},
43 {name: "underscore", in: []string{"a_b"}, bad: true},
44 {name: "space", in: []string{"a b"}, bad: true},
45 {name: "dot", in: []string{"a.b"}, bad: true},
46 {name: "non-ASCII", in: []string{"café"}, bad: true},
47 {name: "one bad among good", in: []string{"go", "no!"}, bad: true},
48 }
49 for _, tt := range tests {
50 t.Run(tt.name, func(t *testing.T) {
51 t.Parallel()
52 got, err := domain.NormalizeTopics(tt.in)
53 if tt.bad {
54 require.ErrorIs(t, err, domain.ErrInvalid)
55 assert.Nil(t, got)
56 return
57 }
58 require.NoError(t, err)
59 assert.Equal(t, tt.want, got)
60 })
61 }
62}