Bugzilla – Attachment 193692 Details for
Bug 39224
Migrate SAML/Shibboleth configuration into Identity Providers
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 39224: Cypress tests for identity providers admin interface
991f3dd.patch (text/plain), 13.82 KB, created by
Martin Renvoize (ashimema)
on 2026-02-24 07:33:57 UTC
(
hide
)
Description:
Bug 39224: Cypress tests for identity providers admin interface
Filename:
MIME Type:
Creator:
Martin Renvoize (ashimema)
Created:
2026-02-24 07:33:57 UTC
Size:
13.82 KB
patch
obsolete
>From 991f3dd7a87712e30cc66c1ac9463b9e239dbfb4 Mon Sep 17 00:00:00 2001 >From: Martin Renvoize <martin.renvoize@openfifth.co.uk> >Date: Tue, 24 Feb 2026 07:29:03 +0000 >Subject: [PATCH] Bug 39224: Cypress tests for identity providers admin > interface > >Add cypress integration tests for the new identity providers vue app. > >Test plan >1) Run the new tests with: > yarn cypress run --spec t/cypress/integration/Admin/IdentityProviders_spec.ts > >Sponsored-by: ByWater Solutions >--- > .../Admin/IdentityProviders_spec.ts | 355 ++++++++++++++++++ > 1 file changed, 355 insertions(+) > create mode 100644 t/cypress/integration/Admin/IdentityProviders_spec.ts > >diff --git a/t/cypress/integration/Admin/IdentityProviders_spec.ts b/t/cypress/integration/Admin/IdentityProviders_spec.ts >new file mode 100644 >index 00000000000..19c9d199e6e >--- /dev/null >+++ b/t/cypress/integration/Admin/IdentityProviders_spec.ts >@@ -0,0 +1,355 @@ >+import { mount } from "@cypress/vue"; >+ >+function get_provider() { >+ return { >+ identity_provider_id: 1, >+ code: "test_oauth", >+ description: "Test OAuth Provider", >+ protocol: "OAuth", >+ enabled: true, >+ icon_url: null, >+ config: { >+ key: "my_client_id", >+ secret: "my_client_secret", >+ authorize_url: "https://idp.example.com/authorize", >+ token_url: "https://idp.example.com/token", >+ userinfo_url: "", >+ scope: "", >+ }, >+ domains: [], >+ hostnames: [], >+ mappings: [], >+ }; >+} >+ >+describe("Identity providers", () => { >+ beforeEach(() => { >+ cy.login(); >+ cy.title().should("eq", "Koha staff interface"); >+ // The provider component fetches all known hostnames on mount >+ cy.intercept("GET", "/api/v1/auth/hostnames*", []); >+ }); >+ >+ it("List providers", () => { >+ // GET returns empty list >+ cy.intercept("GET", "/api/v1/auth/identity_providers*", []); >+ cy.visit("/cgi-bin/koha/admin/identity_providers"); >+ cy.get("#providers_list").contains( >+ "There are no identity providers configured" >+ ); >+ >+ // GET returns something >+ let provider = get_provider(); >+ let providers = [provider]; >+ >+ cy.intercept("GET", "/api/v1/auth/identity_providers*", { >+ statusCode: 200, >+ body: providers, >+ headers: { >+ "X-Base-Total-Count": "1", >+ "X-Total-Count": "1", >+ }, >+ }); >+ cy.intercept("GET", "/api/v1/auth/identity_providers/*", provider); >+ cy.visit("/cgi-bin/koha/admin/identity_providers/"); >+ cy.get("#providers_list").contains("Showing 1 to 1 of 1 entries"); >+ }); >+ >+ it("Add provider", () => { >+ cy.intercept("GET", "/api/v1/auth/identity_providers**", { >+ statusCode: 200, >+ body: [], >+ }); >+ >+ cy.visit("/cgi-bin/koha/admin/identity_providers"); >+ cy.contains("New identity provider").click(); >+ cy.get("#providers_add h2").contains("New identity provider"); >+ cy.left_menu_active_item_is("Identity providers"); >+ >+ // Required fields are validated >+ cy.get("#providers_add").contains("Save").click(); >+ cy.get("input:invalid,textarea:invalid,select:invalid").should( >+ "have.length.gte", >+ 1 >+ ); >+ >+ cy.get("#code").type("test_oauth"); >+ cy.get("#description").type("Test OAuth Provider"); >+ >+ // Selecting OAuth shows OAuth-specific config fields >+ cy.get("#protocol .vs__search").type("OAuth{enter}", { force: true }); >+ cy.get("#_config_key").should("be.visible"); >+ cy.get("#_config_secret").should("be.visible"); >+ cy.get("#_config_authorize_url").should("be.visible"); >+ cy.get("#_config_token_url").should("be.visible"); >+ // OIDC-only field should not be visible >+ cy.get("#_config_well_known_url").should("not.exist"); >+ >+ cy.get("#_config_key").type("my_client_id"); >+ cy.get("#_config_secret").type("my_client_secret"); >+ cy.get("#_config_authorize_url").type( >+ "https://idp.example.com/authorize" >+ ); >+ cy.get("#_config_token_url").type("https://idp.example.com/token"); >+ >+ // Add a mapping relationship >+ cy.contains("Add mapping").click(); >+ cy.get("#mappings_0 #mappings_provider_field_0").type("email"); >+ >+ // Add a domain rule >+ cy.contains("Add domain rule").click(); >+ cy.get("#domains_0 #domains_domain_0").type("library.org"); >+ >+ // Submit the form, get 500 >+ cy.intercept("POST", "/api/v1/auth/identity_providers", { >+ statusCode: 500, >+ }); >+ cy.get("#providers_add").contains("Save").click(); >+ cy.get("main div[class='alert alert-warning']").contains( >+ "Something went wrong: Error: Internal Server Error" >+ ); >+ >+ // Submit the form, success! >+ let provider = get_provider(); >+ cy.intercept("POST", "/api/v1/auth/identity_providers", { >+ statusCode: 201, >+ body: provider, >+ }); >+ cy.intercept("POST", "/api/v1/auth/identity_providers/*/mappings", { >+ statusCode: 201, >+ body: {}, >+ }); >+ cy.intercept("POST", "/api/v1/auth/identity_providers/*/domains", { >+ statusCode: 201, >+ body: {}, >+ }); >+ cy.get("#providers_add").contains("Save").click(); >+ cy.get("main div[class='alert alert-info']").contains( >+ "Identity provider created" >+ ); >+ }); >+ >+ it("Add provider - OIDC protocol shows correct fields", () => { >+ cy.intercept("GET", "/api/v1/auth/identity_providers**", { >+ statusCode: 200, >+ body: [], >+ }); >+ >+ cy.visit("/cgi-bin/koha/admin/identity_providers/add"); >+ >+ // Select OIDC - should show well_known_url, hide OAuth-specific fields >+ cy.get("#protocol .vs__search").type("OIDC{enter}", { force: true }); >+ cy.get("#_config_well_known_url").should("be.visible"); >+ cy.get("#_config_authorize_url").should("not.exist"); >+ cy.get("#_config_token_url").should("not.exist"); >+ }); >+ >+ it("Add provider - matchpoint validation", () => { >+ cy.intercept("GET", "/api/v1/auth/identity_providers**", { >+ statusCode: 200, >+ body: [], >+ }); >+ cy.intercept("GET", "/api/v1/auth/hostnames*", [ >+ { hostname_id: 1, hostname: "library.example.com" }, >+ ]); >+ >+ cy.visit("/cgi-bin/koha/admin/identity_providers/add"); >+ cy.get("#code").type("test_oauth"); >+ cy.get("#description").type("Test OAuth Provider"); >+ cy.get("#protocol .vs__search").type("OAuth{enter}", { force: true }); >+ cy.get("#_config_key").type("my_client_id"); >+ cy.get("#_config_secret").type("my_client_secret"); >+ cy.get("#_config_authorize_url").type( >+ "https://idp.example.com/authorize" >+ ); >+ cy.get("#_config_token_url").type("https://idp.example.com/token"); >+ >+ // Add a hostname with a matchpoint but no corresponding mapping >+ cy.contains("Add hostname").click(); >+ cy.get("#hostnames_0 #hostnames_hostname_0 .vs__search").type( >+ "library.example.com{enter}", >+ { force: true } >+ ); >+ cy.get("#hostnames_0 #hostnames_matchpoint_0 .vs__search").type( >+ "Email{enter}", >+ { force: true } >+ ); >+ >+ // Submit without a matching mapping รข should show validation error >+ cy.intercept("POST", "/api/v1/auth/identity_providers", { >+ statusCode: 201, >+ body: { identity_provider_id: 1 }, >+ }); >+ cy.get("#providers_add").contains("Save").click(); >+ cy.get("main div[class='alert alert-warning']").contains( >+ "The selected matchpoint must have a corresponding attribute mapping" >+ ); >+ }); >+ >+ it("Edit provider", () => { >+ let provider = get_provider(); >+ let providers = [provider]; >+ >+ // Intercept the list load >+ cy.intercept("GET", "/api/v1/auth/identity_providers?_page*", { >+ statusCode: 200, >+ body: providers, >+ headers: { >+ "X-Base-Total-Count": "1", >+ "X-Total-Count": "1", >+ }, >+ }).as("get-providers-list"); >+ >+ cy.visit("/cgi-bin/koha/admin/identity_providers"); >+ cy.wait("@get-providers-list"); >+ >+ // Intercept the single-provider fetch after clicking Edit >+ cy.intercept("GET", "/api/v1/auth/identity_providers/*", provider).as( >+ "get-provider" >+ ); >+ >+ cy.get("#providers_list table tbody tr:first").contains("Edit").click(); >+ cy.wait("@get-provider"); >+ cy.wait(500); // Allow Vue to populate the form >+ cy.get("#providers_add h2").contains("Edit identity provider"); >+ cy.left_menu_active_item_is("Identity providers"); >+ >+ // Form is pre-filled correctly >+ cy.get("#code").should("have.value", provider.code); >+ cy.get("#description").should("have.value", provider.description); >+ >+ // Submit the form, get 500 >+ cy.intercept("PUT", "/api/v1/auth/identity_providers/*", req => { >+ req.reply({ >+ statusCode: 500, >+ delay: 1000, >+ }); >+ }).as("edit-provider"); >+ cy.get("#providers_add").contains("Save").click(); >+ cy.get("main div[class='modal_centered']").contains("Submitting..."); >+ cy.wait("@edit-provider"); >+ cy.get("main div[class='alert alert-warning']").contains( >+ "Something went wrong: Error: Internal Server Error" >+ ); >+ >+ // Submit the form, success! >+ cy.intercept("PUT", "/api/v1/auth/identity_providers/*", { >+ statusCode: 200, >+ body: provider, >+ }); >+ cy.get("#providers_add").contains("Save").click(); >+ cy.get("main div[class='alert alert-info']").contains( >+ "Identity provider updated" >+ ); >+ }); >+ >+ it("Show provider", () => { >+ let provider = get_provider(); >+ let providers = [provider]; >+ >+ cy.intercept("GET", "/api/v1/auth/identity_providers*", { >+ statusCode: 200, >+ body: providers, >+ headers: { >+ "X-Base-Total-Count": "1", >+ "X-Total-Count": "1", >+ }, >+ }); >+ cy.intercept("GET", "/api/v1/auth/identity_providers/*", provider).as( >+ "get-provider" >+ ); >+ >+ cy.visit("/cgi-bin/koha/admin/identity_providers"); >+ let code_link = cy.get( >+ "#providers_list table tbody tr:first td:first a" >+ ); >+ code_link.should("have.text", provider.code); >+ code_link.click(); >+ cy.wait("@get-provider"); >+ cy.get("#providers_show h2").contains( >+ "Identity provider #" + provider.identity_provider_id >+ ); >+ cy.left_menu_active_item_is("Identity providers"); >+ }); >+ >+ it("Delete provider", () => { >+ let provider = get_provider(); >+ let providers = [provider]; >+ >+ // Delete from list >+ cy.intercept("GET", "/api/v1/auth/identity_providers*", { >+ statusCode: 200, >+ body: providers, >+ headers: { >+ "X-Base-Total-Count": "1", >+ "X-Total-Count": "1", >+ }, >+ }); >+ cy.intercept("GET", "/api/v1/auth/identity_providers/*", provider); >+ cy.visit("/cgi-bin/koha/admin/identity_providers"); >+ >+ cy.get("#providers_list table tbody tr:first") >+ .contains("Delete") >+ .click(); >+ cy.get(".alert-warning.confirmation h1").contains( >+ "delete this identity provider" >+ ); >+ cy.contains(provider.code); >+ >+ // Accept the confirmation dialog, get 500 >+ cy.intercept("DELETE", "/api/v1/auth/identity_providers/*", { >+ statusCode: 500, >+ }); >+ cy.contains("Yes, delete").click(); >+ cy.get("main div[class='alert alert-warning']").contains( >+ "Something went wrong: Error: Internal Server Error" >+ ); >+ >+ // Accept the confirmation dialog, success! >+ cy.intercept("DELETE", "/api/v1/auth/identity_providers/*", { >+ statusCode: 204, >+ body: null, >+ }); >+ cy.get("#providers_list table tbody tr:first") >+ .contains("Delete") >+ .click(); >+ cy.get(".alert-warning.confirmation h1").contains( >+ "delete this identity provider" >+ ); >+ cy.contains("Yes, delete").click(); >+ cy.get("main div[class='alert alert-info']").contains( >+ "Identity provider deleted" >+ ); >+ >+ // Delete from show >+ cy.intercept("GET", "/api/v1/auth/identity_providers*", { >+ statusCode: 200, >+ body: providers, >+ headers: { >+ "X-Base-Total-Count": "1", >+ "X-Total-Count": "1", >+ }, >+ }); >+ cy.intercept("GET", "/api/v1/auth/identity_providers/*", provider).as( >+ "get-provider" >+ ); >+ cy.visit("/cgi-bin/koha/admin/identity_providers"); >+ let code_link = cy.get( >+ "#providers_list table tbody tr:first td:first a" >+ ); >+ code_link.click(); >+ cy.wait("@get-provider"); >+ cy.get("#providers_show h2").contains( >+ "Identity provider #" + provider.identity_provider_id >+ ); >+ >+ cy.get("#providers_show #toolbar").contains("Delete").click(); >+ cy.get(".alert-warning.confirmation h1").contains( >+ "delete this identity provider" >+ ); >+ cy.contains("Yes, delete").click(); >+ >+ // Make sure we return to the list after deleting from show >+ cy.get("#providers_list table tbody tr:first"); >+ }); >+}); >-- >2.53.0 >
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 39224
:
189234
|
189235
|
189236
|
189237
|
189238
|
189239
|
189240
|
189241
|
189242
|
189243
|
189244
|
193618
|
193619
|
193620
|
193621
|
193622
|
193623
|
193624
|
193625
|
193626
|
193627
|
193681
|
193682
|
193683
|
193684
|
193685
|
193686
|
193687
|
193688
|
193689
|
193690
|
193691
| 193692