diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..ca5a761 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "build_utils"] + path = build_utils + url = git@github.com:rbkmoney/build_utils.git + branch = master diff --git a/Dockerfile.sh b/Dockerfile.sh new file mode 100755 index 0000000..6233483 --- /dev/null +++ b/Dockerfile.sh @@ -0,0 +1,23 @@ +#!/bin/bash +cat < +COPY dist /usr/share/nginx/html +COPY nginx.conf /etc/nginx/vhosts.d/fraudbusters-ui.conf +EXPOSE 8080 +LABEL base_image_tag=$BASE_IMAGE_TAG +LABEL build_image_tag=$BUILD_IMAGE_TAG +# A bit of magic to get a proper branch name +# even when the HEAD is detached (Hey Jenkins! +# BRANCH_NAME is available in Jenkins env). +LABEL branch=$( \ + if [ "HEAD" != $(git rev-parse --abbrev-ref HEAD) ]; then \ + echo $(git rev-parse --abbrev-ref HEAD); \ + elif [ -n "$BRANCH_NAME" ]; then \ + echo $BRANCH_NAME; \ + else \ + echo $(git name-rev --name-only HEAD); \ + fi) +LABEL commit=$(git rev-parse HEAD) +LABEL commit_number=$(git rev-list --count HEAD) +EOF diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 0000000..876a5e7 --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,43 @@ +#!groovy + +build('fraudbusters-ui', 'docker-host') { + checkoutRepo() + loadBuildUtils() + + def pipeDefault + def withWsCache + runStage('load pipeline') { + env.JENKINS_LIB = "build_utils/jenkins_lib" + pipeDefault = load("${env.JENKINS_LIB}/pipeDefault.groovy") + withWsCache = load("${env.JENKINS_LIB}/withWsCache.groovy") + } + + def pipeline = { + runStage('init') { + withGithubSshCredentials { + withGithubToken { + sh 'make wc_init' + } + } + } + runStage('build') { + sh 'make wc_build' + } + runStage('build image') { + sh 'make build_image' + } + runFESecurityTools() + try { + if (env.BRANCH_NAME == 'master') { + runStage('push image') { + sh 'make push_image' + } + } + } finally { + runStage('rm local image') { + sh 'make rm_local_image' + } + } + } + pipeDefault(pipeline) +} diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..d2c1793 --- /dev/null +++ b/Makefile @@ -0,0 +1,52 @@ +SUBMODULES = build_utils +SUBTARGETS = $(patsubst %,%/.git,$(SUBMODULES)) + +UTILS_PATH := build_utils +TEMPLATES_PATH := . + +# Name of the service +SERVICE_NAME := fraudbusters-ui +# Service image default tag +SERVICE_IMAGE_TAG ?= $(shell git rev-parse HEAD) +# The tag for service image to be pushed with +SERVICE_IMAGE_PUSH_TAG ?= $(SERVICE_IMAGE_TAG) + +REGISTRY ?= dr2.rbkmoney.com + +# Base image for the service +BASE_IMAGE_NAME := service-fe +BASE_IMAGE_TAG := 647d66a59ba89ea42b326ca5156f5d1e1395febc + +BUILD_IMAGE_TAG := b04c5291d101132e53e578d96e1628d2e6dab0c0 + +GIT_SSH_COMMAND := +DOCKER_RUN_OPTS = -e GIT_SSH_COMMAND='$(GIT_SSH_COMMAND)' -e NG_CLI_ANALYTICS=ci -e NPM_TOKEN='$(GITHUB_TOKEN)' + + +CALL_W_CONTAINER := init build clean submodules + +.PHONY: $(CALL_W_CONTAINER) + +all: build + +-include $(UTILS_PATH)/make_lib/utils_image.mk +-include $(UTILS_PATH)/make_lib/utils_container.mk + +$(SUBTARGETS): %/.git: % + git submodule update --init $< + touch $@ + +submodules: $(SUBTARGETS) + +init: + echo -e "//npm.pkg.github.com/:_authToken=$(NPM_TOKEN)" >> .npmrc + npm ci + +build: check lint + npm run build + +lint: + npm run lint + +check: + npm run prettier diff --git a/build_utils b/build_utils new file mode 160000 index 0000000..f42e059 --- /dev/null +++ b/build_utils @@ -0,0 +1 @@ +Subproject commit f42e059d9ec93826ba4ad23232eed8ce67bd5486 diff --git a/e2e/protractor.conf.js b/e2e/protractor.conf.js new file mode 100644 index 0000000..702a166 --- /dev/null +++ b/e2e/protractor.conf.js @@ -0,0 +1,30 @@ +// @ts-check +// Protractor configuration file, see link for more information +// https://github.com/angular/protractor/blob/master/lib/config.ts + +const { SpecReporter } = require('jasmine-spec-reporter'); + +/** + * @type { import("protractor").Config } + */ +exports.config = { + allScriptsTimeout: 11000, + specs: ['./src/**/*.e2e-spec.ts'], + capabilities: { + browserName: 'chrome', + }, + directConnect: true, + baseUrl: 'http://localhost:4200/', + framework: 'jasmine', + jasmineNodeOpts: { + showColors: true, + defaultTimeoutInterval: 30000, + print: function () {}, + }, + onPrepare() { + require('ts-node').register({ + project: require('path').join(__dirname, './tsconfig.json'), + }); + jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } })); + }, +}; diff --git a/e2e/src/app.e2e-spec.ts b/e2e/src/app.e2e-spec.ts new file mode 100644 index 0000000..e80e18b --- /dev/null +++ b/e2e/src/app.e2e-spec.ts @@ -0,0 +1,26 @@ +import { browser, logging } from 'protractor'; + +import { AppPage } from './app.po'; + +describe('workspace-project App', () => { + let page: AppPage; + + beforeEach(() => { + page = new AppPage(); + }); + + it('should display welcome message', () => { + page.navigateTo(); + expect(page.getTitleText()).toEqual('angular9 app is running!'); + }); + + afterEach(async () => { + // Assert that there are no errors emitted from the browser + const logs = await browser.manage().logs().get(logging.Type.BROWSER); + expect(logs).not.toContain( + jasmine.objectContaining({ + level: logging.Level.SEVERE, + } as logging.Entry) + ); + }); +}); diff --git a/e2e/src/app.po.ts b/e2e/src/app.po.ts new file mode 100644 index 0000000..7bcff2a --- /dev/null +++ b/e2e/src/app.po.ts @@ -0,0 +1,11 @@ +import { browser, by, element } from 'protractor'; + +export class AppPage { + navigateTo(): Promise { + return browser.get(browser.baseUrl) as Promise; + } + + getTitleText(): Promise { + return element(by.css('app-root .content span')).getText() as Promise; + } +} diff --git a/e2e/tsconfig.json b/e2e/tsconfig.json new file mode 100644 index 0000000..be6d1ec --- /dev/null +++ b/e2e/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../tsconfig.base.json", + "compilerOptions": { + "outDir": "../out-tsc/e2e", + "module": "commonjs", + "target": "es5", + "types": ["jasmine", "jasminewd2", "node"] + } +} diff --git a/package.json b/package.json index ab18f19..d73b4b3 100644 --- a/package.json +++ b/package.json @@ -4,9 +4,14 @@ "scripts": { "ng": "ng", "start": "ng serve", - "build": "ng build", + "build": "ng build --prod", "test": "ng test", "lint": "ng lint", + "lint:fix": "ng lint --fix", + "prettier-preset": "prettier \"**/*.{html,js,ts,css,scss,md,json,prettierrc,svg,huskyrc}\"", + "prettier": "npm run prettier-preset -- --list-different", + "prettier:fix": "npm run prettier-preset -- --write", + "fix": "npm run lint:fix; npm run prettier:fix", "e2e": "ng e2e", "postinstall": "ngcc" }, diff --git a/src/app/groups/create-group/create-group.component.spec.ts b/src/app/groups/create-group/create-group.component.spec.ts index e110591..ca04b5f 100644 --- a/src/app/groups/create-group/create-group.component.spec.ts +++ b/src/app/groups/create-group/create-group.component.spec.ts @@ -3,23 +3,22 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { CreateGroupComponent } from './create-group.component'; describe('CreateGroupComponent', () => { - let component: CreateGroupComponent; - let fixture: ComponentFixture; + let component: CreateGroupComponent; + let fixture: ComponentFixture; - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [ CreateGroupComponent ] - }) - .compileComponents(); - }); + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [CreateGroupComponent], + }).compileComponents(); + }); - beforeEach(() => { - fixture = TestBed.createComponent(CreateGroupComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(CreateGroupComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should create', () => { - expect(component).toBeTruthy(); - }); + it('should create', () => { + expect(component).toBeTruthy(); + }); }); diff --git a/src/app/groups/edit-group/edit-group.component.spec.ts b/src/app/groups/edit-group/edit-group.component.spec.ts index cd94906..10ed76f 100644 --- a/src/app/groups/edit-group/edit-group.component.spec.ts +++ b/src/app/groups/edit-group/edit-group.component.spec.ts @@ -3,23 +3,22 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { EditGroupComponent } from './edit-group.component'; describe('EditGroupComponent', () => { - let component: EditGroupComponent; - let fixture: ComponentFixture; + let component: EditGroupComponent; + let fixture: ComponentFixture; - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [ EditGroupComponent ] - }) - .compileComponents(); - }); + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [EditGroupComponent], + }).compileComponents(); + }); - beforeEach(() => { - fixture = TestBed.createComponent(EditGroupComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(EditGroupComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should create', () => { - expect(component).toBeTruthy(); - }); + it('should create', () => { + expect(component).toBeTruthy(); + }); }); diff --git a/src/app/groups/groups.service.spec.ts b/src/app/groups/groups.service.spec.ts index b29a47a..8488205 100644 --- a/src/app/groups/groups.service.spec.ts +++ b/src/app/groups/groups.service.spec.ts @@ -3,14 +3,14 @@ import { TestBed } from '@angular/core/testing'; import { GroupsService } from './groups.service'; describe('GroupsService', () => { - let service: GroupsService; + let service: GroupsService; - beforeEach(() => { - TestBed.configureTestingModule({}); - service = TestBed.inject(GroupsService); - }); + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(GroupsService); + }); - it('should be created', () => { - expect(service).toBeTruthy(); - }); + it('should be created', () => { + expect(service).toBeTruthy(); + }); }); diff --git a/src/app/groups/remove-group-dialog/remove-group-dialog.component.html b/src/app/groups/remove-group-dialog/remove-group-dialog.component.html index 48f9f91..471c15f 100644 --- a/src/app/groups/remove-group-dialog/remove-group-dialog.component.html +++ b/src/app/groups/remove-group-dialog/remove-group-dialog.component.html @@ -1,7 +1,7 @@
-

Do you want remove group with name: {{ this.data.id }}

+

Do you want remove group with name: {{ this.data.id }}

- - + +
diff --git a/src/app/groups/remove-group-dialog/remove-group-dialog.component.spec.ts b/src/app/groups/remove-group-dialog/remove-group-dialog.component.spec.ts index 135ef5b..5ba31d9 100644 --- a/src/app/groups/remove-group-dialog/remove-group-dialog.component.spec.ts +++ b/src/app/groups/remove-group-dialog/remove-group-dialog.component.spec.ts @@ -3,23 +3,22 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { RemoveGroupDialogComponent } from './remove-group-dialog.component'; describe('RemoveGroupDialogComponent', () => { - let component: RemoveGroupDialogComponent; - let fixture: ComponentFixture; + let component: RemoveGroupDialogComponent; + let fixture: ComponentFixture; - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [ RemoveGroupDialogComponent ] - }) - .compileComponents(); - }); + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [RemoveGroupDialogComponent], + }).compileComponents(); + }); - beforeEach(() => { - fixture = TestBed.createComponent(RemoveGroupDialogComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(RemoveGroupDialogComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should create', () => { - expect(component).toBeTruthy(); - }); + it('should create', () => { + expect(component).toBeTruthy(); + }); }); diff --git a/src/app/groups/utils/group-utils.service.spec.ts b/src/app/groups/utils/group-utils.service.spec.ts index 6852393..3fcdca8 100644 --- a/src/app/groups/utils/group-utils.service.spec.ts +++ b/src/app/groups/utils/group-utils.service.spec.ts @@ -3,14 +3,14 @@ import { TestBed } from '@angular/core/testing'; import { GroupUtilsService } from './group-utils.service'; describe('GroupUtilsService', () => { - let service: GroupUtilsService; + let service: GroupUtilsService; - beforeEach(() => { - TestBed.configureTestingModule({}); - service = TestBed.inject(GroupUtilsService); - }); + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(GroupUtilsService); + }); - it('should be created', () => { - expect(service).toBeTruthy(); - }); + it('should be created', () => { + expect(service).toBeTruthy(); + }); }); diff --git a/src/app/references/remove-reference-dialog/remove-reference-dialog.component.ts b/src/app/references/remove-reference-dialog/remove-reference-dialog.component.ts index 00d7015..8ad4786 100644 --- a/src/app/references/remove-reference-dialog/remove-reference-dialog.component.ts +++ b/src/app/references/remove-reference-dialog/remove-reference-dialog.component.ts @@ -31,12 +31,10 @@ export class RemoveReferenceDialogComponent { } delete(): void { - this.referenceService - .deleteReference(this.data.operationType, this.data.reference) - .subscribe( - (id) => console.log(id), - (error: HttpErrorResponse) => this.errorHandlerService.handleError(error, this.snackBar) - ); + this.referenceService.deleteReference(this.data.operationType, this.data.reference).subscribe( + (id) => console.log(id), + (error: HttpErrorResponse) => this.errorHandlerService.handleError(error, this.snackBar) + ); this.dialogRef.close(); } } diff --git a/src/app/shared/services/operation-type-management.service.ts b/src/app/shared/services/operation-type-management.service.ts index 9ce1d3a..2cfb21d 100644 --- a/src/app/shared/services/operation-type-management.service.ts +++ b/src/app/shared/services/operation-type-management.service.ts @@ -20,7 +20,7 @@ export class OperationTypeManagementService { private paymentGroupsService: PaymentGroupsService, private p2pGroupsService: P2pGroupsService, private paymentReferenceService: PaymentReferencesService, - private p2pReferenceService: P2pReferencesService, + private p2pReferenceService: P2pReferencesService ) {} findTemplateService(type: OperationType): ITemplatesService { diff --git a/src/app/shared/services/reference/model/SearchReferenceParams.ts b/src/app/shared/services/reference/model/SearchReferenceParams.ts index 520f7b1..552dce3 100644 --- a/src/app/shared/services/reference/model/SearchReferenceParams.ts +++ b/src/app/shared/services/reference/model/SearchReferenceParams.ts @@ -1,7 +1,7 @@ import { SearchParams } from '../../../model/SearchParams'; export class SearchReferenceParams extends SearchParams { - searchValue: string; + searchValue: string; constructor(id: string, lastId: string, size: number, sortOrder: string) { super(id, lastId, size, sortOrder); this.searchValue = id; diff --git a/src/app/shared/services/reference/p2p-references.service.ts b/src/app/shared/services/reference/p2p-references.service.ts index e47a498..51ba829 100644 --- a/src/app/shared/services/reference/p2p-references.service.ts +++ b/src/app/shared/services/reference/p2p-references.service.ts @@ -26,10 +26,9 @@ export class P2pReferencesService implements IReferencesService { } deleteReference(reference: P2pReference): Observable { - return this.http.delete( - `${this.fbManagementEndpoint}/p2p/template/${reference.templateId}/reference`, - { params: { identityId: reference.identityId} } - ); + return this.http.delete(`${this.fbManagementEndpoint}/p2p/template/${reference.templateId}/reference`, { + params: { identityId: reference.identityId }, + }); } saveReference(reference: Reference): Observable { diff --git a/src/app/shared/services/reference/payment-references.service.ts b/src/app/shared/services/reference/payment-references.service.ts index b1553e3..b624687 100644 --- a/src/app/shared/services/reference/payment-references.service.ts +++ b/src/app/shared/services/reference/payment-references.service.ts @@ -26,10 +26,9 @@ export class PaymentReferencesService implements IReferencesService { } deleteReference(reference: PaymentReference): Observable { - return this.http.delete( - `${this.fbManagementEndpoint}/template/${reference.templateId}/reference`, - { params: { shopId: reference.shopId, partyId: reference.partyId} } - ); + return this.http.delete(`${this.fbManagementEndpoint}/template/${reference.templateId}/reference`, { + params: { shopId: reference.shopId, partyId: reference.partyId }, + }); } saveReference(reference: Reference): Observable {