1//go:build unit
2
3package auth
4
5import (
6 "context"
7 "errors"
8 "testing"
9
10 "github.com/samber/lo"
11
12 "git.sr.ht/~gabrielgio/img/pkg/components/user"
13 "git.sr.ht/~gabrielgio/img/pkg/ext"
14 "git.sr.ht/~gabrielgio/img/pkg/testkit"
15)
16
17type (
18 scene struct {
19 ctx context.Context
20 mockRepository *MockUserRepository
21 controller Controller
22 }
23
24 mockUser struct {
25 id uint
26 username string
27 password []byte
28 }
29
30 MockUserRepository struct {
31 index uint
32 users []*mockUser
33 err error
34 }
35)
36
37var (
38 _ Repository = &MockUserRepository{}
39 key = []byte("6368616e676520746869732070617373")
40)
41
42func setUp() *scene {
43 mockUserRepository := &MockUserRepository{}
44 return &scene{
45 ctx: context.Background(),
46 mockRepository: mockUserRepository,
47 controller: *NewController(mockUserRepository, nil, key),
48 }
49}
50
51func TestInitialRegisterAndLogin(t *testing.T) {
52 testCases := []struct {
53 name string
54 username string
55 password []byte
56 }{
57 {
58 name: "Normal register",
59 username: "username",
60 password: []byte("password"),
61 },
62 }
63
64 for _, tc := range testCases {
65 t.Run(tc.name, func(t *testing.T) {
66 scene := setUp()
67
68 err := scene.controller.InitialRegister(scene.ctx, []byte(tc.username), tc.password, []byte("/"))
69 testkit.TestFatalError(t, "Register", err)
70
71 userID := scene.mockRepository.GetLastId()
72
73 user, err := scene.mockRepository.Get(scene.ctx, userID)
74 testkit.TestFatalError(t, "Get", err)
75 testkit.TestValue(t, "Register", tc.username, user.Username)
76
77 auth, err := scene.controller.Login(scene.ctx, []byte(tc.username), tc.password)
78 testkit.TestFatalError(t, "Login", err)
79
80 token, err := ext.ReadToken(auth, key)
81 testkit.TestFatalError(t, "Login", err)
82
83 testkit.TestValue(t, "Login", tc.username, token.Username)
84 testkit.TestValue(t, "Login", userID, token.UserID)
85 })
86 }
87}
88
89func toUser(m *mockUser, _ int) *user.User {
90 return &user.User{
91 ID: m.id,
92 Username: m.username,
93 }
94}
95
96func (m *MockUserRepository) GetLastId() uint {
97 return m.index
98}
99
100func (m *MockUserRepository) List(ctx context.Context) ([]*user.User, error) {
101 if m.err != nil {
102 return nil, m.err
103 }
104
105 return lo.Map(m.users, toUser), nil
106}
107
108func (m *MockUserRepository) Get(ctx context.Context, id uint) (*user.User, error) {
109 if m.err != nil {
110 return nil, m.err
111 }
112
113 for _, m := range m.users {
114 if m.id == id {
115 return toUser(m, 0), nil
116 }
117 }
118 return nil, errors.New("Item not found")
119}
120
121func (m *MockUserRepository) GetIDByUsername(ctx context.Context, username string) (uint, error) {
122 if m.err != nil {
123 return 0, m.err
124 }
125
126 for _, m := range m.users {
127 if m.username == username {
128 return m.id, nil
129 }
130 }
131 return 0, errors.New("Item not found")
132}
133
134func (m *MockUserRepository) GetPassword(ctx context.Context, id uint) ([]byte, error) {
135 if m.err != nil {
136 return nil, m.err
137 }
138
139 for _, m := range m.users {
140 if m.id == id {
141 return m.password, nil
142 }
143 }
144 return nil, errors.New("Item not found")
145}
146
147func (m *MockUserRepository) Create(ctx context.Context, createUser *user.CreateUser) (uint, error) {
148 if m.err != nil {
149 return 0, m.err
150 }
151
152 m.index++
153
154 m.users = append(m.users, &mockUser{
155 id: m.index,
156 username: createUser.Username,
157 password: createUser.Password,
158 })
159
160 return m.index, nil
161}
162
163func (m *MockUserRepository) Update(ctx context.Context, id uint, update *user.UpdateUser) error {
164 if m.err != nil {
165 return m.err
166 }
167
168 for _, m := range m.users {
169 if m.id == id {
170 m.username = update.Username
171 }
172 }
173 return nil
174}
175
176func remove[T any](slice []T, s int) []T {
177 return append(slice[:s], slice[s+1:]...)
178}
179
180func (r *MockUserRepository) Delete(ctx context.Context, id uint) error {
181 if r.err != nil {
182 return r.err
183 }
184
185 for i, m := range r.users {
186 if m.id == id {
187 r.users = remove(r.users, i)
188 }
189 }
190 return nil
191}