Added EventBus to create new alert events

This commit is contained in:
Jason Wheeler 2022-11-08 16:11:40 -05:00
parent bca83d4783
commit 652eed2585
6 changed files with 241 additions and 7 deletions

View file

@ -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
View 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 };

View 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;
},
};

View 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();
});
});

View file

@ -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()

View file

@ -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);
});
});