From 30934f60cceba9e01755b77f8330fa80a9b10c16 Mon Sep 17 00:00:00 2001 From: Jonathan Druart Date: Thu, 12 Jun 2025 16:43:12 +0200 Subject: [PATCH] Bug 40173: Make http-client reusable from Cypress tests We will need to call REST API endpoints from Cypress tests, and more specifically from Cypress's tasks. It will be useful to reuse what has been done in http-client.js instead of using the low-level fetch JS function. 1. Add missing get and getAll functions 2. Allow overwrite of return_response and mark_submitting 3. Add a "default" client that will bring flexibility (can call any routes) 4. Add rspack config to generate t/cypress/plugins/dist/api-client.cjs.js that will make it reusable from Cypress's tasks --- .../intranet-tmpl/prog/js/fetch/api-client.js | 2 + .../prog/js/fetch/default-api-client.js | 19 ++++++++ .../prog/js/fetch/http-client.js | 46 +++++++++++++++--- .../prog/js/vue/fetch/http-client.js | 48 +++++++++++++------ rspack.config.js | 34 +++++++++++++ 5 files changed, 128 insertions(+), 21 deletions(-) create mode 100644 koha-tmpl/intranet-tmpl/prog/js/fetch/default-api-client.js diff --git a/koha-tmpl/intranet-tmpl/prog/js/fetch/api-client.js b/koha-tmpl/intranet-tmpl/prog/js/fetch/api-client.js index 5b516fa4458..2fe5a6dce8c 100644 --- a/koha-tmpl/intranet-tmpl/prog/js/fetch/api-client.js +++ b/koha-tmpl/intranet-tmpl/prog/js/fetch/api-client.js @@ -13,6 +13,7 @@ import RecallAPIClient from "./recall-api-client.js"; import SysprefAPIClient from "./system-preferences-api-client.js"; import TicketAPIClient from "./ticket-api-client.js"; import AcquisitionAPIClient from "./acquisition-api-client.js"; +import DefaultAPIClient from "./default-api-client.js"; export const APIClient = { article_request: new ArticleRequestAPIClient(HttpClient), @@ -28,4 +29,5 @@ export const APIClient = { recall: new RecallAPIClient(HttpClient), sysprefs: new SysprefAPIClient(HttpClient), ticket: new TicketAPIClient(HttpClient), + default: new DefaultAPIClient(HttpClient), }; diff --git a/koha-tmpl/intranet-tmpl/prog/js/fetch/default-api-client.js b/koha-tmpl/intranet-tmpl/prog/js/fetch/default-api-client.js new file mode 100644 index 00000000000..714d3a33578 --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/js/fetch/default-api-client.js @@ -0,0 +1,19 @@ +export class DefaultAPIClient { + constructor(HttpClient) { + this.httpClient = new HttpClient({ + baseURL: "", + }); + } + + get koha() { + return { + get: params => this.httpClient.get(params), + getAll: params => this.httpClient.getAll(params), + post: params => this.httpClient.post(params), + put: params => this.httpClient.put(params), + delete: params => this.httpClient.delete(params), + }; + } +} + +export default DefaultAPIClient; diff --git a/koha-tmpl/intranet-tmpl/prog/js/fetch/http-client.js b/koha-tmpl/intranet-tmpl/prog/js/fetch/http-client.js index 93194a164b5..8f2c3d3ab27 100644 --- a/koha-tmpl/intranet-tmpl/prog/js/fetch/http-client.js +++ b/koha-tmpl/intranet-tmpl/prog/js/fetch/http-client.js @@ -105,6 +105,40 @@ class HttpClient { return res; } + get(params = {}) { + return this._fetchJSON( + params.endpoint, + params.headers, + { + ...params.options, + method: "GET", + }, + params.return_response ?? false, + params.mark_submitting ?? false + ); + } + + getAll(params = {}) { + let url = + params.endpoint + + "?" + + new URLSearchParams({ + _per_page: -1, + ...(params.params && params.params), + ...(params.query && { q: JSON.stringify(params.query) }), + }); + return this._fetchJSON( + url, + params.headers, + { + ...params.options, + method: "GET", + }, + params.return_response ?? false, + params.mark_submitting ?? false + ); + } + post(params = {}) { const body = params.body ? typeof params.body === "string" @@ -121,8 +155,8 @@ class HttpClient { body, method: "POST", }, - false, - true + params.return_response ?? false, + params.mark_submitting ?? true ); } @@ -142,8 +176,8 @@ class HttpClient { body, method: "PUT", }, - false, - true + params.return_response ?? false, + params.mark_submitting ?? true ); } @@ -158,8 +192,8 @@ class HttpClient { ...params.options, method: "DELETE", }, - true, - true + params.return_response ?? true, + params.mark_submitting ?? true ); } } diff --git a/koha-tmpl/intranet-tmpl/prog/js/vue/fetch/http-client.js b/koha-tmpl/intranet-tmpl/prog/js/vue/fetch/http-client.js index ac848c28097..23a2b6b2862 100644 --- a/koha-tmpl/intranet-tmpl/prog/js/vue/fetch/http-client.js +++ b/koha-tmpl/intranet-tmpl/prog/js/vue/fetch/http-client.js @@ -59,10 +59,16 @@ class HttpClient { } get(params = {}) { - return this._fetchJSON(params.endpoint, params.headers, { - ...params.options, - method: "GET", - }); + return this._fetchJSON( + params.endpoint, + params.headers, + { + ...params.options, + method: "GET", + }, + params.return_response ?? false, + params.mark_submitting ?? false + ); } getAll(params = {}) { @@ -74,10 +80,16 @@ class HttpClient { ...(params.params && params.params), ...(params.query && { q: JSON.stringify(params.query) }), }); - return this._fetchJSON(url, params.headers, { - ...params.options, - method: "GET", - }); + return this._fetchJSON( + url, + params.headers, + { + ...params.options, + method: "GET", + }, + params.return_response ?? false, + params.mark_submitting ?? false + ); } post(params = {}) { @@ -96,8 +108,8 @@ class HttpClient { body, method: "POST", }, - false, - true + params.return_response ?? false, + params.mark_submitting ?? true ); } @@ -117,8 +129,8 @@ class HttpClient { body, method: "PUT", }, - false, - true + params.return_response ?? false, + params.mark_submitting ?? true ); } @@ -133,14 +145,20 @@ class HttpClient { ...params.options, method: "DELETE", }, - true, - true + params.return_response ?? true, + params.mark_submitting ?? true ); } count(params = {}) { let res; - return this._fetchJSON(params.endpoint, params.headers, {}, 1).then( + return this._fetchJSON( + params.endpoint, + params.headers, + {}, + params.return_response ?? true, + params.mark_submitting ?? false + ).then( response => { if (response) { return response.headers.get("X-Total-Count"); diff --git a/rspack.config.js b/rspack.config.js index 630aa6a5133..9b10583d51b 100644 --- a/rspack.config.js +++ b/rspack.config.js @@ -161,4 +161,38 @@ module.exports = [ "datatables.net-buttons/js/buttons.colVis": "DataTable", }, }, + { + entry: { + "api-client.cjs": + "./koha-tmpl/intranet-tmpl/prog/js/fetch/api-client.js", + }, + output: { + filename: "[name].js", + path: path.resolve(__dirname, "t/cypress/plugins/dist/"), + library: { + type: "commonjs", + }, + globalObject: "global", + }, + target: "node", + module: { + rules: [ + { + test: /\.js$/, + loader: "builtin:swc-loader", + options: { + jsc: { + parser: { + syntax: "ecmascript", + }, + }, + }, + exclude: [/node_modules/], + type: "javascript/auto", + }, + ], + }, + externals: [], + plugins: [], + }, ]; -- 2.34.1