test(api): build deletion queue users from the real row type (#2303)

This commit is contained in:
Hampus authored and GitHub committed 2026-09-01 00:57:41 +02:00
1 parent 5da4d24d38
commit 0cd12b2f32
4 files changed
+44 -43

No files matched your search

@@ -2,8 +2,9 @@
import {describe, expect, it} from 'vitest';
import {createUserID} from '../../BrandedTypes';
import {EMPTY_USER_ROW} from '../../database/types/UserTypes';
import {KVAccountDeletionQueueService} from '../../infrastructure/KVAccountDeletionQueueService';
import type {User} from '../../models/User';
import {User} from '../../models/User';
import {MockKVProvider} from '../../test/mocks/MockKVProvider';
import {NoopLogger} from '../../test/mocks/NoopLogger';
import type {UserRepository} from '../../user/repositories/UserRepository';
@@ -12,11 +13,12 @@ import {ensureDeletionQueueState} from '../DeletionQueueStartup';
const WORKER_PAGE_COUNT = 2;
function createPendingUser(index: number): User {
return {
id: createUserID(BigInt(9100 + index)),
pendingDeletionAt: new Date('2026-06-01T00:00:00.000Z'),
deletionReasonCode: 0,
} as unknown as User;
return new User({
...EMPTY_USER_ROW,
user_id: createUserID(BigInt(9100 + index)),
pending_deletion_at: new Date('2026-06-01T00:00:00.000Z'),
deletion_reason_code: 0,
});
}
function createWorkerRepository(onPageStart: (page: number) => Promise<void>): UserRepository {
@@ -3,19 +3,21 @@
import {UserFlags} from '@fluxer/constants/src/UserConstants';
import {describe, expect, it} from 'vitest';
import {createUserID} from '../../BrandedTypes';
import type {User} from '../../models/User';
import {EMPTY_USER_ROW, type UserRow} from '../../database/types/UserTypes';
import {User} from '../../models/User';
import {MockKVProvider} from '../../test/mocks/MockKVProvider';
import type {UserRepository} from '../../user/repositories/UserRepository';
import {KVAccountDeletionQueueService} from '../KVAccountDeletionQueueService';
function createUser(id: bigint, overrides: Partial<Pick<User, 'isBot' | 'flags'>> = {}): User {
return {
id: createUserID(id),
pendingDeletionAt: new Date('2026-06-01T00:00:00.000Z'),
deletionReasonCode: 0,
isBot: overrides.isBot ?? false,
function createUser(id: bigint, overrides: Partial<Pick<UserRow, 'bot' | 'flags'>> = {}): User {
return new User({
...EMPTY_USER_ROW,
user_id: createUserID(id),
pending_deletion_at: new Date('2026-06-01T00:00:00.000Z'),
deletion_reason_code: 0,
bot: overrides.bot ?? false,
flags: overrides.flags ?? 0n,
} as unknown as User;
});
}
function createUserRepository(users: Array<User>): UserRepository {
@@ -34,11 +36,7 @@ function createUserRepository(users: Array<User>): UserRepository {
describe('KVAccountDeletionQueueService rebuild', () => {
it('does not requeue accounts the deletion worker refuses to process', async () => {
const kvClient = new MockKVProvider();
const users = [
createUser(1n, {isBot: true}),
createUser(2n, {flags: UserFlags.APP_STORE_REVIEWER}),
createUser(3n),
];
const users = [createUser(1n, {bot: true}), createUser(2n, {flags: UserFlags.APP_STORE_REVIEWER}), createUser(3n)];
const service = new KVAccountDeletionQueueService(kvClient, createUserRepository(users));
await service.rebuildState();
@@ -3,7 +3,8 @@
import {ms} from 'itty-time';
import {afterEach, describe, expect, it, vi} from 'vitest';
import {createUserID} from '../../BrandedTypes';
import type {User} from '../../models/User';
import {EMPTY_USER_ROW} from '../../database/types/UserTypes';
import {User} from '../../models/User';
import {MockKVProvider} from '../../test/mocks/MockKVProvider';
import type {UserRepository} from '../../user/repositories/UserRepository';
import {KVAccountDeletionQueueService} from '../KVAccountDeletionQueueService';
@@ -12,13 +13,14 @@ const PAGE_DURATION_MS = ms('3 minutes');
const PAGE_COUNT = 3;
function createPendingUser(index: number): User {
return {
id: createUserID(BigInt(7000 + index)),
pendingDeletionAt: new Date('2026-06-01T00:00:00.000Z'),
deletionReasonCode: 0,
isBot: false,
return new User({
...EMPTY_USER_ROW,
user_id: createUserID(BigInt(7000 + index)),
pending_deletion_at: new Date('2026-06-01T00:00:00.000Z'),
deletion_reason_code: 0,
bot: false,
flags: 0n,
} as unknown as User;
});
}
function createSlowUserRepository(): UserRepository {
@@ -5,27 +5,28 @@ import type {IWorkerService} from '@pkgs/worker/src/contracts/IWorkerService';
import type {WorkerTaskHelpers} from '@pkgs/worker/src/contracts/WorkerTask';
import {afterEach, describe, expect, test} from 'vitest';
import {createUserID, type UserID} from '../../BrandedTypes';
import {EMPTY_USER_ROW, type UserRow} from '../../database/types/UserTypes';
import {KVAccountDeletionQueueService} from '../../infrastructure/KVAccountDeletionQueueService';
import type {User} from '../../models/User';
import {User} from '../../models/User';
import {MockKVProvider} from '../../test/mocks/MockKVProvider';
import {NoopLogger} from '../../test/mocks/NoopLogger';
import type {UserRepository} from '../../user/repositories/UserRepository';
import userProcessPendingDeletions from '../tasks/UserProcessPendingDeletions';
import {clearWorkerDependencies, setWorkerDependenciesForTest} from '../WorkerContext';
interface FakeUserOptions {
isBot?: boolean;
flags?: bigint;
}
function createFakeUser(userId: UserID, pendingDeletionAt: Date, options: FakeUserOptions = {}): User {
return {
id: userId,
pendingDeletionAt,
deletionReasonCode: 1,
isBot: options.isBot ?? false,
function createFakeUser(
userId: UserID,
pendingDeletionAt: Date,
options: Partial<Pick<UserRow, 'bot' | 'flags'>> = {},
): User {
return new User({
...EMPTY_USER_ROW,
user_id: userId,
pending_deletion_at: pendingDeletionAt,
deletion_reason_code: 1,
bot: options.bot ?? false,
flags: options.flags ?? 0n,
} as unknown as User;
});
}
async function createHarness(users: Array<User>) {
@@ -83,9 +84,7 @@ describe('userProcessPendingDeletions', () => {
const users: Array<User> = [];
for (let i = 0; i < 1000; i++) {
const userId = createUserID(BigInt(100_000 + i));
users.push(
createFakeUser(userId, skippedAt, i % 2 === 0 ? {isBot: true} : {flags: UserFlags.APP_STORE_REVIEWER}),
);
users.push(createFakeUser(userId, skippedAt, i % 2 === 0 ? {bot: true} : {flags: UserFlags.APP_STORE_REVIEWER}));
}
const genuineUserId = createUserID(999_999n);
users.push(createFakeUser(genuineUserId, genuineAt));
@@ -106,7 +105,7 @@ describe('userProcessPendingDeletions', () => {
const botId = createUserID(1n);
const reviewerId = createUserID(2n);
const harness = await createHarness([
createFakeUser(botId, pendingAt, {isBot: true}),
createFakeUser(botId, pendingAt, {bot: true}),
createFakeUser(reviewerId, pendingAt, {flags: UserFlags.APP_STORE_REVIEWER}),
]);