Skip to content
Snippets Groups Projects
Commit 99da23a1 authored by OZGCloud's avatar OZGCloud
Browse files

Merge branch 'master' into OZG-6300-OZG-6417-Zusammarbeit-E2E

parents 2aeabac1 ed57145b
Branches
Tags
No related merge requests found
Showing
with 417 additions and 136 deletions
...@@ -85,6 +85,27 @@ pipeline { ...@@ -85,6 +85,27 @@ pipeline {
// } // }
} }
stage('Build and push client container') {
steps {
script {
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
dir('alfa-client') {
IMAGE_TAG = generateImageTag()
sh 'npm run ci-build-alfa-client-container'
withCredentials([usernamePassword(credentialsId: 'jenkins-nexus-login', usernameVariable: 'USER', passwordVariable: 'PASSWORD')]) {
sh 'docker login docker.ozg-sh.de -u ${USER} -p ${PASSWORD}'
sh "docker tag docker.ozg-sh.de/alfa-client:build-latest docker.ozg-sh.de/alfa-client:${IMAGE_TAG}"
sh "docker push docker.ozg-sh.de/alfa-client:${IMAGE_TAG}"
}
}
}
}
}
}
stage('Set Version') { stage('Set Version') {
when { when {
not { not {
...@@ -243,6 +264,25 @@ pipeline { ...@@ -243,6 +264,25 @@ pipeline {
dependencyCheckPublisher pattern: 'dependency-check-report.xml' dependencyCheckPublisher pattern: 'dependency-check-report.xml'
} }
} }
stage ('Trigger Barrierefreiheit Rollout') {
when {
branch 'barrierefreiheit-dev'
}
steps {
script {
FAILED_STAGE = env.STAGE_NAME
cloneGitopsRepo()
setNewBarrierefreiheitVersion()
pushGitopsRepo()
}
}
}
} }
post { post {
failure { failure {
...@@ -274,7 +314,10 @@ String generateHelmChartVersion() { ...@@ -274,7 +314,10 @@ String generateHelmChartVersion() {
def chartVersion = "${VERSION}" def chartVersion = "${VERSION}"
if (isMasterBranch()) { if (isMasterBranch()) {
chartVersion += "-${env.GIT_COMMIT.take(7)}" chartVersion += getCommitHash()
}
else if (isBarrierefreiheitBranch()) {
chartVersion += "-barrierefreiheit${getCommitHash()}"
} }
else if (!isReleaseBranch()) { else if (!isReleaseBranch()) {
chartVersion += "-${env.BRANCH_NAME}" chartVersion += "-${env.BRANCH_NAME}"
...@@ -295,8 +338,8 @@ Void tagAndPushDockerImage(String newTag){ ...@@ -295,8 +338,8 @@ Void tagAndPushDockerImage(String newTag){
String generateImageTag() { String generateImageTag() {
def imageTag = "${env.BRANCH_NAME}-${VERSION}" def imageTag = "${env.BRANCH_NAME}-${VERSION}"
if (isMasterBranch()) { if (isMasterBranch() || isBarrierefreiheitBranch()) {
imageTag += "-${env.GIT_COMMIT.take(7)}" imageTag += getCommitHash()
} }
return imageTag return imageTag
...@@ -365,9 +408,19 @@ Void setNewTestVersion() { ...@@ -365,9 +408,19 @@ Void setNewTestVersion() {
} }
Void setNewGitopsVersion(String environment) { Void setNewGitopsVersion(String environment) {
dir("gitops") {
def envFile = "${environment}/application/values/alfa-values.yaml" def envFile = "${environment}/application/values/alfa-values.yaml"
def commitMessage = "jenkins rollout ${environment} alfa version ${IMAGE_TAG}";
setNewGitopsVersion(envFile, commitMessage);
}
Void setNewBarrierefreiheitVersion() {
def envFile = "dev/namespace/namespaces/by-barrierefreiheit-dev.yaml"
def commitMessage = "jenkins rollout ${IMAGE_TAG} for Barrierefreiheit Dev"
setNewGitopsVersion(envFile, commitMessage);
}
Void setNewGitopsVersion(String envFile, String commitMessage) {
dir("gitops") {
def envVersions = readYaml file: envFile def envVersions = readYaml file: envFile
envVersions.alfa.image.tag = IMAGE_TAG envVersions.alfa.image.tag = IMAGE_TAG
...@@ -375,15 +428,19 @@ Void setNewGitopsVersion(String environment) { ...@@ -375,15 +428,19 @@ Void setNewGitopsVersion(String environment) {
writeYaml file: envFile, data: envVersions, overwrite: true writeYaml file: envFile, data: envVersions, overwrite: true
if (hasValuesFileChanged(environment)) { if (hasValuesFileChanged(envFile)) {
sh "git add ${envFile}" sh "git add ${envFile}"
sh "git commit -m 'jenkins rollout ${environment} alfa version ${IMAGE_TAG}'" sh "git commit -m '${commitMessage}'"
}
} }
} }
String getCommitHash() {
return "-${env.GIT_COMMIT.take(7)}";
} }
Boolean hasValuesFileChanged(String environment) { Boolean hasValuesFileChanged(String envFile) {
return sh (script: "git status | grep '${environment}/application/values/alfa-values.yaml'", returnStatus: true) == env.SH_SUCCESS_STATUS_CODE as Integer return sh (script: "git status | grep '${envFile}'", returnStatus: true) == env.SH_SUCCESS_STATUS_CODE as Integer
} }
Boolean isReleaseBranch() { Boolean isReleaseBranch() {
...@@ -394,6 +451,10 @@ Boolean isMasterBranch() { ...@@ -394,6 +451,10 @@ Boolean isMasterBranch() {
return env.BRANCH_NAME == 'master' return env.BRANCH_NAME == 'master'
} }
Boolean isBarrierefreiheitBranch() {
return env.BRANCH_NAME == 'barrierefreiheit-dev'
}
Boolean isReleaseVersion(List versions) { Boolean isReleaseVersion(List versions) {
return matchRegexVersion(versions, RELEASE_REGEX) return matchRegexVersion(versions, RELEASE_REGEX)
} }
......
...@@ -73,3 +73,4 @@ tests: ...@@ -73,3 +73,4 @@ tests:
content: content:
name: my_test_environment_name name: my_test_environment_name
value: "A test value" value: "A test value"
:8080 {
file_server
root * /usr/share/caddy
try_files {path} /index.html
}
\ No newline at end of file
# Benutzt das vorher zu bauende Docker image "nx-build-base:x.y.z" FROM caddy:2.6.4-alpine
# Siehe ../Dockerfile.nx-build-base
FROM docker.ozg-sh.de/nx-build-base:2.0.0 AS builder
ARG NODE_ENV RUN adduser --system --ingroup root caddy
ARG CONFIGURATION
# Turn off Nx Daemon WORKDIR /usr/share/caddy
ENV CI=true
WORKDIR /app/builder COPY apps/alfa/Caddyfile /etc/caddy/Caddyfile
COPY . .
RUN echo "Building configuration: $CONFIGURATION..." COPY dist/apps/alfa /usr/share/caddy
RUN npx nx build alfa --outputHashing=all --configuration ${CONFIGURATION:-development} \ RUN chgrp -R 0 /usr/bin/caddy /etc/caddy /config/caddy /usr/share/caddy && \
&& ./node_modules/.bin/gzipper compress ./dist --verbose --exclude jpg,jpeg,png,ico,woff,woff2 chmod -R g=u /usr/bin/caddy /etc/caddy /config/caddy /usr/share/caddy
FROM nginx:stable-alpine USER caddy
WORKDIR /usr/share/nginx/html EXPOSE 8080 8081
COPY --from=builder /app/builder/dist/apps/alfa ./ ENTRYPOINT ["/usr/bin/caddy"]
COPY --from=builder /app/builder/apps/alfa/nginx.conf /etc/nginx/nginx.conf
CMD ["run", "--config", "/etc/caddy/Caddyfile", "--adapter", "caddyfile"]
\ No newline at end of file
...@@ -122,6 +122,22 @@ ...@@ -122,6 +122,22 @@
"outputs": [ "outputs": [
"{workspaceRoot}/coverage/apps/alfa" "{workspaceRoot}/coverage/apps/alfa"
] ]
},
"container": {
"executor": "@nx-tools/nx-container:build",
"options": {
"engine": "docker",
"push": false,
"metadata": {
"images": [
"docker.ozg-sh.de/alfa-client"
],
"load": true,
"tags": [
"build-latest"
]
}
}
} }
} }
} }
\ No newline at end of file
...@@ -16,6 +16,7 @@ import { ...@@ -16,6 +16,7 @@ import {
FileIconComponent, FileIconComponent,
FileUploadButtonComponent, FileUploadButtonComponent,
InstantSearchComponent, InstantSearchComponent,
OfficeIconComponent,
RadioButtonCardComponent, RadioButtonCardComponent,
SaveIconComponent, SaveIconComponent,
SendIconComponent, SendIconComponent,
...@@ -26,6 +27,7 @@ import { ...@@ -26,6 +27,7 @@ import {
} from '@ods/system'; } from '@ods/system';
import { EMPTY_STRING } from '@alfa-client/tech-shared'; import { EMPTY_STRING } from '@alfa-client/tech-shared';
import { Resource } from '@ngxp/rest';
import { import {
InstantSearchQuery, InstantSearchQuery,
InstantSearchResult, InstantSearchResult,
...@@ -53,6 +55,7 @@ import { CustomStepperComponent } from './components/cdk-demo/custom-stepper.com ...@@ -53,6 +55,7 @@ import { CustomStepperComponent } from './components/cdk-demo/custom-stepper.com
RadioButtonCardComponent, RadioButtonCardComponent,
ReactiveFormsModule, ReactiveFormsModule,
InstantSearchComponent, InstantSearchComponent,
OfficeIconComponent,
SaveIconComponent, SaveIconComponent,
SendIconComponent, SendIconComponent,
StampIconComponent, StampIconComponent,
...@@ -79,26 +82,22 @@ export class AppComponent { ...@@ -79,26 +82,22 @@ export class AppComponent {
title = 'demo'; title = 'demo';
instantSearchItems: InstantSearchResult<unknown>[] = [ instantSearchItems: InstantSearchResult<Resource>[] = [
{ {
title: 'Landeshauptstadt Kiel - Ordnungsamt, Gewerbe- und Schornsteinfegeraufsicht', title: 'Landeshauptstadt Kiel - Ordnungsamt, Gewerbe- und Schornsteinfegeraufsicht',
description: 'Fabrikstraße 8-10, 24103 Kiel', description: 'Fabrikstraße 8-10, 24103 Kiel',
data: { resource: 'dummy 1' },
}, },
{ {
title: 'Amt für Digitalisierung, Breitband und Vermessung Nürnberg Außenstelle Hersbruck', title: 'Amt für Digitalisierung, Breitband und Vermessung Nürnberg Außenstelle Hersbruck',
description: 'Rathausmarkt 7, Hersbruck', description: 'Rathausmarkt 7, Hersbruck',
data: { resource: 'dummy 2' },
}, },
{ {
title: 'Amt für Digitalisierung, Breitband und Vermessung Stuttgart', title: 'Amt für Digitalisierung, Breitband und Vermessung Stuttgart',
description: 'Rathausmarkt 7, Stuttgart', description: 'Rathausmarkt 7, Stuttgart',
data: { resource: 'dummy 3' },
}, },
{ {
title: 'Amt für Digitalisierung, Breitband und Vermessung Ulm', title: 'Amt für Digitalisierung, Breitband und Vermessung Ulm',
description: 'Rathausmarkt 7, Ulm', description: 'Rathausmarkt 7, Ulm',
data: { resource: 'dummy 4' },
}, },
]; ];
instantSearchFormControl = new FormControl(EMPTY_STRING); instantSearchFormControl = new FormControl(EMPTY_STRING);
...@@ -110,7 +109,7 @@ export class AppComponent { ...@@ -110,7 +109,7 @@ export class AppComponent {
); );
} }
selectSearchResult(result: InstantSearchResult<unknown>) { selectSearchResult(result: InstantSearchResult<Resource>) {
console.log(result); console.log(result);
} }
......
...@@ -13,11 +13,11 @@ ...@@ -13,11 +13,11 @@
/> />
</label> </label>
<div <div
*ngIf="errorMessages.length > 0" *ngIf="invalidParams.length > 0"
[attr.data-test-id]="'text-field-errors-' + label | convertForDataTest" [attr.data-test-id]="'text-field-errors-' + label | convertForDataTest"
> >
<span class="mb-3 italic text-red-500" *ngFor="let errorMessage of errorMessages">{{ <span class="mb-3 italic text-red-500" *ngFor="let invalidParam of invalidParams">{{
errorMessage getErrorMessage(invalidParam)
}}</span> }}</span>
</div> </div>
</div> </div>
import { ConvertForDataTestPipe } from '@alfa-client/tech-shared'; import { ConvertForDataTestPipe, InvalidParam } from '@alfa-client/tech-shared';
import { getElementFromFixture, notExistsAsHtmlElement } from '@alfa-client/test-utils';
import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ComponentFixture, TestBed } from '@angular/core/testing';
import { FormControl, NgControl, ReactiveFormsModule, ValidationErrors } from '@angular/forms'; import { ReactiveFormsModule } from '@angular/forms';
import { getDataTestIdOf } from 'libs/tech-shared/test/data-test'; import { createInvalidParam, createProblemDetail } from 'libs/tech-shared/test/error';
import { TextFieldComponent } from './text-field.component'; import { TextFieldComponent } from './text-field.component';
import * as TechValidationUtil from 'libs/tech-shared/src/lib/validation/tech.validation.util';
describe('TextFieldComponent', () => { describe('TextFieldComponent', () => {
let component: TextFieldComponent; let component: TextFieldComponent;
let fixture: ComponentFixture<TextFieldComponent>; let fixture: ComponentFixture<TextFieldComponent>;
const label = 'custom'; const label = 'custom';
const spanSelector = getDataTestIdOf('text-field-span-' + label);
const inputSelector = getDataTestIdOf('text-field-input-' + label);
const errorsSelector = getDataTestIdOf('text-field-errors-' + label);
const formControl = new FormControl('');
beforeEach(async () => { beforeEach(async () => {
await TestBed.configureTestingModule({ await TestBed.configureTestingModule({
declarations: [TextFieldComponent, ConvertForDataTestPipe], declarations: [TextFieldComponent, ConvertForDataTestPipe],
imports: [ReactiveFormsModule], imports: [ReactiveFormsModule],
}) }).compileComponents();
.overrideComponent(TextFieldComponent, {
add: {
providers: [
{
provide: NgControl,
useValue: formControl,
},
],
},
})
.compileComponents();
fixture = TestBed.createComponent(TextFieldComponent); fixture = TestBed.createComponent(TextFieldComponent);
component = fixture.componentInstance; component = fixture.componentInstance;
...@@ -43,62 +28,39 @@ describe('TextFieldComponent', () => { ...@@ -43,62 +28,39 @@ describe('TextFieldComponent', () => {
expect(component).toBeTruthy(); expect(component).toBeTruthy();
}); });
it('should use label', () => { describe('getErrorMessage', () => {
const labelElement = getElementFromFixture(fixture, spanSelector); it('should call getMessageForInvalidParam()', () => {
expect(labelElement.textContent).toBe(label); const getMessageForInvalidParam: jest.SpyInstance<string, [string, InvalidParam]> =
}); jest.spyOn(TechValidationUtil, 'getMessageForInvalidParam');
const invalidParam: InvalidParam = createInvalidParam();
it('should use form control', () => {
const fieldText = 'text';
component.writeValue(fieldText);
fixture.detectChanges(); component.getErrorMessage(invalidParam);
const inputElement = getElementFromFixture(fixture, inputSelector); expect(getMessageForInvalidParam).toHaveBeenCalledWith(label, invalidParam);
expect(inputElement.value).toBe(fieldText);
}); });
describe('invalid indication', () => {
it('should show as red if invalid', () => {
formControl.setErrors({ someErrorCode: 'Invalid' });
fixture.detectChanges();
const labelElement = getElementFromFixture(fixture, spanSelector);
expect([...labelElement.classList]).toEqual(['text-red-500', 'font-bold']);
}); });
it('should not show as red if valid', () => { describe('show error messages', () => {
formControl.setErrors(null); it('should not call getErrorMessage() if no error', () => {
component.getErrorMessage = jest.fn();
component.fieldControl.setErrors({});
fixture.detectChanges(); fixture.detectChanges();
const labelElement = getElementFromFixture(fixture, spanSelector); expect(component.getErrorMessage).not.toHaveBeenCalled();
expect([...labelElement.classList]).toEqual([]);
});
}); });
describe('error messages', () => { it('should call getErrorMessage() if error', () => {
it('should not show empty error message container', () => { component.getErrorMessage = jest.fn();
fixture.detectChanges();
notExistsAsHtmlElement(fixture, errorsSelector); component.fieldControl.setErrors({
...createProblemDetail(),
invalidParams: [{ ...createInvalidParam(), name: 'settingBody.absender.name' }],
}); });
it('should show error messages', () => {
const errors: ValidationErrors = {
firstMessage: 'first',
secondMessage: 'second',
};
formControl.setErrors(errors);
fixture.detectChanges(); fixture.detectChanges();
const errorsElement: HTMLElement = getElementFromFixture(fixture, errorsSelector); expect(component.getErrorMessage).toHaveBeenCalled();
const spansTexts = Array.from(errorsElement.querySelectorAll('span')).map(
(span) => span.textContent,
);
expect(spansTexts).toEqual(Object.values(errors));
}); });
}); });
}); });
import { isNotNil } from '@alfa-client/tech-shared'; import { getMessageForInvalidParam, InvalidParam } from '@alfa-client/tech-shared';
import { Component, Input } from '@angular/core'; import { Component, Input } from '@angular/core';
import { FormControlEditorAbstractComponent } from '@ods/component'; import { FormControlEditorAbstractComponent } from '@ods/component';
...@@ -10,7 +10,7 @@ export class TextFieldComponent extends FormControlEditorAbstractComponent { ...@@ -10,7 +10,7 @@ export class TextFieldComponent extends FormControlEditorAbstractComponent {
@Input() @Input()
label: string; label: string;
get errorMessages(): string[] { public getErrorMessage(invalidParam: InvalidParam): string {
return isNotNil(this.control?.errors) ? Object.values(this.control.errors) : []; return getMessageForInvalidParam(this.label, invalidParam);
} }
} }
export * from './lib/collaboration-shared.module'; export * from './lib/collaboration-shared.module';
export * from './lib/organisations-einheit.linkrel';
export * from './lib/organisations-einheit.model';
export * from './lib/organisations-einheit.service';
import { ResourceRepository } from '@alfa-client/tech-shared';
import { VorgangService } from '@alfa-client/vorgang-shared';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { CollaborationService } from './collaboration.service'; import { CollaborationService } from './collaboration.service';
import {
OrganisationsEinheitResourceSearchService,
createOrganisationsEinheitResourceSearchService,
} from './organisations-einheit-resource-search.service';
import { OrganisationsEinheitService } from './organisations-einheit.service';
@NgModule({ @NgModule({
imports: [CommonModule], imports: [CommonModule],
providers: [CollaborationService], providers: [
CollaborationService,
OrganisationsEinheitService,
{
provide: OrganisationsEinheitResourceSearchService,
useFactory: createOrganisationsEinheitResourceSearchService,
deps: [ResourceRepository, VorgangService],
},
],
}) })
export class CollaborationSharedModule {} export class CollaborationSharedModule {}
import {
ResourceRepository,
ResourceSearchService,
SearchResourceServiceConfig,
mapToResource,
} from '@alfa-client/tech-shared';
import {
VorgangResource,
VorgangService,
VorgangWithEingangLinkRel,
} from '@alfa-client/vorgang-shared';
import {
OrganisationsEinheitListResource,
OrganisationsEinheitResource,
} from './organisations-einheit.model';
export class OrganisationsEinheitResourceSearchService extends ResourceSearchService<
VorgangResource,
OrganisationsEinheitListResource,
OrganisationsEinheitResource
> {}
export function createOrganisationsEinheitResourceSearchService(
repository: ResourceRepository,
vorgangService: VorgangService,
) {
return new ResourceSearchService(buildConfig(vorgangService), repository);
}
function buildConfig(vorgangService: VorgangService): SearchResourceServiceConfig<VorgangResource> {
return {
baseResource: vorgangService.getVorgangWithEingang().pipe(mapToResource<VorgangResource>()),
searchLinkRel: VorgangWithEingangLinkRel.SEARCH_ORGANISATIONS_EINHEIT,
};
}
export enum OrganisationsEinheitListLinkRel {
ORGANISATIONS_EINHEIT_HEADER_LIST = 'organisationsEinheitHeaderList',
}
import { ListItemResource, ListResource } from '@alfa-client/tech-shared';
import { Resource } from '@ngxp/rest';
export interface OrganisationsEinheit {
name: string;
anschrift: Anschrift;
}
export interface Anschrift {
strasse: string;
hausnummer: string;
plz: string;
ort: string;
}
export interface OrganisationsEinheitResource
extends OrganisationsEinheit,
Resource,
ListItemResource {}
export interface OrganisationsEinheitListResource extends ListResource {}
import { StateResource, createStateResource } from '@alfa-client/tech-shared';
import { Mock, mock, useFromMock } from '@alfa-client/test-utils';
import faker from '@faker-js/faker';
import { Observable, of } from 'rxjs';
import { singleColdCompleted } from '../../../tech-shared/test/marbles';
import {
createOrganisationsEinheitListResource,
createOrganisationsEinheitResource,
} from '../../test/organisations-einheit';
import { OrganisationsEinheitResourceSearchService } from './organisations-einheit-resource-search.service';
import {
OrganisationsEinheitListResource,
OrganisationsEinheitResource,
} from './organisations-einheit.model';
import { OrganisationsEinheitService } from './organisations-einheit.service';
jest.mock('./organisations-einheit-resource-search.service');
describe('OrganisationsEinheitService', () => {
let service: OrganisationsEinheitService;
let searchService: Mock<OrganisationsEinheitResourceSearchService>;
const listResource: OrganisationsEinheitListResource = createOrganisationsEinheitListResource();
const listStateResource: StateResource<OrganisationsEinheitListResource> =
createStateResource(listResource);
beforeEach(() => {
searchService = mock(OrganisationsEinheitResourceSearchService);
service = new OrganisationsEinheitService(useFromMock(searchService));
});
describe('get search result list', () => {
it('should call search service', () => {
service.getSearchResultList();
expect(searchService.getResultList).toHaveBeenCalled();
});
it('should return result', (done) => {
searchService.getResultList.mockReturnValue(of(listStateResource));
service
.getSearchResultList()
.subscribe((result: StateResource<OrganisationsEinheitListResource>) => {
expect(result).toBe(listStateResource);
done();
});
});
});
describe('search', () => {
const searchBy: string = faker.random.word();
it('should call search service with search string', () => {
service.search(searchBy);
expect(searchService.search).toHaveBeenCalledWith(searchBy);
});
});
describe('clear search result', () => {
it('should call search service', () => {
service.clearSearchResult();
expect(searchService.clearResultList).toHaveBeenCalledWith();
});
});
describe('get selected result', () => {
const organisationsEinheitStateResource: StateResource<OrganisationsEinheitResource> =
createStateResource(createOrganisationsEinheitResource());
beforeEach(() => {
searchService.getSelectedResult.mockReturnValue(of(organisationsEinheitStateResource));
});
it('should call service', () => {
service.getSelectedResult();
expect(searchService.getSelectedResult).toHaveBeenCalled();
});
it('should return result', () => {
const selectedResult$: Observable<StateResource<OrganisationsEinheitResource>> =
service.getSelectedResult();
expect(selectedResult$).toBeObservable(
singleColdCompleted(organisationsEinheitStateResource),
);
});
});
describe('select search result', () => {
const organisationsEinheitResource: OrganisationsEinheitResource =
createOrganisationsEinheitResource();
it('should call service', () => {
service.selectSearchResult(organisationsEinheitResource);
expect(searchService.selectResult).toHaveBeenCalledWith(organisationsEinheitResource);
});
});
});
import { StateResource } from '@alfa-client/tech-shared';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { OrganisationsEinheitResourceSearchService } from './organisations-einheit-resource-search.service';
import {
OrganisationsEinheitListResource,
OrganisationsEinheitResource,
} from './organisations-einheit.model';
@Injectable()
export class OrganisationsEinheitService {
constructor(private readonly searchService: OrganisationsEinheitResourceSearchService) {}
public getSearchResultList(): Observable<StateResource<OrganisationsEinheitListResource>> {
return this.searchService.getResultList();
}
public search(searchBy: string): void {
this.searchService.search(searchBy);
}
public clearSearchResult(): void {
this.searchService.clearResultList();
}
public getSelectedResult(): Observable<StateResource<OrganisationsEinheitResource>> {
return this.searchService.getSelectedResult();
}
public selectSearchResult(organisationsEinheitResource: OrganisationsEinheitResource): void {
this.searchService.selectResult(organisationsEinheitResource);
}
}
import { times } from 'lodash-es';
import { toResource } from '../../tech-shared/test/resource';
import {
Anschrift,
OrganisationsEinheit,
OrganisationsEinheitListLinkRel,
OrganisationsEinheitListResource,
OrganisationsEinheitResource,
} from '../src';
import { faker } from '@faker-js/faker';
export function createAnschrift(): Anschrift {
return {
hausnummer: faker.random.word(),
ort: faker.random.word(),
plz: faker.random.word(),
strasse: faker.random.words(2),
};
}
export function createOrganisationsEinheit(): OrganisationsEinheit {
return {
name: faker.random.word(),
anschrift: createAnschrift(),
};
}
export function createOrganisationsEinheitResource(
linkRel: string[] = [],
): OrganisationsEinheitResource {
return toResource(createOrganisationsEinheit(), linkRel);
}
export function createOrganisationsEinheitResources(
linkRelations: string[] = [],
): OrganisationsEinheitResource[] {
return times(10, () => toResource(createOrganisationsEinheitResource(), [...linkRelations]));
}
export function createOrganisationsEinheitListResource(
resources?: OrganisationsEinheitResource[],
linkRelations: string[] = [],
): OrganisationsEinheitListResource {
return toResource({}, [...linkRelations], {
[OrganisationsEinheitListLinkRel.ORGANISATIONS_EINHEIT_HEADER_LIST]:
resources ? resources : createOrganisationsEinheitResources(),
});
}
...@@ -10,8 +10,8 @@ ...@@ -10,8 +10,8 @@
</ng-template> </ng-template>
<ng-container *ngIf="isRequestFormVisible$ | async; else anfrageErstellenButton"> <ng-container *ngIf="isRequestFormVisible$ | async; else anfrageErstellenButton">
<alfa-collaboration-request-container <alfa-collaboration-request-form
data-test-id="collaboration-request-container" data-test-id="collaboration-request-form"
(hideRequestForm)="hideRequestForm()" (hide)="hideRequestForm()"
></alfa-collaboration-request-container> ></alfa-collaboration-request-form>
</ng-container> </ng-container>
...@@ -12,14 +12,14 @@ import { getDataTestIdAttributeOf, getDataTestIdOf } from 'libs/tech-shared/test ...@@ -12,14 +12,14 @@ import { getDataTestIdAttributeOf, getDataTestIdOf } from 'libs/tech-shared/test
import { MockComponent } from 'ng-mocks'; import { MockComponent } from 'ng-mocks';
import { of } from 'rxjs'; import { of } from 'rxjs';
import { CollaborationInVorgangContainerComponent } from './collaboration-in-vorgang-container.component'; import { CollaborationInVorgangContainerComponent } from './collaboration-in-vorgang-container.component';
import { CollaborationRequestContainerComponent } from './collaboration-request-container/collaboration-request-container.component'; import { CollaborationRequestFormComponent } from './collaboration-request-form/collaboration-request-form.component';
describe('CollaborationInVorgangContainerComponent', () => { describe('CollaborationInVorgangContainerComponent', () => {
let component: CollaborationInVorgangContainerComponent; let component: CollaborationInVorgangContainerComponent;
let fixture: ComponentFixture<CollaborationInVorgangContainerComponent>; let fixture: ComponentFixture<CollaborationInVorgangContainerComponent>;
const anfrageErstellenButton: string = getDataTestIdAttributeOf('anfrage-erstellen-button'); const anfrageErstellenButton: string = getDataTestIdAttributeOf('anfrage-erstellen-button');
const collaborationRequestContainer: string = getDataTestIdOf('collaboration-request-container'); const collaborationRequestForm: string = getDataTestIdOf('collaboration-request-form');
const service: Mock<CollaborationService> = { const service: Mock<CollaborationService> = {
...mock(CollaborationService), ...mock(CollaborationService),
...@@ -31,7 +31,7 @@ describe('CollaborationInVorgangContainerComponent', () => { ...@@ -31,7 +31,7 @@ describe('CollaborationInVorgangContainerComponent', () => {
declarations: [ declarations: [
CollaborationInVorgangContainerComponent, CollaborationInVorgangContainerComponent,
MockComponent(ButtonComponent), MockComponent(ButtonComponent),
MockComponent(CollaborationRequestContainerComponent), MockComponent(CollaborationRequestFormComponent),
MockComponent(CollaborationIconComponent), MockComponent(CollaborationIconComponent),
], ],
providers: [ providers: [
...@@ -97,13 +97,13 @@ describe('CollaborationInVorgangContainerComponent', () => { ...@@ -97,13 +97,13 @@ describe('CollaborationInVorgangContainerComponent', () => {
it('should be shown', () => { it('should be shown', () => {
fixture.detectChanges(); fixture.detectChanges();
existsAsHtmlElement(fixture, collaborationRequestContainer); existsAsHtmlElement(fixture, collaborationRequestForm);
}); });
it('should call service on hideFormular output', () => { it('should call service on hideFormular output', () => {
fixture.detectChanges(); fixture.detectChanges();
dispatchEventFromFixture(fixture, collaborationRequestContainer, 'hideRequestForm'); dispatchEventFromFixture(fixture, collaborationRequestForm, 'hide');
expect(service.hideRequestForm).toHaveBeenCalled(); expect(service.hideRequestForm).toHaveBeenCalled();
}); });
...@@ -114,7 +114,7 @@ describe('CollaborationInVorgangContainerComponent', () => { ...@@ -114,7 +114,7 @@ describe('CollaborationInVorgangContainerComponent', () => {
fixture.detectChanges(); fixture.detectChanges();
notExistsAsHtmlElement(fixture, collaborationRequestContainer); notExistsAsHtmlElement(fixture, collaborationRequestForm);
}); });
}); });
}); });
<ods-button
variant="outline"
text="Zuständige Stelle auswählen"
dataTestId="zustaendige-stelle-search-button"
>
<ods-search-icon icon />
</ods-button>
<div class="my-6">
<alfa-collaboration-request-form></alfa-collaboration-request-form>
</div>
<div class="flex items-center gap-6">
<ods-button text="Zuarbeit anfragen" dataTestId="collaboration-request-send-button"></ods-button>
<ods-button
variant="outline"
text="Abbrechen"
dataTestId="collaboration-request-cancel-button"
(clickEmitter)="hideRequestForm.emit()"
>
<ods-close-icon icon class="fill-primary"></ods-close-icon>
</ods-button>
</div>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment