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>
This commit is contained in:
Jonathan Druart 2025-06-12 16:43:12 +02:00 committed by Lucas Gass
parent c14e72e782
commit 0985c64a54
No known key found for this signature in database
GPG Key ID: 60B447398B0D36CA
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: [],
},
];