| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110 |
- /**
- * 【API级】联系人管理全流程
- * ================================================================
- * 对应 DOM 版:e2e/contact-management.spec.js(远程无 SPA,DOM 版不可跑)
- * 接口契约来源:ContactController(/api/contact/*)
- * list : {} 联系人列表
- * create : Contact 实体 { name, phone?, relationshipType?, tags?, notes?, ... }
- * update : Contact 实体 { id, ... }
- * delete : { id }
- * detail : { id }
- * import-phone: { name, phone, extra? }
- * interaction : { id } 记录互动
- * relationshipType 合法值:family / friend / partner / colleague / other
- * 运行:npx playwright test -c playwright.config.api.js --project=desktop
- */
- const { test, expect } = require('@playwright/test');
- const { registerRole, apiPost, uniqueSuffix } = require('../helpers/api');
- test.describe('【API级】联系人管理全流程', () => {
- let ctx;
- test.beforeAll(async ({ request }) => {
- ctx = await registerRole(request, 'parent', 'QA-CONTACT');
- });
- /** 创建一个联系人,返回 { id, name } */
- async function createContact(request, tag, extra) {
- const name = 'QA_' + tag + '_' + uniqueSuffix();
- const payload = Object.assign(
- { name, relationshipType: 'friend', contactSource: 'manual', notes: 'QA' },
- extra || {}
- );
- const r = await apiPost(request, '/api/contact/create', payload, ctx.token);
- expect(r.code, '创建联系人应成功').toBe(200);
- expect(r.data && r.data.id, '应返回联系人ID').toBeTruthy();
- return { id: r.data.id, name: r.data.name || name };
- }
- // ===== 场景1:创建联系人 =====
- test('[场景1] 创建联系人 - 期望创建成功', async ({ request }) => {
- const c = await createContact(request, 'CREATE');
- const list = await apiPost(request, '/api/contact/list', {}, ctx.token);
- expect(list.code).toBe(200);
- expect(Array.isArray(list.data)).toBeTruthy();
- expect(list.data.some((x) => String(x.id) === String(c.id))).toBeTruthy();
- });
- // ===== 场景2:通讯录导入 =====
- test('[场景2] 通讯录导入 - 期望导入成功', async ({ request }) => {
- const name = 'QA_IMPORT_' + uniqueSuffix();
- const phone = '13' + String(Math.floor(Math.random() * 900000000) + 100000000);
- const r = await apiPost(request, '/api/contact/import-phone', { name, phone }, ctx.token);
- expect(r.code).toBe(200);
- expect(r.data).toBeTruthy();
- const list = await apiPost(request, '/api/contact/list', {}, ctx.token);
- expect(list.data.some((x) => x.name === name)).toBeTruthy();
- });
- // ===== 场景3:记录互动 =====
- test('[场景3] 记录互动 - 期望记录成功', async ({ request }) => {
- const c = await createContact(request, 'INTERACT');
- const r = await apiPost(request, '/api/contact/interaction', { id: c.id }, ctx.token);
- expect(r.code).toBe(200);
- expect(r.data).toBeTruthy();
- const detail = await apiPost(request, '/api/contact/detail', { id: c.id }, ctx.token);
- expect(detail.code).toBe(200);
- expect(detail.data).toBeTruthy();
- });
- // ===== 场景4:编辑/删除联系人 =====
- test('[场景4] 编辑联系人 - 期望更新成功', async ({ request }) => {
- const c = await createContact(request, 'UPDATE');
- const newName = 'QA_UPDATED_' + uniqueSuffix();
- const r = await apiPost(request, '/api/contact/update', { id: c.id, name: newName }, ctx.token);
- expect(r.code).toBe(200);
- const detail = await apiPost(request, '/api/contact/detail', { id: c.id }, ctx.token);
- expect(detail.code).toBe(200);
- expect(detail.data.name).toBe(newName);
- });
- test('[场景4b] 删除联系人 - 期望从列表中移除', async ({ request }) => {
- const c = await createContact(request, 'DELETE');
- const before = await apiPost(request, '/api/contact/list', {}, ctx.token);
- const beforeCount = before.data.length;
- const r = await apiPost(request, '/api/contact/delete', { id: c.id }, ctx.token);
- expect(r.code).toBe(200);
- const after = await apiPost(request, '/api/contact/list', {}, ctx.token);
- expect(after.data.length).toBeLessThan(beforeCount);
- expect(after.data.some((x) => String(x.id) === String(c.id))).toBeFalsy();
- });
- // ===== 场景5:权限边界 =====
- test('[场景5b] 越权操作他人联系人 - 期望被拒绝', async ({ request }) => {
- const c = await createContact(request, 'AUTH');
- const other = await registerRole(request, 'parent', 'QA-OTHER');
- const r = await apiPost(request, '/api/contact/delete', { id: c.id }, other.token);
- expect(r.code).not.toBe(200);
- });
- });
|