|
|
@@ -30,9 +30,8 @@ describe('teacher learning report PDF download', () => {
|
|
|
report = reportFixture(); groupId.set(3);
|
|
|
api = jasmine.createSpyObj('ApiService',['get']);
|
|
|
api.get.and.callFake((action: string) => of({retcode:0,result:(action==='app_lesson_report'?report:action==='e_record_detail'?wordsFixture():{batches:[]}) as any}));
|
|
|
- download = jasmine.createSpyObj('LessonReportDownloadService',['createPdf','createZip','download']);
|
|
|
+ download = jasmine.createSpyObj('LessonReportDownloadService',['createPdf','download']);
|
|
|
download.createPdf.and.resolveTo(new Blob(['%PDF-test'],{type:'application/pdf'}));
|
|
|
- download.createZip.and.callFake(files => new LessonReportDownloadService().createZip(files));
|
|
|
TestBed.configureTestingModule({providers:[provideRouter([]),
|
|
|
{provide:ActivatedRoute,useValue:{snapshot:{queryParamMap:convertToParamMap({sid:'901'})}}},
|
|
|
{provide:ApiService,useValue:api},{provide:SessionService,useValue:{groupId}},
|
|
|
@@ -58,9 +57,10 @@ describe('teacher learning report PDF download', () => {
|
|
|
expect(fixture.nativeElement.querySelector('[role="status"]').textContent).toContain('已生成 1 份 PDF');
|
|
|
expect(fixture.nativeElement.querySelector('.pdf-render')).toBeNull();
|
|
|
});
|
|
|
- it('downloads all three formats as one archive and keeps answers out of the worksheets',async()=>{
|
|
|
+ it('downloads all three formats as separate PDFs and keeps answers out of the worksheets',async()=>{
|
|
|
const fixture=screen();const titles:string[]=[];
|
|
|
expect(fixture.nativeElement.querySelectorAll('.pdf-options input:checked').length).toBe(3);
|
|
|
+ expect(fixture.nativeElement.querySelector('.download-pdf').textContent).toContain('下载 3 份 PDF');
|
|
|
download.createPdf.and.callFake(async element=>{
|
|
|
titles.push(element.querySelector('h1')!.textContent!);
|
|
|
const table=element.querySelector('.worksheet-table');
|
|
|
@@ -74,21 +74,21 @@ describe('teacher learning report PDF download', () => {
|
|
|
expect(element.querySelector('.report-summary')).toBeNull();expect(element.querySelector('.feedback-section')).toBeNull();
|
|
|
}
|
|
|
expect(download.download).not.toHaveBeenCalled();
|
|
|
- return new Blob(['%PDF-'+titles.length]);
|
|
|
+ return new Blob(['%PDF-'+titles.length],{type:'application/pdf'});
|
|
|
});
|
|
|
await fixture.componentInstance.downloadPdf();fixture.detectChanges();
|
|
|
expect(titles).toEqual(['单词学习报表','英文填中文复习表','中文填英文复习表']);
|
|
|
- expect(download.createZip).toHaveBeenCalledTimes(1);
|
|
|
- const { unzipSync } = await import('fflate');
|
|
|
- const archive = await download.createZip.calls.mostRecent().returnValue;
|
|
|
- const entries = unzipSync(new Uint8Array(await archive.arrayBuffer()));
|
|
|
- expect(Object.keys(entries)).toEqual(titles.map(title => `小树陪练-${title}-测试学员-2026-10-22-901.pdf`));
|
|
|
- expect(Object.values(entries).map(bytes => new TextDecoder().decode(bytes))).toEqual(['%PDF-1', '%PDF-2', '%PDF-3']);
|
|
|
- expect(download.download).toHaveBeenCalledTimes(1);
|
|
|
- expect(download.download.calls.mostRecent().args[0].filename).toMatch(/\.zip$/);
|
|
|
- expect(fixture.nativeElement.querySelectorAll('.generated-files a[download]').length).toBe(1);
|
|
|
+ expect(download.download).toHaveBeenCalledTimes(3);
|
|
|
+ const files = download.download.calls.allArgs().map(([file]) => file);
|
|
|
+ expect(files.map(file => file.filename)).toEqual(titles.map(title => `小树陪练-${title}-测试学员-2026-10-22-901.pdf`));
|
|
|
+ const links = Array.from(fixture.nativeElement.querySelectorAll('.generated-files a[download]') as NodeListOf<HTMLAnchorElement>);
|
|
|
+ expect(links.map(link => link.download)).toEqual(files.map(file => file.filename));
|
|
|
+ expect(links.map(link => link.href)).toEqual(files.map(file => file.url));
|
|
|
+ const blobs = await Promise.all(files.map(file => fetch(file.url).then(response => response.blob())));
|
|
|
+ expect(blobs.map(blob => blob.type)).toEqual(Array(3).fill('application/pdf'));
|
|
|
+ expect(await Promise.all(blobs.map(blob => blob.text()))).toEqual(['%PDF-1', '%PDF-2', '%PDF-3']);
|
|
|
expect(api.get.calls.allArgs().filter(args=>args[0]==='e_record_detail').length).toBe(1);
|
|
|
- const revoke=spyOn(URL,'revokeObjectURL');fixture.destroy();expect(revoke).toHaveBeenCalledTimes(1);
|
|
|
+ const revoke=spyOn(URL,'revokeObjectURL').and.callThrough();fixture.destroy();expect(revoke).toHaveBeenCalledTimes(3);
|
|
|
});
|
|
|
it('downloads only selected formats and prevents an empty selection',async()=>{
|
|
|
const fixture=screen();const choices=fixture.nativeElement.querySelectorAll('.pdf-options input');
|
|
|
@@ -118,7 +118,7 @@ describe('teacher learning report PDF download', () => {
|
|
|
expect(download.download).not.toHaveBeenCalled();expect(fixture.nativeElement.querySelector('[role="alert"]').textContent).toContain('单词读取失败');
|
|
|
expect(fixture.nativeElement.querySelector('.download-pdf').disabled).toBeFalse();
|
|
|
api.get.and.callFake((action:string)=>of({retcode:0,result:(action==='e_record_detail'?wordsFixture():report) as any}));
|
|
|
- await fixture.componentInstance.downloadPdf();expect(download.download).toHaveBeenCalledTimes(1);
|
|
|
+ await fixture.componentInstance.downloadPdf();expect(download.download).toHaveBeenCalledTimes(3);
|
|
|
});
|
|
|
it('does not export incomplete lessons or empty record lists',async()=>{
|
|
|
const fixture=screen();report.order['dszt']=10;
|