refac: missing mutation tests, spa specs, checks shown to pass, touch targets, catalogue entry, production code

This commit is contained in:
Florian Sylvain committed 2026-11-04 03:04:35 +01:00
1 parent 7c15206170
commit 3e02e14da4
48 files changed
+2173 -83

No files matched your search

+45 -11
View File
@@ -35,6 +35,7 @@ func (s *stubHasher) Compare(hashed string, value string) error {
}
type mockUserRepo struct {
mu sync.Mutex
users map[uint32]user.User
nextID uint32
findByIDsCalls int
@@ -60,7 +61,6 @@ type mockUserRepo struct {
beforeTransfer func()
beforeClearVerification func()
knownRoles *mockRoleRepo
confirmLock sync.Mutex
}
func newMockUserRepo() *mockUserRepo {
@@ -83,8 +83,8 @@ func (m *mockUserRepo) sortedIds() []uint32 {
}
func (m *mockUserRepo) Get(id uint32) (user.User, error) {
m.confirmLock.Lock()
defer m.confirmLock.Unlock()
m.mu.Lock()
defer m.mu.Unlock()
m.getCalls++
if err := m.fail.trigger("Get"); err != nil {
return user.User{}, err
@@ -97,6 +97,8 @@ func (m *mockUserRepo) Get(id uint32) (user.User, error) {
}
func (m *mockUserRepo) GetByUsername(username string) (user.User, error) {
m.mu.Lock()
defer m.mu.Unlock()
if err := m.fail.trigger("GetByUsername"); err != nil {
return user.User{}, err
}
@@ -110,6 +112,8 @@ func (m *mockUserRepo) GetByUsername(username string) (user.User, error) {
}
func (m *mockUserRepo) GetByEmail(email string) (user.User, error) {
m.mu.Lock()
defer m.mu.Unlock()
if err := m.fail.trigger("GetByEmail"); err != nil {
return user.User{}, err
}
@@ -123,8 +127,8 @@ func (m *mockUserRepo) GetByEmail(email string) (user.User, error) {
}
func (m *mockUserRepo) IsEmailInUse(email string, exceptUserId uint32) (bool, error) {
m.confirmLock.Lock()
defer m.confirmLock.Unlock()
m.mu.Lock()
defer m.mu.Unlock()
return m.emailInUse(email, exceptUserId)
}
@@ -141,6 +145,8 @@ func (m *mockUserRepo) emailInUse(email string, exceptUserId uint32) (bool, erro
}
func (m *mockUserRepo) SetPendingEmailChange(userId uint32, pendingEmail string, code string, expiration time.Time) (user.User, error) {
m.mu.Lock()
defer m.mu.Unlock()
if err := m.fail.trigger("SetPendingEmailChange"); err != nil {
return user.User{}, err
}
@@ -156,6 +162,8 @@ func (m *mockUserRepo) SetPendingEmailChange(userId uint32, pendingEmail string,
}
func (m *mockUserRepo) ClearPendingEmailChange(userId uint32) (user.User, error) {
m.mu.Lock()
defer m.mu.Unlock()
if err := m.fail.trigger("ClearPendingEmailChange"); err != nil {
return user.User{}, err
}
@@ -171,8 +179,8 @@ func (m *mockUserRepo) ClearPendingEmailChange(userId uint32) (user.User, error)
}
func (m *mockUserRepo) ConfirmEmailChange(userId uint32, pendingEmail string, code string, now time.Time) (user.User, error) {
m.confirmLock.Lock()
defer m.confirmLock.Unlock()
m.mu.Lock()
defer m.mu.Unlock()
if err := m.fail.trigger("ConfirmEmailChange"); err != nil {
return user.User{}, err
}
@@ -198,6 +206,8 @@ func (m *mockUserRepo) ConfirmEmailChange(userId uint32, pendingEmail string, co
}
func (m *mockUserRepo) GetAll() ([]user.User, error) {
m.mu.Lock()
defer m.mu.Unlock()
m.getAllCalls++
if err := m.fail.trigger("GetAll"); err != nil {
return nil, err
@@ -210,6 +220,8 @@ func (m *mockUserRepo) GetAll() ([]user.User, error) {
}
func (m *mockUserRepo) FindByIDs(ids []uint32) ([]user.User, error) {
m.mu.Lock()
defer m.mu.Unlock()
if err := m.fail.trigger("FindByIDs"); err != nil {
return nil, err
}
@@ -224,6 +236,8 @@ func (m *mockUserRepo) FindByIDs(ids []uint32) ([]user.User, error) {
}
func (m *mockUserRepo) Create(u user.User) (user.User, error) {
m.mu.Lock()
defer m.mu.Unlock()
if err := m.fail.trigger("Create"); err != nil {
return user.User{}, err
}
@@ -234,6 +248,8 @@ func (m *mockUserRepo) Create(u user.User) (user.User, error) {
}
func (m *mockUserRepo) Delete(id uint32) error {
m.mu.Lock()
defer m.mu.Unlock()
if err := m.fail.trigger("Delete"); err != nil {
return err
}
@@ -245,6 +261,8 @@ func (m *mockUserRepo) Delete(id uint32) error {
}
func (m *mockUserRepo) DeleteIfRole(id uint32, roleID uint32) error {
m.mu.Lock()
defer m.mu.Unlock()
m.deleteIfRoleCalls++
if err := m.fail.trigger("DeleteIfRole"); err != nil {
return err
@@ -252,7 +270,7 @@ func (m *mockUserRepo) DeleteIfRole(id uint32, roleID uint32) error {
if m.beforeDeleteIfRole != nil {
hook := m.beforeDeleteIfRole
m.beforeDeleteIfRole = nil
hook()
outsideLock(&m.mu, hook)
}
stored, ok := m.users[id]
if !ok {
@@ -266,6 +284,8 @@ func (m *mockUserRepo) DeleteIfRole(id uint32, roleID uint32) error {
}
func (m *mockUserRepo) UpdateVerificationStatus(userId uint32, isVerified bool) (user.User, error) {
m.mu.Lock()
defer m.mu.Unlock()
if err := m.fail.trigger("UpdateVerificationStatus"); err != nil {
return user.User{}, err
}
@@ -279,6 +299,8 @@ func (m *mockUserRepo) UpdateVerificationStatus(userId uint32, isVerified bool)
}
func (m *mockUserRepo) UpdatePassword(userId uint32, password string) (user.User, error) {
m.mu.Lock()
defer m.mu.Unlock()
if err := m.fail.trigger("UpdatePassword"); err != nil {
return user.User{}, err
}
@@ -292,6 +314,8 @@ func (m *mockUserRepo) UpdatePassword(userId uint32, password string) (user.User
}
func (m *mockUserRepo) UpdatePasswordResetCode(userId uint32, code string, expiration time.Time) (user.User, error) {
m.mu.Lock()
defer m.mu.Unlock()
m.updatePasswordResetCodeCalls++
m.lastUpdatePasswordResetCodeUserId = userId
m.lastUpdatePasswordResetCodeCode = code
@@ -310,6 +334,8 @@ func (m *mockUserRepo) UpdatePasswordResetCode(userId uint32, code string, expir
}
func (m *mockUserRepo) ClearVerificationCode(userId uint32) (user.User, error) {
m.mu.Lock()
defer m.mu.Unlock()
m.clearVerificationCodeCalls++
m.clearVerificationCodeUserIds = append(m.clearVerificationCodeUserIds, userId)
if err := m.fail.trigger("ClearVerificationCode"); err != nil {
@@ -318,7 +344,7 @@ func (m *mockUserRepo) ClearVerificationCode(userId uint32) (user.User, error) {
if m.beforeClearVerification != nil {
hook := m.beforeClearVerification
m.beforeClearVerification = nil
hook()
outsideLock(&m.mu, hook)
}
u, ok := m.users[userId]
if !ok {
@@ -338,6 +364,8 @@ func (m *mockUserRepo) ClearVerificationCode(userId uint32) (user.User, error) {
}
func (m *mockUserRepo) ResetPassword(userId uint32, hashedPassword string) (user.User, error) {
m.mu.Lock()
defer m.mu.Unlock()
m.resetPasswordCalls++
m.lastResetPasswordUserId = userId
m.lastResetPasswordHash = hashedPassword
@@ -357,6 +385,8 @@ func (m *mockUserRepo) ResetPassword(userId uint32, hashedPassword string) (user
}
func (m *mockUserRepo) UpdateDisplayName(userId uint32, displayName string) (user.User, error) {
m.mu.Lock()
defer m.mu.Unlock()
m.updateDisplayNameCalls++
m.lastUpdateDisplayName = displayName
if err := m.fail.trigger("UpdateDisplayName"); err != nil {
@@ -380,6 +410,8 @@ func (m *mockUserRepo) roleExists(id uint32) bool {
}
func (m *mockUserRepo) UpdateRole(id uint32, from uint32, to uint32, assignedBy uint32) (user.User, error) {
m.mu.Lock()
defer m.mu.Unlock()
m.updateRoleCalls++
if err := m.fail.trigger("UpdateRole"); err != nil {
return user.User{}, err
@@ -387,7 +419,7 @@ func (m *mockUserRepo) UpdateRole(id uint32, from uint32, to uint32, assignedBy
if m.beforeUpdateRole != nil {
hook := m.beforeUpdateRole
m.beforeUpdateRole = nil
hook()
outsideLock(&m.mu, hook)
}
stored, ok := m.users[id]
if !ok {
@@ -406,6 +438,8 @@ func (m *mockUserRepo) UpdateRole(id uint32, from uint32, to uint32, assignedBy
}
func (m *mockUserRepo) TransferOwnership(from uint32, to uint32, ownerRoleID uint32, formerRoleID uint32) error {
m.mu.Lock()
defer m.mu.Unlock()
m.transferCalls++
if err := m.fail.trigger("TransferOwnership"); err != nil {
return err
@@ -413,7 +447,7 @@ func (m *mockUserRepo) TransferOwnership(from uint32, to uint32, ownerRoleID uin
if m.beforeTransfer != nil {
hook := m.beforeTransfer
m.beforeTransfer = nil
hook()
outsideLock(&m.mu, hook)
}
former, formerFound := m.users[from]
if !formerFound || former.RoleID != ownerRoleID {