msw-handlers.ts 7.02 KB
import { http, HttpResponse, delay } from 'msw';

const BASE = '/api/v1';

export const handlers = [
  http.post(`${BASE}/auth/login`, async ({ request }) => {
    const body = (await request.json()) as { username: string; password: string; companyCode: string };

    if (body.companyCode === 'NOPE') {
      return HttpResponse.json(
        { code: 40004, message: '公司不存在或已删除', data: null, timestamp: Date.now() },
        { status: 400 },
      );
    }
    if (body.username === 'locked') {
      return HttpResponse.json(
        {
          code: 42301,
          message: '账号已锁定,请稍后再试',
          data: { lockUntil: '2030-01-01T12:00:00' },
          timestamp: Date.now(),
        },
        { status: 423 },
      );
    }
    if (body.username === 'deleted') {
      return HttpResponse.json(
        { code: 40103, message: '账号已被作废,禁止登录', data: null, timestamp: Date.now() },
        { status: 401 },
      );
    }
    if (body.username !== 'alice' || body.password !== 'Password1!') {
      return HttpResponse.json(
        { code: 40101, message: '用户名或密码错误', data: null, timestamp: Date.now() },
        { status: 401 },
      );
    }

    return HttpResponse.json(
      {
        code: 200,
        message: '操作成功',
        data: {
          accessToken: 'fake-jwt',
          tokenType: 'Bearer',
          expiresInSec: 7200,
          userInfo: {
            userId: 1,
            username: 'alice',
            userType: 'NORMAL',
            language: 'zh-CN',
            employeeName: '张三',
            companyCode: body.companyCode,
          },
        },
        timestamp: Date.now(),
      },
      { status: 200 },
    );
  }),

  // Generic network-error stub for tests that pass requestUrl = "/network-error"
  http.post(`${BASE}/network-error`, async () => {
    await delay(50);
    return HttpResponse.error();
  }),

  // === REQ-USR-002/003/004: users CRUD ===
  http.get(`${BASE}/users`, ({ request }) => {
    const url = new URL(request.url);
    const queryField = url.searchParams.get('queryField');
    const queryValue = url.searchParams.get('queryValue');
    const page = Number(url.searchParams.get('page') ?? 1);
    const size = Number(url.searchParams.get('size') ?? 20);
    const allUsers = [
      {
        userId: 1,
        username: 'alice',
        employeeName: '张三',
        userCode: 'U001',
        departmentName: '技术部',
        userType: 'NORMAL',
        language: 'zh-CN',
        isDeleted: false,
        lastLoginDate: '2026-05-15T08:00:00',
        createdBy: 'admin',
        createdDate: '2026-05-10T00:00:00',
      },
      {
        userId: 2,
        username: 'admin',
        employeeName: null,
        userCode: 'U000',
        departmentName: null,
        userType: 'SUPER_ADMIN',
        language: 'zh-CN',
        isDeleted: false,
        lastLoginDate: null,
        createdBy: 'system',
        createdDate: '2026-05-01T00:00:00',
      },
      {
        userId: 3,
        username: 'bob_deleted',
        employeeName: null,
        userCode: 'U002',
        departmentName: null,
        userType: 'NORMAL',
        language: 'zh-CN',
        isDeleted: true,
        lastLoginDate: null,
        createdBy: 'admin',
        createdDate: '2026-05-05T00:00:00',
      },
    ];
    let filtered = allUsers;
    if (queryField === 'username' && queryValue) {
      filtered = allUsers.filter((u) => u.username.includes(queryValue));
    }
    const start = (page - 1) * size;
    const records = filtered.slice(start, start + size);
    return HttpResponse.json({
      code: 200,
      message: '操作成功',
      data: { records, total: filtered.length, page, size },
      timestamp: Date.now(),
    });
  }),

  http.get(`${BASE}/users/:userId`, ({ params }) => {
    const userId = Number(params.userId);
    if (userId === 99999) {
      return HttpResponse.json(
        { code: 40401, message: '用户不存在', data: null, timestamp: Date.now() },
        { status: 404 },
      );
    }
    return HttpResponse.json({
      code: 200,
      message: '操作成功',
      data: {
        userId,
        username: 'alice',
        employeeName: '张三',
        userCode: 'U001',
        departmentName: '技术部',
        userType: 'NORMAL',
        language: 'zh-CN',
        isDeleted: false,
        lastLoginDate: '2026-05-15T08:00:00',
        canEditDocument: true,
        employeeId: 1,
        permissionCategoryIds: [1, 2],
        createdBy: 'admin',
        createdDate: '2026-05-10T00:00:00',
        updatedBy: 'admin',
        updatedDate: '2026-05-14T00:00:00',
      },
      timestamp: Date.now(),
    });
  }),

  http.post(`${BASE}/users`, async ({ request }) => {
    const body = (await request.json()) as { username: string; userCode: string; userType: string };
    if (body.username === 'dup') {
      return HttpResponse.json(
        { code: 40901, message: '用户名已存在', data: null, timestamp: Date.now() },
        { status: 409 },
      );
    }
    if (body.userCode === 'dup-code') {
      return HttpResponse.json(
        { code: 40902, message: '用户号已被占用', data: null, timestamp: Date.now() },
        { status: 409 },
      );
    }
    if (!['NORMAL', 'SUPER_ADMIN'].includes(body.userType)) {
      return HttpResponse.json(
        { code: 40001, message: 'userType 不在白名单', data: null, timestamp: Date.now() },
        { status: 400 },
      );
    }
    return HttpResponse.json(
      {
        code: 200,
        message: '操作成功',
        data: { userId: 42, username: body.username, userCode: body.userCode },
        timestamp: Date.now(),
      },
      { status: 201 },
    );
  }),

  http.put(`${BASE}/users/:userId`, async ({ params, request }) => {
    const userId = Number(params.userId);
    const body = (await request.json()) as { isDeleted?: boolean; userCode?: string };
    if (userId === 99999) {
      return HttpResponse.json(
        { code: 40401, message: '用户不存在', data: null, timestamp: Date.now() },
        { status: 404 },
      );
    }
    if (body.isDeleted === true && userId === 2) {
      return HttpResponse.json(
        { code: 40302, message: '不允许停用当前登录用户自己', data: null, timestamp: Date.now() },
        { status: 403 },
      );
    }
    if (body.userCode === 'dup-code') {
      return HttpResponse.json(
        { code: 40902, message: '用户号已被占用', data: null, timestamp: Date.now() },
        { status: 409 },
      );
    }
    return HttpResponse.json({
      code: 200,
      message: '操作成功',
      data: {
        userId,
        username: 'alice',
        employeeName: '张三',
        userCode: body.userCode ?? 'U001',
        departmentName: '技术部',
        userType: 'NORMAL',
        language: 'zh-CN',
        isDeleted: body.isDeleted ?? false,
        lastLoginDate: '2026-05-15T08:00:00',
        employeeId: 1,
        permissionCategoryIds: [1, 2],
        updatedBy: 'admin',
        updatedDate: '2026-05-15T09:00:00',
      },
      timestamp: Date.now(),
    });
  }),
];