@vulog/aima-vehicle 1.2.29 → 1.2.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,276 +1,216 @@
1
- // src/getModel.ts
2
- var getModelsById = async (client, id) => {
3
- return client.get(`boapi/proxy/user/vehicle/fleets/${client.clientOptions.fleetId}/vehicles/models/${id}`).then(({ data }) => data);
1
+ import z$1, { z } from "zod";
2
+ import { createPaginableOptionsSchema } from "@vulog/aima-core";
3
+ //#region src/getModel.ts
4
+ const getModelsById = async (client, id) => {
5
+ return client.get(`boapi/proxy/user/vehicle/fleets/${client.clientOptions.fleetId}/vehicles/models/${id}`).then(({ data }) => data);
4
6
  };
5
-
6
- // src/getModelAssets.ts
7
- import { z } from "zod";
8
- var schema = z.object({
9
- id: z.number().int().positive()
10
- });
11
- var getModelByIdAssets = async (client, id) => {
12
- const result = schema.safeParse({ id });
13
- if (!result.success) {
14
- throw new TypeError("Invalid args", {
15
- cause: result.error.issues
16
- });
17
- }
18
- return client.get(`boapi/proxy/eds/rest_pub/rest/fleets/${client.clientOptions.fleetId}/models/${id}/`).then(({ data }) => data);
7
+ //#endregion
8
+ //#region src/getModelAssets.ts
9
+ const schema$5 = z.object({ id: z.number().int().positive() });
10
+ const getModelByIdAssets = async (client, id) => {
11
+ const result = schema$5.safeParse({ id });
12
+ if (!result.success) throw new TypeError("Invalid args", { cause: result.error.issues });
13
+ return client.get(`boapi/proxy/eds/rest_pub/rest/fleets/${client.clientOptions.fleetId}/models/${id}/`).then(({ data }) => data);
19
14
  };
20
-
21
- // src/getModels.ts
22
- var getModels = async (client) => {
23
- return client.get(`boapi/proxy/user/vehicle/fleets/${client.clientOptions.fleetId}/vehicles/models`).then(({ data }) => data);
15
+ //#endregion
16
+ //#region src/getModels.ts
17
+ const getModels = async (client) => {
18
+ return client.get(`boapi/proxy/user/vehicle/fleets/${client.clientOptions.fleetId}/vehicles/models`).then(({ data }) => data);
24
19
  };
25
-
26
- // src/getVehicle.ts
27
- import { z as z2 } from "zod";
28
- var schema2 = z2.object({
29
- id: z2.string().trim().min(1).uuid()
30
- });
31
- var getVehicleById = async (client, id) => {
32
- const result = schema2.safeParse({ id });
33
- if (!result.success) {
34
- throw new TypeError("Invalid args", {
35
- cause: result.error.issues
36
- });
37
- }
38
- return client.get(`boapi/proxy/user/vehicle/fleets/${client.clientOptions.fleetId}/vehicles/${result.data.id}`).then(({ data }) => data).catch((error) => {
39
- if (error.formattedError?.status === 404) {
40
- return null;
41
- }
42
- throw error;
43
- });
20
+ //#endregion
21
+ //#region src/getVehicle.ts
22
+ const schema$4 = z.object({ id: z.string().trim().min(1).uuid() });
23
+ const getVehicleById = async (client, id) => {
24
+ const result = schema$4.safeParse({ id });
25
+ if (!result.success) throw new TypeError("Invalid args", { cause: result.error.issues });
26
+ return client.get(`boapi/proxy/user/vehicle/fleets/${client.clientOptions.fleetId}/vehicles/${result.data.id}`).then(({ data }) => data).catch((error) => {
27
+ if (error.formattedError?.status === 404) return null;
28
+ throw error;
29
+ });
44
30
  };
45
- var getVehicleRealTimeById = async (client, id) => {
46
- const result = schema2.safeParse({ id });
47
- if (!result.success) {
48
- throw new TypeError("Invalid args", {
49
- cause: result.error.issues
50
- });
51
- }
52
- return client.get(
53
- `boapi/proxy/fleetmanager/public/fleets/${client.clientOptions.fleetId}/vehicles/${result.data.id}`
54
- ).then(({ data }) => data).catch((error) => {
55
- if (error.formattedError?.status === 404) {
56
- return null;
57
- }
58
- throw error;
59
- });
31
+ const getVehicleRealTimeById = async (client, id) => {
32
+ const result = schema$4.safeParse({ id });
33
+ if (!result.success) throw new TypeError("Invalid args", { cause: result.error.issues });
34
+ return client.get(`boapi/proxy/fleetmanager/public/fleets/${client.clientOptions.fleetId}/vehicles/${result.data.id}`).then(({ data }) => data).catch((error) => {
35
+ if (error.formattedError?.status === 404) return null;
36
+ throw error;
37
+ });
60
38
  };
61
-
62
- // src/getVehicleAssets.ts
63
- import { z as z3 } from "zod";
64
- var schema3 = z3.object({
65
- id: z3.string().uuid()
66
- });
67
- var getVehicleByIdAssets = async (client, id) => {
68
- const result = schema3.safeParse({ id });
69
- if (!result.success) {
70
- throw new TypeError("Invalid args", {
71
- cause: result.error.issues
72
- });
73
- }
74
- return client.get(`boapi/proxy/eds/rest_pub/rest/fleets/${client.clientOptions.fleetId}/vehicles/${id}/`).then(({ data }) => data);
39
+ //#endregion
40
+ //#region src/getVehicleAssets.ts
41
+ const schema$3 = z.object({ id: z.string().uuid() });
42
+ const getVehicleByIdAssets = async (client, id) => {
43
+ const result = schema$3.safeParse({ id });
44
+ if (!result.success) throw new TypeError("Invalid args", { cause: result.error.issues });
45
+ return client.get(`boapi/proxy/eds/rest_pub/rest/fleets/${client.clientOptions.fleetId}/vehicles/${id}/`).then(({ data }) => data);
75
46
  };
76
-
77
- // src/getVehicles.ts
78
- import { z as z4 } from "zod";
79
- var getVehiclesPage = async (client, page, pageSize) => {
80
- const response = await client.get(
81
- `boapi/proxy/user/vehicle/fleets/${client.clientOptions.fleetId}/vehicles?page=${page}&size=${pageSize}`
82
- );
83
- return response.data;
47
+ //#endregion
48
+ //#region src/getVehicles.ts
49
+ /**
50
+ * Fetches a single page of vehicles from the API
51
+ * @param client - The AIMA client instance
52
+ * @param page - The page number to fetch
53
+ * @param pageSize - Number of vehicles per page
54
+ * @returns Promise that resolves to an array of vehicles for the requested page
55
+ */
56
+ const getVehiclesPage = async (client, page, pageSize) => {
57
+ return (await client.get(`boapi/proxy/user/vehicle/fleets/${client.clientOptions.fleetId}/vehicles?page=${page}&size=${pageSize}`)).data;
84
58
  };
85
- var getVehicles = async (client, pageSize = 500) => {
86
- const schema7 = z4.object({
87
- pageSize: z4.number().min(1).default(500)
88
- });
89
- const result = schema7.safeParse({ pageSize });
90
- if (!result.success) {
91
- throw new TypeError("Invalid args", {
92
- cause: result.error.issues
93
- });
94
- }
95
- const allVehicles = [];
96
- let currentPage = 0;
97
- let hasMorePages = true;
98
- const MAX_PAGES = 50;
99
- while (hasMorePages) {
100
- if (currentPage >= MAX_PAGES) {
101
- throw new Error(
102
- `Maximum page limit (${MAX_PAGES}) reached. This might indicate an issue with the pagination or a very large dataset.`
103
- );
104
- }
105
- const vehicles = await getVehiclesPage(client, currentPage, result.data.pageSize);
106
- allVehicles.push(...vehicles);
107
- hasMorePages = vehicles.length === result.data.pageSize;
108
- currentPage += 1;
109
- }
110
- return allVehicles;
59
+ /**
60
+ * Fetches all vehicles from the API using pagination
61
+ * @param client - The AIMA client instance
62
+ * @param pageSize - Number of vehicles per page (default: 500)
63
+ * @returns Promise that resolves to an array of all vehicles
64
+ * @throws Error if more than 50 pages are required to fetch all vehicles
65
+ */
66
+ const getVehicles = async (client, pageSize = 500) => {
67
+ const result = z.object({ pageSize: z.number().min(1).default(500) }).safeParse({ pageSize });
68
+ if (!result.success) throw new TypeError("Invalid args", { cause: result.error.issues });
69
+ const allVehicles = [];
70
+ let currentPage = 0;
71
+ let hasMorePages = true;
72
+ const MAX_PAGES = 50;
73
+ while (hasMorePages) {
74
+ if (currentPage >= MAX_PAGES) throw new Error(`Maximum page limit (${MAX_PAGES}) reached. This might indicate an issue with the pagination or a very large dataset.`);
75
+ const vehicles = await getVehiclesPage(client, currentPage, result.data.pageSize);
76
+ allVehicles.push(...vehicles);
77
+ hasMorePages = vehicles.length === result.data.pageSize;
78
+ currentPage += 1;
79
+ }
80
+ return allVehicles;
111
81
  };
112
- var getVehiclesRealTimePage = async (client, page, pageSize, lastUpdatedMillis) => {
113
- const queryParams = new URLSearchParams({
114
- page: page.toString(),
115
- size: pageSize.toString()
116
- });
117
- if (lastUpdatedMillis !== void 0) {
118
- queryParams.append("lastUpdatedMillis", lastUpdatedMillis.toString());
119
- }
120
- const response = await client.get(
121
- `boapi/proxy/fleetmanager/public/fleets/${client.clientOptions.fleetId}/vehicles?${queryParams.toString()}`
122
- );
123
- return response.data;
82
+ /**
83
+ * Fetches a single page of real-time vehicle data from the API
84
+ * @param client - The AIMA client instance
85
+ * @param page - The page number to fetch
86
+ * @param pageSize - Number of vehicles per page
87
+ * @param lastUpdatedMillis - Optional timestamp in UTC milliseconds
88
+ * @returns Promise that resolves to an array of real-time vehicle data for the requested page
89
+ */
90
+ const getVehiclesRealTimePage = async (client, page, pageSize, lastUpdatedMillis) => {
91
+ const queryParams = new URLSearchParams({
92
+ page: page.toString(),
93
+ size: pageSize.toString()
94
+ });
95
+ if (lastUpdatedMillis !== void 0) queryParams.append("lastUpdatedMillis", lastUpdatedMillis.toString());
96
+ return (await client.get(`boapi/proxy/fleetmanager/public/fleets/${client.clientOptions.fleetId}/vehicles?${queryParams.toString()}`)).data;
124
97
  };
125
- var getVehiclesRealTime = async (client, pageSize = 500, lastUpdatedMillis) => {
126
- const schema7 = z4.object({
127
- pageSize: z4.number().min(1).default(500),
128
- lastUpdatedMillis: z4.number().positive().optional()
129
- });
130
- const result = schema7.safeParse({ pageSize, lastUpdatedMillis });
131
- if (!result.success) {
132
- throw new TypeError("Invalid args", {
133
- cause: result.error.issues
134
- });
135
- }
136
- const allVehicles = [];
137
- let currentPage = 0;
138
- let hasMorePages = true;
139
- const MAX_PAGES = 50;
140
- if (lastUpdatedMillis !== void 0) {
141
- const now = Date.now();
142
- if (lastUpdatedMillis > now) {
143
- throw new Error("lastUpdatedMillis must be in the past");
144
- }
145
- }
146
- while (hasMorePages) {
147
- if (currentPage >= MAX_PAGES) {
148
- throw new Error(
149
- `Maximum page limit (${MAX_PAGES}) reached. This might indicate an issue with the pagination or a very large dataset.`
150
- );
151
- }
152
- const vehicles = await getVehiclesRealTimePage(
153
- client,
154
- currentPage,
155
- result.data.pageSize,
156
- result.data.lastUpdatedMillis
157
- );
158
- allVehicles.push(...vehicles);
159
- hasMorePages = vehicles.length === result.data.pageSize;
160
- currentPage += 1;
161
- }
162
- return allVehicles;
98
+ /**
99
+ * Fetches all real-time vehicle data from the API using pagination
100
+ * @param client - The AIMA client instance
101
+ * @param pageSize - Number of vehicles per page (default: 500)
102
+ * @param lastUpdatedMillis - Optional timestamp in UTC milliseconds. If provided, only vehicles updated after this timestamp will be returned.
103
+ * @returns Promise that resolves to an array of all real-time vehicle data
104
+ * @throws Error if more than 50 pages are required to fetch all vehicles
105
+ * @throws Error if lastUpdatedMillis is in the future
106
+ */
107
+ const getVehiclesRealTime = async (client, pageSize = 500, lastUpdatedMillis) => {
108
+ const result = z.object({
109
+ pageSize: z.number().min(1).default(500),
110
+ lastUpdatedMillis: z.number().positive().optional()
111
+ }).safeParse({
112
+ pageSize,
113
+ lastUpdatedMillis
114
+ });
115
+ if (!result.success) throw new TypeError("Invalid args", { cause: result.error.issues });
116
+ const allVehicles = [];
117
+ let currentPage = 0;
118
+ let hasMorePages = true;
119
+ const MAX_PAGES = 50;
120
+ if (lastUpdatedMillis !== void 0) {
121
+ if (lastUpdatedMillis > Date.now()) throw new Error("lastUpdatedMillis must be in the past");
122
+ }
123
+ while (hasMorePages) {
124
+ if (currentPage >= MAX_PAGES) throw new Error(`Maximum page limit (${MAX_PAGES}) reached. This might indicate an issue with the pagination or a very large dataset.`);
125
+ const vehicles = await getVehiclesRealTimePage(client, currentPage, result.data.pageSize, result.data.lastUpdatedMillis);
126
+ allVehicles.push(...vehicles);
127
+ hasMorePages = vehicles.length === result.data.pageSize;
128
+ currentPage += 1;
129
+ }
130
+ return allVehicles;
163
131
  };
164
-
165
- // src/pingVehicle.ts
166
- import { z as z5 } from "zod";
167
- var schema4 = z5.object({
168
- id: z5.string().trim().min(1).uuid()
169
- });
170
- var pingVehicleById = async (client, id) => {
171
- const result = schema4.safeParse({ id });
172
- if (!result.success) {
173
- throw new TypeError("Invalid args", {
174
- cause: result.error.issues
175
- });
176
- }
177
- try {
178
- await client.get(
179
- `boapi/proxy/fleetmanager/public/v2/fleets/${client.clientOptions.fleetId}/vehicles/${result.data.id}/ping`
180
- );
181
- return true;
182
- } catch (error) {
183
- if (error?.response?.data?.codeStr === "carConnectionProblem" && error?.response?.data?.code === 410) {
184
- return false;
185
- }
186
- throw error;
187
- }
132
+ //#endregion
133
+ //#region src/pingVehicle.ts
134
+ const schema$2 = z.object({ id: z.string().trim().min(1).uuid() });
135
+ /**
136
+ * Pings a vehicle to check if it is alive (box connected).
137
+ * Returns true if alive (HTTP 200), false if box not connected (code 410, codeStr 'carConnectionProblem'),
138
+ * throws for other errors or invalid id.
139
+ */
140
+ const pingVehicleById = async (client, id) => {
141
+ const result = schema$2.safeParse({ id });
142
+ if (!result.success) throw new TypeError("Invalid args", { cause: result.error.issues });
143
+ try {
144
+ await client.get(`boapi/proxy/fleetmanager/public/v2/fleets/${client.clientOptions.fleetId}/vehicles/${result.data.id}/ping`);
145
+ return true;
146
+ } catch (error) {
147
+ if (error?.response?.data?.codeStr === "carConnectionProblem" && error?.response?.data?.code === 410) return false;
148
+ throw error;
149
+ }
188
150
  };
189
-
190
- // src/enableVehicle.ts
191
- import z6 from "zod";
192
- var schema5 = z6.object({
193
- subStatus: z6.string()
194
- });
195
- var enableVehicle = async (client, vehicleId, payload) => {
196
- const result = schema5.safeParse(payload);
197
- if (!result.success) {
198
- throw new TypeError("Invalid args", {
199
- cause: result.error.issues
200
- });
201
- }
202
- return client.post(
203
- `boapi/proxy/fleetmanager/public/fleets/${client.clientOptions.fleetId}/vehicles/${vehicleId}/enable`,
204
- payload
205
- ).then(({ data }) => data);
151
+ //#endregion
152
+ //#region src/enableVehicle.ts
153
+ const schema$1 = z$1.object({ subStatus: z$1.string() });
154
+ const enableVehicle = async (client, vehicleId, payload) => {
155
+ const result = schema$1.safeParse(payload);
156
+ if (!result.success) throw new TypeError("Invalid args", { cause: result.error.issues });
157
+ return client.post(`boapi/proxy/fleetmanager/public/fleets/${client.clientOptions.fleetId}/vehicles/${vehicleId}/enable`, payload).then(({ data }) => data);
206
158
  };
207
-
208
- // src/disableVehicle.ts
209
- import z7 from "zod";
210
- var schema6 = z7.object({
211
- subStatus: z7.string()
212
- });
213
- var disableVehicle = async (client, vehicleId, payload) => {
214
- const result = schema6.safeParse(payload);
215
- if (!result.success) {
216
- throw new TypeError("Invalid args", {
217
- cause: result.error.issues
218
- });
219
- }
220
- return client.post(
221
- `boapi/proxy/fleetmanager/public/fleets/${client.clientOptions.fleetId}/vehicles/${vehicleId}/disable`,
222
- payload
223
- ).then(({ data }) => data);
159
+ //#endregion
160
+ //#region src/disableVehicle.ts
161
+ const schema = z$1.object({ subStatus: z$1.string() });
162
+ const disableVehicle = async (client, vehicleId, payload) => {
163
+ const result = schema.safeParse(payload);
164
+ if (!result.success) throw new TypeError("Invalid args", { cause: result.error.issues });
165
+ return client.post(`boapi/proxy/fleetmanager/public/fleets/${client.clientOptions.fleetId}/vehicles/${vehicleId}/disable`, payload).then(({ data }) => data);
224
166
  };
225
-
226
- // src/getModelVehicles.ts
227
- import { createPaginableOptionsSchema } from "@vulog/aima-core";
228
- var getModelVehicles = async (client, options) => {
229
- const PaginableOptionsSchema = createPaginableOptionsSchema().default({});
230
- const resultOptions = PaginableOptionsSchema.safeParse(options);
231
- if (!resultOptions.success) {
232
- throw new TypeError("Invalid options", {
233
- cause: resultOptions.error.issues
234
- });
235
- }
236
- const finalOptions = resultOptions.data;
237
- const searchParams = new URLSearchParams();
238
- searchParams.append("page", finalOptions.page.toString());
239
- searchParams.append("size", finalOptions.pageSize.toString());
240
- if (finalOptions.sort) {
241
- searchParams.append("sort", `${finalOptions.sort.toString()},${finalOptions.sortDirection.toString()}`);
242
- }
243
- if (finalOptions.filters) {
244
- Object.entries(finalOptions.filters).forEach(([key, value]) => {
245
- if (value === void 0) {
246
- return;
247
- }
248
- searchParams.append(key, value);
249
- });
250
- }
251
- const basePath = `boapi/proxy/user/vehicle/fleets/${client.clientOptions.fleetId}/vehicles/models/modelvehicles`;
252
- const urlWithParams = `${basePath}?${searchParams.toString()}`;
253
- return client.get(urlWithParams).then(({ data, headers }) => {
254
- return {
255
- data,
256
- page: headers.number,
257
- pageSize: headers.size,
258
- total: headers.totalelements,
259
- totalPages: headers.totalpages
260
- };
261
- });
167
+ //#endregion
168
+ //#region src/getModelVehicles.ts
169
+ const getModelVehicles = async (client, options) => {
170
+ const resultOptions = createPaginableOptionsSchema().default({}).safeParse(options);
171
+ if (!resultOptions.success) throw new TypeError("Invalid options", { cause: resultOptions.error.issues });
172
+ const finalOptions = resultOptions.data;
173
+ const searchParams = new URLSearchParams();
174
+ searchParams.append("page", finalOptions.page.toString());
175
+ searchParams.append("size", finalOptions.pageSize.toString());
176
+ if (finalOptions.sort) searchParams.append("sort", `${finalOptions.sort.toString()},${finalOptions.sortDirection.toString()}`);
177
+ if (finalOptions.filters) Object.entries(finalOptions.filters).forEach(([key, value]) => {
178
+ if (value === void 0) return;
179
+ searchParams.append(key, value);
180
+ });
181
+ const urlWithParams = `${`boapi/proxy/user/vehicle/fleets/${client.clientOptions.fleetId}/vehicles/models/modelvehicles`}?${searchParams.toString()}`;
182
+ return client.get(urlWithParams).then(({ data, headers }) => {
183
+ return {
184
+ data,
185
+ page: headers.number,
186
+ pageSize: headers.size,
187
+ total: headers.totalelements,
188
+ totalPages: headers.totalpages
189
+ };
190
+ });
262
191
  };
263
- export {
264
- disableVehicle,
265
- enableVehicle,
266
- getModelByIdAssets,
267
- getModelVehicles,
268
- getModels,
269
- getModelsById,
270
- getVehicleById,
271
- getVehicleByIdAssets,
272
- getVehicleRealTimeById,
273
- getVehicles,
274
- getVehiclesRealTime,
275
- pingVehicleById
192
+ //#endregion
193
+ //#region src/createVehicle.ts
194
+ const createVehicleBodySchema = z.object({
195
+ vin: z.string().trim().min(1).max(20),
196
+ plate: z.string().trim().min(1).max(16),
197
+ name: z.string().trim().min(1).max(64),
198
+ model: z.object({ id: z.number().int().positive() }),
199
+ vuboxId: z.string().optional(),
200
+ externalId: z.string().max(32).optional(),
201
+ wakeupProvider: z.string().max(16).optional(),
202
+ noBox: z.boolean().optional(),
203
+ published: z.boolean().optional(),
204
+ archived: z.boolean().optional(),
205
+ msisdn: z.string().max(32).optional(),
206
+ iccid: z.string().max(32).optional(),
207
+ imsi: z.string().max(32).optional(),
208
+ residualValue: z.number().optional()
209
+ });
210
+ const createVehicle = async (client, body) => {
211
+ const result = createVehicleBodySchema.safeParse(body);
212
+ if (!result.success) throw new TypeError("Invalid args", { cause: result.error.issues });
213
+ return client.post(`/boapi/proxy/vehicle/fleets/${client.clientOptions.fleetId}/vehicles`, result.data).then(({ data }) => data);
276
214
  };
215
+ //#endregion
216
+ export { createVehicle, disableVehicle, enableVehicle, getModelByIdAssets, getModelVehicles, getModels, getModelsById, getVehicleById, getVehicleByIdAssets, getVehicleRealTimeById, getVehicles, getVehiclesRealTime, pingVehicleById };
package/package.json CHANGED
@@ -1,12 +1,25 @@
1
1
  {
2
2
  "name": "@vulog/aima-vehicle",
3
- "version": "1.2.29",
4
- "main": "dist/index.js",
3
+ "type": "module",
4
+ "version": "1.2.31",
5
+ "main": "dist/index.cjs",
5
6
  "module": "dist/index.mjs",
6
- "types": "dist/index.d.ts",
7
+ "types": "dist/index.d.cts",
8
+ "exports": {
9
+ ".": {
10
+ "import": {
11
+ "types": "./dist/index.d.mts",
12
+ "default": "./dist/index.mjs"
13
+ },
14
+ "require": {
15
+ "types": "./dist/index.d.cts",
16
+ "default": "./dist/index.cjs"
17
+ }
18
+ }
19
+ },
7
20
  "scripts": {
8
- "build": "tsup",
9
- "dev": "tsup --watch",
21
+ "build": "tsdown",
22
+ "dev": "tsdown --watch",
10
23
  "test": "vitest run",
11
24
  "test:watch": "vitest",
12
25
  "lint": "eslint src/**/* --ext .ts"
@@ -19,8 +32,8 @@
19
32
  "author": "Vulog",
20
33
  "license": "MIT",
21
34
  "dependencies": {
22
- "@vulog/aima-client": "1.2.29",
23
- "@vulog/aima-core": "1.2.29"
35
+ "@vulog/aima-client": "1.2.31",
36
+ "@vulog/aima-core": "1.2.31"
24
37
  },
25
38
  "peerDependencies": {
26
39
  "zod": "^3.25.76"
@@ -0,0 +1,88 @@
1
+ import { describe, test, vi, expect, beforeEach } from 'vitest';
2
+ import { Client } from '@vulog/aima-client';
3
+ import { createVehicle, CreateVehicleBody } from './createVehicle';
4
+
5
+ describe('createVehicle', () => {
6
+ const postMock = vi.fn();
7
+ const client = {
8
+ post: postMock,
9
+ clientOptions: {
10
+ fleetId: 'FLEET_ID',
11
+ },
12
+ } as unknown as Client;
13
+
14
+ beforeEach(() => {
15
+ vi.clearAllMocks();
16
+ });
17
+
18
+ const validBody: CreateVehicleBody = {
19
+ vin: '1HGBH41JXMN109186',
20
+ plate: 'AB-123-CD',
21
+ name: 'Test Vehicle',
22
+ model: { id: 1 },
23
+ };
24
+
25
+ test('should create a vehicle with required fields only', async () => {
26
+ const mockResponse = { id: 'vehicle-uuid', ...validBody };
27
+ postMock.mockResolvedValueOnce({ data: mockResponse });
28
+
29
+ const result = await createVehicle(client, validBody);
30
+
31
+ expect(result).toEqual(mockResponse);
32
+ expect(postMock).toHaveBeenCalledWith(
33
+ '/boapi/proxy/vehicle/fleets/FLEET_ID/vehicles',
34
+ validBody
35
+ );
36
+ });
37
+
38
+ test('should create a vehicle with optional fields', async () => {
39
+ const fullBody: CreateVehicleBody = {
40
+ ...validBody,
41
+ vuboxId: 'vubox-123',
42
+ externalId: 'ext-123',
43
+ wakeupProvider: 'provider',
44
+ noBox: true,
45
+ published: true,
46
+ archived: false,
47
+ msisdn: '33600000000',
48
+ iccid: '8933000000000000000',
49
+ imsi: '208000000000000',
50
+ residualValue: 15000,
51
+ };
52
+ const mockResponse = { id: 'vehicle-uuid', ...fullBody };
53
+ postMock.mockResolvedValueOnce({ data: mockResponse });
54
+
55
+ const result = await createVehicle(client, fullBody);
56
+
57
+ expect(result).toEqual(mockResponse);
58
+ expect(postMock).toHaveBeenCalledWith(
59
+ '/boapi/proxy/vehicle/fleets/FLEET_ID/vehicles',
60
+ fullBody
61
+ );
62
+ });
63
+
64
+ test('should throw for missing vin', async () => {
65
+ const body = { ...validBody, vin: '' };
66
+ await expect(createVehicle(client, body)).rejects.toThrow(TypeError);
67
+ });
68
+
69
+ test('should throw for missing plate', async () => {
70
+ const body = { ...validBody, plate: '' };
71
+ await expect(createVehicle(client, body)).rejects.toThrow(TypeError);
72
+ });
73
+
74
+ test('should throw for missing name', async () => {
75
+ const body = { ...validBody, name: '' };
76
+ await expect(createVehicle(client, body)).rejects.toThrow(TypeError);
77
+ });
78
+
79
+ test('should throw for invalid model id', async () => {
80
+ const body = { ...validBody, model: { id: -1 } };
81
+ await expect(createVehicle(client, body)).rejects.toThrow(TypeError);
82
+ });
83
+
84
+ test('should throw for missing model', async () => {
85
+ const body = { vin: 'VIN123', plate: 'AB-123', name: 'Test' } as CreateVehicleBody;
86
+ await expect(createVehicle(client, body)).rejects.toThrow(TypeError);
87
+ });
88
+ });