diff --git a/src/shipping/estimateShippingLines.ts b/src/shipping/estimateShippingLines.ts new file mode 100644 index 0000000..826ea64 --- /dev/null +++ b/src/shipping/estimateShippingLines.ts @@ -0,0 +1,24 @@ +import { + apiTypeKeys, + apiTypes, + fetchAPI, + getApiOptions, + getApiUrl, + IApiReturnObject, + checkApiResponse, + IEstimateShippingLinesRequest +} from 'src'; + +/** + * + * Retrieve the estimated shipping lines + * + */ +export async function estimateShippingLines(requestBody: IEstimateShippingLinesRequest, numOfRetries = 0): Promise { + const {estimateShippingLines} = apiTypeKeys; + const url = getApiUrl(estimateShippingLines); + const options = getApiOptions(estimateShippingLines, requestBody); + const fetchRes = await fetchAPI(url, options, numOfRetries); + const {keysToTest} = apiTypes.estimateShippingLines; + return checkApiResponse(fetchRes, keysToTest); +} diff --git a/src/shipping/index.ts b/src/shipping/index.ts index 7c21659..f3d5010 100644 --- a/src/shipping/index.ts +++ b/src/shipping/index.ts @@ -1,2 +1,3 @@ export * from './getShippingLines'; +export * from './estimateShippingLines'; export * from './changeShippingLine'; diff --git a/src/taxes/estimateTaxes.ts b/src/taxes/estimateTaxes.ts new file mode 100644 index 0000000..187a05a --- /dev/null +++ b/src/taxes/estimateTaxes.ts @@ -0,0 +1,23 @@ +import { + apiTypeKeys, + fetchAPI, + getApiUrl, + getApiOptions, + IApiReturnObject, + checkApiResponse, + apiTypes, + IEstimateTaxRequest, +} from 'src'; + +/** estimateTaxes + * + * Get the estimated taxes on the order + */ +export async function estimateTaxes(requestBody: IEstimateTaxRequest, numOfRetries = 0): Promise { + const {estimateTaxes} = apiTypeKeys; + const options = getApiOptions(estimateTaxes, requestBody); + const url = getApiUrl(estimateTaxes); + const fetchRes = await fetchAPI(url, options, numOfRetries); + const {keysToTest} = apiTypes.estimateTaxes; + return checkApiResponse(fetchRes, keysToTest); +} diff --git a/src/taxes/index.ts b/src/taxes/index.ts index 97744c5..63a0b46 100644 --- a/src/taxes/index.ts +++ b/src/taxes/index.ts @@ -1 +1,2 @@ +export * from './estimateTaxes'; export * from './setTaxes'; diff --git a/src/types/apiInterfaces.ts b/src/types/apiInterfaces.ts index 5c601cc..8d3bf47 100644 --- a/src/types/apiInterfaces.ts +++ b/src/types/apiInterfaces.ts @@ -295,6 +295,8 @@ export interface IApiTypes { walletPayCreateOrder: IApiTypesDetail, walletPayOnShipping: IApiTypesDetail, walletPayOnApprove: IApiTypesDetail, + estimateShippingLines: IApiTypesDetail, + estimateTaxes: IApiTypesDetail, } export interface IApiTypeKeys { @@ -334,6 +336,8 @@ export interface IApiTypeKeys { walletPayCreateOrder: keyof IApiTypes; walletPayOnShipping: keyof IApiTypes; walletPayOnApprove: keyof IApiTypes; + estimateShippingLines: keyof IApiTypes; + estimateTaxes: keyof IApiTypes; } export interface IValidateAddress { @@ -812,6 +816,9 @@ export type IUpdatePaymentRequest = IAddPaymentRequest; export type IDeletePaymentRequest = IAddPaymentRequest; +export type IEstimateTaxRequest = IAddress; +export type IEstimateShippingLinesRequest = IAddress; + export interface IPatchOrderMetaDataRequest { cart_parameters: ICartParameters | null; note_attributes: ICartParameters | null; @@ -839,6 +846,8 @@ export type IGetApiOptionsBody = IWalletPayOnApproveRequest | IWalletPayCreateOrderRequest | IWalletPayOnShippingRequest | + IEstimateTaxRequest | + IEstimateShippingLinesRequest | Record; export interface IShippingLine { diff --git a/src/variables/constants.ts b/src/variables/constants.ts index 8212d9a..b80dd77 100644 --- a/src/variables/constants.ts +++ b/src/variables/constants.ts @@ -316,6 +316,18 @@ export const apiTypes: IApiTypes = { useJwt: true, keysToTest: [...appStateKeysToTest] }, + estimateTaxes: { + path: '/taxes/estimate', + method: methods.POST, + useJwt: true, + keysToTest: [...appStateKeysToTest] + }, + estimateShippingLines: { + path: '/shipping_lines/estimate', + method: methods.POST, + useJwt: true, + keysToTest: [...appStateKeysToTest] + }, }; export const apiTypeKeys: IApiTypeKeys = { @@ -355,6 +367,8 @@ export const apiTypeKeys: IApiTypeKeys = { walletPayCreateOrder: 'walletPayCreateOrder', walletPayOnShipping: 'walletPayOnShipping', walletPayOnApprove: 'walletPayOnApprove', + estimateShippingLines: 'estimateShippingLines', + estimateTaxes: 'estimateTaxes', }; export const baseReturnObject: IApiReturnObject = { diff --git a/tests/shipping/estimateShippingLine.test.ts b/tests/shipping/estimateShippingLine.test.ts new file mode 100644 index 0000000..5db99fd --- /dev/null +++ b/tests/shipping/estimateShippingLine.test.ts @@ -0,0 +1,69 @@ +import {apiTypeKeys, baseReturnObject, methods, apiTypes, estimateShippingLines} from 'src'; +import {applicationStateMock, selectShippingLineMock, shippingAddressMock} from 'src/variables/mocks'; +import * as fetchAPI from 'src/utils/fetchAPI'; +import * as getApiOptions from 'src/utils/getApiOptions'; +import * as apiUrl from 'src/utils/apiUrl'; +import * as apiResponse from 'src/utils/apiResponse'; + +describe('testing estimate shipping lines api', () => { + const returnObject = {...baseReturnObject}; + const timesWhenCalled = 1; + const apiUrlMock = 'https://api.com/checkout/storefront/123/123/addresses/shipping/estimate'; + const {keysToTest} = apiTypes.estimateShippingLines; + let optionsMock: RequestInit; + let getApiOptionsSpy: jest.SpyInstance; + let getApiUrlSpy: jest.SpyInstance; + let fetchApiSpy: jest.SpyInstance; + let checkApiResponseSpy: jest.SpyInstance; + + beforeEach(() => { + global.Headers = jest.fn().mockReturnValue({ + append: jest.fn(() => null) + }); + optionsMock = {method: methods.POST, headers: new Headers(), body: JSON.stringify({})}; + getApiOptionsSpy = jest.spyOn(getApiOptions, 'getApiOptions').mockReturnValue(optionsMock); + getApiUrlSpy = jest.spyOn(apiUrl, 'getApiUrl').mockReturnValue(apiUrlMock); + fetchApiSpy = jest.spyOn(fetchAPI, 'fetchAPI').mockReturnValue(Promise.resolve(returnObject)); + checkApiResponseSpy = jest.spyOn(apiResponse, 'checkApiResponse').mockReturnValue(returnObject); + returnObject.response = { data: { selected_shipping: selectShippingLineMock, application_state: applicationStateMock }}; + returnObject.success = true; + }); + + afterEach(() => { + jest.restoreAllMocks(); + }); + + test('calling shippingLines', async () => { + const res = await estimateShippingLines(shippingAddressMock); + + expect(getApiOptionsSpy).toHaveBeenCalledTimes(timesWhenCalled); + expect(getApiUrlSpy).toHaveBeenCalledTimes(timesWhenCalled); + expect(fetchApiSpy).toHaveBeenCalledTimes(timesWhenCalled); + expect(checkApiResponseSpy).toHaveBeenCalledTimes(timesWhenCalled); + expect(getApiOptionsSpy).toHaveBeenCalledWith(apiTypeKeys.estimateShippingLines, shippingAddressMock); + expect(getApiUrlSpy).toHaveBeenCalledWith(apiTypeKeys.estimateShippingLines); + expect(fetchApiSpy).toHaveBeenCalledWith(apiUrlMock, optionsMock, 0); + expect(checkApiResponseSpy).toHaveBeenCalledWith(returnObject, keysToTest); + expect(res).toStrictEqual(returnObject); + }); + + test('calling shippingLines w/ success = false', async () => { + const tempReturnObject = {...baseReturnObject}; + + fetchApiSpy.mockReturnValueOnce(Promise.resolve(tempReturnObject)); + checkApiResponseSpy.mockReturnValueOnce(tempReturnObject); + + const res = await estimateShippingLines(shippingAddressMock, 1); + + expect(getApiOptionsSpy).toHaveBeenCalledTimes(timesWhenCalled); + expect(getApiUrlSpy).toHaveBeenCalledTimes(timesWhenCalled); + expect(fetchApiSpy).toHaveBeenCalledTimes(timesWhenCalled); + expect(checkApiResponseSpy).toHaveBeenCalledTimes(timesWhenCalled); + expect(getApiOptionsSpy).toHaveBeenCalledWith(apiTypeKeys.estimateShippingLines, shippingAddressMock); + expect(getApiUrlSpy).toHaveBeenCalledWith(apiTypeKeys.estimateShippingLines); + expect(fetchApiSpy).toHaveBeenCalledWith(apiUrlMock, optionsMock, 1); + expect(checkApiResponseSpy).toHaveBeenCalledWith(tempReturnObject, keysToTest); + expect(res).toStrictEqual(tempReturnObject); + }); + +}); diff --git a/tests/taxes/estimateTaxes.test.ts b/tests/taxes/estimateTaxes.test.ts new file mode 100644 index 0000000..425078f --- /dev/null +++ b/tests/taxes/estimateTaxes.test.ts @@ -0,0 +1,61 @@ +import {apiTypeKeys, baseReturnObject, estimateTaxes, methods} from 'src'; +import * as fetchAPI from 'src/utils/fetchAPI'; +import * as getApiOptions from 'src/utils/getApiOptions'; +import * as apiUrl from 'src/utils/apiUrl'; +import {applicationStateMock, shippingAddressMock, taxesArrayMock} from 'src/variables/mocks'; +import * as apiResponse from 'src/utils/apiResponse'; + +describe('testing estimate taxes api', () => { + const returnObject = {...baseReturnObject}; + const timesWhenCalled = 1; + const apiUrlMock = 'https://api.com/checkout/storefront/123/123/taxes/estimate'; + let optionsMock: RequestInit; + let getApiOptionsSpy: jest.SpyInstance; + let getApiUrlSpy: jest.SpyInstance; + let fetchApiSpy: jest.SpyInstance; + let checkApiResponseSpy: jest.SpyInstance; + + beforeEach(() => { + global.Headers = jest.fn().mockReturnValue({append: jest.fn()}); + optionsMock = {method: methods.POST, headers: new Headers(), body: JSON.stringify({})}; + getApiOptionsSpy = jest.spyOn(getApiOptions, 'getApiOptions').mockReturnValue(optionsMock); + getApiUrlSpy = jest.spyOn(apiUrl, 'getApiUrl').mockReturnValue(apiUrlMock); + fetchApiSpy = jest.spyOn(fetchAPI, 'fetchAPI').mockReturnValue(Promise.resolve(returnObject)); + checkApiResponseSpy = jest.spyOn(apiResponse, 'checkApiResponse').mockReturnValue(returnObject); + returnObject.response = { data: { taxes: taxesArrayMock, application_state: applicationStateMock }}; + returnObject.success = true; + }); + + afterEach(() => { + jest.restoreAllMocks(); + }); + + test('calling setTaxes', async () => { + const res = await estimateTaxes(shippingAddressMock); + + expect(getApiOptionsSpy).toHaveBeenCalledTimes(timesWhenCalled); + expect(getApiUrlSpy).toHaveBeenCalledTimes(timesWhenCalled); + expect(fetchApiSpy).toHaveBeenCalledTimes(timesWhenCalled); + expect(getApiOptionsSpy).toHaveBeenCalledWith(apiTypeKeys.estimateTaxes, shippingAddressMock); + expect(getApiUrlSpy).toHaveBeenCalledWith(apiTypeKeys.estimateTaxes); + expect(fetchApiSpy).toHaveBeenCalledWith(apiUrlMock, optionsMock, 0); + expect(res).toStrictEqual(returnObject); + }); + + test('calling setTaxes w/ success = false', async () => { + const tempReturnObject = {...baseReturnObject}; + checkApiResponseSpy.mockReturnValueOnce(tempReturnObject); + fetchApiSpy.mockReturnValueOnce(Promise.resolve(tempReturnObject)); + + const res = await estimateTaxes(shippingAddressMock, 1); + + expect(getApiOptionsSpy).toHaveBeenCalledTimes(timesWhenCalled); + expect(getApiUrlSpy).toHaveBeenCalledTimes(timesWhenCalled); + expect(fetchApiSpy).toHaveBeenCalledTimes(timesWhenCalled); + expect(getApiOptionsSpy).toHaveBeenCalledWith(apiTypeKeys.estimateTaxes, shippingAddressMock); + expect(getApiUrlSpy).toHaveBeenCalledWith(apiTypeKeys.estimateTaxes); + expect(fetchApiSpy).toHaveBeenCalledWith(apiUrlMock, optionsMock, 1); + expect(res).toStrictEqual(tempReturnObject); + }); +}); +