Skip to content

Commit

Permalink
add react native items
Browse files Browse the repository at this point in the history
  • Loading branch information
GuilhermeAlbert committed Aug 3, 2024
1 parent 81a977e commit 4134a2d
Show file tree
Hide file tree
Showing 33 changed files with 538 additions and 40 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { EntityItem } from "../../entities/entity-item.entity";
import { EntityItem } from "../../../src/common/entities/entity-item.entity";

describe("EntityItem Interface", () => {
it("should allow a string label and value", () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
ResponseEncodings,
ResponseHeaders,
ResponseTypes,
} from "../../enums/http.enum";
} from "../../common/enums/http.enum";

describe("HTTP Enums", () => {
it("should have correct values for ContentTypes", () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { TimeDurations } from "../../enums/time-duration.enum";
import { TimeDurations } from "../../../src/common/enums/time-duration.enum";

describe("TimeDurations Enum", () => {
it("should have correct values", () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
getLastWord,
getPluralOrSingular,
isShortWord,
} from "../../helpers/string.helper";
} from "../../../src/common/helpers/string.helper";

describe("String Utilities", () => {
it("should get the first word", () => {
Expand Down
52 changes: 52 additions & 0 deletions __tests__/react-native/helpers/storage.helper.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import AsyncStorage from "@react-native-async-storage/async-storage";
import {
setStorageItem,
getStorageItem,
removeStorageItem,
multiRemoveFromStorage,
} from "react-native/helpers/storage.helper";

jest.mock("@react-native-async-storage/async-storage");

describe("storage.helper", () => {
beforeEach(() => {
jest.clearAllMocks();
});

test("setStorageItem sets an item in AsyncStorage", async () => {
const key = "testKey";
const value = "testValue";

await setStorageItem(key, value);

expect(AsyncStorage.setItem).toHaveBeenCalledWith(key, value);
});

test("getStorageItem gets an item from AsyncStorage", async () => {
const key = "testKey";
const value = "testValue";

(AsyncStorage.getItem as jest.Mock).mockResolvedValueOnce(value);

const result = await getStorageItem(key);

expect(AsyncStorage.getItem).toHaveBeenCalledWith(key);
expect(result).toBe(value);
});

test("removeStorageItem removes an item from AsyncStorage", async () => {
const key = "testKey";

await removeStorageItem(key);

expect(AsyncStorage.removeItem).toHaveBeenCalledWith(key);
});

test("multiRemoveFromStorage removes multiple items from AsyncStorage", async () => {
const keys = ["testKey1", "testKey2"];

await multiRemoveFromStorage(keys);

expect(AsyncStorage.multiRemove).toHaveBeenCalledWith(keys);
});
});
60 changes: 60 additions & 0 deletions __tests__/react-native/hooks/async-storage-cache.hook.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { TimeDurations } from "common/enums/time-duration.enum";
import { useAsyncStorageCache } from "react-native/hooks/async-storage-cache.hook";
import AsyncStorage from "@react-native-async-storage/async-storage";

jest.mock("@react-native-async-storage/async-storage");

describe("useAsyncStorageCache", () => {
beforeEach(() => {
jest.clearAllMocks();
});

it("should set item in cache with expiration", async () => {
const { setItem } = useAsyncStorageCache();
const key = "test-key";
const value = "test-value";
const expiration = TimeDurations.FiveMinutes;

await setItem(key, value, expiration);

const calls = (AsyncStorage.setItem as jest.Mock).mock.calls[0];
const cachedItem = JSON.parse(calls[1]);

expect(calls[0]).toBe(key);
expect(cachedItem.value).toBe(value);
expect(typeof cachedItem.expireAt).toBe("number");
});

it("should get item from cache if not expired", async () => {
const { getItem } = useAsyncStorageCache();
const key = "test-key";
const value = "test-value";
const expireAt = Date.now() + TimeDurations.FiveMinutes;

(AsyncStorage.getItem as jest.Mock).mockResolvedValueOnce(
JSON.stringify({ value, expireAt })
);

const result = await getItem(key);

expect(AsyncStorage.getItem).toHaveBeenCalledWith(key);
expect(result).toBe(value);
});

it("should return null if item is expired", async () => {
const { getItem } = useAsyncStorageCache();
const key = "test-key";
const value = "test-value";
const expireAt = Date.now() - TimeDurations.FiveMinutes; // Already expired

(AsyncStorage.getItem as jest.Mock).mockResolvedValueOnce(
JSON.stringify({ value, expireAt })
);

const result = await getItem(key);

expect(AsyncStorage.getItem).toHaveBeenCalledWith(key);
expect(AsyncStorage.removeItem).toHaveBeenCalledWith(key);
expect(result).toBeNull();
});
});
67 changes: 67 additions & 0 deletions __tests__/react-native/hooks/entity-loader.hook.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { renderHook, act } from "@testing-library/react-hooks";
import AsyncStorage from "@react-native-async-storage/async-storage";
import { useEntityLoader } from "react-native/hooks/entity-loader.hook";
import { TimeDurations } from "common/enums/time-duration.enum";

jest.mock("@react-native-async-storage/async-storage", () => ({
getItem: jest.fn(),
setItem: jest.fn(),
removeItem: jest.fn(),
}));

const mockFetchFunction = jest.fn();

describe("useEntityLoader", () => {
beforeEach(() => {
jest.clearAllMocks();
});

it("should load data from cache if available", async () => {
const cachedData = [{ id: 1, name: "test" }];
(AsyncStorage.getItem as jest.Mock).mockResolvedValueOnce(
JSON.stringify({
value: cachedData,
expireAt: Date.now() + TimeDurations.OneDay,
})
);

const { result, waitForNextUpdate } = renderHook(() =>
useEntityLoader({
fetchFunction: mockFetchFunction,
cacheKey: "test-cache",
cacheExpiration: TimeDurations.OneDay,
labelField: "name",
valueField: "id",
})
);

await waitForNextUpdate();

expect(result.current.items).toEqual(cachedData);
expect(result.current.isLoading).toBe(false);
expect(AsyncStorage.getItem).toHaveBeenCalledWith("test-cache");
});

it("should fetch data and set cache if no cached data", async () => {
const fetchedData = [{ id: 1, name: "test" }];
mockFetchFunction.mockResolvedValueOnce(fetchedData);
(AsyncStorage.getItem as jest.Mock).mockResolvedValueOnce(null);

const { result, waitForNextUpdate } = renderHook(() =>
useEntityLoader({
fetchFunction: mockFetchFunction,
cacheKey: "test-cache",
cacheExpiration: TimeDurations.OneDay,
labelField: "name",
valueField: "id",
})
);

await waitForNextUpdate();

expect(result.current.items).toEqual(fetchedData);
expect(result.current.isLoading).toBe(false);
expect(mockFetchFunction).toHaveBeenCalled();
expect(AsyncStorage.setItem).toHaveBeenCalled();
});
});
63 changes: 63 additions & 0 deletions __tests__/react-native/hooks/object-loader.hook.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { renderHook, act } from "@testing-library/react-hooks";
import AsyncStorage from "@react-native-async-storage/async-storage";
import { useObjectLoader } from "react-native/hooks/object-loader.hook";
import { TimeDurations } from "common/enums/time-duration.enum";

jest.mock("@react-native-async-storage/async-storage", () => ({
getItem: jest.fn(),
setItem: jest.fn(),
removeItem: jest.fn(),
}));

const mockFetchObjectFunction = jest.fn();

describe("useObjectLoader", () => {
beforeEach(() => {
jest.clearAllMocks();
});

it("should load object from cache if available", async () => {
const cachedObject = { id: 1, name: "test" };
(AsyncStorage.getItem as jest.Mock).mockResolvedValueOnce(
JSON.stringify({
value: cachedObject,
expireAt: Date.now() + TimeDurations.OneDay,
})
);

const { result, waitForNextUpdate } = renderHook(() =>
useObjectLoader({
fetchFunction: mockFetchObjectFunction,
cacheKey: "test-cache-object",
cacheExpiration: TimeDurations.OneDay,
})
);

await waitForNextUpdate();

expect(result.current.item).toEqual(cachedObject);
expect(result.current.isLoading).toBe(false);
expect(AsyncStorage.getItem).toHaveBeenCalledWith("test-cache-object");
});

it("should fetch object and set cache if no cached object", async () => {
const fetchedObject = { id: 1, name: "test" };
mockFetchObjectFunction.mockResolvedValueOnce(fetchedObject);
(AsyncStorage.getItem as jest.Mock).mockResolvedValueOnce(null);

const { result, waitForNextUpdate } = renderHook(() =>
useObjectLoader({
fetchFunction: mockFetchObjectFunction,
cacheKey: "test-cache-object",
cacheExpiration: TimeDurations.OneDay,
})
);

await waitForNextUpdate();

expect(result.current.item).toEqual(fetchedObject);
expect(result.current.isLoading).toBe(false);
expect(mockFetchObjectFunction).toHaveBeenCalled();
expect(AsyncStorage.setItem).toHaveBeenCalled();
});
});
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { renderHook } from "@testing-library/react-hooks";
import { useCache, CachedData } from "../../hooks/cache.hook";
import { TimeDurations } from "../../enums/time-duration.enum";
import { TimeDurations } from "common/enums/time-duration.enum";
import { CachedData, useCache } from "web/hooks";

describe("useCache Hook", () => {
const cacheKey = "test-key";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { renderHook, act } from "@testing-library/react-hooks";
import { renderHook } from "@testing-library/react-hooks";
import { AxiosResponse } from "axios";
import { TimeDurations } from "../../enums/time-duration.enum";
import { CachedData, useCache } from "../../hooks/cache.hook";
import { FetchFunction, useEntityLoader } from "../../hooks/entity-loader.hook";
import { TimeDurations } from "common/enums/time-duration.enum";
import { FetchFunction, useCache, useEntityLoader } from "web/hooks";

jest.mock("../../hooks/cache.hook");
jest.mock("web/hooks/cache.hook");

describe("useEntityLoader Hook", () => {
const originalError = console.error;
Expand Down
10 changes: 0 additions & 10 deletions jest.config.js

This file was deleted.

14 changes: 14 additions & 0 deletions jest.react-native.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module.exports = {
roots: ["<rootDir>/__tests__/react-native", "<rootDir>/src/react-native"],
transform: {
"^.+\\.tsx?$": "ts-jest",
},
testRegex: "(/__tests__/react-native/.*|(\\.|/)(test|spec))\\.tsx?$",
moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"],
collectCoverage: true,
coverageDirectory: "coverage/react-native",
moduleNameMapper: {
"^common/(.*)$": "<rootDir>/src/common/$1",
"^react-native/(.*)$": "<rootDir>/src/react-native/$1",
},
};
14 changes: 14 additions & 0 deletions jest.web.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module.exports = {
roots: ["<rootDir>/__tests__/react-native", "<rootDir>/src/react-native"],
transform: {
"^.+\\.tsx?$": "ts-jest",
},
testRegex: "(/__tests__/react-native/.*|(\\.|/)(test|spec))\\.tsx?$",
moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"],
collectCoverage: true,
coverageDirectory: "coverage/react-native",
moduleNameMapper: {
"^common/(.*)$": "<rootDir>/src/common/$1",
"^react-native/(.*)$": "<rootDir>/src/react-native/$1",
},
};
25 changes: 21 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,27 @@
"name": "@trebla/lyra",
"version": "1.0.2",
"description": "A utility library.",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"main": "dist/web/index.js",
"types": "dist/web/index.d.ts",
"exports": {
".": {
"import": "./dist/web/index.js",
"require": "./dist/web/index.js"
},
"./react-native": {
"import": "./dist/react-native/index.js",
"require": "./dist/react-native/index.js"
},
"./common": {
"import": "./dist/common/index.js",
"require": "./dist/common/index.js"
}
},
"scripts": {
"build": "tsc",
"test": "jest",
"build": "tsc -p tsconfig.web.json && tsc -p tsconfig.react-native.json",
"test:web": "jest --config jest.web.config.js",
"test:react-native": "jest --config jest.react-native.config.js",
"test": "yarn test:web && yarn test:react-native",
"lint": "eslint . --ext .ts,.tsx",
"prepublishOnly": "yarn build"
},
Expand All @@ -28,6 +44,7 @@
"react": "^17.0.0"
},
"devDependencies": {
"@react-native-async-storage/async-storage": "^1.24.0",
"@testing-library/react-hooks": "7.0.0",
"@types/jest": "^29.5.12",
"@types/node": "^16.0.0",
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
6 changes: 3 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export * from "./helpers";
export * from "./hooks";
export * from "./enums";
export * from "./common/helpers";
export * from "./common/hooks";
export * from "./common/enums";
Loading

0 comments on commit 4134a2d

Please sign in to comment.