1// SPDX-License-Identifier: AGPL-3.0-or-later
2
3package domain_test
4
5import (
6 "errors"
7 "strings"
8 "testing"
9
10 "github.com/stretchr/testify/assert"
11 "github.com/stretchr/testify/require"
12
13 "bnema.dev/ermite/internal/domain"
14)
15
16func TestParseRepoName(t *testing.T) {
17 tests := []struct {
18 in string
19 valid bool
20 suggestion string
21 }{
22 {in: "ermite", valid: true},
23 {in: "a", valid: true},
24 {in: "my-repo_1.0", valid: true},
25 {in: "x.y", valid: true},
26 {in: "0", valid: true},
27 {in: strings.Repeat("a", 100), valid: true},
28 {in: strings.Repeat("a", 101)},
29 {in: ""},
30 {in: "Ermite", suggestion: "ermite"},
31 {in: "My-Repo", suggestion: "my-repo"},
32 {in: "UPPER.git"}, // lowercase would still end in .git: no suggestion
33 {in: ".hidden"},
34 {in: "trailing."},
35 {in: "a..b"},
36 {in: "tools.git"},
37 {in: "-"},
38 {in: "robots.txt"},
39 {in: "favicon.ico"},
40 {in: "-dash-ok", valid: true},
41 {in: "has space"},
42 {in: "a/b"},
43 {in: "caf\u00e9"},
44 {in: "a\x00b"},
45 }
46 for _, tt := range tests {
47 t.Run(tt.in, func(t *testing.T) {
48 n, err := domain.ParseRepoName(tt.in)
49 if tt.valid {
50 require.NoError(t, err)
51 assert.Equal(t, tt.in, n.String())
52 assert.False(t, n.IsZero())
53 return
54 }
55 require.Error(t, err)
56 assert.ErrorIs(t, err, domain.ErrInvalidName)
57 assert.True(t, n.IsZero())
58 var ine *domain.InvalidNameError
59 require.True(t, errors.As(err, &ine))
60 assert.Equal(t, tt.suggestion, ine.Suggestion)
61 if tt.suggestion != "" {
62 assert.Contains(t, err.Error(), tt.suggestion)
63 }
64 })
65 }
66}
67
68func TestParseRepoPath(t *testing.T) {
69 tests := []struct {
70 in string
71 want string
72 valid bool
73 }{
74 {"tools", "tools", true},
75 {"tools.git", "tools", true},
76 {"tools.git.git", "", false}, // only one suffix is stripped
77 {".git", "", false},
78 {"Tools.git", "", false},
79 {"", "", false},
80 }
81 for _, tt := range tests {
82 t.Run(tt.in, func(t *testing.T) {
83 n, err := domain.ParseRepoPath(tt.in)
84 if !tt.valid {
85 assert.ErrorIs(t, err, domain.ErrInvalidName)
86 return
87 }
88 require.NoError(t, err)
89 assert.Equal(t, tt.want, n.String())
90 })
91 }
92}
93
94func TestParseVisibility(t *testing.T) {
95 for in, want := range map[string]domain.Visibility{"public": domain.VisibilityPublic, "private": domain.VisibilityPrivate} {
96 got, err := domain.ParseVisibility(in)
97 require.NoError(t, err)
98 assert.Equal(t, want, got)
99 }
100 for _, in := range []string{"", "Public", "secret"} {
101 _, err := domain.ParseVisibility(in)
102 assert.ErrorIs(t, err, domain.ErrInvalidVisibility, in)
103 }
104}
105
106func TestPrincipal(t *testing.T) {
107 var zero domain.Principal
108 assert.True(t, zero.IsAnonymous())
109 assert.False(t, zero.IsRoot())
110 assert.True(t, domain.Root().IsRoot())
111 assert.Equal(t, "anonymous", domain.Anonymous().Label())
112}