| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263 |
- import test from 'node:test';
- import assert from 'node:assert/strict';
- import { indexBoardMembers, seedMemberGroups, changeMemberGroups } from '../src/core/member-groups.js';
- import { buildModel } from '../src/core/kfs/build.js';
- import { MemberGroupService } from '../src/services/member-groups.js';
- const raw = () => ({ session: [
- { objectId: 's1', studentName: '原昵称', groupId: 'G1', meta: { participantKey: 'participant:old1' }, employee: { key: 'channel-employee:stable', displayName: '小智' } },
- { objectId: 's2', studentName: '另一昵称', groupId: 'G1', meta: { participantKey: 'participant:old2' }, employee: { key: 'channel-employee:stable', displayName: '小智' } },
- { objectId: 's3', studentName: '小智', groupId: 'G2', meta: { participantKey: 'participant:other' } },
- ], artifact: [{ objectId: 'a1', ownerName: '原昵称', uploadedByKey: 'participant:old1', ownerSession: 's1' }],
- project: [{ objectId: 'p1', ownerName: '原昵称', uploadedByKey: 'participant:old2', ownerSession: 's2' }],
- opportunity: [{ objectId: 'o1', title: '机会', uploadedBy: '原昵称', uploadedByKey: 'participant:old1', sourceSession: 's1' }] });
- test('同一员工跨会话、旧键与昵称仍归同人,同名其他身份不合并', () => {
- const input = raw(), db = buildModel(input);
- assert.equal(db.members.length, 2);
- const m = db.memberById['channel-employee:stable'];
- assert.equal(m.name, '小智(G1)');assert.deepEqual(m.sessionIds, ['s1','s2']);
- assert.deepEqual(m.artifactIds, ['a1']);assert.deepEqual(m.projectIds, ['p1']);assert.deepEqual(m.oppIds, ['o1']);
- assert.equal(db.memberById['participant:other'].name, '小智(G2)');
- const renamed = raw();renamed.session[0].employee.displayName = '新称呼';renamed.session[1].employee.displayName = '新称呼';
- assert.equal(indexBoardMembers(renamed).members[0].id, m.id);
- assert.equal(input.artifact[0].ownerName, '原昵称');
- });
- test('姓名补充不能改变旧数据的分组编号,前端与服务端成员索引逐项一致', () => {
- const input = { session: [
- { objectId: 's1', studentName: '陈静', groupId: 'G1' },
- { objectId: 's2', studentName: '陈静', groupId: 'G1', meta: { participantKey: 'legacy-account-1' } },
- ], artifact: [{ objectId: 'a1', ownerName: '陈静', ownerSession: 's1', uploadedByKey: 'legacy-account-2' }],
- project: [], opportunity: [] };
- const directory = indexBoardMembers(input), db = buildModel(input);
- assert.deepEqual(db.members.map((m) => m.id).sort(), directory.members.map((m) => m.id).sort());
- assert.equal(db.members.length, 1);
- assert.equal(db.members[0].name, '陈静');
- assert.equal(seedMemberGroups(db.members).assignments[db.members[0].id], 'legacy-group:G1');
- });
- test('分组名独立于成员身份,重命名不改归属,删除只移回未分组', () => {
- const members = indexBoardMembers(raw()).members, ids = new Set(members.map((m) => m.id));
- const state = seedMemberGroups(members), before = JSON.stringify(members);
- const assigned = changeMemberGroups(state, { action: 'assign', groupId: state.groups[1].id, memberIds: [...ids] }, ids);
- const renamed = changeMemberGroups(assigned, { action: 'rename', groupId: state.groups[1].id, name: '新品研发' }, ids);
- assert.equal(renamed.groups[1].name, '新品研发');assert.deepEqual(renamed.assignments, assigned.assignments);
- const deleted = changeMemberGroups(renamed, { action: 'delete', groupId: state.groups[1].id }, ids);
- assert.equal(Object.keys(deleted.assignments).length, 0);assert.equal(JSON.stringify(members), before);
- assert.equal(state.revision, 0);
- });
- test('重复、空白、保留名、长名及未知成员不会产生有效分组变更', () => {
- const members = indexBoardMembers(raw()).members, ids = new Set(members.map((m) => m.id)), state = seedMemberGroups(members);
- for (const name of ['G1',' G1 ','', '未分组','全部成员','字'.repeat(31)]) assert.throws(() => changeMemberGroups(state, { action:'create',name }, ids, 'new'), { code:'VALIDATION_FAILED' });
- assert.throws(() => changeMemberGroups(state, { action:'assign',groupId:state.groups[0].id,memberIds:[members[0].id,'private-person'] }, ids), { code:'VALIDATION_FAILED' });
- assert.equal(state.revision, 0);
- });
- test('分组服务发送版本与稳定编号,网络异常不自动重试', async () => {
- let calls=0;
- const service = new MemberGroupService({ url:'/fixture',call:async (input) => { calls++;assert.equal(input.name,'ksfManagePublicMemberGroups');assert.equal(input.params.expectedRevision,3);assert.equal(input.params.requestId,'same');throw Error('timeout'); } });
- await assert.rejects(() => service.change({revision:3},{action:'assign',memberIds:['employee:one'],groupId:null},'same'),/timeout/);
- assert.equal(calls,1);
- });
|