Fixed test, added documentation to store, broke out processing functions for both documentation purposes and to reduce overall size of store file, sorted store actions methods.
This commit is contained in:
parent
33420c6077
commit
46cdd41772
10 changed files with 1842 additions and 1160 deletions
|
|
@ -12,7 +12,8 @@
|
|||
"serve": "vue-cli-service serve",
|
||||
"build": "vue-cli-service build",
|
||||
"test:unit": "vue-cli-service test:unit --coverage --ci",
|
||||
"test:unit:lite": "vue-cli-service test:unit --ci"
|
||||
"test:unit:lite": "vue-cli-service test:unit --ci",
|
||||
"test:pc": "vue-cli-service test:unit site-footer.spec.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^1.4.0",
|
||||
|
|
|
|||
|
|
@ -7,6 +7,15 @@
|
|||
</router-view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// eslint-disable-next-line no-extend-native
|
||||
Array.prototype.safeFilter = (propertyName) => {
|
||||
if (!propertyName) return this;
|
||||
if (!this?.length) return [];
|
||||
return this.map((x) => x[propertyName])
|
||||
.filter((x) => x);
|
||||
};
|
||||
</script>
|
||||
<style lang="scss">
|
||||
@import "./node_modules/bootstrap/scss/bootstrap";
|
||||
@import "@/styles/common-styles.scss";
|
||||
|
|
|
|||
|
|
@ -462,13 +462,16 @@ export default {
|
|||
if (direction === 'future') {
|
||||
// first 0, then 1
|
||||
for (let i = 0; i <= monthsAfterToLoadOffset; i++) {
|
||||
months.push(await this.getMonthData(i, options));
|
||||
months.push(this.getMonthData(i, options));
|
||||
}
|
||||
// See https://eslint.org/docs/latest/rules/no-await-in-loop
|
||||
Promise.all(months);
|
||||
} else if (direction === 'past') {
|
||||
// first 0, then -1
|
||||
for (let i = 0; i >= 0 - monthsBeforeToLoadOffset; i--) {
|
||||
months.unshift(await this.getMonthData(i, options));
|
||||
months.unshift(this.getMonthData(i, options));
|
||||
}
|
||||
Promise.all(months);
|
||||
} else {
|
||||
// TODO - IF A CALENDAR WITH BOTH PAST AND FUTURE WAS EVER NEEDED
|
||||
// for (let i = monthsAfterToLoadOffset; i >= monthsBeforeToLoadOffset; i--) {
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
:text="getRouterLinkDisplayTextFromCopy(copy)"
|
||||
href="javascript:void(0)"
|
||||
useLoadingModal
|
||||
@click-event="navigateWithScenario(getRouterLinkRouteFromCopy(copy))" />
|
||||
@clickEvent="navigateWithScenario(getRouterLinkRouteFromCopy(copy))" />
|
||||
</span>
|
||||
<span v-else-if="doesCopyContainTextLink(copy)">
|
||||
<textLink
|
||||
|
|
@ -19,7 +19,7 @@
|
|||
:text="getRouterLinkDisplayTextFromCopy(copy)"
|
||||
:href="getExternalLink(copy)"
|
||||
:data-bs-target="'#' + getRouterLinkRouteFromCopy(copy)"
|
||||
@click-event="$emit('textLinkClicked', getRouterLinkRouteFromCopy(copy))" />
|
||||
@clickEvent="$emit('textLinkClicked', getRouterLinkRouteFromCopy(copy))" />
|
||||
</span>
|
||||
<span
|
||||
v-else
|
||||
|
|
@ -57,6 +57,7 @@ export default {
|
|||
cmsWidgetName: String,
|
||||
marginTopSizeOverride: Number // override mt-2 with a bootstrap size from 0-5 or auto
|
||||
},
|
||||
emits: ['textLinkClicked'],
|
||||
computed: {
|
||||
pageQueryString() {
|
||||
return applicationConfig.PAGE_QUERYSTRING;
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ export function getDamageString() {
|
|||
const { isRepair } = mainStore.damage;
|
||||
const damageLocations = mainStore.damage.glassToReplace;
|
||||
|
||||
if (isRepair || !damageLocations || !Array.isArray(damageLocations)) {
|
||||
if (isRepair || !damageLocations?.length) {
|
||||
return '';
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,15 @@
|
|||
import { useMainStore } from '@/store';
|
||||
import { updateOrCreateISSCookie } from '@/helpers/cookie-helper';
|
||||
|
||||
/*
|
||||
Encapsulates asynchronous Save Session logic inside a promise to allow for Save Session queuing
|
||||
*/
|
||||
async function saveSessionHelper(store) {
|
||||
const savedSessionInfo = await store.saveSession();
|
||||
store.setSaveSessionInfo(savedSessionInfo.data);
|
||||
updateOrCreateISSCookie();
|
||||
}
|
||||
|
||||
/*
|
||||
Will call API to save existing order, or create new one depending where it's called from.
|
||||
This will also set Referral information in the store after saving, and then
|
||||
|
|
@ -8,8 +17,8 @@ import { updateOrCreateISSCookie } from '@/helpers/cookie-helper';
|
|||
*/
|
||||
export async function saveSession({ shouldAwaitSaveSessionQueue = false }) {
|
||||
const store = useMainStore();
|
||||
var saveSessionPromise = store.applicationUser.saveSessionPromise
|
||||
? store.applicationUser.saveSessionPromise.then(() => { return saveSessionHelper(store); })
|
||||
const saveSessionPromise = store.applicationUser.saveSessionPromise
|
||||
? store.applicationUser.saveSessionPromise.then(() => saveSessionHelper(store))
|
||||
: saveSessionHelper(store);
|
||||
|
||||
store.setSaveSessionPromise(saveSessionPromise);
|
||||
|
|
@ -18,12 +27,3 @@ export async function saveSession({ shouldAwaitSaveSessionQueue = false }) {
|
|||
await saveSessionPromise;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Encapsulates asynchronous Save Session logic inside a promise to allow for Save Session queuing
|
||||
*/
|
||||
async function saveSessionHelper(store) {
|
||||
const savedSessionInfo = await store.saveSession();
|
||||
store.setSaveSessionInfo(savedSessionInfo.data);
|
||||
updateOrCreateISSCookie();
|
||||
}
|
||||
|
|
@ -10,26 +10,24 @@ const mockMixin = {
|
|||
};
|
||||
|
||||
describe('site-footer.vue', () => {
|
||||
// TODO: fix this so that it works correctly (toHaveBeenCalled() <-- )
|
||||
it.skip('Should emit ForwardClicked on button click', async () => {
|
||||
it('Should emit ForwardClicked on button click', async () => {
|
||||
// Act
|
||||
const wrapper = mount(siteFooter, {
|
||||
mixins: [mockMixin]
|
||||
});
|
||||
wrapper.vm.buttonClick();
|
||||
// Assert
|
||||
expect(wrapper.emitted().forwardClicked[0]).toHaveBeenCalled;
|
||||
expect(wrapper.emitted().forwardClicked).toBeTruthy(); // This is how to verify emitted custom events.
|
||||
});
|
||||
|
||||
// TODO: fix this so that it works correctly (toHaveBeenCalled() <--
|
||||
it.skip('Should emit BackClicked on link click', async () => {
|
||||
it('Should emit BackClicked on link click', async () => {
|
||||
// Act
|
||||
const wrapper = mount(siteFooter, {
|
||||
mixins: [mockMixin]
|
||||
});
|
||||
wrapper.vm.linkClick();
|
||||
// Assert
|
||||
expect(wrapper.emitted().backClicked[0]).toHaveBeenCalled;
|
||||
expect(wrapper.emitted().backClicked).toBeTruthy(); // This is how to verify emitted custom events.
|
||||
});
|
||||
|
||||
it('Should change button text when update button text is called', async () => {
|
||||
|
|
|
|||
385
src/store/data-processors.js
Normal file
385
src/store/data-processors.js
Normal file
|
|
@ -0,0 +1,385 @@
|
|||
/* eslint-disable no-plusplus */
|
||||
/* eslint-disable no-param-reassign */
|
||||
import getDateDifferenceInDays from '@/helpers/date-helper';
|
||||
|
||||
if (!Array.prototype.safeFilter) {
|
||||
// eslint-disable-next-line no-extend-native
|
||||
Array.prototype.safeFilter = (propertyName) => {
|
||||
if (!propertyName) return this;
|
||||
if (!this?.length) return [];
|
||||
return this.map((x) => x[propertyName])
|
||||
.filter((x) => x);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @function addPricesToLineItems
|
||||
* @memberof StoreProcessors
|
||||
* @author T-Wrecks Team
|
||||
* @copyright Safelite
|
||||
* @summary
|
||||
* Accepts an array of items and an array of corresponding prices, then
|
||||
* adds the price data to the line items by collating on partNumber.
|
||||
* The added properties are "**laborAmount**", "**sellingPrice**" and "**kitPrice**".
|
||||
* @remarks
|
||||
* This will almost certainly change when Insurance Pricing is live.
|
||||
* @param {Array} lineItems
|
||||
* An array filled with order items (windshield, wipers, raindefense, etc.)
|
||||
* @param {Array} pricingLineItems
|
||||
* An array filled with prices for repair items.
|
||||
* @returns {Array}
|
||||
* The line items array with price data added.
|
||||
* @static
|
||||
*/
|
||||
const addPricesToLineItems = (lineItems, pricingLineItems) => {
|
||||
if (!lineItems) throw new Error('Invalid line items specified.');
|
||||
if (!pricingLineItems) throw new Error('Invalid pricing line items specified.');
|
||||
lineItems.forEach((lineItem) => {
|
||||
const lineItemIndex = pricingLineItems
|
||||
.findIndex((pricingLineItem) => pricingLineItem.partNumber === lineItem.partNumber);
|
||||
|
||||
if (lineItem.childParts) {
|
||||
addPricesToLineItems(lineItem.childParts, pricingLineItems);
|
||||
}
|
||||
|
||||
if (lineItemIndex > -1) {
|
||||
const pricedLineItem = pricingLineItems[lineItemIndex];
|
||||
lineItem.laborAmount = pricedLineItem.laborAmount;
|
||||
lineItem.sellingPrice = pricedLineItem.sellingPrice;
|
||||
lineItem.kitPrice = pricedLineItem.kitPrice;
|
||||
}
|
||||
});
|
||||
return lineItems;
|
||||
};
|
||||
|
||||
/**
|
||||
* @function buildQueryStringParameterFromArrayOfComplexObjects
|
||||
* @memberof StoreProcessors
|
||||
* @author T-Wrecks Team
|
||||
* @copyright Safelite
|
||||
* @summary
|
||||
* Accepts an array of objects and the name of a parameter present on these objects.
|
||||
* Extracts the value of these properties so as to create a query string snippet containing
|
||||
* this data in the format "propertyName[index].[key]=[value]&..."
|
||||
* @param {Array} arrayOfObjects
|
||||
* Array of items containing data to transform into a query string snippet.
|
||||
* @param {string} parameterName
|
||||
* The name of the parameter used to extract data from the "arrayOfObjects".
|
||||
* @returns {string}
|
||||
* A string containing the query string snippet.
|
||||
* @static
|
||||
*/
|
||||
const buildQueryStringParameterFromArrayOfComplexObjects = (arrayOfObjects, parameterName) => {
|
||||
if (!arrayOfObjects) throw new Error('Invalid array of objects specified.');
|
||||
if (!parameterName) throw new Error('Invalid parameter name specified.');
|
||||
let queryStringParameter = '';
|
||||
for (let i = 0; i < arrayOfObjects.length; i++) {
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
for (const [key, value] of Object.entries(arrayOfObjects[i])) {
|
||||
queryStringParameter += `${parameterName}[${i}].${key}=${value}&`;
|
||||
}
|
||||
}
|
||||
// Remove trailing &
|
||||
return queryStringParameter.slice(0, -1);
|
||||
};
|
||||
|
||||
/**
|
||||
* @function convertGlassPieceNamingFromApi
|
||||
* @memberof StoreProcessors
|
||||
* @author T-Wrecks Team
|
||||
* @copyright Safelite
|
||||
* @summary
|
||||
* Accepts an array with glass data properties.
|
||||
* Array is modified such that "glassPiece", "location" and "name" properties are removed (if present) and
|
||||
* location/name data is moved to properties "**glassLocation**" and "**glassName**".
|
||||
* @remarks
|
||||
* This is one of a few functions that deal with glassLocation data.
|
||||
* Modified to be a bit more fault tolerant/flexible.
|
||||
* Essentially the reverse of convertGlassPieceToBackEndCompatibleFormat.
|
||||
* Could potentially refactor all such to be more DRY.
|
||||
* @param {Array} glassArray
|
||||
* An array of glass parts with location and name defined.
|
||||
* @returns {Array}
|
||||
* A modified glass array with data defined on **glassLocation** and **glassName** properties.
|
||||
* @static
|
||||
*/
|
||||
const convertGlassPieceNamingFromApi = (glassArray) => {
|
||||
if (!glassArray) return [];
|
||||
return glassArray.map((glass) => {
|
||||
glass.glassLocation = glass.glassPiece?.location ?? glass.location ?? glass.glassLocation;
|
||||
glass.glassName = glass.glassPiece?.name ?? glass.name ?? glass.glassName;
|
||||
delete glass.glassPiece;
|
||||
delete glass.location;
|
||||
delete glass.name;
|
||||
return glass;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @function convertGlassPieceToBackEndCompatibleFormat
|
||||
* @memberof StoreProcessors
|
||||
* @author T-Wrecks Team
|
||||
* @copyright Safelite
|
||||
* @summary
|
||||
* Accepts an array with glass data properties.
|
||||
* Array is modified such that glassLocation/glassName data is moved to properties "**location**" and "**name**".
|
||||
* @remarks
|
||||
* This is one of a few functions that deal with glassLocation data.
|
||||
* Could potentially be combined with very similar convertResultsForApi
|
||||
* @param {Array} glassPieces
|
||||
* An array of glass parts with glassLocation and glassName defined.
|
||||
* @returns {Array}
|
||||
* A modified glass array with data defined on **location** and **name** properties.
|
||||
* @static
|
||||
*/
|
||||
// There was no meaningful difference between the below and convertGlassPieceNamingForApi
|
||||
const convertGlassPieceToBackEndCompatibleFormat = (glassPieces) => {
|
||||
if (!glassPieces?.length) return [];
|
||||
|
||||
// check if array already converted. (likely when a session has been saved previously and then reloaded)
|
||||
if (glassPieces[0].location !== undefined) {
|
||||
return glassPieces;
|
||||
}
|
||||
|
||||
return glassPieces.map((glassPiece) => ({
|
||||
location: glassPiece.glassLocation,
|
||||
name: glassPiece.glassName
|
||||
}));
|
||||
};
|
||||
|
||||
/**
|
||||
* @function convertResultsForApi
|
||||
* @memberof StoreProcessors
|
||||
* @author T-Wrecks Team
|
||||
* @copyright Safelite
|
||||
* @summary
|
||||
* Accepts a source array and maps to an API friendly format.
|
||||
* Array with "**glassLocation**" is mapped to "**location**", "**glassName**" is mapped to
|
||||
* "**name**", and property "result" is simply copied if present.
|
||||
* @remarks
|
||||
* This is one of a few functions that deal with glassLocation data.
|
||||
* This one also copies result data if present.
|
||||
* Could potentially be refactored with others to be more DRY
|
||||
* @param {Array} resultsArray
|
||||
* Array with glassLocation and glassName properties (often result as well).
|
||||
* @returns {Array}
|
||||
* Array that only has **location**, **name** and **result** properties
|
||||
* @static
|
||||
*/
|
||||
const convertResultsForApi = (resultsArray) => {
|
||||
if (!resultsArray) return [];
|
||||
// check if array already converted.
|
||||
// (likely when a session has been saved previously and then reloaded)
|
||||
if (resultsArray[0].location !== undefined) {
|
||||
return resultsArray;
|
||||
}
|
||||
|
||||
return resultsArray.map((answer) => ({
|
||||
location: answer.glassLocation,
|
||||
name: answer.glassName,
|
||||
result: answer.result
|
||||
}));
|
||||
};
|
||||
|
||||
/**
|
||||
* @function getFlattenedArrayOfLineItemsWithChildParts
|
||||
* @memberof StoreProcessors
|
||||
* @author T-Wrecks Team
|
||||
* @copyright Safelite
|
||||
* @summary
|
||||
* Accepts a source array of line item data.
|
||||
* Flattens array in regard to childPart line items.
|
||||
* @param {Array} lineItems
|
||||
* Array with line items and potentially childParts to be flattened.
|
||||
* @returns {Array}
|
||||
* Flattened line item array.
|
||||
* @static
|
||||
*/
|
||||
const getFlattenedArrayOfLineItemsWithChildParts = (lineItems) => {
|
||||
let flattenedArray = [];
|
||||
lineItems?.forEach((lineItem) => {
|
||||
flattenedArray.push(lineItem);
|
||||
if (lineItem.childParts) {
|
||||
flattenedArray = [
|
||||
...flattenedArray,
|
||||
...getFlattenedArrayOfLineItemsWithChildParts(lineItem.childParts)
|
||||
];
|
||||
}
|
||||
});
|
||||
return flattenedArray;
|
||||
};
|
||||
|
||||
/**
|
||||
* @function getHasRecalibrationPart
|
||||
* @memberof StoreProcessors
|
||||
* @author T-Wrecks Team
|
||||
* @copyright Safelite
|
||||
* @summary
|
||||
* Examines the store.order.lineItems state for a requiresRecalibration portion.
|
||||
* If present, examines the state -> order -> lineItems -> glassParts state for a
|
||||
* **recalibrationType** section.
|
||||
* If present, checks that the first element is defined.
|
||||
* @param {object} state
|
||||
* The store state having a valid store -> order -> lineItems section.
|
||||
* @returns {boolean}
|
||||
* True if recalibration part is present in state, false otherwise.
|
||||
* @static
|
||||
*/
|
||||
const getHasRecalibrationPart = (state) => {
|
||||
// eslint-disable-next-line max-len
|
||||
const hasRequiresRecalibration = state.order.lineItems.glassParts.safeFilter('requiresRecalibration')?.length > 0;
|
||||
// eslint-disable-next-line max-len
|
||||
const hasRecalibrationType = state.order.lineItems.glassParts.safeFilter('recalibrationType')?.length > 0;
|
||||
|
||||
if (hasRequiresRecalibration) {
|
||||
if (hasRecalibrationType) {
|
||||
// Has both 'requiresRecalibration' and 'recalibrationType' and 'recalibrationType'
|
||||
return (
|
||||
state.order.lineItems.glassParts.safeFilter('recalibrationType')[0].toLowerCase() !== 'unknown'
|
||||
);
|
||||
}
|
||||
// Has 'requiresRecalibration' but no 'recalibrationType' at all
|
||||
return true;
|
||||
}
|
||||
// Does not have 'requiresRecalibration'
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @function getLineItemQueryStringForPricing
|
||||
* @memberof StoreProcessors
|
||||
* @summary
|
||||
* Accepts an array of line items with "partNumber" properties and converts this
|
||||
* information to a query string snippet acceptable to the pricing endpoint.
|
||||
* Currently the endpoint requires the inclusion of an index.
|
||||
* However it appears that the actual index number is irrelevant.
|
||||
* @remarks
|
||||
* Please note that if the index number became relevant this method
|
||||
* would have a BUG in that it potentially calls itself recursively without
|
||||
* passing the current index. Thus child parts restart the index.
|
||||
* However, this isn't a huge concern as Insurance Pricing won't be using this
|
||||
* and it will go away completely.
|
||||
* @param {Array} lineItems
|
||||
* An array of line items to be priced.
|
||||
* @returns {string}
|
||||
* A query string text snippet containing part number data to be priced.
|
||||
* @static
|
||||
*/
|
||||
const getLineItemQueryStringForPricing = (lineItems) => lineItems
|
||||
.map((lineItem, index) => {
|
||||
let queryStringSnippet = `&LineItems[${index}].partNumber=${lineItem.partNumber}`;
|
||||
if (lineItem.childParts) {
|
||||
queryStringSnippet += getLineItemQueryStringForPricing(lineItem.childParts);
|
||||
}
|
||||
return queryStringSnippet;
|
||||
})
|
||||
.join('');
|
||||
|
||||
/**
|
||||
* @function getTimeSlotsAdditionalEventData
|
||||
* @memberof StoreProcessors
|
||||
* @summary
|
||||
* Converts provided parameters into comma delimited key/value pairs specifying data with state magic number keys.
|
||||
* @param {Array} provisionalTriggers
|
||||
* Array that is converted to comma delimited data point.
|
||||
* @param {string} zipCode
|
||||
* Service location zip code
|
||||
* @param {string} firstAvailableAppointmentDateString
|
||||
* The first available appointment date, used to determine
|
||||
* the number of days until that date.
|
||||
* @param {string} shopAppointmentType
|
||||
* Value included in return data points if present.
|
||||
* @returns {string}
|
||||
* A string containing comma delimited data points.
|
||||
* @static
|
||||
*/
|
||||
const getTimeSlotsAdditionalEventData = (
|
||||
provisionalTriggers,
|
||||
zipCode,
|
||||
firstAvailableAppointmentDateString,
|
||||
shopAppointmentType
|
||||
) => {
|
||||
let numberOfDays = null;
|
||||
if (firstAvailableAppointmentDateString) numberOfDays = getDateDifferenceInDays(new Date(), firstAvailableAppointmentDateString);
|
||||
|
||||
return (shopAppointmentType)
|
||||
// eslint-disable-next-line max-len
|
||||
? `FirstAvailableAppointment:${numberOfDays},Zip:${zipCode},ShopAppointmentType:${shopAppointmentType},ProvisionalTriggers:${provisionalTriggers.join(',')}`
|
||||
: `FirstAvailableAppointment:${numberOfDays},Zip:${zipCode},ProvisionalTriggers:${provisionalTriggers.join(',')}`;
|
||||
};
|
||||
|
||||
/**
|
||||
* @function providersEqual
|
||||
* @memberof StoreProcessors
|
||||
* @summary
|
||||
* Tests equality of addy/number properties on two provider objects.
|
||||
* @remarks
|
||||
* TODO: Change back to deepEqual once zipCodeCtu is added to saveSession.
|
||||
* @param {Array} providerA
|
||||
* First Provider object to compare for equality
|
||||
* @param {string} providerB
|
||||
* Second Provider object to compare for equality
|
||||
* @returns {boolean}
|
||||
* True if provider objects have equal addy/number properties, false otherwise.
|
||||
* @static
|
||||
*/
|
||||
const providersEqual = (providerA, providerB) =>
|
||||
(
|
||||
providerA.providerNumber === providerB.providerNumber
|
||||
&& providerA.address?.city === providerB.address?.city
|
||||
&& providerA.address?.state === providerB.address?.state
|
||||
&& providerA.address?.streetAddress === providerB.address?.streetAddress
|
||||
&& providerA.address?.zipCode === providerB.address?.zipCode
|
||||
);
|
||||
|
||||
/**
|
||||
* @function provisionalTriggersToString
|
||||
* @memberof StoreProcessors
|
||||
* @summary
|
||||
* Converts provided array to comma delimited string with key prepended.
|
||||
* @remarks
|
||||
* @param {Array} provisionalTriggers
|
||||
* Array of items to include in result.
|
||||
* @returns {string}
|
||||
* Returns string with key name and parameter array converted to comma delimited string.
|
||||
* @static
|
||||
*/
|
||||
const provisionalTriggersToString = (provisionalTriggers) => `ProvisionalTriggers:${provisionalTriggers.join(',')}`;
|
||||
|
||||
/**
|
||||
* @module StoreProcessors
|
||||
* @endpoint
|
||||
* @property {StoreProcessors.addPricesToLineItems} addPricesToLineItems
|
||||
* See method for details.
|
||||
* @property {StoreProcessors.buildQueryStringParameterFromArrayOfComplexObjects} buildQueryStringParameterFromArrayOfComplexObjects
|
||||
* See method for details.
|
||||
* @property {StoreProcessors.convertGlassPieceNamingFromApi} convertGlassPieceNamingFromApi
|
||||
* See method for details.
|
||||
* @property {StoreProcessors.convertResultsForApi} convertResultsForApi
|
||||
* See method for details.
|
||||
* @property {StoreProcessors.getAllPartNumbers} getAllPartNumbers
|
||||
* See method for details.
|
||||
* @property {StoreProcessors.getHasRecalibrationPart} getHasRecalibrationPart
|
||||
* See method for details.
|
||||
* @property {StoreProcessors.getLineItemQueryStringForPricing} getLineItemQueryStringForPricing
|
||||
* See method for details.
|
||||
* @property {StoreProcessors.getTimeSlotsAdditionalEventData} getTimeSlotsAdditionalEventData
|
||||
* See method for details.
|
||||
* @static
|
||||
* @default
|
||||
*/
|
||||
const StoreProcessors = {
|
||||
addPricesToLineItems,
|
||||
buildQueryStringParameterFromArrayOfComplexObjects,
|
||||
convertGlassPieceNamingFromApi,
|
||||
convertGlassPieceToBackEndCompatibleFormat,
|
||||
convertResultsForApi,
|
||||
getFlattenedArrayOfLineItemsWithChildParts,
|
||||
getHasRecalibrationPart,
|
||||
getLineItemQueryStringForPricing,
|
||||
getTimeSlotsAdditionalEventData,
|
||||
providersEqual,
|
||||
provisionalTriggersToString
|
||||
};
|
||||
|
||||
export default StoreProcessors;
|
||||
2557
src/store/index.js
2557
src/store/index.js
File diff suppressed because it is too large
Load diff
|
|
@ -898,7 +898,7 @@ describe('Store', () => {
|
|||
store.damage.glassToReplace = [
|
||||
{ glassLocation: location1, glassName: name1 },
|
||||
{ glassLocation: location2, glassName: name2 }
|
||||
],
|
||||
];
|
||||
globalMethods.callHttpClient = jest.fn().mockReturnValue(Promise.resolve({}));
|
||||
|
||||
// Act
|
||||
|
|
|
|||
Loading…
Reference in a new issue