@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 ADDED
@@ -0,0 +1,2 @@
1
+ INSTANCE="my.daktela.com"
2
+ ACCESS_TOKEN="5f4dcc3b5aa765d61d8327deb882cf99"
package/CHANGELOG.md ADDED
@@ -0,0 +1,2 @@
1
+ # 1.0.0
2
+ Initial Version of the library.
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
+ });