Skip to content

Commit f6a23f9

Browse files
authored
test(#19|#17) write tests for cache (#21)
* test(#19|#17) write tests for cache * ci(test): run unit tests in ci
1 parent 4d49ae5 commit f6a23f9

6 files changed

Lines changed: 278 additions & 22 deletions

File tree

.github/workflows/test.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ jobs:
3333
run: npm ci && npm run build
3434
working-directory: ./
3535

36+
- name: Test Unit
37+
run: npm run test:cover
38+
working-directory: ./
39+
3640
- name: dotenv
3741
run: echo "${{ secrets.ENV_FILE }}" >> .env
3842

@@ -42,5 +46,5 @@ jobs:
4246
- name: Seed
4347
run: npm run seed:example
4448

45-
- name: Test
49+
- name: Test Integration
4650
run: npm run test:cover

package-lock.json

Lines changed: 169 additions & 18 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,16 @@
4141
"check": "biome check",
4242
"check:fix": "biome check --write",
4343
"test:ts:back": "run -T tsc -p server/tsconfig.json",
44+
"test:cover": "vitest run ./server --coverage",
45+
"test:watch": "vitest watch ./server",
4446
"release": "semantic-release"
4547
},
4648
"devDependencies": {
4749
"@biomejs/biome": "2.3.2",
4850
"@strapi/sdk-plugin": "^5",
4951
"@strapi/strapi": "^5",
5052
"@strapi/typescript-utils": "^5",
53+
"@vitest/coverage-v8": "^4.0.6",
5154
"semantic-release": "^25.0.1",
5255
"typescript": "^5.9.3",
5356
"vitest": "^4.0.6"

server/src/utils/getPopulateQuery.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import type { UID } from "@strapi/strapi";
22

33
// memory cache to only execute query generation ones per modelUid
44
// biome-ignore lint/suspicious/noExplicitAny: any object can be cached
5-
const queryCache: Partial<Record<UID.Schema, any>> = {};
5+
export const queryCache: Partial<Record<UID.Schema, any>> = {};
66

77
export const getPopulateQuery = (
88
modelUid: UID.Schema,
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import type { UID } from "@strapi/strapi";
2+
import { beforeEach, describe, expect, test, vi } from "vitest";
3+
import { getPopulateQuery, queryCache } from "../getPopulateQuery";
4+
5+
describe("getPopulateQuery: cache", () => {
6+
const mockStrapi = {
7+
log: { debug: vi.fn() },
8+
getModel: vi.fn(),
9+
plugin: vi.fn().mockReturnValue({ config: vi.fn() }),
10+
};
11+
12+
beforeEach(() => {
13+
// @ts-expect-error enough to mock
14+
global.strapi = mockStrapi;
15+
mockStrapi.log.debug.mockClear();
16+
mockStrapi.getModel.mockClear();
17+
mockStrapi.plugin.mockClear();
18+
19+
// reset cache
20+
Object.keys(queryCache).forEach((key) => {
21+
delete queryCache[key];
22+
});
23+
});
24+
25+
test("uses cache by default", () => {
26+
mockStrapi.getModel.mockReturnValue({
27+
attributes: { media: { type: "media" } },
28+
});
29+
30+
getPopulateQuery("model" as UID.Schema);
31+
32+
expect(queryCache).toEqual({ model: { populate: { media: true } } });
33+
});
34+
35+
test("uses cache if enabled", () => {
36+
mockStrapi.plugin.mockReturnValue({
37+
config: vi
38+
.fn()
39+
.mockImplementation((key) => (key === "cache" ? true : undefined)),
40+
});
41+
mockStrapi.getModel.mockReturnValue({
42+
attributes: { media: { type: "media" } },
43+
});
44+
45+
getPopulateQuery("model" as UID.Schema);
46+
47+
expect(queryCache).toEqual({ model: { populate: { media: true } } });
48+
});
49+
50+
test("skips cache if disabled", () => {
51+
mockStrapi.plugin.mockReturnValue({
52+
config: vi
53+
.fn()
54+
.mockImplementation((key) => (key === "cache" ? false : undefined)),
55+
});
56+
mockStrapi.getModel.mockReturnValue({
57+
attributes: { media: { type: "media" } },
58+
});
59+
60+
getPopulateQuery("model" as UID.Schema);
61+
62+
expect(queryCache).toEqual({});
63+
});
64+
65+
test("cache does not mutate original object", () => {
66+
mockStrapi.plugin.mockReturnValue({
67+
config: vi
68+
.fn()
69+
.mockImplementation((key) => (key === "cache" ? true : undefined)),
70+
});
71+
mockStrapi.getModel.mockReturnValue({
72+
attributes: {
73+
media: { type: "media" },
74+
},
75+
});
76+
77+
const result = getPopulateQuery("model" as UID.Schema);
78+
// @ts-expect-error: simulating race condition where `queryCache` gets overwritten by other call
79+
queryCache.model.populate.media = false;
80+
81+
expect(result).toEqual({
82+
populate: { media: true },
83+
});
84+
});
85+
});

0 commit comments

Comments
 (0)