ohayolibs
Version:
Ohayo is a set of essential modules for ohayojp.
228 lines (203 loc) • 8.07 kB
text/typescript
// tslint:disable: deprecation
import { HttpHeaders, HttpResponse } from '@angular/common/http';
import { HttpClientTestingModule, HttpTestingController, TestRequest } from '@angular/common/http/testing';
import { Component, DebugElement } from '@angular/core';
import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { _HttpClient } from '@ohayo/theme';
import * as fs from 'file-saver';
import { NzSafeAny } from 'ng-zorro-antd/core/types';
import { DownFileModule } from './down-file.module';
function genFile(isRealFile: boolean = true): Blob {
const blob = new Blob([
isRealFile ? `iVBORw0KGgoAAAANSUhEUgAAAAEAAAcomponentsAYAAAAfFcSJAAAADUlEQVR42mP8/5+hHgAHggJ/PchI7wAAAABJRU5ErkJggg==` : '',
]);
return blob;
}
describe('components: down-file', () => {
let fixture: ComponentFixture<TestComponent>;
let dl: DebugElement;
let context: TestComponent;
let httpBed: HttpTestingController;
function createComp(): void {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule, DownFileModule],
declarations: [TestComponent],
});
fixture = TestBed.createComponent(TestComponent);
dl = fixture.debugElement;
context = fixture.componentInstance;
httpBed = TestBed.inject(HttpTestingController);
}
describe('[default]', () => {
beforeEach(() => {
createComp();
fixture.detectChanges();
});
['xlsx', 'docx', 'pptx', 'pdf'].forEach(ext => {
it(`should be down ${ext}`, () => {
spyOn(fs, 'saveAs');
if (ext === 'docx') context.data = null;
fixture.detectChanges();
(dl.query(By.css('#down-' + ext)).nativeElement as HTMLButtonElement).click();
const ret = httpBed.expectOne(req => req.url.startsWith('/')) as TestRequest;
ret.flush(genFile());
expect(fs.saveAs).toHaveBeenCalled();
});
});
it('should be used custom filename', () => {
let fn: string;
const filename = 'newfile.docx';
spyOn(fs, 'saveAs').and.callFake(((_body: {}, fileName: string) => (fn = fileName)) as NzSafeAny);
context.fileName = rep => rep.headers.get('a')!;
fixture.detectChanges();
(dl.query(By.css('#down-docx')).nativeElement as HTMLButtonElement).click();
const ret = httpBed.expectOne(req => req.url.startsWith('/')) as TestRequest;
ret.flush(genFile(), {
headers: new HttpHeaders({ a: filename }),
});
expect(fn!).toBe(filename);
});
it('should be using header filename when repseon has [filename]', () => {
let fn: string;
const filename = 'newfile.docx';
spyOn(fs, 'saveAs').and.callFake(((_body: {}, fileName: string) => (fn = fileName)) as NzSafeAny);
context.fileName = null;
fixture.detectChanges();
(dl.query(By.css('#down-docx')).nativeElement as HTMLButtonElement).click();
const ret = httpBed.expectOne(req => req.url.startsWith('/')) as TestRequest;
ret.flush(genFile(), {
headers: new HttpHeaders({ filename }),
});
expect(fn!).toBe(filename);
});
it('should be using header filename when repseon has [x-filename]', () => {
let fn: string;
const filename = 'x-newfile.docx';
spyOn(fs, 'saveAs').and.callFake(((_body: {}, fileName: string) => (fn = fileName)) as NzSafeAny);
context.fileName = null;
fixture.detectChanges();
(dl.query(By.css('#down-docx')).nativeElement as HTMLButtonElement).click();
const ret = httpBed.expectOne(req => req.url.startsWith('/')) as TestRequest;
ret.flush(genFile(), {
headers: new HttpHeaders({ 'x-filename': filename }),
});
expect(fn!).toBe(filename);
});
it('should be throw error when a bad request', () => {
spyOn(context, 'error');
expect(context.error).not.toHaveBeenCalled();
(dl.query(By.css('#down-docx')).nativeElement as HTMLButtonElement).click();
const ret = httpBed.expectOne(req => req.url.startsWith('/')) as TestRequest;
ret.error(new ErrorEvent(''), { status: 404 });
expect(context.error).toHaveBeenCalled();
});
it('should be throw error when a empty file', () => {
spyOn(context, 'error');
expect(context.error).not.toHaveBeenCalled();
(dl.query(By.css('#down-docx')).nativeElement as HTMLButtonElement).click();
const ret = httpBed.expectOne(req => req.url.startsWith('/')) as TestRequest;
ret.flush(genFile(false));
expect(context.error).toHaveBeenCalled();
});
it('should be throw error when http status is not 200', () => {
spyOn(fs, 'saveAs');
spyOn(context, 'error');
expect(context.error).not.toHaveBeenCalled();
expect(fs.saveAs).not.toHaveBeenCalled();
(dl.query(By.css('#down-docx')).nativeElement as HTMLButtonElement).click();
const ret = httpBed.expectOne(req => req.url.startsWith('/')) as TestRequest;
ret.flush(null, { status: 201, statusText: '201' });
expect(fs.saveAs).not.toHaveBeenCalled();
expect(context.error).toHaveBeenCalled();
});
it('should be request via post', () => {
spyOn(fs, 'saveAs');
(dl.query(By.css('#down-docx')).nativeElement as HTMLButtonElement).click();
const ret = httpBed.expectOne(req => req.url.startsWith('/')) as TestRequest;
expect(ret.request.body.a).toBe(1);
});
describe('#pre', () => {
it('should be download when return true', fakeAsync(() => {
const btn = dl.query(By.css('#down-xlsx')).nativeElement as HTMLButtonElement;
context.pre = () => Promise.resolve(true);
fixture.detectChanges();
btn.click();
tick();
fixture.detectChanges();
expect(btn.classList).toContain(`down-file__disabled`);
}));
it('should be cannot download when return false', () => {
const btn = dl.query(By.css('#down-xlsx')).nativeElement as HTMLButtonElement;
context.pre = () => Promise.resolve(false);
fixture.detectChanges();
btn.click();
expect(btn.classList).not.toContain(`down-file__disabled`);
});
});
});
it('should be using content-disposition filename', () => {
createComp();
fixture.detectChanges();
let fn: string;
const filename = 'newfile.docx';
spyOn(fs, 'saveAs').and.callFake(((_body: {}, fileName: string) => (fn = fileName)) as NzSafeAny);
context.fileName = null;
fixture.detectChanges();
(dl.query(By.css('#down-docx')).nativeElement as HTMLButtonElement).click();
const ret = httpBed.expectOne(req => req.url.startsWith('/')) as TestRequest;
ret.flush(genFile(), {
headers: new HttpHeaders({
'Content-Disposition': `attachment; filename=${filename}; filename*=UTF-8''${filename}`,
}),
});
expect(fn!).toBe(filename);
});
it('should be down-file__not-support when not supoort fileSaver', () => {
class MockBlob {
constructor() {
throw new Error('');
}
}
spyOn(window, 'Blob').and.callFake(() => new MockBlob() as NzSafeAny);
createComp();
fixture.detectChanges();
const el = dl.query(By.css('#down-xlsx')).nativeElement as HTMLButtonElement;
el.click();
expect(el.classList).toContain(`down-file__not-support`);
});
});
({
template: `
<button
*ngFor="let i of fileTypes"
id="down-{{ i }}"
down-file
[http-data]="data"
[http-body]="body"
[http-method]="method"
http-url="/demo.{{ i }}"
[file-name]="fileName"
[pre]="pre"
(success)="success()"
(error)="error()"
>
{{ i }}
</button>
`,
})
class TestComponent {
fileTypes = ['xlsx', 'docx', 'pptx', 'pdf'];
data: any = {
otherdata: 1,
time: new Date(),
};
body = {
a: 1,
};
method = 'get';
fileName: string | ((rep: HttpResponse<Blob>) => string) | null = 'demo中文';
pre: (ev: MouseEvent) => Promise<boolean>;
success(): void { }
error(): void { }
}