diff --git a/src/features/Apiexplorer/LoginDialog/index.tsx b/src/features/Apiexplorer/LoginDialog/index.tsx index 56f6995b..48f14d9b 100644 --- a/src/features/Apiexplorer/LoginDialog/index.tsx +++ b/src/features/Apiexplorer/LoginDialog/index.tsx @@ -1,7 +1,6 @@ import React, { useCallback } from 'react'; -import { Modal } from '@deriv/ui'; +import { Modal, Button } from '@deriv/ui'; import useLoginUrl from '@site/src/hooks/useLoginUrl'; -import { Button } from '@deriv/ui'; import styles from './LoginDialog.module.scss'; type TLoginDialog = { diff --git a/src/features/Apiexplorer/RequestJSONBox/__tests__/RequestJsonBox.test.tsx b/src/features/Apiexplorer/RequestJSONBox/__tests__/RequestJsonBox.test.tsx index a866f592..22795d03 100644 --- a/src/features/Apiexplorer/RequestJSONBox/__tests__/RequestJsonBox.test.tsx +++ b/src/features/Apiexplorer/RequestJSONBox/__tests__/RequestJsonBox.test.tsx @@ -3,14 +3,39 @@ import '@testing-library/jest-dom'; import { cleanup, render, screen } from '@testing-library/react'; import { TSocketEndpointNames } from '@site/src/configs/websocket/types'; import useAuthContext from '@site/src/hooks/useAuthContext'; +import useSubscription from '@site/src/hooks/useSubscription'; +import useWS from '@site/src/hooks/useWs'; import { IAuthContext } from '@site/src/contexts/auth/auth.context'; import userEvent from '@testing-library/user-event'; import RequestJSONBox from '..'; +const fakeHookObject = { + clear: jest.fn(), + send: jest.fn(), + full_response: { + tick: 1, + echo_req: { tick: 1 }, + }, +}; + jest.mock('@site/src/hooks/useAuthContext'); const mockUseAuthContext = useAuthContext as jest.MockedFunction<() => Partial>; +jest.mock('@site/src/hooks/useSubscription'); + +const mockUseSubscription = useSubscription as jest.MockedFunction< + () => Partial> +>; + +mockUseSubscription.mockImplementation(() => fakeHookObject); + +jest.mock('@site/src/hooks/useWs'); + +const mockuseWS = useWS as jest.MockedFunction<() => Partial>>; + +mockuseWS.mockImplementation(() => fakeHookObject); + describe('RequestResponseRenderer', () => { const mockProps = { handleChange: jest.fn(), diff --git a/src/features/Apiexplorer/RequestResponseRenderer/PlaygroundSection/JsonData/JsonData.module.scss b/src/features/Apiexplorer/RequestResponseRenderer/PlaygroundSection/JsonData/JsonData.module.scss new file mode 100644 index 00000000..11f9c1da --- /dev/null +++ b/src/features/Apiexplorer/RequestResponseRenderer/PlaygroundSection/JsonData/JsonData.module.scss @@ -0,0 +1,7 @@ +@use 'src/styles/utility' as *; + +.reactJsonContainer { + display: flex; + flex-direction: column; + gap: rem(2); +} \ No newline at end of file diff --git a/src/features/Apiexplorer/RequestResponseRenderer/PlaygroundSection/JsonData/index.tsx b/src/features/Apiexplorer/RequestResponseRenderer/PlaygroundSection/JsonData/index.tsx new file mode 100644 index 00000000..d146c507 --- /dev/null +++ b/src/features/Apiexplorer/RequestResponseRenderer/PlaygroundSection/JsonData/index.tsx @@ -0,0 +1,35 @@ +import React from 'react'; +import styles from './JsonData.module.scss'; +import { + TSocketEndpointNames, + TSocketSubscribableEndpointNames, + TSocketResponse, +} from '@site/src/configs/websocket/types'; + +const ReactJson = React.lazy(() => import('react-json-view')); + +type TJsonData = { + full_response: TSocketResponse; + error: unknown; + name: string; +}; + +const JsonData = ({ + full_response, + error, +}: TJsonData) => { + return ( + + {full_response !== null ? ( +
+ + +
+ ) : ( + + )} +
+ ); +}; + +export default JsonData; diff --git a/src/features/Apiexplorer/RequestResponseRenderer/PlaygroundSection/__tests__/PlaygroundSection.test.tsx b/src/features/Apiexplorer/RequestResponseRenderer/PlaygroundSection/__tests__/PlaygroundSection.test.tsx index 898dfa33..d723ffc5 100644 --- a/src/features/Apiexplorer/RequestResponseRenderer/PlaygroundSection/__tests__/PlaygroundSection.test.tsx +++ b/src/features/Apiexplorer/RequestResponseRenderer/PlaygroundSection/__tests__/PlaygroundSection.test.tsx @@ -4,19 +4,31 @@ import { render, screen } from '@testing-library/react'; describe('PlaygroundSection', () => { it('should render the loader', async () => { - render(); + render( + , + ); const loader = await screen.findByTestId('circles-loading'); expect(loader).toBeVisible(); }); it('should render the PlaygroundConsole', async () => { - render(); + render( + , + ); const playground_section = await screen.findByTestId('dt_playground_section'); expect(playground_section).toBeVisible(); }); it('should render the ReactJson', async () => { - render(); + render( + , + ); const playground_section = await screen.findByTestId('dt_playground_section'); expect(playground_section).toBeVisible(); diff --git a/src/features/Apiexplorer/RequestResponseRenderer/PlaygroundSection/index.tsx b/src/features/Apiexplorer/RequestResponseRenderer/PlaygroundSection/index.tsx index 571756b1..e195f5b4 100644 --- a/src/features/Apiexplorer/RequestResponseRenderer/PlaygroundSection/index.tsx +++ b/src/features/Apiexplorer/RequestResponseRenderer/PlaygroundSection/index.tsx @@ -1,26 +1,27 @@ import React, { Suspense } from 'react'; import { TSocketEndpointNames, - TSocketResponseData, TSocketSubscribableEndpointNames, + TSocketResponse, } from '@site/src/configs/websocket/types'; +import JsonData from './JsonData'; import Loader from '@site/src/components/Loader'; import styles from './PlaygroundSection.module.scss'; -const ReactJson = React.lazy(() => import('react-json-view')); - type TPlaygroundSection = { loader: boolean; response_state: boolean; - data: TSocketResponseData; + full_response: TSocketResponse; error: unknown; + name: string; }; const PlaygroundSection = ({ loader, response_state, - data, + full_response, error, + name, }: TPlaygroundSection) => { if (loader) return ; @@ -34,11 +35,7 @@ const PlaygroundSection = }>
- {data !== null ? ( - - ) : ( - - )} +
diff --git a/src/features/Apiexplorer/RequestResponseRenderer/index.tsx b/src/features/Apiexplorer/RequestResponseRenderer/index.tsx index 3950b9ff..e8eadeeb 100644 --- a/src/features/Apiexplorer/RequestResponseRenderer/index.tsx +++ b/src/features/Apiexplorer/RequestResponseRenderer/index.tsx @@ -21,7 +21,7 @@ function RequestResponseRenderer({ }: IResponseRendererProps) { const { is_logged_in } = useAuthContext(); const { disableSendRequest } = useDisableSendRequest(); - const { data, is_loading, send, clear, error } = useWS(name); + const { full_response, is_loading, send, clear, error } = useWS(name); const [toggle_modal, setToggleModal] = useState(false); const [response_state, setResponseState] = useState(false); @@ -66,8 +66,9 @@ function RequestResponseRenderer({ )} diff --git a/src/features/Apiexplorer/SubscribeRenderer/__tests__/SubscribeRenderer.test.tsx b/src/features/Apiexplorer/SubscribeRenderer/__tests__/SubscribeRenderer.test.tsx index f783a472..c39a930f 100644 --- a/src/features/Apiexplorer/SubscribeRenderer/__tests__/SubscribeRenderer.test.tsx +++ b/src/features/Apiexplorer/SubscribeRenderer/__tests__/SubscribeRenderer.test.tsx @@ -55,6 +55,10 @@ mockUseSubscription.mockImplementation(() => ({ subscribe: mockSubscribe, unsubscribe: mockUnsubscribe, error: 'random error', + full_response: { + tick: 1, + echo_req: { tick: 1 }, + }, })); const request_data = `{ @@ -96,13 +100,19 @@ describe('SubscribeRenderer', () => { expect(mockUnsubscribe).toBeCalledTimes(1); }); - it('should throw an error if incorrect json is being parsed', () => { + it('should throw an error if incorrect json is being parsed', async () => { const consoleOutput = []; const mockedError = (output) => consoleOutput.push(output); console.error = mockedError; render(); - expect(consoleOutput[0]).toEqual('something went wrong when parsing the json data: '); + const send_request_button = screen.getByRole('button', { name: 'Send Request' }); + + await userEvent.click(send_request_button); + + expect(consoleOutput[0]).toEqual( + 'Could not parse the JSON data while trying to send the request: ', + ); }); }); diff --git a/src/features/Apiexplorer/SubscribeRenderer/index.tsx b/src/features/Apiexplorer/SubscribeRenderer/index.tsx index 3232e48b..6d826d58 100644 --- a/src/features/Apiexplorer/SubscribeRenderer/index.tsx +++ b/src/features/Apiexplorer/SubscribeRenderer/index.tsx @@ -1,5 +1,8 @@ import React, { useState, useCallback, useEffect } from 'react'; -import { TSocketSubscribableEndpointNames } from '@site/src/configs/websocket/types'; +import { + TSocketSubscribableEndpointNames, + TSocketRequestProps, +} from '@site/src/configs/websocket/types'; import { Button } from '@deriv/ui'; import styles from '../RequestJSONBox/RequestJSONBox.module.scss'; import useAuthContext from '@site/src/hooks/useAuthContext'; @@ -21,7 +24,7 @@ function SubscribeRenderer({ }: IResponseRendererProps) { const { is_logged_in } = useAuthContext(); const { disableSendRequest } = useDisableSendRequest(); - const { data, is_loading, subscribe, unsubscribe, error } = useSubscription(name); + const { full_response, is_loading, subscribe, unsubscribe, error } = useSubscription(name); const [response_state, setResponseState] = useState(false); const [toggle_modal, setToggleModal] = useState(false); @@ -31,17 +34,21 @@ function SubscribeRenderer({ } }, [error]); - let json_data; - try { - json_data = JSON.parse(reqData); - } catch (error) { - json_data = ''; - console.error('something went wrong when parsing the json data: ', error); - } + const parseRequestJSON = () => { + let json_data: TSocketRequestProps extends never ? undefined : TSocketRequestProps; + + try { + json_data = JSON.parse(reqData); + } catch (error) { + console.error('Could not parse the JSON data while trying to send the request: ', error); + } + + return json_data; + }; const handleClick = useCallback(() => { unsubscribe(); - subscribe(json_data); + subscribe(parseRequestJSON()); setResponseState(true); }, [reqData, subscribe, unsubscribe]); @@ -66,8 +73,9 @@ function SubscribeRenderer({ )} diff --git a/src/features/Apiexplorer/__tests__/ApiExplorer.test.tsx b/src/features/Apiexplorer/__tests__/ApiExplorer.test.tsx index 7d3a2852..8eae5326 100644 --- a/src/features/Apiexplorer/__tests__/ApiExplorer.test.tsx +++ b/src/features/Apiexplorer/__tests__/ApiExplorer.test.tsx @@ -32,6 +32,10 @@ const mockClear = jest.fn(); mockuseWS.mockImplementation(() => ({ clear: mockClear, send: jest.fn(), + full_response: { + tick: 1, + echo_req: { tick: 1 }, + }, })); jest.mock('@site/src/hooks/useDynamicImportJSON'); diff --git a/src/hooks/useSubscription/index.tsx b/src/hooks/useSubscription/index.tsx index 43dbc82d..09f63f84 100644 --- a/src/hooks/useSubscription/index.tsx +++ b/src/hooks/useSubscription/index.tsx @@ -11,12 +11,14 @@ const useSubscription = (name: T) => const [is_subscribed, setSubscribed] = useState(false); const [error, setError] = useState(); const [data, setData] = useState>(); + const [full_response, setFullResponse] = useState>(); const [subscriber, setSubscriber] = useState<{ unsubscribe?: VoidFunction }>(); const onData = useCallback( (response: TSocketResponse) => { const key = response['msg_type'] ?? name; setData(response[key] as TSocketResponseData); + setFullResponse(response); setIsLoading(false); }, [name], @@ -41,7 +43,7 @@ const useSubscription = (name: T) => setSubscribed(false); }, [subscriber]); - return { subscribe, unsubscribe, is_loading, is_subscribed, error, data }; + return { subscribe, unsubscribe, is_loading, is_subscribed, error, data, full_response }; }; export default useSubscription; diff --git a/src/hooks/useWs/index.tsx b/src/hooks/useWs/index.tsx index cf4d2bdb..b8ac97aa 100644 --- a/src/hooks/useWs/index.tsx +++ b/src/hooks/useWs/index.tsx @@ -1,15 +1,21 @@ import apiManager from '@site/src/configs/websocket'; -import { TSocketEndpointNames, TSocketResponseData } from '@site/src/configs/websocket/types'; +import { + TSocketEndpointNames, + TSocketResponse, + TSocketResponseData, +} from '@site/src/configs/websocket/types'; import { useCallback, useState } from 'react'; const useWS = (name: T) => { const [is_loading, setIsLoading] = useState(false); const [error, setError] = useState(); const [data, setData] = useState>(); + const [full_response, setFullResponse] = useState>(); const clear = useCallback(() => { setError(null); setData(null); + setFullResponse(null); }, []); const send = useCallback( @@ -19,6 +25,7 @@ const useWS = (name: T) => { const response = await apiManager.augmentedSend(name, data); const key = response['msg_type'] ?? name; setData(response[key] as TSocketResponseData); + setFullResponse(response); } catch (e) { setError(e); } finally { @@ -28,7 +35,7 @@ const useWS = (name: T) => { [name], ); - return { send, is_loading, error, data, clear }; + return { send, full_response, is_loading, error, data, clear }; }; export default useWS;