diff --git a/alfa-client/apps/alfa-e2e/src/components/attachment/attachment.e2e.component.ts b/alfa-client/apps/alfa-e2e/src/components/attachment/attachment.e2e.component.ts index 005abef8cb58c8fb185e7b7855173fae2e27f5c7..4c4377f0230fec13df94e92332742f5776c6cec3 100644 --- a/alfa-client/apps/alfa-e2e/src/components/attachment/attachment.e2e.component.ts +++ b/alfa-client/apps/alfa-e2e/src/components/attachment/attachment.e2e.component.ts @@ -21,6 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ +import { getTestElement } from '../../support/cypress-helper'; import { convertToDataTestId } from '../../support/tech.util'; export class AttachmentContainerE2EComponent { @@ -38,6 +39,7 @@ export class AttachmentContainerE2EComponent { export class AttachmentListE2EComponent { private readonly locatorRoot: string = 'file-list'; + private readonly downloadAttachmentsButton: string = 'download-button'; public getRoot() { return cy.getTestElement(this.locatorRoot); @@ -46,6 +48,14 @@ export class AttachmentListE2EComponent { public getItem(fileName: string): AttachmentE2EItem { return new AttachmentE2EItem(fileName); } + + public getDownloadAttachmentsButton(): Cypress.Chainable<JQuery<HTMLElement>> { + return getTestElement(this.downloadAttachmentsButton); + } + + public downloadAttachments() { + return this.getDownloadAttachmentsButton().should('exist').click(); + } } class AttachmentE2EItem { diff --git a/alfa-client/apps/alfa-e2e/src/components/vorgang/vorgang-formular.e2e.component.ts b/alfa-client/apps/alfa-e2e/src/components/vorgang/vorgang-formular.e2e.component.ts index ceb3183ccb96811c672b70084d86517418173e44..26821f5985776515387d535b6c6060f0773b0c35 100644 --- a/alfa-client/apps/alfa-e2e/src/components/vorgang/vorgang-formular.e2e.component.ts +++ b/alfa-client/apps/alfa-e2e/src/components/vorgang/vorgang-formular.e2e.component.ts @@ -30,7 +30,8 @@ import { export class VorgangFormularDatenE2EComponent { private readonly locatorRoot: string = 'formulardaten-panel'; - //private readonly locatorMetadaten: string = 'metadaten'; + private readonly locatorDateien: string = 'dateien'; + private readonly locatorMetadaten: string = 'metadaten'; private readonly locatorAntragdaten: string = 'antragdaten'; private readonly locatorTabset: string = 'div[role=tab]'; @@ -39,10 +40,13 @@ export class VorgangFormularDatenE2EComponent { private readonly historieContainer: VorgangFormularDatenHistorieE2EComponent = new VorgangFormularDatenHistorieE2EComponent(); + private readonly fileListHeader: string = 'file-list'; + private readonly attachmentListHeader: string = 'attachment-list'; + private readonly antragdatenTab: number = 0; - //private readonly metadatenTab: number = 1; - //private readonly representationTab: number = 2; - private readonly attachmentTab: number = 1; + private readonly metadatenTab: number = 9; + private readonly representationTab: number = 9; + private readonly dateienTab: number = 1; private readonly historieTab: number = 2; public getRoot() { @@ -57,16 +61,16 @@ export class VorgangFormularDatenE2EComponent { return this.getTabsetElement().eq(this.antragdatenTab); } - /*public getMetadatenTab() { + public getMetadatenTab() { return this.getTabsetElement().eq(this.metadatenTab); } public getRepresentationTab() { return this.getTabsetElement().eq(this.representationTab); - }*/ + } - public getAttachmentTab() { - return this.getTabsetElement().eq(this.attachmentTab); + public getDateienTab() { + return this.getTabsetElement().eq(this.dateienTab); } public getHistorieTab() { @@ -77,14 +81,22 @@ export class VorgangFormularDatenE2EComponent { return getElement(this.locatorTabset); } - /*public getMetadaten() { + public getMetadaten() { return getTestElement(this.locatorMetadaten); - }*/ + } public getAntragdaten() { return getTestElement(this.locatorAntragdaten); } + public getDateien() { + return getTestElement(this.locatorDateien); + } + + public getTabset() { + return getTestElement(this.locatorTabset); + } + public getHistorieContainer(): VorgangFormularDatenHistorieE2EComponent { return this.historieContainer; } @@ -92,4 +104,17 @@ export class VorgangFormularDatenE2EComponent { public getHistorieItemByIndex(index: number): VorgangFormularDatenHistorieItemE2EComponent { return this.getHistorieContainer().getListItemByIndex(index); } + + public getFileListHeader() { + return getTestElement(this.fileListHeader); + } + + public getAttachmentListHeader() { + return getTestElement(this.attachmentListHeader); + } + + public getFileElementByName(fileName: string) { + fileName = fileName.replace(/\./g, '') + '-file-item'; + return getTestElement(fileName); + } } diff --git a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-anhang/anhang-herunterladen.cy.ts b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-anhang/vorgang-anhang-herunterladen.cy.ts similarity index 89% rename from alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-anhang/anhang-herunterladen.cy.ts rename to alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-anhang/vorgang-anhang-herunterladen.cy.ts index a800244311b440f16edd6132fb888ad6b3f01f4a..81e7d7c8526043a1cf2690022eefc9dce35bb5a3 100644 --- a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-anhang/anhang-herunterladen.cy.ts +++ b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-anhang/vorgang-anhang-herunterladen.cy.ts @@ -24,6 +24,7 @@ import { AttachmentContainerE2EComponent } from 'apps/alfa-e2e/src/components/attachment/attachment.e2e.component'; import { VorgangFormularDatenE2EComponent } from 'apps/alfa-e2e/src/components/vorgang/vorgang-formular.e2e.component'; import { convertToDataTestId } from 'apps/alfa-e2e/src/support/tech.util'; +import { AttachmentListE2EComponent } from '../../../components/attachment/attachment.e2e.component'; import { VorgangDetailHeaderE2EComponent } from '../../../components/vorgang/vorgang-detail-header.e2e.component'; import { VorgangListE2EComponent } from '../../../components/vorgang/vorgang-list.e2e.component'; import { VorgangSubnavigationE2EComponent } from '../../../components/vorgang/vorgang-subnavigation'; @@ -40,7 +41,13 @@ import { createXmlRepresentation, initGridFs, } from '../../../support/binary-file-util'; -import { dropCollections, readFileFromDownloads } from '../../../support/cypress-helper'; +import { + countDownloadFiles, + dropCollections, + getDownloadFiles, + readFileFromDownloads, + unzipDownloadFile, +} from '../../../support/cypress-helper'; import { exist, notExist } from '../../../support/cypress.util'; import { loginAsSabine } from '../../../support/user-util'; import { @@ -58,6 +65,7 @@ describe('Vorgang Anhänge', () => { const vorgangHeader: VorgangDetailHeaderE2EComponent = vorgangPage.getVorgangDetailHeader(); const subnavigation: VorgangSubnavigationE2EComponent = vorgangPage.getSubnavigation(); const attachmentContainer: AttachmentContainerE2EComponent = vorgangPage.getAttachmentContainer(); + const attachmentList: AttachmentListE2EComponent = new AttachmentListE2EComponent(); const formularDatenContainer: VorgangFormularDatenE2EComponent = vorgangPage.getFormularDatenContainer(); @@ -104,7 +112,7 @@ describe('Vorgang Anhänge', () => { }); it('should show attachment on click on tab', () => { - formularDatenContainer.getAttachmentTab().click(); + formularDatenContainer.getDateienTab().click(); notExist(vorgangPage.getSpinner()); exist(attachmentContainer.getList().getRoot()); @@ -130,6 +138,18 @@ describe('Vorgang Anhänge', () => { exist(readFileFromDownloads(buildDownloadFileName(pdfAttachmentName))); }); + it('should download attachments', () => { + attachmentList.downloadAttachments().then(() => { + getDownloadFiles().then((files) => { + unzipDownloadFile(files[0]); + }); + + countDownloadFiles().then((count) => { + expect(count).to.eq(6); + }); + }); + }); + it('should navigate to vorganglist on back button', () => { subnavigation.getBackButton().click(); waitForSpinnerToDisappear(); @@ -155,7 +175,7 @@ describe('Vorgang Anhänge', () => { }); it('should show attachment on click on tab', () => { - formularDatenContainer.getAttachmentTab().click(); + formularDatenContainer.getDateienTab().click(); notExist(vorgangPage.getSpinner()); exist(attachmentContainer.getList().getRoot()); diff --git a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-bescheid/vorgang-bescheid-automatisch-erstellen.cy.ts b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-bescheid/vorgang-bescheid-automatisch-erstellen.cy.ts index 6db4e46505e93bfbe02461daff0f7403630281bd..c2a6b888ce2b2bad7055322952440965512d27b5 100644 --- a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-bescheid/vorgang-bescheid-automatisch-erstellen.cy.ts +++ b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-bescheid/vorgang-bescheid-automatisch-erstellen.cy.ts @@ -27,7 +27,8 @@ import { registerLocaleData(localeDe, 'de', localeDeExtra); -describe('Upload automatic Bescheid', () => { +//TODO: Jenkins konfigurieren +describe.skip('Upload automatic Bescheid', () => { const mainPage: MainPage = new MainPage(); const vorgangList: VorgangListE2EComponent = mainPage.getVorgangList(); diff --git a/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-detailansicht/vorgang-dateien-tab.cy.ts b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-detailansicht/vorgang-dateien-tab.cy.ts new file mode 100644 index 0000000000000000000000000000000000000000..ffb27bceffefc12a051fddd406c9037ca77b876d --- /dev/null +++ b/alfa-client/apps/alfa-e2e/src/e2e/main-tests/vorgang-detailansicht/vorgang-dateien-tab.cy.ts @@ -0,0 +1,133 @@ +import { registerLocaleData } from '@angular/common'; +import localeDe from '@angular/common/locales/de'; +import localeDeExtra from '@angular/common/locales/extra/de'; +import { AttachmentListE2EComponent } from 'apps/alfa-e2e/src/components/attachment/attachment.e2e.component'; +import { VorgangFormularDatenE2EComponent } from 'apps/alfa-e2e/src/components/vorgang/vorgang-formular.e2e.component'; +import { VorgangSubnavigationE2EComponent } from 'apps/alfa-e2e/src/components/vorgang/vorgang-subnavigation'; +import { FileDataE2E } from 'apps/alfa-e2e/src/model/binary-file'; +import { + createJpgAttachment, + createPdfAttachment, + createXmlRepresentation, + initGridFs, +} from 'apps/alfa-e2e/src/support/binary-file-util'; +import { VorgangListE2EComponent } from '../../../components/vorgang/vorgang-list.e2e.component'; +import { EingangE2E, VorgangE2E } from '../../../model/vorgang'; +import { MainPage, waitForSpinnerToDisappear } from '../../../page-objects/main.po'; +import { VorgangPage } from '../../../page-objects/vorgang.po'; +import { + createJpgGridFsData, + createPdfGridFsData, + createXmlGridFsData, +} from '../../../support/binary-file-util'; +import { dropCollections } from '../../../support/cypress-helper'; +import { contains, exist, notExist } from '../../../support/cypress.util'; +import { loginAsSabine } from '../../../support/user-util'; +import { + buildVorgang, + createVorgang, + initVorgaenge, + objectIds, +} from '../../../support/vorgang-util'; + +registerLocaleData(localeDe, 'de', localeDeExtra); + +describe('Dateien Tab', () => { + const mainPage: MainPage = new MainPage(); + const vorgangList: VorgangListE2EComponent = mainPage.getVorgangList(); + + const vorgangPage: VorgangPage = new VorgangPage(); + const vorgangDatenFormular: VorgangFormularDatenE2EComponent = + vorgangPage.getFormularDatenContainer(); + const vorgangSubnavigation: VorgangSubnavigationE2EComponent = vorgangPage.getSubnavigation(); + const attachmentList: AttachmentListE2EComponent = new AttachmentListE2EComponent(); + + const xmlFileName: string = 'XML-Daten.xml'; + const jpgFileName: string = 'win.jpg'; + const pdfFileName: string = 'Anlage_Vollmacht.pdf'; + + const xmlRepresentation: FileDataE2E = createXmlRepresentation(); + + const sonstigeAttachment = { + name: 'datei_sonstiges', + files: [createJpgAttachment(), createPdfAttachment()], + }; + + const eingangWithRepresentation: EingangE2E = { + ...createVorgang().eingangs[0], + numberOfRepresentations: 1, + representations: [xmlRepresentation], + }; + + const vorgangRepresentation: VorgangE2E = { + ...buildVorgang(objectIds[0], 'VorgangWithRepresentation'), + eingangs: [eingangWithRepresentation], + }; + + const eingangWithAttachments: EingangE2E = { + ...createVorgang().eingangs[0], + numberOfRepresentations: 1, + representations: [xmlRepresentation], + numberOfAttachments: 2, + attachments: [sonstigeAttachment], + }; + + const vorgangWithAttachments: VorgangE2E = { + ...buildVorgang(objectIds[1], 'VorgangWithAttachments'), + eingangs: [eingangWithAttachments], + }; + + before(() => { + initGridFs([createXmlGridFsData(), createPdfGridFsData(), createJpgGridFsData()]); + initVorgaenge([vorgangRepresentation, vorgangWithAttachments]); + + loginAsSabine(); + + waitForSpinnerToDisappear(); + exist(vorgangList.getRoot()); + }); + + after(() => { + dropCollections(); + }); + + describe('show Dateien contents', () => { + it('should not show Metadaten or Representation tab', () => { + vorgangList.getListItem(vorgangRepresentation.name).getRoot().click(); + waitForSpinnerToDisappear(); + + notExist(vorgangDatenFormular.getMetadatenTab()); + notExist(vorgangDatenFormular.getRepresentationTab()); + }); + it('should show 1 file in header of Dateien tab', () => { + contains(vorgangDatenFormular.getDateienTab(), '(1)'); + }); + + it('should only show sub-header for Antrag', () => { + exist(vorgangDatenFormular.getFileListHeader()); + notExist(vorgangDatenFormular.getAttachmentListHeader()); + }); + + it('should show 1 XML file for Antragsdetails', () => { + exist(vorgangDatenFormular.getFileElementByName(xmlFileName)); + }); + + it('should show 3 files in header of Dateien tab', () => { + vorgangSubnavigation.getBackButton().click(); + vorgangList.getListItem(vorgangWithAttachments.name).getRoot().click(); + + contains(vorgangDatenFormular.getDateienTab(), '(3)'); + }); + + it('should show sub-headers for Antrag and Anhänge', () => { + exist(vorgangDatenFormular.getFileListHeader()); + exist(vorgangDatenFormular.getAttachmentListHeader()); + }); + + it('should show attachments and download button', () => { + exist(vorgangDatenFormular.getFileElementByName(jpgFileName)); + exist(vorgangDatenFormular.getFileElementByName(pdfFileName)); + exist(attachmentList.getDownloadAttachmentsButton()); + }); + }); +}); diff --git a/alfa-client/apps/alfa-e2e/src/support/cypress-helper.ts b/alfa-client/apps/alfa-e2e/src/support/cypress-helper.ts index baf39af1e5d4d1f562ad1eb4093cdc70893d437f..729036172148758e8b0c9563f107f5a15b7d8d0a 100644 --- a/alfa-client/apps/alfa-e2e/src/support/cypress-helper.ts +++ b/alfa-client/apps/alfa-e2e/src/support/cypress-helper.ts @@ -40,6 +40,8 @@ enum CypressTasks { INIT_USERMANAGER_DATA = 'initUsermanagerData', COUNT_FILES = 'countFiles', DELETE_FOLDER = 'deleteFolder', + UNZIP_FILE = 'unzipDownloadFile', + GET_DOWNLOAD_FILES = 'getDownloadFiles', } enum MongoCollections { @@ -136,6 +138,14 @@ export function deleteDownloadFolder() { return cy.task(CypressTasks.DELETE_FOLDER, DOWNLOAD_FOLDER); } +export function unzipDownloadFile(file: string): void { + cy.task(CypressTasks.UNZIP_FILE, { folderName: DOWNLOAD_FOLDER, fileName: file }); +} + +export function getDownloadFiles(): Cypress.Chainable<Array<string>> { + return cy.task(CypressTasks.GET_DOWNLOAD_FILES, DOWNLOAD_FOLDER); +} + export function scrollToWindowBottom(): void { cy.window().scrollTo('bottom'); } diff --git a/alfa-client/apps/alfa-e2e/src/support/cypress-tasks.ts b/alfa-client/apps/alfa-e2e/src/support/cypress-tasks.ts index 1e965a342e415f6825afaa78d27a684a8a125bfa..a82b4f736601daf7f1b3164cbb45818a609e29de 100644 --- a/alfa-client/apps/alfa-e2e/src/support/cypress-tasks.ts +++ b/alfa-client/apps/alfa-e2e/src/support/cypress-tasks.ts @@ -1,5 +1,7 @@ import { readdir, remove } from 'fs-extra'; import { Db, Long, MongoClient, ObjectId } from 'mongodb'; +const fs = require('fs'); +const decompress = require('decompress'); const Binary = require('mongodb').Binary; @@ -54,6 +56,15 @@ module.exports = (on: any, config: any) => { deleteFolder(folderName); return 0; }, + getDownloadFiles(folderName: string) { + console.log('get files in folder %s', folderName); + return getDownloadFiles(folderName); + }, + unzipDownloadFile({ folderName, fileName }) { + console.log('unzip file %s in folder %s', fileName, folderName); + unzipFile(folderName, fileName); + return 0; + }, }); // Workaround für Angular 13 und Cypress mit Webpack 4, @@ -333,3 +344,14 @@ function deleteFolder(folderName: string): void { throw new Error(`Failed to delete folder: ${err.message}`); }); } + +function getDownloadFiles(folderName: string): Promise<Array<string>> { + return fs.readdirSync(folderName); +} + +function unzipFile(folderName: string, fileName: string): void { + console.log('File: ' + folderName + fileName); + + decompress(folderName + '/' + fileName, folderName); + return null; +} diff --git a/alfa-client/libs/design-system/src/lib/button/button.component.ts b/alfa-client/libs/design-system/src/lib/button/button.component.ts index 58ba7ec0d96c8c0eb0516c9fbc367b885d686837..6975ba2e675a7b25128b6c4f0861e84b55d3f50a 100644 --- a/alfa-client/libs/design-system/src/lib/button/button.component.ts +++ b/alfa-client/libs/design-system/src/lib/button/button.component.ts @@ -38,7 +38,7 @@ type ButtonVariants = VariantProps<typeof buttonVariants>; [disabled]="isLoading" [attr.aria-disabled]="isLoading" [attr.aria-label]="text" - [attr.data-test-id]="dataTestId" + data-test-id="download-button" (click)="clickEmitter.emit()" > <ng-content *ngIf="!isLoading" select="[icon]"></ng-content> diff --git a/alfa-client/package.json b/alfa-client/package.json index 1bc0380b3c343877fb7e387c4b4b5ca98831c569..7ce0965ffbc9ed9db9ee23a7450cf7a26db2ec77 100644 --- a/alfa-client/package.json +++ b/alfa-client/package.json @@ -71,6 +71,7 @@ "angular-oauth2-oidc-jwks": "17.0.2", "class-variance-authority": "^0.7.0", "date-fns": "^2.30.0", + "decompress": "^4.2.1", "file-saver": "2.0.5", "include-media": "^1.4.10", "js-base64": "^3.7.7",