Added EventBus to create new alert events
This commit is contained in:
parent
bca83d4783
commit
652eed2585
6 changed files with 241 additions and 7 deletions
|
|
@ -18,6 +18,8 @@
|
|||
<script>
|
||||
import menuModal from "@/common-components/site-header/menu-modal/menu-modal";
|
||||
import alert from "@/ux-components/alert/alert";
|
||||
import eventBus from "@/helpers/event-bus/event-bus";
|
||||
import { globalEvents } from "@/constants/events";
|
||||
|
||||
export default({
|
||||
name: "siteHeader",
|
||||
|
|
@ -45,6 +47,18 @@ import alert from "@/ux-components/alert/alert";
|
|||
return this.getCmsContent(this.cmsWidgetName, "AltText")
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
// Check if alert event is on the bus
|
||||
const alertEvent = eventBus.readAndPopEventFromBus(
|
||||
globalEvents.Categories.GLOBAL_ALERT,
|
||||
globalEvents.SubCategories.PAGE_NOT_FOUND
|
||||
);
|
||||
// If alert event is on the bus, then display the alert
|
||||
if (alertEvent !== undefined) {
|
||||
this.displayGlobalAlert = true;
|
||||
this.globalAlertMessage = alertEvent;
|
||||
}
|
||||
},
|
||||
components: {
|
||||
menuModal,
|
||||
alert
|
||||
|
|
|
|||
17
src/constants/events.js
Normal file
17
src/constants/events.js
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
const globalEvents = {
|
||||
Categories: {
|
||||
GLOBAL_ALERT: "GLOBAL_ALERT",
|
||||
},
|
||||
SubCategories: {
|
||||
PAGE_NOT_FOUND: "PAGE_NOT_FOUND",
|
||||
},
|
||||
};
|
||||
|
||||
const globalEventTypes = {
|
||||
Success: "alert-success",
|
||||
Warning: "alert-warning",
|
||||
Info: "alert-info",
|
||||
Danger: "alert-danger",
|
||||
};
|
||||
|
||||
export { globalEvents, globalEventTypes };
|
||||
36
src/helpers/event-bus/event-bus.js
Normal file
36
src/helpers/event-bus/event-bus.js
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
import { useMainStore } from '@/store';
|
||||
|
||||
export default {
|
||||
// Adds event to the bus given its category, subcategory, and eventValue;
|
||||
addEventToBus(category, subCategory, eventValue) {
|
||||
|
||||
useMainStore().addEventToBus( {
|
||||
category: category,
|
||||
subCategory: subCategory,
|
||||
eventValue: eventValue,
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
// Finds event on the bus, removes the item, and returns its value to the caller.
|
||||
readAndPopEventFromBus(category, subCategory) {
|
||||
|
||||
const event = useMainStore().eventBusItem(category, subCategory);
|
||||
|
||||
if(event) {
|
||||
useMainStore().removeEventFromBus( {
|
||||
category: category,
|
||||
subCategory: subCategory,
|
||||
});
|
||||
}
|
||||
|
||||
return event;
|
||||
},
|
||||
|
||||
// Finds the event on the bus and returns its value to the caller, does not remove it.
|
||||
readEventFromBus(category, subCategory) {
|
||||
const event = useMainStore().eventBusItem(category, subCategory);
|
||||
|
||||
return event;
|
||||
},
|
||||
};
|
||||
78
src/helpers/event-bus/event-bus.spec.js
Normal file
78
src/helpers/event-bus/event-bus.spec.js
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
import { globalEvents, globalEventTypes } from "@/constants/events";
|
||||
import eventBus from "@/helpers/event-bus/event-bus";
|
||||
import { useMainStore } from '@/store';
|
||||
import { createTestingPinia } from '@pinia/testing';
|
||||
|
||||
const pinia = createTestingPinia();
|
||||
useMainStore(pinia);
|
||||
|
||||
useMainStore().addEventToBus = jest.fn();
|
||||
useMainStore().removeEventFromBus = jest.fn();
|
||||
useMainStore().eventBusItem = jest.fn();
|
||||
|
||||
describe("event-bus.js", () => {
|
||||
let event = {
|
||||
isDismissible: true,
|
||||
messageCopy: "You can get a quote by starting on this page.",
|
||||
messageHeadline: "We're sorry, something went wrong.",
|
||||
type: globalEventTypes.Danger,
|
||||
};
|
||||
|
||||
afterEach(() => {
|
||||
jest.resetAllMocks();
|
||||
})
|
||||
|
||||
it("removes items when readandpop is called", () => {
|
||||
useMainStore().eventBusItem.mockReturnValueOnce(event);
|
||||
|
||||
const eventValue = eventBus.readAndPopEventFromBus(
|
||||
globalEvents.Categories.GLOBAL_ALERT,
|
||||
globalEvents.SubCategories.PAGE_NOT_FOUND
|
||||
);
|
||||
|
||||
expect(useMainStore().eventBusItem).toBeCalledTimes(1);
|
||||
expect(useMainStore().removeEventFromBus).toBeCalledTimes(1);
|
||||
|
||||
});
|
||||
|
||||
it("doesn't try to remove items when readandpop is called and item doesn't exist", () => {
|
||||
|
||||
useMainStore().eventBusItem.mockReturnValueOnce(undefined);
|
||||
|
||||
const eventValue = eventBus.readAndPopEventFromBus(
|
||||
globalEvents.Categories.GLOBAL_ALERT,
|
||||
globalEvents.SubCategories.PAGE_NOT_FOUND
|
||||
);
|
||||
|
||||
expect(useMainStore().eventBusItem).toBeCalledTimes(1);
|
||||
expect(useMainStore().removeEventFromBus).toBeCalledTimes(0);
|
||||
|
||||
});
|
||||
|
||||
it("returns event from bus", () => {
|
||||
|
||||
useMainStore().eventBusItem.mockReturnValueOnce(event);
|
||||
|
||||
const eventValue = eventBus.readEventFromBus(
|
||||
globalEvents.Categories.GLOBAL_ALERT,
|
||||
globalEvents.SubCategories.PAGE_NOT_FOUND
|
||||
);
|
||||
|
||||
expect(eventValue).toBe(event);
|
||||
|
||||
});
|
||||
|
||||
|
||||
it("Reads event from bus, should have event value.", () => {
|
||||
// Arrange / Act
|
||||
eventBus.addEventToBus(
|
||||
globalEvents.Categories.GLOBAL_ALERT,
|
||||
globalEvents.SubCategories.PAGE_NOT_FOUND,
|
||||
event
|
||||
);
|
||||
|
||||
expect(useMainStore().addEventToBus).toHaveBeenCalled();
|
||||
|
||||
|
||||
});
|
||||
});
|
||||
|
|
@ -37,7 +37,8 @@ const getDefaultState = () => {
|
|||
crmCustomerId: null,
|
||||
lastPageVisited: null,
|
||||
experiments: [],
|
||||
triggeredSiteEntry: false
|
||||
triggeredSiteEntry: false,
|
||||
eventBus: []
|
||||
},
|
||||
};
|
||||
};
|
||||
|
|
@ -47,7 +48,17 @@ export const state = getDefaultState();
|
|||
export const useMainStore = defineStore({
|
||||
id: storeId,
|
||||
state: () => state,
|
||||
getters: {},
|
||||
getters: {
|
||||
eventBusItem: (state) => (eventCategory, eventSubCategory) => {
|
||||
|
||||
const matchedEvent = state.applicationUser.eventBus.find(
|
||||
({ category, subCategory }) =>
|
||||
category === eventCategory && subCategory === eventSubCategory
|
||||
);
|
||||
return matchedEvent?.eventValue;
|
||||
},
|
||||
eventBus: (state) => state.applicationUser.eventBus,
|
||||
},
|
||||
actions:
|
||||
{
|
||||
// Content API Actions
|
||||
|
|
@ -135,6 +146,21 @@ export const useMainStore = defineStore({
|
|||
this.order.vehicle.style = style;
|
||||
}
|
||||
},
|
||||
addEventToBus(state, event) {
|
||||
state.applicationUser.eventBus.push(event);
|
||||
},
|
||||
removeEventFromBus(state, eventData) {
|
||||
const matchedEvent = state.applicationUser.eventBus.find(
|
||||
({ category, subCategory }) =>
|
||||
category === eventData.category && subCategory === eventData.subCategory
|
||||
);
|
||||
const itemIndex = state.applicationUser.eventBus.indexOf(matchedEvent);
|
||||
|
||||
// If the item exists, remove it.
|
||||
if (itemIndex > -1) {
|
||||
state.applicationUser.eventBus.splice(itemIndex, 1);
|
||||
}
|
||||
},
|
||||
|
||||
// populate initial state
|
||||
populateInitialState()
|
||||
|
|
|
|||
|
|
@ -4,18 +4,81 @@ import { createPinia } from "pinia";
|
|||
import App from '@/App.vue';
|
||||
|
||||
describe("Store", () => {
|
||||
let store = null;
|
||||
|
||||
beforeAll(() => {
|
||||
const vueApp = createApp(App);
|
||||
const pinia = createPinia();
|
||||
vueApp.use(pinia);
|
||||
let store;
|
||||
|
||||
const vueApp = createApp(App);
|
||||
const pinia = createPinia();
|
||||
vueApp.use(pinia);
|
||||
|
||||
beforeEach(() => {
|
||||
store = useMainStore();
|
||||
store.applicationUser.eventBus = [];
|
||||
jest.resetAllMocks();
|
||||
})
|
||||
|
||||
|
||||
it("Should Store Vehicle Year", () => {
|
||||
let testYear = "2001";
|
||||
store.updateVehicleYear(testYear);
|
||||
expect(store.order.vehicle.year).toEqual(testYear);
|
||||
});
|
||||
|
||||
it("Should add events to the bus", () => {
|
||||
let event = {
|
||||
category: "TestCategory",
|
||||
subCategory: "TestSubCategory",
|
||||
eventValue: {
|
||||
isDismissible: true,
|
||||
messageCopy: "You can get a quote by starting on this page.",
|
||||
messageHeadline: "We're sorry, something went wrong.",
|
||||
type: "testType",
|
||||
},
|
||||
};
|
||||
|
||||
store.addEventToBus(store, event);
|
||||
|
||||
expect(store.applicationUser.eventBus[0]).toEqual(event);
|
||||
});
|
||||
|
||||
it("Should remove events from the bus", () => {
|
||||
let event = {
|
||||
category: "TestCategory",
|
||||
subCategory: "TestSubCategory",
|
||||
eventValue: {
|
||||
isDismissible: true,
|
||||
messageCopy: "You can get a quote by starting on this page.",
|
||||
messageHeadline: "We're sorry, something went wrong.",
|
||||
type: "testType",
|
||||
},
|
||||
};
|
||||
|
||||
store.addEventToBus(store, event);
|
||||
|
||||
expect(store.applicationUser.eventBus.length).toBe(1);
|
||||
|
||||
store.removeEventFromBus(store, { category: event.category, subCategory: event.subCategory })
|
||||
|
||||
expect(store.applicationUser.eventBus.length).toBe(0);
|
||||
});
|
||||
|
||||
it("Should return correct event using the getter function eventBusItem", () => {
|
||||
let event = {
|
||||
category: "TestCategory",
|
||||
subCategory: "TestSubCategory",
|
||||
eventValue: {
|
||||
isDismissible: true,
|
||||
messageCopy: "You can get a quote by starting on this page.",
|
||||
messageHeadline: "We're sorry, something went wrong.",
|
||||
type: "testType",
|
||||
},
|
||||
};
|
||||
|
||||
store.addEventToBus(store, event);
|
||||
|
||||
const actual = store.eventBusItem(event.category, event.subCategory)
|
||||
|
||||
expect(actual).toEqual(event.eventValue);
|
||||
});
|
||||
|
||||
});
|
||||
Loading…
Reference in a new issue