Skip to content

Commit

Permalink
fix: remove double slash from api urls (#198)
Browse files Browse the repository at this point in the history
  • Loading branch information
EdieLemoine authored Oct 3, 2023
1 parent 304bb80 commit 381f71a
Show file tree
Hide file tree
Showing 32 changed files with 615 additions and 339 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@
"jest": "^29.2.2",
"lint-staged": "^13.0.3",
"mockdate": "^3.0.5",
"node-fetch": "^3.3.2",
"node-gyp": "^9.3.1",
"sass": "^1.55.0",
"sass-loader": "^10.3.1",
Expand Down
4 changes: 3 additions & 1 deletion src/data/locales/nl/config.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import * as CONFIG from '@/data/keys/configKeys';

export const DEFAULT_LOCALE = 'nl-NL';

export const config = {
[CONFIG.LOCALE]: 'nl-NL',
[CONFIG.LOCALE]: DEFAULT_LOCALE,
[CONFIG.ALLOW_MONDAY_DELIVERY]: true,
[CONFIG.SATURDAY_CUTOFF_TIME]: '16:00',
};
17 changes: 3 additions & 14 deletions src/delivery-options/data/carriers/fetchCarrierData.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { METHOD_SEARCH, fetchFromEndpoint } from '@/delivery-options/data/request/fetchFromEndpoint';
import { endpointCarriers } from '../endpoints';
import { fetchFromEndpoint } from '@/delivery-options/data/request/fetchFromEndpoint';
import { formatCarrierResponse } from '@/delivery-options/data/carriers/formatCarrierResponse';

/**
Expand All @@ -9,19 +10,7 @@ import { formatCarrierResponse } from '@/delivery-options/data/carriers/formatCa
* @returns {Promise<MyParcelDeliveryOptions.CarrierData[]>}
*/
export async function fetchCarrierData(carrier = null) {
const params = {};

if (carrier) {
params.carrier = carrier;
}

const data = await fetchFromEndpoint(
'carriers',
{
method: METHOD_SEARCH,
params,
},
);
const data = await fetchFromEndpoint(endpointCarriers, { path: carrier });

return formatCarrierResponse(data);
}
9 changes: 6 additions & 3 deletions src/delivery-options/data/delivery/fetchDeliveryOptions.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import * as CONFIG from '@/data/keys/configKeys';
import { METHOD_SEARCH, fetchFromEndpoint } from '@/delivery-options/data/request/fetchFromEndpoint';
import { ACCEPT_JSON, HEADER_ACCEPT, endpointDeliveryOptions } from '../endpoints';
import { CarrierConfigurationFactory } from '@/data/carriers/carrierConfigurationFactory';
import { configBus } from '@/delivery-options/config/configBus';
import { fetchFromEndpoint } from '@/delivery-options/data/request/fetchFromEndpoint';
import { getRequestParameters } from '@/delivery-options/data/request/getRequestParameters';

/**
Expand Down Expand Up @@ -31,9 +32,11 @@ export function fetchDeliveryOptions(carrier = configBus.currentCarrier, platfor
]);

return fetchFromEndpoint(
'delivery_options',
endpointDeliveryOptions,
{
method: METHOD_SEARCH,
headers: {
[HEADER_ACCEPT]: `${ACCEPT_JSON};version=2.0`,
},
params: {
...carrierAllowsPackageType ? { package_type: configBus.get(CONFIG.PACKAGE_TYPE) } : {},
...getRequestParameters(carrierConfiguration),
Expand Down
30 changes: 30 additions & 0 deletions src/delivery-options/data/endpoints.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
export const METHOD_GET = 'get';

export const ACCEPT_JSON = 'application/json';

export const ENDPOINT_PICKUP_LOCATIONS = 'pickup_locations';
export const ENDPOINT_DELIVERY_OPTIONS = 'delivery_options';
export const ENDPOINT_CARRIERS = 'carriers';

export const HEADER_ACCEPT = 'Accept';
export const HEADER_ACCEPT_LANGUAGE = 'Accept-Language';
export const HEADER_USER_AGENT = 'X-User-Agent';

export const endpointDeliveryOptions = Object.freeze({
endpoint: ENDPOINT_DELIVERY_OPTIONS,
property: 'deliveries',
});

export const endpointPickupLocations = Object.freeze({
endpoint: ENDPOINT_PICKUP_LOCATIONS,
});

export const endpointCarriers = Object.freeze({
endpoint: ENDPOINT_CARRIERS,
});

export const ENDPOINTS = Object.freeze([
endpointDeliveryOptions,
endpointPickupLocations,
endpointCarriers,
]);
6 changes: 3 additions & 3 deletions src/delivery-options/data/pickup/fetchPickupLocations.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { METHOD_SEARCH, fetchFromEndpoint } from '@/delivery-options/data/request/fetchFromEndpoint';
import { AbstractCarrierConfiguration } from '@/data/carriers/abstractCarrierConfiguration';
import { endpointPickupLocations } from '../endpoints';
import { fetchFromEndpoint } from '@/delivery-options/data/request/fetchFromEndpoint';
import { getRequestParameters } from '@/delivery-options/data/request/getRequestParameters';

/**
Expand All @@ -11,9 +12,8 @@ import { getRequestParameters } from '@/delivery-options/data/request/getRequest
*/
export async function fetchPickupLocations(carrierConfiguration, parameters = {}) {
const data = await fetchFromEndpoint(
'pickup_locations',
endpointPickupLocations,
{
method: METHOD_SEARCH,
params: {
...getRequestParameters(carrierConfiguration),
...parameters,
Expand Down
62 changes: 46 additions & 16 deletions src/delivery-options/data/request/fetchFromEndpoint.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,15 @@
import '@myparcel/js-sdk/dist/endpoint/public/carriers';
import '@myparcel/js-sdk/dist/endpoint/public/delivery-options';
import '@myparcel/js-sdk/dist/endpoint/public/pickup-locations';
import Client from '@myparcel/js-sdk/dist/client';
import { ACCEPT_JSON, HEADER_ACCEPT, HEADER_ACCEPT_LANGUAGE, HEADER_USER_AGENT, METHOD_GET } from '../endpoints';
import { DEFAULT_LOCALE } from '../../../data/locales/nl/config';
import { LOCALE } from '@/data/keys/configKeys';
import { configBus } from '@/delivery-options/config/configBus';
import { getApiUrl } from '@/delivery-options/data/request/getApiUrl';
import isEqual from 'lodash-es/isEqual';
import memoize from 'lodash-es/memoize';
import { ERROR_WADDEN_ISLANDS } from '@/config/errorConfig';

export const METHOD_GET = 'get';
export const METHOD_SEARCH = 'search';

const memoizedFetch = memoize(async function fetchFunc(endpoint, options = {}) {
const client = new Client();

client.config.acceptLanguage = configBus ? configBus.get(LOCALE) : 'nl-NL';
client.config.url = getApiUrl();

const memoizedFetch = memoize(async function fetchFunc(definition, options = {}) {
let response = [];

// Set default options and override with given options.
Expand All @@ -26,8 +18,35 @@ const memoizedFetch = memoize(async function fetchFunc(endpoint, options = {}) {
...options,
};

let url = getApiUrl() + definition.endpoint;

if (options.path) {
url += `/${options.path}`;
}

if (options.params) {
const params = new URLSearchParams(options.params);
url += `?${params.toString()}`;
}

try {
response = await client[endpoint][options.method](options.params) || [];
const result = await fetch(url, {
method: options.method,
headers: {
[HEADER_ACCEPT]: ACCEPT_JSON,
...options.headers,
[HEADER_ACCEPT_LANGUAGE]: configBus ? configBus.get(LOCALE) : DEFAULT_LOCALE,
[HEADER_USER_AGENT]: `MyParcelDeliveryOptions/${process.env.VERSION}`,
},
});

const json = await result.json();

if (!result.ok) {
throw json;
}

response = json.data[definition.property ?? definition.endpoint] ?? [];
} catch (e) {
if (!configBus) {
return;
Expand All @@ -38,13 +57,17 @@ const memoizedFetch = memoize(async function fetchFunc(endpoint, options = {}) {
error: e,
};
}
return { response, error: null };

return {
response,
error: null,
};
}, (...args) => JSON.stringify(args));

/**
* Fetch data from an endpoint, handle any errors and return an object containing the response.
*
* @param {string} endpoint - Endpoint to use.
* @param {Object} endpoint - Endpoint definition to use.
*
* @param {Object} options - Options.
* @param {string} options.method? - Method.
Expand All @@ -53,7 +76,10 @@ const memoizedFetch = memoize(async function fetchFunc(endpoint, options = {}) {
* @returns {Promise<{response: Array, errors: Array}>}
*/
export const fetchFromEndpoint = async(endpoint, options = {}) => {
const { response, error } = await memoizedFetch(endpoint, options);
const {
response,
error,
} = await memoizedFetch(endpoint, options);

if (error) {
const { errors } = error;
Expand All @@ -69,7 +95,11 @@ export const fetchFromEndpoint = async(endpoint, options = {}) => {
});
});
} else {
configBus.addError({ type: 'fatal', endpoint, error });
configBus.addError({
type: 'fatal',
endpoint,
error,
});
}
}

Expand Down
36 changes: 0 additions & 36 deletions tests/__mocks__/@myparcel/js-sdk/dist/client.js

This file was deleted.

This file was deleted.

49 changes: 49 additions & 0 deletions tests/jest-setup/mock-fetch.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import {
ENDPOINTS,
ENDPOINT_CARRIERS,
ENDPOINT_DELIVERY_OPTIONS,
ENDPOINT_PICKUP_LOCATIONS,
} from '@/delivery-options/data/endpoints';
import { fakeCarriersResponse } from '../mocks/fakeCarriersResponse';
import { fakeDeliveryOptionsResponse } from '../mocks/fakeDeliveryOptionsResponse';
import { fakePickupLocationsResponse } from '../mocks/fakePickupLocationsResponse';

global.fetch = jest.fn((url) => {
const urlInstance = new URL(url);
const endpoint = urlInstance.pathname.split('/').filter(Boolean)[0];
const params = Object.fromEntries(urlInstance.searchParams.entries());

let response = [];

const matchingEndpoint = ENDPOINTS.find((endpointDefinition) => endpointDefinition.endpoint === endpoint);

switch (endpoint) {
case ENDPOINT_CARRIERS:
response = fakeCarriersResponse(params);
break;

case ENDPOINT_DELIVERY_OPTIONS:
response = fakeDeliveryOptionsResponse(params);
break;

case ENDPOINT_PICKUP_LOCATIONS:
response = fakePickupLocationsResponse(params);
break;

default:
throw new Error(`Unknown endpoint: ${endpoint}`);
}

return Promise.resolve({
ok: true,
status: 200,
statusText: 'OK',
json: () => {
return Promise.resolve({
data: {
[matchingEndpoint?.property ?? matchingEndpoint?.endpoint ?? 'unknown']: response,
},
});
},
});
});
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { createCutoffTimeDate } from '@Tests/helpers/createCutoffTimeDate';
import { createCutoffTimeDate } from '../../helpers/createCutoffTimeDate';

/**
* @param {string} cutoffTime - Timestamp in HH:mm format.
Expand Down
Loading

0 comments on commit 381f71a

Please sign in to comment.