import experimentMixin from "@/mixins/experiment-mixin";
import { shallowMount } from "@vue/test-utils";
import { getMountOptions } from "@/helpers/unit-test-helper.js";
import store from "@/store";

describe("experiment-mixin", () => {
    describe("hasSettingEqualTo", () => {
        test("setting exists and value matches => return true", () => {
            // Arrange
            const { wrapper } = setupMocks({});

            // Act
            const result = wrapper.vm.hasSettingEqualTo("Setting2", "Value2");

            // Assert
            expect(result).toEqual(true);
        });

        test("setting exists and value does not match => return false", () => {
            // Arrange
            const { wrapper } = setupMocks({});

            // Act
            const result = wrapper.vm.hasSettingEqualTo("Setting2", "Value3");

            // Assert
            expect(result).toEqual(false);
        });

        test("setting does not exist => return false", () => {
            // Arrange
            const { wrapper } = setupMocks({});

            // Act
            const result = wrapper.vm.hasSettingEqualTo("SettingBoogly", "Woogly");

            // Assert
            expect(result).toEqual(false);
        });

        test("there are no settings => return false", () => {
            // Arrange
            const { wrapper } = setupMocks({ experimentSettings: {} });

            // Act
            const result = wrapper.vm.hasSettingEqualTo("Setting2", "Value3");

            // Assert
            expect(result).toEqual(false);
        });
    });

    describe("hasSetting", () => {
        test("has setting => return true", () => {
            // Arrange
            const { wrapper } = setupMocks({});

            // Act
            const result = wrapper.vm.hasSetting("Setting4");

            // Assert
            expect(result).toEqual(true);
        });

        test("does not have setting => return false", () => {
            // Arrange
            const { wrapper } = setupMocks({});

            // Act
            const result = wrapper.vm.hasSetting("BooglyWoogly");

            // Assert
            expect(result).toEqual(false);
        });

        test("experimentSettings is empty => return false", () => {
            // Arrange
            const { wrapper } = setupMocks({ experimentSettings: {} });

            // Act
            const result = wrapper.vm.hasSetting("Setting4");

            // Assert
            expect(result).toEqual(false);
        });
    });

    describe("getSettingValue", () => {
        test("has setting => return correct value", () => {
            // Arrange
            const { wrapper } = setupMocks({});

            // Act
            const result = wrapper.vm.getSettingValue("Setting3");

            // Assert
            expect(result).toEqual("Value3");
        });

        test("does not have setting => return null", () => {
            // Arrange
            const { wrapper } = setupMocks({});

            // Act
            const result = wrapper.vm.getSettingValue("Hello");

            // Assert
            expect(result).toBeNull();
        });

        test("experimentSettings is empty => return null", () => {
            // Arrange
            const { wrapper } = setupMocks({ experimentSettings: {} });

            // Act
            const result = wrapper.vm.getSettingValue("Hello");

            // Assert
            expect(result).toBeNull();
        });
    });
});

function setupMocks({ experimentSettings }) {
    const mocks = getMountOptions({});

    const testExperimentSettings = {
        Setting1: "Value1",
        Setting2: "Value2",
        Setting3: "Value3",
        Setting4: "Value1",
        Setting5: "Value2",
        Setting6: "Value3",
    };

    store.getters = {
        experimentSettings: experimentSettings ?? testExperimentSettings,
        applicationUser: {
            experiments: [
                {
                    isActive: true,
                    isExposed: true,
                    settings: experimentSettings ?? testExperimentSettings,
                },
            ],
        },
    };

    const mockComponent = {
        template: "<div></div>",
        mixins: [experimentMixin],
    };

    const wrapper = shallowMount(mockComponent, mocks);

    return { wrapper };
}
