From 7b35c0c0d586565e98ce80653da43aedec536c3e Mon Sep 17 00:00:00 2001 From: alecmerdler Date: Sun, 5 Mar 2017 20:47:23 -0800 Subject: [PATCH] refactored BuildService --- static/js/quay.module.ts | 2 + static/js/services/build-service.js | 62 -------------- .../services/build/build.service.impl.spec.ts | 76 +++++++++++++++++ .../js/services/build/build.service.impl.ts | 84 +++++++++++++++++++ static/js/services/build/build.service.ts | 19 +++++ static/js/services/view-array/view-array.ts | 2 + 6 files changed, 183 insertions(+), 62 deletions(-) delete mode 100644 static/js/services/build-service.js create mode 100644 static/js/services/build/build.service.impl.spec.ts create mode 100644 static/js/services/build/build.service.impl.ts create mode 100644 static/js/services/build/build.service.ts diff --git a/static/js/quay.module.ts b/static/js/quay.module.ts index f8d54c5a0..b0fb55d44 100644 --- a/static/js/quay.module.ts +++ b/static/js/quay.module.ts @@ -12,6 +12,7 @@ import { LinearWorkflowComponent } from './directives/ui/linear-workflow/linear- import { LinearWorkflowSectionComponent } from './directives/ui/linear-workflow/linear-workflow-section.component'; import { QuayConfig } from './quay-config.module'; import { QuayRun } from './quay-run.module'; +import { BuildServiceImpl } from './services/build/build.service.impl'; /** @@ -33,6 +34,7 @@ import { QuayRun } from './quay-run.module'; ], providers: [ ViewArrayImpl, + BuildServiceImpl, ], }) export class quay { diff --git a/static/js/services/build-service.js b/static/js/services/build-service.js deleted file mode 100644 index 0f68edec2..000000000 --- a/static/js/services/build-service.js +++ /dev/null @@ -1,62 +0,0 @@ -/** - * Service which provides helper methods for reasoning about builds. - */ -angular.module('quay').factory('BuildService', [function() { - var buildService = {}; - buildService.isActive = function(build) { - return build.phase != 'complete' && build.phase != 'error' && build.phase != 'expired' && build.phase != 'cancelled'; - }; - - buildService.getBuildMessage = function(phase) { - switch (phase) { - case 'cannot_load': - return 'Cannot load build status'; - - case 'starting': - case 'initializing': - return 'Starting Dockerfile build'; - - case 'waiting': - return 'Waiting for available build worker'; - - case 'unpacking': - return 'Unpacking build package'; - - case 'pulling': - return 'Pulling base image'; - - case 'building': - return 'Building image from Dockerfile'; - - case 'checking-cache': - return 'Looking up cached images'; - - case 'priming-cache': - return 'Priming cache for build'; - - case 'build-scheduled': - return 'Preparing build node'; - - case 'pushing': - return 'Pushing image built from Dockerfile'; - - case 'complete': - return 'Dockerfile build completed and pushed'; - - case 'error': - return 'Dockerfile build failed'; - - case 'expired': - return 'Build did not complete after 3 attempts. Re-submit this build to try again.'; - - case 'internalerror': - return 'An internal system error occurred while building; the build will be retried in the next few minutes.'; - - case 'cancelled': - return 'This build was previously cancelled.'; - - } - }; - - return buildService; -}]); diff --git a/static/js/services/build/build.service.impl.spec.ts b/static/js/services/build/build.service.impl.spec.ts new file mode 100644 index 000000000..48c5aa841 --- /dev/null +++ b/static/js/services/build/build.service.impl.spec.ts @@ -0,0 +1,76 @@ +import { BuildServiceImpl } from './build.service.impl'; + + +describe("BuildServiceImpl", () => { + var buildServiceImpl: BuildServiceImpl; + var build: {phase: string}; + + beforeEach(() => { + buildServiceImpl = new BuildServiceImpl(); + build = {phase: ""}; + }); + + describe("isActive", () => { + var phases: string[]; + + beforeEach(() => { + phases = ['complete', 'error', 'expired', 'cancelled']; + }); + + it("returns false if given build's phase matches an inactive phase", () => { + phases.forEach((phase: string) => { + build.phase = phase; + + expect(buildServiceImpl.isActive(build)).toBe(false); + }); + }); + + it("returns true if given build's phase does not match inactive phases", () => { + build.phase = 'initializing'; + + expect(buildServiceImpl.isActive(build)).toBe(true); + }); + }); + + describe("getBuildMessage", () => { + var buildMessages: {phase: string, message: string}[]; + + beforeEach(() => { + buildMessages = [ + {phase: 'cannot_load', message: 'Cannot load build status'}, + {phase: 'starting', message: 'Starting Dockerfile build'}, + {phase: 'initializing', message: 'Starting Dockerfile build'}, + {phase: 'waiting', message: 'Waiting for available build worker'}, + {phase: 'unpacking', message: 'Unpacking build package'}, + {phase: 'pulling', message: 'Pulling base image'}, + {phase: 'building', message: 'Building image from Dockerfile'}, + {phase: 'checking-cache', message: 'Looking up cached images'}, + {phase: 'priming-cache', message: 'Priming cache for build'}, + {phase: 'build-scheduled', message: 'Preparing build node'}, + {phase: 'pushing', message: 'Pushing image built from Dockerfile'}, + {phase: 'complete', message: 'Dockerfile build completed and pushed'}, + {phase: 'error', message: 'Dockerfile build failed'}, + {phase: 'expired', message: 'Build did not complete after 3 attempts. Re-submit this build to try again.'}, + {phase: 'internalerror', message: 'An internal system error occurred while building; the build will be retried in the next few minutes.'}, + {phase: 'cancelled', message: 'This build was previously cancelled.'}, + ]; + }); + + it("returns the correct message for the given phase", () => { + buildMessages.forEach((buildMessage) => { + expect(buildServiceImpl.getBuildMessage(buildMessage.phase)).toEqual(buildMessage.message, buildMessage); + }); + }); + + it("throws an error if given phase is not supported", () => { + var phase: string = "not-a-phase"; + + try { + buildServiceImpl.getBuildMessage(phase); + fail("Should throw error"); + } catch (error) { + expect(error.message).toEqual("Invalid build phase"); + } + }); + }); +}); \ No newline at end of file diff --git a/static/js/services/build/build.service.impl.ts b/static/js/services/build/build.service.impl.ts new file mode 100644 index 000000000..05d08dd62 --- /dev/null +++ b/static/js/services/build/build.service.impl.ts @@ -0,0 +1,84 @@ +import { BuildService } from './build.service'; +import { Injectable } from 'angular-ts-decorators'; + + +@Injectable(BuildService.name) +export class BuildServiceImpl implements BuildService { + + private inactivePhases: string[] = ['complete', 'error', 'expired', 'cancelled']; + + public isActive(build: {phase: string}): boolean { + return this.inactivePhases.indexOf(build.phase) == -1; + } + + public getBuildMessage(phase: string): string { + var message: string; + switch (phase) { + case 'cannot_load': + message = 'Cannot load build status'; + break; + + case 'starting': + case 'initializing': + message = 'Starting Dockerfile build'; + break; + + case 'waiting': + message = 'Waiting for available build worker'; + break; + + case 'unpacking': + message = 'Unpacking build package'; + break; + + case 'pulling': + message = 'Pulling base image'; + break; + + case 'building': + message = 'Building image from Dockerfile'; + break; + + case 'checking-cache': + message = 'Looking up cached images'; + break; + + case 'priming-cache': + message = 'Priming cache for build'; + break; + + case 'build-scheduled': + message = 'Preparing build node'; + break; + + case 'pushing': + message = 'Pushing image built from Dockerfile'; + break; + + case 'complete': + message = 'Dockerfile build completed and pushed'; + break; + + case 'error': + message = 'Dockerfile build failed'; + break; + + case 'expired': + message = 'Build did not complete after 3 attempts. Re-submit this build to try again.'; + break; + + case 'internalerror': + message = 'An internal system error occurred while building; the build will be retried in the next few minutes.'; + break; + + case 'cancelled': + message = 'This build was previously cancelled.'; + break; + + default: + throw new Error("Invalid build phase"); + } + + return message; + } +} \ No newline at end of file diff --git a/static/js/services/build/build.service.ts b/static/js/services/build/build.service.ts new file mode 100644 index 000000000..d07f9d111 --- /dev/null +++ b/static/js/services/build/build.service.ts @@ -0,0 +1,19 @@ +/** + * Service which provides helper methods for reasoning about builds. + */ +export abstract class BuildService { + + /** + * Determine if the given build is active. + * @param build The build object. + * @return isActive If the given build is active. + */ + public abstract isActive(build: {phase: string}): boolean; + + /** + * Generate a message based on a given phase. + * @param phase The phase type. + * @return buildMessage The message associated with the given phase. + */ + public abstract getBuildMessage(phase: string): string; +} \ No newline at end of file diff --git a/static/js/services/view-array/view-array.ts b/static/js/services/view-array/view-array.ts index fbdfaf4db..4b7abbd35 100644 --- a/static/js/services/view-array/view-array.ts +++ b/static/js/services/view-array/view-array.ts @@ -1,4 +1,6 @@ import { ViewArrayImpl } from "static/js/services/view-array/view-array.impl"; + + /** * Specialized wrapper around array which provides a toggle() method for viewing the contents of the * array in a manner that is asynchronously filled in over a short time period. This prevents long