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

Signed-off-by: Owen Leonard <oleonard@myacpl.org>
Signed-off-by: Matt Blenkinsop <matt.blenkinsop@openfifth.co.uk>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 0985c64a54)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
This commit is contained in:
Jonathan Druart 2025-06-12 16:43:12 +02:00 committed by Paul Derscheid
parent c60f0bfe85
commit fc419ce2ef
No known key found for this signature in database
GPG Key ID: C25F9FD44CED595B
5 changed files with 128 additions and 21 deletions

View File

@ -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),
};

View File

@ -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;

View File

@ -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
);
}
}

View File

@ -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");

View File

@ -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: [],
},
];