| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 |
- import { TestBed } from '@angular/core/testing';
- import { Agent, Person } from './api/models';
- import { ContactsService } from './contacts.service';
- import { FmodeApi } from './api/fmode-api';
- import { LiveService } from './live.service';
- /**
- * 通讯录服务。
- *
- * 重点回归:
- * ① 同事由 `Agent.owner` **去重聚合**(同一 owner 的多个容器只出一行)
- * ② Tab 切换与关键字过滤叠加时结果正确
- * ③ 空态只在「加载完成且确实没有」时为真
- */
- describe('ContactsService', () => {
- let svc: ContactsService;
- let live: LiveService;
- function agent(id: string, name: string, owner?: Person, extra: Partial<Agent> = {}): Agent {
- return {
- id,
- name,
- status: 'idle',
- matrixReady: true,
- unread: 0,
- owner,
- ...extra,
- };
- }
- const OWNER_A: Person = { id: 'u1', name: '张总', mobile: '13800000001' };
- const OWNER_B: Person = { id: 'u2', name: '李工', mobile: '13800000002' };
- function setAgents(list: Agent[]): void {
- (live as unknown as { _agents: { set(v: Agent[]): void }; _state: { set(v: string): void } })._agents.set(list);
- (live as unknown as { _state: { set(v: string): void } })._state.set(list.length ? 'ready' : 'empty');
- }
- beforeEach(() => {
- TestBed.resetTestingModule();
- TestBed.configureTestingModule({
- providers: [ContactsService, LiveService, { provide: FmodeApi, useValue: { fetchAgents: () => Promise.resolve([]) } }],
- });
- svc = TestBed.inject(ContactsService);
- live = TestBed.inject(LiveService);
- });
- describe('同事聚合', () => {
- it('🔴 同一个 owner 的多个容器 → 只出一行同事', () => {
- setAgents([
- agent('a1', 'lj', OWNER_A),
- agent('a2', 'lj-test', OWNER_A),
- agent('a3', 'other', OWNER_B),
- ]);
- expect(svc.people().map((p) => p.id)).toEqual(['u1', 'u2']);
- expect(svc.people()[0].agents?.length).toBe(2);
- });
- it('没有 owner 的容器 → 不进同事列表', () => {
- setAgents([agent('a1', 'lj')]);
- expect(svc.people().length).toBe(0);
- });
- it('counts 正确(ai / people / all)', () => {
- setAgents([
- agent('a1', 'lj', OWNER_A),
- agent('a2', 'lj-test', OWNER_A),
- agent('a3', 'x'),
- ]);
- const c = svc.counts();
- expect(c.ai).toBe(3);
- expect(c.people).toBe(1);
- expect(c.all).toBe(4); // 3 个 AI + 1 个同事
- });
- });
- describe('Tab 与过滤', () => {
- beforeEach(() => {
- setAgents([
- agent('a1', 'lj', OWNER_A, { specialty: '前端' }),
- agent('a2', 'lj-test', OWNER_A, { specialty: '后端' }),
- agent('a3', 'orphan'),
- ]);
- });
- it('tab=people → 不显示 AI', () => {
- svc.setTab('people');
- expect(svc.visibleAgents().length).toBe(0);
- expect(svc.visiblePeople().length).toBe(1);
- });
- it('tab=ai → 不显示同事', () => {
- svc.setTab('ai');
- expect(svc.visibleAgents().length).toBe(3);
- expect(svc.visiblePeople().length).toBe(0);
- });
- it('按容器名过滤', () => {
- svc.setTab('ai');
- svc.keyword.set('lj-test');
- expect(svc.visibleAgents().map((a) => a.id)).toEqual(['a2']);
- });
- it('🔴 按专长过滤(不只名字)', () => {
- svc.setTab('ai');
- svc.keyword.set('前端');
- expect(svc.visibleAgents().map((a) => a.id)).toEqual(['a1']);
- });
- it('🔴 按主人名字过滤(找「张总名下的容器」)', () => {
- svc.setTab('ai');
- svc.keyword.set('张总');
- expect(svc.visibleAgents().map((a) => a.id)).toEqual(['a1', 'a2']);
- });
- it('切换 Tab 会收起展开的同事', () => {
- svc.toggleColleague('u1');
- expect(svc.expandedColleague()).toBe('u1');
- svc.setTab('ai');
- expect(svc.expandedColleague()).toBeNull();
- });
- });
- describe('空态', () => {
- it('有数据 → isEmpty 为假', () => {
- setAgents([agent('a1', 'lj')]);
- expect(svc.isEmpty()).toBeFalse();
- });
- it('加载中 → isEmpty 为假(不能提前显示空态)', () => {
- setAgents([]);
- (live as unknown as { _state: { set(v: string): void } })._state.set('loading');
- expect(svc.isEmpty()).toBeFalse();
- });
- it('🔴 加载完成且确实为空 → isEmpty 为真', () => {
- setAgents([]);
- (live as unknown as { _state: { set(v: string): void } })._state.set('empty');
- expect(svc.isEmpty()).toBeTrue();
- });
- });
- });
|