import {TestBed} from '@angular/core/testing'; import {ActivatedRoute,convertToParamMap} from '@angular/router'; import {OperationsService} from '../operations.service'; import {LessonRecordsComponent} from './lesson-records.component'; import {LessonRecordDetailComponent} from './lesson-record-detail.component'; describe('上课记录与复习转交',()=>{ let ops:jasmine.SpyObj; beforeEach(()=>{ops=jasmine.createSpyObj('OperationsService',['request']);TestBed.configureTestingModule({providers:[{provide:OperationsService,useValue:ops},{provide:ActivatedRoute,useValue:{snapshot:{queryParamMap:convertToParamMap({})}}}]});}); const page=(items:unknown[],total=2)=>({items,total,cumulativeTotal:51,page:1,pageSize:100,version:'snapshot1'}); it('单个会员查看全部连续读取分页,保持筛选与实际总课次数',async()=>{ const c=TestBed.runInInjectionContext(()=>new LessonRecordsComponent());c.studentId=20;c.all=true;c.coachName='钱老师'; ops.request.and.returnValues(Promise.resolve(page([{lessonId:'a'}])),Promise.resolve(page([{lessonId:'b'}]))); await c.load();expect(c.data()?.items.length).toBe(2);expect(c.data()?.cumulativeTotal).toBe(51);expect(ops.request.calls.mostRecent().args[1]).toEqual(jasmine.objectContaining({studentId:20,coachName:'钱老师',page:2})); }); it('后续页失败时清除不完整结果并允许重试',async()=>{ const c=TestBed.runInInjectionContext(()=>new LessonRecordsComponent());c.studentId=20;c.all=true; ops.request.and.returnValues(Promise.resolve(page([{lessonId:'a'}])),Promise.reject(new Error('网络中断'))); await c.load();expect(c.data()).toBeNull();expect(c.error()).toBe('网络中断');expect(c.busy()).toBeFalse(); }); it('查询默认没有月份限制;切换条件清除查看全部',async()=>{ const c=TestBed.runInInjectionContext(()=>new LessonRecordsComponent());expect(c.params()['dateFrom']).toBe('');expect(c.params()['dateTo']).toBe(''); c.all=true;c.page=4;ops.request.and.resolveTo(page([]));c.query();expect(c.page).toBe(1);expect(c.all).toBeFalse(); }); it('转交预览失败不保留旧预览;未选择目标或原因不能提交',async()=>{ const c=TestBed.runInInjectionContext(()=>new LessonRecordDetailComponent());await c.checkTransfer();expect(ops.request).not.toHaveBeenCalled(); c.coachId=11;c.reason='老师交接';c.preview.set({version:'old',count:2} as never);ops.request.and.rejectWith(new Error('任务变化')); await c.checkTransfer();expect(c.preview()).toBeNull();expect(c.error()).toBe('任务变化'); }); it('陪练支持姓名片段和编号搜索,修改搜索后清除旧目标和旧预览',async()=>{ const c=TestBed.runInInjectionContext(()=>new LessonRecordDetailComponent());c.coaches.set([{userId:69,displayName:'钱老师'},{userId:1665,displayName:'张老师'}]); c.searchCoach('钱');expect(c.filteredCoaches().map(x=>x.userId)).toEqual([69]);c.selectCoach(c.filteredCoaches()[0]);expect(c.coachId).toBe(69); c.preview.set({count:10,version:'old'} as never);c.searchCoach('665');expect(c.coachId).toBe(0);expect(c.preview()).toBeNull();expect(c.filteredCoaches().map(x=>x.userId)).toEqual([1665]); c.reason='老师交接';await c.checkTransfer();expect(ops.request).not.toHaveBeenCalled(); c.searchCoach('不存在');expect(c.filteredCoaches()).toEqual([]); }); it('键盘可选择搜索结果,Escape 仅收起陪练列表',()=>{ const c=TestBed.runInInjectionContext(()=>new LessonRecordDetailComponent());c.coaches.set([{userId:69,displayName:'钱老师'}]);c.searchCoach('钱'); c.coachKeydown(new KeyboardEvent('keydown',{key:'ArrowDown'}));c.coachKeydown(new KeyboardEvent('keydown',{key:'Enter'}));expect(c.coachId).toBe(69);expect(c.coachPickerOpen()).toBeFalse(); c.openCoaches();c.coachKeydown(new KeyboardEvent('keydown',{key:'Escape'}));expect(c.coachPickerOpen()).toBeFalse();expect(c.coachId).toBe(69); }); it('保存失败保留同一幂等请求,重复点击仅提交一次;成功后回读',async()=>{ const c=TestBed.runInInjectionContext(()=>new LessonRecordDetailComponent());c.data.set({studentId:20,appointmentId:'1000'} as never);c.coachId=11;c.reason='老师交接'; ops.request.and.resolveTo({version:'v1',count:2});await c.checkTransfer();ops.request.and.rejectWith(new Error('断网')); await c.saveTransfer();const first=ops.request.calls.mostRecent().args[1];expect(c.preview()?.version).toBe('v1');await c.saveTransfer();expect(ops.request.calls.mostRecent().args[1]?.['idempotencyKey']).toBe(first?.['idempotencyKey']); ops.request.and.returnValues(Promise.resolve({count:2}),Promise.resolve({studentId:20,appointmentId:'1000'}));await c.saveTransfer();expect(c.preview()).toBeNull();expect(c.message()).toContain('2'); }); });