Bug 30708: Add tests
[koha.git] / t / cypress / integration / Preservation / Trains.ts
1 import { mount } from "@cypress/vue";
2
3 function get_attributes() {
4     return [
5         {
6             processing_attribute_id: 1,
7             processing_id: 1,
8             name: "Country",
9             type: "authorised_value",
10             option_source: "COUNTRY",
11         },
12         {
13             processing_attribute_id: 2,
14             processing_id: 1,
15             name: "DB",
16             type: "db_column",
17             option_source: "biblio.title",
18         },
19         {
20             processing_attribute_id: 3,
21             processing_id: 1,
22             name: "Height",
23             type: "free_text",
24             option_source: null,
25         },
26     ];
27 }
28 function get_other_attributes() {
29     return [
30         {
31             processing_attribute_id: 4,
32             processing_id: 2,
33             name: "Country",
34             type: "authorised_value",
35             option_source: "COUNTRY",
36         },
37         {
38             processing_attribute_id: 5,
39             processing_id: 2,
40             name: "Width",
41             type: "free_text",
42             option_source: null,
43         },
44     ];
45 }
46
47 function get_processings() {
48     return [
49         {
50             name: "new processing",
51             processing_id: 1,
52             attributes: get_attributes(),
53         },
54         {
55             name: "an other processing",
56             processing_id: 2,
57             attributes: get_other_attributes(),
58         },
59     ];
60 }
61
62 function get_items() {
63     // This is not a full item but it contains the info we are using
64     return [
65         {
66             biblio: {
67                 biblio_id: 1,
68                 title: "a biblio title",
69             },
70             external_id: "bc_1",
71             item_id: 1,
72         },
73         {
74             biblio: {
75                 biblio_id: 2,
76                 title: "an other biblio title",
77             },
78             external_id: "bc_2",
79             item_id: 2,
80         },
81         {
82             biblio: {
83                 biblio_id: 3,
84                 title: "yet an other biblio title",
85             },
86             external_id: "bc_3",
87             item_id: 3,
88         },
89     ];
90 }
91
92 function get_train_items() {
93     let train_item_1 = get_items()[0];
94     let processing_attributes = get_attributes();
95     train_item_1.attributes = [
96         {
97             processing_attribute: processing_attributes[0],
98             processing_attribute_id:
99                 processing_attributes[0].processing_attribute_id,
100             value: "Argentina",
101         },
102         {
103             processing_attribute: processing_attributes[1],
104             processing_attribute_id:
105                 processing_attributes[1].processing_attribute_id,
106             value: "a biblio title modified",
107         },
108         {
109             processing_attribute: processing_attributes[2],
110             processing_attribute_id:
111                 processing_attributes[2].processing_attribute_id,
112             value: "12cm",
113         },
114     ];
115     train_item_1.added_on = "2023-03-31T12:23:34+00:00";
116     train_item_1.processing_id = 1;
117     train_item_1.item_id = 1;
118
119     let train_item_2 = get_items()[1];
120     let processing_attributes = get_attributes();
121     train_item_2.attributes = [
122         {
123             processing_attribute: processing_attributes[0],
124             processing_attribute_id:
125                 processing_attributes[0].processing_attribute_id,
126             value: "Uruguay",
127         },
128         {
129             processing_attribute: processing_attributes[1],
130             processing_attribute_id:
131                 processing_attributes[1].processing_attribute_id,
132             value: "an other modified title",
133         },
134         {
135             processing_attribute: processing_attributes[2],
136             processing_attribute_id:
137                 processing_attributes[2].processing_attribute_id,
138             value: "34cm",
139         },
140     ];
141     train_item_2.added_on = "2023-04-01T12:34:56+00:00";
142     train_item_2.processing_id = 1;
143     train_item_2.item_id = 2;
144
145     let train_item_3 = get_items()[0];
146     let processing_attributes = get_other_attributes();
147     train_item_3.attributes = [
148         {
149             processing_attribute: processing_attributes[0],
150             processing_attribute_id:
151                 processing_attributes[0].processing_attribute_id,
152             value: "Bolivia",
153         },
154         {
155             processing_attribute: processing_attributes[1],
156             processing_attribute_id:
157                 processing_attributes[1].processing_attribute_id,
158             value: "W 123cm",
159         },
160     ];
161     train_item_3.added_on = "2023-04-02T12:34:56+00:00";
162     train_item_3.processing_id = 2;
163     train_item_3.item_id = 3;
164
165     return [train_item_1, train_item_2, train_item_3];
166 }
167
168 function get_train() {
169     let processings = get_processings();
170     return {
171         train_id: 1,
172         name: "My train",
173         description: "Just a train",
174         default_processing_id: processings[0].processing_id,
175         not_for_loan: "42",
176         created_on: "2023-04-05T10:16:27+00:00",
177         closed_on: null,
178         sent_on: null,
179         received_on: null,
180         items: [],
181         default_processing: processings[0],
182     };
183 }
184
185 describe("Trains", () => {
186     beforeEach(() => {
187         cy.login();
188         cy.title().should("eq", "Koha staff interface");
189         cy.intercept(
190             "GET",
191             "/cgi-bin/koha/svc/config/systempreferences/?pref=PreservationModule",
192             '{"value":"1"}'
193         );
194         cy.intercept(
195             "GET",
196             "/cgi-bin/koha/svc/config/systempreferences/?pref=PreservationNotForLoanWaitingListIn",
197             '{"value":"24"}'
198         );
199         cy.intercept(
200             "GET",
201             "/cgi-bin/koha/svc/config/systempreferences/?pref=PreservationNotForLoanDefaultTrainIn",
202             '{"value":"42"}'
203         );
204         cy.intercept(
205             "GET",
206             "/api/v1/authorised_value_categories/NOT_LOAN/authorised_values",
207             [
208                 {
209                     category_name: "NOT_LOAN",
210                     description: "Ordered",
211                     value: "-1",
212                 },
213                 {
214                     category_name: "NOT_LOAN",
215                     description: "Not for loan",
216                     value: "1",
217                 },
218                 {
219                     category_name: "NOT_LOAN",
220                     description: "Staff collection",
221                     value: "2",
222                 },
223                 {
224                     category_name: "NOT_LOAN",
225                     description: "Added to bundle",
226                     value: "3",
227                 },
228                 {
229                     category_name: "NOT_LOAN",
230                     description: "In preservation",
231                     value: "24",
232                 },
233                 {
234                     category_name: "NOT_LOAN",
235                     description: "In preservation external",
236                     value: "42",
237                 },
238                 {
239                     category_name: "NOT_LOAN",
240                     description: "In preservation other",
241                     value: "43",
242                 },
243             ]
244         );
245     });
246
247     it("List trains", () => {
248         // GET trains returns 500
249         cy.intercept("GET", "/api/v1/preservation/trains*", {
250             statusCode: 500,
251             error: "Something went wrong",
252         });
253         cy.visit("/cgi-bin/koha/preservation/home.pl");
254         cy.get("#navmenulist").contains("Trains").click();
255         cy.get("main div[class='dialog alert']").contains(
256             /Something went wrong/
257         );
258
259         // GET trains returns empty list
260         cy.intercept("GET", "/api/v1/*", []);
261         cy.visit("/cgi-bin/koha/preservation/trains");
262         cy.get("#trains_list").contains("There are no trains defined");
263
264         // GET trains returns something
265         let train = get_train();
266         let trains = [train];
267
268         cy.intercept("GET", "/api/v1/preservation/trains*", {
269             statusCode: 200,
270             body: trains,
271             headers: {
272                 "X-Base-Total-Count": "1",
273                 "X-Total-Count": "1",
274             },
275         });
276         cy.intercept("GET", "/api/v1/preservation/trains/*", train);
277         cy.visit("/cgi-bin/koha/preservation/trains");
278         cy.get("#trains_list").contains("Showing 1 to 1 of 1 entries");
279     });
280
281     it("Add train", () => {
282         cy.intercept("GET", "/api/v1/preservation/trains", []);
283         cy.intercept(
284             "GET",
285             "/api/v1/preservation/processings",
286             get_processings()
287         );
288         cy.visit("/cgi-bin/koha/preservation/trains");
289         let train = get_train();
290         cy.contains("New train").click();
291         cy.get("#train_name").type(train.name);
292         cy.get("#train_description").type(train.description);
293         // Confirm that the default not_for_loan is selected
294         cy.get("#not_for_loan .vs__selected").contains(
295             "In preservation external"
296         );
297         // Change it
298         cy.get("#not_for_loan .vs__search").type(
299             "In preservation other{enter}"
300         );
301         cy.get("#train_default_processing .vs__search").type(
302             "new processing{enter}"
303         );
304
305         // Submit the form, get 500
306         cy.intercept("POST", "/api/v1/preservation/trains", {
307             statusCode: 500,
308             error: "Something went wrong",
309         });
310         cy.get("#trains_add").contains("Submit").click();
311         cy.get("main div[class='dialog alert']").contains(
312             "Something went wrong: Error: Internal Server Error"
313         );
314
315         // Submit the form, success!
316         cy.intercept("POST", "/api/v1/preservation/trains", {
317             statusCode: 201,
318             body: train,
319         });
320         cy.get("#trains_add").contains("Submit").click();
321         cy.get("main div[class='dialog message']").contains("Train created");
322     });
323
324     it("Edit train", () => {
325         let train = get_train();
326         let processings = get_processings();
327         cy.intercept("GET", "/api/v1/preservation/trains/*", train);
328         cy.intercept("GET", "/api/v1/preservation/trains", [train]);
329         cy.intercept("GET", "/api/v1/preservation/processings*", processings);
330         cy.visit("/cgi-bin/koha/preservation/trains");
331         cy.get("#trains_list table tbody tr:first").contains("Edit").click();
332         cy.get("#train_name").should("have.value", train.name);
333         cy.get("#train_description").should("have.value", train.description);
334         cy.get("#not_for_loan .vs__selected").contains(
335             "In preservation external"
336         );
337         cy.get("#train_default_processing .vs__selected").contains(
338             train.default_processing.name
339         );
340
341         // Submit the form, get 500
342         cy.intercept("PUT", "/api/v1/preservation/trains/*", {
343             statusCode: 500,
344             error: "Something went wrong",
345         });
346         cy.get("#trains_add").contains("Submit").click();
347         cy.get("main div[class='dialog alert']").contains(
348             "Something went wrong: Error: Internal Server Error"
349         );
350
351         // Submit the form, success!
352         cy.intercept("PUT", "/api/v1/preservation/trains/*", {
353             statusCode: 200,
354             body: train,
355         });
356         cy.intercept("GET", "/api/v1/preservation/trains", {
357             statusCode: 200,
358             body: [train],
359         });
360         cy.get("#trains_add").contains("Submit").click();
361         cy.get("main div[class='dialog message']").contains("Train updated");
362     });
363
364     it("Simple show train", () => {
365         let train = get_train();
366         let trains = [train];
367
368         cy.intercept("GET", "/api/v1/preservation/trains*", {
369             statusCode: 200,
370             body: trains,
371             headers: {
372                 "X-Base-Total-Count": "1",
373                 "X-Total-Count": "1",
374             },
375         });
376         cy.intercept("GET", "/api/v1/preservation/trains/*", train);
377         cy.visit("/cgi-bin/koha/preservation/trains");
378         let name_link = cy.get("#trains_list table tbody tr:first td:first a");
379         name_link.should(
380             "have.text",
381             train.name + " (#" + train.train_id + ")"
382         );
383         name_link.click();
384         cy.get("#trains_show h2").contains("Train #" + train.train_id);
385
386         cy.contains("Name:" + train.name);
387         cy.contains("Description:" + train.description);
388         cy.contains(
389             "Status for item added to this train:" + "In preservation external"
390         );
391         cy.contains("Default processing:" + train.default_processing.name);
392     });
393
394     it("Show train close, send, receive", () => {
395         let train = get_train();
396         cy.intercept("GET", "/api/v1/preservation/trains/" + train.train_id, {
397             statusCode: 200,
398             body: train,
399         }).as("get-train");
400         cy.visit("/cgi-bin/koha/preservation/trains/" + train.train_id);
401         cy.wait("@get-train");
402         cy.contains("Closed on:").should("not.exist");
403         cy.contains("Sent on:").should("not.exist");
404         cy.contains("Received on:").should("not.exist");
405
406         let closed_train = Object.assign({}, train);
407         closed_train.closed_on = "2022-10-27 12:34:56";
408         cy.intercept("PUT", "/api/v1/preservation/trains/" + train.train_id, {
409             statusCode: 201,
410             body: closed_train,
411         }).as("set-train");
412         cy.intercept("GET", "/api/v1/preservation/trains/" + train.train_id, {
413             statusCode: 200,
414             body: closed_train,
415         }).as("get-train");
416         cy.get("#toolbar").contains("Close").click();
417         cy.wait("@get-train");
418         cy.contains("Closed on:").should("exist");
419         cy.contains("Sent on:").should("not.exist");
420         cy.contains("Received on:").should("not.exist");
421
422         let sent_train = Object.assign({}, closed_train);
423         sent_train.sent_on = "2022-10-28 12:34:56";
424         cy.intercept("PUT", "/api/v1/preservation/trains/" + train.train_id, {
425             statusCode: 201,
426             body: sent_train,
427         }).as("set-train");
428         cy.intercept("GET", "/api/v1/preservation/trains/" + train.train_id, {
429             statusCode: 200,
430             body: sent_train,
431         }).as("get-train");
432         cy.get("#toolbar").contains("Send").click();
433         cy.wait("@get-train");
434         cy.contains("Closed on:").should("exist");
435         cy.contains("Sent on:").should("exist");
436         cy.contains("Received on:").should("not.exist");
437
438         let received_train = Object.assign({}, sent_train);
439         received_train.received_on = "2022-10-29 12:34:56";
440         cy.intercept("PUT", "/api/v1/preservation/trains/" + train.train_id, {
441             statusCode: 201,
442             body: received_train,
443         }).as("set-train");
444         cy.intercept("GET", "/api/v1/preservation/trains/" + train.train_id, {
445             statusCode: 200,
446             body: received_train,
447         }).as("get-train");
448         cy.get("#toolbar").contains("Receive").click();
449         cy.wait("@get-train");
450         cy.contains("Closed on:").should("exist");
451         cy.contains("Sent on:").should("exist");
452         cy.contains("Received on:").should("exist");
453     });
454
455     it("Delete train", () => {
456         let train = get_train();
457         cy.intercept("GET", "/api/v1/preservation/trains*", {
458             statusCode: 200,
459             body: [train],
460             headers: {
461                 "X-Base-Total-Count": "1",
462                 "X-Total-Count": "1",
463             },
464         });
465         cy.visit("/cgi-bin/koha/preservation/trains");
466
467         // Submit the form, get 500
468         cy.intercept(
469             "DELETE",
470             "/api/v1/preservation/trains/" + train.train_id,
471             {
472                 statusCode: 500,
473                 error: "Something went wrong",
474             }
475         );
476         cy.get("#trains_list table tbody tr:first").contains("Delete").click();
477         cy.contains("Yes, delete").click();
478         cy.get("main div[class='dialog alert']").contains(
479             "Something went wrong: Error: Internal Server Error"
480         );
481
482         // Submit the form, success!
483         cy.intercept(
484             "DELETE",
485             "/api/v1/preservation/trains/" + train.train_id,
486             {
487                 statusCode: 201,
488                 body: null,
489             }
490         );
491         cy.get("#trains_list table tbody tr:first").contains("Delete").click();
492         cy.contains("Yes, delete").click();
493         cy.get("main div[class='dialog message']").contains(
494             `Train ${train.name} deleted`
495         );
496     });
497
498     it("Add new item to a train", () => {
499         let train = get_train();
500         cy.intercept(
501             "GET",
502             "/api/v1/preservation/trains/" + train.train_id,
503             train
504         );
505         let processings = get_processings();
506         cy.intercept("GET", "/api/v1/preservation/processings*", processings);
507         cy.intercept(
508             "GET",
509             "/api/v1/preservation/processings/" + processings[0].processing_id,
510             processings[0]
511         );
512         cy.visit("/cgi-bin/koha/preservation/trains/" + train.train_id);
513         cy.contains("Add items").click();
514         cy.get("#barcode").type("bc_1");
515         cy.intercept("GET", "/api/v1/preservation/waiting-list/items*", []);
516         cy.contains("Submit").click();
517         cy.get("div[class='dialog alert modal']").contains(
518             "Cannot find item with this barcode. It must be in the waiting list."
519         );
520         cy.get("#close_modal").click();
521
522         let item = get_items()[0];
523         cy.intercept("GET", "/api/v1/preservation/waiting-list/items*", [item]);
524         cy.contains("Submit").click();
525         cy.intercept(
526             "POST",
527             `/api/v1/preservation/trains/${train.train_id}/items`,
528             {
529                 statusCode: 201,
530                 body: item, // Not correct but not important
531             }
532         );
533         cy.contains("Itemnumber:" + item.item_id);
534         cy.get("#processing .vs__selected").contains(
535             train.default_processing.name
536         );
537         cy.contains("Country:");
538         cy.get("#attribute_0 .vs__search").type("Argentin{enter}");
539         cy.contains("DB:");
540         cy.get("#attribute_1").should("have.value", item.biblio.title);
541         cy.get("#attribute_1").type(" modified");
542         cy.contains("Height:");
543         cy.get("#attribute_2").type("42cm");
544
545         let train_items = get_train_items();
546         let train_with_one_item = Object.assign({}, train);
547         train_with_one_item.items = [train_items[0]];
548
549         cy.intercept(
550             "GET",
551             "/api/v1/preservation/trains/" + train.train_id,
552             train_with_one_item
553         );
554         cy.contains("Submit").click();
555         cy.get("#trains_show").contains("Showing 1 to 1 of 1 entries");
556
557         let train_with_2_items = Object.assign({}, train);
558         train_with_2_items.items = [train_items[0], train_items[1]];
559         cy.intercept(
560             "GET",
561             "/api/v1/preservation/trains/" + train.train_id,
562             train_with_2_items
563         );
564         cy.visit("/cgi-bin/koha/preservation/trains/" + train.train_id);
565         cy.get("#trains_show table").should("exist");
566         cy.get("#trains_show").contains("Showing 1 to 2 of 2 entries");
567         train_with_2_items.items.forEach(train_item => {
568             train_item.attributes.forEach(attribute => {
569                 cy.get("td").contains(attribute.value);
570             });
571         });
572
573         let train_with_3_items = Object.assign({}, train);
574         train_with_3_items.items = [
575             train_items[0],
576             train_items[1],
577             train_items[2],
578         ];
579         cy.intercept(
580             "GET",
581             "/api/v1/preservation/trains/" + train.train_id,
582             train_with_3_items
583         );
584         cy.visit("/cgi-bin/koha/preservation/trains/" + train.train_id);
585         cy.get("#trains_show table").should("not.exist");
586         train_with_3_items.items.forEach((train_item, i) => {
587             train_item.attributes.forEach(attribute => {
588                 let re = new RegExp(attribute.value);
589                 cy.get(`#item_${i}`).contains(re);
590             });
591         });
592     });
593 });