UNPKG

@applicaster/zapp-react-native-bridge

Version:

Applicaster Zapp React Native modules

548 lines (427 loc) • 15.4 kB
import { sessionStorage as NativeSessionStorage } from "../__mocks__/ios"; import { DEFAULT_NAMESPACE } from "../__mocks__/storageMock"; import { NativeModules } from "react-native"; NativeModules.SessionStorage = NativeSessionStorage; const { sessionStorage } = require("../SessionStorage"); const test_key = "test_key"; const test_value = "test_value"; const namespaced_key = "namespaced_key"; const namespaced_value = "namespaced_value"; const test_namespace = "test_namespace"; const obj_key = "obj_key"; const obj_value = { prop: "value" }; function setUpStorage() { NativeSessionStorage.setItem(test_key, test_value); NativeSessionStorage.setItem( namespaced_key, namespaced_value, test_namespace ); NativeSessionStorage.setItem(obj_key, JSON.stringify(obj_value)); } describe("sessionStorage", () => { describe("setItem", () => { beforeEach(async () => { NativeSessionStorage.__clear(); }); it("sets an item in storage", async () => { const key = "test_key"; const value = "test_value"; const result = await sessionStorage.setItem(key, value); expect(result).toBe(true); expect( NativeSessionStorage.items.get(DEFAULT_NAMESPACE).get(key) ).toEqual(value); }); it("works as a bound method", async () => { const key = "test_key"; const value = "test_value"; const setItem = sessionStorage.setItem; const result = await setItem(key, value); expect(result).toBe(true); expect( NativeSessionStorage.items.get(DEFAULT_NAMESPACE).get(key) ).toEqual(value); }); it("stringifies the value if its not a string", async () => { const key = "test_key"; const value = { objVal: "test_value" }; const result = await sessionStorage.setItem(key, value); expect(result).toBe(true); expect( NativeSessionStorage.items.get(DEFAULT_NAMESPACE).get(key) ).toEqual(JSON.stringify(value)); }); it("sets a value in a specific namespace", async () => { const key = "test_key"; const value = "test_value"; const namespace = "test_namespace"; const result = await sessionStorage.setItem(key, value, namespace); expect(result).toBe(true); expect(NativeSessionStorage.items.get(namespace).get(key)).toEqual(value); }); it("throws if key is null", async () => { const value = "test_value"; expect(() => sessionStorage.setItem(null, value) ).rejects.toThrowErrorMatchingSnapshot(); }); it("throws if key is undefined", async () => { const value = "test_value"; expect(() => sessionStorage.setItem(undefined, value) ).rejects.toThrowErrorMatchingSnapshot(); }); it("throws if value is null", async () => { const key = "test_key"; expect(() => sessionStorage.setItem(key, null) ).rejects.toThrowErrorMatchingSnapshot(); }); it("throws if value is undefined", async () => { const key = "test_key"; expect(() => sessionStorage.setItem(key, undefined) ).rejects.toThrowErrorMatchingSnapshot(); }); it("throws if there is an error in the native module", async () => { const key = "fail"; const value = "value"; expect(() => sessionStorage.setItem(key, value) ).rejects.toThrowErrorMatchingSnapshot(); }); describe("listeners", () => { describe("listening for a specific key and namespace change", () => { const listener = jest.fn(); const new_value = "new_value"; let removeListener; beforeEach(() => { setUpStorage(); listener.mockClear(); removeListener = sessionStorage.addListener( { key: namespaced_key, namespace: test_namespace }, listener ); }); it("invokes the listener when this key is changed", async () => { await sessionStorage.setItem( namespaced_key, new_value, test_namespace ); expect(listener).toHaveBeenCalledWith( expect.objectContaining({ key: namespaced_key, namespace: test_namespace, value: new_value, }) ); }); it("works as a bound method", async () => { const setItem = sessionStorage.setItem; await setItem(namespaced_key, new_value, test_namespace); expect(listener).toHaveBeenCalledWith( expect.objectContaining({ key: namespaced_key, namespace: test_namespace, value: new_value, }) ); }); it("is not invoked when another key is changed", async () => { await sessionStorage.setItem(test_key, new_value); expect(listener).not.toHaveBeenCalled(); }); it("removes the listener when invoking the remove function", async () => { removeListener(); await sessionStorage.setItem( namespaced_key, new_value, test_namespace ); expect(listener).not.toHaveBeenCalled(); }); }); describe("listening for any key change in a namespace", () => { const listener = jest.fn(); const new_value = "new_value"; let removeListener; beforeEach(() => { setUpStorage(); listener.mockClear(); removeListener = sessionStorage.addListener( { namespace: test_namespace }, listener ); }); it("is invoked when a key in the namespace is changed", async () => { await sessionStorage.setItem( namespaced_key, new_value, test_namespace ); expect(listener).toHaveBeenCalledWith( expect.objectContaining({ key: namespaced_key, value: new_value, namespace: test_namespace, }) ); }); it("is not invoked when a key in a different namespace is changed", async () => { await sessionStorage.setItem(test_key, new_value, DEFAULT_NAMESPACE); expect(listener).not.toHaveBeenCalled(); }); it("is not invoked after being removed", async () => { removeListener(); await sessionStorage.setItem( namespaced_key, new_value, test_namespace ); expect(listener).not.toHaveBeenCalled(); }); }); describe("listening for key changes in the default namespace", () => { const listener = jest.fn(); const new_value = "new_value"; let removeListener; beforeEach(() => { setUpStorage(); listener.mockClear(); removeListener = sessionStorage.addListener({}, listener); }); it("is invoked when a key is changed in the default namespace", async () => { await sessionStorage.setItem(test_key, new_value); expect(listener).toHaveBeenCalledWith( expect.objectContaining({ key: test_key, value: new_value, namespace: DEFAULT_NAMESPACE, }) ); }); it("is not invoked when a key in a nother namespace is changed", async () => { await sessionStorage.setItem( namespaced_key, new_value, test_namespace ); expect(listener).not.toHaveBeenCalled(); }); it("is not invoked after having been removed", async () => { removeListener(); await sessionStorage.setItem(test_key, new_value); expect(listener).not.toHaveBeenCalled(); }); }); }); }); describe("getItem", () => { beforeAll(setUpStorage); it("retrieves a value from storage", async () => { const result = await sessionStorage.getItem(test_key); expect(result).toBe(test_value); }); it("works as a bound method", async () => { const getItem = sessionStorage.getItem; const result = await getItem(test_key); expect(result).toBe(test_value); }); it("retrieves a value in a namespace", async () => { const result = await sessionStorage.getItem( namespaced_key, test_namespace ); expect(result).toBe(namespaced_value); }); it("retrieves non string values", async () => { const result = await sessionStorage.getItem(obj_key); expect(result).toEqual(obj_value); }); it("throws if key is null", async () => { expect(() => sessionStorage.getItem(null) ).rejects.toThrowErrorMatchingSnapshot(); }); it("throws if key is undefined", async () => { expect(() => sessionStorage.getItem() ).rejects.toThrowErrorMatchingSnapshot(); }); it("throws if there is an error on the native side", async () => { expect(() => sessionStorage.getItem("fail") ).rejects.toThrowErrorMatchingSnapshot(); }); }); describe("removeItem", () => { beforeEach(setUpStorage); it("removes a value from storage", async () => { const result = await sessionStorage.removeItem(test_key); expect(result).toBe(true); expect( NativeSessionStorage.items.get(DEFAULT_NAMESPACE).get(test_key) ).toBeUndefined(); }); it("works as a bound method", async () => { const removeItem = sessionStorage.removeItem; const result = await removeItem(test_key); expect(result).toBe(true); expect( NativeSessionStorage.items.get(DEFAULT_NAMESPACE).get(test_key) ).toBeUndefined(); }); it("removes a value in a namespace", async () => { const result = await sessionStorage.removeItem( namespaced_key, test_namespace ); expect(result).toBe(true); expect( NativeSessionStorage.items.get(test_namespace).get(namespaced_key) ).toBeUndefined(); }); it("throws if key is null", async () => { expect(() => sessionStorage.removeItem(null) ).rejects.toThrowErrorMatchingSnapshot(); }); it("throws if key is undefined", async () => { expect(() => sessionStorage.removeItem() ).rejects.toThrowErrorMatchingSnapshot(); }); it("throws if a native error is thrown", async () => { expect(() => sessionStorage.removeItem("fail") ).rejects.toThrowErrorMatchingSnapshot(); }); describe("listeners", () => { describe("listening for a specific key and namespace change", () => { const listener = jest.fn(); let removeListener; beforeEach(() => { setUpStorage(); listener.mockClear(); removeListener = sessionStorage.addListener( { key: namespaced_key, namespace: test_namespace }, listener ); }); it("invokes the listener when this key is changed", async () => { await sessionStorage.removeItem(namespaced_key, test_namespace); expect(listener).toHaveBeenCalledWith( expect.objectContaining({ key: namespaced_key, namespace: test_namespace, value: null, }) ); }); it("is not invoked when another key is changed", async () => { await sessionStorage.removeItem(test_key); expect(listener).not.toHaveBeenCalled(); }); it("removes the listener when invoking the remove function", async () => { removeListener(); await sessionStorage.removeItem(namespaced_key, test_namespace); expect(listener).not.toHaveBeenCalled(); }); }); describe("listening for any key change in a namespace", () => { const listener = jest.fn(); let removeListener; beforeEach(() => { setUpStorage(); listener.mockClear(); removeListener = sessionStorage.addListener( { namespace: test_namespace }, listener ); }); it("is invoked when a key in the namespace is changed", async () => { await sessionStorage.removeItem(namespaced_key, test_namespace); expect(listener).toHaveBeenCalledWith( expect.objectContaining({ key: namespaced_key, value: null, namespace: test_namespace, }) ); }); it("is not invoked when a key in a different namespace is changed", async () => { await sessionStorage.removeItem(test_key, DEFAULT_NAMESPACE); expect(listener).not.toHaveBeenCalled(); }); it("is not invoked after being removed", async () => { removeListener(); await sessionStorage.removeItem(namespaced_key, test_namespace); expect(listener).not.toHaveBeenCalled(); }); }); describe("listening for key changes in the default namespace", () => { const listener = jest.fn(); let removeListener; beforeEach(() => { setUpStorage(); listener.mockClear(); removeListener = sessionStorage.addListener({}, listener); }); it("is invoked when a key is changed in the default namespace", async () => { await sessionStorage.removeItem(test_key); expect(listener).toHaveBeenCalledWith( expect.objectContaining({ key: test_key, value: null, namespace: DEFAULT_NAMESPACE, }) ); }); it("is not invoked when a key in a nother namespace is changed", async () => { await sessionStorage.removeItem(namespaced_key, test_namespace); expect(listener).not.toHaveBeenCalled(); }); it("is not invoked after having been removed", async () => { removeListener(); await sessionStorage.removeItem(test_key); expect(listener).not.toHaveBeenCalled(); }); }); }); }); describe("getAllItems", () => { beforeAll(setUpStorage); it("retrieves all values", async () => { const result = await sessionStorage.getAllItems(); expect(result).toEqual( expect.objectContaining({ [test_key]: test_value, [obj_key]: obj_value, }) ); }); it("works as a bound method", async () => { const getAllItems = sessionStorage.getAllItems; const result = await getAllItems(); expect(result).toEqual( expect.objectContaining({ [test_key]: test_value, [obj_key]: obj_value, }) ); }); it("retrieves all values in a namespace", async () => { const result = await sessionStorage.getAllItems(test_namespace); expect(result).toEqual( expect.objectContaining({ [namespaced_key]: namespaced_value }) ); }); it("throws if an error happen on native side", async () => { expect(() => sessionStorage.getAllItems("undefined_namespace") ).rejects.toThrowErrorMatchingSnapshot(); }); }); });