From 1344e85510ceef8644676af89bffa6e78779114c Mon Sep 17 00:00:00 2001 From: "M. Akbar Nugroho" <37355855+thexdev@users.noreply.github.com> Date: Fri, 8 Sep 2023 19:25:21 +0700 Subject: [PATCH 1/2] Merge pull request #10 from thexdev/feature feat(api): add `RetrieveTracking` and `UpdateOrder` command (cherry picked from commit e8135d4cdc4dc0f552fb79c595dd49375b4db3a4) --- src/commands/retrieve-tracking.ts | 7 ++ src/commands/update-order.ts | 7 ++ src/index.ts | 4 + tests/commands/retrieve-tracking.test.ts | 140 +++++++++++++++++++++++ tests/commands/update-order.test.ts | 88 ++++++++++++++ 5 files changed, 246 insertions(+) create mode 100644 src/commands/retrieve-tracking.ts create mode 100644 src/commands/update-order.ts create mode 100644 tests/commands/retrieve-tracking.test.ts create mode 100644 tests/commands/update-order.test.ts diff --git a/src/commands/retrieve-tracking.ts b/src/commands/retrieve-tracking.ts new file mode 100644 index 0000000..8d7503c --- /dev/null +++ b/src/commands/retrieve-tracking.ts @@ -0,0 +1,7 @@ +import Command from './command'; + +export class RetrieveTracking extends Command { + execute(): Promise { + return this.http.get(`v1/trackings/${this.extra.id}`); + } +} diff --git a/src/commands/update-order.ts b/src/commands/update-order.ts new file mode 100644 index 0000000..727b488 --- /dev/null +++ b/src/commands/update-order.ts @@ -0,0 +1,7 @@ +import Command from './command'; + +export class UpdateOrder extends Command { + execute(): Promise { + return this.http.setBody(this.extra).post(`v1/orders/${this.extra.id}`); + } +} diff --git a/src/index.ts b/src/index.ts index d5bfdca..0dcf14a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,7 +3,9 @@ import { CreateOrder } from './commands/create-order'; import { RetrieveArea } from './commands/retrieve-area'; import { RetrieveCourierRates } from './commands/retrieve-courier-rates'; import { RetrieveOrder } from './commands/retrieve-order'; +import { RetrieveTracking } from './commands/retrieve-tracking'; import { SearchRates } from './commands/search-rates'; +import { UpdateOrder } from './commands/update-order'; export { Biteship, @@ -11,5 +13,7 @@ export { RetrieveArea, RetrieveOrder, RetrieveCourierRates, + RetrieveTracking, SearchRates, + UpdateOrder, }; diff --git a/tests/commands/retrieve-tracking.test.ts b/tests/commands/retrieve-tracking.test.ts new file mode 100644 index 0000000..a2340af --- /dev/null +++ b/tests/commands/retrieve-tracking.test.ts @@ -0,0 +1,140 @@ +import Command from '../../src/commands/command'; +import { RetrieveTracking } from '../../src'; +import { rest } from 'msw'; +import { baseUrl } from '../fixtures/base-url'; +import { + invokerWithApiKey, + invokerWithInvalidApiKey, + invokerWithMissingApiKey, +} from '../fixtures/invoker'; +import { server } from '../fixtures/server'; + +describe('retrieve-tracking.ts', () => { + it('should be able to instantiated', async () => { + const command = new RetrieveTracking(); + expect(command).toBeInstanceOf(Command); + }); + + describe('when API_KEY is not provided', () => { + it('should returns authorization failure', async () => { + const payload = { + success: true, + error: 'Authorization failed', + code: 40101001, + }; + + server.use( + rest.get(baseUrl('trackings/1'), (_, res, ctx) => { + return res(ctx.status(401), ctx.json(payload)); + }), + ); + + const command = new RetrieveTracking({ id: 1 }); + + const response = await invokerWithMissingApiKey.send(command); + + expect(response).toEqual(payload); + }); + }); + + describe('when API_KEY is invalid', () => { + it('should return invalid api key warnings', async () => { + const payload = { + success: false, + error: + 'Authentication for your key is failed. Please make sure input the right key or contact info@biteship.com for more information.', + code: 40000001, + }; + + server.use( + rest.get(baseUrl('trackings/1'), (_, res, ctx) => { + return res(ctx.status(400), ctx.json(payload)); + }), + ); + + const command = new RetrieveTracking({ id: 1 }); + + const response = await invokerWithInvalidApiKey.send(command); + + expect(response).toEqual(payload); + }); + }); + + describe('when tracking found', () => { + it('should returns list of current tracking histories', async () => { + const payload = { + success: true, + messsage: 'Successfully get tracking info', + object: 'tracking', + id: '6051861741a37414e6637fab', + waybill_id: '0123082100003094', + courier: { + company: 'jne', + name: null, + phone: null, + }, + origin: { + contact_name: '[INSTANT COURIER] BITESHIP/FIE', + address: + 'JALAN TANJUNG 16 NO.5, RT.8/RW.2, WEST TANJUNG, SOUTH JAKARTA CITY, JAKARTA, IN', + }, + destination: { + contact_name: 'ADITARA MADJID', + address: + 'THE PAKUBUWONO RESIDENCE, JALAN PAKUBUWONO VI, RW.1, GUNUNG, SOUTH JAKARTA CITY', + }, + history: [ + { + note: 'SHIPMENT RECEIVED BY JNE COUNTER OFFICER AT [JAKARTA]', + updated_at: '2021-03-16T18:17:00+07:00', + status: 'dropping_off', + }, + { + note: 'RECEIVED AT SORTING CENTER [JAKARTA]', + updated_at: '2021-03-16T21:15:00+07:00', + status: 'dropping_off', + }, + { + note: 'SHIPMENT FORWARDED TO DESTINATION [JAKARTA , HUB VETERAN BINTARO]', + updated_at: '2021-03-16T23:12:00+07:00', + status: 'dropping_off', + }, + { + note: 'RECEIVED AT INBOUND STATION [JAKARTA , HUB VETERAN BINTARO]', + updated_at: '2021-03-16T23:43:00+07:00', + status: 'dropping_off', + }, + { + note: 'WITH DELIVERY COURIER [JAKARTA , HUB VETERAN BINTARO]', + updated_at: '2021-03-17T09:29:00+07:00', + status: 'dropping_off', + }, + { + note: 'DELIVERED TO [ainul yakin | 17-03-2021 11:15 | JAKARTA ]', + updated_at: '2021-03-17T11:15:00+07:00', + status: 'delivered', + }, + ], + link: '-', + order_id: '6251863341sa3714e6637fab', + status: 'delivered', + }; + + const params = { + id: 1, + }; + + server.use( + rest.get(baseUrl('trackings/1'), (_, res, ctx) => { + return res(ctx.json(payload)); + }), + ); + + const command = new RetrieveTracking(params); + + const response = await invokerWithApiKey.send(command); + + expect(response).toEqual(payload); + }); + }); +}); diff --git a/tests/commands/update-order.test.ts b/tests/commands/update-order.test.ts new file mode 100644 index 0000000..d7e8eab --- /dev/null +++ b/tests/commands/update-order.test.ts @@ -0,0 +1,88 @@ +import Command from '../../src/commands/command'; +import { CreateOrder, UpdateOrder } from '../../src'; +import { rest } from 'msw'; +import { baseUrl } from '../fixtures/base-url'; +import { + invokerWithApiKey, + invokerWithInvalidApiKey, + invokerWithMissingApiKey, +} from '../fixtures/invoker'; +import { server } from '../fixtures/server'; + +describe('update-order.ts', () => { + it('should be able to instantiated', async () => { + const command = new CreateOrder(); + expect(command).toBeInstanceOf(Command); + }); + + describe('when API_KEY is not provided', () => { + it('should returns authorization failure', async () => { + const payload = { + success: true, + error: 'Authorization failed', + code: 40101001, + }; + + server.use( + rest.post(baseUrl('orders/1'), (_, res, ctx) => { + return res(ctx.status(401), ctx.json(payload)); + }), + ); + + const command = new UpdateOrder({ id: 1 }); + + const response = await invokerWithMissingApiKey.send(command); + + expect(response).toEqual(payload); + }); + }); + + describe('when API_KEY is invalid', () => { + it('should return invalid api key warnings', async () => { + const payload = { + success: false, + error: + 'Authentication for your key is failed. Please make sure input the right key or contact info@biteship.com for more information.', + code: 40000001, + }; + + server.use( + rest.post(baseUrl('orders/1'), (_, res, ctx) => { + return res(ctx.status(400), ctx.json(payload)); + }), + ); + + const command = new UpdateOrder({ id: 1 }); + + const response = await invokerWithInvalidApiKey.send(command); + + expect(response).toEqual(payload); + }); + }); + + describe('when order successfully updated', () => { + it('should returns 200 OK', async () => { + const payload = { + success: true, + message: 'Order has been updated', + object: 'order', + }; + + const params = { + origin_address: 'jl sana sini suka', + }; + + server.use( + rest.post(baseUrl('orders'), (_, res, ctx) => { + return res(ctx.json(payload)); + }), + ); + + const command = new CreateOrder(params); + + const response = await invokerWithApiKey.send(command); + + expect(response).toEqual(payload); + }); + }); +}); From d414a18a2d55b7f563ee8412b04cf8bdbfb81204 Mon Sep 17 00:00:00 2001 From: "M. Akbar Nugroho" Date: Fri, 8 Sep 2023 19:34:50 +0700 Subject: [PATCH 2/2] docs(guide): update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index ad9b9ee..87f0a43 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,5 @@ # biteship-nodejs -> 🚧 WORKING IN PROGRESS 🚧 - `@thexdev/biteship-nodejs` is unofficial NodeJS client for interacting with [Biteship API](https://biteship.com/en). Since Biteship does not provide package to interact with their API so, I created this simple wrapper for our convenient. @@ -50,11 +48,13 @@ find it all on Biteship official documentation. ## List of Commands - `CreateOrder` +- `DeleteOrder` - `RetrieveArea` - `RetrieveCourierRates` - `RetrieveOrder` +- `RetrieveTracking` - `SearchRates` -- More commands (soon) +- `UpdateOrder` ## Want to Support Me?