Bug 40180: (bug 40118 follow-up) Add Cypress tests
This patch heavily reuses what has been introduced by the previous
patches in the tree, and add a insertSampleHold task to be reusable
easily in other tests.
Test plan:
All Cypress tests must pass
Signed-off-by: Owen Leonard <oleonard@myacpl.org>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit af311b5395)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
This commit is contained in:
parent
604ede20d9
commit
f66133bcd5
|
|
@ -24,7 +24,7 @@ describe("catalogue/detail/holdings_table with items", () => {
|
|||
});
|
||||
|
||||
afterEach(function () {
|
||||
cy.task("deleteSampleObjects", this.objects);
|
||||
cy.task("deleteSampleObjects", [this.objects]);
|
||||
cy.set_syspref(
|
||||
"AlwaysShowHoldingsTableFilters",
|
||||
this.syspref_AlwaysShowHoldingsTableFilters
|
||||
|
|
@ -279,7 +279,7 @@ describe("catalogue/detail/holdings_table without items", () => {
|
|||
});
|
||||
|
||||
afterEach(function () {
|
||||
cy.task("deleteSampleObjects", this.objects);
|
||||
cy.task("deleteSampleObjects", [this.objects]);
|
||||
cy.set_syspref(
|
||||
"AlwaysShowHoldingsTableFilters",
|
||||
this.syspref_AlwaysShowHoldingsTableFilters
|
||||
|
|
|
|||
|
|
@ -0,0 +1,101 @@
|
|||
describe("circ/pendingreserves/holdst", () => {
|
||||
const table_id = "holdst";
|
||||
beforeEach(() => {
|
||||
cy.login();
|
||||
cy.title().should("eq", "Koha staff interface");
|
||||
cy.task("insertSampleBiblio", {
|
||||
item_count: 2,
|
||||
options: { different_libraries: true },
|
||||
}).then(objects_biblio_1 => {
|
||||
cy.wrap(objects_biblio_1).as("objects_biblio_1");
|
||||
const commonLibraryId = objects_biblio_1.items[0].home_library_id;
|
||||
cy.task("insertSampleHold", {
|
||||
biblio: objects_biblio_1.biblio,
|
||||
library_id: commonLibraryId,
|
||||
}).then(objects_hold_1 => {
|
||||
cy.wrap(objects_hold_1).as("objects_hold_1");
|
||||
});
|
||||
cy.task("insertSampleBiblio", { item_count: 1 }).then(
|
||||
objects_biblio_2 => {
|
||||
cy.wrap(objects_biblio_2).as("objects_biblio_2");
|
||||
cy.task("insertSampleHold", {
|
||||
biblio: objects_biblio_2.biblio,
|
||||
library_id: objects_biblio_2.items[0].home_library_id,
|
||||
}).then(objects_hold_2 => {
|
||||
cy.wrap(objects_hold_2).as("objects_hold_2");
|
||||
});
|
||||
cy.task("query", {
|
||||
sql: "UPDATE items SET homebranch=?, holdingbranch=? WHERE itemnumber=?",
|
||||
values: [
|
||||
commonLibraryId,
|
||||
commonLibraryId,
|
||||
objects_biblio_2.items[0].item_id,
|
||||
],
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
cy.task("deleteSampleObjects", [
|
||||
this.objects_hold_1,
|
||||
this.objects_hold_2,
|
||||
this.objects_biblio_1,
|
||||
this.objects_biblio_2,
|
||||
]);
|
||||
});
|
||||
|
||||
it("Should render library filters", function () {
|
||||
cy.visit(
|
||||
"/cgi-bin/koha/circ/pendingreserves.pl?from=2000-01-01&to=2999-12-31&run_report=Submit"
|
||||
);
|
||||
|
||||
cy.get(`#${table_id} thead tr:eq(1) th:eq(5)`).should(
|
||||
"have.text",
|
||||
"Libraries"
|
||||
);
|
||||
|
||||
// select has library names in value and text, this table is not using server-side processing
|
||||
let libraries = this.objects_biblio_1.libraries
|
||||
.map(library => library.name)
|
||||
.sort();
|
||||
cy.get(`#${table_id} thead tr:eq(1) th:eq(5) select`)
|
||||
.children()
|
||||
.should("have.length", 3)
|
||||
.then(options => {
|
||||
expect(options.eq(0).val()).to.eq("");
|
||||
expect(options.eq(1).val()).to.eq(libraries[0]);
|
||||
expect(options.eq(2).val()).to.eq(libraries[1]);
|
||||
});
|
||||
});
|
||||
|
||||
it("Should filter table on library", function () {
|
||||
cy.visit(
|
||||
"/cgi-bin/koha/circ/pendingreserves.pl?from=2000-01-01&to=2999-12-31&run_report=Submit"
|
||||
);
|
||||
|
||||
cy.get(`#${table_id} thead tr:eq(1) th:eq(5) select`).select(
|
||||
this.objects_biblio_1.libraries[0].name,
|
||||
{ force: true }
|
||||
);
|
||||
cy.get(`#${table_id} tbody tr:eq(0) td:eq(4)`).should(
|
||||
"contain",
|
||||
this.objects_biblio_1.biblio.title
|
||||
);
|
||||
cy.get(`#${table_id} tbody tr:eq(1) td:eq(4)`).should(
|
||||
"contain",
|
||||
this.objects_biblio_2.biblio.title
|
||||
);
|
||||
cy.get(`#${table_id} tbody tr`).should("have.length", 2);
|
||||
|
||||
cy.get(`#${table_id} thead tr:eq(1) th:eq(5) select`).select(
|
||||
this.objects_biblio_1.libraries[1].name
|
||||
);
|
||||
cy.get(`#${table_id} tbody tr:eq(0) td:eq(4)`).should(
|
||||
"contain",
|
||||
this.objects_biblio_1.biblio.title
|
||||
);
|
||||
cy.get(`#${table_id} tbody tr`).should("have.length", 1);
|
||||
});
|
||||
});
|
||||
|
|
@ -1,11 +1,13 @@
|
|||
const { query } = require("./../../plugins/db.js");
|
||||
|
||||
describe("insertSampleBiblio", () => {
|
||||
it("should generate library and item type", () => {
|
||||
it("insertSampleBiblio - should generate library and item type", () => {
|
||||
cy.task("insertSampleBiblio", { item_count: 3 }).then(objects => {
|
||||
const biblio_id = objects.biblio.biblio_id;
|
||||
expect(typeof objects.biblio.biblio_id).to.be.equal("number");
|
||||
expect(typeof objects.biblio.title).to.be.equal("string");
|
||||
expect(typeof objects.biblio.author).to.be.equal("string");
|
||||
|
||||
expect(typeof biblio_id).to.be.equal("number");
|
||||
const biblio_id = objects.biblio.biblio_id;
|
||||
|
||||
cy.task("query", {
|
||||
sql: "SELECT COUNT(*) as count FROM biblio WHERE biblionumber=?",
|
||||
|
|
@ -30,7 +32,7 @@ describe("insertSampleBiblio", () => {
|
|||
|
||||
cy.task("query", {
|
||||
sql: "SELECT COUNT(*) as count FROM branches WHERE branchcode=?",
|
||||
values: [objects.library.library_id],
|
||||
values: [objects.libraries[0].library_id],
|
||||
}).then(result => {
|
||||
expect(result[0].count).to.be.equal(1);
|
||||
});
|
||||
|
|
@ -60,7 +62,7 @@ describe("insertSampleBiblio", () => {
|
|||
|
||||
cy.task("query", {
|
||||
sql: "SELECT COUNT(*) as count FROM branches WHERE branchcode=?",
|
||||
values: [objects.library.library_id],
|
||||
values: [objects.libraries[0].library_id],
|
||||
}).then(result => {
|
||||
expect(result[0].count).to.be.equal(0);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ const { buildSampleObject, buildSampleObjects } = require("./mockData.js");
|
|||
|
||||
const {
|
||||
insertSampleBiblio,
|
||||
insertSampleHold,
|
||||
insertObject,
|
||||
deleteSampleObjects,
|
||||
} = require("./insertData.js");
|
||||
|
|
@ -36,11 +37,14 @@ module.exports = (on, config) => {
|
|||
},
|
||||
buildSampleObject,
|
||||
buildSampleObjects,
|
||||
insertSampleBiblio({ item_count }) {
|
||||
return insertSampleBiblio(item_count, baseUrl, authHeader);
|
||||
insertSampleBiblio(args) {
|
||||
return insertSampleBiblio({ ...args, baseUrl, authHeader });
|
||||
},
|
||||
insertObject({ type, object }) {
|
||||
return insertObject(type, object, baseUrl, authHeader);
|
||||
insertSampleHold(args) {
|
||||
return insertSampleHold({ ...args, baseUrl, authHeader });
|
||||
},
|
||||
insertObject(args) {
|
||||
return insertObject({ ...args, baseUrl, authHeader });
|
||||
},
|
||||
deleteSampleObjects,
|
||||
query,
|
||||
|
|
|
|||
|
|
@ -3,27 +3,22 @@ const { query } = require("./db.js");
|
|||
|
||||
const { apiGet, apiPost } = require("./api-client.js");
|
||||
|
||||
const insertSampleBiblio = async (item_count, baseUrl, authHeader) => {
|
||||
let generated_objects = {};
|
||||
const objects = [{ object: "library" }, { object: "item_type" }];
|
||||
for (const { object } of objects) {
|
||||
const attributes = await buildSampleObject({ object });
|
||||
generated_objects[object] = attributes;
|
||||
}
|
||||
|
||||
const library = await insertObject(
|
||||
"library",
|
||||
generated_objects["library"],
|
||||
const insertSampleBiblio = async ({
|
||||
item_count,
|
||||
options,
|
||||
baseUrl,
|
||||
authHeader,
|
||||
}) => {
|
||||
const generatedItemType = await buildSampleObject({ object: "item_type" });
|
||||
const item_type = await insertObject({
|
||||
type: "item_type",
|
||||
object: generatedItemType,
|
||||
baseUrl,
|
||||
authHeader
|
||||
);
|
||||
const item_type = await insertObject(
|
||||
"item_type",
|
||||
generated_objects["item_type"],
|
||||
baseUrl,
|
||||
authHeader
|
||||
);
|
||||
authHeader,
|
||||
});
|
||||
|
||||
let title = "Some boring read";
|
||||
let author = "Some boring author";
|
||||
let biblio = {
|
||||
leader: " nam a22 7a 4500",
|
||||
fields: [
|
||||
|
|
@ -32,14 +27,14 @@ const insertSampleBiblio = async (item_count, baseUrl, authHeader) => {
|
|||
245: {
|
||||
ind1: "",
|
||||
ind2: "",
|
||||
subfields: [{ a: "Some boring read" }],
|
||||
subfields: [{ a: title }],
|
||||
},
|
||||
},
|
||||
{
|
||||
100: {
|
||||
ind1: "",
|
||||
ind2: "",
|
||||
subfields: [{ c: "Some boring author" }],
|
||||
subfields: [{ c: author }],
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -66,6 +61,8 @@ const insertSampleBiblio = async (item_count, baseUrl, authHeader) => {
|
|||
// We might need to refine that in the future
|
||||
biblio = {
|
||||
biblio_id,
|
||||
title,
|
||||
author,
|
||||
};
|
||||
|
||||
let items = buildSampleObjects({
|
||||
|
|
@ -80,9 +77,8 @@ const insertSampleBiblio = async (item_count, baseUrl, authHeader) => {
|
|||
restricted_status: 0,
|
||||
new_status: null,
|
||||
issues: 0,
|
||||
checked_out_date: null,
|
||||
item_type_id: item_type.item_type_id,
|
||||
home_library_id: library.library_id,
|
||||
holding_library_id: library.library_id,
|
||||
},
|
||||
});
|
||||
items = items.map(
|
||||
|
|
@ -123,7 +119,37 @@ const insertSampleBiblio = async (item_count, baseUrl, authHeader) => {
|
|||
}) => rest
|
||||
);
|
||||
let createdItems = [];
|
||||
let libraries = [];
|
||||
let commonLibrary;
|
||||
if (!options || !options.different_libraries) {
|
||||
const generatedLibrary = await buildSampleObject({ object: "library" });
|
||||
commonLibrary = await insertObject({
|
||||
type: "library",
|
||||
object: generatedLibrary,
|
||||
baseUrl,
|
||||
authHeader,
|
||||
});
|
||||
libraries.push(commonLibrary);
|
||||
}
|
||||
for (const item of items) {
|
||||
if (options?.different_libraries) {
|
||||
const generatedLibrary = await buildSampleObject({
|
||||
object: "library",
|
||||
});
|
||||
const library = await insertObject({
|
||||
type: "library",
|
||||
object: generatedLibrary,
|
||||
baseUrl,
|
||||
authHeader,
|
||||
});
|
||||
libraries.push(library);
|
||||
item.home_library_id = library.library_id;
|
||||
item.holding_library_id = library.library_id;
|
||||
} else {
|
||||
item.home_library_id = commonLibrary.library_id;
|
||||
item.holding_library_id = commonLibrary.library_id;
|
||||
}
|
||||
|
||||
await apiPost({
|
||||
endpoint: `/api/v1/biblios/${biblio_id}/items`,
|
||||
body: item,
|
||||
|
|
@ -131,51 +157,128 @@ const insertSampleBiblio = async (item_count, baseUrl, authHeader) => {
|
|||
authHeader,
|
||||
}).then(i => createdItems.push(i));
|
||||
}
|
||||
return { biblio, items: createdItems, library, item_type };
|
||||
return { biblio, items: createdItems, libraries, item_type };
|
||||
};
|
||||
|
||||
const deleteSampleObjects = async objects => {
|
||||
const deletionOrder = ["items", "biblio", "library", "item_type"];
|
||||
const insertSampleHold = async ({
|
||||
item,
|
||||
biblio,
|
||||
library_id,
|
||||
baseUrl,
|
||||
authHeader,
|
||||
}) => {
|
||||
library_id ||= item.home_library_id;
|
||||
const generatedPatron = await buildSampleObject({
|
||||
object: "patron",
|
||||
values: { library_id, incorrect_address: null, patron_card_lost: null },
|
||||
});
|
||||
|
||||
const patron = await insertObject({
|
||||
type: "patron",
|
||||
object: generatedPatron,
|
||||
baseUrl,
|
||||
authHeader,
|
||||
});
|
||||
|
||||
const generatedHold = buildSampleObject({
|
||||
object: "hold",
|
||||
values: {
|
||||
patron_id: patron.patron_id,
|
||||
biblio_id: item?.biblio_id || biblio.biblio_id,
|
||||
pickup_library_id: library_id,
|
||||
item_id: item?.item_id || null,
|
||||
},
|
||||
});
|
||||
const hold = await insertObject({
|
||||
type: "hold",
|
||||
object: generatedHold,
|
||||
baseUrl,
|
||||
authHeader,
|
||||
});
|
||||
return { hold, patron };
|
||||
};
|
||||
|
||||
const deleteSampleObjects = async allObjects => {
|
||||
if (!Array.isArray(allObjects)) {
|
||||
allObjects = [allObjects];
|
||||
}
|
||||
|
||||
const deletionOrder = [
|
||||
"hold",
|
||||
"patron",
|
||||
"item",
|
||||
"items",
|
||||
"biblio",
|
||||
"library",
|
||||
"libraries",
|
||||
"item_type",
|
||||
];
|
||||
|
||||
for (const type of deletionOrder) {
|
||||
if (!objects.hasOwnProperty(type)) {
|
||||
continue;
|
||||
}
|
||||
if (Array.isArray(objects[type]) && objects[type].length == 0) {
|
||||
// Empty array
|
||||
continue;
|
||||
}
|
||||
switch (type) {
|
||||
case "biblio":
|
||||
await query({
|
||||
sql: "DELETE FROM biblio WHERE biblionumber=?",
|
||||
values: [objects[type].biblio_id],
|
||||
});
|
||||
break;
|
||||
case "items":
|
||||
let item_ids = objects[type].map(i => i.item_id);
|
||||
await query({
|
||||
sql: `DELETE FROM items WHERE itemnumber IN (${item_ids.map(() => "?").join(",")})`,
|
||||
values: item_ids,
|
||||
});
|
||||
break;
|
||||
case "item":
|
||||
await query({
|
||||
sql: "DELETE FROM items WHERE itemnumber = ?",
|
||||
values: [objects[type].item_id],
|
||||
});
|
||||
break;
|
||||
case "library":
|
||||
await query({
|
||||
sql: "DELETE FROM branches WHERE branchcode = ?",
|
||||
values: [objects[type].library_id],
|
||||
});
|
||||
break;
|
||||
case "item_type":
|
||||
await query({
|
||||
sql: "DELETE FROM itemtypes WHERE itemtype = ?",
|
||||
values: [objects[type].item_type_id],
|
||||
});
|
||||
break;
|
||||
for (const objects of allObjects) {
|
||||
if (!objects.hasOwnProperty(type)) {
|
||||
continue;
|
||||
}
|
||||
if (Array.isArray(objects[type]) && objects[type].length == 0) {
|
||||
// Empty array
|
||||
continue;
|
||||
}
|
||||
switch (type) {
|
||||
case "biblio":
|
||||
await query({
|
||||
sql: "DELETE FROM biblio WHERE biblionumber=?",
|
||||
values: [objects[type].biblio_id],
|
||||
});
|
||||
break;
|
||||
case "items":
|
||||
let item_ids = objects[type].map(i => i.item_id);
|
||||
await query({
|
||||
sql: `DELETE FROM items WHERE itemnumber IN (${item_ids.map(() => "?").join(",")})`,
|
||||
values: item_ids,
|
||||
});
|
||||
break;
|
||||
case "item":
|
||||
await query({
|
||||
sql: "DELETE FROM items WHERE itemnumber = ?",
|
||||
values: [objects[type].item_id],
|
||||
});
|
||||
break;
|
||||
case "library":
|
||||
await query({
|
||||
sql: "DELETE FROM branches WHERE branchcode = ?",
|
||||
values: [objects[type].library_id],
|
||||
});
|
||||
break;
|
||||
case "libraries":
|
||||
let library_ids = objects[type].map(i => i.library_id);
|
||||
await query({
|
||||
sql: `DELETE FROM branches WHERE branchcode IN (${library_ids.map(() => "?").join(",")})`,
|
||||
values: library_ids,
|
||||
});
|
||||
break;
|
||||
case "hold":
|
||||
await query({
|
||||
sql: "DELETE FROM reserves WHERE reserve_id = ?",
|
||||
values: [objects[type].hold_id],
|
||||
});
|
||||
break;
|
||||
case "item_type":
|
||||
await query({
|
||||
sql: "DELETE FROM itemtypes WHERE itemtype = ?",
|
||||
values: [objects[type].item_type_id],
|
||||
});
|
||||
break;
|
||||
case "patron":
|
||||
await query({
|
||||
sql: "DELETE FROM borrowers WHERE borrowernumber = ?",
|
||||
values: [objects[type].patron_id],
|
||||
});
|
||||
break;
|
||||
default:
|
||||
console.log(
|
||||
`Not implemented yet: cannot deleted object '${type}'`
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
|
@ -199,7 +302,7 @@ const insertLibrary = async (library, baseUrl, authHeader) => {
|
|||
});
|
||||
};
|
||||
|
||||
const insertObject = async (type, object, baseUrl, authHeader) => {
|
||||
const insertObject = async ({ type, object, baseUrl, authHeader }) => {
|
||||
if (type == "patron") {
|
||||
await query({
|
||||
sql: "SELECT COUNT(*) AS count FROM branches WHERE branchcode = ?",
|
||||
|
|
@ -274,6 +377,41 @@ const insertObject = async (type, object, baseUrl, authHeader) => {
|
|||
});
|
||||
})
|
||||
.then(item_types => item_types[0]);
|
||||
} else if (type == "hold") {
|
||||
const {
|
||||
hold_id,
|
||||
deleted_biblio_id,
|
||||
item_group_id,
|
||||
desk_id,
|
||||
cancellation_date,
|
||||
cancellation_reason,
|
||||
notes,
|
||||
priority,
|
||||
status,
|
||||
timestamp,
|
||||
waiting_date,
|
||||
expiration_date,
|
||||
lowest_priority,
|
||||
suspended,
|
||||
suspended_until,
|
||||
non_priority,
|
||||
item_type,
|
||||
item_level,
|
||||
cancellation_requested,
|
||||
biblio,
|
||||
deleted_biblio,
|
||||
item,
|
||||
pickup_library,
|
||||
hold_date,
|
||||
...hold
|
||||
} = object;
|
||||
|
||||
return apiPost({
|
||||
endpoint: `/api/v1/holds`,
|
||||
body: hold,
|
||||
baseUrl,
|
||||
authHeader,
|
||||
});
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -283,6 +421,7 @@ const insertObject = async (type, object, baseUrl, authHeader) => {
|
|||
|
||||
module.exports = {
|
||||
insertSampleBiblio,
|
||||
insertSampleHold,
|
||||
insertObject,
|
||||
deleteSampleObjects,
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue