|
Lines 767-772
describe("Booking Modal Basic Tests", () => {
Link Here
|
| 767 |
}); |
767 |
}); |
| 768 |
}); |
768 |
}); |
| 769 |
|
769 |
|
|
|
770 |
it("should refresh edit modal state across consecutive openings", () => { |
| 771 |
const today = dayjs().startOf("day"); |
| 772 |
let secondPatron; |
| 773 |
let firstBookingId; |
| 774 |
let secondBookingId; |
| 775 |
|
| 776 |
const firstBooking = { |
| 777 |
start: today.add(8, "day"), |
| 778 |
end: today.add(10, "day"), |
| 779 |
patron_id: testData.patron.patron_id, |
| 780 |
patron_label: testData.patron.surname, |
| 781 |
}; |
| 782 |
|
| 783 |
cy.task("buildSampleObject", { |
| 784 |
object: "patron", |
| 785 |
values: { |
| 786 |
firstname: "Jane", |
| 787 |
surname: "Roe", |
| 788 |
cardnumber: `TEST${Date.now()}B`, |
| 789 |
category_id: "PT", |
| 790 |
library_id: testData.libraries[0].library_id, |
| 791 |
}, |
| 792 |
}).then(mockPatron => { |
| 793 |
secondPatron = mockPatron; |
| 794 |
|
| 795 |
return cy.task("query", { |
| 796 |
sql: `INSERT INTO borrowers (borrowernumber, firstname, surname, cardnumber, categorycode, branchcode, dateofbirth) |
| 797 |
VALUES (?, ?, ?, ?, ?, ?, ?)`, |
| 798 |
values: [ |
| 799 |
mockPatron.patron_id, |
| 800 |
mockPatron.firstname, |
| 801 |
mockPatron.surname, |
| 802 |
mockPatron.cardnumber, |
| 803 |
mockPatron.category_id, |
| 804 |
mockPatron.library_id, |
| 805 |
"1990-01-01", |
| 806 |
], |
| 807 |
}); |
| 808 |
}); |
| 809 |
|
| 810 |
cy.then(() => |
| 811 |
cy |
| 812 |
.task("query", { |
| 813 |
sql: `INSERT INTO bookings (biblio_id, item_id, patron_id, start_date, end_date, pickup_library_id, status) |
| 814 |
VALUES (?, ?, ?, ?, ?, ?, '1')`, |
| 815 |
values: [ |
| 816 |
testData.biblio.biblio_id, |
| 817 |
testData.items[0].item_id, |
| 818 |
firstBooking.patron_id, |
| 819 |
firstBooking.start.format("YYYY-MM-DD HH:mm:ss"), |
| 820 |
firstBooking.end.format("YYYY-MM-DD HH:mm:ss"), |
| 821 |
testData.libraries[0].library_id, |
| 822 |
], |
| 823 |
}) |
| 824 |
.then(result => { |
| 825 |
firstBookingId = result.insertId; |
| 826 |
}) |
| 827 |
); |
| 828 |
|
| 829 |
cy.then(() => { |
| 830 |
const secondBooking = { |
| 831 |
start: today.add(15, "day"), |
| 832 |
end: today.add(17, "day"), |
| 833 |
patron_id: secondPatron.patron_id, |
| 834 |
patron_label: secondPatron.surname, |
| 835 |
}; |
| 836 |
|
| 837 |
return cy |
| 838 |
.task("query", { |
| 839 |
sql: `INSERT INTO bookings (biblio_id, item_id, patron_id, start_date, end_date, pickup_library_id, status) |
| 840 |
VALUES (?, ?, ?, ?, ?, ?, '1')`, |
| 841 |
values: [ |
| 842 |
testData.biblio.biblio_id, |
| 843 |
testData.items[1].item_id, |
| 844 |
secondBooking.patron_id, |
| 845 |
secondBooking.start.format("YYYY-MM-DD HH:mm:ss"), |
| 846 |
secondBooking.end.format("YYYY-MM-DD HH:mm:ss"), |
| 847 |
testData.libraries[0].library_id, |
| 848 |
], |
| 849 |
}) |
| 850 |
.then(result => { |
| 851 |
secondBookingId = result.insertId; |
| 852 |
}) |
| 853 |
.then(() => secondBooking); |
| 854 |
}).then(secondBooking => { |
| 855 |
cy.visit( |
| 856 |
`/cgi-bin/koha/catalogue/detail.pl?biblionumber=${testData.biblio.biblio_id}` |
| 857 |
); |
| 858 |
cy.get("booking-modal-island .modal").should("exist"); |
| 859 |
|
| 860 |
// First open: booking A |
| 861 |
cy.window().then(win => { |
| 862 |
win.openBookingModal({ |
| 863 |
booking: String(firstBookingId), |
| 864 |
patron: String(firstBooking.patron_id), |
| 865 |
itemnumber: String(testData.items[0].item_id), |
| 866 |
pickup_library: testData.libraries[0].library_id, |
| 867 |
start_date: firstBooking.start.startOf("day").toISOString(), |
| 868 |
end_date: firstBooking.end.endOf("day").toISOString(), |
| 869 |
biblionumber: String(testData.biblio.biblio_id), |
| 870 |
}); |
| 871 |
}); |
| 872 |
|
| 873 |
cy.get("booking-modal-island .modal", { timeout: 10000 }).should( |
| 874 |
"be.visible" |
| 875 |
); |
| 876 |
cy.vueSelectShouldHaveValue( |
| 877 |
"booking_patron", |
| 878 |
firstBooking.patron_label |
| 879 |
); |
| 880 |
|
| 881 |
cy.get("booking-modal-island .modal .btn-close").first().click(); |
| 882 |
cy.get("booking-modal-island .modal").should("not.be.visible"); |
| 883 |
cy.get("body").should("not.have.class", "modal-open"); |
| 884 |
|
| 885 |
// Second open: booking B (must not stay stale with booking A data) |
| 886 |
cy.window().then(win => { |
| 887 |
win.openBookingModal({ |
| 888 |
booking: String(secondBookingId), |
| 889 |
patron: String(secondBooking.patron_id), |
| 890 |
itemnumber: String(testData.items[1].item_id), |
| 891 |
pickup_library: testData.libraries[0].library_id, |
| 892 |
start_date: secondBooking.start |
| 893 |
.startOf("day") |
| 894 |
.toISOString(), |
| 895 |
end_date: secondBooking.end.endOf("day").toISOString(), |
| 896 |
biblionumber: String(testData.biblio.biblio_id), |
| 897 |
}); |
| 898 |
}); |
| 899 |
|
| 900 |
cy.get("booking-modal-island .modal", { timeout: 10000 }).should( |
| 901 |
"be.visible" |
| 902 |
); |
| 903 |
cy.vueSelectShouldHaveValue( |
| 904 |
"booking_patron", |
| 905 |
secondBooking.patron_label |
| 906 |
); |
| 907 |
}); |
| 908 |
|
| 909 |
cy.then(() => { |
| 910 |
if (firstBookingId) { |
| 911 |
cy.task("query", { |
| 912 |
sql: "DELETE FROM bookings WHERE booking_id = ?", |
| 913 |
values: [firstBookingId], |
| 914 |
}); |
| 915 |
} |
| 916 |
if (secondBookingId) { |
| 917 |
cy.task("query", { |
| 918 |
sql: "DELETE FROM bookings WHERE booking_id = ?", |
| 919 |
values: [secondBookingId], |
| 920 |
}); |
| 921 |
} |
| 922 |
if (secondPatron) { |
| 923 |
cy.task("query", { |
| 924 |
sql: "DELETE FROM borrowers WHERE borrowernumber = ?", |
| 925 |
values: [secondPatron.patron_id], |
| 926 |
}); |
| 927 |
} |
| 928 |
}); |
| 929 |
}); |
| 930 |
|
| 770 |
it("should handle booking failure gracefully", () => { |
931 |
it("should handle booking failure gracefully", () => { |
| 771 |
/** |
932 |
/** |
| 772 |
* Comprehensive Error Handling and Recovery Test |
933 |
* Comprehensive Error Handling and Recovery Test |
| 773 |
- |
|
|