Skip to content

Commit da592de

Browse files
committed
Merge branch 'release/1.2.0'
2 parents 6c0e642 + 6776f86 commit da592de

35 files changed

+6510
-6682
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ dist/
44
node_modules/
55
reports/
66
\.env
7+
\.stryker-tmp

.travis.yml

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,27 +7,37 @@ addons:
77
secure: EHyqb+NjwY29lysfyfyogVYjhnTU2BTx/oLvRjZ15tXcFx2jUj3cfY/97zQYjF8r9laqdBonlryrTAIdOyp4he3cdY4Xll3I14e+biT49bdhyMofSAFQbNuFpxpBNuVcg4sJBfmj5CB1qhcvTTq+oEKNpAjJV3QZfTVcvsE1dNgRWHWOq3mm7G97TGYOF58Rjm601KaBEqXNAMKO1fCp2D6lJ/VA9uGAlhkTWz+7SsdjuxE7FqHFBeIqNyoR8utuh6GVkWnJmaMPlFnZLwmuB3ojz2Y6h5PVINPCnz7ZeLbAldOp5QXJQIL5Rt+ZBhP8bGlZTEzYwp3O/77TkQhgvfkyHXoDMmkweCtKP+fj/NAlcQpa+iiFvalEOVz9CV+21WL3SRqqOZNEpEqaj3zPIlflsFpD79Wk4Zxa44QtmV6AOPVE5JsQfPq2cDhyv2KS4sU3cIjaZOKKXwMJKga7F+eGI/i/kCw9LJqlCNxLHJLI9/c7byn+rUHhu1DN3bz5TmR/K08M9JMGbVUGfpA1vAn0eW58H2qm/Ifi4oF5WaFVpXPvAA36BwOHl7wzSd8uQKyoXc6IQhxAn+awxAgibOImgsyavUN09rAO7+RKwQpqiLpfU68fLhaz+O5PMDe+727Bt6F5ILteL0xp2uyIY+Aau5FIAdTemRin4t4YUGM=
88
language: node_js
99
node_js:
10-
- 8.10.0
10+
- 8.10.0
1111
jdk:
12-
- oraclejdk8
12+
- oraclejdk8
1313
install:
14-
- npm install
14+
- npm install
1515
script:
16-
- npm test
17-
- npm run e2e
16+
- npm test
17+
- npm run e2e
1818
after_success:
19-
- bash .travis/overwrite-sonar-project-version.sh
20-
- sonar-scanner
19+
- if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then bash .travis/overwrite-sonar-project-version.sh; fi
20+
- if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then sonar-scanner; fi
2121
cache:
2222
directories:
23-
- node_modules
24-
- "$HOME/.sonar/cache"
23+
- node_modules
24+
- "$HOME/.sonar/cache"
2525
deploy:
26-
provider: npm
27-
skip_cleanup: true
28-
email:
29-
- "$NPM_EMAIL"
30-
api_key:
31-
- "$NPM_TOKEN"
32-
on:
33-
tags: true
26+
- provider: npm
27+
skip_cleanup: true
28+
email:
29+
- "$NPM_EMAIL"
30+
api_key:
31+
- "$NPM_TOKEN"
32+
tag: develop
33+
on:
34+
branch: develop
35+
- provider: npm
36+
skip_cleanup: true
37+
email:
38+
- "$NPM_EMAIL"
39+
api_key:
40+
- "$NPM_TOKEN"
41+
tag: latest
42+
on:
43+
branch: master

CONTRIBUTING.md

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
# Contributing
2+
Thanks for taking the time to contribute to the ChannelApe SDK project!
3+
4+
The following is a guide for contributing to the project. These are mostly guidelines and not rules. We are open for discussion on changes to this document in a Pull Request.
5+
6+
## Table of contents
7+
- [Just have a question?](#just-have-a-question)
8+
- [Prerequisites](#prerequisites)
9+
- [Getting Started](#getting-started)
10+
- [Building and Testing](#building-and-testing)
11+
- [Reporting a bug](#reporting-a-bug)
12+
- [Suggesting a new feature](#suggesting-a-new-feature)
13+
- [Pull Request Template](#pull-request-template)
14+
- [Style Guide](#style-guide)
15+
- [Update README if applicable](#update-readme-if-applicable)
16+
17+
## Just have a question?
18+
If you have a question please refrain from opening a GitHub issue. We have an official message board with a detailed FAQ and where the community chimes in with helpful advice if you have questions.
19+
- [ChannelApe Community](https://community.channelape.com/)
20+
21+
## Prerequisites
22+
- NPM
23+
24+
## Useful tools
25+
- vscode (This repo contains configuration files that will get you up and running straight away with vscode)
26+
27+
## Getting Started
28+
ChannelApe uses the [gitflow](https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow) workflow for managing our projects. So depending on what you are working on will dictate which branch to start from and merge to.
29+
- Clone the repository locally.
30+
- New Features/Improvements start from the **'develop'** branch.
31+
- Hotfixes start from the **'master'** branch.
32+
- Run ``npm install `` from the root directory of the project.
33+
34+
35+
## Building and Testing
36+
ChannelApe uses different types of tests to verify functionality.
37+
1. **Unit tests** - Automated tests that validate a specific piece of functionality within code. Any new code added by the contributor should be covered.
38+
2. **Integration tests** - End to End tests to validate the logical flow of the program. Cucumber is used to automate the integration tests.
39+
3. **Driver Test** - Tests that actually make calls to external dependencies to validate your code works without having to run it locally. These aren't run during the building of the project.
40+
41+
#### Running all tests
42+
43+
``npm run test``
44+
45+
#### Coverage
46+
The goal is to get line and branch coverage to **100%** on new code.
47+
48+
ChannelApe uses [Mocha](https://mochajs.org/) for running tests and [NYC](https://www.npmjs.com/package/nyc) for simple code coverage.
49+
50+
Additionally ChannelApe uses [Stryker](https://stryker-mutator.io/) for running mutations on unit tests. This ensures that tests are well written. The goal for mutation coverage is equal to or greater than the threshold. The threshold is defined in **stryker.conf.js**. If you are to increase mutation coverage, please update the threshold to reflect the new coverage percentage.
51+
52+
## Reporting a bug
53+
If you find a bug and would like to report it, please follow the guidelines below:
54+
- Verify that a bug for this doesn't already exist [here](https://github.com/ChannelApe/channelape-typescript-sdk/issues).
55+
- If a bug is closed and you find that it is possibly still an issue, open a new one and reference the old one.
56+
- Use a clear descriptive title.
57+
- Describe in detail how to reproduce the issue.
58+
- Examples can help if you have them (especially if you can't reliably reproduce).
59+
- Describe expected behavior and why.
60+
61+
## Suggesting a new feature
62+
If you would like to suggest a new feature, please follow the guidelines below:
63+
- Verify that a feature request doesn't already exist [here](https://github.com/ChannelApe/channelape-typescript-sdk/issues).
64+
- Use a clear descriptive title.
65+
- Describe in detail how the new feature should work.
66+
- Examples can help if you have them.
67+
- Describe expected behavior and why.
68+
69+
## Pull Request Template
70+
All of the following should be filled out as descriptive as possible or the pull request will be denied at the maintainers discretion.
71+
72+
#### Title
73+
Pull requests titles should be meaningful to the context of what you are adding/fixing.
74+
75+
#### Description of Changes
76+
What you are adding/fixing and why.
77+
78+
#### Possible Drawbacks
79+
If there are known caveats or tradeoffs with the code, please note them here and why we should consider this change.
80+
81+
## Style Guide
82+
83+
Please review our style guide. ChannelApe will request changes based on this style guide if needed on Pull Requests. The JavaScript style guide can be found [here](https://channelape.github.io/styleguide/js/javascriptguide.html).
84+
85+
## Update README if applicable
86+
If you make any changes that affect the end user, please update the README.md to reflect this.

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,13 @@ TypeScript and JavaScript SDK for the [ChannelApe REST API](https://docs.channel
1515

1616
The ChannelApe SDK is asynchronous and all functions return promises.
1717

18+
### Using in a browser based app?
19+
20+
Make sure when you install the SDK you install with the *--no-optional* flag
21+
```
22+
npm i channelape-sdk --save --no-optional
23+
```
24+
1825
#### Creating a client
1926

2027
Create a new instance of the ChannelApeClient with your sessionId.
@@ -31,6 +38,8 @@ const channelApeClient = new ChannelApeClient({
3138
* endpoint - Envrionment endpoint you would like to hit. Defaults to https://api.channelape.com
3239
* logLevel - Level of logs you wish to see from the SDK. Defaults to OFF.
3340
* maximumRequestRetryTimeout - Number of milliseconds to keep retrying a request for when an undesired response status code is received. Defaults to 180000 (3 minutes). Cannot be set lower than 2000 (2 seconds).
41+
* minimumRequestRetryRandomDelay - Minimum number of milliseconds to randomly delay by when an undesired response status code is received. Defaults to 1000 (1 second). Cannot be set lower than 1000 (1 second).
42+
* maximumRequestRetryRandomDelay - Maximum number of milliseconds to randomly delay by when an undesired response status code is received. Defaults to 5000 (5 seconds). Cannot be set lower than 2000 (2 seconds).
3443

3544
### Sessions
3645

e2e/ChannelApeClient.spec.ts

Lines changed: 44 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,22 @@ import OrdersQueryRequestByBusinessId from '../src/orders/model/OrdersQueryReque
77
import { LogLevel } from 'channelape-logger';
88

99
describe('ChannelApe Client', () => {
10-
1110
describe('Given valid session ID', () => {
1211
const sessionId = getSessionId();
1312

1413
const channelApeClient = new ChannelApeClient({
1514
sessionId,
16-
logLevel: LogLevel.OFF
15+
logLevel: LogLevel.OFF,
16+
maximumRequestRetryRandomDelay: 2000,
17+
minimumRequestRetryRandomDelay: 1000,
18+
maximumRequestRetryTimeout: 30000
1719
});
1820

1921
describe('And valid action ID for action with error processing status', () => {
2022
context('When retrieving action', () => {
21-
const expectedActionId = 'a85d7463-a2f2-46ae-95a1-549e70ecb2ca';
22-
const actualActionPromise = channelApeClient.actions().get(expectedActionId);
23-
2423
it('Then return action', () => {
24+
const expectedActionId = 'a85d7463-a2f2-46ae-95a1-549e70ecb2ca';
25+
const actualActionPromise = channelApeClient.actions().get(expectedActionId);
2526
return actualActionPromise.then((actualAction) => {
2627
expect(actualAction.action).to.equal('PRODUCT_PULL');
2728
expect(actualAction.businessId).to.equal('4baafa5b-4fbf-404e-9766-8a02ad45c3a4');
@@ -43,10 +44,9 @@ describe('ChannelApe Client', () => {
4344

4445
describe('And valid action ID for action with completed processing status', () => {
4546
context('When retrieving action', () => {
46-
const expectedActionId = '4da63571-a4c5-4774-ae20-4fee24ab98e5';
47-
const actualActionPromise = channelApeClient.actions().get(expectedActionId);
48-
4947
it('Then return action', () => {
48+
const expectedActionId = '4da63571-a4c5-4774-ae20-4fee24ab98e5';
49+
const actualActionPromise = channelApeClient.actions().get(expectedActionId);
5050
return actualActionPromise.then((actualAction) => {
5151
expect(actualAction.action).to.equal('PRODUCT_PUSH');
5252
expect(actualAction.businessId).to.equal('4baafa5b-4fbf-404e-9766-8a02ad45c3a4');
@@ -73,10 +73,9 @@ describe('ChannelApe Client', () => {
7373

7474
describe('And invalid action ID', () => {
7575
context('When retrieving action', () => {
76-
const expectedActionId = '676cb925-b603-4140-a3dd-2af160c257d1';
77-
const actualActionPromise = channelApeClient.actions().get(expectedActionId);
78-
7976
it('Then return 404 status code and action not found error message', () => {
77+
const expectedActionId = '676cb925-b603-4140-a3dd-2af160c257d1';
78+
const actualActionPromise = channelApeClient.actions().get(expectedActionId);
8079
return actualActionPromise.then((actualAction) => {
8180
throw new Error('Expected rejected promise');
8281
}).catch((actualChannelApeError: ChannelApeError) => {
@@ -93,16 +92,15 @@ describe('ChannelApe Client', () => {
9392

9493
describe('And valid channel ID', () => {
9594
context('When retrieving channel', () => {
96-
const expectedChannelId = '9c728601-0286-457d-b0d6-ec19292d4485';
97-
const actualChannelPromise = channelApeClient.channels().get(expectedChannelId);
98-
9995
it('Then return channel', () => {
96+
const expectedChannelId = '9c728601-0286-457d-b0d6-ec19292d4485';
97+
const actualChannelPromise = channelApeClient.channels().get(expectedChannelId);
10098
return actualChannelPromise.then((actualChannel) => {
10199
expect(actualChannel.id).to.equal('9c728601-0286-457d-b0d6-ec19292d4485');
102100
expect(actualChannel.businessId).to.equal('4baafa5b-4fbf-404e-9766-8a02ad45c3a4');
103101
expect(actualChannel.enabled).to.equal(true);
104102
expect(actualChannel.integrationId).to.equal('02df0b31-a071-4791-b9c2-aa01e4fb0ce6');
105-
expect(actualChannel.name).to.equal('Custom Column Export');
103+
expect(actualChannel.name).to.equal('EuropaSports Snacks / Foods');
106104
expect(actualChannel.settings.allowCreate).to.equal(false);
107105
expect(actualChannel.settings.allowRead).to.equal(true);
108106
expect(actualChannel.settings.allowUpdate).to.equal(false);
@@ -130,10 +128,9 @@ describe('ChannelApe Client', () => {
130128

131129
describe('And valid order ID', () => {
132130
context('When retrieving order', () => {
133-
const expectedOrderId = '3bc9120d-b706-49cd-ad81-6445ce77d8ad';
134-
const actualOrderPromise = channelApeClient.orders().get(expectedOrderId);
135-
136131
it('Then return order', () => {
132+
const expectedOrderId = '3bc9120d-b706-49cd-ad81-6445ce77d8ad';
133+
const actualOrderPromise = channelApeClient.orders().get(expectedOrderId);
137134
return actualOrderPromise.then((actualOrder) => {
138135
expect(actualOrder.id).to.equal(expectedOrderId);
139136
expect(actualOrder.businessId).to.equal('4baafa5b-4fbf-404e-9766-8a02ad45c3a4');
@@ -149,52 +146,52 @@ describe('ChannelApe Client', () => {
149146
});
150147

151148
describe('And valid business ID', () => {
152-
context('When retrieving orders', () => {
153-
const expectedBusinessId = '4baafa5b-4fbf-404e-9766-8a02ad45c3a4';
154-
const ordersQueryRequestByBusinessId: OrdersQueryRequestByBusinessId = {
155-
businessId: expectedBusinessId
156-
};
157-
const actualOrdersPromise = channelApeClient.orders().get(ordersQueryRequestByBusinessId);
158-
159-
it('Then return all orders for the business', () => {
160-
return actualOrdersPromise.then((actualOrders) => {
161-
expect(actualOrders).to.be.an('array');
162-
expect(actualOrders.length).to.equal(201);
163-
expect(actualOrders[0].id).to.equal('3bc9120d-b706-49cd-ad81-6445ce77d8ad');
149+
describe('And a startDate of "2018-03-29T17:00:51.000Z" and an endDate of "2018-08-23T12:41:33.000Z"', () => {
150+
context('When retrieving orders', () => {
151+
it('Then return the 228 orders between those dates', () => {
152+
const expectedBusinessId = '4baafa5b-4fbf-404e-9766-8a02ad45c3a4';
153+
const ordersQueryRequestByBusinessId: OrdersQueryRequestByBusinessId = {
154+
businessId: expectedBusinessId,
155+
startDate: new Date('2018-03-29T17:00:51.000Z'),
156+
endDate: new Date('2018-08-23T12:41:33.000Z')
157+
};
158+
const actualOrdersPromise = channelApeClient.orders().get(ordersQueryRequestByBusinessId);
159+
return actualOrdersPromise.then((actualOrders) => {
160+
expect(actualOrders).to.be.an('array');
161+
expect(actualOrders.length).to.equal(228);
162+
expect(actualOrders[0].id).to.equal('dda8a05f-d5dd-4535-9261-b55c501085ef');
163+
});
164164
});
165165
});
166166
});
167167

168-
describe('And query request size of 150 And business has 201 orders', () => {
168+
describe('And query request size of 150 And business has more than 150 orders', () => {
169169
context('When retrieving a single page of orders', () => {
170-
const expectedBusinessId = '4baafa5b-4fbf-404e-9766-8a02ad45c3a4';
171-
const ordersQueryRequestByBusinessId: OrdersQueryRequestByBusinessId = {
172-
businessId: expectedBusinessId,
173-
size: 150
174-
};
175-
const actualOrdersPromise = channelApeClient.orders().getPage(ordersQueryRequestByBusinessId);
176-
177170
it('Then return a single page of 150 orders for the business', () => {
171+
const expectedBusinessId = '4baafa5b-4fbf-404e-9766-8a02ad45c3a4';
172+
const ordersQueryRequestByBusinessId: OrdersQueryRequestByBusinessId = {
173+
businessId: expectedBusinessId,
174+
size: 150
175+
};
176+
const actualOrdersPromise = channelApeClient.orders().getPage(ordersQueryRequestByBusinessId);
178177
return actualOrdersPromise.then((actualOrders) => {
179178
expect(actualOrders.orders).to.be.an('array');
180179
expect(actualOrders.orders.length).to.equal(150);
181-
expect(actualOrders.orders[0].id).to.equal('3bc9120d-b706-49cd-ad81-6445ce77d8ad');
182180
expect(actualOrders.pagination.lastPage).to.equal(false);
183181
});
184182
});
185183
});
186184

187185
describe('And lastKey of "1f557ede-3df5-4335-a64b-cb4181943965"', () => {
188186
context('When retrieving the next single page of orders', () => {
189-
const expectedBusinessId = '4baafa5b-4fbf-404e-9766-8a02ad45c3a4';
190-
const ordersQueryRequestByBusinessId: OrdersQueryRequestByBusinessId = {
191-
businessId: expectedBusinessId,
192-
lastKey: '1f557ede-3df5-4335-a64b-cb4181943965',
193-
size: 150
194-
};
195-
const actualOrdersPromise = channelApeClient.orders().getPage(ordersQueryRequestByBusinessId);
196-
197187
it('Then return the last single page of 51 orders for the business', () => {
188+
const expectedBusinessId = '4baafa5b-4fbf-404e-9766-8a02ad45c3a4';
189+
const ordersQueryRequestByBusinessId: OrdersQueryRequestByBusinessId = {
190+
businessId: expectedBusinessId,
191+
lastKey: '1f557ede-3df5-4335-a64b-cb4181943965',
192+
size: 150
193+
};
194+
const actualOrdersPromise = channelApeClient.orders().getPage(ordersQueryRequestByBusinessId);
198195
return actualOrdersPromise.then((actualOrders) => {
199196
expect(actualOrders.orders).to.be.an('array');
200197
expect(actualOrders.orders.length).to.equal(51);

0 commit comments

Comments
 (0)