diff --git a/packages/shared/src/__tests__/fixtures.ts b/packages/shared/src/__tests__/fixtures.ts new file mode 100644 index 0000000..5e728e8 --- /dev/null +++ b/packages/shared/src/__tests__/fixtures.ts @@ -0,0 +1,57 @@ +/** + * Shared test fixtures for push-pipeline tests. + * + * Previously duplicated as local `makeUser` / `makeProblem` / `makeChannel` + * functions in individual test files. Centralised here so a schema change + * only needs to touch one place. + */ +import type { PushCandidate, VerifiedChannel } from '../push/push.repository.js' +import type { PushMessage, SelectedProblem } from '../types/push.js' + +export function makeUser(overrides: Partial = {}): PushCandidate { + return { + id: 'user-1', + timezone: 'Asia/Taipei', + active_mode: 'list', + difficulty_min: 0, + difficulty_max: 3000, + topic_filter: null, + line_push_allowed: true, + ...overrides, + } +} + +export function makeProblem(overrides: Partial = {}): SelectedProblem { + return { + problem_id: 42, + leetcode_id: 1, + slug: 'two-sum', + title: 'Two Sum', + difficulty: 'Easy', + explanation: 'Use a hash map.', + ...overrides, + } +} + +export function makeChannel(overrides: Partial = {}): VerifiedChannel { + return { + id: 'ch-1', + user_id: 'user-1', + channel_type: 'telegram', + channel_identifier: '123456', + ...overrides, + } +} + +export function makePushMessage(overrides: Partial = {}): PushMessage { + return { + title: 'Two Sum', + difficulty: 'Easy', + leetcodeId: 1, + explanation: 'Use a hash map.', + url: 'https://caffecode.net/problems/two-sum', + problemSlug: 'two-sum', + problemId: 42, + ...overrides, + } +} diff --git a/packages/shared/src/push/__tests__/push.pipeline.test.ts b/packages/shared/src/push/__tests__/push.pipeline.test.ts index 7b7f713..1da030d 100644 --- a/packages/shared/src/push/__tests__/push.pipeline.test.ts +++ b/packages/shared/src/push/__tests__/push.pipeline.test.ts @@ -14,13 +14,11 @@ import { stampLastPushDate, advanceListPositions, resetChannelFailures, - type PushCandidate, - type VerifiedChannel, } from '../push.repository.js' import { selectProblemForUser } from '../../services/problem-selector.js' import type { SupabaseClient } from '@supabase/supabase-js' -import type { SelectedProblem } from '../../types/push.js' import type { NotificationChannel } from '../channels/registry.js' +import { makeUser, makeProblem, makeChannel } from '../../__tests__/fixtures.js' const mockGetAllCandidates = vi.mocked(getAllCandidates) const mockGetChannels = vi.mocked(getVerifiedChannelsBulk) @@ -35,41 +33,6 @@ const db = {} as SupabaseClient // A p-limit stub that invokes the thunk immediately (no concurrency control needed in tests) const noopLimit = vi.fn((fn: () => unknown) => fn()) as unknown as LimitFunction -function makeUser(overrides: Partial = {}): PushCandidate { - return { - id: 'user-1', - timezone: 'Asia/Taipei', - active_mode: 'list', - difficulty_min: 0, - difficulty_max: 3000, - topic_filter: null, - line_push_allowed: true, - ...overrides, - } -} - -function makeProblem(overrides: Partial = {}): SelectedProblem { - return { - problem_id: 42, - leetcode_id: 1, - slug: 'two-sum', - title: 'Two Sum', - difficulty: 'Easy', - explanation: 'Use a hash map.', - ...overrides, - } -} - -function makeChannel(overrides: Partial = {}): VerifiedChannel { - return { - id: 'ch-1', - user_id: 'user-1', - channel_type: 'telegram', - channel_identifier: '123456', - ...overrides, - } -} - // Channel registry stub: dispatches succeed without real HTTP calls function makeChannelRegistry(channelTypes = ['telegram', 'email', 'line']): Record { const channel: NotificationChannel = vi.fn().mockResolvedValue({ success: true })