UNPKG

webextension-store-meta

Version:

Get browser extension(webextension) item meta from Chrome Web Store, Firefox add-ons, and Microsoft Edge Add-ons.

153 lines (138 loc) 5.97 kB
import { load } from "cheerio"; import { fetch, type RequestInit } from "undici"; import { describe, expect, it, type MockedFunction, vi } from "vitest"; import { fetchText } from "../../utils/fetch-text"; import { Amo } from "../"; import { fixtures } from "./fixtures"; const fetchTextMock = fetchText as MockedFunction<typeof fetchText>; vi.mock("../../utils/fetch-text", () => { const cache = new Map<string, string>(); return { fetchText: vi.fn(async (url, options): Promise<string> => { if (cache.has(url)) { return cache.get(url) || ""; } const result = await fetch(url, options).then((res) => res.text()); cache.set(url, result); return result; }), }; }); describe("Amo", async () => { const matchAnyInfo = { name: expect.any(String), description: expect.any(String), ratingValue: expect.any(Number), ratingCount: expect.any(Number), users: expect.any(Number), price: expect.any(Number), priceCurrency: expect.any(String), version: expect.any(String), url: expect.any(String), image: expect.any(String), operatingSystem: expect.any(String), size: expect.any(String), lastUpdated: expect.any(String), }; describe.each(await fixtures())( "%s", (extId) => { it("should return ext info", async () => { const amo = new Amo({ id: extId }); await amo.load(); expect(amo.meta()).toMatchObject(matchAnyInfo); expect(amo.sourceDOM.name()).toEqual(expect.any(String)); expect(amo.sourceDOM.description()).toEqual(expect.any(String)); expect(amo.sourceDOM.ratingValue()).toEqual(expect.any(Number)); expect(amo.sourceDOM.ratingCount()).toEqual(expect.any(Number)); expect(amo.sourceDOM.users()).toEqual(expect.any(Number)); expect(amo.sourceDOM.version()).toEqual(expect.any(String)); expect(amo.sourceDOM.url()).toEqual(expect.any(String)); expect(amo.sourceDOM.image()).toEqual(expect.any(String)); expect(amo.sourceDOM.size()).toEqual(expect.any(String)); expect(amo.sourceDOM.lastUpdated()).toEqual(expect.any(String)); expect(amo.sourceJSONLD.name()).toEqual(expect.any(String)); expect(amo.sourceJSONLD.description()).toEqual(expect.any(String)); expect(amo.sourceJSONLD.ratingValue()).toEqual(expect.any(Number)); expect(amo.sourceJSONLD.ratingCount()).toEqual(expect.any(Number)); expect(amo.sourceJSONLD.price()).toEqual(expect.any(Number)); expect(amo.sourceJSONLD.priceCurrency()).toEqual(expect.any(String)); expect(amo.sourceJSONLD.version()).toEqual(expect.any(String)); expect(amo.sourceJSONLD.url()).toEqual(expect.any(String)); expect(amo.sourceJSONLD.image()).toEqual(expect.any(String)); expect(amo.sourceJSONLD.operatingSystem()).toEqual(expect.any(String)); expect(amo.sourceReduxStoreState.name()).toEqual(expect.any(String)); expect(amo.sourceReduxStoreState.description()).toEqual( expect.any(String), ); expect(amo.sourceReduxStoreState.ratingValue()).toEqual( expect.any(Number), ); expect(amo.sourceReduxStoreState.ratingCount()).toEqual( expect.any(Number), ); expect(amo.sourceReduxStoreState.users()).toEqual(expect.any(Number)); expect(amo.sourceReduxStoreState.version()).toEqual(expect.any(String)); expect(amo.sourceReduxStoreState.url()).toEqual(expect.any(String)); expect(amo.sourceReduxStoreState.image()).toEqual(expect.any(String)); expect(amo.sourceReduxStoreState.size()).toEqual(expect.any(String)); expect(amo.sourceReduxStoreState.lastUpdated()).toEqual( expect.any(String), ); expect(amo.sourceOG.description()).toEqual(expect.any(String)); expect(amo.sourceOG.url()).toEqual(expect.any(String)); expect(amo.sourceOG.image()).toEqual(expect.any(String)); }); it("should also return ext info with static `load` shortcut", async () => { const amo = await Amo.load({ id: extId }); expect(amo.meta()).toMatchObject(matchAnyInfo); }); it("should concat querystring", async () => { const amo = await Amo.load({ id: extId, qs: { hl: "zh", lr: "lang_zh-CN" }, }); expect(amo.meta()).toMatchObject(matchAnyInfo); expect(fetchTextMock).toHaveBeenLastCalledWith( expect.stringContaining("?hl=zh&lr=lang_zh-CN"), undefined, ); }); it("should throw error if document is not loaded", () => { const amo = new Amo({ id: extId }); expect(() => amo.meta()).toThrow(); }); it("should extract from elements", async () => { const cache = new Map<string, string>(); fetchTextMock.mockImplementationOnce( async (url: string, options?: RequestInit): Promise<string> => { const result: string = cache.get(url) || (await fetch(url, options).then((res) => res.text())); const $ = load(result); $("[itemprop]").remove(); $("[property]").remove(); $('script[type="application/ld+json"]').remove(); cache.set(url, $.html()); return result; }, ); const amo = await Amo.load({ id: "ublock-origin" }); expect(amo.meta()).toMatchObject({ name: expect.any(String), description: expect.any(String), url: expect.any(String), version: expect.any(String), users: expect.any(Number), ratingValue: expect.any(Number), ratingCount: expect.any(Number), image: expect.any(String), operatingSystem: expect.any(String), price: expect.any(Number), priceCurrency: expect.any(String), }); }); }, 20000, ); });