import { TestBed } from '@angular/core/testing'; import { ReviewRewardsComponent } from './review-rewards.component'; import { OperationsService } from '../operations.service'; import { ReviewRewardPage } from '../admin.models'; describe('ReviewRewardsComponent',()=>{ const empty:ReviewRewardPage={items:[],total:0,page:1,pageSize:20,summary:{reviewCount:0,reviewAmount:0,historicalCount:0,exceptionCount:0}}; let service:jasmine.SpyObj; beforeEach(async()=>{ service=jasmine.createSpyObj('OperationsService',['reviewRewards','confirmLegacyReviewRewards','correctReviewReward','payrolls']);service.reviewRewards.and.resolveTo(empty);service.confirmLegacyReviewRewards.and.resolveTo({confirmed:1,alreadyConfirmed:0}); await TestBed.configureTestingModule({imports:[ReviewRewardsComponent],providers:[{provide:OperationsService,useValue:service}]}).compileComponents(); }); it('passes coach, store, month and status filters, resetting pagination when filters change',async()=>{ const fixture=TestBed.createComponent(ReviewRewardsComponent),component=fixture.componentInstance; fixture.componentRef.setInput('filters',{month:'2026-09',coachId:10,storeId:40,search:'老师'});fixture.detectChanges();await fixture.whenStable(); expect(service.reviewRewards).toHaveBeenCalledWith(component.filters,1,'');component.status.set('historical');await component.load(2);expect(service.reviewRewards).toHaveBeenCalledWith(component.filters,2,'historical'); fixture.componentRef.setInput('filters',{...component.filters,month:'2026-10'});fixture.detectChanges();await fixture.whenStable();expect(service.reviewRewards).toHaveBeenCalledWith(component.filters,1,'historical'); }); it('shows historical evidence as zero value pending review, separately from earned totals',async()=>{ service.reviewRewards.and.resolveTo({...empty,total:1,summary:{...empty.summary,historicalCount:1},items:[{objectId:'r',taskId:'t',coachId:10,coachName:'老师',studentName:'学生',courseName:'单词',storeId:40,storeName:'门店',plannedDate:'2026-08-01',completedAt:'',incomeMonth:'',amount:0,status:'historical',statusLabel:'历史待核对',exception:''}]}); const fixture=TestBed.createComponent(ReviewRewardsComponent);fixture.componentRef.setInput('filters',{month:'2026-09',coachId:0,storeId:0,search:''});fixture.detectChanges();await fixture.whenStable();fixture.detectChanges(); expect(fixture.nativeElement.textContent).toContain('需核对历史发放情况');expect(fixture.nativeElement.textContent).toContain('¥0.00'); }); it('keeps the newest response and displays read errors instead of a false zero income',async()=>{ const fixture=TestBed.createComponent(ReviewRewardsComponent),component=fixture.componentInstance;component.filters={month:'2026-09',coachId:0,storeId:0,search:''}; let resolveOld!:(value:ReviewRewardPage)=>void;service.reviewRewards.and.returnValues(new Promise(resolve=>resolveOld=resolve),Promise.resolve({...empty,total:2})); const old=component.load();await component.load();resolveOld({...empty,total:1});await old;expect(component.data()?.total).toBe(2); service.reviewRewards.and.rejectWith(new Error('服务不可用'));await component.load();expect(component.error()).toBe('服务不可用');expect(component.data()).toBeNull(); }); it('clears record type only for an explicit reset', async()=>{const fixture=TestBed.createComponent(ReviewRewardsComponent),component=fixture.componentInstance;component.filters={month:'2026-09',coachId:0,storeId:0,search:''};component.status.set('historical');fixture.componentRef.setInput('filters',{...component.filters,resetRevision:1});fixture.detectChanges();await fixture.whenStable();expect(component.status()).toBe('');}); it('requires manager review and a reason before confirming selected historical evidence',async()=>{ const fixture=TestBed.createComponent(ReviewRewardsComponent),component=fixture.componentInstance;component.filters={month:'2026-09',coachId:0,storeId:0,search:''}; component.toggleSelection('reward-1',true);component.confirmReason.set('已核对未发放');await component.confirmSelected();expect(service.confirmLegacyReviewRewards).not.toHaveBeenCalled(); component.canManage=true;await component.confirmSelected();expect(service.confirmLegacyReviewRewards).toHaveBeenCalledWith(['reward-1'],'已核对未发放');expect(component.selectedIds()).toEqual([]); }); it('requires a reviewed correction reason and a versioned draft for paid evidence',async()=>{ const component=TestBed.createComponent(ReviewRewardsComponent).componentInstance;component.filters={month:'2026-10',coachId:0,storeId:0,search:''}; const row:any={objectId:'reward-1',canCorrect:true,batchStatus:'paid',amount:1}; await component.openCorrection(row);expect(component.correction()).toBeNull(); component.canManage=true;service.payrolls.and.resolveTo({items:[{objectId:'draft',month:'2026-11',status:'draft',version:4}],total:1} as any); await component.openCorrection(row);component.correctionReason.set('核对真实完成时间');await component.saveCorrection();expect(service.correctReviewReward).not.toHaveBeenCalled(); component.correctionBatch.set('draft');service.correctReviewReward.and.resolveTo({});await component.saveCorrection(); expect(service.correctReviewReward).toHaveBeenCalledWith('reward-1','核对真实完成时间','draft',4);expect(component.correction()).toBeNull(); }); });