From 671b65624cb56162ec13b32d41cd3116a640e775 Mon Sep 17 00:00:00 2001 From: Jeremy Sestok Date: Tue, 9 Jan 2018 14:34:15 -0500 Subject: [PATCH 01/22] minor updates to reduce lodash usage --- walkoff/client/cases/cases.component.ts | 4 ++-- walkoff/client/devices/devices.component.ts | 5 ++--- walkoff/client/main/main.component.ts | 2 +- walkoff/client/messages/messages.component.ts | 2 +- walkoff/client/scheduler/scheduler.component.ts | 4 ++-- walkoff/client/settings/settings.component.ts | 7 +++---- walkoff/client/utilities.service.ts | 8 ++++++++ 7 files changed, 19 insertions(+), 13 deletions(-) diff --git a/walkoff/client/cases/cases.component.ts b/walkoff/client/cases/cases.component.ts index 549736ccc..8b72b9fb2 100644 --- a/walkoff/client/cases/cases.component.ts +++ b/walkoff/client/cases/cases.component.ts @@ -146,7 +146,7 @@ export class CasesComponent { this.casesService .deleteCase(caseToDelete.id) .then(() => { - this.cases = _.reject(this.cases, c => c.id === caseToDelete.id); + this.cases = this.cases.filter(c => c.id !== caseToDelete.id); this.filterCases(); @@ -267,7 +267,7 @@ export class CasesComponent { //On edit, find and update the edited item if (result.isEdit) { - const toUpdate = _.find(this.cases, c => c.id === result.case.id); + const toUpdate = this.cases.find(c => c.id === result.case.id); Object.assign(toUpdate, result.case); this.filterCases(); diff --git a/walkoff/client/devices/devices.component.ts b/walkoff/client/devices/devices.component.ts index 8a7b30553..d36f69b1a 100644 --- a/walkoff/client/devices/devices.component.ts +++ b/walkoff/client/devices/devices.component.ts @@ -1,6 +1,5 @@ import { Component, ViewEncapsulation } from '@angular/core'; import { FormControl } from '@angular/forms'; -import * as _ from 'lodash'; import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap'; import { ToastyService, ToastyConfig } from 'ng2-toasty'; import { Select2OptionData } from 'ng2-select2'; @@ -106,7 +105,7 @@ export class DevicesComponent { this.devicesService .deleteDevice(deviceToDelete.id) .then(() => { - this.devices = _.reject(this.devices, device => device.id === deviceToDelete.id); + this.devices = this.devices.filter(device => device.id !== deviceToDelete.id); this.filterDevices(); @@ -144,7 +143,7 @@ export class DevicesComponent { //On edit, find and update the edited item if (result.isEdit) { - const toUpdate = _.find(this.devices, d => d.id === result.device.id); + const toUpdate = this.devices.find(d => d.id === result.device.id); Object.assign(toUpdate, result.device); this.filterDevices(); diff --git a/walkoff/client/main/main.component.ts b/walkoff/client/main/main.component.ts index 6220958fd..644821664 100644 --- a/walkoff/client/main/main.component.ts +++ b/walkoff/client/main/main.component.ts @@ -141,7 +141,7 @@ export class MainComponent { this.messageModalRef = this.modalService.open(MessagesModalComponent); - this.messageModalRef.componentInstance.message = _.cloneDeep(message); + this.messageModalRef.componentInstance.message = this.utils.cloneDeep(message); this._handleModalClose(this.messageModalRef); }) diff --git a/walkoff/client/messages/messages.component.ts b/walkoff/client/messages/messages.component.ts index 876302129..fbf9d605a 100644 --- a/walkoff/client/messages/messages.component.ts +++ b/walkoff/client/messages/messages.component.ts @@ -75,7 +75,7 @@ export class MessagesComponent { const modalRef = this.modalService.open(MessagesModalComponent); - modalRef.componentInstance.message = _.cloneDeep(message); + modalRef.componentInstance.message = this.utils.cloneDeep(message); this._handleModalClose(modalRef); }) diff --git a/walkoff/client/scheduler/scheduler.component.ts b/walkoff/client/scheduler/scheduler.component.ts index 4a0aad5fe..edd05c3b9 100644 --- a/walkoff/client/scheduler/scheduler.component.ts +++ b/walkoff/client/scheduler/scheduler.component.ts @@ -108,7 +108,7 @@ export class SchedulerComponent { this.schedulerService .deleteScheduledTask(taskToDelete.id) .then(() => { - this.scheduledTasks = _.reject(this.scheduledTasks, scheduledTask => scheduledTask.id === taskToDelete.id); + this.scheduledTasks = this.scheduledTasks.filter(scheduledTask => scheduledTask.id !== taskToDelete.id); this.filterScheduledTasks(); @@ -194,7 +194,7 @@ export class SchedulerComponent { //On edit, find and update the edited item if (result.isEdit) { - const toUpdate = _.find(this.scheduledTasks, st => st.id === result.scheduledTask.id); + const toUpdate = this.scheduledTasks.find(st => st.id === result.scheduledTask.id); Object.assign(toUpdate, result.scheduledTask); this.filterScheduledTasks(); diff --git a/walkoff/client/settings/settings.component.ts b/walkoff/client/settings/settings.component.ts index d69a319fe..8d1ce209c 100644 --- a/walkoff/client/settings/settings.component.ts +++ b/walkoff/client/settings/settings.component.ts @@ -1,6 +1,5 @@ import { Component } from '@angular/core'; import { FormControl } from '@angular/forms'; -import * as _ from 'lodash'; import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap'; import { ToastyService, ToastyConfig } from 'ng2-toasty'; import 'rxjs/add/operator/debounceTime'; @@ -128,7 +127,7 @@ export class SettingsComponent { this.settingsService .deleteUser(userToDelete.id) .then(() => { - this.users = _.reject(this.users, user => user.id === userToDelete.id); + this.users = this.users.filter(user => user.id !== userToDelete.id); this.filterUsers(); @@ -138,7 +137,7 @@ export class SettingsComponent { } getFriendlyRoles(roles: Role[]): string { - return _.map(roles, 'name').join(', '); + return roles.map(r => r.name).join(', '); } getFriendlyBool(val: boolean): string { @@ -153,7 +152,7 @@ export class SettingsComponent { //On edit, find and update the edited item if (result.isEdit) { - const toUpdate = _.find(this.users, u => u.id === result.user.id); + const toUpdate = this.users.find(u => u.id === result.user.id); Object.assign(toUpdate, result.user); this.filterUsers(); diff --git a/walkoff/client/utilities.service.ts b/walkoff/client/utilities.service.ts index 949804d5f..cc915efc7 100644 --- a/walkoff/client/utilities.service.ts +++ b/walkoff/client/utilities.service.ts @@ -45,4 +45,12 @@ export class UtilitiesService { getRelativeLocalTime(time: Date | string): string { return moment.utc(time).local().fromNow(); } + + /** + * Clones JSON into a new value. + * @param val Value to clone + */ + cloneDeep(val: T): T { + return JSON.parse(JSON.stringify(val)); + } } From 9ee562d0f57e0880291ba287bc4029f4d72ebd12 Mon Sep 17 00:00:00 2001 From: Jeremy Sestok Date: Wed, 10 Jan 2018 13:44:46 -0500 Subject: [PATCH 02/22] updating paths for webpack, other small updates --- .gitignore | 2 ++ walkoff/client/cases/cases.component.ts | 4 +-- walkoff/client/cases/cases.modal.component.ts | 4 +-- .../client/dashboard/dashboard.component.ts | 4 +-- walkoff/client/devices/devices.component.ts | 4 +-- .../client/devices/devices.modal.component.ts | 4 +-- .../client/interfaces/interfaces.component.ts | 4 +-- walkoff/client/main/main.component.ts | 4 +-- walkoff/client/messages/messages.component.ts | 4 +-- .../messages/messages.modal.component.ts | 4 +-- walkoff/client/package.json | 31 ++++++++++++++----- .../playbook/playbook.argument.component.ts | 2 +- walkoff/client/playbook/playbook.component.ts | 4 +-- .../playbook/playbook.conditions.component.ts | 2 +- .../playbook/playbook.transforms.component.ts | 2 +- .../client/scheduler/scheduler.component.ts | 4 +-- .../scheduler/scheduler.modal.component.ts | 4 +-- walkoff/client/settings/settings.component.ts | 4 +-- .../settings/settings.roles.component.ts | 4 +-- .../settings.roles.modal.component.ts | 4 +-- .../settings/settings.user.modal.component.ts | 4 +-- walkoff/client/tsconfig.json | 28 +++++++++++------ walkoff/templates/index.html | 7 +++-- 23 files changed, 84 insertions(+), 54 deletions(-) diff --git a/.gitignore b/.gitignore index 6078655b0..7b186b37c 100644 --- a/.gitignore +++ b/.gitignore @@ -26,5 +26,7 @@ tests/testWorkflows/testGeneratedWorkflows_bkup walkoff/api/composed_api.yaml walkoff/client/node_modules/ walkoff/client/build/ +walkoff/client/coverage/ +walkoff/client/dist/ !apps/*.py !interfaces/*.py \ No newline at end of file diff --git a/walkoff/client/cases/cases.component.ts b/walkoff/client/cases/cases.component.ts index 8b72b9fb2..efa4f4b44 100644 --- a/walkoff/client/cases/cases.component.ts +++ b/walkoff/client/cases/cases.component.ts @@ -29,10 +29,10 @@ const childrenTypes = ['workflows', 'actions', 'branches', 'conditions', 'transf @Component({ selector: 'cases-component', - templateUrl: 'client/cases/cases.html', + templateUrl: './cases.html', encapsulation: ViewEncapsulation.None, styleUrls: [ - 'client/cases/cases.css', + './cases.css', ], providers: [CasesService], }) diff --git a/walkoff/client/cases/cases.modal.component.ts b/walkoff/client/cases/cases.modal.component.ts index 9d0929eba..371f7ecae 100644 --- a/walkoff/client/cases/cases.modal.component.ts +++ b/walkoff/client/cases/cases.modal.component.ts @@ -12,9 +12,9 @@ import { Subscription } from '../models/subscription'; @Component({ encapsulation: ViewEncapsulation.None, selector: 'case-modal', - templateUrl: 'client/cases/cases.modal.html', + templateUrl: './cases.modal.html', styleUrls: [ - 'client/cases/cases.modal.css', + './cases.modal.css', ], providers: [CasesService], }) diff --git a/walkoff/client/dashboard/dashboard.component.ts b/walkoff/client/dashboard/dashboard.component.ts index d62e761cf..b04a68c36 100644 --- a/walkoff/client/dashboard/dashboard.component.ts +++ b/walkoff/client/dashboard/dashboard.component.ts @@ -4,9 +4,9 @@ import { DashboardService } from './dashboard.service'; @Component({ selector: 'dashboard-component', - templateUrl: 'client/dashboard/dashboard.html', + templateUrl: './dashboard.html', styleUrls: [ - 'client/dashboard/dashboard.css', + './dashboard.css', ], providers: [DashboardService], }) diff --git a/walkoff/client/devices/devices.component.ts b/walkoff/client/devices/devices.component.ts index d36f69b1a..032517f8d 100644 --- a/walkoff/client/devices/devices.component.ts +++ b/walkoff/client/devices/devices.component.ts @@ -13,9 +13,9 @@ import { AppApi } from '../models/api/appApi'; @Component({ selector: 'devices-component', - templateUrl: 'client/devices/devices.html', + templateUrl: './devices.html', styleUrls: [ - 'client/devices/devices.css', + './devices.css', ], encapsulation: ViewEncapsulation.None, providers: [DevicesService], diff --git a/walkoff/client/devices/devices.modal.component.ts b/walkoff/client/devices/devices.modal.component.ts index 647e42844..1422ae133 100644 --- a/walkoff/client/devices/devices.modal.component.ts +++ b/walkoff/client/devices/devices.modal.component.ts @@ -11,9 +11,9 @@ import { ParameterSchema } from '../models/api/parameterSchema'; @Component({ selector: 'device-modal', - templateUrl: 'client/devices/devices.modal.html', + templateUrl: './devices.modal.html', styleUrls: [ - 'client/devices/devices.css', + './devices.css', ], providers: [DevicesService], }) diff --git a/walkoff/client/interfaces/interfaces.component.ts b/walkoff/client/interfaces/interfaces.component.ts index f3242d63d..89d5a8d28 100644 --- a/walkoff/client/interfaces/interfaces.component.ts +++ b/walkoff/client/interfaces/interfaces.component.ts @@ -6,8 +6,8 @@ import { AuthService } from '../auth/auth.service'; @Component({ selector: 'interfaces-component', - templateUrl: 'client/interfaces/interfaces.html', - styleUrls: ['client/interfaces/interfaces.css'], + templateUrl: './interfaces.html', + styleUrls: ['./interfaces.css'], encapsulation: ViewEncapsulation.None, providers: [AuthService], }) diff --git a/walkoff/client/main/main.component.ts b/walkoff/client/main/main.component.ts index 644821664..50a96f720 100644 --- a/walkoff/client/main/main.component.ts +++ b/walkoff/client/main/main.component.ts @@ -19,9 +19,9 @@ const MAX_TOTAL_MESSAGES = 20; @Component({ selector: 'main-component', - templateUrl: 'client/main/main.html', + templateUrl: './main.html', styleUrls: [ - 'client/main/main.css', + './main.css', ], providers: [MainService, AuthService, UtilitiesService], }) diff --git a/walkoff/client/messages/messages.component.ts b/walkoff/client/messages/messages.component.ts index fbf9d605a..dc2af7d21 100644 --- a/walkoff/client/messages/messages.component.ts +++ b/walkoff/client/messages/messages.component.ts @@ -14,9 +14,9 @@ import { MessageListing } from '../models/message/messageListing'; @Component({ selector: 'messages-component', - templateUrl: 'client/messages/messages.html', + templateUrl: './messages.html', styleUrls: [ - 'client/messages/messages.css', + './messages.css', ], providers: [MessagesService], }) diff --git a/walkoff/client/messages/messages.modal.component.ts b/walkoff/client/messages/messages.modal.component.ts index 535e14122..2ea39ba3a 100644 --- a/walkoff/client/messages/messages.modal.component.ts +++ b/walkoff/client/messages/messages.modal.component.ts @@ -9,9 +9,9 @@ import { Message } from '../models/message/message'; @Component({ selector: 'messages-modal', - templateUrl: 'client/messages/messages.modal.html', + templateUrl: './messages.modal.html', styleUrls: [ - 'client/messages/messages.css', + './messages.css', ], providers: [MessagesService], }) diff --git a/walkoff/client/package.json b/walkoff/client/package.json index 6c4dc2f5f..1a221bd11 100644 --- a/walkoff/client/package.json +++ b/walkoff/client/package.json @@ -1,10 +1,17 @@ { - "name": "WALKOFF", - "description": "WALKOFF", + "name": "walkoff", + "description": "WALKOFF automation and orchestration framework.", "license": "MIT", "scripts": { "build": "gulp ts", + "build:dev": "webpack -p --progress --config webpack.config.js", + "clean:dist": "npm run rimraf -- dist", + "clean:install": "npm set progress=false && npm install", + "clean": "npm cache clean --force && npm run rimraf -- node_modules coverage dist", + "rimraf": "rimraf", "watch": "gulp", + "watch:dev": "webpack -p --progress --config webpack.config.js --watch", + "watch:test": "npm run test -- --auto-watch --no-single-run", "test": "karma start" }, "dependencies": { @@ -51,10 +58,10 @@ "ng2-toasty": "~4.0.3", "ngx-contextmenu": "~1.3.4", "plugin-typescript": "~7.0.6", - "rxjs": "~5.3.0", + "rxjs": "^5.5.6", "select2": "~4.0.3", "systemjs": "~0.20.12", - "zone.js": "~0.8.5" + "zone.js": "~0.8.19" }, "repository": {}, "engines": { @@ -68,21 +75,31 @@ "@types/jstree": "^3.3.35", "@types/lodash": "~4.14.68", "@types/select2": "~4.0.38", + "angular2-template-loader": "^0.6.2", + "awesome-typescript-loader": "^3.4.1", + "css-loader": "^0.28.8", "gulp": "~3.9.1", "gulp-concat": "~2.6.1", "gulp-sourcemaps": "~2.6.0", "gulp-typescript": "~3.2.0", "gulp-uglify": "~3.0.0", + "istanbul-instrumenter-loader": "^3.0.0", "jasmine": "~2.4.1", "jasmine-core": "^2.8.0", "karma": "^2.0.0", "karma-chrome-launcher": "^2.0.0", "karma-coverage": "^1.1.1", - "karma-coverage-istanbul-reporter": "^1.3.3", "karma-jasmine": "^1.1.1", - "karma-jasmine-html-reporter": "^0.2.2", - "karma-remap-istanbul": "^0.6.0", + "karma-mocha-reporter": "^2.2.5", + "karma-remap-coverage": "^0.1.4", + "karma-sourcemap-loader": "^0.3.7", "karma-webpack": "^2.0.9", + "raw-loader": "^0.5.1", + "rimraf": "~2.6.2", + "sass-loader": "^6.0.6", + "style-loader": "^0.19.1", + "to-string-loader": "^1.1.5", + "ts-loader": "^3.2.0", "tslint": "^5.8.0", "typescript": "~2.3.2", "webpack": "^3.10.0" diff --git a/walkoff/client/playbook/playbook.argument.component.ts b/walkoff/client/playbook/playbook.argument.component.ts index f128e4695..08484e7db 100644 --- a/walkoff/client/playbook/playbook.argument.component.ts +++ b/walkoff/client/playbook/playbook.argument.component.ts @@ -16,7 +16,7 @@ const AVAILABLE_TYPES = ['string', 'number', 'boolean']; @Component({ selector: 'playbook-argument-component', - templateUrl: 'client/playbook/playbook.argument.html', + templateUrl: './playbook.argument.html', styleUrls: [], encapsulation: ViewEncapsulation.None, providers: [PlaybookService], diff --git a/walkoff/client/playbook/playbook.component.ts b/walkoff/client/playbook/playbook.component.ts index 57298126d..e3bc25c1d 100644 --- a/walkoff/client/playbook/playbook.component.ts +++ b/walkoff/client/playbook/playbook.component.ts @@ -28,9 +28,9 @@ import { Role } from '../models/role'; @Component({ selector: 'playbook-component', - templateUrl: 'client/playbook/playbook.html', + templateUrl: './playbook.html', styleUrls: [ - 'client/playbook/playbook.css', + './playbook.css', ], encapsulation: ViewEncapsulation.None, providers: [PlaybookService, AuthService], diff --git a/walkoff/client/playbook/playbook.conditions.component.ts b/walkoff/client/playbook/playbook.conditions.component.ts index f6cbcbd08..d7af8ad81 100644 --- a/walkoff/client/playbook/playbook.conditions.component.ts +++ b/walkoff/client/playbook/playbook.conditions.component.ts @@ -11,7 +11,7 @@ import { Condition } from '../models/playbook/condition'; @Component({ selector: 'playbook-conditions-component', - templateUrl: 'client/playbook/playbook.conditions.html', + templateUrl: './playbook.conditions.html', styleUrls: [], encapsulation: ViewEncapsulation.None, providers: [PlaybookService], diff --git a/walkoff/client/playbook/playbook.transforms.component.ts b/walkoff/client/playbook/playbook.transforms.component.ts index 60256ffce..96944a891 100644 --- a/walkoff/client/playbook/playbook.transforms.component.ts +++ b/walkoff/client/playbook/playbook.transforms.component.ts @@ -11,7 +11,7 @@ import { Transform } from '../models/playbook/transform'; @Component({ selector: 'playbook-transforms-component', - templateUrl: 'client/playbook/playbook.transforms.html', + templateUrl: './playbook.transforms.html', styleUrls: [], encapsulation: ViewEncapsulation.None, providers: [PlaybookService], diff --git a/walkoff/client/scheduler/scheduler.component.ts b/walkoff/client/scheduler/scheduler.component.ts index edd05c3b9..9eb9d5076 100644 --- a/walkoff/client/scheduler/scheduler.component.ts +++ b/walkoff/client/scheduler/scheduler.component.ts @@ -14,9 +14,9 @@ import { ScheduledTask } from '../models/scheduledTask'; @Component({ selector: 'scheduler-component', - templateUrl: 'client/scheduler/scheduler.html', + templateUrl: './scheduler.html', styleUrls: [ - 'client/scheduler/scheduler.css', + './scheduler.css', ], encapsulation: ViewEncapsulation.None, providers: [SchedulerService], diff --git a/walkoff/client/scheduler/scheduler.modal.component.ts b/walkoff/client/scheduler/scheduler.modal.component.ts index 5891c07ec..8c89d0f35 100644 --- a/walkoff/client/scheduler/scheduler.modal.component.ts +++ b/walkoff/client/scheduler/scheduler.modal.component.ts @@ -14,9 +14,9 @@ import { GenericObject } from '../models/genericObject'; @Component({ selector: 'scheduler-modal', - templateUrl: 'client/scheduler/scheduler.modal.html', + templateUrl: './scheduler.modal.html', styleUrls: [ - 'client/scheduler/scheduler.css', + './scheduler.css', ], providers: [SchedulerService], }) diff --git a/walkoff/client/settings/settings.component.ts b/walkoff/client/settings/settings.component.ts index 8d1ce209c..f77a9ab74 100644 --- a/walkoff/client/settings/settings.component.ts +++ b/walkoff/client/settings/settings.component.ts @@ -15,9 +15,9 @@ import { Role } from '../models/role'; @Component({ selector: 'settings-component', - templateUrl: 'client/settings/settings.html', + templateUrl: './settings.html', styleUrls: [ - 'client/settings/settings.css', + './settings.css', ], providers: [SettingsService], }) diff --git a/walkoff/client/settings/settings.roles.component.ts b/walkoff/client/settings/settings.roles.component.ts index 7f25bce0d..af51994ec 100644 --- a/walkoff/client/settings/settings.roles.component.ts +++ b/walkoff/client/settings/settings.roles.component.ts @@ -14,9 +14,9 @@ import { GenericObject } from '../models/genericObject'; @Component({ selector: 'settings-roles-component', - templateUrl: 'client/settings/settings.roles.html', + templateUrl: './settings.roles.html', styleUrls: [ - 'client/settings/settings.css', + './settings.css', ], encapsulation: ViewEncapsulation.None, providers: [SettingsService], diff --git a/walkoff/client/settings/settings.roles.modal.component.ts b/walkoff/client/settings/settings.roles.modal.component.ts index 86ce14204..907232317 100644 --- a/walkoff/client/settings/settings.roles.modal.component.ts +++ b/walkoff/client/settings/settings.roles.modal.component.ts @@ -11,9 +11,9 @@ import { Resource } from '../models/resource'; @Component({ selector: 'settings-role-modal', - templateUrl: 'client/settings/settings.roles.modal.html', + templateUrl: './settings.roles.modal.html', styleUrls: [ - 'client/settings/settings.css', + './settings.css', ], providers: [SettingsService], }) diff --git a/walkoff/client/settings/settings.user.modal.component.ts b/walkoff/client/settings/settings.user.modal.component.ts index ee9c64349..1d5532f91 100644 --- a/walkoff/client/settings/settings.user.modal.component.ts +++ b/walkoff/client/settings/settings.user.modal.component.ts @@ -10,9 +10,9 @@ import { Select2OptionData } from 'ng2-select2/ng2-select2.interface'; @Component({ selector: 'user-modal', - templateUrl: 'client/settings/settings.user.modal.html', + templateUrl: './settings.user.modal.html', styleUrls: [ - 'client/settings/settings.css', + './settings.css', ], providers: [SettingsService], }) diff --git a/walkoff/client/tsconfig.json b/walkoff/client/tsconfig.json index 3204c9fe6..438047721 100644 --- a/walkoff/client/tsconfig.json +++ b/walkoff/client/tsconfig.json @@ -1,25 +1,35 @@ { "compilerOptions": { + "allowSyntheticDefaultImports": true, "experimentalDecorators": true, "emitDecoratorMetadata": true, - "lib": ["es2015", "dom", "es2017.object"], + "lib": [ + "es2015", + "dom", + "es2017.object" + ], "module": "commonjs", "moduleResolution": "node", "noImplicitAny": true, "noUnusedLocals": true, "removeComments": true, "preserveConstEnums": true, - // "outFile": "site.js", "target": "es5", - "sourceMap": true, - "typeRoots": ["./node_modules/@types/"] + "typeRoots": [ + "node_modules/@types/" + ], + "sourceMap": true }, "include": [ - "**/*.ts" + "**/*.ts" ], "exclude": [ - "node_modules", - "build", - "**/*.spec.ts" - ] + "node_modules", + "build", + "dist" + ], + "awesomeTypescriptLoaderOptions": { + "forkChecker": true, + "useWebpackText": true + } } \ No newline at end of file diff --git a/walkoff/templates/index.html b/walkoff/templates/index.html index b93c714b4..2de22b55b 100644 --- a/walkoff/templates/index.html +++ b/walkoff/templates/index.html @@ -50,8 +50,9 @@ - - + Loading... From 02e89197825cbbe45dfaf929de66d54958983f48 Mon Sep 17 00:00:00 2001 From: Jeremy Sestok Date: Thu, 11 Jan 2018 10:23:03 -0500 Subject: [PATCH 03/22] restructuring client folder and first tests --- walkoff/client/helpers.js | 28 ++ walkoff/client/karma.conf.js | 141 ++++++++++ walkoff/client/main.ts | 14 - walkoff/client/package.json | 7 +- walkoff/client/spec-bundle.js | 59 +++++ walkoff/client/{ => src}/auth/auth.service.ts | 0 .../client/{ => src}/cases/cases.component.ts | 0 walkoff/client/{ => src}/cases/cases.css | 0 walkoff/client/{ => src}/cases/cases.html | 0 .../{ => src}/cases/cases.modal.component.ts | 0 .../client/{ => src}/cases/cases.modal.css | 0 .../client/{ => src}/cases/cases.modal.html | 0 .../client/{ => src}/cases/cases.service.ts | 0 .../client/{ => src}/dashboard/_widget.html | 0 .../dashboard/dashboard.component.ts | 0 .../client/{ => src}/dashboard/dashboard.css | 0 .../client/{ => src}/dashboard/dashboard.html | 0 .../{ => src}/dashboard/dashboard.service.ts | 0 .../{ => src}/devices/devices.component.ts | 0 walkoff/client/{ => src}/devices/devices.css | 0 walkoff/client/{ => src}/devices/devices.html | 0 .../devices/devices.modal.component.ts | 0 .../{ => src}/devices/devices.modal.html | 0 .../{ => src}/devices/devices.service.ts | 0 .../interfaces/interfaces.component.ts | 0 .../{ => src}/interfaces/interfaces.css | 0 .../{ => src}/interfaces/interfaces.html | 0 walkoff/client/src/jwthttp.factory.ts | 51 ++++ .../{ => src}/login/img/walkoffLogo.png | Bin walkoff/client/{ => src}/login/index.html | 0 .../client/{ => src}/login/login.component.ts | 0 walkoff/client/{ => src}/login/login.html | 0 .../client/{ => src}/login/login.module.ts | 0 .../client/{ => src}/login/login.service.ts | 0 walkoff/client/{ => src}/main.module.ts | 56 +--- walkoff/client/src/main.ts | 16 ++ .../client/{ => src}/main/img/genericUser.png | Bin .../client/src/main/main.component.spec.ts | 155 +++++++++++ .../client/{ => src}/main/main.component.ts | 4 +- walkoff/client/{ => src}/main/main.css | 0 walkoff/client/{ => src}/main/main.html | 4 +- walkoff/client/{ => src}/main/main.service.ts | 0 .../{ => src}/messages/messages.component.ts | 0 .../client/{ => src}/messages/messages.css | 0 .../client/{ => src}/messages/messages.html | 0 .../messages/messages.modal.component.ts | 0 .../{ => src}/messages/messages.modal.html | 0 .../{ => src}/messages/messages.service.ts | 0 .../client/{ => src}/models/accessToken.ts | 0 .../client/{ => src}/models/api/actionApi.ts | 0 walkoff/client/{ => src}/models/api/appApi.ts | 0 .../{ => src}/models/api/conditionApi.ts | 0 .../client/{ => src}/models/api/deviceApi.ts | 0 .../{ => src}/models/api/deviceFieldApi.ts | 0 .../{ => src}/models/api/parameterApi.ts | 0 .../{ => src}/models/api/parameterSchema.ts | 0 .../client/{ => src}/models/api/returnApi.ts | 0 .../{ => src}/models/api/transformApi.ts | 0 .../models/availableResourceAction.ts | 0 .../{ => src}/models/availableSubscription.ts | 0 walkoff/client/{ => src}/models/case.ts | 0 walkoff/client/{ => src}/models/caseEvent.ts | 0 .../client/{ => src}/models/configuration.ts | 0 walkoff/client/{ => src}/models/device.ts | 0 .../client/{ => src}/models/genericObject.ts | 0 .../{ => src}/models/ischeduledTaskArgs.ts | 0 .../{ => src}/models/message/message.ts | 0 .../{ => src}/models/message/messageBody.ts | 0 .../models/message/messageListing.ts | 0 .../{ => src}/models/message/messageUpdate.ts | 0 walkoff/client/{ => src}/models/permission.ts | 0 .../{ => src}/models/playbook/action.ts | 0 .../{ => src}/models/playbook/argument.ts | 0 .../{ => src}/models/playbook/branch.ts | 0 .../{ => src}/models/playbook/condition.ts | 0 .../models/playbook/graphPosition.ts | 0 .../{ => src}/models/playbook/playbook.ts | 0 .../{ => src}/models/playbook/transform.ts | 0 .../{ => src}/models/playbook/widget.ts | 0 .../{ => src}/models/playbook/workflow.ts | 0 .../models/playbook/workflowResult.ts | 0 walkoff/client/{ => src}/models/resource.ts | 0 walkoff/client/{ => src}/models/role.ts | 0 .../client/{ => src}/models/scheduledTask.ts | 0 .../{ => src}/models/scheduledTaskCron.ts | 0 .../{ => src}/models/scheduledTaskDate.ts | 0 .../{ => src}/models/scheduledTaskInterval.ts | 0 .../{ => src}/models/scheduledTaskTrigger.ts | 0 .../client/{ => src}/models/subscription.ts | 0 walkoff/client/{ => src}/models/user.ts | 0 walkoff/client/{ => src}/models/userClaims.ts | 0 .../client/{ => src}/models/workingDevice.ts | 0 .../client/{ => src}/models/workingUser.ts | 0 walkoff/client/{ => src}/pipes/keys.pipe.ts | 0 .../playbook/playbook.argument.component.ts | 6 +- .../{ => src}/playbook/playbook.argument.html | 0 .../{ => src}/playbook/playbook.component.ts | 0 .../playbook/playbook.conditions.component.ts | 4 +- .../playbook/playbook.conditions.html | 0 .../client/{ => src}/playbook/playbook.css | 0 .../client/{ => src}/playbook/playbook.d.ts | 0 .../client/{ => src}/playbook/playbook.html | 0 .../{ => src}/playbook/playbook.service.ts | 0 .../playbook/playbook.transforms.component.ts | 4 +- .../playbook/playbook.transforms.html | 0 walkoff/client/src/polyfills.ts | 37 +++ walkoff/client/{ => src}/routing.ts | 0 .../scheduler/scheduler.component.ts | 0 .../client/{ => src}/scheduler/scheduler.css | 0 .../client/{ => src}/scheduler/scheduler.html | 0 .../scheduler/scheduler.modal.component.ts | 0 .../{ => src}/scheduler/scheduler.modal.html | 0 .../{ => src}/scheduler/scheduler.service.ts | 0 .../{ => src}/settings/settings.component.ts | 0 .../client/{ => src}/settings/settings.css | 0 .../client/{ => src}/settings/settings.html | 0 .../settings/settings.roles.component.ts | 0 .../{ => src}/settings/settings.roles.html | 0 .../settings.roles.modal.component.ts | 0 .../settings/settings.roles.modal.html | 0 .../{ => src}/settings/settings.service.ts | 0 .../settings/settings.user.modal.component.ts | 0 .../settings/settings.user.modal.html | 0 walkoff/client/{ => src}/utilities.service.ts | 0 walkoff/client/tsconfig.webpack.json | 38 +++ walkoff/client/webpack.config.js | 244 ++++++++++++++++++ walkoff/client/webpack.test.config.js | 93 +++++++ 127 files changed, 878 insertions(+), 83 deletions(-) create mode 100644 walkoff/client/helpers.js create mode 100644 walkoff/client/karma.conf.js delete mode 100644 walkoff/client/main.ts create mode 100644 walkoff/client/spec-bundle.js rename walkoff/client/{ => src}/auth/auth.service.ts (100%) rename walkoff/client/{ => src}/cases/cases.component.ts (100%) rename walkoff/client/{ => src}/cases/cases.css (100%) rename walkoff/client/{ => src}/cases/cases.html (100%) rename walkoff/client/{ => src}/cases/cases.modal.component.ts (100%) rename walkoff/client/{ => src}/cases/cases.modal.css (100%) rename walkoff/client/{ => src}/cases/cases.modal.html (100%) rename walkoff/client/{ => src}/cases/cases.service.ts (100%) rename walkoff/client/{ => src}/dashboard/_widget.html (100%) rename walkoff/client/{ => src}/dashboard/dashboard.component.ts (100%) rename walkoff/client/{ => src}/dashboard/dashboard.css (100%) rename walkoff/client/{ => src}/dashboard/dashboard.html (100%) rename walkoff/client/{ => src}/dashboard/dashboard.service.ts (100%) rename walkoff/client/{ => src}/devices/devices.component.ts (100%) rename walkoff/client/{ => src}/devices/devices.css (100%) rename walkoff/client/{ => src}/devices/devices.html (100%) rename walkoff/client/{ => src}/devices/devices.modal.component.ts (100%) rename walkoff/client/{ => src}/devices/devices.modal.html (100%) rename walkoff/client/{ => src}/devices/devices.service.ts (100%) rename walkoff/client/{ => src}/interfaces/interfaces.component.ts (100%) rename walkoff/client/{ => src}/interfaces/interfaces.css (100%) rename walkoff/client/{ => src}/interfaces/interfaces.html (100%) create mode 100644 walkoff/client/src/jwthttp.factory.ts rename walkoff/client/{ => src}/login/img/walkoffLogo.png (100%) rename walkoff/client/{ => src}/login/index.html (100%) rename walkoff/client/{ => src}/login/login.component.ts (100%) rename walkoff/client/{ => src}/login/login.html (100%) rename walkoff/client/{ => src}/login/login.module.ts (100%) rename walkoff/client/{ => src}/login/login.service.ts (100%) rename walkoff/client/{ => src}/main.module.ts (65%) create mode 100644 walkoff/client/src/main.ts rename walkoff/client/{ => src}/main/img/genericUser.png (100%) create mode 100644 walkoff/client/src/main/main.component.spec.ts rename walkoff/client/{ => src}/main/main.component.ts (98%) rename walkoff/client/{ => src}/main/main.css (100%) rename walkoff/client/{ => src}/main/main.html (96%) rename walkoff/client/{ => src}/main/main.service.ts (100%) rename walkoff/client/{ => src}/messages/messages.component.ts (100%) rename walkoff/client/{ => src}/messages/messages.css (100%) rename walkoff/client/{ => src}/messages/messages.html (100%) rename walkoff/client/{ => src}/messages/messages.modal.component.ts (100%) rename walkoff/client/{ => src}/messages/messages.modal.html (100%) rename walkoff/client/{ => src}/messages/messages.service.ts (100%) rename walkoff/client/{ => src}/models/accessToken.ts (100%) rename walkoff/client/{ => src}/models/api/actionApi.ts (100%) rename walkoff/client/{ => src}/models/api/appApi.ts (100%) rename walkoff/client/{ => src}/models/api/conditionApi.ts (100%) rename walkoff/client/{ => src}/models/api/deviceApi.ts (100%) rename walkoff/client/{ => src}/models/api/deviceFieldApi.ts (100%) rename walkoff/client/{ => src}/models/api/parameterApi.ts (100%) rename walkoff/client/{ => src}/models/api/parameterSchema.ts (100%) rename walkoff/client/{ => src}/models/api/returnApi.ts (100%) rename walkoff/client/{ => src}/models/api/transformApi.ts (100%) rename walkoff/client/{ => src}/models/availableResourceAction.ts (100%) rename walkoff/client/{ => src}/models/availableSubscription.ts (100%) rename walkoff/client/{ => src}/models/case.ts (100%) rename walkoff/client/{ => src}/models/caseEvent.ts (100%) rename walkoff/client/{ => src}/models/configuration.ts (100%) rename walkoff/client/{ => src}/models/device.ts (100%) rename walkoff/client/{ => src}/models/genericObject.ts (100%) rename walkoff/client/{ => src}/models/ischeduledTaskArgs.ts (100%) rename walkoff/client/{ => src}/models/message/message.ts (100%) rename walkoff/client/{ => src}/models/message/messageBody.ts (100%) rename walkoff/client/{ => src}/models/message/messageListing.ts (100%) rename walkoff/client/{ => src}/models/message/messageUpdate.ts (100%) rename walkoff/client/{ => src}/models/permission.ts (100%) rename walkoff/client/{ => src}/models/playbook/action.ts (100%) rename walkoff/client/{ => src}/models/playbook/argument.ts (100%) rename walkoff/client/{ => src}/models/playbook/branch.ts (100%) rename walkoff/client/{ => src}/models/playbook/condition.ts (100%) rename walkoff/client/{ => src}/models/playbook/graphPosition.ts (100%) rename walkoff/client/{ => src}/models/playbook/playbook.ts (100%) rename walkoff/client/{ => src}/models/playbook/transform.ts (100%) rename walkoff/client/{ => src}/models/playbook/widget.ts (100%) rename walkoff/client/{ => src}/models/playbook/workflow.ts (100%) rename walkoff/client/{ => src}/models/playbook/workflowResult.ts (100%) rename walkoff/client/{ => src}/models/resource.ts (100%) rename walkoff/client/{ => src}/models/role.ts (100%) rename walkoff/client/{ => src}/models/scheduledTask.ts (100%) rename walkoff/client/{ => src}/models/scheduledTaskCron.ts (100%) rename walkoff/client/{ => src}/models/scheduledTaskDate.ts (100%) rename walkoff/client/{ => src}/models/scheduledTaskInterval.ts (100%) rename walkoff/client/{ => src}/models/scheduledTaskTrigger.ts (100%) rename walkoff/client/{ => src}/models/subscription.ts (100%) rename walkoff/client/{ => src}/models/user.ts (100%) rename walkoff/client/{ => src}/models/userClaims.ts (100%) rename walkoff/client/{ => src}/models/workingDevice.ts (100%) rename walkoff/client/{ => src}/models/workingUser.ts (100%) rename walkoff/client/{ => src}/pipes/keys.pipe.ts (100%) rename walkoff/client/{ => src}/playbook/playbook.argument.component.ts (98%) rename walkoff/client/{ => src}/playbook/playbook.argument.html (100%) rename walkoff/client/{ => src}/playbook/playbook.component.ts (100%) rename walkoff/client/{ => src}/playbook/playbook.conditions.component.ts (97%) rename walkoff/client/{ => src}/playbook/playbook.conditions.html (100%) rename walkoff/client/{ => src}/playbook/playbook.css (100%) rename walkoff/client/{ => src}/playbook/playbook.d.ts (100%) rename walkoff/client/{ => src}/playbook/playbook.html (100%) rename walkoff/client/{ => src}/playbook/playbook.service.ts (100%) rename walkoff/client/{ => src}/playbook/playbook.transforms.component.ts (97%) rename walkoff/client/{ => src}/playbook/playbook.transforms.html (100%) create mode 100644 walkoff/client/src/polyfills.ts rename walkoff/client/{ => src}/routing.ts (100%) rename walkoff/client/{ => src}/scheduler/scheduler.component.ts (100%) rename walkoff/client/{ => src}/scheduler/scheduler.css (100%) rename walkoff/client/{ => src}/scheduler/scheduler.html (100%) rename walkoff/client/{ => src}/scheduler/scheduler.modal.component.ts (100%) rename walkoff/client/{ => src}/scheduler/scheduler.modal.html (100%) rename walkoff/client/{ => src}/scheduler/scheduler.service.ts (100%) rename walkoff/client/{ => src}/settings/settings.component.ts (100%) rename walkoff/client/{ => src}/settings/settings.css (100%) rename walkoff/client/{ => src}/settings/settings.html (100%) rename walkoff/client/{ => src}/settings/settings.roles.component.ts (100%) rename walkoff/client/{ => src}/settings/settings.roles.html (100%) rename walkoff/client/{ => src}/settings/settings.roles.modal.component.ts (100%) rename walkoff/client/{ => src}/settings/settings.roles.modal.html (100%) rename walkoff/client/{ => src}/settings/settings.service.ts (100%) rename walkoff/client/{ => src}/settings/settings.user.modal.component.ts (100%) rename walkoff/client/{ => src}/settings/settings.user.modal.html (100%) rename walkoff/client/{ => src}/utilities.service.ts (100%) create mode 100644 walkoff/client/tsconfig.webpack.json create mode 100644 walkoff/client/webpack.config.js create mode 100644 walkoff/client/webpack.test.config.js diff --git a/walkoff/client/helpers.js b/walkoff/client/helpers.js new file mode 100644 index 000000000..b5cb9ada0 --- /dev/null +++ b/walkoff/client/helpers.js @@ -0,0 +1,28 @@ +/** + * @author: @AngularClass + */ +var path = require('path'); + +const EVENT = process.env.npm_lifecycle_event || ''; + +// Helper functions +var ROOT = path.resolve(__dirname); + +function hasProcessFlag(flag) { + return process.argv.join('').indexOf(flag) > -1; +} + +function hasNpmFlag(flag) { + return EVENT.includes(flag); +} + +function isWebpackDevServer() { + return process.argv[1] && !!(/webpack-dev-server/.exec(process.argv[1])); +} + +var root = path.join.bind(path, ROOT); + +exports.hasProcessFlag = hasProcessFlag; +exports.hasNpmFlag = hasNpmFlag; +exports.isWebpackDevServer = isWebpackDevServer; +exports.root = root; \ No newline at end of file diff --git a/walkoff/client/karma.conf.js b/walkoff/client/karma.conf.js new file mode 100644 index 000000000..2570a1919 --- /dev/null +++ b/walkoff/client/karma.conf.js @@ -0,0 +1,141 @@ +module.exports = (config) => { + // const coverage = config.singleRun ? ['coverage'] : []; + let plugins = [ + 'karma-jasmine', + 'karma-webpack', + 'karma-coverage', + 'karma-chrome-launcher', + 'karma-remap-istanbul', + 'karma-sourcemap-loader', + // 'karma-jasmine-html-reporter', + // 'karma-coverage-istanbul-reporter', + ]; + + let configuration = { + basePath: '', + frameworks: ['jasmine'], + + // plugins: [ + // 'karma-jasmine', + // 'karma-webpack', + // 'karma-coverage', + // 'karma-chrome-launcher', + // 'karma-remap-istanbul', + // // 'karma-jasmine-html-reporter', + // // 'karma-coverage-istanbul-reporter', + // ], + plugins, + + client: { + clearContext: false // leave Jasmine Spec Runner output visible in browser + }, + + coverageIstanbulReporter: { + reports: ['html', 'lcovonly'], + fixWebpackSourcePaths: true + }, + + files: [ + { pattern: 'spec-bundle.js', watched: false }, + // '**/*.spec.ts' + // './tests.entry.ts', + // { + // pattern: '**/*.map', + // served: true, + // included: false, + // watched: true, + // }, + ], + + proxies: { + '/assets/': '/base/src/assets/', + }, + + preprocessors: { + 'spec-bundle.js': ['coverage', 'webpack', 'sourcemap'] + // './src/tests.entry.ts': [ + // 'webpack', + // 'sourcemap', + // ], + // './src/**/!(*.test|tests.*).(ts|js)': [ + // 'sourcemap', + // ], + }, + + webpack: require('./webpack.test.config')({ env: 'test' }), + // { + // plugins, + // entry: './tests.entry.ts', + // devtool: 'inline-source-map', + // resolve: { + // extensions: ['.webpack.js', '.web.js', '.ts', '.js'], + // }, + // module: { + // rules: combinedLoaders().concat(config.singleRun ? [ loaders.istanbulInstrumenter ] : [ ]), + // }, + // stats: { colors: true, reasons: true }, + // }, + coverageReporter: { + type: 'in-memory' + }, + + remapCoverageReporter: { + 'text-summary': null, + json: './coverage/coverage.json', + html: './coverage/html' + }, + + // Webpack please don't spam the console when running in karma! + webpackMiddleware: { + // webpack-dev-middleware configuration + // i.e. + noInfo: true, + // and use stats to turn off verbose output + stats: { + // options i.e. + chunks: false + } + }, + + exclude: [ + 'node_modules/**/*.spec.ts' + ], + + reporters: ['mocha', 'coverage', 'remap-coverage'], + // reporters: ['spec'].concat(coverage), + + // coverageReporter: { + // reporters: [ + // { type: 'json' }, + // ], + // dir: './coverage/', + // subdir: (browser) => { + // return browser.toLowerCase().split(/[ /-]/)[0]; // returns 'chrome' + // }, + // }, + + reporters: ['progress'], + port: 9876, + browsers: ['Chrome'], // Alternatively: 'PhantomJS' + colors: true, + logLevel: config.LOG_INFO, + autoWatch: true, + captureTimeout: 6000, + customLaunchers: { + ChromeTravisCi: { + base: 'Chrome', + flags: ['--no-sandbox'] + } + }, + }; + + if (process.env.TRAVIS) { + configuration.browsers = [ + 'ChromeTravisCi' + ]; + + configuration.singleRun = true; + } + + config.set(configuration); +}; \ No newline at end of file diff --git a/walkoff/client/main.ts b/walkoff/client/main.ts deleted file mode 100644 index 4b152909a..000000000 --- a/walkoff/client/main.ts +++ /dev/null @@ -1,14 +0,0 @@ -// import { enableProdMode } from '@angular/core'; -import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; - -import { MainModule } from './main.module'; - -if (sessionStorage.getItem('refresh_token')) { - //TODO: figure out a good way of handling this - // Enable production mode unless running locally - // if (!/localhost/.test(document.location.host)) { - // enableProdMode(); - // } - - platformBrowserDynamic().bootstrapModule(MainModule); -} else { location.href = '/login'; } diff --git a/walkoff/client/package.json b/walkoff/client/package.json index 1a221bd11..abbc6e44e 100644 --- a/walkoff/client/package.json +++ b/walkoff/client/package.json @@ -3,8 +3,8 @@ "description": "WALKOFF automation and orchestration framework.", "license": "MIT", "scripts": { - "build": "gulp ts", - "build:dev": "webpack -p --progress --config webpack.config.js", + "build": "npm run build:dev", + "build:dev": "npm run clean:dist && npm run webpack -p --progress --config webpack.config.js", "clean:dist": "npm run rimraf -- dist", "clean:install": "npm set progress=false && npm install", "clean": "npm cache clean --force && npm run rimraf -- node_modules coverage dist", @@ -12,7 +12,8 @@ "watch": "gulp", "watch:dev": "webpack -p --progress --config webpack.config.js --watch", "watch:test": "npm run test -- --auto-watch --no-single-run", - "test": "karma start" + "test": "karma start", + "webpack": "node --max_old_space_size=4096 node_modules/webpack/bin/webpack.js" }, "dependencies": { "@angular/animations": "~4.0.3", diff --git a/walkoff/client/spec-bundle.js b/walkoff/client/spec-bundle.js new file mode 100644 index 000000000..16496eefd --- /dev/null +++ b/walkoff/client/spec-bundle.js @@ -0,0 +1,59 @@ +/** + * @author: @AngularClass + */ + +/* + * When testing with webpack and ES6, we have to do some extra + * things to get testing to work right. Because we are gonna write tests + * in ES6 too, we have to compile those as well. That's handled in + * karma.conf.js with the karma-webpack plugin. This is the entry + * file for webpack test. Just like webpack will create a bundle.js + * file for our client, when we run test, it will compile and bundle them + * all here! Crazy huh. So we need to do some setup + */ +Error.stackTraceLimit = Infinity; + +require('core-js/es6'); +require('core-js/es7/reflect'); + +require('zone.js/dist/zone'); +require('zone.js/dist/long-stack-trace-zone'); +require('zone.js/dist/proxy'); // since zone.js 0.6.15 +require('zone.js/dist/sync-test'); +require('zone.js/dist/jasmine-patch'); // put here since zone.js 0.6.14 +require('zone.js/dist/async-test'); +require('zone.js/dist/fake-async-test'); + +// RxJS +require('rxjs/Rx'); + +var testing = require('@angular/core/testing'); +var browser = require('@angular/platform-browser-dynamic/testing'); + +testing.TestBed.initTestEnvironment( + browser.BrowserDynamicTestingModule, + browser.platformBrowserDynamicTesting() +); + +/* + * Ok, this is kinda crazy. We can use the context method on + * require that webpack created in order to tell webpack + * what files we actually want to require or import. + * Below, context will be a function/object with file names as keys. + * Using that regex we are saying look in ../src then find + * any file that ends with spec.ts and get its path. By passing in true + * we say do this recursively + */ +var testContext = require.context('./src', true, /\.spec\.ts/); + +/* + * get all the files, for each file, call the context function + * that will require the file and load it up here. Context will + * loop and require those spec files here + */ +function requireAll(requireContext) { + return requireContext.keys().map(requireContext); +} + +// requires and returns all modules that match +var modules = requireAll(testContext); \ No newline at end of file diff --git a/walkoff/client/auth/auth.service.ts b/walkoff/client/src/auth/auth.service.ts similarity index 100% rename from walkoff/client/auth/auth.service.ts rename to walkoff/client/src/auth/auth.service.ts diff --git a/walkoff/client/cases/cases.component.ts b/walkoff/client/src/cases/cases.component.ts similarity index 100% rename from walkoff/client/cases/cases.component.ts rename to walkoff/client/src/cases/cases.component.ts diff --git a/walkoff/client/cases/cases.css b/walkoff/client/src/cases/cases.css similarity index 100% rename from walkoff/client/cases/cases.css rename to walkoff/client/src/cases/cases.css diff --git a/walkoff/client/cases/cases.html b/walkoff/client/src/cases/cases.html similarity index 100% rename from walkoff/client/cases/cases.html rename to walkoff/client/src/cases/cases.html diff --git a/walkoff/client/cases/cases.modal.component.ts b/walkoff/client/src/cases/cases.modal.component.ts similarity index 100% rename from walkoff/client/cases/cases.modal.component.ts rename to walkoff/client/src/cases/cases.modal.component.ts diff --git a/walkoff/client/cases/cases.modal.css b/walkoff/client/src/cases/cases.modal.css similarity index 100% rename from walkoff/client/cases/cases.modal.css rename to walkoff/client/src/cases/cases.modal.css diff --git a/walkoff/client/cases/cases.modal.html b/walkoff/client/src/cases/cases.modal.html similarity index 100% rename from walkoff/client/cases/cases.modal.html rename to walkoff/client/src/cases/cases.modal.html diff --git a/walkoff/client/cases/cases.service.ts b/walkoff/client/src/cases/cases.service.ts similarity index 100% rename from walkoff/client/cases/cases.service.ts rename to walkoff/client/src/cases/cases.service.ts diff --git a/walkoff/client/dashboard/_widget.html b/walkoff/client/src/dashboard/_widget.html similarity index 100% rename from walkoff/client/dashboard/_widget.html rename to walkoff/client/src/dashboard/_widget.html diff --git a/walkoff/client/dashboard/dashboard.component.ts b/walkoff/client/src/dashboard/dashboard.component.ts similarity index 100% rename from walkoff/client/dashboard/dashboard.component.ts rename to walkoff/client/src/dashboard/dashboard.component.ts diff --git a/walkoff/client/dashboard/dashboard.css b/walkoff/client/src/dashboard/dashboard.css similarity index 100% rename from walkoff/client/dashboard/dashboard.css rename to walkoff/client/src/dashboard/dashboard.css diff --git a/walkoff/client/dashboard/dashboard.html b/walkoff/client/src/dashboard/dashboard.html similarity index 100% rename from walkoff/client/dashboard/dashboard.html rename to walkoff/client/src/dashboard/dashboard.html diff --git a/walkoff/client/dashboard/dashboard.service.ts b/walkoff/client/src/dashboard/dashboard.service.ts similarity index 100% rename from walkoff/client/dashboard/dashboard.service.ts rename to walkoff/client/src/dashboard/dashboard.service.ts diff --git a/walkoff/client/devices/devices.component.ts b/walkoff/client/src/devices/devices.component.ts similarity index 100% rename from walkoff/client/devices/devices.component.ts rename to walkoff/client/src/devices/devices.component.ts diff --git a/walkoff/client/devices/devices.css b/walkoff/client/src/devices/devices.css similarity index 100% rename from walkoff/client/devices/devices.css rename to walkoff/client/src/devices/devices.css diff --git a/walkoff/client/devices/devices.html b/walkoff/client/src/devices/devices.html similarity index 100% rename from walkoff/client/devices/devices.html rename to walkoff/client/src/devices/devices.html diff --git a/walkoff/client/devices/devices.modal.component.ts b/walkoff/client/src/devices/devices.modal.component.ts similarity index 100% rename from walkoff/client/devices/devices.modal.component.ts rename to walkoff/client/src/devices/devices.modal.component.ts diff --git a/walkoff/client/devices/devices.modal.html b/walkoff/client/src/devices/devices.modal.html similarity index 100% rename from walkoff/client/devices/devices.modal.html rename to walkoff/client/src/devices/devices.modal.html diff --git a/walkoff/client/devices/devices.service.ts b/walkoff/client/src/devices/devices.service.ts similarity index 100% rename from walkoff/client/devices/devices.service.ts rename to walkoff/client/src/devices/devices.service.ts diff --git a/walkoff/client/interfaces/interfaces.component.ts b/walkoff/client/src/interfaces/interfaces.component.ts similarity index 100% rename from walkoff/client/interfaces/interfaces.component.ts rename to walkoff/client/src/interfaces/interfaces.component.ts diff --git a/walkoff/client/interfaces/interfaces.css b/walkoff/client/src/interfaces/interfaces.css similarity index 100% rename from walkoff/client/interfaces/interfaces.css rename to walkoff/client/src/interfaces/interfaces.css diff --git a/walkoff/client/interfaces/interfaces.html b/walkoff/client/src/interfaces/interfaces.html similarity index 100% rename from walkoff/client/interfaces/interfaces.html rename to walkoff/client/src/interfaces/interfaces.html diff --git a/walkoff/client/src/jwthttp.factory.ts b/walkoff/client/src/jwthttp.factory.ts new file mode 100644 index 000000000..7c109997e --- /dev/null +++ b/walkoff/client/src/jwthttp.factory.ts @@ -0,0 +1,51 @@ +import { Http, RequestOptions, Response } from '@angular/http'; +import { AuthConfig, tokenNotExpired } from 'angular2-jwt'; +import { JwtConfigService, JwtHttp, RefreshConfig } from 'angular2-jwt-refresh'; + +export function GetJwtHttp(http: Http, options: RequestOptions) { + const jwtOptions: RefreshConfig = { + endPoint: '/api/auth/refresh', + // optional + // payload: { type: 'refresh' }, + beforeSeconds: 300, // refresh token before 5 min + tokenName: 'refresh_token', + refreshTokenGetter: (() => { + const token = sessionStorage.getItem('refresh_token'); + + if (token && tokenNotExpired(null, token)) { return token; } + + //TODO: figure out a better way of handling this... maybe incorporate login into the main component somehow + location.href = '/login'; + return; + }), + tokenSetter: ((res: Response): boolean | Promise => { + res = res.json(); + + if (!(res as any).access_token) { + sessionStorage.removeItem('access_token'); + sessionStorage.removeItem('refresh_token'); + //TODO: figure out a better way of handling this... maybe incorporate login into the main component somehow + location.href = '/login'; + return false; + } + + sessionStorage.setItem('access_token', (res as any).access_token); + // sessionStorage.setItem('refresh_token', (res)['refresh_token']); + + return true; + }), + }; + + const authConfig = new AuthConfig({ + noJwtError: true, + // globalHeaders: [{ 'Accept': 'application/json' }], + tokenName: 'access_token', + tokenGetter: (() => sessionStorage.getItem('access_token')), + }); + + return new JwtHttp( + new JwtConfigService(jwtOptions, authConfig), + http, + options, + ); +} diff --git a/walkoff/client/login/img/walkoffLogo.png b/walkoff/client/src/login/img/walkoffLogo.png similarity index 100% rename from walkoff/client/login/img/walkoffLogo.png rename to walkoff/client/src/login/img/walkoffLogo.png diff --git a/walkoff/client/login/index.html b/walkoff/client/src/login/index.html similarity index 100% rename from walkoff/client/login/index.html rename to walkoff/client/src/login/index.html diff --git a/walkoff/client/login/login.component.ts b/walkoff/client/src/login/login.component.ts similarity index 100% rename from walkoff/client/login/login.component.ts rename to walkoff/client/src/login/login.component.ts diff --git a/walkoff/client/login/login.html b/walkoff/client/src/login/login.html similarity index 100% rename from walkoff/client/login/login.html rename to walkoff/client/src/login/login.html diff --git a/walkoff/client/login/login.module.ts b/walkoff/client/src/login/login.module.ts similarity index 100% rename from walkoff/client/login/login.module.ts rename to walkoff/client/src/login/login.module.ts diff --git a/walkoff/client/login/login.service.ts b/walkoff/client/src/login/login.service.ts similarity index 100% rename from walkoff/client/login/login.service.ts rename to walkoff/client/src/login/login.service.ts diff --git a/walkoff/client/main.module.ts b/walkoff/client/src/main.module.ts similarity index 65% rename from walkoff/client/main.module.ts rename to walkoff/client/src/main.module.ts index c6d2c3784..65fdbb96c 100644 --- a/walkoff/client/main.module.ts +++ b/walkoff/client/src/main.module.ts @@ -1,5 +1,5 @@ import { NgModule } from '@angular/core'; -import { Http, RequestOptions, Response } from '@angular/http'; +import { Http, RequestOptions } from '@angular/http'; import { BrowserModule } from '@angular/platform-browser'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { HttpModule } from '@angular/http'; @@ -7,13 +7,13 @@ import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; import { NgxDatatableModule } from '@swimlane/ngx-datatable'; import { ToastyModule } from 'ng2-toasty'; import { Select2Module } from 'ng2-select2'; -import { AuthConfig, tokenNotExpired } from 'angular2-jwt'; -import { JwtConfigService, JwtHttp, RefreshConfig } from 'angular2-jwt-refresh'; +import { JwtHttp } from 'angular2-jwt-refresh'; import { DateTimePickerModule } from 'ng-pick-datetime'; import { DndModule } from 'ng2-dnd'; // Custom routing module import { RoutingModule } from './routing'; +import { GetJwtHttp } from './jwthttp.factory'; import { MainComponent } from './main/main.component'; import { SchedulerComponent } from './scheduler/scheduler.component'; import { PlaybookComponent } from './playbook/playbook.component'; @@ -81,7 +81,7 @@ import { KeysPipe } from './pipes/keys.pipe'; ], providers: [{ provide: JwtHttp, - useFactory: getJwtHttp, + useFactory: GetJwtHttp, deps: [ Http, RequestOptions ], }], entryComponents: [ @@ -95,51 +95,3 @@ import { KeysPipe } from './pipes/keys.pipe'; bootstrap: [MainComponent], }) export class MainModule {} - -export function getJwtHttp(http: Http, options: RequestOptions) { - const jwtOptions: RefreshConfig = { - endPoint: '/api/auth/refresh', - // optional - // payload: { type: 'refresh' }, - beforeSeconds: 300, // refresh token before 5 min - tokenName: 'refresh_token', - refreshTokenGetter: (() => { - const token = sessionStorage.getItem('refresh_token'); - - if (token && tokenNotExpired(null, token)) { return token; } - - //TODO: figure out a better way of handling this... maybe incorporate login into the main component somehow - location.href = '/login'; - return; - }), - tokenSetter: ((res: Response): boolean | Promise => { - res = res.json(); - - if (!(res as any).access_token) { - sessionStorage.removeItem('access_token'); - sessionStorage.removeItem('refresh_token'); - //TODO: figure out a better way of handling this... maybe incorporate login into the main component somehow - location.href = '/login'; - return false; - } - - sessionStorage.setItem('access_token', (res as any).access_token); - // sessionStorage.setItem('refresh_token', (res)['refresh_token']); - - return true; - }), - }; - - const authConfig = new AuthConfig({ - noJwtError: true, - // globalHeaders: [{ 'Accept': 'application/json' }], - tokenName: 'access_token', - tokenGetter: (() => sessionStorage.getItem('access_token')), - }); - - return new JwtHttp( - new JwtConfigService(jwtOptions, authConfig), - http, - options, - ); -} diff --git a/walkoff/client/src/main.ts b/walkoff/client/src/main.ts new file mode 100644 index 000000000..97c86ef93 --- /dev/null +++ b/walkoff/client/src/main.ts @@ -0,0 +1,16 @@ +// import { enableProdMode } from '@angular/core'; +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; + +import { MainModule } from './main.module'; + +document.addEventListener('DOMContentLoaded', function (event) { + if (sessionStorage.getItem('refresh_token')) { + //TODO: figure out a good way of handling this + // Enable production mode unless running locally + // if (!/localhost/.test(document.location.host)) { + // enableProdMode(); + // } + + platformBrowserDynamic().bootstrapModule(MainModule); + } else { location.href = '/login'; } +}); diff --git a/walkoff/client/main/img/genericUser.png b/walkoff/client/src/main/img/genericUser.png similarity index 100% rename from walkoff/client/main/img/genericUser.png rename to walkoff/client/src/main/img/genericUser.png diff --git a/walkoff/client/src/main/main.component.spec.ts b/walkoff/client/src/main/main.component.spec.ts new file mode 100644 index 000000000..77c595eb7 --- /dev/null +++ b/walkoff/client/src/main/main.component.spec.ts @@ -0,0 +1,155 @@ +import { HttpModule, Http, RequestOptions } from '@angular/http'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { async, fakeAsync, tick, TestBed, ComponentFixture } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; +import { } from 'jasmine'; +import { JwtHttp } from 'angular2-jwt-refresh'; +import { ToastyModule } from 'ng2-toasty'; +import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; + +import { GetJwtHttp } from '../jwthttp.factory'; +import { MainComponent } from './main.component'; +import { MainService } from './main.service'; +import { AuthService } from '../auth/auth.service'; + +// import { Message } from '../models/message/message'; +import { MessageListing } from '../models/message/messageListing'; + +describe('App', () => { + let comp: MainComponent; + let fixture: ComponentFixture; + + // let getInterfaceNamesSpy: jasmine.Spy; + // let getInitialNotificationsSpy: jasmine.Spy; + // let getAndDecodeAccessTokenSpy: jasmine.Spy; + + let mainService: MainService; + let authService: AuthService; + + const testInterfaceNames = ['MyInterface', 'SomeOtherInterface', 'ThirdInterface']; + const testInitialNotifications: MessageListing[] = [ + { + id: 5, + subject: 'Need Action', + created_at: new Date(), + awaiting_response: true, + is_read: false, + last_read_at: null, + }, + { + id: 4, + subject: 'Informative Message', + created_at: new Date(), + awaiting_response: false, + is_read: false, + last_read_at: null, + }, + { + id: 3, + subject: 'Already Acted On', + created_at: new Date(), + awaiting_response: false, + is_read: true, + last_read_at: new Date(), + }, + { + id: 2, + subject: 'Already Read', + created_at: new Date(), + awaiting_response: true, + is_read: true, + last_read_at: new Date(), + }, + { + id: 1, + subject: 'Another One', + created_at: new Date(), + awaiting_response: false, + is_read: true, + last_read_at: new Date(), + }, + ]; + // const testMessage: Message = { }; + const testDecodedJwt = { user_claims: { username: 'test' } }; + + /** + * async beforeEach + */ + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [ + HttpModule, + NgbModule.forRoot(), + ToastyModule.forRoot(), + ], + declarations: [MainComponent], + schemas: [NO_ERRORS_SCHEMA], + providers: [MainService, AuthService, { + provide: JwtHttp, + useFactory: GetJwtHttp, + deps: [Http, RequestOptions], + }], + }) + .compileComponents(); + })); + + /** + * Synchronous beforeEach + */ + beforeEach(() => { + fixture = TestBed.createComponent(MainComponent); + comp = fixture.componentInstance; + + // Services actually injected into the component + mainService = fixture.debugElement.injector.get(MainService); + authService = fixture.debugElement.injector.get(AuthService); + + spyOn(comp, 'getNotificationsSSE').and.stub(); + + spyOn(mainService, 'getInterfaceNames') + .and.returnValue(Promise.resolve(testInterfaceNames)); + spyOn(mainService, 'getInitialNotifications') + .and.returnValue(Promise.resolve(testInitialNotifications)); + // spyOn(mainService, 'getMessage') + // .and.returnValue(Promise.resolve(testInterfaceNames)); + spyOn(authService, 'getAndDecodeAccessToken') + .and.returnValue(testDecodedJwt); + + /** + * Trigger initial data binding + */ + }); + + it('should properly load the username', () => { + fixture.detectChanges(); + expect(comp.currentUser).toEqual('test'); + const el = fixture.debugElement.query(By.css('.userName')); + expect(el.nativeElement.textContent).toEqual('test'); + }); + + it('should grab interface names', fakeAsync(() => { + fixture.detectChanges(); + expect(comp.interfaceNames).toBeTruthy(); + expect(comp.interfaceNames.length).toBe(0); + tick(); + fixture.detectChanges(); + expect(fixture.componentInstance.interfaceNames).toBe(testInterfaceNames); + const els = fixture.debugElement.queryAll(By.css('.installedInterface')); + expect(els.length).toBeGreaterThan(0); + })); + + it('should grab initial notifications', fakeAsync(() => { + fixture.detectChanges(); + expect(comp.messageListings).toBeTruthy(); + expect(comp.messageListings.length).toBe(0); + tick(); + fixture.detectChanges(); + expect(comp.messageListings.length).toBeGreaterThan(0); + // also check that the unread number changes, and the list of messages + const el = fixture.debugElement.query(By.css('.messages-menu a span')); + // 2 unread messages + expect(el.nativeElement.textContent).toEqual('2'); + const els = fixture.debugElement.queryAll(By.css('.messageTable tr')); + expect(els.length).toEqual(5); + })); +}); diff --git a/walkoff/client/main/main.component.ts b/walkoff/client/src/main/main.component.ts similarity index 98% rename from walkoff/client/main/main.component.ts rename to walkoff/client/src/main/main.component.ts index 50a96f720..ac4ea03f1 100644 --- a/walkoff/client/main/main.component.ts +++ b/walkoff/client/src/main/main.component.ts @@ -1,4 +1,4 @@ -import { Component } from '@angular/core'; +import { Component, OnInit } from '@angular/core'; import { JwtHelper } from 'angular2-jwt'; import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap'; import { ToastyService, ToastyConfig } from 'ng2-toasty'; @@ -25,7 +25,7 @@ const MAX_TOTAL_MESSAGES = 20; ], providers: [MainService, AuthService, UtilitiesService], }) -export class MainComponent { +export class MainComponent implements OnInit { utils = new UtilitiesService(); currentUser: string; interfaceNames: string[] = []; diff --git a/walkoff/client/main/main.css b/walkoff/client/src/main/main.css similarity index 100% rename from walkoff/client/main/main.css rename to walkoff/client/src/main/main.css diff --git a/walkoff/client/main/main.html b/walkoff/client/src/main/main.html similarity index 96% rename from walkoff/client/main/main.html rename to walkoff/client/src/main/main.html index fa84e1d5d..ca9865090 100644 --- a/walkoff/client/main/main.html +++ b/walkoff/client/src/main/main.html @@ -81,14 +81,14 @@ - User Image + User Image {{currentUser}}