A community based topic aggregation platform built on atproto
1package users_test
2
3import (
4 "fmt"
5 "testing"
6 "time"
7
8 "Coves/internal/core/users"
9)
10
11type mockUserRepository struct {
12 users map[int]*users.User
13 nextID int
14 shouldFail bool
15}
16
17func newMockUserRepository() *mockUserRepository {
18 return &mockUserRepository{
19 users: make(map[int]*users.User),
20 nextID: 1,
21 }
22}
23
24func (m *mockUserRepository) Create(user *users.User) (*users.User, error) {
25 if m.shouldFail {
26 return nil, fmt.Errorf("mock: database error")
27 }
28
29 user.ID = m.nextID
30 m.nextID++
31 user.CreatedAt = time.Now()
32 user.UpdatedAt = time.Now()
33
34 m.users[user.ID] = user
35 return user, nil
36}
37
38func (m *mockUserRepository) GetByID(id int) (*users.User, error) {
39 if m.shouldFail {
40 return nil, fmt.Errorf("mock: database error")
41 }
42
43 user, exists := m.users[id]
44 if !exists {
45 return nil, fmt.Errorf("repository: user not found")
46 }
47 return user, nil
48}
49
50func (m *mockUserRepository) GetByEmail(email string) (*users.User, error) {
51 if m.shouldFail {
52 return nil, fmt.Errorf("mock: database error")
53 }
54
55 for _, user := range m.users {
56 if user.Email == email {
57 return user, nil
58 }
59 }
60 return nil, fmt.Errorf("repository: user not found")
61}
62
63func (m *mockUserRepository) GetByUsername(username string) (*users.User, error) {
64 if m.shouldFail {
65 return nil, fmt.Errorf("mock: database error")
66 }
67
68 for _, user := range m.users {
69 if user.Username == username {
70 return user, nil
71 }
72 }
73 return nil, fmt.Errorf("repository: user not found")
74}
75
76func (m *mockUserRepository) Update(user *users.User) (*users.User, error) {
77 if m.shouldFail {
78 return nil, fmt.Errorf("mock: database error")
79 }
80
81 if _, exists := m.users[user.ID]; !exists {
82 return nil, fmt.Errorf("repository: user not found")
83 }
84
85 user.UpdatedAt = time.Now()
86 m.users[user.ID] = user
87 return user, nil
88}
89
90func (m *mockUserRepository) Delete(id int) error {
91 if m.shouldFail {
92 return fmt.Errorf("mock: database error")
93 }
94
95 if _, exists := m.users[id]; !exists {
96 return fmt.Errorf("repository: user not found")
97 }
98
99 delete(m.users, id)
100 return nil
101}
102
103func TestCreateUser(t *testing.T) {
104 repo := newMockUserRepository()
105 service := users.NewUserService(repo)
106
107 tests := []struct {
108 name string
109 req users.CreateUserRequest
110 wantErr bool
111 errMsg string
112 }{
113 {
114 name: "valid user",
115 req: users.CreateUserRequest{
116 Email: "test@example.com",
117 Username: "testuser",
118 },
119 wantErr: false,
120 },
121 {
122 name: "empty email",
123 req: users.CreateUserRequest{
124 Email: "",
125 Username: "testuser",
126 },
127 wantErr: true,
128 errMsg: "email is required",
129 },
130 {
131 name: "empty username",
132 req: users.CreateUserRequest{
133 Email: "test@example.com",
134 Username: "",
135 },
136 wantErr: true,
137 errMsg: "username is required",
138 },
139 {
140 name: "invalid email format",
141 req: users.CreateUserRequest{
142 Email: "invalidemail",
143 Username: "testuser",
144 },
145 wantErr: true,
146 errMsg: "invalid email format",
147 },
148 {
149 name: "short username",
150 req: users.CreateUserRequest{
151 Email: "test@example.com",
152 Username: "ab",
153 },
154 wantErr: true,
155 errMsg: "username must be at least 3 characters",
156 },
157 }
158
159 for _, tt := range tests {
160 t.Run(tt.name, func(t *testing.T) {
161 user, err := service.CreateUser(tt.req)
162
163 if tt.wantErr {
164 if err == nil {
165 t.Errorf("expected error but got none")
166 } else if tt.errMsg != "" && err.Error() != "service: "+tt.errMsg {
167 t.Errorf("expected error message '%s' but got '%s'", tt.errMsg, err.Error())
168 }
169 } else {
170 if err != nil {
171 t.Errorf("unexpected error: %v", err)
172 }
173 if user == nil {
174 t.Errorf("expected user but got nil")
175 }
176 }
177 })
178 }
179}
180
181func TestCreateUserDuplicates(t *testing.T) {
182 repo := newMockUserRepository()
183 service := users.NewUserService(repo)
184
185 req := users.CreateUserRequest{
186 Email: "test@example.com",
187 Username: "testuser",
188 }
189
190 _, err := service.CreateUser(req)
191 if err != nil {
192 t.Fatalf("unexpected error creating first user: %v", err)
193 }
194
195 _, err = service.CreateUser(req)
196 if err == nil {
197 t.Errorf("expected error for duplicate email but got none")
198 } else if err.Error() != "service: email already exists" {
199 t.Errorf("unexpected error message: %v", err)
200 }
201
202 req2 := users.CreateUserRequest{
203 Email: "different@example.com",
204 Username: "testuser",
205 }
206
207 _, err = service.CreateUser(req2)
208 if err == nil {
209 t.Errorf("expected error for duplicate username but got none")
210 } else if err.Error() != "service: username already exists" {
211 t.Errorf("unexpected error message: %v", err)
212 }
213}
214
215func TestGetUserByID(t *testing.T) {
216 repo := newMockUserRepository()
217 service := users.NewUserService(repo)
218
219 createdUser, err := service.CreateUser(users.CreateUserRequest{
220 Email: "test@example.com",
221 Username: "testuser",
222 })
223 if err != nil {
224 t.Fatalf("failed to create user: %v", err)
225 }
226
227 tests := []struct {
228 name string
229 id int
230 wantErr bool
231 errMsg string
232 }{
233 {
234 name: "valid ID",
235 id: createdUser.ID,
236 wantErr: false,
237 },
238 {
239 name: "invalid ID",
240 id: 0,
241 wantErr: true,
242 errMsg: "invalid user ID",
243 },
244 {
245 name: "non-existent ID",
246 id: 999,
247 wantErr: true,
248 errMsg: "user not found",
249 },
250 }
251
252 for _, tt := range tests {
253 t.Run(tt.name, func(t *testing.T) {
254 user, err := service.GetUserByID(tt.id)
255
256 if tt.wantErr {
257 if err == nil {
258 t.Errorf("expected error but got none")
259 } else if tt.errMsg != "" && err.Error() != "service: "+tt.errMsg {
260 t.Errorf("expected error message '%s' but got '%s'", tt.errMsg, err.Error())
261 }
262 } else {
263 if err != nil {
264 t.Errorf("unexpected error: %v", err)
265 }
266 if user == nil {
267 t.Errorf("expected user but got nil")
268 }
269 }
270 })
271 }
272}