diff --git a/static/js/services/dockerfile/dockerfile.service.impl.spec.ts b/static/js/services/dockerfile/dockerfile.service.impl.spec.ts index 0848a85d4..9f3ba1747 100644 --- a/static/js/services/dockerfile/dockerfile.service.impl.spec.ts +++ b/static/js/services/dockerfile/dockerfile.service.impl.spec.ts @@ -21,12 +21,14 @@ describe("DockerfileServiceImpl", () => { describe("getDockerfile", () => { var file: any; + var invalidArchiveFile: any[]; + var validArchiveFile: any[]; var readAsFileBufferSpy: Spy; + var forDataSpy: Spy; beforeEach(() => { dataFileServiceMock.readDataArrayAsPossibleArchive.and.callFake((buf, success, failure) => { - var files: any[] = []; - failure(files); + failure([]); }); dataFileServiceMock.arrayToString.and.callFake((buf, callback) => { @@ -35,28 +37,29 @@ describe("DockerfileServiceImpl", () => { }); dataFileServiceMock.blobToString.and.callFake((blob, callback) => { - var contents: string = ""; - callback(contents); + callback(blob.toString()); }); - spyOn(DockerfileInfoImpl, "forData").and.returnValue(null); + forDataSpy = spyOn(DockerfileInfoImpl, "forData").and.returnValue(new DockerfileInfoImpl(file, configMock)); readAsFileBufferSpy = spyOn(fileReaderMock, "readAsArrayBuffer").and.callFake(() => { var event: any = {target: {result: file}}; fileReaderMock.onload(event); }); file = "FROM quay.io/coreos/nginx:latest"; + validArchiveFile = [{name: 'Dockerfile', toBlob: jasmine.createSpy('toBlobSpy').and.returnValue(file)}]; + invalidArchiveFile = [{name: 'main.exe', toBlob: jasmine.createSpy('toBlobSpy').and.returnValue("")}]; }); it("calls datafile service to read given file as possible archive file", (done) => { dockerfileServiceImpl.getDockerfile(file, (dockerfile: DockerfileInfoImpl) => { - fail("Should not invoke success callback"); + expect(readAsFileBufferSpy.calls.argsFor(0)[0]).toEqual(file); + expect(dataFileServiceMock.readDataArrayAsPossibleArchive).toHaveBeenCalled(); done(); }, (error: Event | string) => { - expect(readAsFileBufferSpy.calls.argsFor(0)[0]).toEqual(file); - expect(dataFileServiceMock.readDataArrayAsPossibleArchive).toHaveBeenCalled(); + fail("Should not invoke failure callback"); done(); }); }); @@ -64,16 +67,17 @@ describe("DockerfileServiceImpl", () => { it("calls datafile service to convert file to string if given file is not an archive", (done) => { dockerfileServiceImpl.getDockerfile(file, (dockerfile: DockerfileInfoImpl) => { - fail("Should not invoke success callback"); + expect(dataFileServiceMock.arrayToString.calls.argsFor(0)[0]).toEqual(file); done(); }, (error: Event | string) => { - expect(dataFileServiceMock.arrayToString.calls.argsFor(0)[0]).toEqual(file); + fail("Should not invoke success callback"); done(); }); }); it("calls failure callback if given non-archive file that is not a valid Dockerfile", (done) => { + forDataSpy.and.returnValue(null); dockerfileServiceImpl.getDockerfile(file, (dockerfile: DockerfileInfoImpl) => { fail("Should not invoke success callback"); @@ -86,28 +90,87 @@ describe("DockerfileServiceImpl", () => { }); it("calls success callback with new DockerfileInfoImpl instance if given valid Dockerfile", (done) => { - done(); + dockerfileServiceImpl.getDockerfile(file, + (dockerfile: DockerfileInfoImpl) => { + expect(dockerfile).toBeDefined(); + done(); + }, + (error: Event | string) => { + fail('Should not invoke failure callback'); + done(); + }); }); it("calls failure callback if given archive file with no Dockerfile present in root directory", (done) => { - done(); + dataFileServiceMock.readDataArrayAsPossibleArchive.and.callFake((buf, success, failure) => { + success(invalidArchiveFile); + }); + + dockerfileServiceImpl.getDockerfile(file, + (dockerfile: DockerfileInfoImpl) => { + fail("Should not invoke success callback"); + done(); + }, + (error: Event | string) => { + expect(error).toEqual('No Dockerfile found in root of archive'); + done(); + }); }); it("calls datafile service to convert blob to string if given file is an archive", (done) => { - done(); + dataFileServiceMock.readDataArrayAsPossibleArchive.and.callFake((buf, success, failure) => { + success(validArchiveFile); + }); + + dockerfileServiceImpl.getDockerfile(file, + (dockerfile: DockerfileInfoImpl) => { + expect(validArchiveFile[0].toBlob).toHaveBeenCalled(); + expect(dataFileServiceMock.blobToString.calls.argsFor(0)[0]).toEqual(validArchiveFile[0].toBlob()); + done(); + }, + (error: Event | string) => { + fail("Should not invoke success callback"); + done(); + }); }); it("calls failure callback if given archive file with invalid Dockerfile", (done) => { - done(); + forDataSpy.and.returnValue(null); + invalidArchiveFile[0].name = 'Dockerfile'; + dataFileServiceMock.readDataArrayAsPossibleArchive.and.callFake((buf, success, failure) => { + success(invalidArchiveFile); + }); + + dockerfileServiceImpl.getDockerfile(file, + (dockerfile: DockerfileInfoImpl) => { + fail("Should not invoke success callback"); + done(); + }, + (error: Event | string) => { + expect(error).toEqual('Dockerfile inside archive is not a valid Dockerfile'); + done(); + }); }); it("calls success callback with new DockerfileInfoImpl instance if given archive with valid Dockerfile", (done) => { - done(); + dataFileServiceMock.readDataArrayAsPossibleArchive.and.callFake((buf, success, failure) => { + success(validArchiveFile); + }); + + dockerfileServiceImpl.getDockerfile(file, + (dockerfile: DockerfileInfoImpl) => { + expect(dockerfile).toBeDefined(); + done(); + }, + (error: Event | string) => { + fail('Should not invoke failure callback'); + done(); + }); }); }); describe("extractDockerfile", () => { - // TODO + // TODO: TDD promise-based method with same functionality as getDockerfile }); }); diff --git a/static/js/services/dockerfile/dockerfile.service.impl.ts b/static/js/services/dockerfile/dockerfile.service.impl.ts index 6783e8786..d2060b08d 100644 --- a/static/js/services/dockerfile/dockerfile.service.impl.ts +++ b/static/js/services/dockerfile/dockerfile.service.impl.ts @@ -20,17 +20,13 @@ export class DockerfileServiceImpl implements DockerfileService { failure: (error: Event | string) => void): void { var reader: FileReader = this.FileReaderFactory(); reader.onload = (event: any) => { - - // FIXME: Debugging - console.log(event.target.result); - this.DataFileService.readDataArrayAsPossibleArchive(event.target.result, (files: any[]) => { - this.processFiles(files, event.target.result, success, failure); + this.processFiles(files, success, failure); }, () => { - // Not an archive. Read directly as a single file. - this.processFiles([], event.target.result, success, failure); + // Not an archive. Read directly as a single file. + this.processFile(event.target.result, success, failure); }); }; @@ -38,25 +34,23 @@ export class DockerfileServiceImpl implements DockerfileService { reader.readAsArrayBuffer(file); } + private processFile(dataArray: any, + success: (dockerfile: DockerfileInfoImpl) => void, + failure: (error: ErrorEvent | string) => void): void { + this.DataFileService.arrayToString(dataArray, (contents: string) => { + var result: DockerfileInfoImpl | null = DockerfileInfoImpl.forData(contents, this.Config); + if (result == null) { + failure('File chosen is not a valid Dockerfile'); + } + else { + success(result); + } + }); + } + private processFiles(files: any[], - dataArray: any[], success: (dockerfile: DockerfileInfoImpl) => void, failure: (error: ErrorEvent | string) => void): void { - // The files array will be empty if the submitted file was not an archive. We therefore - // treat it as a single Dockerfile. - if (files.length == 0) { - this.DataFileService.arrayToString(dataArray, (contents: string) => { - var result: DockerfileInfoImpl | null = DockerfileInfoImpl.forData(contents, this.Config); - if (result == null) { - failure('File chosen is not a valid Dockerfile'); - return; - } - - success(result); - }); - return; - } - var found: boolean = false; files.forEach((file) => { if (file['name'] == 'Dockerfile') { @@ -64,10 +58,10 @@ export class DockerfileServiceImpl implements DockerfileService { var result: DockerfileInfoImpl | null = DockerfileInfoImpl.forData(contents, this.Config); if (result == null) { failure('Dockerfile inside archive is not a valid Dockerfile'); - return; } - - success(result); + else { + success(result); + } }); found = true; }