diff --git a/package.json b/package.json index 4fb9f445c..8d21d6401 100644 --- a/package.json +++ b/package.json @@ -62,6 +62,7 @@ "source-map-loader": "0.1.5", "style-loader": "0.13.1", "ts-loader": "^0.9.5", + "ts-mocks": "^0.2.2", "typescript": "^2.2.1", "typings": "1.4.0", "webpack": "^2.2" diff --git a/static/js/directives/ui/dockerfile-build-form.js b/static/js/directives/ui/dockerfile-build-form.js index 136f29118..2a6ef94de 100644 --- a/static/js/directives/ui/dockerfile-build-form.js +++ b/static/js/directives/ui/dockerfile-build-form.js @@ -10,10 +10,8 @@ angular.module('quay').directive('dockerfileBuildForm', function () { restrict: 'C', scope: { 'repository': '=repository', - 'isReady': '=?isReady', 'reset': '=?reset', - 'readyForBuild': '&readyForBuild' }, controller: function($scope, $element, ApiService, DockerfileService, Config) { diff --git a/static/js/services/datafile/datafile.service.impl.spec.ts b/static/js/services/datafile/datafile.service.impl.spec.ts new file mode 100644 index 000000000..e69de29bb diff --git a/static/js/services/datafile/datafile.service.impl.ts b/static/js/services/datafile/datafile.service.impl.ts new file mode 100644 index 000000000..e69de29bb diff --git a/static/js/services/datafile/datafile.service.ts b/static/js/services/datafile/datafile.service.ts new file mode 100644 index 000000000..43bae9d11 --- /dev/null +++ b/static/js/services/datafile/datafile.service.ts @@ -0,0 +1,48 @@ +/** + * Service which provides helper methods for downloading a data file from a URL, and extracting + * its contents as .tar, .tar.gz, or .zip file. Note that this service depends on external + * library code in the lib/ directory: + * - jszip.min.js + * - Blob.js + * - zlib.js + */ +export abstract class DatafileService { + + /** + * Convert a blob to a string. + * @param blob The blob to convert. + * @param callback The success callback given converted blob. + */ + public abstract blobToString(blob: any, callback: (result: string) => void): void; + + /** + * Convert array to string. + * @param buf The array buffer to convert. + * @param callback The success callback given converted array buffer. + */ + public abstract arrayToString(buf: any, callback: (result: string) => void): void; + + /** + * Determine if a given data array is an archive file. + * @param buf The data array to check. + * @param success The success callback if the given array is an archive file, given the file contents. + * @param failure The failure callback if the given array is not an archive file, given the error message. + */ + public abstract readDataArrayAsPossibleArchive(buf: any, + success: (result: any) => void, + failure: (error: any) => void): void; + + /** + * Download a file into an array buffer while tracking progress. + * @param $scope An AngularJS $scope instance. + * @param url The URL of the file to be downloaded. + * @param progress The callback for download progress. + * @param error The error callback. + * @param loaded The success callback given the downloaded array buffer. + */ + public abstract downloadDataFileAsArrayBuffer($scope: ng.IScope, + url: string, + progress: (percent: number) => void, + error: () => void, + loaded: (uint8array: Uint8Array) => void): void; +} \ No newline at end of file diff --git a/static/js/services/dockerfile/dockerfile.service.impl.spec.ts b/static/js/services/dockerfile/dockerfile.service.impl.spec.ts index edbb8175a..ebccbc2ea 100644 --- a/static/js/services/dockerfile/dockerfile.service.impl.spec.ts +++ b/static/js/services/dockerfile/dockerfile.service.impl.spec.ts @@ -1,22 +1,22 @@ import { DockerfileServiceImpl, DockerfileInfoImpl } from './dockerfile.service.impl'; +import { DatafileService } from '../datafile/datafile.service'; import Spy = jasmine.Spy; +import { Mock } from 'ts-mocks'; describe("DockerfileServiceImpl", () => { var dockerfileServiceImpl: DockerfileServiceImpl; - var dataFileServiceMock: any; + var datafileServiceMock: Mock; + var datafileService: DatafileService; var configMock: any; var fileReaderMock: FileReader; beforeEach(() => { - dataFileServiceMock = jasmine.createSpyObj('dataFileServiceMock', [ - 'readDataArrayAsPossibleArchive', - 'arrayToString', - 'blobToString', - ]); + datafileServiceMock = new Mock(); + datafileService = datafileServiceMock.Object; configMock = jasmine.createSpyObj('configMock', ['getDomain']); fileReaderMock = new FileReader(); - dockerfileServiceImpl = new DockerfileServiceImpl(dataFileServiceMock, configMock, () => fileReaderMock); + dockerfileServiceImpl = new DockerfileServiceImpl(datafileService, configMock, () => fileReaderMock); }); describe("getDockerfile", () => { @@ -27,16 +27,15 @@ describe("DockerfileServiceImpl", () => { var forDataSpy: Spy; beforeEach(() => { - dataFileServiceMock.readDataArrayAsPossibleArchive.and.callFake((buf, success, failure) => { + datafileServiceMock.setup(mock => mock.readDataArrayAsPossibleArchive).is((buf, success, failure) => { failure([]); }); - dataFileServiceMock.arrayToString.and.callFake((buf, callback) => { - var contents: string = ""; - callback(contents); + datafileServiceMock.setup(mock => mock.arrayToString).is((buf, callback) => { + callback(""); }); - dataFileServiceMock.blobToString.and.callFake((blob, callback) => { + datafileServiceMock.setup(mock => mock.blobToString).is((blob, callback) => { callback(blob.toString()); }); @@ -55,7 +54,7 @@ describe("DockerfileServiceImpl", () => { dockerfileServiceImpl.getDockerfile(file) .then((dockerfile: DockerfileInfoImpl) => { expect(readAsFileBufferSpy.calls.argsFor(0)[0]).toEqual(file); - expect(dataFileServiceMock.readDataArrayAsPossibleArchive).toHaveBeenCalled(); + expect(datafileService.readDataArrayAsPossibleArchive).toHaveBeenCalled(); done(); }) .catch((error: string) => { @@ -67,7 +66,7 @@ describe("DockerfileServiceImpl", () => { it("calls datafile service to convert file to string if given file is not an archive", (done) => { dockerfileServiceImpl.getDockerfile(file) .then((dockerfile: DockerfileInfoImpl) => { - expect(dataFileServiceMock.arrayToString.calls.argsFor(0)[0]).toEqual(file); + expect((datafileService.arrayToString).calls.argsFor(0)[0]).toEqual(file); done(); }) .catch((error: string) => { @@ -102,7 +101,7 @@ describe("DockerfileServiceImpl", () => { }); it("returns rejected promise if given archive file with no Dockerfile present in root directory", (done) => { - dataFileServiceMock.readDataArrayAsPossibleArchive.and.callFake((buf, success, failure) => { + datafileServiceMock.setup(mock => mock.readDataArrayAsPossibleArchive).is((buf, success, failure) => { success(invalidArchiveFile); }); @@ -118,14 +117,14 @@ describe("DockerfileServiceImpl", () => { }); it("calls datafile service to convert blob to string if given file is an archive", (done) => { - dataFileServiceMock.readDataArrayAsPossibleArchive.and.callFake((buf, success, failure) => { + datafileServiceMock.setup(mock => mock.readDataArrayAsPossibleArchive).is((buf, success, failure) => { success(validArchiveFile); }); dockerfileServiceImpl.getDockerfile(file) .then((dockerfile: DockerfileInfoImpl) => { expect(validArchiveFile[0].toBlob).toHaveBeenCalled(); - expect(dataFileServiceMock.blobToString.calls.argsFor(0)[0]).toEqual(validArchiveFile[0].toBlob()); + expect((datafileService.blobToString).calls.argsFor(0)[0]).toEqual(validArchiveFile[0].toBlob()); done(); }) .catch((error: string) => { @@ -137,7 +136,7 @@ describe("DockerfileServiceImpl", () => { it("returns rejected promise if given archive file with invalid Dockerfile", (done) => { forDataSpy.and.returnValue(null); invalidArchiveFile[0].name = 'Dockerfile'; - dataFileServiceMock.readDataArrayAsPossibleArchive.and.callFake((buf, success, failure) => { + datafileServiceMock.setup(mock => mock.readDataArrayAsPossibleArchive).is((buf, success, failure) => { success(invalidArchiveFile); }); @@ -153,7 +152,7 @@ describe("DockerfileServiceImpl", () => { }); it("returns resolved promise of new DockerfileInfoImpl instance if given archive with valid Dockerfile", (done) => { - dataFileServiceMock.readDataArrayAsPossibleArchive.and.callFake((buf, success, failure) => { + datafileServiceMock.setup(mock => mock.readDataArrayAsPossibleArchive).is((buf, success, failure) => { success(validArchiveFile); }); diff --git a/static/js/services/dockerfile/dockerfile.service.impl.ts b/static/js/services/dockerfile/dockerfile.service.impl.ts index e2826b54c..a6e53be81 100644 --- a/static/js/services/dockerfile/dockerfile.service.impl.ts +++ b/static/js/services/dockerfile/dockerfile.service.impl.ts @@ -1,11 +1,12 @@ import { DockerfileService, DockerfileInfo } from './dockerfile.service'; import { Injectable } from 'angular-ts-decorators'; +import { DatafileService } from '../datafile/datafile.service'; @Injectable(DockerfileService.name) export class DockerfileServiceImpl implements DockerfileService { - constructor(private DataFileService: any, + constructor(private DataFileService: DatafileService, private Config: any, private fileReaderFactory: () => FileReader) { diff --git a/yarn.lock b/yarn.lock index 2d7325650..bfeb362ba 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3880,6 +3880,10 @@ ts-loader@^0.9.5: object-assign "^4.1.0" semver "^5.0.1" +ts-mocks@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/ts-mocks/-/ts-mocks-0.2.2.tgz#051e5b3a30068f6b9f1b1faa552a6f172793c6d6" + ts-node@^1.2.1: version "1.7.3" resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-1.7.3.tgz#dee7f8a84751732d3c2e497cac5a02fb117dfee7"