UNPKG

@applicaster/quick-brick-core

Version:

Core package for Applicaster's Quick Brick App

341 lines (282 loc) • 7.92 kB
const layoutId = "A1234"; const layout = { id: layoutId, screens: [ { id: "screen1", name: "home", general: { icon: "http://img.com/icon.png" }, home: true, home_offline: false, supports_offline: false, }, { id: "screen2", name: "show screen", general: {}, navigations: [ { category: "tabs", nav_items: [ { target: "screen3", asset: "http://img.com/tab_asset.png" }, ], }, ], home: false, home_offline: false, supports_offline: false, }, { id: "screen3", name: "other screen", general: {}, home: false, home_offline: false, supports_offline: false, styles: { failing_asset: "http://img.com/failing_asset.png", }, }, ], content_types: { type: { screen_id: "screen1", }, }, }; const pluginConfigurations = [ { plugin: { api: {}, dependency_name: "plugin_1", name: "plugin 1", type: "general" as PluginType, identifier: "plugin_1", dependency_version: "0.0.1", }, configuration_json: { plugin_asset: "http://img.com/plugin_asset.png" }, }, ]; const cellStyles = { cellId1: { plugin_identifier: "cell-style", configuration: { assets: { cell_asset: "http://img.com/cell_asset.png" }, styles: {}, }, }, }; let assetCacheEnabled = true; let isTV = false; const offlineAssetsBridge = jest.requireActual( "@applicaster/zapp-react-native-bridge/OfflineAssets" ); const mockedStoreFiles = (files) => { const result = files.reduce((acc, { url, file }) => { const success = !url.includes("fail"); return { ...acc, [file]: success }; }, {}); return Promise.resolve(result); }; jest.mock("@applicaster/zapp-react-native-bridge/OfflineAssets", () => ({ isAssetCacheEnabled: jest.fn(() => assetCacheEnabled), getNativeRootPath: jest.fn(() => Promise.resolve("/path")), storeFiles: jest.fn((files) => mockedStoreFiles(files)), collectAssets: jest.fn(offlineAssetsBridge.collectAssets), remapAssetPath: jest.fn(offlineAssetsBridge.remapAssetPath), fileIsSaved: jest.fn(offlineAssetsBridge.fileIsSaved), })); jest.mock("@applicaster/zapp-react-native-utils/reactUtils", () => ({ isTV: jest.fn(() => isTV), platformSelect: jest.fn( (specs) => specs.ios || specs.android || specs.default ), isApplePlatform: jest.fn(() => true), })); const { CacheManager } = require("../CacheManager"); const { storeFiles, } = require("@applicaster/zapp-react-native-bridge/OfflineAssets"); const getFilesToCache = jest.spyOn(CacheManager.instance, "getFilesToCache"); const clearCache = jest .spyOn(CacheManager.instance, "clearCache") .mockImplementation(jest.fn()); const saveCacheData = jest .spyOn(CacheManager.instance, "saveCacheData") .mockImplementation(jest.fn()); const { cacheAssets, getLayoutAssets } = require(".."); function clearMocks() { getFilesToCache.mockClear(); clearCache.mockClear(); saveCacheData.mockClear(); storeFiles.mockClear(); } describe("getLayoutAssets", () => { it("returns the list of assets in the layout", async () => { await expect( getLayoutAssets({ layout, pluginConfigurations, cellStyles }) ).resolves.toMatchSnapshot(); }); }); describe("asset cache", () => { describe("when native module doesn't exist", () => { beforeEach(() => { assetCacheEnabled = false; clearMocks(); }); afterAll(() => { assetCacheEnabled = true; }); it("it returns the provided config", async () => { const layoutData = { layout, pluginConfigurations, cellStyles, }; await expect(cacheAssets(layoutData)).resolves.toEqual(layoutData); }); }); describe("when running on a TV platform", () => { beforeEach(() => { isTV = true; clearMocks(); }); afterAll(() => { isTV = false; }); it("it returns the provided config", async () => { const layoutData = { layout, pluginConfigurations, cellStyles, }; await expect(cacheAssets(layoutData)).resolves.toEqual(layoutData); }); }); describe("when layoutId is undefined", () => { beforeEach(clearMocks); it("returns the provided configuration", async () => { const layoutWithNoId = { ...layout, id: null, }; const layoutData = { layout: layoutWithNoId, pluginConfigurations, cellStyles, }; await expect(cacheAssets(layoutData)).resolves.toEqual(layoutData); }); }); describe("when there are files to cache", () => { const removedFiles = []; beforeEach(async () => { clearMocks(); const { assetFiles: newFiles } = await getLayoutAssets({ layout, pluginConfigurations, cellStyles, }); getFilesToCache.mockImplementation(() => Promise.resolve({ removedFiles, newFiles, unchangedFiles: [], }) ); }); it("stores the new files", async () => { await cacheAssets({ layout, pluginConfigurations, cellStyles, }); const { assetFiles } = await getLayoutAssets({ layout, pluginConfigurations, cellStyles, }); expect(clearCache).not.toHaveBeenCalled(); expect(storeFiles).toHaveBeenCalledWith(assetFiles); expect(saveCacheData).toHaveBeenCalledWith( layoutId, assetFiles.filter(({ url }) => !url.includes("fail")) ); }); it("returns the remapped layout files", async () => { const result = await cacheAssets({ layout, pluginConfigurations, cellStyles, }); expect(result).toMatchSnapshot(); }); }); describe("when there are no files to cache", () => { beforeEach(() => { clearMocks(); getFilesToCache.mockImplementation(() => Promise.resolve({ removedFiles: [], newFiles: [], unchangedFiles: [], }) ); }); it("doesn't cache any new file", () => { expect(clearCache).not.toHaveBeenCalled(); expect(storeFiles).not.toHaveBeenCalled(); expect(saveCacheData).not.toHaveBeenCalled(); }); it("returns the remapped layout files", async () => { await expect( cacheAssets({ layout, pluginConfigurations, cellStyles }) ).resolves.toMatchSnapshot(); }); }); describe("when only a few files changed", () => { beforeEach(async () => { clearMocks(); const { assetFiles } = await getLayoutAssets({ layout, pluginConfigurations, cellStyles, }); const [removedFiles, ...newFiles] = assetFiles; getFilesToCache.mockImplementation(() => Promise.resolve({ removedFiles: [removedFiles], newFiles, unchangedFiles: [], }) ); }); it("stores the new files and removes the obsolete ones", async () => { await cacheAssets({ layout, pluginConfigurations, cellStyles, }); const { assetFiles } = await getLayoutAssets({ layout, pluginConfigurations, cellStyles, }); const [removedFiles, ...newFiles] = assetFiles; expect(clearCache).toHaveBeenCalledWith([removedFiles]); expect(storeFiles).toHaveBeenCalledWith(newFiles); expect(saveCacheData).toHaveBeenCalledWith( layoutId, newFiles.filter(({ url }) => !url.includes("fail")) ); }); it("returns the remapped layout files", async () => { const result = await cacheAssets({ layout, pluginConfigurations, cellStyles, }); expect(result).toMatchSnapshot(); }); }); });