Bugzilla – Attachment 193528 Details for
Bug 26355
Allow patrons to self-renew through the OPAC
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 26355: Add cypress tests
Bug-26355-Add-cypress-tests.patch (text/plain), 12.15 KB, created by
Matt Blenkinsop
on 2026-02-20 10:59:45 UTC
(
hide
)
Description:
Bug 26355: Add cypress tests
Filename:
MIME Type:
Creator:
Matt Blenkinsop
Created:
2026-02-20 10:59:45 UTC
Size:
12.15 KB
patch
obsolete
>From cf7e1998429316b3f451bac21572026f86971944 Mon Sep 17 00:00:00 2001 >From: Matt Blenkinsop <matt.blenkinsop@openfifth.co.uk> >Date: Thu, 19 Feb 2026 13:32:58 +0000 >Subject: [PATCH] Bug 26355: Add cypress tests > >Adds categories to the db insertion mechanics and allows values to be passed to the patron insertion method >--- > Koha/REST/V1/Patrons/Categories.pm | 20 ++ > t/cypress/integration/Islands/SelfRenewal.ts | 206 +++++++++++++++++++ > t/cypress/plugins/insertData.js | 27 +++ > 3 files changed, 253 insertions(+) > create mode 100644 t/cypress/integration/Islands/SelfRenewal.ts > >diff --git a/Koha/REST/V1/Patrons/Categories.pm b/Koha/REST/V1/Patrons/Categories.pm >index 6fa4ec84c94..f2439ff1b05 100644 >--- a/Koha/REST/V1/Patrons/Categories.pm >+++ b/Koha/REST/V1/Patrons/Categories.pm >@@ -50,4 +50,24 @@ sub list { > }; > } > >+=head3 add >+ >+=cut >+ >+sub add { >+ my $c = shift->openapi->valid_input or return; >+ >+ return try { >+ my $category = Koha::Patron::Category->new_from_api( $c->req->json ); >+ $category->store; >+ $c->res->headers->location( $c->req->url->to_string . '/' . $category->categorycode ); >+ return $c->render( >+ status => 201, >+ openapi => $c->objects->to_api($category), >+ ); >+ } catch { >+ $c->unhandled_exception($_); >+ }; >+} >+ > 1; >diff --git a/t/cypress/integration/Islands/SelfRenewal.ts b/t/cypress/integration/Islands/SelfRenewal.ts >new file mode 100644 >index 00000000000..fef1ddb06fe >--- /dev/null >+++ b/t/cypress/integration/Islands/SelfRenewal.ts >@@ -0,0 +1,206 @@ >+describe("Patron self-renewal", () => { >+ beforeEach(() => { >+ cy.task("buildSampleObject", { >+ object: "patron_category", >+ values: { >+ self_renewal_enabled: 1, >+ self_renewal_availability_start: 10, >+ self_renewal_if_expired: 10, >+ self_renewal_failure_message: "This cypress renewal has failed", >+ self_renewal_information_message: >+ "This should display before renewal", >+ self_renewal_fines_block: 0, >+ }, >+ }).then(patron_category => { >+ cy.task("insertObject", { >+ type: "category", >+ object: patron_category, >+ }).then(patron_category => { >+ cy.wrap(patron_category).as("patron_category"); >+ cy.task("insertSamplePatron", { >+ patron_category, >+ patronValues: { >+ password: "Cypress1234", >+ email: "test@email.com", >+ secondary_email: "test@email.com", >+ altaddress_email: "test@email.com", >+ }, >+ }).then(objects_patron => { >+ cy.wrap(objects_patron).as("objects_patron"); >+ cy.loginOpac( >+ objects_patron.patron.cardnumber, >+ "Cypress1234" >+ ); >+ }); >+ }); >+ }); >+ }); >+ >+ afterEach(function () { >+ this.objects_patron.category = this.patron_category; >+ cy.task("deleteSampleObjects", this.objects_patron); >+ }); >+ >+ it("should display a message that self renewal is available", function () { >+ cy.visitOpac("/cgi-bin/koha/opac-user.pl"); >+ cy.get("#self_renewal_available").contains( >+ "You are eligible for self-renewal. Please click here to renew your account" >+ ); >+ }); >+ it("should open the modal for self-renewal", function () { >+ cy.visitOpac("/cgi-bin/koha/opac-user.pl"); >+ cy.get("#patronSelfRenewal", { timeout: 10000 }); >+ cy.get("#self_renewal_available a").click(); >+ cy.get("#patronSelfRenewal").should("be.visible"); >+ }); >+ it("should verify that the patron wants to renew their account", function () { >+ cy.visitOpac("/cgi-bin/koha/opac-user.pl"); >+ cy.intercept( >+ "GET", >+ Cypress.env("opacBaseUrl") + >+ "/api/v1/public/patrons/*/self_renewal?_per_page=-1", >+ { >+ self_renewal_settings: { >+ opac_patron_details: "0", >+ self_renewal_failure_message: >+ "Your self-renewal can't be processed at this time. Please visit your local branch to complete your renewal.", >+ }, >+ } >+ ).as("renewalConfig"); >+ cy.get("#patronSelfRenewal", { timeout: 10000 }); >+ cy.get("#self_renewal_available a").click(); >+ cy.wait("@renewalConfig"); >+ cy.get("#patronSelfRenewal .verification_question").contains( >+ "Are you sure you want to renew your account?" >+ ); >+ }); >+ it("should renew a patron's account", function () { >+ cy.visitOpac("/cgi-bin/koha/opac-user.pl"); >+ cy.intercept( >+ "GET", >+ Cypress.env("opacBaseUrl") + >+ "/api/v1/public/patrons/*/self_renewal?_per_page=-1", >+ { >+ self_renewal_settings: { >+ opac_patron_details: "0", >+ self_renewal_failure_message: >+ "Your self-renewal can't be processed at this time. Please visit your local branch to complete your renewal.", >+ }, >+ } >+ ).as("renewalConfig"); >+ cy.get("#patronSelfRenewal", { timeout: 10000 }); >+ cy.get("#self_renewal_available a").click(); >+ cy.wait("@renewalConfig"); >+ cy.intercept( >+ "POST", >+ Cypress.env("opacBaseUrl") + >+ "/api/v1/public/patrons/*/self_renewal", >+ { >+ statusCode: 201, >+ body: { >+ expiry_date: "2099-01-01", >+ confirmation_sent: true, >+ }, >+ } >+ ).as("submitRenewal"); >+ cy.get("#patronSelfRenewal .verification_actions") >+ .contains("Yes") >+ .click(); >+ cy.wait("@submitRenewal"); >+ cy.get("#self_renewal_success").contains( >+ "Your account has been successfully renewed" >+ ); >+ }); >+ it("should display an information message step", function () { >+ cy.visitOpac("/cgi-bin/koha/opac-user.pl"); >+ cy.intercept( >+ "GET", >+ Cypress.env("opacBaseUrl") + >+ "/api/v1/public/patrons/*/self_renewal?_per_page=-1", >+ { >+ self_renewal_settings: { >+ opac_patron_details: "0", >+ self_renewal_failure_message: >+ "Your self-renewal can't be processed at this time. Please visit your local branch to complete your renewal.", >+ self_renewal_information_message: "This should be shown", >+ }, >+ } >+ ).as("renewalConfig"); >+ cy.get("#patronSelfRenewal", { timeout: 10000 }); >+ cy.get("#self_renewal_available a").click(); >+ cy.wait("@renewalConfig"); >+ cy.intercept( >+ "POST", >+ Cypress.env("opacBaseUrl") + >+ "/api/v1/public/patrons/*/self_renewal", >+ { >+ statusCode: 201, >+ body: { >+ expiry_date: "2099-01-01", >+ confirmation_sent: true, >+ }, >+ } >+ ).as("submitRenewal"); >+ cy.get("#patronSelfRenewal .verification_question").contains( >+ "This should be shown" >+ ); >+ cy.get("#patronSelfRenewal .verification_actions") >+ .contains("Yes") >+ .click(); >+ >+ cy.get("#patronSelfRenewal .verification_actions") >+ .contains("Yes") >+ .click(); >+ cy.wait("@submitRenewal"); >+ cy.get("#self_renewal_success").contains( >+ "Your account has been successfully renewed" >+ ); >+ }); >+ it("should confirm patron details if required", function () { >+ cy.visitOpac("/cgi-bin/koha/opac-user.pl"); >+ cy.intercept( >+ "GET", >+ Cypress.env("opacBaseUrl") + >+ "/api/v1/public/patrons/*/self_renewal?_per_page=-1", >+ { >+ self_renewal_settings: { >+ opac_patron_details: "1", >+ self_renewal_failure_message: >+ "Your self-renewal can't be processed at this time. Please visit your local branch to complete your renewal.", >+ }, >+ } >+ ).as("renewalConfig"); >+ cy.get("#patronSelfRenewal", { timeout: 10000 }); >+ cy.get("#self_renewal_available a").click(); >+ cy.wait("@renewalConfig"); >+ >+ cy.get("#patronSelfRenewal legend").contains( >+ "Confirm your account details" >+ ); >+ cy.get("#patronSelfRenewal button").contains("Continue").click(); >+ >+ cy.get("h1").contains("Your personal details"); >+ cy.get("#update-account div.alert.alert-info").contains( >+ "Please verify your details to proceed with your self-renewal" >+ ); >+ cy.intercept( >+ "POST", >+ Cypress.env("opacBaseUrl") + >+ "/api/v1/public/patrons/*/self_renewal", >+ { >+ statusCode: 201, >+ body: { >+ expiry_date: "2099-01-01", >+ confirmation_sent: true, >+ }, >+ } >+ ).as("submitRenewal"); >+ cy.get("#update-account fieldset.action input[type='submit']") >+ .contains("Submit renewal request") >+ .click(); >+ cy.wait("@submitRenewal"); >+ cy.get("#self_renewal_success").contains( >+ "Your account has been successfully renewed" >+ ); >+ }); >+}); >diff --git a/t/cypress/plugins/insertData.js b/t/cypress/plugins/insertData.js >index a784245dc60..d757425b33b 100644 >--- a/t/cypress/plugins/insertData.js >+++ b/t/cypress/plugins/insertData.js >@@ -388,6 +388,7 @@ const insertSampleCheckout = async ({ patron, baseUrl, authHeader }) => { > const insertSamplePatron = async ({ > library, > patron_category, >+ patronValues, > baseUrl, > authHeader, > }) => { >@@ -427,6 +428,7 @@ const insertSamplePatron = async ({ > category_id: patron_category.patron_category_id, > incorrect_address: null, > patron_card_lost: null, >+ ...patronValues, > }, > }); > >@@ -443,6 +445,7 @@ const insertSamplePatron = async ({ > lang, > login_attempts, > sms_provider_id, >+ self_renewal_available, > ...patron > } = generatedPatron; > delete patron.library; >@@ -454,6 +457,16 @@ const insertSamplePatron = async ({ > authHeader, > }); > >+ if (patronValues.hasOwnProperty("password")) { >+ const password = patronValues.password; >+ await apiPost({ >+ endpoint: `/api/v1/patrons/${patron.patron_id}/password`, >+ body: { password, password_2: password }, >+ baseUrl, >+ authHeader, >+ }); >+ } >+ > return { > patron, > ...(generatedLibrary ? { library } : {}), >@@ -563,6 +576,12 @@ const deleteSampleObjects = async allObjects => { > table: "erm_eholdings_titles", > whereColumn: "title_id", > }, >+ category: { >+ plural: "categories", >+ table: "categories", >+ whereColumn: "categorycode", >+ idField: "patron_category_id", >+ }, > }; > // Merge by type > const mergedObjects = {}; >@@ -594,6 +613,7 @@ const deleteSampleObjects = async allObjects => { > "item_types", > "erm_agreements", > "erm_eholdings_titles", >+ "categories", > ]; > const matchTypeToObjectMap = type => { > const matchingKey = Object.keys(objectsMap).find( >@@ -858,6 +878,13 @@ const insertObject = async ({ type, object, baseUrl, authHeader }) => { > baseUrl, > authHeader, > }); >+ } else if (type === "category") { >+ return apiPost({ >+ endpoint: "/api/v1/patron_categories", >+ body: object, >+ baseUrl, >+ authHeader, >+ }); > } else { > throw Error(`Unsupported object type '${type}' to insert`); > } >-- >2.39.5
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 26355
:
191781
|
191782
|
191783
|
191784
|
191785
|
191786
|
191787
|
191788
|
191789
|
192440
|
192441
|
192442
|
192443
|
192444
|
192445
|
192446
|
192447
|
192448
|
193065
|
193066
|
193067
|
193068
|
193069
|
193070
|
193071
|
193072
|
193073
|
193074
|
193249
|
193250
|
193251
|
193252
|
193253
|
193521
|
193522
|
193523
|
193524
|
193525
|
193526
|
193527
|
193528
|
193529
|
193581
|
193635
|
193654
|
193699
|
193756
|
193757
|
193758
|
193759
|
193760
|
193761
|
193762
|
193763
|
193764
|
193765
|
193921
|
194435
|
194464
|
194465
|
194466
|
194467
|
194468
|
194469
|
194470
|
194471
|
194472
|
194473
|
194474