import type { Response } from 'supertest';
import { E2E_ROLE_LIST, type E2ERole } from '../fixtures/e2e-roles.js';
import type { E2EAccessTokenMap } from './e2e-auth.helper.js';

interface RoleMatrixCase {
  name: string;
  tokens: E2EAccessTokenMap;
  expectedStatusByRole: Record<E2ERole, number>;
  sendAsRole: (role: E2ERole, token: string) => Promise<Response>;
  sendWithoutToken: () => Promise<Response>;
  expectedStatusWithoutToken?: number;
}

export async function assertRoleMatrix(matrixCase: RoleMatrixCase) {
  for (const role of E2E_ROLE_LIST) {
    const response = await matrixCase.sendAsRole(role, matrixCase.tokens[role]);
    const expectedStatus = matrixCase.expectedStatusByRole[role];
    const isSuccess = expectedStatus >= 200 && expectedStatus < 300;

    expect(response.status).toBe(expectedStatus);
    expect(response.body.code).toBe(isSuccess ? 0 : expectedStatus);
  }

  const unauthorizedResponse = await matrixCase.sendWithoutToken();
  const unauthorizedStatus = matrixCase.expectedStatusWithoutToken ?? 401;
  expect(unauthorizedResponse.status).toBe(unauthorizedStatus);
  expect(unauthorizedResponse.body.code).toBe(
    unauthorizedStatus >= 200 && unauthorizedStatus < 300
      ? 0
      : unauthorizedStatus,
  );
}
