Repository: MotiaDev/motia
File: packages/wistro/dev/__tests__/workflows-endpoint.test.ts (TypeScript)

Code before:
// Mock randomUUID for consistent test results
jest.mock('crypto', () => ({
  randomUUID: jest.fn(() => 'mocked-uuid'),
}));

describe('generateWorkflowsList', () => {
  it('should generate a list of workflows with steps', () => {
    const mockConfig: Config = {
      workflows: {
        workflow1: { name: 'Workflow 1' },
      },
      api: {
        paths: {
          '/path1': { name: 'Path 1', emits: 'event1', workflow: 'workflow1', method: 'GET' },
          '/path2': { name: 'Path 2', emits: 'event2', workflow: 'workflow1', method: 'POST' },
        },
        port: 3000,
      },
      cron: {
        cron1: { name: 'Cron Job 1', emits: 'event1', workflow: 'workflow1', cron: '* * * * *' },
      },
      state: {
        adapter: 'redis',
        host: 'localhost',
        port: 6379,
      }
    };

    const mockWorkflowSteps: WorkflowStep[] = [
      {
        config: {
          workflow: 'workflow1',
          name: 'Step 1',
          description: 'First step',
          emits: ['event1'],
          subscribes: [],
          input: z.object({}),
        },
        file: 'path',
        filePath: 'step1/path',
      },
      {
        config: {
          workflow: 'workflow1',
          name: 'Step 2',
          description: 'Second step',
          emits: ['event2'],
          subscribes: ['event1'],
          input: z.object({}),
        },
        file: 'path',

Review comment (suggestion):
suggestion: create a fixture for and only add the relevant test data here, because we will change this type quite often and will be annoying to remember to update it here too

Code after:
import { mockConfigWithoutTriggers, mockValidConfig } from '../../test/fixtures/mockedConfig';

// Mock randomUUID for consistent test results
jest.mock('crypto', () => ({
  randomUUID: jest.fn(() => 'mocked-uuid'),
}));

describe('generateWorkflowsList', () => {
  it('should generate a list of workflows with steps', () => {
    const result = generateWorkflowsList(mockValidConfig, mockWorkflowSteps);

    expect(result.map(({ id }) => id)).toEqual(['workflow1']);
    expect(result.map(({ steps }) => steps.map(step => step.name)).flat()).toEqual([
      'Path 1',
      'Path 2',
      'Step 1', 
      'Step 2',
      'Step 3',
      'Cron Job 1'
    ]);
  });

  it('should throw an error for missing workflow in steps', () => {
    const mockWorkflowSteps: WorkflowStep[] = [
      {
        config: {
          workflow: 'workflow2', // Invalid workflow
          name: 'Step 1',
          description: 'First step',
          emits: ['event1'],
          subscribes: [],
          input: z.object({}),
        },
        filePath: 'step1/path',
        file: 'path',
      },
    ];

    expect(() => generateWorkflowsList(mockConfigWithoutTriggers, mockWorkflowSteps)).toThrow(
      'Unknown workflow name workflow2 in step1/path, all workflows should be defined in the config.yml'
    );
  });

  it('should throw an error if no workflow steps are found for a workflow', () => {
    const mockWorkflowSteps: WorkflowStep[] = [];

    expect(() => generateWorkflowsList(mockConfigWithoutTriggers, mockWorkflowSteps)).toThrow(
      'No workflow steps found for workflow with id workflow1'
    );
  });