Merge branch 'rrt/dev' into rrt/production

This commit is contained in:
Aaron Louie 2020-06-15 14:58:48 -04:00
commit 2ccace8e6d
10 changed files with 110 additions and 95 deletions

View File

@ -32,6 +32,6 @@ RUN echo "pushstate: enabled" > /etc/nginx/html/Staticfile
# then starts/reloads nginx. # then starts/reloads nginx.
ENTRYPOINT ["./entrypoint.sh", \ ENTRYPOINT ["./entrypoint.sh", \
"/etc/nginx/html/index.html,/etc/nginx/conf.d/default.conf", \ "/etc/nginx/html/index.html,/etc/nginx/conf.d/default.conf", \
"PRODUCTION,API_URL,IRB_URL,HOME_ROUTE,BASE_HREF,DEPLOY_URL,PORT0,GOOGLE_ANALYTICS_KEY", \ "PRODUCTION,API_URL,IRB_URL,HOME_ROUTE,BASE_HREF,DEPLOY_URL,PORT0,GOOGLE_ANALYTICS_KEY,SENTRY_KEY,TITLE", \
"/etc/nginx/html", \ "/etc/nginx/html", \
"true"] "true"]

View File

@ -1,14 +1,20 @@
version: "3.3" version: "3.3"
services: services:
ldap:
container_name: ldap
image: tuxmonteiro/ldap-mock
ports:
- "3890:3890"
db: db:
container_name: db container_name: db
image: sartography/cr-connect-db:dev image: sartography/cr-connect-db:$E2E_TAG
ports: ports:
- "5432:5432" - "5432:5432"
environment: environment:
- POSTGRES_USER=rrt_user - POSTGRES_USER=crc_user
- POSTGRES_PASSWORD=rrt_pass - POSTGRES_PASSWORD=crc_pass
- POSTGRES_MULTIPLE_DATABASES=rrt - POSTGRES_MULTIPLE_DATABASES=crc_test,pb_test
healthcheck: healthcheck:
test: ["CMD", "pg_isready"] test: ["CMD", "pg_isready"]
timeout: 20s timeout: 20s
@ -18,52 +24,73 @@ services:
container_name: backend container_name: backend
depends_on: depends_on:
- db - db
image: sartography/cr-connect-workflow:dev image: sartography/cr-connect-workflow:$E2E_TAG
environment: environment:
- APPLICATION_ROOT=/api - APPLICATION_ROOT=/
- CORS_ALLOW_ORIGINS=localhost:5002,bpmn:5002,localhost:4200,frontend:4200 - CORS_ALLOW_ORIGINS=localhost:5002,bpmn:5002,localhost:4200,frontend:4200
- DB_HOST=db - DB_HOST=db
- DB_NAME=rrt - DB_NAME=crc_test
- DB_PASSWORD=rrt_pass - DB_PASSWORD=crc_pass
- DB_PORT=5432 - DB_PORT=5432
- DB_USER=rrt_user - DB_USER=crc_user
- LDAP_URL=ldap.virginia.edu - LDAP_URL=ldap
- PB_ENABLED=false - PB_ENABLED=true
- PB_BASE_URL=http://pb:5001/v2.0/
- PORT0=5000 - PORT0=5000
- RESET_DB=true - RESET_DB=true
- UPGRADE_DB=true - UPGRADE_DB=true
- TESTING=true
ports: ports:
- "5000:5000" - "5000:5000"
command: ./wait-for-it.sh db:5432 -t 0 -- ./docker_run.sh command: ./wait-for-it.sh db:5432 -t 0 -- ./docker_run.sh
bpmn: pb:
container_name: bpmn container_name: pb
depends_on: depends_on:
- db - db
- backend image: sartography/protocol-builder-mock:$E2E_TAG
image: sartography/cr-connect-bpmn:dev
environment: environment:
- API_URL=http://localhost:5000/api/v1.0 - APPLICATION_ROOT=/
- BASE_HREF=/bpmn/ - CORS_ALLOW_ORIGINS=localhost:5000,backend:5000,localhost:5002,bpmn:5002,localhost:4200,frontend:4200
- DEPLOY_URL=/bpmn/ - DB_HOST=db
- HOME_ROUTE=home - DB_NAME=pb_test
- PORT0=5002 - DB_PASSWORD=crc_pass
- PRODUCTION=false - DB_PORT=5432
- DB_USER=crc_user
- PORT0=5001
- UPGRADE_DB=true
ports: ports:
- "5002:5002" - "5001:5001"
command: ./wait-for-it.sh db:5432 -t 0 -- ./docker_run.sh
frontend: # bpmn:
container_name: frontend # container_name: bpmn
depends_on: # depends_on:
- db # - db
- backend # - backend
image: sartography/cr-connect-frontend:dev # image: sartography/cr-connect-bpmn:dev
environment: # environment:
- API_URL=http://localhost:5000/api/v1.0 # - API_URL=http://localhost:5000/api/v1.0
- BASE_HREF=/app/ # - BASE_HREF=/bpmn/
- DEPLOY_URL=/app/ # - DEPLOY_URL=/bpmn/
- HOME_ROUTE=home # - HOME_ROUTE=home
- PORT0=4200 # - PORT0=5002
- PRODUCTION=false # - PRODUCTION=false
ports: # ports:
- "4200:4200" # - "5002:5002"
#
# frontend:
# container_name: frontend
# depends_on:
# - db
# - backend
# image: sartography/cr-connect-frontend:dev
# environment:
# - API_URL=http://localhost:5000/api/v1.0
# - BASE_HREF=/app/
# - DEPLOY_URL=/app/
# - HOME_ROUTE=home
# - PORT0=4200
# - PRODUCTION=false
# ports:
# - "4200:4200"

6
package-lock.json generated
View File

@ -12356,9 +12356,9 @@
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
}, },
"sartography-workflow-lib": { "sartography-workflow-lib": {
"version": "0.0.261", "version": "0.0.265",
"resolved": "https://registry.npmjs.org/sartography-workflow-lib/-/sartography-workflow-lib-0.0.261.tgz", "resolved": "https://registry.npmjs.org/sartography-workflow-lib/-/sartography-workflow-lib-0.0.265.tgz",
"integrity": "sha512-K6Jd/xzxah2p8NCE2bbphd88wbUJnl466AmmTA1t5EtOJGMymvaj2iO25SWgi7fxBeFBYHGjpHFw5Bl/xoCIcg==" "integrity": "sha512-cb1Wc09m83hgpjz7d60KHGDjHvrpq6oZns8lL+kgjFUrGwsL8lRxwsjt1cOGMnCTzi48icybEogvSsluhU7RhA=="
}, },
"sass": { "sass": {
"version": "1.23.3", "version": "1.23.3",

View File

@ -12,16 +12,12 @@
"test:coverage": "ng test --codeCoverage=true --watch=false --browsers=ChromeHeadless", "test:coverage": "ng test --codeCoverage=true --watch=false --browsers=ChromeHeadless",
"lint": "ng lint", "lint": "ng lint",
"e2e": "./node_modules/protractor/bin/webdriver-manager update && ng e2e", "e2e": "./node_modules/protractor/bin/webdriver-manager update && ng e2e",
"e2e:with-wf": "npm run e2e-wf && ng e2e && npm run e2e-wf:stop && npm run e2e-wf:clean", "e2e:with-wf": "npm run e2e-wf && ng e2e && npm run e2e-wf:stop",
"e2e-wf:stop": "docker stop db || true && docker stop backend || true && docker stop pb || true", "e2e-wf:stop": "cd docker && docker-compose down && cd ..",
"e2e-wf:clean": "docker system prune -f && cd docker && docker-compose rm -f -v -s && cd ..", "e2e-wf:build": "cd docker && docker-compose pull && docker-compose build && cd ..",
"e2e-wf:build": "cd docker && docker-compose pull && docker-compose build --no-cache && cd ..", "e2e-wf:start": "cd docker && docker-compose up -d --force-recreate && cd ..",
"e2e-wf:start": "cd docker && docker-compose up -d && cd ..", "e2e-wf": "npm run e2e-wf:stop && npm run e2e-wf:build && npm run e2e-wf:start",
"e2e-wf:db-upgrade": "docker exec -it backend pipenv run flask db upgrade", "env": "chmod +x ./docker/substitute-env-variables.sh && ./docker/substitute-env-variables.sh src/index.html PRODUCTION,API_URL,IRB_URL,HOME_ROUTE,BASE_HREF,DEPLOY_URL,PORT0,GOOGLE_ANALYTICS_KEY,SENTRY_KEY,TITLE",
"e2e-wf:db-setup": "docker exec -it backend pipenv run flask load-example-data",
"e2e-wf:pb-setup": "docker exec -it pb pipenv run flask db upgrade",
"e2e-wf": "npm run e2e-wf:stop && npm run e2e-wf:clean && npm run e2e-wf:build && npm run e2e-wf:start && npm run e2e-wf:db-upgrade && npm run e2e-wf:db-setup && npm run e2e-wf:pb-setup",
"env": "chmod +x ./docker/substitute-env-variables.sh && ./docker/substitute-env-variables.sh src/index.html PRODUCTION,API_URL,IRB_URL,HOME_ROUTE,BASE_HREF,PORT0,GOOGLE_ANALYTICS_KEY",
"ci": "npm run lint && npm run test:coverage && sonar-scanner" "ci": "npm run lint && npm run test:coverage && sonar-scanner"
}, },
"private": true, "private": true,
@ -55,7 +51,7 @@
"ngx-file-drop": "^8.0.8", "ngx-file-drop": "^8.0.8",
"ngx-markdown": "^9.0.0", "ngx-markdown": "^9.0.0",
"rxjs": "~6.5.4", "rxjs": "~6.5.4",
"sartography-workflow-lib": "0.0.261", "sartography-workflow-lib": "0.0.265",
"tslib": "^1.11.1", "tslib": "^1.11.1",
"uuid": "^7.0.2", "uuid": "^7.0.2",
"zone.js": "^0.10.3" "zone.js": "^0.10.3"

View File

@ -1,5 +1,4 @@
import {FileMeta, FileType, WorkflowSpec, WorkflowSpecCategory} from 'sartography-workflow-lib'; import {FileMeta, FileType, WorkflowSpec, WorkflowSpecCategory} from 'sartography-workflow-lib';
import {ApiError} from 'sartography-workflow-lib/lib/types/api';
export interface FileMetaDialogData { export interface FileMetaDialogData {
id?: number; id?: number;

View File

@ -1,5 +1,5 @@
<div class="mat-typography"> <div class="mat-typography">
<app-navbar *ngIf="isSignedIn" class="mat-elevation-z6" id="globalHeader"></app-navbar> <app-navbar></app-navbar>
<router-outlet></router-outlet> <router-outlet></router-outlet>
<app-footer></app-footer> <app-footer></app-footer>
</div> </div>

View File

@ -1,7 +0,0 @@
#globalHeader {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 2;
}

View File

@ -1,61 +1,57 @@
import {APP_BASE_HREF} from '@angular/common'; import {APP_BASE_HREF} from '@angular/common';
import {HttpClient} from '@angular/common/http'; import {HttpClient} from '@angular/common/http';
import {HttpClientTestingModule} from '@angular/common/http/testing'; import {HttpClientTestingModule} from '@angular/common/http/testing';
import {Component} from '@angular/core';
import {async, ComponentFixture, TestBed} from '@angular/core/testing'; import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import {BrowserAnimationsModule} from '@angular/platform-browser/animations'; import {MatIconModule} from '@angular/material/icon';
import {FakeMatIconRegistry} from '@angular/material/icon/testing';
import {MatMenuModule} from '@angular/material/menu';
import {RouterTestingModule} from '@angular/router/testing'; import {RouterTestingModule} from '@angular/router/testing';
import {ApiService, MockEnvironment} from 'sartography-workflow-lib'; import {ApiService, MockEnvironment} from 'sartography-workflow-lib';
import {AppComponent} from './app.component'; import {AppComponent} from './app.component';
import {FooterComponent} from './footer/footer.component';
import {NavbarComponent} from './navbar/navbar.component';
@Component({
selector: 'app-navbar',
template: ''
})
class MockNavbarComponent {
}
@Component({
selector: 'app-footer',
template: ''
})
class MockFooterComponent {
}
describe('AppComponent', () => { describe('AppComponent', () => {
let component: AppComponent; let component: AppComponent;
let fixture: ComponentFixture<AppComponent>; let fixture: ComponentFixture<AppComponent>;
const mockEnvironment = new MockEnvironment();
const mockTitle = `'Once,' said the Mock Title at last, with a deep sigh, 'I was a real Title.'`;
beforeEach(async(() => { beforeEach(async(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
declarations: [ declarations: [
AppComponent, AppComponent,
MockNavbarComponent, FooterComponent,
MockFooterComponent NavbarComponent,
], ],
imports: [ imports: [
HttpClientTestingModule, HttpClientTestingModule,
BrowserAnimationsModule, MatIconModule,
MatMenuModule,
RouterTestingModule, RouterTestingModule,
], ],
providers: [ providers: [
HttpClient, HttpClient,
FakeMatIconRegistry,
ApiService, ApiService,
{provide: 'APP_ENVIRONMENT', useClass: MockEnvironment}, {provide: 'APP_ENVIRONMENT', useValue: mockEnvironment},
{provide: APP_BASE_HREF, useValue: ''}, {provide: APP_BASE_HREF, useValue: ''},
], ]
}) }).compileComponents();
.compileComponents();
})); }));
beforeEach(() => { beforeEach(() => {
mockEnvironment.title = mockTitle;
fixture = TestBed.createComponent(AppComponent); fixture = TestBed.createComponent(AppComponent);
component = fixture.componentInstance; component = fixture.componentInstance;
fixture.detectChanges(); fixture.detectChanges();
}); });
it('should create', () => { it('should create the app', () => {
expect(component).toBeTruthy(); expect(component).toBeTruthy();
}); });
it(`should set the page title to match environment variable`, () => {
expect((component as any).titleService.getTitle()).toEqual(mockTitle);
});
}); });

View File

@ -1,5 +1,7 @@
import {Component, Inject} from '@angular/core'; import {Component, Inject} from '@angular/core';
import {ApiService, AppEnvironment, GoogleAnalyticsService} from 'sartography-workflow-lib'; import {MatIconRegistry} from '@angular/material/icon';
import {DomSanitizer, Title} from '@angular/platform-browser';
import {AppEnvironment, FileType, GoogleAnalyticsService} from 'sartography-workflow-lib';
@Component({ @Component({
selector: 'app-root', selector: 'app-root',
@ -7,17 +9,19 @@ import {ApiService, AppEnvironment, GoogleAnalyticsService} from 'sartography-wo
styleUrls: ['./app.component.scss'] styleUrls: ['./app.component.scss']
}) })
export class AppComponent { export class AppComponent {
title = 'CR Connect Configuration';
constructor( constructor(
@Inject('APP_ENVIRONMENT') private environment: AppEnvironment, @Inject('APP_ENVIRONMENT') private environment: AppEnvironment,
private apiService: ApiService, private titleService: Title,
private matIconRegistry: MatIconRegistry,
private domSanitizer: DomSanitizer,
private googleAnalyticsService: GoogleAnalyticsService, private googleAnalyticsService: GoogleAnalyticsService,
) { ) {
this.googleAnalyticsService.init(this.environment.googleAnalyticsKey); this.googleAnalyticsService.init(this.environment.googleAnalyticsKey);
} const fileTypes = Object.values(FileType);
fileTypes.forEach(t => {
get isSignedIn() { const url = this.domSanitizer.bypassSecurityTrustResourceUrl(`assets/icons/file_types/${t}.svg`)
return this.apiService.isSignedIn(); this.matIconRegistry.addSvgIconInNamespace('crc', t, url);
});
this.titleService.setTitle(this.environment.title);
} }
} }

View File

@ -10,7 +10,7 @@
production: '$PRODUCTION', production: '$PRODUCTION',
api: '$API_URL', api: '$API_URL',
irbUrl: '$IRB_URL', irbUrl: '$IRB_URL',
baseHref: '$BASE_HREF', title: '$TITLE',
googleAnalyticsKey: '$GOOGLE_ANALYTICS_KEY', googleAnalyticsKey: '$GOOGLE_ANALYTICS_KEY',
sentryKey: '$SENTRY_KEY', sentryKey: '$SENTRY_KEY',
}; };