@orchesty/connector-productboard 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/CHANGELOG.md +7 -0
- package/LICENSE +190 -0
- package/coverage/clover.xml +119 -0
- package/coverage/coverage-final.json +6 -0
- package/coverage/lcov-report/base.css +224 -0
- package/coverage/lcov-report/block-navigation.js +87 -0
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +161 -0
- package/coverage/lcov-report/prettify.css +1 -0
- package/coverage/lcov-report/prettify.js +2 -0
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +210 -0
- package/coverage/lcov-report/src/Batch/ProductboardListAllFeaturesBatch.ts.html +301 -0
- package/coverage/lcov-report/src/Batch/ProductboardListAllProductsBatch.ts.html +259 -0
- package/coverage/lcov-report/src/Batch/index.html +131 -0
- package/coverage/lcov-report/src/Connector/ProductboardCreateNewFeatureConnector.ts.html +391 -0
- package/coverage/lcov-report/src/Connector/index.html +116 -0
- package/coverage/lcov-report/src/ProductboardApplication.ts.html +274 -0
- package/coverage/lcov-report/src/index.html +116 -0
- package/coverage/lcov-report/test/dataProvider.ts.html +202 -0
- package/coverage/lcov-report/test/index.html +116 -0
- package/coverage/lcov.info +169 -0
- package/dist/Batch/ProductboardListAllFeaturesBatch.d.ts +38 -0
- package/dist/Batch/ProductboardListAllFeaturesBatch.js +28 -0
- package/dist/Batch/ProductboardListAllProductsBatch.d.ts +24 -0
- package/dist/Batch/ProductboardListAllProductsBatch.js +28 -0
- package/dist/Connector/ProductboardCreateNewFeatureConnector.d.ts +83 -0
- package/dist/Connector/ProductboardCreateNewFeatureConnector.js +23 -0
- package/dist/ProductboardApplication.d.ts +17 -0
- package/dist/ProductboardApplication.js +83 -0
- package/dist/package.json +22 -0
- package/jest.config.js +13 -0
- package/package.json +22 -0
- package/src/Batch/ProductboardListAllFeaturesBatch.ts +72 -0
- package/src/Batch/ProductboardListAllProductsBatch.ts +58 -0
- package/src/Batch/__tests__/Data/ProductboardListAllFeaturesBatch/input.json +6 -0
- package/src/Batch/__tests__/Data/ProductboardListAllFeaturesBatch/mock.json +42 -0
- package/src/Batch/__tests__/Data/ProductboardListAllFeaturesBatch/output.json +11 -0
- package/src/Batch/__tests__/Data/ProductboardListAllProductsBatch/input.json +6 -0
- package/src/Batch/__tests__/Data/ProductboardListAllProductsBatch/mock.json +23 -0
- package/src/Batch/__tests__/Data/ProductboardListAllProductsBatch/output.json +11 -0
- package/src/Batch/__tests__/ProductboardListAllFeaturesBatch.ts +17 -0
- package/src/Batch/__tests__/ProductboardListAllProductsBatch.ts +17 -0
- package/src/Connector/ProductboardCreateNewFeatureConnector.ts +102 -0
- package/src/Connector/__tests__/Data/ProductboardCreateNewFeatureConnector/input.json +28 -0
- package/src/Connector/__tests__/Data/ProductboardCreateNewFeatureConnector/mock.json +35 -0
- package/src/Connector/__tests__/Data/ProductboardCreateNewFeatureConnector/output.json +37 -0
- package/src/Connector/__tests__/ProductboardCreateNewFeatureConnector.ts +17 -0
- package/src/ProductboardApplication.ts +63 -0
- package/test/dataProvider.ts +39 -0
- package/tsconfig.json +8 -0
- package/tsconfig.prod.json +13 -0
- package/tsconfig.prod.tsbuildinfo +1 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import ABatchNode from '@orchesty/nodejs-sdk/dist/lib/Batch/ABatchNode';
|
|
2
|
+
import { HttpMethods } from '@orchesty/nodejs-sdk/dist/lib/Transport/HttpMethods';
|
|
3
|
+
import BatchProcessDto from '@orchesty/nodejs-sdk/dist/lib/Utils/BatchProcessDto';
|
|
4
|
+
import { BASE_URL } from '../ProductboardApplication';
|
|
5
|
+
|
|
6
|
+
export const NAME = 'productboard-list-all-features-batch';
|
|
7
|
+
export default class ProductboardListAllFeaturesBatch extends ABatchNode {
|
|
8
|
+
|
|
9
|
+
public getName(): string {
|
|
10
|
+
return NAME;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
public async processAction(dto: BatchProcessDto): Promise<BatchProcessDto> {
|
|
14
|
+
const appInstall = await this.getApplicationInstallFromProcess(dto);
|
|
15
|
+
const url = dto.getBatchCursor('features?pageLimit=100&pageOffset=0');
|
|
16
|
+
const req = await this.getApplication().getRequestDto(
|
|
17
|
+
dto,
|
|
18
|
+
appInstall,
|
|
19
|
+
HttpMethods.GET,
|
|
20
|
+
url,
|
|
21
|
+
);
|
|
22
|
+
const resp = await this.getSender().send<IResponse>(req, [200]);
|
|
23
|
+
const response = resp.getJsonBody();
|
|
24
|
+
|
|
25
|
+
dto.setItemList(response.data ?? []);
|
|
26
|
+
if (response.links.next) {
|
|
27
|
+
dto.setBatchCursor(response.links.next.replace(`${BASE_URL}/`, ''));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return dto;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
interface IResponse {
|
|
36
|
+
data: IOutput[];
|
|
37
|
+
links: {
|
|
38
|
+
next: string;
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface IOutput {
|
|
43
|
+
id: string;
|
|
44
|
+
name: string;
|
|
45
|
+
description: string;
|
|
46
|
+
type: string;
|
|
47
|
+
archived: boolean;
|
|
48
|
+
status: {
|
|
49
|
+
id: string;
|
|
50
|
+
name: string;
|
|
51
|
+
};
|
|
52
|
+
parent: {
|
|
53
|
+
feature: {
|
|
54
|
+
id: string;
|
|
55
|
+
links: {
|
|
56
|
+
self: string;
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
};
|
|
60
|
+
links: {
|
|
61
|
+
self: string;
|
|
62
|
+
html: string;
|
|
63
|
+
};
|
|
64
|
+
timeframe: {
|
|
65
|
+
startDate: string;
|
|
66
|
+
endDate: string;
|
|
67
|
+
granularity: string;
|
|
68
|
+
};
|
|
69
|
+
owner: {
|
|
70
|
+
email: string;
|
|
71
|
+
};
|
|
72
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import ABatchNode from '@orchesty/nodejs-sdk/dist/lib/Batch/ABatchNode';
|
|
2
|
+
import { HttpMethods } from '@orchesty/nodejs-sdk/dist/lib/Transport/HttpMethods';
|
|
3
|
+
import BatchProcessDto from '@orchesty/nodejs-sdk/dist/lib/Utils/BatchProcessDto';
|
|
4
|
+
import { BASE_URL } from '../ProductboardApplication';
|
|
5
|
+
|
|
6
|
+
export const NAME = 'productboard-list-all-products-batch';
|
|
7
|
+
export default class ProductboardListAllProductsBatch extends ABatchNode {
|
|
8
|
+
|
|
9
|
+
public getName(): string {
|
|
10
|
+
return NAME;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
public async processAction(dto: BatchProcessDto): Promise<BatchProcessDto> {
|
|
14
|
+
const appInstall = await this.getApplicationInstallFromProcess(dto);
|
|
15
|
+
const url = dto.getBatchCursor('products?pageLimit=100&pageOffset=0');
|
|
16
|
+
const req = await this.getApplication().getRequestDto(
|
|
17
|
+
dto,
|
|
18
|
+
appInstall,
|
|
19
|
+
HttpMethods.GET,
|
|
20
|
+
url,
|
|
21
|
+
);
|
|
22
|
+
const resp = await this.getSender().send<IResponse>(req, [200]);
|
|
23
|
+
const response = resp.getJsonBody();
|
|
24
|
+
|
|
25
|
+
dto.setItemList(response.data ?? []);
|
|
26
|
+
if (response.links.next) {
|
|
27
|
+
dto.setBatchCursor(response.links.next.replace(`${BASE_URL}/`, ''));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return dto;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
interface IResponse {
|
|
36
|
+
data: IOutput[];
|
|
37
|
+
links: {
|
|
38
|
+
next: string;
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface IOutput {
|
|
43
|
+
data: {
|
|
44
|
+
id: string;
|
|
45
|
+
name: string;
|
|
46
|
+
description: string;
|
|
47
|
+
owner: {
|
|
48
|
+
email: string;
|
|
49
|
+
};
|
|
50
|
+
links: {
|
|
51
|
+
self: string;
|
|
52
|
+
html: string;
|
|
53
|
+
};
|
|
54
|
+
}[];
|
|
55
|
+
links: {
|
|
56
|
+
next: string;
|
|
57
|
+
};
|
|
58
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"http": "GET https://api.productboard.com/features?pageLimit=100&pageOffset=0",
|
|
3
|
+
"code": 200,
|
|
4
|
+
"body": {
|
|
5
|
+
"data": [
|
|
6
|
+
{
|
|
7
|
+
"id": "00000000-0000-0000-0000-000000000000",
|
|
8
|
+
"name": "Zlack Messaging App",
|
|
9
|
+
"description": "<p>Custom <s>branding</s> for the agent and user portals.</p>",
|
|
10
|
+
"type": "feature",
|
|
11
|
+
"archived": false,
|
|
12
|
+
"status": {
|
|
13
|
+
"id": "00000000-0000-0000-0000-000000000000",
|
|
14
|
+
"name": "In Progress"
|
|
15
|
+
},
|
|
16
|
+
"parent": {
|
|
17
|
+
"feature": {
|
|
18
|
+
"id": "00000000-0000-0000-0000-000000000000",
|
|
19
|
+
"links": {
|
|
20
|
+
"self": "https://api.productboard.com/features/00000000-0000-0000-0000-000000000000"
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"links": {
|
|
25
|
+
"self": "https://api.productboard.com/features/00000000-0000-0000-0000-000000000000",
|
|
26
|
+
"html": "https://space.productboard.com/feature-board/planning/features/00000000-0000-0000-0000-000000000000"
|
|
27
|
+
},
|
|
28
|
+
"timeframe": {
|
|
29
|
+
"startDate": "2021-01-01",
|
|
30
|
+
"endDate": "2021-03-31",
|
|
31
|
+
"granularity": "quarter"
|
|
32
|
+
},
|
|
33
|
+
"owner": {
|
|
34
|
+
"email": "email@example.com"
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
],
|
|
38
|
+
"links": {
|
|
39
|
+
"next": null
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"headers": {
|
|
3
|
+
"user": "TestUser"
|
|
4
|
+
},
|
|
5
|
+
"data": [
|
|
6
|
+
{
|
|
7
|
+
"body": "{\"id\":\"00000000-0000-0000-0000-000000000000\",\"name\":\"Zlack Messaging App\",\"description\":\"<p>Custom <s>branding</s> for the agent and user portals.</p>\",\"type\":\"feature\",\"archived\":false,\"status\":{\"id\":\"00000000-0000-0000-0000-000000000000\",\"name\":\"In Progress\"},\"parent\":{\"feature\":{\"id\":\"00000000-0000-0000-0000-000000000000\",\"links\":{\"self\":\"https://api.productboard.com/features/00000000-0000-0000-0000-000000000000\"}}},\"links\":{\"self\":\"https://api.productboard.com/features/00000000-0000-0000-0000-000000000000\",\"html\":\"https://space.productboard.com/feature-board/planning/features/00000000-0000-0000-0000-000000000000\"},\"timeframe\":{\"startDate\":\"2021-01-01\",\"endDate\":\"2021-03-31\",\"granularity\":\"quarter\"},\"owner\":{\"email\":\"email@example.com\"}}",
|
|
8
|
+
"headers": {}
|
|
9
|
+
}
|
|
10
|
+
]
|
|
11
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"http": "GET https://api.productboard.com/products?pageLimit=100&pageOffset=0",
|
|
3
|
+
"code": 200,
|
|
4
|
+
"body": {
|
|
5
|
+
"data": [
|
|
6
|
+
{
|
|
7
|
+
"id": "00000000-0000-0000-0000-000000000000",
|
|
8
|
+
"name": "Zlack Messaging App",
|
|
9
|
+
"description": "<p>Custom <s>branding</s> for the agent and user portals.</p>",
|
|
10
|
+
"owner": {
|
|
11
|
+
"email": "email@example.com"
|
|
12
|
+
},
|
|
13
|
+
"links": {
|
|
14
|
+
"self": "https://api.productboard.com/products/00000000-0000-0000-0000-000000000000",
|
|
15
|
+
"html": "https://space.productboard.com/feature-board/planning/features/00000000-0000-0000-0000-000000000000"
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
],
|
|
19
|
+
"links": {
|
|
20
|
+
"next": null
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"headers": {
|
|
3
|
+
"user": "TestUser"
|
|
4
|
+
},
|
|
5
|
+
"data": [
|
|
6
|
+
{
|
|
7
|
+
"body": "{\"id\":\"00000000-0000-0000-0000-000000000000\",\"name\":\"Zlack Messaging App\",\"description\":\"<p>Custom <s>branding</s> for the agent and user portals.</p>\",\"owner\":{\"email\":\"email@example.com\"},\"links\":{\"self\":\"https://api.productboard.com/products/00000000-0000-0000-0000-000000000000\",\"html\":\"https://space.productboard.com/feature-board/planning/features/00000000-0000-0000-0000-000000000000\"}}",
|
|
8
|
+
"headers": {}
|
|
9
|
+
}
|
|
10
|
+
]
|
|
11
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { container } from '@orchesty/nodejs-connectors/test/TestAbstract';
|
|
2
|
+
import NodeTester from '@orchesty/nodejs-sdk/dist/test/Testers/NodeTester';
|
|
3
|
+
import init from '../../../test/dataProvider';
|
|
4
|
+
import { NAME as PRODUCTBOARD_LIST_ALL_FEATURES_BATCH } from '../ProductboardListAllFeaturesBatch';
|
|
5
|
+
|
|
6
|
+
let tester: NodeTester;
|
|
7
|
+
|
|
8
|
+
describe('Tests for ProductboardListAllFeaturesBatch', () => {
|
|
9
|
+
beforeEach(() => {
|
|
10
|
+
tester = new NodeTester(container, __filename);
|
|
11
|
+
init();
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it('process - ok', async () => {
|
|
15
|
+
await tester.testBatch(PRODUCTBOARD_LIST_ALL_FEATURES_BATCH);
|
|
16
|
+
});
|
|
17
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { container } from '@orchesty/nodejs-connectors/test/TestAbstract';
|
|
2
|
+
import NodeTester from '@orchesty/nodejs-sdk/dist/test/Testers/NodeTester';
|
|
3
|
+
import init from '../../../test/dataProvider';
|
|
4
|
+
import { NAME as PRODUCTBOARD_LIST_ALL_PRODUCTS_BATCH } from '../ProductboardListAllProductsBatch';
|
|
5
|
+
|
|
6
|
+
let tester: NodeTester;
|
|
7
|
+
|
|
8
|
+
describe('Tests for ProductboardListAllProductsBatch', () => {
|
|
9
|
+
beforeEach(() => {
|
|
10
|
+
tester = new NodeTester(container, __filename);
|
|
11
|
+
init();
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it('process - ok', async () => {
|
|
15
|
+
await tester.testBatch(PRODUCTBOARD_LIST_ALL_PRODUCTS_BATCH);
|
|
16
|
+
});
|
|
17
|
+
});
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import AConnector from '@orchesty/nodejs-sdk/dist/lib/Connector/AConnector';
|
|
2
|
+
import { HttpMethods } from '@orchesty/nodejs-sdk/dist/lib/Transport/HttpMethods';
|
|
3
|
+
import ProcessDto from '@orchesty/nodejs-sdk/dist/lib/Utils/ProcessDto';
|
|
4
|
+
|
|
5
|
+
export const NAME = 'productboard-create-new-feature-connector';
|
|
6
|
+
|
|
7
|
+
export default class ProductboardCreateNewFeatureConnector extends AConnector {
|
|
8
|
+
|
|
9
|
+
public getName(): string {
|
|
10
|
+
return NAME;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
public async processAction(dto: ProcessDto<IInput>): Promise<ProcessDto<IOutput>> {
|
|
14
|
+
const body = dto.getJsonData();
|
|
15
|
+
|
|
16
|
+
const appInstall = await this.getApplicationInstallFromProcess(dto);
|
|
17
|
+
const url = 'features';
|
|
18
|
+
const req = await this.getApplication().getRequestDto(dto, appInstall, HttpMethods.POST, url, body);
|
|
19
|
+
const resp = await this.getSender().send<IOutput>(req, [200]);
|
|
20
|
+
|
|
21
|
+
return dto.setNewJsonData(resp.getJsonBody());
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface IInput {
|
|
27
|
+
data: {
|
|
28
|
+
name: string;
|
|
29
|
+
description: string;
|
|
30
|
+
type: 'feature' | 'subfeature';
|
|
31
|
+
status: {
|
|
32
|
+
id: string;
|
|
33
|
+
name: string;
|
|
34
|
+
};
|
|
35
|
+
parent: {
|
|
36
|
+
feature?: {
|
|
37
|
+
id: string;
|
|
38
|
+
};
|
|
39
|
+
product?: {
|
|
40
|
+
id: string;
|
|
41
|
+
};
|
|
42
|
+
component?: {
|
|
43
|
+
id: string;
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
archived: boolean;
|
|
47
|
+
timeframe: {
|
|
48
|
+
startDate: string;
|
|
49
|
+
endDate: string;
|
|
50
|
+
granularity: string;
|
|
51
|
+
};
|
|
52
|
+
owner?: {
|
|
53
|
+
email: string;
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export interface IOutput {
|
|
59
|
+
data: {
|
|
60
|
+
id: string;
|
|
61
|
+
name: string;
|
|
62
|
+
description: string;
|
|
63
|
+
type: string;
|
|
64
|
+
archived: boolean;
|
|
65
|
+
status: {
|
|
66
|
+
id: string;
|
|
67
|
+
name: string;
|
|
68
|
+
};
|
|
69
|
+
parent: {
|
|
70
|
+
feature?: {
|
|
71
|
+
id: string;
|
|
72
|
+
links: {
|
|
73
|
+
self: string;
|
|
74
|
+
};
|
|
75
|
+
};
|
|
76
|
+
product?: {
|
|
77
|
+
id: string;
|
|
78
|
+
links: {
|
|
79
|
+
self: string;
|
|
80
|
+
};
|
|
81
|
+
};
|
|
82
|
+
component?: {
|
|
83
|
+
id: string;
|
|
84
|
+
links: {
|
|
85
|
+
self: string;
|
|
86
|
+
};
|
|
87
|
+
};
|
|
88
|
+
};
|
|
89
|
+
links: {
|
|
90
|
+
self: string;
|
|
91
|
+
html: string;
|
|
92
|
+
};
|
|
93
|
+
timeframe: {
|
|
94
|
+
startDate: string;
|
|
95
|
+
endDate: string;
|
|
96
|
+
granularity: string;
|
|
97
|
+
};
|
|
98
|
+
owner?: {
|
|
99
|
+
email: string;
|
|
100
|
+
};
|
|
101
|
+
};
|
|
102
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"headers": {
|
|
3
|
+
"user": "TestUser"
|
|
4
|
+
},
|
|
5
|
+
"data": {
|
|
6
|
+
"name": "Custom branding",
|
|
7
|
+
"description": "<p>Custom <s>branding</s> for the agent and user portals.</p>",
|
|
8
|
+
"type": "feature",
|
|
9
|
+
"status": {
|
|
10
|
+
"id": "00000000-0000-0000-0000-000000000000",
|
|
11
|
+
"name": "In Progress"
|
|
12
|
+
},
|
|
13
|
+
"parent": {
|
|
14
|
+
"feature": {
|
|
15
|
+
"id": "00000000-0000-0000-0000-000000000000"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"archived": false,
|
|
19
|
+
"timeframe": {
|
|
20
|
+
"startDate": "2021-01-01",
|
|
21
|
+
"endDate": "2021-03-31",
|
|
22
|
+
"granularity": "quarter"
|
|
23
|
+
},
|
|
24
|
+
"owner": {
|
|
25
|
+
"email": "email@example.com"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"http": "POST https://api.productboard.com/features",
|
|
3
|
+
"code": 200,
|
|
4
|
+
"body": {
|
|
5
|
+
"id": "00000000-0000-0000-0000-000000000000",
|
|
6
|
+
"name": "Zlack Messaging App",
|
|
7
|
+
"description": "<p>Custom <s>branding</s> for the agent and user portals.</p>",
|
|
8
|
+
"type": "feature",
|
|
9
|
+
"archived": false,
|
|
10
|
+
"status": {
|
|
11
|
+
"id": "00000000-0000-0000-0000-000000000000",
|
|
12
|
+
"name": "In Progress"
|
|
13
|
+
},
|
|
14
|
+
"parent": {
|
|
15
|
+
"feature": {
|
|
16
|
+
"id": "00000000-0000-0000-0000-000000000000",
|
|
17
|
+
"links": {
|
|
18
|
+
"self": "https://api.productboard.com/features/00000000-0000-0000-0000-000000000000"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"links": {
|
|
23
|
+
"self": "https://api.productboard.com/features/00000000-0000-0000-0000-000000000000",
|
|
24
|
+
"html": "https://space.productboard.com/feature-board/planning/features/00000000-0000-0000-0000-000000000000"
|
|
25
|
+
},
|
|
26
|
+
"timeframe": {
|
|
27
|
+
"startDate": "2021-01-01",
|
|
28
|
+
"endDate": "2021-03-31",
|
|
29
|
+
"granularity": "quarter"
|
|
30
|
+
},
|
|
31
|
+
"owner": {
|
|
32
|
+
"email": "email@example.com"
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"headers": {
|
|
3
|
+
"user": "TestUser"
|
|
4
|
+
},
|
|
5
|
+
"data": {
|
|
6
|
+
"id": "00000000-0000-0000-0000-000000000000",
|
|
7
|
+
"name": "Zlack Messaging App",
|
|
8
|
+
"description": "<p>Custom <s>branding</s> for the agent and user portals.</p>",
|
|
9
|
+
"type": "feature",
|
|
10
|
+
"archived": false,
|
|
11
|
+
"status": {
|
|
12
|
+
"id": "00000000-0000-0000-0000-000000000000",
|
|
13
|
+
"name": "In Progress"
|
|
14
|
+
},
|
|
15
|
+
"parent": {
|
|
16
|
+
"feature": {
|
|
17
|
+
"id": "00000000-0000-0000-0000-000000000000",
|
|
18
|
+
"links": {
|
|
19
|
+
"self": "https://api.productboard.com/features/00000000-0000-0000-0000-000000000000"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"links": {
|
|
24
|
+
"self": "https://api.productboard.com/features/00000000-0000-0000-0000-000000000000",
|
|
25
|
+
"html": "https://space.productboard.com/feature-board/planning/features/00000000-0000-0000-0000-000000000000"
|
|
26
|
+
},
|
|
27
|
+
"timeframe": {
|
|
28
|
+
"startDate": "2021-01-01",
|
|
29
|
+
"endDate": "2021-03-31",
|
|
30
|
+
"granularity": "quarter"
|
|
31
|
+
},
|
|
32
|
+
"owner": {
|
|
33
|
+
"email": "email@example.com"
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { container } from '@orchesty/nodejs-connectors/test/TestAbstract';
|
|
2
|
+
import NodeTester from '@orchesty/nodejs-sdk/dist/test/Testers/NodeTester';
|
|
3
|
+
import init from '../../../test/dataProvider';
|
|
4
|
+
import { NAME as PRODUCTBOARD_CREATE_NEW_FEATURE_CONNECTOR } from '../ProductboardCreateNewFeatureConnector';
|
|
5
|
+
|
|
6
|
+
let tester: NodeTester;
|
|
7
|
+
|
|
8
|
+
describe('Tests for ProductboardCreateNewFeatureConnector', () => {
|
|
9
|
+
beforeEach(() => {
|
|
10
|
+
tester = new NodeTester(container, __filename);
|
|
11
|
+
init();
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it('process - ok', async () => {
|
|
15
|
+
await tester.testConnector(PRODUCTBOARD_CREATE_NEW_FEATURE_CONNECTOR);
|
|
16
|
+
});
|
|
17
|
+
});
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import CoreFormsEnum, { getFormName } from '@orchesty/nodejs-sdk/dist/lib/Application/Base/CoreFormsEnum';
|
|
2
|
+
import { ApplicationInstall } from '@orchesty/nodejs-sdk/dist/lib/Application/Database/ApplicationInstall';
|
|
3
|
+
import Field from '@orchesty/nodejs-sdk/dist/lib/Application/Model/Form/Field';
|
|
4
|
+
import FieldType from '@orchesty/nodejs-sdk/dist/lib/Application/Model/Form/FieldType';
|
|
5
|
+
import Form from '@orchesty/nodejs-sdk/dist/lib/Application/Model/Form/Form';
|
|
6
|
+
import FormStack from '@orchesty/nodejs-sdk/dist/lib/Application/Model/Form/FormStack';
|
|
7
|
+
import { ABasicApplication } from '@orchesty/nodejs-sdk/dist/lib/Authorization/Type/Basic/ABasicApplication';
|
|
8
|
+
import RequestDto from '@orchesty/nodejs-sdk/dist/lib/Transport/Curl/RequestDto';
|
|
9
|
+
import { HttpMethods } from '@orchesty/nodejs-sdk/dist/lib/Transport/HttpMethods';
|
|
10
|
+
import AProcessDto from '@orchesty/nodejs-sdk/dist/lib/Utils/AProcessDto';
|
|
11
|
+
import { CommonHeaders, JSON_TYPE } from '@orchesty/nodejs-sdk/dist/lib/Utils/Headers';
|
|
12
|
+
|
|
13
|
+
export const NAME = 'productboard';
|
|
14
|
+
export const TOKEN = 'token';
|
|
15
|
+
export const BASE_URL = 'https://api.productboard.com';
|
|
16
|
+
export default class ProductboardApplication extends ABasicApplication {
|
|
17
|
+
|
|
18
|
+
public getName(): string {
|
|
19
|
+
return NAME;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
public getPublicName(): string {
|
|
23
|
+
return 'Productboard';
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
public getDescription(): string {
|
|
27
|
+
return 'Customer-driven product management system that empowers teams to get the right products to market, faster';
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
public getLogo(): string {
|
|
31
|
+
return 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDI1LjAuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IlZyc3R2YV8xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4PSIwcHgiIHk9IjBweCIKCSB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgMTAwIDEwMDsiIHhtbDpzcGFjZT0icHJlc2VydmUiPgo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPgoJLnN0MHtmaWxsOiNGRjI2Mzg7fQoJLnN0MXtmaWxsOiNGRkM2MDA7fQoJLnN0MntmaWxsOiMwMDc5RjI7fQo8L3N0eWxlPgo8Zz4KCTxwb2x5Z29uIGNsYXNzPSJzdDAiIHBvaW50cz0iMzMuMyw1MCA2Ni43LDgyLjggMCw4Mi44IAkiLz4KCTxwb2x5Z29uIGNsYXNzPSJzdDEiIHBvaW50cz0iMCwxNy4yIDMzLjMsNTAgNjYuNywxNy4yIAkiLz4KCTxwb2x5Z29uIGNsYXNzPSJzdDIiIHBvaW50cz0iMzMuMyw1MCA2Ni43LDgyLjggMTAwLDUwIDY2LjcsMTcuMiAJIi8+CjwvZz4KPC9zdmc+Cg==';
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
public getRequestDto(
|
|
35
|
+
dto: AProcessDto,
|
|
36
|
+
applicationInstall: ApplicationInstall,
|
|
37
|
+
method: HttpMethods,
|
|
38
|
+
_url?: string,
|
|
39
|
+
data?: unknown,
|
|
40
|
+
): RequestDto {
|
|
41
|
+
const url = `${BASE_URL}/${_url}`;
|
|
42
|
+
const request = new RequestDto(url ?? '', method, dto);
|
|
43
|
+
request.setHeaders({
|
|
44
|
+
[CommonHeaders.CONTENT_TYPE]: JSON_TYPE,
|
|
45
|
+
[CommonHeaders.ACCEPT]: JSON_TYPE,
|
|
46
|
+
[CommonHeaders.AUTHORIZATION]: `Bearer ${applicationInstall.getSettings()[CoreFormsEnum.AUTHORIZATION_FORM][TOKEN]}`,
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
if (data) {
|
|
50
|
+
request.setJsonBody(data);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return request;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
public getFormStack(): FormStack {
|
|
57
|
+
const form = new Form(CoreFormsEnum.AUTHORIZATION_FORM, getFormName(CoreFormsEnum.AUTHORIZATION_FORM))
|
|
58
|
+
.addField(new Field(FieldType.TEXT, TOKEN, ' Token', undefined, true));
|
|
59
|
+
|
|
60
|
+
return new FormStack().addForm(form);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { appInstall, DEFAULT_ACCESS_TOKEN, DEFAULT_USER } from '@orchesty/nodejs-connectors/test/DataProvider';
|
|
2
|
+
import { container, db, sender } from '@orchesty/nodejs-connectors/test/TestAbstract';
|
|
3
|
+
import CoreFormsEnum from '@orchesty/nodejs-sdk/dist/lib/Application/Base/CoreFormsEnum';
|
|
4
|
+
import { TOKEN } from '@orchesty/nodejs-sdk/dist/lib/Authorization/Type/Basic/ABasicApplication';
|
|
5
|
+
import ProductboardListAllFeaturesBatch from '../src/Batch/ProductboardListAllFeaturesBatch';
|
|
6
|
+
import ProductboardListAllProductsBatch from '../src/Batch/ProductboardListAllProductsBatch';
|
|
7
|
+
import ProductboardCreateNewFeatureConnector
|
|
8
|
+
from '../src/Connector/ProductboardCreateNewFeatureConnector';
|
|
9
|
+
import ProductboardApplication, { NAME as PRODUCTBOARD_APP } from '../src/ProductboardApplication';
|
|
10
|
+
|
|
11
|
+
export default function init(): void {
|
|
12
|
+
appInstall(PRODUCTBOARD_APP, DEFAULT_USER, {
|
|
13
|
+
[CoreFormsEnum.AUTHORIZATION_FORM]: {
|
|
14
|
+
[TOKEN]: DEFAULT_ACCESS_TOKEN,
|
|
15
|
+
},
|
|
16
|
+
});
|
|
17
|
+
const app = new ProductboardApplication();
|
|
18
|
+
container.setApplication(app);
|
|
19
|
+
|
|
20
|
+
const listAllFeatures = new ProductboardListAllFeaturesBatch();
|
|
21
|
+
const listAllProducts = new ProductboardListAllProductsBatch();
|
|
22
|
+
const createNewFeature = new ProductboardCreateNewFeatureConnector();
|
|
23
|
+
|
|
24
|
+
listAllFeatures
|
|
25
|
+
.setSender(sender)
|
|
26
|
+
.setDb(db)
|
|
27
|
+
.setApplication(app);
|
|
28
|
+
container.setBatch(listAllFeatures);
|
|
29
|
+
listAllProducts
|
|
30
|
+
.setSender(sender)
|
|
31
|
+
.setDb(db)
|
|
32
|
+
.setApplication(app);
|
|
33
|
+
container.setBatch(listAllProducts);
|
|
34
|
+
createNewFeature
|
|
35
|
+
.setSender(sender)
|
|
36
|
+
.setDb(db)
|
|
37
|
+
.setApplication(app);
|
|
38
|
+
container.setConnector(createNewFeature);
|
|
39
|
+
}
|
package/tsconfig.json
ADDED