@daktela/daktela-connector 1.0.0
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/.env.example +2 -0
- package/CHANGELOG.md +2 -0
- package/README.md +71 -0
- package/package.json +29 -0
- package/src/index.js +316 -0
- package/test/test.js +217 -0
package/.env.example
ADDED
package/CHANGELOG.md
ADDED
package/README.md
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Daktela V6 JavaScript Connector
|
|
2
|
+
|
|
3
|
+
Daktela V6 JavaScript Connector is a library that connects your JavaScript application and your Daktela instance through REST API.
|
|
4
|
+
Complete documentation of Daktela API is available on following link: https://customer.daktela.com/apihelp/v6/global/general-information.
|
|
5
|
+
|
|
6
|
+
## Setup
|
|
7
|
+
|
|
8
|
+
The connector requires following prerequisites:
|
|
9
|
+
|
|
10
|
+
* Instance URL (e.g. my.daktela.com).
|
|
11
|
+
* Access token to access protected Daktela API endpoints.
|
|
12
|
+
|
|
13
|
+
The only dependency of this library is HTTP client `Axios` (https://axios-http.com/).
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
`DaktelaConnector` is a class that allows you to send CRUD requests on your Daktela server.
|
|
18
|
+
Beside `instance` and `accessToken` you can pass `options` object with following parameters:
|
|
19
|
+
|
|
20
|
+
* `cookieAuth` (boolean) - whether authorize requests via Cookie header or via query parameters. Default value is authorization via cookies.
|
|
21
|
+
* `userAgent` (string) - HTTP User-Agent header.
|
|
22
|
+
* `timeout` {number} - requests' timeout. Default value is `0` (no timeout).
|
|
23
|
+
|
|
24
|
+
Once `DaktelaConnector` is initalized you can call HTTP GET, POST, PUT and DELETE requests via provided methods.
|
|
25
|
+
|
|
26
|
+
Response is an instance of `DaktelaResponse` which contains:
|
|
27
|
+
|
|
28
|
+
* `status` (number) - status code of a HTTP request.
|
|
29
|
+
* `data` (object or array) - returned data.
|
|
30
|
+
* `total` (number) - total number of rows (in case of GET reponse contains multiple objects).
|
|
31
|
+
|
|
32
|
+
An request may throw `DaktelaError`. The class contains originally thrown error as well as `status` code and `apiError` returned by Daktela API.
|
|
33
|
+
|
|
34
|
+
In `options` argument of HTTP GET method `get` you can specify optional arguments of the Daktela API like `fields`, `sort`, `pagination`, `filters` or `filter`.
|
|
35
|
+
To build `sort`, `pagination` or `filters` use functions `Sort`, `Pagination`, `FilterSimple` predefined by the library.
|
|
36
|
+
|
|
37
|
+
Other way is to directly pass Axios's `params` argument which overrides Daktela API parameters and is available in all methods (`get`, `post`, `put`, `delete`).
|
|
38
|
+
|
|
39
|
+
## Example
|
|
40
|
+
|
|
41
|
+
```js
|
|
42
|
+
require('dotenv').config();
|
|
43
|
+
const Daktela = require('daktela-connector');
|
|
44
|
+
let daktela = new Daktela.DaktelaConnector(process.env.INSTANCE, process.env.ACCESS_TOKEN);
|
|
45
|
+
|
|
46
|
+
//...
|
|
47
|
+
|
|
48
|
+
// login request
|
|
49
|
+
try {
|
|
50
|
+
const r = await daktela.post('login', {
|
|
51
|
+
username: 'user_1',
|
|
52
|
+
password: 'password_1',
|
|
53
|
+
});
|
|
54
|
+
console.log(r.data);
|
|
55
|
+
} catch (e) {
|
|
56
|
+
console.log(e);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// filter tickets
|
|
60
|
+
try {
|
|
61
|
+
const r = await daktela.get('tickets', {
|
|
62
|
+
pagination: Daktela.Pagination(3),
|
|
63
|
+
fields: ['name', 'title', 'category', 'user'],
|
|
64
|
+
sort: Daktela.Sort('edited', Daktela.SortDescending),
|
|
65
|
+
filters: [Daktela.FilterSimple('stage', 'eq', 'OPEN')]
|
|
66
|
+
});
|
|
67
|
+
console.log(r.data);
|
|
68
|
+
} catch (e) {
|
|
69
|
+
console.log(e);
|
|
70
|
+
}
|
|
71
|
+
```
|
package/package.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@daktela/daktela-connector",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Daktela's JavaScript SDK",
|
|
5
|
+
"main": "src/index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"test": "jest"
|
|
8
|
+
},
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/Daktela/daktela-v6-js-connector.git"
|
|
12
|
+
},
|
|
13
|
+
"author": "Martin Sach",
|
|
14
|
+
"license": "Apache-2.0",
|
|
15
|
+
"bugs": {
|
|
16
|
+
"url": "https://github.com/Daktela/daktela-v6-js-connector/issues"
|
|
17
|
+
},
|
|
18
|
+
"homepage": "https://github.com/Daktela/daktela-v6-js-connector#readme",
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"axios": "^1.6.3"
|
|
21
|
+
},
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"dotenv": "^16.3.1",
|
|
24
|
+
"jest": "^29.7.0"
|
|
25
|
+
},
|
|
26
|
+
"directories": {
|
|
27
|
+
"test": "test"
|
|
28
|
+
}
|
|
29
|
+
}
|
package/src/index.js
ADDED
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
const axios = require('axios');
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Default number of rows to be returned.
|
|
5
|
+
*/
|
|
6
|
+
const PaginationTake = 100;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Default number of rows to be skipped.
|
|
10
|
+
*/
|
|
11
|
+
const PaginationSkip = 0;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Asceding direction of sorting.
|
|
15
|
+
*/
|
|
16
|
+
const SortAscending = 'asc';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Descending direcion of sorting.
|
|
20
|
+
*/
|
|
21
|
+
const SortDescending = 'desc';
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Logical AND of Daktela filter.
|
|
25
|
+
*/
|
|
26
|
+
const FilterLogicAnd = 'and';
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Logical OR of Daktela filter.
|
|
30
|
+
*/
|
|
31
|
+
const FilterLogicOr = 'or';
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Build Daktela's pagination object.
|
|
35
|
+
*
|
|
36
|
+
* @param {number} [take=PaginationTake] Number of rows to be returned.
|
|
37
|
+
* @param {number} [skip=PaginationSkip] Number of rows to be skipped.
|
|
38
|
+
* @return {Object}
|
|
39
|
+
*/
|
|
40
|
+
const Pagination = function (take = PaginationTake, skip = PaginationSkip) {
|
|
41
|
+
return {
|
|
42
|
+
take: take,
|
|
43
|
+
skip: skip
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Builds Daktela's Sort object.
|
|
49
|
+
*
|
|
50
|
+
* @param {string} field Name of field to sort rows by.
|
|
51
|
+
* @param {string} dir Direction of sorting (allowed values are 'asc' or 'desc'). Defined constants are @see SortAscending and @see SortDescending.
|
|
52
|
+
* @return {Object}
|
|
53
|
+
*/
|
|
54
|
+
const Sort = function (field, dir) {
|
|
55
|
+
return {
|
|
56
|
+
field: field,
|
|
57
|
+
dir: dir
|
|
58
|
+
};
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Builds Daktela's simple filter.
|
|
63
|
+
*
|
|
64
|
+
* @param {string} field Name of the field.
|
|
65
|
+
* @param {string} operator Operator of the filter.
|
|
66
|
+
* @param {string} value Value use for filtering.
|
|
67
|
+
* @return {Object}
|
|
68
|
+
*/
|
|
69
|
+
const FilterSimple = function (field, operator, value) {
|
|
70
|
+
return {
|
|
71
|
+
field: field,
|
|
72
|
+
operator: operator,
|
|
73
|
+
value: value
|
|
74
|
+
};
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* A class representing Daktela response.
|
|
79
|
+
*
|
|
80
|
+
* @property {number} status Status code of the request.
|
|
81
|
+
* @property {Object|Array} data Returned data (can be object or array).
|
|
82
|
+
* @property {number|undefined} total Total number of rows.
|
|
83
|
+
*/
|
|
84
|
+
class DaktelaResponse {
|
|
85
|
+
/**
|
|
86
|
+
* @param {axios.AxiosResponse} response
|
|
87
|
+
*/
|
|
88
|
+
constructor(response) {
|
|
89
|
+
var body = response.data;
|
|
90
|
+
this.status = response.status;
|
|
91
|
+
const result = body.result ?? null;
|
|
92
|
+
this.data = result;
|
|
93
|
+
if (result !== null && Array.isArray(result.data)) {
|
|
94
|
+
this.data = result.data;
|
|
95
|
+
}
|
|
96
|
+
if (result !== null && result.total !== null) {
|
|
97
|
+
this.total = result.total;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* A class representing Daktela error.
|
|
104
|
+
*
|
|
105
|
+
* @property {number|undefined} status Status code of the request.
|
|
106
|
+
* @property {Object|undefined} apiError Error returned by Daktela API.
|
|
107
|
+
*/
|
|
108
|
+
class DaktelaError extends Error {
|
|
109
|
+
/**
|
|
110
|
+
* @param {Error} prevError Original error thrown during request.
|
|
111
|
+
*/
|
|
112
|
+
constructor(prevError) {
|
|
113
|
+
super(prevError.message);
|
|
114
|
+
this.name = 'DaktelaError';
|
|
115
|
+
this.prevError = prevError;
|
|
116
|
+
this.status = null;
|
|
117
|
+
this.apiError = null;
|
|
118
|
+
if (prevError.response) {
|
|
119
|
+
this.status = prevError.response.status;
|
|
120
|
+
if (prevError.response.data.error) {
|
|
121
|
+
this.apiError = prevError.response.data.error;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Daktela connector. Use its HTTP methods (get, post, put, delete) to send requests to Daktela API.
|
|
129
|
+
*
|
|
130
|
+
* @param {string} url Target Daktela instance (e. g. my.daktela.com).
|
|
131
|
+
* @param {string} [accessToken=null] Access token.
|
|
132
|
+
* @param {Object} [options={}] Options of the connector. See below.
|
|
133
|
+
* @param {boolean} options.cookieAuth Authorize requests via Cookie header. Default value is true. Otherwise access token will be passed as query parameter.
|
|
134
|
+
* @param {string} options.userAgent User agent header.
|
|
135
|
+
* @param {number} options.timeout Specifies the number of milliseconds before the request times out. Default is 0 (no timout)
|
|
136
|
+
*/
|
|
137
|
+
const DaktelaConnector = function DaktelaConnector(url, accessToken = null, options = {}) {
|
|
138
|
+
if (!url.startsWith('https://')) {
|
|
139
|
+
url = 'https://' + url;
|
|
140
|
+
}
|
|
141
|
+
if (!url.endsWith('/')) {
|
|
142
|
+
url += '/';
|
|
143
|
+
}
|
|
144
|
+
this.cookieAuth = options.cookieAuth ?? true;
|
|
145
|
+
var headers = {};
|
|
146
|
+
if (this.cookieAuth && accessToken != null) {
|
|
147
|
+
headers['Cookie'] = 'c_user=' + accessToken;
|
|
148
|
+
}
|
|
149
|
+
if (options.userAgent !== null) {
|
|
150
|
+
headers['User-Agent'] = options.userAgent;
|
|
151
|
+
}
|
|
152
|
+
this.api = axios.create({
|
|
153
|
+
baseURL: url + 'api/v6/',
|
|
154
|
+
headers: headers,
|
|
155
|
+
timeout: Number.isInteger(options.timeout) && options.timeout >= 0 ? options.timeout : 0
|
|
156
|
+
});
|
|
157
|
+
this.accessToken = accessToken;
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Checks whether given item is an object or not.
|
|
162
|
+
*
|
|
163
|
+
* @param {any} item
|
|
164
|
+
* @return {boolean}
|
|
165
|
+
*/
|
|
166
|
+
function isObject(item) {
|
|
167
|
+
return (typeof item === 'object' && !Array.isArray(item) && item !== null);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Builds Axios' `config` parameter.
|
|
172
|
+
*
|
|
173
|
+
* @param {Object|null} options Options of the request.
|
|
174
|
+
* @return {Object}
|
|
175
|
+
*/
|
|
176
|
+
DaktelaConnector.prototype.buildRequestParams = function (options) {
|
|
177
|
+
let params = {};
|
|
178
|
+
if (isObject(options)) {
|
|
179
|
+
if (isObject(options.params)) {
|
|
180
|
+
params = options.params;
|
|
181
|
+
} else {
|
|
182
|
+
params = {};
|
|
183
|
+
if (Array.isArray(options.fields)) {
|
|
184
|
+
params.fields = options.fields;
|
|
185
|
+
}
|
|
186
|
+
if (Array.isArray(options.sort) || isObject(options.sort)) {
|
|
187
|
+
params.sort = options.sort;
|
|
188
|
+
}
|
|
189
|
+
if (isObject(options.pagination)) {
|
|
190
|
+
params.take = options.pagination.take ?? PaginationTake;
|
|
191
|
+
params.skip = options.pagination.skip ?? PaginationSkip;
|
|
192
|
+
}
|
|
193
|
+
if (Array.isArray(options.filters)) {
|
|
194
|
+
params.filter = {
|
|
195
|
+
logic: FilterLogicAnd,
|
|
196
|
+
filters: options.filters
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
if (isObject(options.filter)) {
|
|
200
|
+
if (isObject(params.filter)) {
|
|
201
|
+
params.filter.filters.push(options.filter);
|
|
202
|
+
} else {
|
|
203
|
+
params.filter = options.filter;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
if (!this.cookieAuth && this.accessToken !== null) {
|
|
209
|
+
params.accessToken = this.accessToken;
|
|
210
|
+
}
|
|
211
|
+
return {
|
|
212
|
+
params: params
|
|
213
|
+
};
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
*
|
|
218
|
+
* @param {Object|null} options
|
|
219
|
+
* @return
|
|
220
|
+
*/
|
|
221
|
+
DaktelaConnector.prototype.enrichWithAccessToken = function (params) {
|
|
222
|
+
return this.buildRequestParams({
|
|
223
|
+
params: params
|
|
224
|
+
});
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* HTTP GET method.
|
|
229
|
+
*
|
|
230
|
+
* @param {string} endpoint Target endpoint (e.g. 'activities' or 'activities/activity_xxx').
|
|
231
|
+
* @param {Object} [options=null] Options of the request. See below.
|
|
232
|
+
* @param {Object} options.params Params of the Axios library. Useful to directly pass query params to the request. This value overrides all other options (i.e.: pagination, filter, sort).
|
|
233
|
+
* @param {Array<string>} options.fields List of fields to be returned in response.
|
|
234
|
+
* @param {Array<Object>|Object} options.sort List of Daktela's sorts. Use @function Sort to build single sort.
|
|
235
|
+
* @param {Object} options.pagination Pagination of the request. Use @function Pagination to build Daktela pagignation.
|
|
236
|
+
* @param {Array<Object>} options.filters List of simple filters (i.e. filters merged by AND condition). Use @see SimpleFilter to build simple Daktela filter. You can combine list of simple filters and custom filter object in one request.
|
|
237
|
+
* @param {Object} options.filter Object containing custom filter. You can combine list of simple filters and custom filter object in one request.
|
|
238
|
+
* @throws {DaktelaError}
|
|
239
|
+
* @return {Promise<DaktelaResponse>}
|
|
240
|
+
*/
|
|
241
|
+
DaktelaConnector.prototype.get = async function (endpoint, options = null) {
|
|
242
|
+
try {
|
|
243
|
+
const response = await this.api.get(endpoint, this.buildRequestParams(options));
|
|
244
|
+
return new DaktelaResponse(response);
|
|
245
|
+
} catch (error) {
|
|
246
|
+
throw new DaktelaError(error);
|
|
247
|
+
}
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* HTTP POST method.
|
|
252
|
+
*
|
|
253
|
+
* @param {string} endpoint Target endpoint (e.g. 'activities' or 'tickets').
|
|
254
|
+
* @param {Object} payload Data payload of the request.
|
|
255
|
+
* @param {Object} [params=null] Params of the Axios library. Useful to directly pass query params to the request.
|
|
256
|
+
* @throws {DaktelaError}
|
|
257
|
+
* @return {Promise<DaktelaResponse>}
|
|
258
|
+
*/
|
|
259
|
+
DaktelaConnector.prototype.post = async function (endpoint, payload, params = null) {
|
|
260
|
+
try {
|
|
261
|
+
const response = await this.api.post(endpoint, payload, this.enrichWithAccessToken(params));
|
|
262
|
+
return new DaktelaResponse(response);
|
|
263
|
+
} catch (error) {
|
|
264
|
+
throw new DaktelaError(error);
|
|
265
|
+
}
|
|
266
|
+
};
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* HTTP PUT method.
|
|
270
|
+
*
|
|
271
|
+
* @param {string} endpoint Target endpoint (e.g. 'activities/activity_xxx' or 'tickets/123').
|
|
272
|
+
* @param {Object} payload Data payload of the request.
|
|
273
|
+
* @param {Object} [params=null] Params of the Axios library. Useful to directly pass query params to the request.
|
|
274
|
+
* @throws {DaktelaError}
|
|
275
|
+
* @return {Promise<DaktelaResponse>}
|
|
276
|
+
*/
|
|
277
|
+
DaktelaConnector.prototype.put = async function (endpoint, payload, params = null) {
|
|
278
|
+
try {
|
|
279
|
+
const response = await this.api.put(endpoint, payload, this.enrichWithAccessToken(params));
|
|
280
|
+
return new DaktelaResponse(response);
|
|
281
|
+
} catch (error) {
|
|
282
|
+
throw new DaktelaError(error);
|
|
283
|
+
}
|
|
284
|
+
};
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* HTTP DELETE method.
|
|
288
|
+
*
|
|
289
|
+
* @param {string} endpoint Target endpoint (e.g. 'activities/activity_xxx' or 'tickets/123').
|
|
290
|
+
* @param {Object} [params=null] Params of the Axios library. Useful to directly pass query params to the request.
|
|
291
|
+
* @throws {DaktelaError}
|
|
292
|
+
* @return {Promise<DaktelaResponse>}
|
|
293
|
+
*/
|
|
294
|
+
DaktelaConnector.prototype.delete = async function (endpoint, params = null) {
|
|
295
|
+
try {
|
|
296
|
+
const response = await this.api.delete(endpoint, this.enrichWithAccessToken(params));
|
|
297
|
+
return new DaktelaResponse(response);
|
|
298
|
+
} catch (error) {
|
|
299
|
+
throw new DaktelaError(error);
|
|
300
|
+
}
|
|
301
|
+
};
|
|
302
|
+
|
|
303
|
+
module.exports = {
|
|
304
|
+
DaktelaConnector,
|
|
305
|
+
DaktelaResponse,
|
|
306
|
+
DaktelaError,
|
|
307
|
+
PaginationTake,
|
|
308
|
+
PaginationSkip,
|
|
309
|
+
Pagination,
|
|
310
|
+
SortAscending,
|
|
311
|
+
SortDescending,
|
|
312
|
+
Sort,
|
|
313
|
+
FilterLogicAnd,
|
|
314
|
+
FilterLogicOr,
|
|
315
|
+
FilterSimple
|
|
316
|
+
};
|
package/test/test.js
ADDED
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
require('dotenv').config();
|
|
2
|
+
const Daktela = require('daktela-connector');
|
|
3
|
+
const daktela = new Daktela.DaktelaConnector(process.env.INSTANCE, process.env.ACCESS_TOKEN);
|
|
4
|
+
const currentDateTime = Date.now();
|
|
5
|
+
|
|
6
|
+
test('Pagination test', () => {
|
|
7
|
+
let pagination = Daktela.Pagination();
|
|
8
|
+
expect(pagination.take).toBe(Daktela.PaginationTake);
|
|
9
|
+
expect(pagination.skip).toBe(Daktela.PaginationSkip);
|
|
10
|
+
|
|
11
|
+
let take = 321;
|
|
12
|
+
pagination = Daktela.Pagination(take);
|
|
13
|
+
expect(pagination.take).toBe(take);
|
|
14
|
+
expect(pagination.skip).toBe(Daktela.PaginationSkip);
|
|
15
|
+
|
|
16
|
+
take = 567;
|
|
17
|
+
skip = 250;
|
|
18
|
+
pagination = Daktela.Pagination(take, skip);
|
|
19
|
+
|
|
20
|
+
expect(pagination.take).toBe(take);
|
|
21
|
+
expect(pagination.skip).toBe(skip);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
test('Sort test', () => {
|
|
25
|
+
const field = 'field_xxx';
|
|
26
|
+
let sort = Daktela.Sort(field, Daktela.SortAscending);
|
|
27
|
+
|
|
28
|
+
expect(sort.field).toBe(field);
|
|
29
|
+
expect(sort.dir).toBe(Daktela.SortAscending);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
test('Filter test', () => {
|
|
33
|
+
const field = 'field_yyy';
|
|
34
|
+
const operator = 'neq';
|
|
35
|
+
const value = 'test_zzz';
|
|
36
|
+
let filter = Daktela.FilterSimple(field, operator, value);
|
|
37
|
+
|
|
38
|
+
expect(filter.field).toBe(field);
|
|
39
|
+
expect(filter.operator).toBe(operator);
|
|
40
|
+
expect(filter.value).toBe(value);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
test('Build params test', () => {
|
|
44
|
+
const fields = ['a', 'b'];
|
|
45
|
+
const take = 50;
|
|
46
|
+
let options = {
|
|
47
|
+
params: {
|
|
48
|
+
xxx: 'yyy'
|
|
49
|
+
},
|
|
50
|
+
fields: fields,
|
|
51
|
+
sort: [
|
|
52
|
+
Daktela.Sort('edited', Daktela.SortDescending),
|
|
53
|
+
Daktela.Sort('title', Daktela.SortAscending)
|
|
54
|
+
],
|
|
55
|
+
pagination: Daktela.Pagination(take)
|
|
56
|
+
};
|
|
57
|
+
let params = daktela.buildRequestParams(options);
|
|
58
|
+
expect(params.params.xxx).toBe('yyy');
|
|
59
|
+
expect(params.params.fields).toBe(undefined);
|
|
60
|
+
expect(params.params.accessToken).toBe(undefined);
|
|
61
|
+
|
|
62
|
+
options.params = undefined;
|
|
63
|
+
params = daktela.buildRequestParams(options);
|
|
64
|
+
expect(params.params.fields).toBe(fields);
|
|
65
|
+
expect(params.params.sort.length).toBe(2);
|
|
66
|
+
expect(params.params.sort[0].field).toBe('edited');
|
|
67
|
+
expect(params.params.sort[0].dir).toBe('desc');
|
|
68
|
+
expect(params.params.sort[1].field).toBe('title');
|
|
69
|
+
expect(params.params.sort[1].dir).toBe('asc');
|
|
70
|
+
expect(params.params.take).toBe(take);
|
|
71
|
+
expect(params.params.skip).toBe(Daktela.PaginationSkip);
|
|
72
|
+
|
|
73
|
+
const filters = [
|
|
74
|
+
Daktela.FilterSimple('firstname', 'eq', 'John'),
|
|
75
|
+
Daktela.FilterSimple('lastname', 'neq', 'Doe')
|
|
76
|
+
];
|
|
77
|
+
options = {
|
|
78
|
+
filters: filters
|
|
79
|
+
};
|
|
80
|
+
params = daktela.buildRequestParams(options);
|
|
81
|
+
expect(params.params.filter.logic).toBe(Daktela.FilterLogicAnd);
|
|
82
|
+
expect(params.params.filter.filters.length).toBe(2);
|
|
83
|
+
expect(params.params.filter.filters[0].field).toBe('firstname');
|
|
84
|
+
expect(params.params.filter.filters[0].operator).toBe('eq');
|
|
85
|
+
expect(params.params.filter.filters[0].value).toBe('John');
|
|
86
|
+
expect(params.params.filter.filters[1].field).toBe('lastname');
|
|
87
|
+
expect(params.params.filter.filters[1].operator).toBe('neq');
|
|
88
|
+
expect(params.params.filter.filters[1].value).toBe('Doe');
|
|
89
|
+
|
|
90
|
+
const filter = {
|
|
91
|
+
logic: Daktela.FilterLogicOr,
|
|
92
|
+
filters: [
|
|
93
|
+
Daktela.FilterSimple('edited', 'lte', '2023-12-31')
|
|
94
|
+
]
|
|
95
|
+
};
|
|
96
|
+
options = {
|
|
97
|
+
filter: filter
|
|
98
|
+
};
|
|
99
|
+
params = daktela.buildRequestParams(options);
|
|
100
|
+
expect(params.params.filter.logic).toBe(Daktela.FilterLogicOr);
|
|
101
|
+
expect(params.params.filter.filters.length).toBe(1);
|
|
102
|
+
expect(params.params.filter.filters[0].field).toBe('edited');
|
|
103
|
+
expect(params.params.filter.filters[0].operator).toBe('lte');
|
|
104
|
+
expect(params.params.filter.filters[0].value).toBe('2023-12-31');
|
|
105
|
+
|
|
106
|
+
options = {
|
|
107
|
+
filters: filters,
|
|
108
|
+
filter: filter
|
|
109
|
+
};
|
|
110
|
+
params = daktela.buildRequestParams(options);
|
|
111
|
+
expect(params.params.filter.logic).toBe(Daktela.FilterLogicAnd);
|
|
112
|
+
expect(params.params.filter.filters.length).toBe(3);
|
|
113
|
+
expect(params.params.filter.filters[0].field).toBe('firstname');
|
|
114
|
+
expect(params.params.filter.filters[0].operator).toBe('eq');
|
|
115
|
+
expect(params.params.filter.filters[0].value).toBe('John');
|
|
116
|
+
expect(params.params.filter.filters[1].field).toBe('lastname');
|
|
117
|
+
expect(params.params.filter.filters[1].operator).toBe('neq');
|
|
118
|
+
expect(params.params.filter.filters[1].value).toBe('Doe');
|
|
119
|
+
expect(params.params.filter.filters[2].logic).toBe(Daktela.FilterLogicOr);
|
|
120
|
+
expect(params.params.filter.filters[2].filters.length).toBe(1);
|
|
121
|
+
expect(params.params.filter.filters[2].filters[0].field).toBe('edited');
|
|
122
|
+
expect(params.params.filter.filters[2].filters[0].operator).toBe('lte');
|
|
123
|
+
expect(params.params.filter.filters[2].filters[0].value).toBe('2023-12-31');
|
|
124
|
+
|
|
125
|
+
const daktela2 = new Daktela.DaktelaConnector(process.env.INSTANCE, process.env.ACCESS_TOKEN, {
|
|
126
|
+
cookieAuth: false
|
|
127
|
+
});
|
|
128
|
+
params = daktela2.buildRequestParams({sort: Daktela.Sort('created', Daktela.SortAscending)});
|
|
129
|
+
expect(params.params.accessToken).toBe(process.env.ACCESS_TOKEN);
|
|
130
|
+
expect(params.params.sort.field).toBe('created');
|
|
131
|
+
expect(params.params.sort.dir).toBe(Daktela.SortAscending);
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
test('Initial request test', async () => {
|
|
135
|
+
const daktela2 = new Daktela.DaktelaConnector(process.env.INSTANCE);
|
|
136
|
+
const r = await daktela2.get('whoim');
|
|
137
|
+
expect(r.status).toBe(200);
|
|
138
|
+
expect(r.total).toBe(undefined);
|
|
139
|
+
expect(r.data.version).not.toBe(null);
|
|
140
|
+
expect(r.data.user).not.toBe(undefined);
|
|
141
|
+
expect(r.data.user).toBe(null);
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
test('Access token test', async () => {
|
|
145
|
+
const r = await daktela.get('whoim');
|
|
146
|
+
expect(r.status).toBe(200);
|
|
147
|
+
expect(r.data.user).not.toBe(null);
|
|
148
|
+
expect(r.data.user._sys.accessToken).toBe(process.env.ACCESS_TOKEN);
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
test('Exception test', async () => {
|
|
152
|
+
expect(daktela.get('xxx')).rejects.toThrow(Daktela.DaktelaError);
|
|
153
|
+
expect(daktela.get('tickets/xxx')).rejects.toThrow(Daktela.DaktelaError);
|
|
154
|
+
expect(daktela.post('login', {
|
|
155
|
+
'username': 'xyz',
|
|
156
|
+
'password': '-123'
|
|
157
|
+
})).rejects.toThrow(Daktela.DaktelaError);
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
describe('CRUD test', () => {
|
|
161
|
+
const name = 'name_' + currentDateTime;
|
|
162
|
+
const title = 'title_' + currentDateTime;
|
|
163
|
+
|
|
164
|
+
test('POST request test', async () => {
|
|
165
|
+
const r = await daktela.post('statuses', {
|
|
166
|
+
name: name,
|
|
167
|
+
title: title
|
|
168
|
+
});
|
|
169
|
+
expect(r.status).toBe(201);
|
|
170
|
+
expect(r.data.name).toBe(name);
|
|
171
|
+
expect(r.data.title).toBe(title);
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
test('GET request test', async () => {
|
|
175
|
+
const r = await daktela.get('statuses/' + name);
|
|
176
|
+
expect(r.status).toBe(200);
|
|
177
|
+
expect(r.data.title).toBe(title);
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
test('GET all request test', async () => {
|
|
181
|
+
const r = await daktela.get('statuses', {
|
|
182
|
+
filters: [Daktela.FilterSimple('name', 'eq', name)]
|
|
183
|
+
});
|
|
184
|
+
expect(r.status).toBe(200);
|
|
185
|
+
expect(r.total).toBe(1);
|
|
186
|
+
expect(r.data[0].name).toBe(name);
|
|
187
|
+
expect(r.data[0].title).toBe(title);
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
test('PUT request test', async () => {
|
|
191
|
+
const description = 'test XXX';
|
|
192
|
+
const r = await daktela.put('statuses/' + name, {
|
|
193
|
+
description: description
|
|
194
|
+
});
|
|
195
|
+
expect(r.status).toBe(200);
|
|
196
|
+
expect(r.data.name).toBe(name);
|
|
197
|
+
expect(r.data.description).toBe(description);
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
test('DELETE request test', async () => {
|
|
201
|
+
const r = await daktela.delete('statuses/' + name);
|
|
202
|
+
expect(r.status).toBe(204);
|
|
203
|
+
expect(r.data).toBe(null);
|
|
204
|
+
});
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
test('Filter tickets from README', async () => {
|
|
208
|
+
const take = 3;
|
|
209
|
+
const r = await daktela.get('tickets', {
|
|
210
|
+
pagination: Daktela.Pagination(take),
|
|
211
|
+
fields: ['name', 'title', 'category', 'user'],
|
|
212
|
+
sort: Daktela.Sort('edited', Daktela.SortDescending),
|
|
213
|
+
filters: [Daktela.FilterSimple('stage', 'eq', 'OPEN')]
|
|
214
|
+
});
|
|
215
|
+
expect(r.status).toBe(200);
|
|
216
|
+
expect(r.data.length).toBe(take);
|
|
217
|
+
});
|