Files
stack/apps/api/test/fixtures/mock-discord.fixture.ts
Jason Woltje 3cdcbf6774 feat(#175): Implement E2E test harness
- Create comprehensive E2E test suite for job orchestration
- Add test fixtures for Discord, BullMQ, and Prisma mocks
- Implement 9 end-to-end test scenarios covering:
  * Happy path: webhook → job → step execution → completion
  * Event emission throughout job lifecycle
  * Step failure and retry handling
  * Job failure after max retries
  * Discord command parsing and job creation
  * WebSocket status updates integration
  * Job cancellation workflow
  * Job retry mechanism
  * Progress percentage tracking

- Add helper methods to services for simplified testing:
  * JobStepsService: start(), complete(), fail(), findByJob()
  * RunnerJobsService: updateStatus(), updateProgress()
  * JobEventsService: findByJob()

- Configure vitest.e2e.config.ts for E2E test execution
- All 9 E2E tests passing
- All 1405 unit tests passing
- Quality gates: typecheck, lint, build all passing

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 21:44:04 -06:00

73 lines
1.7 KiB
TypeScript

import { vi } from "vitest";
import type { Client, Message, TextChannel } from "discord.js";
/**
* Mock Discord client for testing
*/
export function createMockDiscordClient(): Partial<Client> {
const mockChannel: Partial<TextChannel> = {
send: vi.fn().mockResolvedValue({
id: "mock-message-id",
content: "Mock message sent",
}),
id: "mock-channel-id",
name: "test-channel",
};
return {
channels: {
fetch: vi.fn().mockResolvedValue(mockChannel),
cache: {
get: vi.fn().mockReturnValue(mockChannel),
},
} as never,
on: vi.fn(),
once: vi.fn(),
login: vi.fn().mockResolvedValue("mock-token"),
destroy: vi.fn().mockResolvedValue(undefined),
};
}
/**
* Mock Discord message for testing command parsing
*/
export function createMockDiscordMessage(
content: string,
overrides?: Partial<Message>
): Partial<Message> {
return {
content,
author: {
id: "mock-user-id",
username: "test-user",
bot: false,
discriminator: "0001",
avatar: null,
tag: "test-user#0001",
} as never,
channel: {
id: "mock-channel-id",
type: 0, // GuildText
send: vi.fn().mockResolvedValue({
id: "response-message-id",
content: "Response sent",
}),
} as never,
guild: {
id: "mock-guild-id",
name: "Test Guild",
} as never,
createdTimestamp: Date.now(),
id: "mock-message-id",
mentions: {
has: vi.fn().mockReturnValue(false),
users: new Map(),
} as never,
reply: vi.fn().mockResolvedValue({
id: "reply-message-id",
content: "Reply sent",
}),
...overrides,
};
}