diff --git a/index.html b/index.html index 52e7eabdc2..c47e9d9de0 100644 --- a/index.html +++ b/index.html @@ -440,6 +440,13 @@ accept=".json" tabindex="-1" /> + { + let mockBrowser; + let mockChrome; + + beforeEach(() => { + // Mock objects + mockBrowser = { + browserAction: { + onClicked: { addListener: jest.fn() }, + }, + tabs: { create: jest.fn() }, + runtime: { + onInstalled: { addListener: jest.fn() }, + }, + }; + + mockChrome = { + browserAction: { + onClicked: { addListener: jest.fn() }, + }, + runtime: { + onInstalled: { addListener: jest.fn() }, + getURL: jest.fn((path) => `chrome-extension://fake-id/${path}`), + }, + tabs: { create: jest.fn() }, + }; + + global.browser = mockBrowser; + global.chrome = mockChrome; + + Object.defineProperty(global.navigator, "userAgent", { + writable: true, + value: "", + }); + }); + + afterEach(() => { + jest.clearAllMocks(); + delete global.browser; + delete global.chrome; + }); + + it("should set up Firefox-specific listeners when user agent is Firefox", () => { + navigator.userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/109.0"; + + jest.resetModules(); // Clear the module cache + const { isFirefox, browserAction } = require("../background.js"); + + expect(isFirefox).toBe(true); + expect(browserAction.onClicked.addListener).toHaveBeenCalledTimes(1); + expect(mockBrowser.runtime.onInstalled.addListener).toHaveBeenCalledTimes(1); + }); + + it("should set up Chrome-specific listeners when user agent is not Firefox", () => { + navigator.userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36"; + + jest.resetModules(); // Clear the module cache + const { isFirefox, browserAction } = require("../background.js"); + + expect(isFirefox).toBe(false); + expect(browserAction.onClicked.addListener).toHaveBeenCalledTimes(1); + expect(mockChrome.runtime.onInstalled.addListener).toHaveBeenCalledTimes(1); + }); +}); diff --git a/js/__tests__/mxml.test.js b/js/__tests__/mxml.test.js new file mode 100644 index 0000000000..523d27e71a --- /dev/null +++ b/js/__tests__/mxml.test.js @@ -0,0 +1,151 @@ +const saveMxmlOutput = require("../mxml"); + +describe("saveMxmlOutput", () => { + it("should return a valid XML string for a basic input", () => { + const logo = { + notation: { + notationStaging: { + "0": [ + [["C"], 4, 0], + ], + "1": [] + } + } + }; + + const output = saveMxmlOutput(logo); + + expect(output).toContain(""); + expect(output).toContain(""); + expect(output).toContain(""); + expect(output).toContain(""); + expect(output).toContain(""); + }); + + it("should handle multiple voices", () => { + const logo = { + notation: { + notationStaging: { + "0": [ + [["C"], 4, 0], + [["D"], 4, 0] + ], + "1": [ + [["E"], 4, 0], + [["F"], 4, 0] + ] + } + } + }; + + const output = saveMxmlOutput(logo); + + expect(output).toContain(""); + expect(output).toContain(""); + expect(output).toContain(""); + expect(output).toContain(""); + expect(output).toContain("C"); + expect(output).toContain("E"); + }); + + it("should ignore specified elements", () => { + const logo = { + notation: { + notationStaging: { + "0": [ + "voice one", + [["C"], 4, 0], + "voice two" + ] + } + } + }; + + const output = saveMxmlOutput(logo); + + expect(output).not.toContain("voice one"); + expect(output).not.toContain("voice two"); + expect(output).toContain("C"); + }); + + it("should handle tempo changes", () => { + const logo = { + notation: { + notationStaging: { + "0": [ + "tempo", 120, 4, + [["C"], 4, 0] + ] + } + } + }; + + const output = saveMxmlOutput(logo); + + expect(output).toContain(""); + expect(output).toContain("C"); + }); + + it("should handle meter changes", () => { + const logo = { + notation: { + notationStaging: { + "0": [ + "meter", 3, 4, + [["C"], 4, 0] + ] + } + } + }; + + const output = saveMxmlOutput(logo); + + expect(output).toContain("