Skip to content

Commit d041144

Browse files
committed
fix(tests,linting): resolve test hanging and eslint warnings in useSSE
1 parent b4db9c5 commit d041144

File tree

3 files changed

+46
-33
lines changed

3 files changed

+46
-33
lines changed

packages/scene-react/test/useSSE.spec.tsx

+24-19
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,18 @@
11
import { undefinedValue } from '@/helper/variables';
22
import '@testing-library/jest-dom';
33
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
4-
import { Alova, createAlova } from 'alova';
4+
import { createAlova } from 'alova';
55
import GlobalFetch from 'alova/GlobalFetch';
66
import ReactHook from 'alova/react';
77
import ES from 'eventsource';
88
import { AddressInfo } from 'net';
99
import React, { ReactElement } from 'react';
1010
import { IntervalEventName, IntervalMessage, TriggerEventName, server, send as serverSend } from '~/test/sseServer';
1111
import { getAlovaInstance, untilCbCalled } from '~/test/utils';
12-
import { FetchRequestInit } from '~/typings/general';
13-
import { ReactState, useSSE } from '..';
12+
import { useSSE } from '..';
1413
import { AlovaSSEMessageEvent, SSEHookReadyState } from '../typings/general';
1514
Object.defineProperty(global, 'EventSource', { value: ES, writable: false });
1615

17-
let alovaInst: Alova<ReactState<any>, unknown, FetchRequestInit, any, any>;
18-
1916
afterEach(() => {
2017
server.close();
2118
});
@@ -28,29 +25,28 @@ type AnyMessageType<T = any> = AlovaSSEMessageEvent<T, any, any, any, any, any,
2825
const prepareAlova = async () => {
2926
await server.listen();
3027
const { port } = server.address() as AddressInfo;
31-
alovaInst = createAlova({
28+
return createAlova({
3229
baseURL: `http://127.0.0.1:${port}`,
3330
statesHook: ReactHook,
3431
requestAdapter: GlobalFetch(),
3532
cacheLogger: false
36-
}) as any;
33+
});
3734
};
3835

3936
describe('react => useSSE', () => {
4037
// ! 无初始数据,不立即发送请求
4138
test('should default not request immediately', async () => {
42-
await prepareAlova();
39+
const alovaInst = await prepareAlova();
4340
const poster = (data: any) => alovaInst.Get(`/${IntervalEventName}`, data);
4441

4542
let recv = undefinedValue;
4643
const mockOpenFn = jest.fn();
4744
const mockOnFn = jest.fn((event: AnyMessageType) => {
4845
recv = event.data;
4946
});
50-
// const mockOpenFn = jest.fn();
5147

5248
const Page = () => {
53-
const { on, onOpen, data, readyState, send } = useSSE(poster);
49+
const { on, onOpen, data, readyState, send, close } = useSSE(poster);
5450
on(IntervalEventName, mockOnFn);
5551
onOpen(mockOpenFn);
5652

@@ -69,6 +65,11 @@ describe('react => useSSE', () => {
6965
onClick={send}>
7066
send request
7167
</button>
68+
<button
69+
role="close-btn"
70+
onClick={close}>
71+
close
72+
</button>
7273
</div>
7374
);
7475
};
@@ -94,11 +95,15 @@ describe('react => useSSE', () => {
9495
},
9596
{ timeout: 4000 }
9697
);
98+
99+
fireEvent.click(screen.getByRole('close-btn'));
100+
await untilCbCalled(setTimeout, 200);
101+
expect(screen.getByRole('status')).toHaveTextContent('closed');
97102
});
98103

99104
// ! 有初始数据,不立即发送请求
100105
test('should get the initial data and NOT send request immediately', async () => {
101-
await prepareAlova();
106+
const alovaInst = await prepareAlova();
102107
const poster = (data: any) => alovaInst.Get(`/${TriggerEventName}`, data);
103108
const initialData = 'initial-data';
104109
const testDataA = 'test-data-1';
@@ -178,7 +183,7 @@ describe('react => useSSE', () => {
178183

179184
// ! 有初始数据,立即发送请求
180185
test('should get the initial data and send request immediately', async () => {
181-
await prepareAlova();
186+
const alovaInst = await prepareAlova();
182187
const poster = (data: any) => alovaInst.Get(`/${TriggerEventName}`, data);
183188
const initialData = 'initial-data';
184189
const testDataA = 'test-data-1';
@@ -230,7 +235,7 @@ describe('react => useSSE', () => {
230235

231236
// ! 测试关闭后重新连接
232237
test('should not trigger handler after close', async () => {
233-
await prepareAlova();
238+
const alovaInst = await prepareAlova();
234239
const poster = (data: any) => alovaInst.Get(`/${TriggerEventName}`, data);
235240
const testDataA = 'test-data-1';
236241
const testDataB = 'test-data-2';
@@ -327,7 +332,7 @@ describe('react => useSSE', () => {
327332

328333
// ! 打开失败应该报错,立即发送请求
329334
test('should throw error then try to connect a not exist url', async () => {
330-
await prepareAlova();
335+
const alovaInst = await prepareAlova();
331336
const poster = (data: any) => alovaInst.Get('/not-exist-path', data);
332337

333338
let recv = undefinedValue;
@@ -359,7 +364,7 @@ describe('react => useSSE', () => {
359364

360365
render((<Page />) as ReactElement<any, any>);
361366

362-
await untilCbCalled(setTimeout, 500);
367+
await untilCbCalled(setTimeout, 1500);
363368
await screen.findByText(/closed/);
364369

365370
expect(screen.getByRole('data')).toBeEmptyDOMElement();
@@ -371,7 +376,7 @@ describe('react => useSSE', () => {
371376

372377
// ! 打开失败应该报错,不立即发送请求
373378
test('should throw error then try to connect a not exist url (immediate: false)', async () => {
374-
await prepareAlova();
379+
const alovaInst = await prepareAlova();
375380
const poster = (data: any) => alovaInst.Get('/not-exist-path', data);
376381

377382
let recv = undefinedValue;
@@ -399,7 +404,7 @@ describe('react => useSSE', () => {
399404
<span role="data">{data}</span>
400405
<button
401406
role="send"
402-
onClick={send}>
407+
onClick={() => send()}>
403408
send request
404409
</button>
405410
</div>
@@ -441,7 +446,7 @@ describe('react => useSSE', () => {
441446
const mockResponseErrorFn = jest.fn();
442447
const mockResponseCompleteFn = jest.fn();
443448

444-
alovaInst = getAlovaInstance(ReactHook, {
449+
const alovaInst = getAlovaInstance(ReactHook, {
445450
baseURL: `http://localhost:${port}`,
446451
responseExpect: data => {
447452
mockResponseFn();
@@ -600,7 +605,7 @@ describe('react => useSSE', () => {
600605
const mockResponseErrorFn = jest.fn();
601606
const mockResponseCompleteFn = jest.fn();
602607

603-
alovaInst = getAlovaInstance(ReactHook, {
608+
const alovaInst = getAlovaInstance(ReactHook, {
604609
baseURL: `http://localhost:${port}`,
605610
responseExpect: () => {
606611
mockResponseFn();

packages/scene-vue/test/useSSE.spec.ts

+20-13
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,27 @@
1+
import { usePromise } from '@/helper';
12
import '@testing-library/jest-dom';
23
import { fireEvent, render, screen, waitFor } from '@testing-library/vue';
3-
import { Alova, createAlova } from 'alova';
4+
import { createAlova } from 'alova';
45
import GlobalFetch from 'alova/GlobalFetch';
56
import VueHook from 'alova/vue';
67
import ES from 'eventsource';
78
import { AddressInfo } from 'net';
8-
import { Ref } from 'vue';
99
import { IntervalEventName, IntervalMessage, TriggerEventName, server, send as serverSend } from '~/test/sseServer';
1010
import { untilCbCalled } from '~/test/utils';
11-
import { AnyFn, FetchRequestInit, SSEHookReadyState } from '~/typings/general';
11+
import { AnyFn, SSEHookReadyState } from '~/typings/general';
1212
import { useSSE } from '..';
1313
import { AlovaSSEMessageEvent } from '../typings/general';
1414
import CompUseSSEGlobalResponse from './components/use-sse-global-response.vue';
1515
import CompUseSSE from './components/use-sse.vue';
1616

1717
Object.defineProperty(global, 'EventSource', { value: ES, writable: false });
1818

19-
let alovaInst: Alova<Ref<unknown>, Ref<unknown>, FetchRequestInit, Response, Headers>;
20-
2119
afterEach(() => {
22-
server.close();
20+
const { promise, resolve } = usePromise();
21+
if (server.listening) {
22+
server.close(resolve);
23+
return promise;
24+
}
2325
});
2426

2527
type AnyMessageType<T = any> = AlovaSSEMessageEvent<T, any, any, any, any, any, any, any>;
@@ -30,7 +32,7 @@ type AnyMessageType<T = any> = AlovaSSEMessageEvent<T, any, any, any, any, any,
3032
const prepareAlova = async () => {
3133
await server.listen();
3234
const { port } = server.address() as AddressInfo;
33-
alovaInst = createAlova({
35+
return createAlova({
3436
baseURL: `http://127.0.0.1:${port}`,
3537
statesHook: VueHook,
3638
requestAdapter: GlobalFetch(),
@@ -41,9 +43,9 @@ const prepareAlova = async () => {
4143
describe('vue => useSSE', () => {
4244
// ! 无初始数据,不立即发送请求
4345
test('should default NOT request immediately', async () => {
44-
await prepareAlova();
46+
const alovaInst = await prepareAlova();
4547
const poster = (data: any) => alovaInst.Get(`/${IntervalEventName}`, data);
46-
const { on, onOpen, data, readyState, send } = useSSE(poster);
48+
const { on, onOpen, data, readyState, send, close } = useSSE(poster);
4749
const cb = jest.fn();
4850
const openCb = jest.fn();
4951
on(IntervalEventName, cb);
@@ -67,25 +69,26 @@ describe('vue => useSSE', () => {
6769
await untilCbCalled(setTimeout, 100);
6870
expect(openCb).toHaveBeenCalled();
6971

70-
const { data: recvData } = (await untilCbCalled(onIntervalCb)) as AnyMessageType<string>;
72+
const { data: recvData } = (await untilCbCalled(onIntervalCb)) as AnyMessageType;
7173

7274
expect(readyState.value).toStrictEqual(SSEHookReadyState.OPEN);
7375
expect(cb).toHaveBeenCalled();
7476

7577
expect(recvData).toEqual(IntervalMessage);
7678
expect(data.value).toStrictEqual(IntervalMessage);
79+
close();
7780
}, 3000);
7881

7982
// ! 有初始数据,不立即发送请求
8083
test('should get the initial data and NOT send request immediately', async () => {
81-
await prepareAlova();
84+
const alovaInst = await prepareAlova();
8285
const poster = (data: any) => alovaInst.Get(`/${TriggerEventName}`, data);
8386
const initialData = {
8487
id: 9527,
8588
name: 'Tom',
8689
age: 18
8790
};
88-
const { onMessage, onOpen, data, readyState, send } = useSSE(poster, { initialData });
91+
const { onMessage, onOpen, data, readyState, send, close } = useSSE(poster, { initialData });
8992

9093
const testDataA = 'test-data-1';
9194
const testDataB = 'test-data-2';
@@ -117,13 +120,14 @@ describe('vue => useSSE', () => {
117120
await send();
118121
serverSend(testDataB);
119122

120-
const { data: recvData } = (await untilCbCalled(onMessage)) as AnyMessageType<string>;
123+
const { data: recvData } = (await untilCbCalled(onMessage)) as AnyMessageType;
121124

122125
expect(readyState.value).toStrictEqual(SSEHookReadyState.OPEN);
123126
expect(cb).toHaveBeenCalled();
124127

125128
expect(recvData).toEqual(testDataB);
126129
expect(data.value).toStrictEqual(testDataB);
130+
close();
127131
});
128132

129133
// ! 有初始数据,立即发送请求
@@ -145,6 +149,7 @@ describe('vue => useSSE', () => {
145149
expect(screen.getByRole('data')).toHaveTextContent(initialData);
146150

147151
await screen.findByText(/opened/);
152+
await untilCbCalled(setTimeout, 100);
148153

149154
expect(screen.getByRole('onopen').innerHTML).toStrictEqual('1');
150155

@@ -291,6 +296,7 @@ describe('vue => useSSE', () => {
291296
expect(screen.getByRole('data')).toHaveTextContent(initialData);
292297

293298
await screen.findByText(/opened/);
299+
await untilCbCalled(setTimeout, 100);
294300

295301
expect(screen.getByRole('onopen').innerHTML).toStrictEqual('1');
296302
expect(screen.getByRole('on-response').innerHTML).toStrictEqual('0');
@@ -375,6 +381,7 @@ describe('vue => useSSE', () => {
375381
expect(screen.getByRole('data')).toHaveTextContent(initialData);
376382

377383
await screen.findByText(/opened/);
384+
await untilCbCalled(setTimeout, 100);
378385

379386
expect(screen.getByRole('onopen').innerHTML).toStrictEqual('1');
380387
expect(screen.getByRole('on-response').innerHTML).toStrictEqual('0');

src/hooks/useSSE.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ export default <Data, S, E, R, T, RC, RE, RH>(
164164
*/
165165
const createSSEEvent = async (eventFrom: keyof EventSourceEventMap, dataOrError: Promise<any>) => {
166166
assert(!!eventSource.current, 'EventSource is not initialized');
167+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
167168
const es = eventSource.current!;
168169

169170
const ev = (type: AlovaHookEventType, data?: any, error?: Error) => {
@@ -362,7 +363,7 @@ export default <Data, S, E, R, T, RC, RE, RH>(
362363
});
363364
});
364365

365-
return promiseObj!.promise;
366+
return promiseObj.promise;
366367
});
367368

368369
onUnmounted$(() => {

0 commit comments

Comments
 (0)