Skip to content

Commit 40b4341

Browse files
authored
Merge pull request #38 from nebarf/tests
Tests
2 parents e4d160b + dd0087c commit 40b4341

36 files changed

+2599
-855
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -626,8 +626,8 @@ export class HttpSessionStorageCacheStore {
626626
* @inheritdoc
627627
*/
628628
flush() {
629-
this._keys().forEach((entry) => {
630-
this.delete(entry.identifier);
629+
this._keys().forEach((itemKey) => {
630+
this.delete(itemKey);
631631
});
632632
}
633633
}

jest.config.js

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,15 @@ module.exports = {
1212
// Runs special logic, such as cleaning up components
1313
// when using React Testing Library and adds special
1414
// extended assertions to Jest
15-
setupFilesAfterEnv: [
16-
// '@testing-library/react/cleanup-after-each',
17-
// '@testing-library/jest-dom/extend-expect',
18-
],
15+
setupFilesAfterEnv: ['./setup-jest.ts'],
1916

2017
// Test spec file resolution pattern
2118
// Matches parent folder `__tests__` and filename
22-
// should contain `test` or `spec`.
23-
testRegex: '(/__tests__/.*|(\\.|/)(test|spec))\\.tsx?$',
19+
// should contain `spec`.
20+
testRegex: '/__tests__/.*.spec.(ts|tsx)?$',
2421

2522
// Module file extensions for importing
2623
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
24+
25+
testEnvironment: 'jsdom',
2726
};

package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
"eslint-plugin-react-hooks": "^4.2.0",
3535
"husky": "^7.0.0",
3636
"jest": "^27.2.4",
37+
"jest-fetch-mock": "^3.0.3",
38+
"jest-mock-extended": "^2.0.4",
3739
"lint-staged": "^11.2.0",
3840
"prettier": "^2.4.1",
3941
"react": "^17.0.2",
@@ -64,8 +66,8 @@
6466
"release:patch": "release-it patch",
6567
"release:minor": "release-it minor",
6668
"release:major": "release-it major",
67-
"test": "jest -c ./jest.config.js",
68-
"test:watch": "jest -c ./jest.config.js --watch"
69+
"test": "jest -c ./jest.config.js --env=jsdom",
70+
"test:watch": "jest -c ./jest.config.js --watch --env=jsdom"
6971
},
7072
"peerDependencies": {
7173
"react": "^17.0.2",

setup-jest.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { enableFetchMocks } from 'jest-fetch-mock';
2+
3+
enableFetchMocks();
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { HttpCacheService, HttpInMemoryCacheStore } from '../../cache';
2+
import { HttpCacheStorePrefixDecorator } from '../../cache/prefix-decorator';
3+
4+
export class HttpCacheFixture {
5+
static defaultStore: HttpCacheStorePrefixDecorator = new HttpCacheStorePrefixDecorator(
6+
new HttpInMemoryCacheStore()
7+
);
8+
9+
static create(store?: HttpCacheStorePrefixDecorator): HttpCacheService {
10+
const fallenbackStore =
11+
store || new HttpCacheStorePrefixDecorator(new HttpInMemoryCacheStore());
12+
return new HttpCacheService(fallenbackStore);
13+
}
14+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import React, { ReactElement } from 'react';
2+
import { HttpClientConfigProvider, HttpClientProviderConfig } from '../..';
3+
4+
export class HttpClientProviderConfigFixture {
5+
static create<HttpRequestBodyT = void, HttpResponseT = unknown>(
6+
options: Partial<HttpClientProviderConfig<HttpRequestBodyT, HttpResponseT>> = {}
7+
): ({ children }: { children: ReactElement }) => ReactElement {
8+
const fallenbackOptions: Partial<HttpClientProviderConfig<HttpRequestBodyT, HttpResponseT>> =
9+
options;
10+
11+
return ({ children }: { children: ReactElement }): ReactElement => {
12+
const Provider = (
13+
<HttpClientConfigProvider config={fallenbackOptions}>{children}</HttpClientConfigProvider>
14+
);
15+
16+
return Provider;
17+
};
18+
}
19+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { HttpMethod, HttpRequest, HttpRequestProps } from '../..';
2+
3+
export class HttpRequestFixture {
4+
static defaultOptions: HttpRequestProps<undefined> = {
5+
baseUrl: 'http://rhf.com',
6+
method: HttpMethod.Get,
7+
relativeUrl: 'comments',
8+
};
9+
10+
static create<HttpRequestBodyT = void>(
11+
options?: HttpRequestProps<HttpRequestBodyT>
12+
): HttpRequest<HttpRequestBodyT> {
13+
const fallenbackOptions: HttpRequestProps<HttpRequestBodyT> = {
14+
...HttpRequestFixture.defaultOptions,
15+
...options,
16+
};
17+
18+
return new HttpRequest(fallenbackOptions);
19+
}
20+
}

src/__tests__/http-cache.spec.ts

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
import { HttpCacheFixture } from './fixtures/http-cache.fixture';
2+
import { HttpRequestFixture } from './fixtures/http-request.fixture';
3+
4+
describe('http-fetch', () => {
5+
afterEach(() => {
6+
jest.useRealTimers();
7+
});
8+
9+
beforeEach(() => {
10+
jest.useFakeTimers();
11+
jest.spyOn(global, 'setTimeout');
12+
});
13+
14+
test('should return undefined if no cached entry is found for the given identifier', () => {
15+
const httpCache = HttpCacheFixture.create();
16+
const httpRequest = HttpRequestFixture.create();
17+
const cachedEntry = httpCache.get(httpRequest);
18+
19+
expect(cachedEntry).toBeUndefined();
20+
});
21+
22+
test('should return the cached entry corresponding to the provided identifier', () => {
23+
const httpCache = HttpCacheFixture.create();
24+
const httpRequest = HttpRequestFixture.create({
25+
...HttpRequestFixture.defaultOptions,
26+
maxAge: 6000,
27+
});
28+
29+
const cachedResponse = { name: 'Phelony' };
30+
31+
httpCache.put(httpRequest, cachedResponse);
32+
const expiredCachedResponse = httpCache.get<{ name: string }, void>(httpRequest);
33+
34+
expect(expiredCachedResponse).toEqual(cachedResponse);
35+
expect(setTimeout).toHaveBeenCalledTimes(1);
36+
expect(setTimeout).toHaveBeenLastCalledWith(expect.any(Function), 6000);
37+
});
38+
39+
test('should remove the cached entry once expired', () => {
40+
const httpCache = HttpCacheFixture.create();
41+
const httpRequest = HttpRequestFixture.create({
42+
...HttpRequestFixture.defaultOptions,
43+
maxAge: 6000,
44+
});
45+
46+
const httpResponse = { name: 'Phelony' };
47+
48+
httpCache.put(httpRequest, httpResponse);
49+
const cachedResponse = httpCache.get<{ name: string }, void>(httpRequest);
50+
51+
expect(cachedResponse).toEqual(httpResponse);
52+
expect(setTimeout).toHaveBeenCalledTimes(1);
53+
expect(setTimeout).toHaveBeenLastCalledWith(expect.any(Function), 6000);
54+
55+
jest.runOnlyPendingTimers();
56+
const expiredCachedResponse = httpCache.get<{ name: string }, void>(httpRequest);
57+
expect(expiredCachedResponse).toBeUndefined();
58+
});
59+
60+
test('should tell if a cached response for a given request is expired', () => {
61+
const httpCache = HttpCacheFixture.create();
62+
const httpRequest = HttpRequestFixture.create({
63+
...HttpRequestFixture.defaultOptions,
64+
maxAge: 6000,
65+
});
66+
67+
httpCache.put(httpRequest, {});
68+
expect(httpCache.isExpired(httpRequest)).toBe(false);
69+
70+
jest.runOnlyPendingTimers();
71+
expect(httpCache.isExpired(httpRequest)).toBe(true);
72+
});
73+
74+
test('should tell if there is a cached response for the given request', () => {
75+
const httpCache = HttpCacheFixture.create();
76+
const httpRequest = HttpRequestFixture.create({
77+
...HttpRequestFixture.defaultOptions,
78+
maxAge: 6000,
79+
});
80+
81+
httpCache.put(httpRequest, {});
82+
expect(httpCache.has(httpRequest)).toBe(true);
83+
84+
jest.runOnlyPendingTimers();
85+
expect(httpCache.has(httpRequest)).toBe(false);
86+
});
87+
88+
test('should prune the cache by removing any expired entry', () => {
89+
const httpCache = HttpCacheFixture.create();
90+
const httpRequest = HttpRequestFixture.create({
91+
...HttpRequestFixture.defaultOptions,
92+
maxAge: 6000,
93+
});
94+
95+
httpCache.put(httpRequest, {});
96+
expect(httpCache.has(httpRequest)).toBe(true);
97+
98+
jest.runOnlyPendingTimers();
99+
expect(httpCache.has(httpRequest)).toBe(false);
100+
});
101+
102+
test('should flush the cache by removing all entries', () => {
103+
const httpCache = HttpCacheFixture.create();
104+
const firstHttpRequest = HttpRequestFixture.create({
105+
...HttpRequestFixture.defaultOptions,
106+
maxAge: 6000,
107+
relativeUrl: 'posts',
108+
});
109+
const secondHttpRequest = HttpRequestFixture.create({
110+
...HttpRequestFixture.defaultOptions,
111+
maxAge: 6000,
112+
relativeUrl: 'comments',
113+
});
114+
115+
httpCache.put(firstHttpRequest, {});
116+
httpCache.put(secondHttpRequest, {});
117+
118+
expect(httpCache.has(firstHttpRequest)).toBe(true);
119+
expect(httpCache.has(secondHttpRequest)).toBe(true);
120+
121+
httpCache.flush();
122+
expect(httpCache.has(firstHttpRequest)).toBe(false);
123+
expect(httpCache.has(secondHttpRequest)).toBe(false);
124+
});
125+
});

0 commit comments

Comments
 (0)