diff --git a/src/fmg-components/cart/cart.vue b/src/fmg-components/cart/cart.vue
index f4626caa5..8add7bb85 100644
--- a/src/fmg-components/cart/cart.vue
+++ b/src/fmg-components/cart/cart.vue
@@ -87,20 +87,15 @@
@click-event="removeItem(cartItem.cartItemType, cartItem.category)" />
{{ recycleFeeCartItem.name }}
-
-
-
+
{{ msrFeeCartItem.name }}
-
-
-
+
-
-
-
@@ -177,9 +165,9 @@
// Components
import textLink from "@/ux-components/text-link/text-link";
import textBlock from "@/digital-components/text-block/text-block";
-import contentGroupModal from "@/fmg-components/content-group-modal/content-group-modal";
import promoModalQuestion from "@/fmg-components/promo-modal-question/promo-modal-question";
import removeMsrFeeModal from "./remove-msr-fee-modal/remove-msr-fee-modal.vue";
+import toolTip from "@/ux-components/tool-tip/tool-tip.vue";
// Mixins
import baseMixin from "@/mixins/base-mixin.js";
@@ -1015,7 +1003,10 @@ export default {
msrFeeLineItem.laborAmount + msrFeeLineItem.sellingPrice + msrFeeLineItem.kitPrice
);
},
- msrModalTextBlock() {
+ recyclingToolTipBodyText() {
+ return this.getCmsContent("RecycleTextBlock", "Text");
+ },
+ msrToolTipBodyText() {
let cmsContentText = this.getCmsContent("MSRModal", "BodyText");
if (cmsContentText) {
cmsContentText = cmsContentText.replaceAll(
@@ -1287,9 +1278,9 @@ export default {
components: {
textBlock,
textLink,
- contentGroupModal,
promoModalQuestion,
removeMsrFeeModal,
+ toolTip,
},
};
diff --git a/src/ux-components/tool-tip/tool-tip.spec.js b/src/ux-components/tool-tip/tool-tip.spec.js
new file mode 100644
index 000000000..1e4cca40e
--- /dev/null
+++ b/src/ux-components/tool-tip/tool-tip.spec.js
@@ -0,0 +1,121 @@
+import { shallowMount, mount } from "@vue/test-utils";
+import toolTip from "@/ux-components/tool-tip/tool-tip.vue";
+
+const mockMixin = {
+ methods: {
+ getCmsContent: jest.fn(() => "Mock CMS Content"),
+ },
+};
+
+function setupMocks(mountOptionsMockData = {}) {
+ const defaultMountOptions = {
+ propsData: {
+ cmsWidgetName: "testWidget",
+ },
+ mixins: [mockMixin],
+ };
+ return { ...defaultMountOptions, ...mountOptionsMockData };
+}
+
+describe("toolTip.vue", () => {
+ afterEach(() => {
+ jest.clearAllMocks();
+ });
+
+ it("should not show tooltip initially", () => {
+ // Arrange
+ const wrapper = shallowMount(toolTip, setupMocks());
+
+ // Assert
+ expect(wrapper.vm.isVisible).toBe(false);
+ expect(wrapper.find(".tooltip").exists()).toBe(false);
+ });
+
+ it("should show tooltip when icon is clicked", async () => {
+ // Arrange
+ const wrapper = shallowMount(toolTip, setupMocks());
+ const icon = wrapper.find(".tooltip-icon");
+
+ // Act
+ await icon.trigger("click");
+
+ // Assert
+ expect(wrapper.vm.isVisible).toBe(true);
+ expect(wrapper.find(".tooltip").exists()).toBe(true);
+ });
+
+ it("should hide tooltip when clicked outside", async () => {
+ // Arrange
+ const wrapper = shallowMount(toolTip, setupMocks());
+ const icon = wrapper.find(".tooltip-icon");
+
+ // Show tooltip first
+ await icon.trigger("click");
+ expect(wrapper.vm.isVisible).toBe(true);
+
+ // Act - simulate click outside
+ const clickEvent = new Event("click");
+ Object.defineProperty(clickEvent, "target", { value: document.body });
+ document.dispatchEvent(clickEvent);
+
+ // Wait for next tick to allow event handling
+ await wrapper.vm.$nextTick();
+
+ // Assert
+ expect(wrapper.vm.isVisible).toBe(false);
+ expect(wrapper.find(".tooltip").exists()).toBe(false);
+ });
+
+ it("should toggle tooltip visibility when icon is clicked multiple times", async () => {
+ // Arrange
+ const wrapper = shallowMount(toolTip, setupMocks());
+ const icon = wrapper.find(".tooltip-icon");
+
+ // Act & Assert - First click shows
+ await icon.trigger("click");
+ expect(wrapper.vm.isVisible).toBe(true);
+
+ // Second click hides
+ await icon.trigger("click");
+ expect(wrapper.vm.isVisible).toBe(false);
+
+ // Third click shows again
+ await icon.trigger("click");
+ expect(wrapper.vm.isVisible).toBe(true);
+ });
+
+ it("should not hide tooltip when clicking inside the tooltip container", async () => {
+ // Arrange
+ const wrapper = shallowMount(toolTip, setupMocks());
+ const icon = wrapper.find(".tooltip-icon");
+
+ // Show tooltip first
+ await icon.trigger("click");
+ expect(wrapper.vm.isVisible).toBe(true);
+
+ // Act - simulate click inside container
+ const container = wrapper.find(".tooltip-container").element;
+ const clickEvent = new Event("click");
+ Object.defineProperty(clickEvent, "target", { value: container });
+ document.dispatchEvent(clickEvent);
+
+ // Wait for next tick
+ await wrapper.vm.$nextTick();
+
+ // Assert - tooltip should still be visible
+ expect(wrapper.vm.isVisible).toBe(true);
+ });
+
+ it("should calculate lineItemContainerLength based on parent element width", () => {
+ // Arrange
+ const wrapper = mount(toolTip, setupMocks());
+ const parentDiv = document.createElement("div");
+ Object.defineProperty(parentDiv, "offsetWidth", { value: 300, writable: true });
+
+ const container = wrapper.vm.$refs.container;
+ Object.defineProperty(container, "parentElement", { value: parentDiv, writable: true });
+
+ // Act & Assert
+ expect(wrapper.vm.lineItemContainerLength).toBe(-300);
+ });
+});
diff --git a/src/ux-components/tool-tip/tool-tip.vue b/src/ux-components/tool-tip/tool-tip.vue
new file mode 100644
index 000000000..648c5adbd
--- /dev/null
+++ b/src/ux-components/tool-tip/tool-tip.vue
@@ -0,0 +1,140 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+