Skip to content

Commit

Permalink
Fixed linked publications/datasets visibility in detail pages #1372 (#…
Browse files Browse the repository at this point in the history
…1686)

* Added failing tests for #1372

* View related publications/datasets even when not authorized + disable all interactivity for those view-summary-only items #1372

* Add blank state for withdrawn records you do not own and simplify buttons

---------

Co-authored-by: mietcls <[email protected]>
  • Loading branch information
verheyenkoen and mietcls authored Aug 14, 2024
1 parent 01d7bdc commit 84729e4
Show file tree
Hide file tree
Showing 22 changed files with 1,009 additions and 474 deletions.
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,13 @@
"eisbn",
"eissn",
"esci",
"github",
"isbn",
"issn",
"liblogin",
"organiser",
"publicationviewing",
"publicationviews",
"pubmed",
"socs",
"tagify"
Expand Down
284 changes: 284 additions & 0 deletions cypress/e2e/issues/issue-1372.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,284 @@
// https://github.com/ugent-library/biblio-backoffice/issues/1372

import { getRandomText } from "support/util";

describe("Issue #1372: Administrative support staff cannot see linked datasets/publications in a record if they are not assigned", () => {
const publicationTitle = getRandomText();
const datasetTitle = getRandomText();

before(() => {
cy.login("librarian1");

cy.setUpPublication(undefined, {
title: publicationTitle,
biblioIDAlias: "publication",
publish: true,
shouldWaitForIndex: true,
});
cy.addAuthor("Extra", "Author1", {
biblioIDAlias: "@publication",
external: true,
});
cy.addAuthor("Extra", "Author2", {
biblioIDAlias: "@publication",
external: true,
});
cy.addAuthor("Extra", "Author3", {
biblioIDAlias: "@publication",
external: true,
});
cy.addAuthor("Extra", "Author4", {
biblioIDAlias: "@publication",
external: true,
});
cy.addAuthor("Biblio", "Researcher1", { biblioIDAlias: "@publication" });

cy.setUpDataset({
title: datasetTitle,
biblioIDAlias: "dataset",
publish: true,
shouldWaitForIndex: true,
});
cy.addCreator("Extra", "Creator1", {
biblioIDAlias: "@dataset",
external: true,
});
cy.addCreator("Extra", "Creator2", {
biblioIDAlias: "@dataset",
external: true,
});
cy.addCreator("Extra", "Creator3", {
biblioIDAlias: "@dataset",
external: true,
});
cy.addCreator("Extra", "Creator4", {
biblioIDAlias: "@dataset",
external: true,
});
cy.addCreator("Biblio", "Researcher2", { biblioIDAlias: "@dataset" });

// Link the two together
cy.visitPublication("@publication");
cy.contains(".nav .nav-item", "Datasets").click();

cy.get("#datasets-body").should("contain.text", "No datasets");

cy.contains(".card", "Related datasets")
.contains(".btn", "Add dataset")
.click();

cy.ensureModal("Select datasets").within(() => {
cy.intercept("/publication/*/datasets/suggestions?*").as(
"suggestDataset",
);

cy.getLabel("Search")
.next("input")
.should("be.focused")
.type(datasetTitle);
cy.wait("@suggestDataset");

cy.contains(".list-group-item", datasetTitle)
.contains(".btn", "Add dataset")
.click();
});
cy.ensureNoModal();
});

beforeEach(() => {
cy.login("librarian1");

// Refresh biblio ID aliases set in before-hook for subsequent tests
cy.visit("/publication", { qs: { q: publicationTitle } });
cy.extractBiblioId("publication");

cy.visit("/dataset", { qs: { q: datasetTitle } });
cy.extractBiblioId("dataset");
});

it("should be possible for researchers to see linked datasets of a publication, even if they cannot access them directly", () => {
cy.visitPublication("@publication");
cy.contains(".nav .nav-item", "Datasets").click();

cy.get("#datasets-body").should("not.contain.text", "No datasets");
cy.get("#datasets-body .list-group-item")
.as("item")
.should("have.length", 1)
.should("contain.text", datasetTitle);

verifyActionability("publication", true, true);

// Now view this as researcher
cy.login("researcher1");
cy.get<string>("@dataset").then((datasetId) => {
cy.request({
url: `/dataset/${datasetId}`,
failOnStatusCode: false,
}).then((response) => {
expect(response.status).to.eq(403);
expect(response.statusText).to.eq("Forbidden");
});
});

cy.visitPublication("@publication");
cy.contains(".nav .nav-item", "Datasets").click();

cy.contains(".btn", "Add dataset").should("be.visible");
cy.get("#datasets-body").should("not.contain.text", "No datasets");
cy.get("#datasets-body .list-group-item")
.should("have.length", 1)
.should("contain.text", datasetTitle);

verifyActionability("publication", false, true);

// Now lock the publication and make sure the researcher cannot add and remove datasets anymore
cy.login("librarian1");
cy.visitPublication("@publication");
cy.contains(".btn", "Lock record").click();
cy.closeToast();

cy.login("researcher1");
cy.visitPublication("@publication");
cy.contains(".nav .nav-item", "Datasets").click();
cy.contains(".btn", "Add dataset").should("not.exist");

verifyActionability("publication", false, false);
});

it("should be possible for researchers to see linked publications of a dataset, even if they cannot access them directly", () => {
cy.visitDataset("@dataset");
cy.contains(".nav .nav-item", "Publications").click();

cy.get("#publications-body").should("not.contain.text", "No publications");
cy.get("#publications-body .list-group-item")
.as("item")
.should("have.length", 1)
.should("contain.text", publicationTitle);

verifyActionability("dataset", true, true);

// Now view this as researcher
cy.login("researcher2");
cy.get<string>("@publication").then((publicationId) => {
cy.request({
url: `/publication/${publicationId}`,
failOnStatusCode: false,
}).then((response) => {
expect(response.status).to.eq(403);
expect(response.statusText).to.eq("Forbidden");
});
});

cy.visitDataset("@dataset");
cy.contains(".nav .nav-item", "Publications").click();

cy.contains(".btn", "Add publication").should("be.visible");
cy.get("#publications-body").should("not.contain.text", "No publications");
cy.get("#publications-body .list-group-item")
.should("have.length", 1)
.should("contain.text", publicationTitle);

verifyActionability("dataset", false, true);

// Now lock the dataset and make sure the researcher cannot add and remove publications anymore
cy.login("librarian1");
cy.visitDataset("@dataset");
cy.contains(".btn", "Lock record").click();
cy.closeToast();

cy.login("researcher2");
cy.visitDataset("@dataset");
cy.contains(".nav .nav-item", "Publications").click();
cy.contains(".btn", "Add publication").should("not.exist");

verifyActionability("dataset", false, false);
});

function verifyActionability(
context: "publication" | "dataset",
isActionable: boolean,
canAddAndRemoveRelatedItems: boolean,
) {
const prefix = isActionable ? "" : "not.";
const relatedContext =
context === "publication" ? "dataset" : "publication";
const relatedContributorType =
relatedContext === "publication" ? "author" : "creator";

cy.get("@item").within(() => {
// Verify the title is (not) a link to the detail page
const $title = cy
.get(".list-group-item-title")
.parent()
.should(prefix + "have.prop", "tagName", "A");

if (isActionable) {
$title
.should("have.attr", "href")
.should("match", new RegExp(`^/${relatedContext}/[A-Z0-9]+$`));
}

// Verify there is an/no "more authors/creators" link
cy.get(".c-author-list .c-author:not(:contains('Your role'))")
.as("contributors")
.map<HTMLElement, string>((i) => i.textContent.trim())
.should("have.ordered.members", [
"John Doe",
`Extra ${Cypress._.capitalize(relatedContributorType)}1`,
`Extra ${Cypress._.capitalize(relatedContributorType)}2`,
`3 more ${relatedContributorType}s`,
]);

const $moreContributors = cy
.get("@contributors")
.contains(`3 more ${relatedContributorType}s`)
.should(prefix + "have.prop", "tagName", "A");

if (isActionable) {
$moreContributors
.should(prefix + "have.attr", "href")
.should(
"match",
new RegExp(`^/${relatedContext}/[A-Z0-9]+\\?show=contributors$`),
);
}

// Verify there is an/no "Add department" link
const $addDepartment = cy
.contains("a", "Add department")
.should(isActionable ? "be.visible" : "not.exist");

if (isActionable) {
$addDepartment
.should("have.attr", "href")
.should(
"match",
new RegExp(`^/${relatedContext}/[A-Z0-9]+\\?show=contributors$`),
);
}

// Open context menu
const $dropdown = cy
.get(".dropdown .if-more")
.should(
isActionable || canAddAndRemoveRelatedItems
? "be.visible"
: "not.exist",
);

if (isActionable || canAddAndRemoveRelatedItems) {
$dropdown.click();

// Verify there is an/no link to "View publication/dataset" in the context menu
cy.contains(".dropdown-item", `View ${relatedContext}`).should(
isActionable ? "be.visible" : "not.exist",
);

// In any case, there should be a "Remove from publication/dataset" link in the context menu
cy.contains(".dropdown-item", `Remove from ${context}`).should(
"be.visible",
);
}
});
}
});
16 changes: 8 additions & 8 deletions cypress/e2e/publications/search/researcher.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ describe("The publication search (for researchers)", () => {
title: `Dissertation 1 ${randomTitleSuffix}`,
shouldWaitForIndex: true,
});
cy.addAuthor("Biblio", "Researcher1", { biblioIdAlias: "@dissertation1" });
cy.addAuthor("Biblio", "Researcher1", { biblioIDAlias: "@dissertation1" });
cy.addSupervisor("Biblio", "Researcher2", {
biblioIdAlias: "@dissertation1",
biblioIDAlias: "@dissertation1",
});

cy.loginAsResearcher("researcher2");
Expand All @@ -22,27 +22,27 @@ describe("The publication search (for researchers)", () => {
title: `Book ${randomTitleSuffix}`,
shouldWaitForIndex: true,
});
cy.addAuthor("John", "Doe", { biblioIdAlias: "@book" });
cy.addEditor("Biblio", "Researcher2", { biblioIdAlias: "@book" });
cy.addAuthor("John", "Doe", { biblioIDAlias: "@book" });
cy.addEditor("Biblio", "Researcher2", { biblioIDAlias: "@book" });

cy.setUpPublication("Dissertation", {
biblioIDAlias: "dissertation2",
title: `Dissertation 2 ${randomTitleSuffix}`,
shouldWaitForIndex: true,
});
cy.addAuthor("Biblio", "Researcher2", { biblioIdAlias: "@dissertation2" });
cy.addAuthor("Biblio", "Researcher2", { biblioIDAlias: "@dissertation2" });
cy.addSupervisor("Biblio", "Researcher1", {
biblioIdAlias: "@dissertation2",
biblioIDAlias: "@dissertation2",
});

cy.setUpPublication("Dissertation", {
biblioIDAlias: "dissertation3",
title: `Dissertation 3 ${randomTitleSuffix}`,
shouldWaitForIndex: true,
});
cy.addAuthor("Biblio", "Researcher1", { biblioIdAlias: "@dissertation3" });
cy.addAuthor("Biblio", "Researcher1", { biblioIDAlias: "@dissertation3" });
cy.addSupervisor("Biblio", "Researcher2", {
biblioIdAlias: "@dissertation3",
biblioIDAlias: "@dissertation3",
});

// Extra time for ES to index this
Expand Down
14 changes: 7 additions & 7 deletions cypress/support/commands/add-contributor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,11 @@ function addContributor(
contributorType: ContributorType,
firstName: string,
lastName: string,
{ external, role, biblioIdAlias = "@biblioId" }: AddAuthorOptions = {},
{ external, role, biblioIDAlias = "@biblioId" }: AddAuthorOptions = {},
): void {
cy.get<string>(biblioIdAlias, NO_LOG).then((biblioId) => {
cy.get<string>(biblioIDAlias, NO_LOG).then((biblioId) => {
const log = prepareLog({
biblioIdAlias,
biblioIDAlias,
biblioId,
contributorType,
firstName,
Expand Down Expand Up @@ -135,15 +135,15 @@ function addContributor(
}

function prepareLog({
biblioIdAlias,
biblioIDAlias,
biblioId,
contributorType,
firstName,
lastName,
external,
role,
}: {
biblioIdAlias: Cypress.Alias;
biblioIDAlias: Cypress.Alias;
biblioId: string;
contributorType: string;
firstName: string;
Expand All @@ -152,7 +152,7 @@ function prepareLog({
role: string;
}) {
const consoleProps = {
"Biblio ID alias": biblioIdAlias,
"Biblio ID alias": biblioIDAlias,
"Biblio ID": biblioId,
"Contributor type": contributorType,
"First name": firstName,
Expand Down Expand Up @@ -181,7 +181,7 @@ function extractHxValues(response: Cypress.Response<string>) {

type AddContributorOptions = {
external?: boolean;
biblioIdAlias?: Cypress.Alias;
biblioIDAlias?: Cypress.Alias;
};

type AddAuthorOptions = AddContributorOptions & {
Expand Down
Loading

0 comments on commit 84729e4

Please sign in to comment.