Bug 10190: (follow-up): test: cypress tests update
New tests:
- regression: mtt cells render as .fallback (bold italics)
- bg-success-subtle highlight on completed steps in the add flow
- disabled-Delete states:
- patron category filter set
- item type filter set
- default library, if any library has a trigger higher that default's highest
- redirect to admin home if not permitted to access the page
- in the edit/add stepper form
- check row actions are enabled at the 'selectOrAdd' step
- check row actions are disabled once add mode is entered
- check the action column is always available on the main page
Clean up / general updates:
- replace the /api/v1/** catch-all intercept with per-endpoint intercepts so @get-rules waits resolve reliably
- remove now-redundant cy.wait("@get-rules") calls
- drop unused mount / dayjs / dates imports
- ensure expected strings match UI where strings have changed
Assisted-by: Claude Opus 4.7 (Anthropic)
AI used to draft enhancements tests. Changes were reviewed, tweaked, and commited manually and gradually (with a pre-submission commit squash). Tests were run multiple times and adjusted iteratively to match code changes, cover regressions as those were found, and handle vue page load.
Sponsored-by: Glasgow Colleges Library Group <https://library.cityofglasgowcollege.ac.uk>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
This commit is contained in:
parent
d6f596c514
commit
763dc46e31
|
|
@ -1,13 +1,3 @@
|
|||
import { mount } from "@cypress/vue";
|
||||
const dayjs = require("dayjs");
|
||||
|
||||
const dates = {
|
||||
today_iso: dayjs().format("YYYY-MM-DD"),
|
||||
today_us: dayjs().format("MM/DD/YYYY"),
|
||||
tomorrow_iso: dayjs().add(1, "day").format("YYYY-MM-DD"),
|
||||
tomorrow_us: dayjs().add(1, "day").format("MM/DD/YYYY"),
|
||||
};
|
||||
|
||||
// Generates a rule set in the format the API actually returns:
|
||||
// { context: { library_id, patron_category_id, item_type_id }, overdue_N_delay, ... }
|
||||
const getMockRuleSet = (
|
||||
|
|
@ -190,7 +180,6 @@ describe("Circulation Triggers - Initial Load", () => {
|
|||
|
||||
it("Should display trigger tabs when rules exist", () => {
|
||||
cy.visit("/cgi-bin/koha/admin/circulation_triggers");
|
||||
cy.wait("@get-rules");
|
||||
|
||||
cy.get("#circ-triggers-tabs").should("exist");
|
||||
cy.get(".nav-link").contains("Trigger 1").should("exist");
|
||||
|
|
@ -208,6 +197,23 @@ describe("Circulation Triggers - Initial Load", () => {
|
|||
// Component should still render without crashing
|
||||
cy.get("h1").should("contain", "Circulation triggers");
|
||||
});
|
||||
|
||||
// regression check (mtt stopped reliably displaying fallback status)
|
||||
it("Should render MTT cells with the fallback class when no explicit mtt rule exists", () => {
|
||||
// mtt is one DB column shared by email/print/sms, so the three are
|
||||
// atomic — you can't set sms while inheriting print/email. When no
|
||||
// rule set provides an mtt value, all three cells render .fallback
|
||||
// (bold italics) to signal inheritance.
|
||||
cy.visit("/cgi-bin/koha/admin/circulation_triggers");
|
||||
|
||||
cy.get("#trigger-table-main tbody tr")
|
||||
.first()
|
||||
.within(() => {
|
||||
cy.get("td").eq(5).find("span.fallback").should("exist");
|
||||
cy.get("td").eq(6).find("span.fallback").should("exist");
|
||||
cy.get("td").eq(7).find("span.fallback").should("exist");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("Circulation Triggers - No default rules warning", () => {
|
||||
|
|
@ -258,7 +264,6 @@ describe("Circulation Triggers - No default rules warning", () => {
|
|||
}).as("get-rules");
|
||||
|
||||
cy.visit("/cgi-bin/koha/admin/circulation_triggers");
|
||||
cy.wait("@get-rules");
|
||||
|
||||
cy.get(".alert-warning").should(
|
||||
"contain",
|
||||
|
|
@ -279,7 +284,6 @@ describe("Circulation Triggers - No default rules warning", () => {
|
|||
}).as("get-rules");
|
||||
|
||||
cy.visit("/cgi-bin/koha/admin/circulation_triggers");
|
||||
cy.wait("@get-rules");
|
||||
|
||||
cy.get(".alert-warning").should(
|
||||
"contain",
|
||||
|
|
@ -299,7 +303,7 @@ describe("Circulation Triggers - No default rules warning", () => {
|
|||
}).as("get-rules");
|
||||
|
||||
cy.visit("/cgi-bin/koha/admin/circulation_triggers");
|
||||
cy.wait("@get-rules");
|
||||
cy.get("#circ-triggers-tabs").should("exist");
|
||||
|
||||
cy.get(".alert-warning").should("not.exist");
|
||||
});
|
||||
|
|
@ -329,7 +333,6 @@ describe("Circulation Triggers - No default rules warning", () => {
|
|||
}).as("get-rules");
|
||||
|
||||
cy.visit("/cgi-bin/koha/admin/circulation_triggers");
|
||||
cy.wait("@get-rules");
|
||||
|
||||
cy.get(".alert-warning").contains("Centerville").click();
|
||||
|
||||
|
|
@ -380,7 +383,6 @@ describe("Circulation Triggers - Filtering", () => {
|
|||
|
||||
it("Should filter by library", () => {
|
||||
cy.visit("/cgi-bin/koha/admin/circulation_triggers");
|
||||
cy.wait("@get-rules");
|
||||
|
||||
cy.get("#library_select .vs__search").type("Centerville{enter}", {
|
||||
force: true,
|
||||
|
|
@ -393,7 +395,6 @@ describe("Circulation Triggers - Filtering", () => {
|
|||
|
||||
it("Should filter by patron category", () => {
|
||||
cy.visit("/cgi-bin/koha/admin/circulation_triggers");
|
||||
cy.wait("@get-rules");
|
||||
|
||||
cy.get("#patron_category_select .vs__search").type("Patron{enter}", {
|
||||
force: true,
|
||||
|
|
@ -406,7 +407,6 @@ describe("Circulation Triggers - Filtering", () => {
|
|||
|
||||
it("Should filter by item type", () => {
|
||||
cy.visit("/cgi-bin/koha/admin/circulation_triggers");
|
||||
cy.wait("@get-rules");
|
||||
|
||||
cy.get("#item_type_select .vs__search").type("Books{enter}", {
|
||||
force: true,
|
||||
|
|
@ -416,7 +416,6 @@ describe("Circulation Triggers - Filtering", () => {
|
|||
|
||||
it("Should toggle between explicit and all applicable rules", () => {
|
||||
cy.visit("/cgi-bin/koha/admin/circulation_triggers");
|
||||
cy.wait("@get-rules");
|
||||
|
||||
cy.get("#filter-rules").should("exist");
|
||||
|
||||
|
|
@ -432,7 +431,15 @@ describe("Circulation Triggers - Tab Navigation", () => {
|
|||
cy.login();
|
||||
cy.title().should("eq", "Koha staff interface");
|
||||
|
||||
cy.intercept("GET", "/api/v1/**", {
|
||||
cy.intercept("GET", "/api/v1/libraries*", {
|
||||
statusCode: 200,
|
||||
body: [],
|
||||
});
|
||||
cy.intercept("GET", "/api/v1/patron_categories*", {
|
||||
statusCode: 200,
|
||||
body: [],
|
||||
});
|
||||
cy.intercept("GET", "/api/v1/item_types*", {
|
||||
statusCode: 200,
|
||||
body: [],
|
||||
});
|
||||
|
|
@ -453,7 +460,6 @@ describe("Circulation Triggers - Tab Navigation", () => {
|
|||
|
||||
it("Should switch between trigger tabs", () => {
|
||||
cy.visit("/cgi-bin/koha/admin/circulation_triggers");
|
||||
cy.wait("@get-rules");
|
||||
|
||||
cy.get(".nav-link")
|
||||
.contains("Trigger 1")
|
||||
|
|
@ -505,7 +511,6 @@ describe("Circulation Triggers - Add New Trigger", () => {
|
|||
|
||||
it("Should open add trigger modal", () => {
|
||||
cy.visit("/cgi-bin/koha/admin/circulation_triggers");
|
||||
|
||||
cy.get(".modal-dialog").should("not.exist");
|
||||
cy.contains("Add new trigger").click();
|
||||
|
||||
|
|
@ -528,12 +533,8 @@ describe("Circulation Triggers - Add New Trigger", () => {
|
|||
it("Should show trigger number 1 when adding first trigger for a library with no existing rules", () => {
|
||||
// Regression test for bug where triggerNumber was NaN when no rules
|
||||
// existed for a library (triggerCounts[library_id] was undefined).
|
||||
cy.intercept("GET", "/api/v1/circulation_rules*", {
|
||||
statusCode: 200,
|
||||
body: [],
|
||||
headers: { "X-Base-Total-Count": "0", "X-Total-Count": "0" },
|
||||
});
|
||||
|
||||
// The default beforeEach intercept returns only a */*/* rule, so CPL
|
||||
// has no library-specific rules — exact regression case.
|
||||
cy.visit("/cgi-bin/koha/admin/circulation_triggers");
|
||||
cy.contains("Add new trigger").click();
|
||||
|
||||
|
|
@ -548,13 +549,102 @@ describe("Circulation Triggers - Add New Trigger", () => {
|
|||
});
|
||||
cy.contains("Confirm context").click();
|
||||
|
||||
cy.get("#trigger-table-form td.actions button").contains("Add").click();
|
||||
|
||||
// trigger number should be 1, not NaN
|
||||
cy.get("legend").should("contain", "Add new trigger 1");
|
||||
cy.get("#overdue_delay").should("exist");
|
||||
cy.get("#overdue_delay").should("not.have.attr", "name", /NaN/);
|
||||
});
|
||||
|
||||
it("Should allow canceling add operation", () => {
|
||||
it("Should show enabled row actions in the trigger table at the selectOrAdd step", () => {
|
||||
cy.visit("/cgi-bin/koha/admin/circulation_triggers");
|
||||
cy.contains("Add new trigger").click();
|
||||
|
||||
cy.get("#library_id .vs__search").type("Centerville{enter}", {
|
||||
force: true,
|
||||
});
|
||||
cy.get("#patron_category_id .vs__search").type("Patron{enter}", {
|
||||
force: true,
|
||||
});
|
||||
cy.get("#item_type_id .vs__search").type("Books{enter}", {
|
||||
force: true,
|
||||
});
|
||||
cy.contains("Confirm context").click();
|
||||
|
||||
cy.get("#trigger-table-form td.actions").should("exist");
|
||||
cy.get("#trigger-table-form td.actions button").should("exist");
|
||||
cy.get("#trigger-table-form td.actions button[disabled]").should(
|
||||
"not.exist"
|
||||
);
|
||||
});
|
||||
|
||||
it("Should disable row actions once add mode is entered from the trigger table", () => {
|
||||
cy.visit("/cgi-bin/koha/admin/circulation_triggers");
|
||||
cy.contains("Add new trigger").click();
|
||||
|
||||
cy.get("#library_id .vs__search").type("Centerville{enter}", {
|
||||
force: true,
|
||||
});
|
||||
cy.get("#patron_category_id .vs__search").type("Patron{enter}", {
|
||||
force: true,
|
||||
});
|
||||
cy.get("#item_type_id .vs__search").type("Books{enter}", {
|
||||
force: true,
|
||||
});
|
||||
cy.contains("Confirm context").click();
|
||||
|
||||
cy.get("#trigger-table-form td.actions button").contains("Add").click();
|
||||
|
||||
cy.get("#trigger-table-form td.actions button[disabled]").should(
|
||||
"exist"
|
||||
);
|
||||
cy.get("#trigger-table-form td.actions button:not([disabled])").should(
|
||||
"not.exist"
|
||||
);
|
||||
});
|
||||
|
||||
it("Should mark non-active steps with bg-success-subtle in the add flow", () => {
|
||||
cy.visit("/cgi-bin/koha/admin/circulation_triggers");
|
||||
cy.contains("Add new trigger").click();
|
||||
|
||||
cy.get("#library_id .vs__search").type("Centerville{enter}", {
|
||||
force: true,
|
||||
});
|
||||
cy.get("#patron_category_id .vs__search").type("Patron{enter}", {
|
||||
force: true,
|
||||
});
|
||||
cy.get("#item_type_id .vs__search").type("Books{enter}", {
|
||||
force: true,
|
||||
});
|
||||
cy.contains("Confirm context").click();
|
||||
|
||||
// At selectOrAdd: the prior ConfirmContext step is highlighted,
|
||||
// but the active TriggersTable section is not.
|
||||
cy.contains("legend", "Selected trigger context")
|
||||
.parents(".page-section")
|
||||
.first()
|
||||
.should("have.class", "bg-success-subtle");
|
||||
cy.get("#trigger-table-form")
|
||||
.parents(".page-section")
|
||||
.first()
|
||||
.should("not.have.class", "bg-success-subtle");
|
||||
|
||||
// Enter add mode: now both prior steps should be highlighted.
|
||||
cy.get("#trigger-table-form td.actions button").contains("Add").click();
|
||||
cy.get("#trigger-table-form")
|
||||
.parents(".page-section")
|
||||
.first()
|
||||
.should("have.class", "bg-success-subtle");
|
||||
});
|
||||
|
||||
it("Should show row actions in the trigger table on the main list", () => {
|
||||
cy.visit("/cgi-bin/koha/admin/circulation_triggers");
|
||||
|
||||
cy.get("#trigger-table-main td.actions").should("exist");
|
||||
});
|
||||
|
||||
it("Should allow cancelling add operation", () => {
|
||||
cy.visit("/cgi-bin/koha/admin/circulation_triggers");
|
||||
cy.contains("Add new trigger").click();
|
||||
|
||||
|
|
@ -572,7 +662,15 @@ describe("Circulation Triggers - Delete Trigger", () => {
|
|||
cy.login();
|
||||
cy.title().should("eq", "Koha staff interface");
|
||||
|
||||
cy.intercept("GET", "/api/v1/**", {
|
||||
cy.intercept("GET", "/api/v1/libraries*", {
|
||||
statusCode: 200,
|
||||
body: [],
|
||||
});
|
||||
cy.intercept("GET", "/api/v1/patron_categories*", {
|
||||
statusCode: 200,
|
||||
body: [],
|
||||
});
|
||||
cy.intercept("GET", "/api/v1/item_types*", {
|
||||
statusCode: 200,
|
||||
body: [],
|
||||
});
|
||||
|
|
@ -593,7 +691,6 @@ describe("Circulation Triggers - Delete Trigger", () => {
|
|||
|
||||
it("Should only show delete button for last trigger tab", () => {
|
||||
cy.visit("/cgi-bin/koha/admin/circulation_triggers");
|
||||
cy.wait("@get-rules");
|
||||
|
||||
cy.get(".nav-link").contains("Trigger 3").click();
|
||||
cy.contains("Delete").should("exist");
|
||||
|
|
@ -604,19 +701,20 @@ describe("Circulation Triggers - Delete Trigger", () => {
|
|||
|
||||
it("Should show confirmation dialog for delete", () => {
|
||||
cy.visit("/cgi-bin/koha/admin/circulation_triggers");
|
||||
cy.wait("@get-rules");
|
||||
|
||||
cy.get(".nav-link").contains("Trigger 3").click();
|
||||
cy.contains("Delete").click();
|
||||
|
||||
cy.get(".modal-dialog").should("be.visible");
|
||||
cy.get(".modal-title").should("contain", "Delete");
|
||||
cy.get(".modal-body").should("contain", "3");
|
||||
cy.get(".modal-title").should(
|
||||
"contain",
|
||||
"Confirm deletion of Trigger 3"
|
||||
);
|
||||
cy.get(".modal-body").should("contain", "Rule sets to be deleted");
|
||||
});
|
||||
|
||||
it("Should allow canceling delete operation", () => {
|
||||
cy.visit("/cgi-bin/koha/admin/circulation_triggers");
|
||||
cy.wait("@get-rules");
|
||||
|
||||
cy.get(".nav-link").contains("Trigger 3").click();
|
||||
cy.contains("Delete").click();
|
||||
|
|
@ -632,12 +730,155 @@ describe("Circulation Triggers - Delete Trigger", () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe("Circulation Triggers - Delete Trigger Disabled States", () => {
|
||||
beforeEach(() => {
|
||||
cy.login();
|
||||
cy.title().should("eq", "Koha staff interface");
|
||||
|
||||
cy.intercept("GET", "/api/v1/libraries*", {
|
||||
statusCode: 200,
|
||||
body: getMockLibraries(),
|
||||
});
|
||||
cy.intercept("GET", "/api/v1/patron_categories*", {
|
||||
statusCode: 200,
|
||||
body: getMockPatronCategories(),
|
||||
});
|
||||
cy.intercept("GET", "/api/v1/item_types*", {
|
||||
statusCode: 200,
|
||||
body: getMockItemTypes(),
|
||||
});
|
||||
});
|
||||
|
||||
// this is because we always delete a trigger for a library
|
||||
// where a trigger is all the rulesets for the triggerNumber for the library
|
||||
// this mirrors the create trigger pattern, which is also per library per triggerNumber
|
||||
it("Should disable Delete with tooltip when a patron category filter is set", () => {
|
||||
cy.intercept("GET", "/api/v1/circulation_rules*", {
|
||||
statusCode: 200,
|
||||
body: [
|
||||
getMockRuleSet("*", "*", "*", 1),
|
||||
getMockRuleSet("*", "*", "*", 2),
|
||||
],
|
||||
headers: {
|
||||
"X-Base-Total-Count": "2",
|
||||
"X-Total-Count": "2",
|
||||
},
|
||||
}).as("get-rules");
|
||||
|
||||
cy.visit("/cgi-bin/koha/admin/circulation_triggers");
|
||||
|
||||
cy.get(".nav-link").contains("Trigger 2").click();
|
||||
cy.contains("Delete").should("not.have.attr", "disabled");
|
||||
|
||||
cy.get("#patron_category_select .vs__search").type("Patron{enter}", {
|
||||
force: true,
|
||||
});
|
||||
|
||||
cy.contains("Delete").should("have.attr", "disabled");
|
||||
cy.contains("Delete")
|
||||
.parent("span")
|
||||
.should(
|
||||
"have.attr",
|
||||
"title",
|
||||
"Delete is only available when no patron category or item type filter is set, as it removes all explicit rules for this trigger across the selected library."
|
||||
);
|
||||
});
|
||||
|
||||
it("Should disable Delete with tooltip when an item type filter is set", () => {
|
||||
cy.intercept("GET", "/api/v1/circulation_rules*", {
|
||||
statusCode: 200,
|
||||
body: [
|
||||
getMockRuleSet("*", "*", "*", 1),
|
||||
getMockRuleSet("*", "*", "*", 2),
|
||||
],
|
||||
headers: {
|
||||
"X-Base-Total-Count": "2",
|
||||
"X-Total-Count": "2",
|
||||
},
|
||||
}).as("get-rules");
|
||||
|
||||
cy.visit("/cgi-bin/koha/admin/circulation_triggers");
|
||||
|
||||
cy.get(".nav-link").contains("Trigger 2").click();
|
||||
cy.contains("Delete").should("not.have.attr", "disabled");
|
||||
|
||||
cy.get("#item_type_select .vs__search").type("Books{enter}", {
|
||||
force: true,
|
||||
});
|
||||
|
||||
cy.contains("Delete").should("have.attr", "disabled");
|
||||
cy.contains("Delete")
|
||||
.parent("span")
|
||||
.should(
|
||||
"have.attr",
|
||||
"title",
|
||||
"Delete is only available when no patron category or item type filter is set, as it removes all explicit rules for this trigger across the selected library."
|
||||
);
|
||||
});
|
||||
|
||||
it("Should disable Delete on default library when another library has higher triggers", () => {
|
||||
// Default library has triggers 1 and 2; CPL has triggers up to 3.
|
||||
// Deleting trigger 2 on the default library would orphan CPL trigger 3.
|
||||
// Since we do not allow breaks in trigger sequentiality, this should result in the button being disabled
|
||||
cy.intercept("GET", "/api/v1/circulation_rules*", req => {
|
||||
const url = new URL(req.url);
|
||||
if (url.searchParams.get("library_id") === "*") {
|
||||
req.reply({
|
||||
statusCode: 200,
|
||||
body: [
|
||||
getMockRuleSet("*", "*", "*", 1),
|
||||
getMockRuleSet("*", "*", "*", 2),
|
||||
],
|
||||
headers: {
|
||||
"X-Base-Total-Count": "2",
|
||||
"X-Total-Count": "2",
|
||||
},
|
||||
});
|
||||
} else {
|
||||
req.reply({
|
||||
statusCode: 200,
|
||||
body: [
|
||||
getMockRuleSet("*", "*", "*", 1),
|
||||
getMockRuleSet("*", "*", "*", 2),
|
||||
getMockRuleSet("CPL", "*", "*", 1),
|
||||
getMockRuleSet("CPL", "*", "*", 2),
|
||||
getMockRuleSet("CPL", "*", "*", 3),
|
||||
],
|
||||
headers: {
|
||||
"X-Base-Total-Count": "5",
|
||||
"X-Total-Count": "5",
|
||||
},
|
||||
});
|
||||
}
|
||||
}).as("get-rules");
|
||||
|
||||
cy.visit("/cgi-bin/koha/admin/circulation_triggers");
|
||||
|
||||
cy.get(".nav-link").contains("Trigger 2").click();
|
||||
|
||||
cy.contains("Delete").should("have.attr", "disabled");
|
||||
cy.contains("Delete")
|
||||
.parent("span")
|
||||
.should("have.attr", "title")
|
||||
.and("contain", "Centerville")
|
||||
.and("contain", "would be orphaned");
|
||||
});
|
||||
});
|
||||
|
||||
describe("Circulation Triggers - Reset Rule Set", () => {
|
||||
beforeEach(() => {
|
||||
cy.login();
|
||||
cy.title().should("eq", "Koha staff interface");
|
||||
|
||||
cy.intercept("GET", "/api/v1/**", {
|
||||
cy.intercept("GET", "/api/v1/libraries*", {
|
||||
statusCode: 200,
|
||||
body: [],
|
||||
});
|
||||
cy.intercept("GET", "/api/v1/patron_categories*", {
|
||||
statusCode: 200,
|
||||
body: [],
|
||||
});
|
||||
cy.intercept("GET", "/api/v1/item_types*", {
|
||||
statusCode: 200,
|
||||
body: [],
|
||||
});
|
||||
|
|
@ -658,14 +899,12 @@ describe("Circulation Triggers - Reset Rule Set", () => {
|
|||
|
||||
it("Should show Reset button for explicit rule sets in the table", () => {
|
||||
cy.visit("/cgi-bin/koha/admin/circulation_triggers");
|
||||
cy.wait("@get-rules");
|
||||
|
||||
cy.get("table").contains("Reset").should("exist");
|
||||
});
|
||||
|
||||
it("Should show confirmation dialog for reset", () => {
|
||||
cy.visit("/cgi-bin/koha/admin/circulation_triggers");
|
||||
cy.wait("@get-rules");
|
||||
|
||||
cy.get("table").contains("Reset").click();
|
||||
|
||||
|
|
@ -674,15 +913,11 @@ describe("Circulation Triggers - Reset Rule Set", () => {
|
|||
"contain",
|
||||
"Confirm circulation rule set reset"
|
||||
);
|
||||
cy.get(".modal-body").should(
|
||||
"contain",
|
||||
"Resetting this rule set for the chosen context"
|
||||
);
|
||||
cy.get(".modal-body").should("contain", "Rule set selected for reset");
|
||||
});
|
||||
|
||||
it("Should allow canceling reset operation", () => {
|
||||
cy.visit("/cgi-bin/koha/admin/circulation_triggers");
|
||||
cy.wait("@get-rules");
|
||||
|
||||
cy.get("table").contains("Reset").click();
|
||||
cy.get(".modal-dialog").should("be.visible");
|
||||
|
|
@ -697,7 +932,15 @@ describe("Circulation Triggers - Empty States", () => {
|
|||
cy.login();
|
||||
cy.title().should("eq", "Koha staff interface");
|
||||
|
||||
cy.intercept("GET", "/api/v1/**", {
|
||||
cy.intercept("GET", "/api/v1/libraries*", {
|
||||
statusCode: 200,
|
||||
body: [],
|
||||
});
|
||||
cy.intercept("GET", "/api/v1/patron_categories*", {
|
||||
statusCode: 200,
|
||||
body: [],
|
||||
});
|
||||
cy.intercept("GET", "/api/v1/item_types*", {
|
||||
statusCode: 200,
|
||||
body: [],
|
||||
});
|
||||
|
|
@ -709,7 +952,7 @@ describe("Circulation Triggers - Empty States", () => {
|
|||
"X-Base-Total-Count": "0",
|
||||
"X-Total-Count": "0",
|
||||
},
|
||||
});
|
||||
}).as("get-rules");
|
||||
});
|
||||
|
||||
it("Should render without crashing when no rules exist", () => {
|
||||
|
|
@ -762,7 +1005,6 @@ describe("Circulation Triggers - Complex Scenarios", () => {
|
|||
|
||||
it("Should show all three trigger tabs for default library", () => {
|
||||
cy.visit("/cgi-bin/koha/admin/circulation_triggers");
|
||||
cy.wait("@get-rules");
|
||||
|
||||
cy.get(".nav-link").contains("Trigger 1").should("exist");
|
||||
cy.get(".nav-link").contains("Trigger 2").should("exist");
|
||||
|
|
@ -771,7 +1013,6 @@ describe("Circulation Triggers - Complex Scenarios", () => {
|
|||
|
||||
it("Should handle rapid tab switching without errors", () => {
|
||||
cy.visit("/cgi-bin/koha/admin/circulation_triggers");
|
||||
cy.wait("@get-rules");
|
||||
|
||||
cy.get(".nav-link").contains("Trigger 2").click();
|
||||
cy.get(".nav-link").contains("Trigger 1").click();
|
||||
|
|
@ -787,7 +1028,15 @@ describe("Circulation Triggers - Browser Navigation", () => {
|
|||
cy.login();
|
||||
cy.title().should("eq", "Koha staff interface");
|
||||
|
||||
cy.intercept("GET", "/api/v1/**", {
|
||||
cy.intercept("GET", "/api/v1/libraries*", {
|
||||
statusCode: 200,
|
||||
body: [],
|
||||
});
|
||||
cy.intercept("GET", "/api/v1/patron_categories*", {
|
||||
statusCode: 200,
|
||||
body: [],
|
||||
});
|
||||
cy.intercept("GET", "/api/v1/item_types*", {
|
||||
statusCode: 200,
|
||||
body: [],
|
||||
});
|
||||
|
|
@ -799,7 +1048,7 @@ describe("Circulation Triggers - Browser Navigation", () => {
|
|||
"X-Base-Total-Count": "1",
|
||||
"X-Total-Count": "1",
|
||||
},
|
||||
});
|
||||
}).as("get-rules");
|
||||
});
|
||||
|
||||
it("Should close modal on browser back button", () => {
|
||||
|
|
@ -822,3 +1071,21 @@ describe("Circulation Triggers - Browser Navigation", () => {
|
|||
cy.get(".modal-dialog").should("be.visible");
|
||||
});
|
||||
});
|
||||
|
||||
describe("Circulation Triggers - Permissions", () => {
|
||||
beforeEach(() => {
|
||||
cy.login();
|
||||
cy.title().should("eq", "Koha staff interface");
|
||||
});
|
||||
|
||||
it("Should redirect to admin home when config returns no valid permissions", () => {
|
||||
cy.intercept("GET", "/api/v1/circulation_rules/config*", {
|
||||
statusCode: 403,
|
||||
}).as("get-config");
|
||||
|
||||
cy.visit("/cgi-bin/koha/admin/circulation_triggers");
|
||||
cy.wait("@get-config");
|
||||
|
||||
cy.url().should("include", "admin-home");
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in New Issue