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}