Migrate Auth/Contractor/Document/Notification/Subscription services to ctx
Every public method on these five services now takes ctx context.Context as the first arg and routes its repo calls through .WithContext(ctx). With TaskService and ResidenceService already migrated, this means every in-process service that touches Postgres now produces a flame graph in Jaeger where the SQL spans nest under the parent HTTP request span. Endpoints now fully traced (HTTP → service → SQL): - /api/auth/login, /register, /logout, /me, /verify-email, /resend-verification - /api/auth/forgot-password, /verify-reset, /reset-password, /update-profile - /api/contractors/* (CRUD + favorite + by-residence + tasks) - /api/documents/* (CRUD + activate/deactivate + image upload/delete) - /api/notifications/* (list, count, mark-read, prefs, devices) - /api/subscription/* (status, purchase, cancel, triggers, promotions) - All previously-migrated /api/tasks/* and /api/residences/* paths Internal helpers also threaded: - TaskService.sendTaskCompletedNotification → forwards ctx - TaskService.UpdateUserTimezone → forwards ctx to NotificationService - ResidenceService.CreateResidence → forwards ctx to SubscriptionService.CheckLimit - NotificationService.registerAPNSDevice / registerGCMDevice → both take ctx ~75 method signatures, ~120 handler/test call sites updated. Tests pass green; the only failure is the pre-existing flaky TaskHandler_QuickComplete SQLite race that fails ~60% of runs on master. Step 3 of the observability plan is now genuinely complete: every API endpoint backed by a Go service emits a per-request flame graph with HTTP → service → SQL spans, plus B2/APNs/FCM/asynq spans where applicable. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -44,7 +44,7 @@ func TestNotificationService_GetNotifications(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
resp, err := service.GetNotifications(user.ID, 10, 0)
|
||||
resp, err := service.GetNotifications(context.Background(), user.ID, 10, 0)
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, resp, 3)
|
||||
}
|
||||
@@ -56,7 +56,7 @@ func TestNotificationService_GetNotifications_Empty(t *testing.T) {
|
||||
|
||||
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
|
||||
|
||||
resp, err := service.GetNotifications(user.ID, 10, 0)
|
||||
resp, err := service.GetNotifications(context.Background(), user.ID, 10, 0)
|
||||
require.NoError(t, err)
|
||||
assert.Empty(t, resp)
|
||||
}
|
||||
@@ -80,7 +80,7 @@ func TestNotificationService_GetNotifications_Pagination(t *testing.T) {
|
||||
}
|
||||
|
||||
// Get first 2
|
||||
resp, err := service.GetNotifications(user.ID, 2, 0)
|
||||
resp, err := service.GetNotifications(context.Background(), user.ID, 2, 0)
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, resp, 2)
|
||||
}
|
||||
@@ -107,7 +107,7 @@ func TestNotificationService_GetUnreadCount(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
count, err := service.GetUnreadCount(user.ID)
|
||||
count, err := service.GetUnreadCount(context.Background(), user.ID)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, int64(3), count)
|
||||
}
|
||||
@@ -119,7 +119,7 @@ func TestNotificationService_GetUnreadCount_Zero(t *testing.T) {
|
||||
|
||||
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
|
||||
|
||||
count, err := service.GetUnreadCount(user.ID)
|
||||
count, err := service.GetUnreadCount(context.Background(), user.ID)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, int64(0), count)
|
||||
}
|
||||
@@ -142,11 +142,11 @@ func TestNotificationService_MarkAsRead(t *testing.T) {
|
||||
err := db.Create(notif).Error
|
||||
require.NoError(t, err)
|
||||
|
||||
err = service.MarkAsRead(notif.ID, user.ID)
|
||||
err = service.MarkAsRead(context.Background(), notif.ID, user.ID)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Verify unread count is 0
|
||||
count, err := service.GetUnreadCount(user.ID)
|
||||
count, err := service.GetUnreadCount(context.Background(), user.ID)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, int64(0), count)
|
||||
}
|
||||
@@ -168,7 +168,7 @@ func TestNotificationService_MarkAsRead_WrongUser(t *testing.T) {
|
||||
err := db.Create(notif).Error
|
||||
require.NoError(t, err)
|
||||
|
||||
err = service.MarkAsRead(notif.ID, other.ID)
|
||||
err = service.MarkAsRead(context.Background(), notif.ID, other.ID)
|
||||
testutil.AssertAppError(t, err, http.StatusNotFound, "error.notification_not_found")
|
||||
}
|
||||
|
||||
@@ -179,7 +179,7 @@ func TestNotificationService_MarkAsRead_NotFound(t *testing.T) {
|
||||
|
||||
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
|
||||
|
||||
err := service.MarkAsRead(9999, user.ID)
|
||||
err := service.MarkAsRead(context.Background(), 9999, user.ID)
|
||||
testutil.AssertAppError(t, err, http.StatusNotFound, "error.notification_not_found")
|
||||
}
|
||||
|
||||
@@ -204,10 +204,10 @@ func TestNotificationService_MarkAllAsRead(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
err := service.MarkAllAsRead(user.ID)
|
||||
err := service.MarkAllAsRead(context.Background(), user.ID)
|
||||
require.NoError(t, err)
|
||||
|
||||
count, err := service.GetUnreadCount(user.ID)
|
||||
count, err := service.GetUnreadCount(context.Background(), user.ID)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, int64(0), count)
|
||||
}
|
||||
@@ -229,7 +229,7 @@ func TestNotificationService_CreateAndSendNotification(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
// Verify notification was created
|
||||
notifs, err := service.GetNotifications(user.ID, 10, 0)
|
||||
notifs, err := service.GetNotifications(context.Background(), user.ID, 10, 0)
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, notifs, 1)
|
||||
assert.Equal(t, "Due Soon", notifs[0].Title)
|
||||
@@ -254,7 +254,7 @@ func TestNotificationService_CreateAndSendNotification_DisabledPreference(t *tes
|
||||
require.NoError(t, err)
|
||||
|
||||
// Verify no notification was created (silently skipped)
|
||||
notifs, err := service.GetNotifications(user.ID, 10, 0)
|
||||
notifs, err := service.GetNotifications(context.Background(), user.ID, 10, 0)
|
||||
require.NoError(t, err)
|
||||
assert.Empty(t, notifs)
|
||||
}
|
||||
@@ -268,7 +268,7 @@ func TestNotificationService_GetPreferences(t *testing.T) {
|
||||
|
||||
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
|
||||
|
||||
resp, err := service.GetPreferences(user.ID)
|
||||
resp, err := service.GetPreferences(context.Background(), user.ID)
|
||||
require.NoError(t, err)
|
||||
assert.NotNil(t, resp)
|
||||
// Defaults should all be true
|
||||
@@ -289,7 +289,7 @@ func TestNotificationService_UpdatePreferences(t *testing.T) {
|
||||
TaskDueSoon: &falseVal,
|
||||
}
|
||||
|
||||
resp, err := service.UpdatePreferences(user.ID, req)
|
||||
resp, err := service.UpdatePreferences(context.Background(), user.ID, req)
|
||||
require.NoError(t, err)
|
||||
assert.False(t, resp.TaskDueSoon)
|
||||
assert.True(t, resp.TaskOverdue) // unchanged
|
||||
@@ -307,7 +307,7 @@ func TestNotificationService_UpdatePreferences_InvalidHour(t *testing.T) {
|
||||
TaskDueSoonHour: &invalidHour,
|
||||
}
|
||||
|
||||
_, err := service.UpdatePreferences(user.ID, req)
|
||||
_, err := service.UpdatePreferences(context.Background(), user.ID, req)
|
||||
testutil.AssertAppErrorCode(t, err, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
@@ -323,7 +323,7 @@ func TestNotificationService_UpdatePreferences_ValidHour(t *testing.T) {
|
||||
TaskDueSoonHour: &hour,
|
||||
}
|
||||
|
||||
resp, err := service.UpdatePreferences(user.ID, req)
|
||||
resp, err := service.UpdatePreferences(context.Background(), user.ID, req)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 9, *resp.TaskDueSoonHour)
|
||||
}
|
||||
@@ -344,7 +344,7 @@ func TestNotificationService_RegisterDevice_iOS(t *testing.T) {
|
||||
Platform: push.PlatformIOS,
|
||||
}
|
||||
|
||||
resp, err := service.RegisterDevice(user.ID, req)
|
||||
resp, err := service.RegisterDevice(context.Background(), user.ID, req)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "iPhone 15", resp.Name)
|
||||
assert.Equal(t, push.PlatformIOS, resp.Platform)
|
||||
@@ -365,7 +365,7 @@ func TestNotificationService_RegisterDevice_Android(t *testing.T) {
|
||||
Platform: push.PlatformAndroid,
|
||||
}
|
||||
|
||||
resp, err := service.RegisterDevice(user.ID, req)
|
||||
resp, err := service.RegisterDevice(context.Background(), user.ID, req)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "Pixel 8", resp.Name)
|
||||
assert.Equal(t, push.PlatformAndroid, resp.Platform)
|
||||
@@ -386,7 +386,7 @@ func TestNotificationService_RegisterDevice_InvalidPlatform(t *testing.T) {
|
||||
Platform: "windows",
|
||||
}
|
||||
|
||||
_, err := service.RegisterDevice(user.ID, req)
|
||||
_, err := service.RegisterDevice(context.Background(), user.ID, req)
|
||||
testutil.AssertAppError(t, err, http.StatusBadRequest, "error.invalid_platform")
|
||||
}
|
||||
|
||||
@@ -404,12 +404,12 @@ func TestNotificationService_RegisterDevice_UpdateExisting(t *testing.T) {
|
||||
RegistrationID: "token-xyz",
|
||||
Platform: push.PlatformIOS,
|
||||
}
|
||||
_, err := service.RegisterDevice(user.ID, req)
|
||||
_, err := service.RegisterDevice(context.Background(), user.ID, req)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Re-register with same token (should update, not duplicate)
|
||||
req.Name = "iPhone 15 Pro"
|
||||
resp, err := service.RegisterDevice(user.ID, req)
|
||||
resp, err := service.RegisterDevice(context.Background(), user.ID, req)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "iPhone 15 Pro", resp.Name)
|
||||
}
|
||||
@@ -445,7 +445,7 @@ func TestNotificationService_ListDevices(t *testing.T) {
|
||||
err = db.Create(androidDevice).Error
|
||||
require.NoError(t, err)
|
||||
|
||||
resp, err := service.ListDevices(user.ID)
|
||||
resp, err := service.ListDevices(context.Background(), user.ID)
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, resp, 2)
|
||||
}
|
||||
@@ -457,7 +457,7 @@ func TestNotificationService_ListDevices_Empty(t *testing.T) {
|
||||
|
||||
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
|
||||
|
||||
resp, err := service.ListDevices(user.ID)
|
||||
resp, err := service.ListDevices(context.Background(), user.ID)
|
||||
require.NoError(t, err)
|
||||
assert.Empty(t, resp)
|
||||
}
|
||||
@@ -471,7 +471,7 @@ func TestDeleteDevice_InvalidPlatform_Returns400(t *testing.T) {
|
||||
|
||||
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
|
||||
|
||||
err := service.DeleteDevice(1, "windows", user.ID)
|
||||
err := service.DeleteDevice(context.Background(), 1, "windows", user.ID)
|
||||
testutil.AssertAppError(t, err, http.StatusBadRequest, "error.invalid_platform")
|
||||
}
|
||||
|
||||
@@ -494,7 +494,7 @@ func TestNotificationService_UnregisterDevice_iOS(t *testing.T) {
|
||||
err := db.Create(device).Error
|
||||
require.NoError(t, err)
|
||||
|
||||
err = service.UnregisterDevice("reg-token-ios", push.PlatformIOS, user.ID)
|
||||
err = service.UnregisterDevice(context.Background(), "reg-token-ios", push.PlatformIOS, user.ID)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Verify device is deactivated
|
||||
@@ -522,7 +522,7 @@ func TestNotificationService_UnregisterDevice_Android(t *testing.T) {
|
||||
err := db.Create(device).Error
|
||||
require.NoError(t, err)
|
||||
|
||||
err = service.UnregisterDevice("reg-token-android", push.PlatformAndroid, user.ID)
|
||||
err = service.UnregisterDevice(context.Background(), "reg-token-android", push.PlatformAndroid, user.ID)
|
||||
require.NoError(t, err)
|
||||
|
||||
var found models.GCMDevice
|
||||
@@ -538,7 +538,7 @@ func TestNotificationService_UnregisterDevice_NotFound(t *testing.T) {
|
||||
|
||||
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
|
||||
|
||||
err := service.UnregisterDevice("nonexistent-token", push.PlatformIOS, user.ID)
|
||||
err := service.UnregisterDevice(context.Background(), "nonexistent-token", push.PlatformIOS, user.ID)
|
||||
testutil.AssertAppError(t, err, http.StatusNotFound, "error.device_not_found")
|
||||
}
|
||||
|
||||
@@ -560,7 +560,7 @@ func TestNotificationService_UnregisterDevice_WrongUser(t *testing.T) {
|
||||
err := db.Create(device).Error
|
||||
require.NoError(t, err)
|
||||
|
||||
err = service.UnregisterDevice("owner-token", push.PlatformIOS, attacker.ID)
|
||||
err = service.UnregisterDevice(context.Background(), "owner-token", push.PlatformIOS, attacker.ID)
|
||||
testutil.AssertAppError(t, err, http.StatusNotFound, "error.device_not_found")
|
||||
}
|
||||
|
||||
@@ -571,7 +571,7 @@ func TestNotificationService_UnregisterDevice_InvalidPlatform(t *testing.T) {
|
||||
|
||||
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
|
||||
|
||||
err := service.UnregisterDevice("some-token", "windows", user.ID)
|
||||
err := service.UnregisterDevice(context.Background(), "some-token", "windows", user.ID)
|
||||
testutil.AssertAppError(t, err, http.StatusBadRequest, "error.invalid_platform")
|
||||
}
|
||||
|
||||
@@ -585,7 +585,7 @@ func TestNotificationService_UpdateUserTimezone(t *testing.T) {
|
||||
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
|
||||
|
||||
// Should not panic, just silently update
|
||||
service.UpdateUserTimezone(user.ID, "America/Los_Angeles")
|
||||
service.UpdateUserTimezone(context.Background(), user.ID, "America/Los_Angeles")
|
||||
|
||||
// Verify timezone was stored
|
||||
prefs, err := notifRepo.GetOrCreatePreferences(user.ID)
|
||||
@@ -602,7 +602,7 @@ func TestNotificationService_UpdateUserTimezone_Invalid(t *testing.T) {
|
||||
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
|
||||
|
||||
// Invalid timezone should be silently ignored
|
||||
service.UpdateUserTimezone(user.ID, "Invalid/Timezone")
|
||||
service.UpdateUserTimezone(context.Background(), user.ID, "Invalid/Timezone")
|
||||
|
||||
prefs, err := notifRepo.GetOrCreatePreferences(user.ID)
|
||||
require.NoError(t, err)
|
||||
@@ -617,10 +617,10 @@ func TestNotificationService_UpdateUserTimezone_NoChangeSkipsWrite(t *testing.T)
|
||||
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
|
||||
|
||||
// Set timezone
|
||||
service.UpdateUserTimezone(user.ID, "America/New_York")
|
||||
service.UpdateUserTimezone(context.Background(), user.ID, "America/New_York")
|
||||
|
||||
// Set same timezone again — should be a no-op
|
||||
service.UpdateUserTimezone(user.ID, "America/New_York")
|
||||
service.UpdateUserTimezone(context.Background(), user.ID, "America/New_York")
|
||||
|
||||
prefs, err := notifRepo.GetOrCreatePreferences(user.ID)
|
||||
require.NoError(t, err)
|
||||
@@ -648,7 +648,7 @@ func TestDeleteDevice_WrongUser_Returns403(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
// Attacker tries to deactivate the owner's device
|
||||
err = service.DeleteDevice(device.ID, push.PlatformIOS, attacker.ID)
|
||||
err = service.DeleteDevice(context.Background(), device.ID, push.PlatformIOS, attacker.ID)
|
||||
require.Error(t, err, "should not allow deleting another user's device")
|
||||
testutil.AssertAppErrorCode(t, err, http.StatusForbidden)
|
||||
|
||||
@@ -678,7 +678,7 @@ func TestDeleteDevice_CorrectUser_Succeeds(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
// Owner deactivates their own device
|
||||
err = service.DeleteDevice(device.ID, push.PlatformIOS, owner.ID)
|
||||
err = service.DeleteDevice(context.Background(), device.ID, push.PlatformIOS, owner.ID)
|
||||
require.NoError(t, err, "owner should be able to deactivate their own device")
|
||||
|
||||
// Verify the device is now inactive
|
||||
@@ -709,7 +709,7 @@ func TestDeleteDevice_WrongUser_Android_Returns403(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
// Attacker tries to deactivate the owner's Android device
|
||||
err = service.DeleteDevice(device.ID, push.PlatformAndroid, attacker.ID)
|
||||
err = service.DeleteDevice(context.Background(), device.ID, push.PlatformAndroid, attacker.ID)
|
||||
require.Error(t, err, "should not allow deleting another user's Android device")
|
||||
testutil.AssertAppErrorCode(t, err, http.StatusForbidden)
|
||||
|
||||
@@ -727,7 +727,7 @@ func TestDeleteDevice_NonExistent_Returns404(t *testing.T) {
|
||||
|
||||
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "password")
|
||||
|
||||
err := service.DeleteDevice(99999, push.PlatformIOS, user.ID)
|
||||
err := service.DeleteDevice(context.Background(), 99999, push.PlatformIOS, user.ID)
|
||||
require.Error(t, err, "should return error for non-existent device")
|
||||
testutil.AssertAppErrorCode(t, err, http.StatusNotFound)
|
||||
}
|
||||
@@ -744,7 +744,7 @@ func TestNotificationService_CreateAndSend_TaskOverdue(t *testing.T) {
|
||||
err := service.CreateAndSendNotification(context.Background(), user.ID, models.NotificationTaskOverdue, "Overdue", "Task is overdue", nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
notifs, err := service.GetNotifications(user.ID, 10, 0)
|
||||
notifs, err := service.GetNotifications(context.Background(), user.ID, 10, 0)
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, notifs, 1)
|
||||
assert.Equal(t, "Overdue", notifs[0].Title)
|
||||
@@ -760,7 +760,7 @@ func TestNotificationService_CreateAndSend_TaskCompleted(t *testing.T) {
|
||||
err := service.CreateAndSendNotification(context.Background(), user.ID, models.NotificationTaskCompleted, "Completed", "Task done", nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
notifs, err := service.GetNotifications(user.ID, 10, 0)
|
||||
notifs, err := service.GetNotifications(context.Background(), user.ID, 10, 0)
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, notifs, 1)
|
||||
}
|
||||
@@ -775,7 +775,7 @@ func TestNotificationService_CreateAndSend_TaskAssigned(t *testing.T) {
|
||||
err := service.CreateAndSendNotification(context.Background(), user.ID, models.NotificationTaskAssigned, "Assigned", "Task assigned to you", nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
notifs, err := service.GetNotifications(user.ID, 10, 0)
|
||||
notifs, err := service.GetNotifications(context.Background(), user.ID, 10, 0)
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, notifs, 1)
|
||||
}
|
||||
@@ -790,7 +790,7 @@ func TestNotificationService_CreateAndSend_ResidenceShared(t *testing.T) {
|
||||
err := service.CreateAndSendNotification(context.Background(), user.ID, models.NotificationResidenceShared, "Shared", "Someone shared a home", nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
notifs, err := service.GetNotifications(user.ID, 10, 0)
|
||||
notifs, err := service.GetNotifications(context.Background(), user.ID, 10, 0)
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, notifs, 1)
|
||||
}
|
||||
@@ -805,7 +805,7 @@ func TestNotificationService_CreateAndSend_WarrantyExpiring(t *testing.T) {
|
||||
err := service.CreateAndSendNotification(context.Background(), user.ID, models.NotificationWarrantyExpiring, "Expiring", "Warranty expiring soon", nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
notifs, err := service.GetNotifications(user.ID, 10, 0)
|
||||
notifs, err := service.GetNotifications(context.Background(), user.ID, 10, 0)
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, notifs, 1)
|
||||
}
|
||||
@@ -828,7 +828,7 @@ func TestNotificationService_DisabledPrefs_TaskOverdue(t *testing.T) {
|
||||
err = service.CreateAndSendNotification(context.Background(), user.ID, models.NotificationTaskOverdue, "Overdue", "Overdue task", nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
notifs, err := service.GetNotifications(user.ID, 10, 0)
|
||||
notifs, err := service.GetNotifications(context.Background(), user.ID, 10, 0)
|
||||
require.NoError(t, err)
|
||||
assert.Empty(t, notifs)
|
||||
}
|
||||
@@ -849,7 +849,7 @@ func TestNotificationService_DisabledPrefs_TaskCompleted(t *testing.T) {
|
||||
err = service.CreateAndSendNotification(context.Background(), user.ID, models.NotificationTaskCompleted, "Completed", "Task done", nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
notifs, err := service.GetNotifications(user.ID, 10, 0)
|
||||
notifs, err := service.GetNotifications(context.Background(), user.ID, 10, 0)
|
||||
require.NoError(t, err)
|
||||
assert.Empty(t, notifs)
|
||||
}
|
||||
@@ -870,7 +870,7 @@ func TestNotificationService_DisabledPrefs_TaskAssigned(t *testing.T) {
|
||||
err = service.CreateAndSendNotification(context.Background(), user.ID, models.NotificationTaskAssigned, "Assigned", "Task assigned", nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
notifs, err := service.GetNotifications(user.ID, 10, 0)
|
||||
notifs, err := service.GetNotifications(context.Background(), user.ID, 10, 0)
|
||||
require.NoError(t, err)
|
||||
assert.Empty(t, notifs)
|
||||
}
|
||||
@@ -891,7 +891,7 @@ func TestNotificationService_DisabledPrefs_ResidenceShared(t *testing.T) {
|
||||
err = service.CreateAndSendNotification(context.Background(), user.ID, models.NotificationResidenceShared, "Shared", "Home shared", nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
notifs, err := service.GetNotifications(user.ID, 10, 0)
|
||||
notifs, err := service.GetNotifications(context.Background(), user.ID, 10, 0)
|
||||
require.NoError(t, err)
|
||||
assert.Empty(t, notifs)
|
||||
}
|
||||
@@ -912,7 +912,7 @@ func TestNotificationService_DisabledPrefs_WarrantyExpiring(t *testing.T) {
|
||||
err = service.CreateAndSendNotification(context.Background(), user.ID, models.NotificationWarrantyExpiring, "Warranty", "Expiring", nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
notifs, err := service.GetNotifications(user.ID, 10, 0)
|
||||
notifs, err := service.GetNotifications(context.Background(), user.ID, 10, 0)
|
||||
require.NoError(t, err)
|
||||
assert.Empty(t, notifs)
|
||||
}
|
||||
@@ -929,7 +929,7 @@ func TestNotificationService_CreateAndSend_UnknownTypeDefaultsEnabled(t *testing
|
||||
err := service.CreateAndSendNotification(context.Background(), user.ID, models.NotificationType("unknown_type"), "Unknown", "Unknown notification", nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
notifs, err := service.GetNotifications(user.ID, 10, 0)
|
||||
notifs, err := service.GetNotifications(context.Background(), user.ID, 10, 0)
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, notifs, 1)
|
||||
}
|
||||
@@ -953,7 +953,7 @@ func TestNotificationService_CreateAndSend_WithMixedDataTypes(t *testing.T) {
|
||||
err := service.CreateAndSendNotification(context.Background(), user.ID, models.NotificationTaskDueSoon, "Due Soon", "Fix faucet", data)
|
||||
require.NoError(t, err)
|
||||
|
||||
notifs, err := service.GetNotifications(user.ID, 10, 0)
|
||||
notifs, err := service.GetNotifications(context.Background(), user.ID, 10, 0)
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, notifs, 1)
|
||||
assert.NotNil(t, notifs[0].Data)
|
||||
@@ -985,7 +985,7 @@ func TestNotificationService_UpdatePreferences_MultipleFields(t *testing.T) {
|
||||
TaskOverdueHour: &hour14,
|
||||
}
|
||||
|
||||
resp, err := service.UpdatePreferences(user.ID, req)
|
||||
resp, err := service.UpdatePreferences(context.Background(), user.ID, req)
|
||||
require.NoError(t, err)
|
||||
assert.False(t, resp.TaskDueSoon)
|
||||
assert.False(t, resp.TaskOverdue)
|
||||
@@ -1013,7 +1013,7 @@ func TestNotificationService_UpdatePreferences_NegativeHour(t *testing.T) {
|
||||
TaskOverdueHour: &negHour,
|
||||
}
|
||||
|
||||
_, err := service.UpdatePreferences(user.ID, req)
|
||||
_, err := service.UpdatePreferences(context.Background(), user.ID, req)
|
||||
testutil.AssertAppErrorCode(t, err, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
@@ -1032,12 +1032,12 @@ func TestNotificationService_RegisterDevice_UpdateExistingAndroid(t *testing.T)
|
||||
RegistrationID: "token-android-1",
|
||||
Platform: push.PlatformAndroid,
|
||||
}
|
||||
_, err := service.RegisterDevice(user.ID, req)
|
||||
_, err := service.RegisterDevice(context.Background(), user.ID, req)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Re-register with same token but new name
|
||||
req.Name = "Pixel 8 Pro"
|
||||
resp, err := service.RegisterDevice(user.ID, req)
|
||||
resp, err := service.RegisterDevice(context.Background(), user.ID, req)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "Pixel 8 Pro", resp.Name)
|
||||
assert.Equal(t, push.PlatformAndroid, resp.Platform)
|
||||
@@ -1052,7 +1052,7 @@ func TestDeleteDevice_AndroidNotFound_Returns404(t *testing.T) {
|
||||
|
||||
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
|
||||
|
||||
err := service.DeleteDevice(99999, push.PlatformAndroid, user.ID)
|
||||
err := service.DeleteDevice(context.Background(), 99999, push.PlatformAndroid, user.ID)
|
||||
testutil.AssertAppErrorCode(t, err, http.StatusNotFound)
|
||||
}
|
||||
|
||||
@@ -1076,7 +1076,7 @@ func TestDeleteDevice_CorrectUser_Android_Succeeds(t *testing.T) {
|
||||
err := db.Create(device).Error
|
||||
require.NoError(t, err)
|
||||
|
||||
err = service.DeleteDevice(device.ID, push.PlatformAndroid, owner.ID)
|
||||
err = service.DeleteDevice(context.Background(), device.ID, push.PlatformAndroid, owner.ID)
|
||||
require.NoError(t, err)
|
||||
|
||||
var found models.GCMDevice
|
||||
@@ -1106,7 +1106,7 @@ func TestNotificationService_UnregisterDevice_WrongUser_Android(t *testing.T) {
|
||||
err := db.Create(device).Error
|
||||
require.NoError(t, err)
|
||||
|
||||
err = service.UnregisterDevice("owner-android-token", push.PlatformAndroid, attacker.ID)
|
||||
err = service.UnregisterDevice(context.Background(), "owner-android-token", push.PlatformAndroid, attacker.ID)
|
||||
testutil.AssertAppError(t, err, http.StatusNotFound, "error.device_not_found")
|
||||
}
|
||||
|
||||
@@ -1119,7 +1119,7 @@ func TestNotificationService_UnregisterDevice_AndroidNotFound(t *testing.T) {
|
||||
|
||||
user := testutil.CreateTestUser(t, db, "owner", "owner@test.com", "Password123")
|
||||
|
||||
err := service.UnregisterDevice("nonexistent-android", push.PlatformAndroid, user.ID)
|
||||
err := service.UnregisterDevice(context.Background(), "nonexistent-android", push.PlatformAndroid, user.ID)
|
||||
testutil.AssertAppError(t, err, http.StatusNotFound, "error.device_not_found")
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user