Skip to content

Commit

Permalink
Merge branch 'main' into feature/dev-2995-add-form-to-update-restrict…
Browse files Browse the repository at this point in the history
…ed-view-settings-watermark-and

* main:
  fix(dsp-das): image viewer padding, arrows style. Resource list name css adjustments (DEV-3276) (#1456)
  fix: loads all projects when membership dialog is opened (DEV-3268) (#1450)
  test: add projects, list and auth end to end tests (#1454)
  fix: add instrumentation to faro sdk (#1455)
  feat(dsp-app): image settings updates and fixes (DEV-2995) (#1451)
  fix: remove old "edit project" page url (#1452)
  chore(main): release 11.5.1 (#1449)
  chore: update dsp-js to v9.1.11 (#1447)
  chore(main): release 11.5.0 (#1442)
  fix: list item delete (DEV-3267) (#1446)

# Conflicts:
#	apps/dsp-app/src/app/project/image-settings/image-settings.component.html
#	apps/dsp-app/src/app/project/image-settings/image-settings.component.scss
#	apps/dsp-app/src/app/project/image-settings/image-settings.component.ts
#	apps/dsp-app/src/app/project/image-settings/project-image-settings.ts
#	apps/dsp-app/src/assets/i18n/de.json
#	apps/dsp-app/src/assets/i18n/en.json
  • Loading branch information
irmastnt committed Feb 13, 2024
2 parents 760d8ea + 332f8d5 commit 6e45327
Show file tree
Hide file tree
Showing 39 changed files with 793 additions and 116 deletions.
22 changes: 22 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,27 @@
# Changelog

## [11.5.1](https://github.com/dasch-swiss/dsp-das/compare/v11.5.0...v11.5.1) (2024-02-09)


### Maintenance

* update dsp-js to v9.1.11 ([#1447](https://github.com/dasch-swiss/dsp-das/issues/1447)) ([eb4dfa5](https://github.com/dasch-swiss/dsp-das/commit/eb4dfa5d3ba60ab6761e362dbb13e684d1939b2f))

## [11.5.0](https://github.com/dasch-swiss/dsp-das/compare/v11.4.1...v11.5.0) (2024-02-09)


### Enhancements

* **dsp-das:** image settings (DEV-2995) ([#1440](https://github.com/dasch-swiss/dsp-das/issues/1440)) ([3609b52](https://github.com/dasch-swiss/dsp-das/commit/3609b52c1c31a83f980862d72e7206f58802df4d))
* **dsp-das:** project menu items highlighting (DEV-3103) ([#1444](https://github.com/dasch-swiss/dsp-das/issues/1444)) ([c78ddf7](https://github.com/dasch-swiss/dsp-das/commit/c78ddf7fdffca9c547902bc4d2ed618e1bd2ae87))


### Bug Fixes

* list item delete (DEV-3267) ([#1446](https://github.com/dasch-swiss/dsp-das/issues/1446)) ([affd20f](https://github.com/dasch-swiss/dsp-das/commit/affd20f61e11437c4ddd4062df6287d22117c01e))
* styling issue in project membership ([#1443](https://github.com/dasch-swiss/dsp-das/issues/1443)) ([7825d3d](https://github.com/dasch-swiss/dsp-das/commit/7825d3d772701c18dbe7ea117d5ac9ae11d53721))
* user can create a project if no active project exists ([#1441](https://github.com/dasch-swiss/dsp-das/issues/1441)) ([3cc36d9](https://github.com/dasch-swiss/dsp-das/commit/3cc36d947770741e0650be2c28c77fc194cca163))

## [11.4.1](https://github.com/dasch-swiss/dsp-das/compare/v11.4.0...v11.4.1) (2024-02-07)


Expand Down
38 changes: 38 additions & 0 deletions apps/dsp-app/cypress/e2e/logged-out-user/auth.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { faker } from '@faker-js/faker';
import { UserProfiles } from '../../models/user-profiles';

describe('Authentication', () => {
const po = {
loginButton: '[data-cy=login-button]',
username: '[data-cy=username-input]',
password: '[data-cy=password-input]',
submitButton: '[data-cy=submit-button]',
};
it('Logged out user can login', () => {
cy.readFile('cypress/fixtures/user_profiles.json').then((users: UserProfiles) => {
cy.visit('/');

cy.get(po.loginButton).click();

cy.get(po.username).type(users.systemAdmin_username_root);
cy.get(po.password).type(users.systemAdmin_password_root);
cy.get(po.submitButton).click();

cy.get(po.loginButton).should('not.be.visible');
});
});

it('Logged out user receives a notification if wrong credentials', () => {
cy.visit('/');

cy.get(po.loginButton).click();

cy.get(po.username).type(faker.internet.userName());
cy.get(po.password).type(faker.internet.password());
cy.get(po.submitButton).click();

cy.get('body').click('topLeft');
cy.get(po.loginButton).should('be.visible');
cy.get('.data-cy-snackbar').should('contain', 'The username and / or password do not match.');
});
});
15 changes: 7 additions & 8 deletions apps/dsp-app/cypress/e2e/logged-out-user/dashboard.cy.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
describe('Visual Check for Projects on Home Page', () => {
it.skip('should load clickable projects on the home page', () => {
it('should load clickable projects on the home page', () => {
cy.visit('/');

cy.get('[data-cy=accept-cookies]').click();

const projectTileSelector = '[data-cy=tile]';

cy.get(projectTileSelector).should('be.visible').should('have.length.greaterThan', 0);

cy.get(projectTileSelector).first().find('[data-cy=navigate-to-project-button]').click();
cy.get('[data-cy=tile]')
.should('be.visible')
.should('have.length.greaterThan', 0)
.first()
.find('[data-cy=navigate-to-project-button]')
.click();

cy.url().should('include', '/project'); // Update with the expected URL
});
Expand Down
7 changes: 2 additions & 5 deletions apps/dsp-app/cypress/e2e/system-admin/dashboard.cy.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
const MY_TOKEN = '';
localStorage.setItem('ACCESS_TOKEN', MY_TOKEN);

describe('ADMIN TEST', () => {
it.skip('should load clickable projects on the home page', () => {
describe('Dashboard', () => {
it('should load clickable projects on the home page', () => {
cy.visit('/');
const projectTileSelector = '[data-cy=tile]';

Expand Down
59 changes: 59 additions & 0 deletions apps/dsp-app/cypress/e2e/system-admin/lists.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { faker } from '@faker-js/faker';
import { ListGetResponseADM } from '../../../../../libs/vre/open-api/src';

describe('Lists', () => {
let listUrl: string;
let listId: string;
beforeEach(() => {
cy.request<ListGetResponseADM>('POST', `${Cypress.env('apiUrl')}/admin/lists`, {
comments: [{ language: 'de', value: faker.lorem.words(2) }],
labels: [{ language: 'de', value: faker.lorem.words(2) }],
projectIri: 'http://rdfh.ch/projects/00FF',
}).then(response => {
listId = response.body.list.listinfo.id.match(/\/([^\/]*)$/)[1];
listUrl = `/project/00FF/list/${listId}`;
});
});

it('user can create a list', () => {
cy.intercept('POST', '/admin/lists').as('submitRequest');

cy.visit('/project/00FF/add-list');
cy.get('[data-cy=labels-input]').type(faker.lorem.words(2));
cy.get('[data-cy=comments-input]').type(faker.lorem.sentence());
cy.get('[data-cy=submit-button]').click();

cy.wait('@submitRequest');
cy.url().should('match', /\/project\/00FF\/list\/(.+)/);
});

it('user can edit a list', () => {
const data = {
label: faker.lorem.words(2),
comment: faker.lorem.word(2),
};
cy.intercept('PUT', '/admin/lists/*').as('editRequest');

cy.visit(listUrl);

cy.get('[data-cy=edit-button]').click();
cy.get('[data-cy=labels-input] input').clear().type(data.label, { force: true });
cy.get('[data-cy=comments-input]').clear().type(data.comment);
cy.get('[data-cy=submit-button]').click();

cy.wait('@editRequest');
cy.url().should('match', /\/project\/00FF\/list\/(.+)/);
cy.get('[data-cy=label-title]').contains(data.label);
cy.get('[data-cy=comment-title]').contains(data.comment);
});

it('user can delete a list', () => {
cy.visit(listUrl);
cy.intercept('DELETE', '/admin/lists/*').as('deleteRequest');
cy.get('[data-cy=delete-button]').click();
cy.get('[data-cy=confirmation-button]').click();
cy.wait('@deleteRequest');

cy.url().should('match', /\/project\/00FF\/data-models$/);
});
});
117 changes: 117 additions & 0 deletions apps/dsp-app/cypress/e2e/system-admin/projects.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import { faker } from '@faker-js/faker';
import { ProjectOperationResponseADM } from '../../../../../libs/vre/open-api/src';
import { customShortcode } from '../../support/helpers/custom-shortcode';
import { generateKeyword } from '../../support/helpers/custom-word';
import { randomNumber } from '../../support/helpers/random-number';

describe('Projects', () => {
let projectIri: string;

const payload = {
shortname: 'shortname',
shortcode: 'A0A0',
longname: 'Longname',
description: [{ language: 'de', value: 'description' }],
keywords: ['keyword'],
status: true,
selfjoin: true,
};

beforeEach(() => {
cy.request<ProjectOperationResponseADM>('POST', `${Cypress.env('apiUrl')}/admin/projects`, payload).then(
response => {
projectIri = response.body.project.id;
}
);
});

it('admin can create a project', () => {
const data = {
shortcode: customShortcode(),
shortname: faker.internet.userName(),
longname: faker.company.name(),
description: faker.lorem.sentence(),
keywords: Array.from({ length: randomNumber(3, 6) }, () => generateKeyword(4)),
};

cy.intercept('POST', '/admin/projects').as('submitRequest');

cy.visit('/project/create-new');
cy.get('[data-cy=shortcode-input]').type(data.shortcode);
cy.get('[data-cy=shortname-input]').type(data.shortname);
cy.get('[data-cy=longname-input]').type(data.longname);
cy.get('[data-cy=description-input]').type(data.description);
cy.get('[data-cy=keywords-input]').type(`${data.keywords.join('{enter}')}{enter}`);
cy.get('[data-cy=submit-button]').click();

cy.wait('@submitRequest');
cy.url().should('match', /\/project\/(.+)/);
cy.contains(data.shortcode).should('be.visible');
cy.contains(data.description).should('be.visible');
data.keywords.forEach(keyword => cy.contains(keyword).should('be.visible'));
});

it('admin can edit a project', () => {
const data = {
longname: faker.company.name(),
description: faker.lorem.sentence(),
keywords: faker.lorem.words(3).split(' '),
};
cy.intercept('PUT', '/admin/projects/iri/*').as('submitRequest');

cy.visit(`/project/${projectIri.match(/\/([^\/]+)$/)[1]}/settings/edit`);
cy.get('[data-cy=shortcode-input] input').should('have.value', payload.shortcode);
cy.get('[data-cy=shortname-input] input').should('have.value', payload.shortname);
cy.get('[data-cy=longname-input] input').should('have.value', payload.longname).clear().type(data.longname);
cy.get('[data-cy=description-input] textarea')
.should('have.value', payload.description[0].value)
.clear()
.type(data.description);
cy.get('[data-cy=keywords-input] input')
.type('{backspace}'.repeat(5))
.type(`${data.keywords.join('{enter}')}{enter}`);
cy.get('[data-cy=submit-button]').click();

cy.wait('@submitRequest');
cy.url().should('match', /\/project\/(.+)/);
cy.contains(payload.shortcode).should('be.visible');
cy.contains(data.description).should('be.visible');
data.keywords.forEach(keyword => cy.contains(keyword).should('be.visible'));
});

it('admin can deactivate a project', () => {
cy.intercept('DELETE', `/admin/projects/iri/${encodeURIComponent(projectIri)}`).as('deactivateRequest');

cy.visit('/system/projects');
cy.get('[data-cy=active-projects-section]')
.contains('[data-cy=project-row]', payload.shortcode)
.find('[data-cy=more-button]')
.scrollIntoView()
.should('be.visible')
.click();
cy.get('[data-cy=deactivate-button]').click();
cy.get('[data-cy=confirmation-button]').click();
cy.wait('@deactivateRequest');

cy.get('[data-cy=inactive-projects-section]').contains('[data-cy=project-row]', payload.shortcode).should('exist');
});

it.only('admin can reactivate a project', () => {
cy.intercept('PUT', `/admin/projects/iri/${encodeURIComponent(projectIri)}`).as('updateRequest');

cy.request('DELETE', `${Cypress.env('apiUrl')}/admin/projects/iri/${encodeURIComponent(projectIri)}`).then(() => {
cy.visit('/system/projects');
cy.get('[data-cy=inactive-projects-section]')
.contains('[data-cy=project-row]', payload.shortcode)
.find('[data-cy=more-button]')
.scrollIntoView()
.should('be.visible')
.click();
cy.get('[data-cy=reactivate-button]').scrollIntoView().click({ force: true });
cy.get('[data-cy=confirmation-button]').click();
cy.wait('@updateRequest');

cy.get('[data-cy=active-projects-section]').contains('[data-cy=project-row]', payload.shortcode).should('exist');
});
});
});
1 change: 1 addition & 0 deletions apps/dsp-app/cypress/support/commands/login.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Cypress.Commands.add('login', (user: User) => {
},
}).then(response => {
localStorage.setItem('cookieBanner', 'false');
localStorage.setItem('rnw-closed-banners', 'true');
localStorage.setItem('ACCESS_TOKEN', response.body.token);
});
},
Expand Down
7 changes: 7 additions & 0 deletions apps/dsp-app/cypress/support/e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ import { UserProfiles } from '../models/user-profiles';
// All active session data (cookies, localStorage and sessionStorage) across all domains are cleared.
beforeEach(() => {
let users: UserProfiles;

// clear database
cy.request({
method: 'POST',
url: `${Cypress.env('apiUrl')}/admin/store/ResetTriplestoreContent`,
});

cy.readFile('cypress/fixtures/user_profiles.json').then((json: UserProfiles) => {
// read JSON data file
users = json;
Expand Down
19 changes: 19 additions & 0 deletions apps/dsp-app/cypress/support/helpers/custom-shortcode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
export const customShortcode = () => {
const validLetters = 'ABCDEF';
const validDigits = '0123456789';

const getRandomChar = characters => characters[Math.floor(Math.random() * characters.length)];

let result = '';

// Generate up to 4 characters
for (let i = 0; i < 4; i++) {
// Decide whether to add a letter or a digit
const isLetter = Math.random() < 0.5;

// Add a random letter or digit to the result
result += isLetter ? getRandomChar(validLetters) : getRandomChar(validDigits);
}

return result;
};
9 changes: 9 additions & 0 deletions apps/dsp-app/cypress/support/helpers/custom-word.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { faker } from '@faker-js/faker';

export function generateKeyword(minLength: number) {
let keyword = faker.lorem.word();
while (keyword.length < minLength) {
keyword = faker.lorem.word();
}
return keyword;
}
3 changes: 3 additions & 0 deletions apps/dsp-app/cypress/support/helpers/random-number.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function randomNumber(min: number, max: number) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
4 changes: 2 additions & 2 deletions apps/dsp-app/cypress/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
{
"extends": "../tsconfig.json",
"include": [
"**/*.ts"
],
"exclude": [],
"compilerOptions": {
"sourceMap": false,
"types": [
"cypress"
"cypress",
"node"
]
}
}
5 changes: 0 additions & 5 deletions apps/dsp-app/src/app/app-routing.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,6 @@ const routes: Routes = [
path: RouteConstants.projectUuidRelative,
component: ProjectComponent,
children: [
{
path: RouteConstants.edit,
canActivate: [AuthGuard],
component: EditProjectFormPageComponent,
},
{
path: RouteConstants.home,
component: DescriptionComponent,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export interface ConfirmDialogProps {
</div>
<div mat-dialog-actions align="end">
<button mat-button (click)="dialogRef.close(false)">No</button>
<button mat-raised-button color="warn" (click)="dialogRef.close(true)">Yes</button>
<button mat-raised-button color="warn" (click)="dialogRef.close(true)" data-cy="confirmation-button">Yes</button>
</div>
`,
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,13 @@ import { finalize, takeLast, tap } from 'rxjs/operators';
selector: 'app-login-form',
template: `
<form [formGroup]="form" (ngSubmit)="login()" class="login-form">
<app-common-input [formGroup]="form" controlName="username" placeholder="Username"></app-common-input>
<app-common-input
[formGroup]="form"
controlName="username"
placeholder="Username"
data-cy="username-input"></app-common-input>
<mat-form-field>
<mat-form-field data-cy="password-input">
<input
placeholder="Password"
autocomplete="current-password"
Expand All @@ -31,7 +35,8 @@ import { finalize, takeLast, tap } from 'rxjs/operators';
mat-raised-button
appLoadingButton
[isLoading]="loading"
type="submit">
type="submit"
data-cy="submit-button">
{{ isLoginError ? ('appLabels.form.action.retry' | translate) : ('appLabels.form.action.login' | translate) }}
</button>
</form>
Expand Down

0 comments on commit 6e45327

Please sign in to comment.