import BroadcastChannelStrategy from "./broadcastChannel";

describe("BroadcastChannelStrategy", () => {
    const mockChannel = {
        addEventListener: jest.fn(),
        postMessage: jest.fn(),
    };
    const mockBroadcastChannel = jest.fn(() => mockChannel);

    beforeEach(() => {
        jest.clearAllMocks();
    });

    describe("available", () => {
        it("should return true if BroadcastChannelImpl is a function", () => {
            expect(BroadcastChannelStrategy.available(mockBroadcastChannel)).toBe(true);
        });

        it("should return false if BroadcastChannelImpl is not a function", () => {
            expect(BroadcastChannelStrategy.available(null)).toBe(false);
        });
    });

    describe("constructor", () => {
        it("should create a new BroadcastChannel with the default channel name if no key is provided", () => {
            const strategy = new BroadcastChannelStrategy({
                BroadcastChannel: mockBroadcastChannel,
            });

            expect(mockBroadcastChannel).toHaveBeenCalledWith("vuex-shared-mutations");
            expect(strategy.channel).toBe(mockChannel);
        });

        it("should create a new BroadcastChannel with the provided key", () => {
            const strategy = new BroadcastChannelStrategy({
                BroadcastChannel: mockBroadcastChannel,
                key: "test-channel",
            });

            expect(mockBroadcastChannel).toHaveBeenCalledWith("test-channel");
            expect(strategy.channel).toBe(mockChannel);
        });

        it("should throw an error if Broadcast strategy is not available", () => {
            expect(() => new BroadcastChannelStrategy({ BroadcastChannel: null })).toThrow(
                "Broadcast strategy not available"
            );
        });
    });

    describe("addEventListener", () => {
        it("should add a message event listener to the channel", () => {
            const strategy = new BroadcastChannelStrategy({
                BroadcastChannel: mockBroadcastChannel,
            });
            const mockFn = jest.fn();

            strategy.addEventListener(mockFn);
            expect(mockChannel.addEventListener).toHaveBeenCalledWith(
                "message",
                expect.any(Function)
            );

            // const mockEvent = { data: "test-message" };
            // console.log(mockChannel.addEventListener.mock.calls);
            // mockChannel.addEventListener.mock.calls[0][1];
            // expect(mockFn).toHaveBeenCalledWith(mockEvent.data);
        });
    });

    describe("share", () => {
        it("should post a message to the channel", () => {
            const strategy = new BroadcastChannelStrategy({
                BroadcastChannel: mockBroadcastChannel,
            });
            const mockMessage = { test: "message" };

            expect(strategy.share(mockMessage)).toBeUndefined();
            expect(mockChannel.postMessage).toHaveBeenCalledWith(mockMessage);
        });
    });
});
