File size: 2,160 Bytes
bf48b89
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import http from 'node:http';

import { http as mswHttp, HttpResponse } from 'msw';
import { afterEach, describe, expect, it, vi } from 'vitest';

const loadOfetchWithLogger = async () => {
    vi.resetModules();
    const { default: logger } = await import('@/utils/logger');
    const { default: ofetch } = await import('@/utils/ofetch');
    return { logger, ofetch };
};

afterEach(() => {
    vi.restoreAllMocks();
    vi.unstubAllGlobals();
});

describe('ofetch', () => {
    it('marks prefer-proxy header on retryable responses', async () => {
        const { default: server } = await import('@/setup.test');
        server.use(mswHttp.get('http://rsshub.test/fail-500', () => HttpResponse.text('fail', { status: 500 })));

        const { logger, ofetch } = await loadOfetchWithLogger();
        const warnSpy = vi.spyOn(logger, 'warn').mockImplementation(() => logger);

        await expect(
            ofetch('http://rsshub.test/fail-500', {
                retry: 1,
                retryDelay: 0,
                onResponse({ options }) {
                    options.headers = null as unknown as Headers;
                },
            })
        ).rejects.toBeDefined();

        expect(warnSpy).toHaveBeenCalled();
    });

    it('logs redirected responses', async () => {
        const { logger, ofetch } = await loadOfetchWithLogger();
        const httpSpy = vi.spyOn(logger, 'http').mockImplementation(() => logger);

        const server = http.createServer((req, res) => {
            if (req.url === '/redirect') {
                res.statusCode = 302;
                res.setHeader('Location', '/target');
                res.end();
                return;
            }
            res.statusCode = 200;
            res.end('ok');
        });

        await new Promise<void>((resolve) => server.listen(0, resolve));
        const address = server.address();
        const port = typeof address === 'object' && address ? address.port : 0;

        try {
            await ofetch(`http://127.0.0.1:${port}/redirect`);
        } finally {
            server.close();
        }

        expect(httpSpy).toHaveBeenCalled();
    });
});