Skip to content
Snippets Groups Projects
Commit 164975e4 authored by OZGCloud's avatar OZGCloud
Browse files

OZG-297 refresh attachments on wiedervorlage; extend e2e test

parent a861c7eb
No related branches found
No related tags found
No related merge requests found
Showing
with 187 additions and 80 deletions
......@@ -9,13 +9,16 @@ export class WiedervorlageAttachmentListE2EComponent {
public getAttachment(fileName: string): AttachmentE2EItem {
return new AttachmentE2EItem(fileName);
}
public getAttachments() {
return this.getRoot().children();
}
}
class AttachmentE2EItem {
private deleteButton$: string = 'icon-button';
constructor(private fileName: string) { }
public getRoot() {
......
......@@ -5,7 +5,7 @@ import { WiedervorlageE2EComponent } from '../../components/wiedervorlage/wieder
import { MainPage } from '../../page-objects/main.po';
import { VorgangPage } from '../../page-objects/vorgang.po';
import { WiedervorlagePage } from '../../page-objects/wiedervorlage.po';
import { CypressTasks, DatabaseUser, DataCollections, exist, MongoCollections, notExist } from '../../support/cypress.util';
import { CypressTasks, DatabaseUser, DataCollections, exist, haveLength, MongoCollections, notExist } from '../../support/cypress.util';
import { TEST_FILE, TEST_FILE_WITH_CONTENT } from '../../support/data.util';
import { uploadEmptyFile, uploadFile } from '../../support/file-upload';
......@@ -21,13 +21,13 @@ describe('Wiedervorlage attachments', () => {
const attachmentContainer: WiedervorlageAttachmentsE2EComponent = wiedervorlageContainer.getAttachmentContainer();
const attachmentList: WiedervorlageAttachmentListE2EComponent = attachmentContainer.getAttachmentList();
const WIEDERVORLAGE_BETREFF: string = 'WiedervorlageWithAttachments';
const WIEDERVORLAGE_WITH_ATTACHMENTS_BETREFF: string = 'WiedervorlageWithAttachments';
let vorgangWithoutWiedervorlage;
before(() => {
cy.fixture(DataCollections.WIEDERVORLAGEN).then(data => {
vorgangWithoutWiedervorlage = data[0];
vorgangWithoutWiedervorlage = data[2];
cy.task(CypressTasks.INIT_DATA, { collection: MongoCollections.VORGANG, data })
});
......@@ -65,22 +65,22 @@ describe('Wiedervorlage attachments', () => {
})
it('save wiedervorlage', () => {
wiedervorlageContainer.getBetreff().clear().type(WIEDERVORLAGE_BETREFF);
wiedervorlageContainer.getBetreff().clear().type(WIEDERVORLAGE_WITH_ATTACHMENTS_BETREFF);
wiedervorlageContainer.getSpeichernButton().click();
})
it('wiedervorlage in vorgang-detail should show attachments', () => {
wiedervorlageContainerInVorgang.getWiedervorlage(WIEDERVORLAGE_BETREFF).expandItem();
wiedervorlageContainerInVorgang.getWiedervorlage(WIEDERVORLAGE_WITH_ATTACHMENTS_BETREFF).expandItem();
exist(wiedervorlageContainerInVorgang.getWiedervorlage(WIEDERVORLAGE_BETREFF).getAttachmentList().getAttachment(TEST_FILE).getRoot());
exist(wiedervorlageContainerInVorgang.getWiedervorlage(WIEDERVORLAGE_WITH_ATTACHMENTS_BETREFF).getAttachmentList().getAttachment(TEST_FILE).getRoot());
})
})
describe('Delete attachment', () => {
it('open wiedervorlage page', () => {
wiedervorlageContainerInVorgang.getWiedervorlage(WIEDERVORLAGE_BETREFF).getLink().click();
wiedervorlageContainerInVorgang.getWiedervorlage(WIEDERVORLAGE_WITH_ATTACHMENTS_BETREFF).getLink().click();
exist(attachmentList.getAttachment(TEST_FILE).getRoot());
exist(attachmentList.getAttachment(TEST_FILE_WITH_CONTENT).getRoot());
......@@ -96,10 +96,32 @@ describe('Wiedervorlage attachments', () => {
})
it('check attachments in wiedervorlage list', () => {
wiedervorlageContainerInVorgang.getWiedervorlage(WIEDERVORLAGE_BETREFF).expandItem();
wiedervorlageContainerInVorgang.getWiedervorlage(WIEDERVORLAGE_WITH_ATTACHMENTS_BETREFF).expandItem();
notExist(wiedervorlageContainerInVorgang.getWiedervorlage(WIEDERVORLAGE_BETREFF).getAttachmentList().getAttachment(TEST_FILE).getRoot());
exist(wiedervorlageContainerInVorgang.getWiedervorlage(WIEDERVORLAGE_BETREFF).getAttachmentList().getAttachment(TEST_FILE_WITH_CONTENT).getRoot());
notExist(wiedervorlageContainerInVorgang.getWiedervorlage(WIEDERVORLAGE_WITH_ATTACHMENTS_BETREFF).getAttachmentList().getAttachment(TEST_FILE).getRoot());
exist(wiedervorlageContainerInVorgang.getWiedervorlage(WIEDERVORLAGE_WITH_ATTACHMENTS_BETREFF).getAttachmentList().getAttachment(TEST_FILE_WITH_CONTENT).getRoot());
})
})
describe('switch to wiedervorlage without attachments', () => {
const WIEDERVORLAGE_WITHOUT_ATTACHMENT_BETREFF: string = 'WiedervorlageZumErledigen';
it('should not show any attachments', () => {
wiedervorlageContainerInVorgang.getWiedervorlage(WIEDERVORLAGE_WITHOUT_ATTACHMENT_BETREFF).getLink().click();
haveLength(attachmentList.getAttachments(), 0);
wiedervorlagePage.getSubnavigation().navigateBack();
})
})
describe('switch to wiedervorlage with attachments', () => {
it('should show attachments', () => {
wiedervorlageContainerInVorgang.getWiedervorlage(WIEDERVORLAGE_WITH_ATTACHMENTS_BETREFF).getLink().click();
haveLength(attachmentList.getAttachments(), 1);
})
})
})
\ No newline at end of file
......@@ -42,6 +42,10 @@ export function enterWith(element: any, value: any): void {
element.clear().type(value + '{enter}')
}
export function haveLength(element: any, length: number) {
return element.should('have.length', length);
}
//TODO: "first()" rausnehmen -> im html eine entprechende data-test-id ansprechen?!
export function shouldFirstContains(element: any, containing: string) {
element.first().should('exist').contains(containing);
......
......@@ -32,7 +32,7 @@ describe('KommentarFormService', () => {
})
it('should call createKommentar', () => {
formService.source.next(null);
formService.source = null;
formService.submit();
......@@ -40,7 +40,7 @@ describe('KommentarFormService', () => {
})
it('should call editKommentar', () => {
formService.source.next(kommentarResource);
formService.source = kommentarResource;
formService.submit();
......
import { FormBuilder, FormGroup } from '@angular/forms';
import { ApiError, hasError, setValidationError, StateResource } from '@goofy-client/tech-shared';
import { isNull } from 'lodash-es';
import { BehaviorSubject, Observable } from 'rxjs';
import { isNil } from 'lodash-es';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
export abstract class AbstractFormService {
form: FormGroup;
pathPrefix: string;
source: BehaviorSubject<any> = new BehaviorSubject(null);
source: any;
constructor(public formBuilder: FormBuilder) {
this.form = this.initForm();
......@@ -33,9 +33,15 @@ export abstract class AbstractFormService {
this.form.reset();
this.form.patchValue(valueToPatch);
this.source.next(valueToPatch);
this.source = valueToPatch;
this.doAfterPatch(valueToPatch);
}
doAfterPatch(source: any): void {
//No Implementation here for abstract class
};
setError(apiError: ApiError): void {
apiError.issues.forEach(issue => setValidationError(this.form, issue, this.getPathPrefix()))
}
......@@ -46,15 +52,11 @@ export abstract class AbstractFormService {
return this.form.value;
}
public getSource(): Observable<any> {
return this.source.asObservable();
}
protected getSourceValue(): any {
return this.source.value;
return this.source;
}
public isPatch(): boolean {
return !isNull(this.source.value);
return !isNil(this.source);
}
}
\ No newline at end of file
<goofy-client-anhang-list-in-wiedervorlage data-test-id="wiedervorlage-attachment-list"
[attachments]="attachments$ | async" [deletable]="deletable"
(deleteAttachment)="deleteAttachment($event)">
(deleteAttachment)="deleteAttachment.emit($event)">
</goofy-client-anhang-list-in-wiedervorlage>
\ No newline at end of file
......@@ -5,14 +5,14 @@ import { mock } from '@goofy-client/test-utils';
import { WiedervorlageService } from '@goofy-client/wiedervorlage-shared';
import { configureTestSuite } from 'ng-bullet';
import { MockComponent } from 'ng-mocks';
import { WiedervorlageFormService } from '../wiedervorlage-page-container/wiedervorlage-page/wiedervorlage-form/wiedervorlage.formservice';
import { of } from 'rxjs';
import { WiedervorlageAttachmentListComponent } from './wiedervorlage-attachment-list.component';
describe('WiedervorlageAttachmentListComponent', () => {
let component: WiedervorlageAttachmentListComponent;
let fixture: ComponentFixture<WiedervorlageAttachmentListComponent>;
const wiedervorlageFormService = mock(WiedervorlageService);
const wiedervorlageService = { ...mock(WiedervorlageService), getAttachmentList: () => of(null) };
configureTestSuite(() => {
TestBed.configureTestingModule({
......@@ -23,8 +23,8 @@ describe('WiedervorlageAttachmentListComponent', () => {
],
providers: [
{
provide: WiedervorlageFormService,
useValue: wiedervorlageFormService
provide: WiedervorlageService,
useValue: wiedervorlageService
}
]
})
......
import { Component, Input, OnChanges, SimpleChanges } from '@angular/core';
import { Component, EventEmitter, Input, OnChanges, Output, SimpleChanges } from '@angular/core';
import { OzgFileListLinkRel, OzgFileResource } from '@goofy-client/ozg-file-shared';
import { WiedervorlageResource } from '@goofy-client/wiedervorlage-shared';
import { WiedervorlageResource, WiedervorlageService } from '@goofy-client/wiedervorlage-shared';
import { getEmbeddedResource } from '@ngxp/rest';
import { isNil } from 'lodash-es';
import { Observable, of } from 'rxjs';
import { WiedervorlageFormService } from '../wiedervorlage-page-container/wiedervorlage-page/wiedervorlage-form/wiedervorlage.formservice';
import { map } from 'rxjs/operators';
@Component({
selector: 'goofy-client-wiedervorlage-attachment-list',
......@@ -15,23 +16,25 @@ export class WiedervorlageAttachmentListComponent implements OnChanges {
@Input() wiedervorlage: WiedervorlageResource;
@Input() deletable: boolean;
@Output() deleteAttachment: EventEmitter<OzgFileResource> = new EventEmitter();
readonly fileListRel = OzgFileListLinkRel;
attachments$: Observable<OzgFileResource[]> = of([]);
constructor(public formService: WiedervorlageFormService) { }
constructor(public service: WiedervorlageService) { }
ngOnChanges(changes: SimpleChanges): void {
if (changes.wiedervorlage) {
this.attachments$ = this.formService.getAttachments();
if (!isNil(this.wiedervorlage)) {
this.formService.patch(this.wiedervorlage);
}
if (changes.wiedervorlage && !isNil(this.wiedervorlage)) {
this.updateAttachments();
}
}
deleteAttachment(attachment: OzgFileResource): void {
this.formService.deleteAttachment(attachment);
updateAttachments() {
this.attachments$ = this.service.getAttachmentList(this.wiedervorlage).pipe(map(list => {
return list.resource
? getEmbeddedResource<OzgFileResource[]>(list.resource, OzgFileListLinkRel.FILE_LIST)
: [];
}))
}
}
\ No newline at end of file
<goofy-client-wiedervorlage-attachment-list [wiedervorlage]="wiedervorlage" [deletable]="true"></goofy-client-wiedervorlage-attachment-list>
<goofy-client-anhang-list-in-wiedervorlage data-test-id="wiedervorlage-attachment-list"
[attachments]="attachments$ | async" [deletable]="true"
(deleteAttachment)="deleteAttachment($event)">
</goofy-client-anhang-list-in-wiedervorlage>
<goofy-client-spinner [stateResource]="uploadInProgress$ | async">
<goofy-client-file-upload (fileChanged)="uploadFile($event)" data-test-id="wiedervorlage-file-upload"></goofy-client-file-upload>
......
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { AnhaengeComponent } from '@goofy-client/ozg-file';
import { HasLinkPipe } from '@goofy-client/tech-shared';
import { AnhaengeComponent, AnhangListInWiedervorlageComponent } from '@goofy-client/ozg-file';
import { OzgFileResource } from '@goofy-client/ozg-file-shared';
import { createEmptyStateResource, createStateResource, HasLinkPipe } from '@goofy-client/tech-shared';
import { mock } from '@goofy-client/test-utils';
import { FileUploadComponent, SpinnerComponent } from '@goofy-client/ui';
import { WiedervorlageService } from '@goofy-client/wiedervorlage-shared';
import { createOzgFileResource } from 'libs/ozg-file-shared/test/ozg-file';
import { configureTestSuite } from 'ng-bullet';
import { MockComponent } from 'ng-mocks';
import { of } from 'rxjs';
import { WiedervorlageAttachmentListComponent } from '../wiedervorlage-attachment-list/wiedervorlage-attachment-list.component';
import { WiedervorlageFormService } from '../wiedervorlage-page-container/wiedervorlage-page/wiedervorlage-form/wiedervorlage.formservice';
import { WiedervorlageAttachmentsComponent } from './wiedervorlage-attachments.component';
......@@ -14,8 +17,10 @@ describe('WiedervorlageAttachmentsComponent', () => {
let component: WiedervorlageAttachmentsComponent;
let fixture: ComponentFixture<WiedervorlageAttachmentsComponent>;
const wiedervorlageFormService = mock(WiedervorlageFormService);
const wiedervorlageService = mock(WiedervorlageService);
const formService = mock(WiedervorlageFormService);
const service = mock(WiedervorlageService);
const file: OzgFileResource = createOzgFileResource();
configureTestSuite(() => {
TestBed.configureTestingModule({
......@@ -25,16 +30,17 @@ describe('WiedervorlageAttachmentsComponent', () => {
MockComponent(WiedervorlageAttachmentListComponent),
MockComponent(SpinnerComponent),
MockComponent(AnhaengeComponent),
MockComponent(FileUploadComponent)
MockComponent(FileUploadComponent),
MockComponent(AnhangListInWiedervorlageComponent)
],
providers: [
{
provide: WiedervorlageFormService,
useValue: wiedervorlageFormService
useValue: formService
},
{
provide: WiedervorlageService,
useValue: wiedervorlageService
useValue: service
}
]
})
......@@ -49,4 +55,57 @@ describe('WiedervorlageAttachmentsComponent', () => {
it('should create', () => {
expect(component).toBeTruthy();
});
describe('upload file', () => {
const file: File = <any>{ name: 'TestDatei' };
const ozgFile: OzgFileResource = createOzgFileResource();
beforeEach(() => {
service.uploadFile.mockReturnValue(of(createStateResource(ozgFile)));
})
it('should call service', () => {
component.uploadFile(<any>file)
expect(service.uploadFile).toHaveBeenCalledWith(file);
})
describe('do after upload', () => {
beforeEach(() => {
component.addAttachment = jest.fn();
})
it('should emit file after successfull upload', () => {
component.doAfterFileUpload(createStateResource(ozgFile));
expect(component.addAttachment).toHaveBeenCalledWith(ozgFile);
})
it('should not emit file while stateResource is null', () => {
component.doAfterFileUpload(createEmptyStateResource());
expect(component.addAttachment).not.toHaveBeenCalled();
})
})
})
describe('delete attachment', () => {
it('should call form service', () => {
component.deleteAttachment(file);
expect(formService.deleteAttachment).toHaveBeenCalledWith(file);
})
})
describe('add attachment', () => {
it('should call form service', () => {
component.addAttachment(file);
expect(formService.addAttachment).toHaveBeenCalledWith(file);
})
})
});
\ No newline at end of file
import { ChangeDetectorRef, Component, EventEmitter, Input, Output } from '@angular/core';
import { Component, EventEmitter, Input, Output } from '@angular/core';
import { OzgFileResource } from '@goofy-client/ozg-file-shared';
import { createEmptyStateResource, StateResource } from '@goofy-client/tech-shared';
import { WiedervorlageLinkRel, WiedervorlageResource, WiedervorlageService } from '@goofy-client/wiedervorlage-shared';
import { isNull } from 'lodash-es';
import { Observable, of } from 'rxjs';
import { tap } from 'rxjs/operators';
import { WiedervorlageFormService } from '../wiedervorlage-page-container/wiedervorlage-page/wiedervorlage-form/wiedervorlage.formservice';
......@@ -19,19 +20,29 @@ export class WiedervorlageAttachmentsComponent {
readonly linkRel = WiedervorlageLinkRel;
attachments$: Observable<OzgFileResource[]> = of([]);
uploadInProgress$: Observable<StateResource<any>> = of(createEmptyStateResource());
constructor(public formService: WiedervorlageFormService, private changeDetector: ChangeDetectorRef, private wiedervorlageService: WiedervorlageService) { }
constructor(public formService: WiedervorlageFormService, private wiedervorlageService: WiedervorlageService) {
this.attachments$ = this.formService.getAttachments();
}
uploadFile(file: File): void {
this.uploadInProgress$ = this.wiedervorlageService.uploadFile(file).pipe(
tap((stateResource: StateResource<OzgFileResource>) => this.doAfterFileUpload(stateResource)));
}
private doAfterFileUpload(stateResource: StateResource<OzgFileResource>): void {
if (stateResource.loaded) {
this.formService.addAttachment(stateResource.resource);
this.changeDetector.detectChanges();
doAfterFileUpload(stateResource: StateResource<OzgFileResource>): void {
if (stateResource.loaded && !isNull(stateResource.resource)) {
this.addAttachment(stateResource.resource);
}
}
addAttachment(ozgFile: OzgFileResource) {
this.formService.addAttachment(ozgFile);
}
deleteAttachment(ozgFile: OzgFileResource) {
this.formService.deleteAttachment(ozgFile);
}
}
\ No newline at end of file
......@@ -20,7 +20,7 @@ describe('WiedervorlageFormComponent', () => {
let component: WiedervorlageFormComponent;
let fixture: ComponentFixture<WiedervorlageFormComponent>;
const wiedervorlageFormService = new WiedervorlageFormService(new FormBuilder(), useFromMock(mock(WiedervorlageService)));
const formService = new WiedervorlageFormService(new FormBuilder(), useFromMock(mock(WiedervorlageService)));
const wiedervorlage: WiedervorlageResource = createWiedervorlageResource();
configureTestSuite(() => {
......@@ -42,14 +42,14 @@ describe('WiedervorlageFormComponent', () => {
providers: [
{
provide: WiedervorlageFormService,
useValue: wiedervorlageFormService
useValue: formService
}
]
})
});
beforeEach(() => {
wiedervorlageFormService.patch = jest.fn();
formService.patch = jest.fn();
fixture = TestBed.createComponent(WiedervorlageFormComponent);
component = fixture.componentInstance;
......@@ -60,14 +60,14 @@ describe('WiedervorlageFormComponent', () => {
expect(component).toBeTruthy();
});
describe('pathWiedervorlage', () => {
describe('patch wiedervorlage', () => {
it('should NOT patch by formservice', () => {
component.wiedervorlage = null;
component.patchWiedervorlage();
expect(wiedervorlageFormService.patch).not.toHaveBeenCalled();
expect(formService.patch).not.toHaveBeenCalled();
})
it('should patch by formservice', () => {
......@@ -75,7 +75,7 @@ describe('WiedervorlageFormComponent', () => {
component.patchWiedervorlage();
expect(wiedervorlageFormService.patch).toHaveBeenCalledWith(wiedervorlage);
expect(formService.patch).toHaveBeenCalledWith(wiedervorlage);
})
})
});
......@@ -38,7 +38,7 @@ describe('WiedervorlageFormService', () => {
})
it('should call createWiedervorlage', () => {
formService.source.next(null);
formService.source = null;
formService.submit();
......@@ -46,7 +46,7 @@ describe('WiedervorlageFormService', () => {
})
it('should call saveWiedervorlage', () => {
formService.source.next(wiedervorlageResource);
formService.source = wiedervorlageResource;
formService.submit();
......
......@@ -6,6 +6,7 @@ import { Wiedervorlage, WiedervorlageLinkRel, WiedervorlageResource, Wiedervorla
import { getEmbeddedResource, getUrl, hasLink } from '@ngxp/rest';
import { isNil, isNull } from 'lodash-es';
import { BehaviorSubject, Observable, Subscription } from 'rxjs';
import { tap } from 'rxjs/operators';
@Injectable()
export class WiedervorlageFormService extends AbstractFormService implements OnDestroy {
......@@ -18,26 +19,24 @@ export class WiedervorlageFormService extends AbstractFormService implements OnD
private attachments: BehaviorSubject<OzgFileResource[]> = new BehaviorSubject([]);
private attachmentSubscription: Subscription;
private sourceSubscription: Subscription;
constructor(
formBuilder: FormBuilder,
private wiedervorlageService: WiedervorlageService
) {
super(formBuilder);
this.subscribeToSource();
}
private subscribeToSource(): void {
if (!isNil(this.sourceSubscription)) this.sourceSubscription.unsubscribe();
this.sourceSubscription = this.getSource().subscribe((wiedervorlage: WiedervorlageResource) => this.handleSourceChange(wiedervorlage))
}
doAfterPatch(wiedervorlage: WiedervorlageResource): void {
if (!isNil(this.attachmentSubscription)) this.attachmentSubscription.unsubscribe();
console.info('do after patch');
handleSourceChange(wiedervorlage: WiedervorlageResource): void {
this.hasAttachments(wiedervorlage)
? this.subscribeToAttachments(wiedervorlage)
: this.attachments.next([]);
if (this.hasAttachments(wiedervorlage)) {
this.subscribeToAttachments(wiedervorlage);
} else {
console.info('update attachments to []');
this.attachments.next([]);
}
}
private hasAttachments(wiedervorlage: WiedervorlageResource): boolean {
......@@ -45,14 +44,14 @@ export class WiedervorlageFormService extends AbstractFormService implements OnD
}
private subscribeToAttachments(wiedervorlage: WiedervorlageResource): void {
if (!isNil(this.attachmentSubscription)) this.attachmentSubscription.unsubscribe();
this.attachmentSubscription = this.wiedervorlageService.getAttachmentList(wiedervorlage).subscribe(attachmentsList => this.handleAttachmentList(attachmentsList));
}
handleAttachmentList(attachmentsList: StateResource<OzgFileListResource>): void {
attachmentsList.resource
? this.attachments.next(getEmbeddedResource<OzgFileResource[]>(attachmentsList.resource, OzgFileListLinkRel.FILE_LIST))
: this.attachments.next([]);
if (attachmentsList.resource) {
console.info('update attachments to existing');
this.attachments.next(getEmbeddedResource<OzgFileResource[]>(attachmentsList.resource, OzgFileListLinkRel.FILE_LIST));
}
}
protected initForm(): FormGroup {
......@@ -81,18 +80,20 @@ export class WiedervorlageFormService extends AbstractFormService implements OnD
}
public getAttachments(): Observable<OzgFileResource[]> {
return this.attachments.asObservable();
return this.attachments.asObservable().pipe(tap(attachments => console.info('fire with: ', attachments)));
}
public addAttachment(attachment: OzgFileResource): void {
let attachments = this.attachments.value;
attachments.push(attachment);
console.info('update attachment: add: ', attachment);
this.attachments.next(attachments);
}
public deleteAttachment(attachment: OzgFileResource): void {
let attachments = this.attachments.value;
attachments.splice(attachments.indexOf(attachment), 1);
console.info('update attachment: delete: ', attachment);
this.attachments.next(attachments);
}
......@@ -101,7 +102,6 @@ export class WiedervorlageFormService extends AbstractFormService implements OnD
}
unsubscribe(): void {
if (!isNil(this.sourceSubscription)) this.sourceSubscription.unsubscribe();
if (!isNil(this.attachmentSubscription)) this.attachmentSubscription.unsubscribe();
}
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment