1 import { mount } from "@cypress/vue";
2 const dayjs = require("dayjs"); /* Cannot use our calendar JS code, it's in an include file (!)
3 Also note that moment.js is deprecated */
6 today_iso: dayjs().format("YYYY-MM-DD"),
7 today_us: dayjs().format("MM/DD/YYYY"),
8 tomorrow_iso: dayjs().add(1, "day").format("YYYY-MM-DD"),
9 tomorrow_us: dayjs().add(1, "day").format("MM/DD/YYYY"),
11 function get_agreement() {
15 description: "my first agreement",
24 started_on: dates["today_iso"],
25 ended_on: dates["tomorrow_iso"],
26 cancellation_deadline: null,
30 started_on: dates["today_iso"],
32 cancellation_deadline: dates["tomorrow_iso"],
33 notes: "this is a note",
40 agreement_license_id: 3,
42 description: "license description",
49 notes: "license notes",
50 physical_location: "cupboard",
51 status: "controlling",
56 agreement_license_id: 4,
58 description: "second license description",
60 name: "second license name",
65 notes: "second license notes",
66 physical_location: "cupboard",
71 agreement_relationships: [
74 notes: 'related agreement notes',
77 description: "agreement description",
78 name: "agreement name"
80 related_agreement_id: 2,
81 relationship: "supersedes"
84 agreement_packages: [],
88 file_description: "file description",
89 file_name: "file.json",
91 physical_location: "file physical location",
93 uploaded_on: "2022-10-27T11:57:02+00:00"
99 function get_licenses_to_relate() {
103 description: "a license",
104 name: "first license name"
108 description: "a second license",
109 name: "second license name"
113 description: "a third license",
114 name: "third license name"
119 describe("Agreement CRUD operations", () => {
121 cy.fetch_initial_ERM_sys_pref_value();
122 cy.set_ERM_sys_pref_value(true);
126 cy.login("koha", "koha");
127 cy.title().should("eq", "Koha staff interface");
131 cy.reset_initial_ERM_sys_pref_value();
134 it("List agreements", () => {
135 // GET agreements returns 500
136 cy.intercept("GET", "/api/v1/erm/agreements", {
138 error: "Something went wrong",
140 cy.visit("/cgi-bin/koha/erm/erm.pl");
141 cy.get("#navmenulist").contains("Agreements").click();
142 cy.get("main div[class='dialog alert']").contains(
143 /Something went wrong/
146 // GET agreements returns empty list
147 cy.intercept("GET", "/api/v1/erm/agreements*", []);
148 cy.visit("/cgi-bin/koha/erm/agreements");
149 cy.get("#agreements_list").contains("There are no agreements defined");
151 // GET agreements returns something
152 let agreement = get_agreement();
153 let agreements = [agreement];
155 cy.intercept("GET", "/api/v1/erm/agreements*", {
159 "X-Base-Total-Count": "1",
160 "X-Total-Count": "1",
163 cy.intercept("GET", "/api/v1/erm/agreements/*", agreement);
164 cy.visit("/cgi-bin/koha/erm/agreements");
165 cy.get("#agreements_list").contains("Showing 1 to 1 of 1 entries");
168 it("Add agreement", () => {
169 // No agreement, no license yet
170 cy.intercept("GET", "/api/v1/erm/agreements", {
174 cy.intercept("GET", "/api/v1/erm/licenses", {
179 // Click the button in the toolbar
180 cy.visit("/cgi-bin/koha/erm/agreements");
181 cy.contains("New agreement").click();
182 cy.get("#agreements_add h2").contains("New agreement");
184 // Fill in the form for normal attributes
185 let agreement = get_agreement();
187 cy.get("#agreements_add").contains("Submit").click();
188 cy.get("input:invalid,textarea:invalid,select:invalid").should(
192 cy.get("#agreement_name").type(agreement.name);
193 cy.get("#agreement_description").type(agreement.description);
194 cy.get("#agreements_add").contains("Submit").click();
195 cy.get("input:invalid,textarea:invalid,select:invalid").should(
198 ); // name, description, status
199 cy.get("#agreement_status .vs__search").type(
200 agreement.status + "{enter}",
204 cy.contains("Add new period").click();
205 cy.get("#agreements_add").contains("Submit").click();
206 cy.get("input:invalid,textarea:invalid,select:invalid").should(
212 cy.contains("Add new period").click();
213 cy.contains("Add new period").click();
214 cy.get("#agreement_periods > fieldset").should("have.length", 3);
216 cy.get("#agreement_period_1").contains("Remove this period").click();
218 cy.get("#agreement_periods > fieldset").should("have.length", 2);
219 cy.get("#agreement_period_0");
220 cy.get("#agreement_period_1");
222 // Selecting the flatpickr values is a bit tedious here...
223 // We have 3 date inputs per period
224 cy.get("#ended_on_0+input").click();
225 // Second flatpickr => ended_on for the first period
226 cy.get(".flatpickr-calendar")
229 .click({ force: true }); // select today. No idea why we should force, but there is a random failure otherwise
231 cy.get("#started_on_0+input").click();
232 cy.get(".flatpickr-calendar")
236 .click(); // select tomorrow
238 cy.get("#ended_on_0").should("have.value", ""); // Has been reset correctly
240 cy.get("#started_on_0+input").click();
241 cy.get(".flatpickr-calendar").eq(0).find("span.today").click(); // select today
242 cy.get("#ended_on_0+input").click({ force: true }); // No idea why we should force, but there is a random failure otherwise
243 cy.get(".flatpickr-calendar")
247 .click(); // select tomorrow
250 cy.get("#started_on_1+input").click({ force: true });
251 cy.get(".flatpickr-calendar").eq(3).find("span.today").click(); // select today
252 cy.get("#cancellation_deadline_1+input").click();
253 cy.get(".flatpickr-calendar")
257 .click(); // select tomorrow
258 cy.get("#notes_1").type("this is a note");
260 // TODO Add a new user
261 // How to test a new window with cypresS?
262 //cy.contains("Add new user").click();
263 //cy.contains("Select user").click();
265 cy.get("#agreement_licenses").contains(
266 "There are no licenses created yet"
268 cy.get("#agreement_relationships").contains(
269 "There are no other agreements created yet"
273 cy.get("#documents").contains("Add new document").click();
274 cy.get("#document_0 input[id=file_0]").click();
275 cy.get('#document_0 input[id=file_0]').selectFile('t/cypress/fixtures/file.json');
276 cy.get("#document_0 .file_information span").contains("file.json");
277 cy.get('#document_0 input[id=file_description_0]').type('file description');
278 cy.get('#document_0 input[id=physical_location_0]').type('file physical location');
279 cy.get('#document_0 input[id=uri_0]').type('file URI');
280 cy.get('#document_0 input[id=notes_0]').type('file notes');
282 // Submit the form, get 500
283 cy.intercept("POST", "/api/v1/erm/agreements", {
285 error: "Something went wrong",
287 cy.get("#agreements_add").contains("Submit").click();
288 cy.get("main div[class='dialog alert']").contains(
289 "Something went wrong: Internal Server Error"
292 // Submit the form, success!
293 cy.intercept("POST", "/api/v1/erm/agreements", {
297 cy.get("#agreements_add").contains("Submit").click();
298 cy.get("main div[class='dialog message']").contains(
302 cy.intercept("GET", "/api/v1/erm/agreements", {
304 body: [{ agreement_id: 1, description: "an existing agreement" }],
308 let licenses_to_relate = get_licenses_to_relate();
309 let related_license = agreement.agreement_licenses[0];
310 cy.intercept("GET", "/api/v1/erm/licenses", {
312 body: licenses_to_relate,
314 cy.visit("/cgi-bin/koha/erm/agreements/add");
315 cy.get("#agreement_licenses").contains("Add new license").click();
316 cy.get("#agreement_license_0").contains("Agreement license 1");
317 cy.get("#agreement_license_0 #license_id_0 .vs__search").type(
318 related_license.license.name
320 cy.get("#agreement_license_0 #license_id_0 .vs__dropdown-menu li").eq(0).click( { force: true } ); //click first license suggestion
321 cy.get("#agreement_license_0 #license_status_0 .vs__search").type(
322 related_license.status + "{enter}",
325 cy.get("#agreement_license_0 #license_location_0 .vs__search").type(
326 related_license.physical_location + "{enter}",
329 cy.get("#agreement_license_0 #license_notes_0").type(related_license.notes);
330 cy.get("#agreement_license_0 #license_uri_0").type(related_license.uri);
332 // Add new related agreement
333 let related_agreement = agreement.agreement_relationships[0];
334 cy.intercept("GET", "/api/v1/erm/agreements", {
336 body: cy.get_agreements_to_relate(),
338 cy.visit("/cgi-bin/koha/erm/agreements/add");
339 cy.get("#agreement_relationships").contains("Add new related agreement").click();
340 cy.get("#related_agreement_0").contains("Related agreement 1");
341 cy.get("#related_agreement_0 #related_agreement_id_0 .vs__search").type(
342 related_agreement.related_agreement.name
344 cy.get("#related_agreement_0 #related_agreement_id_0 .vs__dropdown-menu li").eq(0).click( { force: true } ); //click first agreement suggestion
345 cy.get("#related_agreement_0 #related_agreement_notes_0").type(related_agreement.notes);
346 cy.get("#related_agreement_0 #related_agreement_relationship_0 .vs__search").type(
347 related_agreement.relationship + "{enter}",
352 it("Edit agreement", () => {
353 let licenses_to_relate = get_licenses_to_relate();
354 let agreement = get_agreement();
355 let agreements = [agreement];
357 // Intercept initial /agreements request once
361 url: "/api/v1/erm/agreements",
369 // Intercept follow-up 'search' request after entering /agreements
370 cy.intercept("GET", "/api/v1/erm/agreements?_page*", {
374 "X-Base-Total-Count": "1",
375 "X-Total-Count": "1",
377 }).as("get-single-agreement-search-result");
378 cy.visit("/cgi-bin/koha/erm/agreements");
380 // Intercept request after edit click
381 cy.intercept("GET", "/api/v1/erm/agreements/*", agreement).as(
384 // Intercept related licenses request after entering agreement edit
385 cy.intercept("GET", "/api/v1/erm/licenses", {
387 body: licenses_to_relate,
388 }).as("get-related-licenses");
389 // Intercept related agreements request after entering agreement edit
390 cy.intercept("GET", "/api/v1/erm/agreements", {
392 body: cy.get_agreements_to_relate(),
393 }).as("get-related-agreements");
395 // Click the 'Edit' button from the list
396 cy.get("#agreements_list table tbody tr:first")
399 cy.wait("@get-agreement");
400 cy.wait(500); // Cypress is too fast! Vue hasn't populated the form yet!
401 cy.get("#agreements_add h2").contains("Edit agreement");
403 // Form has been correctly filled in
404 cy.get("#agreement_name").should("have.value", agreements[0].name);
405 cy.get("#agreement_description").should(
407 agreements[0].description
409 cy.get("#agreement_status .vs__selected").contains("Active");
410 cy.get("#agreement_is_perpetual_no").should("be.checked");
411 cy.get("#started_on_0").invoke("val").should("eq", dates["today_iso"]);
412 cy.get("#ended_on_0").invoke("val").should("eq", dates["tomorrow_iso"]);
413 cy.get("#cancellation_deadline_0").invoke("val").should("eq", "");
414 cy.get("#notes_0").should("have.value", "");
415 cy.get("#started_on_1").invoke("val").should("eq", dates["today_iso"]);
416 cy.get("#ended_on_1").invoke("val").should("eq", "");
417 cy.get("#cancellation_deadline_1")
419 .should("eq", dates["tomorrow_iso"]);
420 cy.get("#notes_1").should("have.value", "this is a note");
422 //Test related content
423 cy.get("#agreement_license_0 #license_id_0 .vs__selected").contains("first license name");
424 cy.get("#agreement_license_1 #license_id_1 .vs__selected").contains("second license name");
425 cy.get("#document_0 .file_information span").contains("file.json" );
426 cy.get("#related_agreement_0 #related_agreement_id_0 .vs__selected").contains("agreement name");
428 // Submit the form, get 500
429 cy.intercept("PUT", "/api/v1/erm/agreements/*", {
431 error: "Something went wrong",
433 cy.get("#agreements_add").contains("Submit").click();
434 cy.get("main div[class='dialog alert']").contains(
435 "Something went wrong: Internal Server Error"
438 // Submit the form, success!
439 cy.intercept("PUT", "/api/v1/erm/agreements/*", {
443 cy.get("#agreements_add").contains("Submit").click();
444 cy.get("main div[class='dialog message']").contains(
449 it("Show agreement", () => {
450 let agreement = get_agreement();
451 let agreements = [agreement];
452 // Click the "name" link from the list
453 cy.intercept("GET", "/api/v1/erm/agreements*", {
457 "X-Base-Total-Count": "1",
458 "X-Total-Count": "1",
461 cy.intercept("GET", "/api/v1/erm/agreements/*", agreement).as(
464 cy.visit("/cgi-bin/koha/erm/agreements");
465 let name_link = cy.get(
466 "#agreements_list table tbody tr:first td:first a"
470 agreement.name + " (#" + agreement.agreement_id + ")"
473 cy.wait("@get-agreement");
474 cy.wait(500); // Cypress is too fast! Vue hasn't populated the form yet!
475 cy.get("#agreements_show h2").contains(
476 "Agreement #" + agreement.agreement_id
479 // TODO There are more to test here:
480 // Dates correctly formatted
482 // AV's libs displayed
483 // Tables for periods and users
485 it("Delete agreement", () => {
486 let agreement = get_agreement();
487 let agreements = [agreement];
489 // Click the 'Delete' button from the list
490 cy.intercept("GET", "/api/v1/erm/agreements*", {
494 "X-Base-Total-Count": "1",
495 "X-Total-Count": "1",
498 cy.intercept("GET", "/api/v1/erm/agreements/*", agreement);
499 cy.visit("/cgi-bin/koha/erm/agreements");
501 cy.get("#agreements_list table tbody tr:first")
504 cy.get("#agreements_confirm_delete h2").contains("Delete agreement");
505 cy.contains("Agreement name: " + agreement.name);
507 // Submit the form, get 500
508 cy.intercept("DELETE", "/api/v1/erm/agreements/*", {
510 error: "Something went wrong",
512 cy.contains("Yes, delete").click();
513 cy.get("main div[class='dialog alert']").contains(
514 "Something went wrong: Internal Server Error"
517 // Submit the form, success!
518 cy.intercept("DELETE", "/api/v1/erm/agreements/*", {
522 cy.contains("Yes, delete").click();
523 cy.get("main div[class='dialog message']").contains(