PluginProbe
Extendify / 3.0.6
Extendify v3.0.6
3.2.1 3.2.0 3.1.6 3.1.5 3.1.4 3.1.3 3.1.2 3.1.1 3.1.0 3.0.6 3.0.5 3.0.4 trunk 0.1.0 0.10.0 0.10.1 0.10.2 0.11.0 0.11.1 0.2.0 0.3.0 0.3.1 0.4.0 0.5.0 0.6.0 All 127 releases
extendify / src / Launch / api / __tests__ / getSiteImages.test.js

getSiteImages.test.js in Extendify 3.0.6, at src/Launch/api/__tests__/getSiteImages.test.js

119 lines 2.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import { getSiteImages } from '@launch/api/DataApi';
2
3 jest.mock(
4 './getSiteImages.deps',
5 () => ({
6 IMAGES_HOST: 'https://img.example.com',
7 extraBody: { foo: 'bar', baz: 'qux' },
8 useUserSelectionStore: {
9 getState: jest.fn(() => ({ siteInformation: { title: 'My Site' } })),
10 },
11 }),
12 { virtual: true },
13 );
14
15 const makeResponse = (ok, body) => ({
16 ok,
17 json: async () => body,
18 });
19
20 describe('getSiteImages', () => {
21 const originalFetch = global.fetch;
22 const originalAbortSignal = global.AbortSignal;
23
24 beforeEach(() => {
25 jest.resetAllMocks();
26
27 global.fetch = jest.fn();
28 global.AbortSignal = {
29 ...originalAbortSignal,
30 timeout: jest.fn((ms) => ({ __fakeTimeoutSignal: true, ms })),
31 };
32 });
33
34 afterEach(() => {
35 global.fetch = originalFetch;
36 global.AbortSignal = originalAbortSignal;
37 });
38
39 test('returns fallback when response.ok = false', async () => {
40 global.fetch.mockResolvedValueOnce(makeResponse(false, {}));
41
42 const data = await getSiteImages({
43 aiSiteType: 'x',
44 aiSiteCategory: 'y',
45 aiDescription: 'z',
46 aiKeywords: 'k',
47 });
48
49 expect(data).toEqual({ siteImages: [] });
50 });
51
52 test('returns fallback when json() throws an error (invalid body)', async () => {
53 global.fetch.mockResolvedValueOnce({
54 ok: true,
55 json: () => {
56 throw new Error('invalid json');
57 },
58 });
59
60 const data = await getSiteImages({
61 aiSiteType: 'x',
62 aiSiteCategory: 'y',
63 aiDescription: 'z',
64 aiKeywords: 'k',
65 });
66
67 expect(data).toEqual({ siteImages: [] });
68 });
69
70 test('handles first timeout → retries → succeeds', async () => {
71 global.fetch
72 .mockRejectedValueOnce(new Error('AbortError: The operation was aborted'))
73 .mockResolvedValueOnce(makeResponse(true, { siteImages: ['ok.jpg'] }));
74
75 const data = await getSiteImages({
76 aiSiteType: 'x',
77 aiSiteCategory: 'y',
78 aiDescription: 'z',
79 aiKeywords: 'k',
80 });
81
82 expect(global.fetch).toHaveBeenCalledTimes(2);
83 expect(data).toEqual({ siteImages: ['ok.jpg'] });
84
85 expect(global.AbortSignal.timeout).toHaveBeenCalledTimes(2);
86 expect(global.AbortSignal.timeout).toHaveBeenNthCalledWith(1, 10000);
87 expect(global.AbortSignal.timeout).toHaveBeenNthCalledWith(2, 10000);
88 });
89
90 test('handles first timeout → second timeout → returns fallback', async () => {
91 global.fetch
92 .mockRejectedValueOnce(new Error('AbortError: timeout 1'))
93 .mockRejectedValueOnce(new Error('AbortError: timeout 2'));
94
95 const data = await getSiteImages({
96 aiSiteType: 'x',
97 aiSiteCategory: 'y',
98 aiDescription: 'z',
99 aiKeywords: 'k',
100 });
101
102 expect(global.fetch).toHaveBeenCalledTimes(2);
103 expect(data).toEqual({ siteImages: [] });
104 });
105
106 test('returns fallback when response body lacks siteImages', async () => {
107 global.fetch.mockResolvedValueOnce(makeResponse(true, { whatever: 123 }));
108
109 const data = await getSiteImages({
110 aiSiteType: 'x',
111 aiSiteCategory: 'y',
112 aiDescription: 'z',
113 aiKeywords: 'k',
114 });
115
116 expect(data).toEqual({ siteImages: [] });
117 });
118 });
119