diff --git a/src/features/Apiexplorer/Schema/RecursiveContent/RecursiveProperties/__tests__/RecursiveProperties.test.tsx b/src/features/Apiexplorer/Schema/RecursiveContent/RecursiveProperties/__tests__/RecursiveProperties.test.tsx index 46e37534d..38d5a1bd8 100644 --- a/src/features/Apiexplorer/Schema/RecursiveContent/RecursiveProperties/__tests__/RecursiveProperties.test.tsx +++ b/src/features/Apiexplorer/Schema/RecursiveContent/RecursiveProperties/__tests__/RecursiveProperties.test.tsx @@ -13,9 +13,35 @@ const fakeItem = { }, }, properties: { - recursive_item: { + recursive_item_1: { description: 'This is a recursive item', }, + recursive_item_2: { + description: 'This is recursive item 2', + oneOf: 'This is oneOf key for recursive_item_2', + }, + }, + definitions: { + stream_types: { + description: 'This stream_types description', + type: 'string', + enum: [ + 'balance', + 'candles', + 'cashier_payments', + 'p2p_advert', + 'p2p_advertiser', + 'p2p_order', + 'proposal', + 'proposal_open_contract', + 'ticks', + 'transaction', + 'trading_platform_asset_listing', + 'website_status', + 'p2p_settings', + 'crypto_estimations', + ], + }, }, }; @@ -26,21 +52,43 @@ describe('RecursiveProperties', () => { is_open properties={fakeItem.properties || fakeItem?.items?.properties} value={fakeItem} + jsonSchema={fakeItem} />, ); const recursion_1_description = await screen.findByText(/nested items/i); expect(recursion_1_description).toBeVisible(); - const recursion_2_name = await screen.findByText(/recursive_item/i); + const recursion_2_name = await screen.findByText(/recursive_item_1/i); expect(recursion_2_name).toBeVisible(); const recursion_2_description = await screen.findByText(/This is a recursive item/i); expect(recursion_2_description).toBeVisible(); + + const recursion_3_name = await screen.findByText(/recursive_item_2/i); + expect(recursion_3_name).toBeVisible(); + + const recursion_3_description = await screen.findByText(/This is recursive item 2/i); + expect(recursion_3_description).toBeVisible(); }); it('renders only the description (last item) if there are no nested items anymore', async () => { - render(); + render( + , + ); const item = await screen.findByText(/This is the main item description/i); expect(item).toBeVisible(); }); + + it('renders StreamTypesObject if value contains oneOf meaning its forgetAll api call', async () => { + render( + , + ); + const streamTypesObject = await screen.getByTestId('dt_stream_types_object'); + expect(streamTypesObject).toBeVisible(); + }); }); diff --git a/src/features/Apiexplorer/Schema/RecursiveContent/RecursiveProperties/index.tsx b/src/features/Apiexplorer/Schema/RecursiveContent/RecursiveProperties/index.tsx index ff6cdb172..808b44c6d 100644 --- a/src/features/Apiexplorer/Schema/RecursiveContent/RecursiveProperties/index.tsx +++ b/src/features/Apiexplorer/Schema/RecursiveContent/RecursiveProperties/index.tsx @@ -7,20 +7,22 @@ type TRecursiveProperties = { is_open: boolean; properties: any; value: any; - jsonSchema?: any; + jsonSchema: any; }; const RecursiveProperties = ({ is_open, properties, value, jsonSchema }: TRecursiveProperties) => { const keys = properties && Object.keys(properties); + if (!is_open) { - //if object is not open then ret null return null; } - - if ('oneOf' in value) { - return ; + if (value && 'oneOf' in value) { + return ( + + + + ); } - // this will be true when we are not inside properties obj? !!!!!! if (!keys) { return ( @@ -36,7 +38,6 @@ const RecursiveProperties = ({ is_open, properties, value, jsonSchema }: TRecurs {index === 0 && value?.items?.description && ( )} - {/* check if its forgetAll Request not response */} {key === 'forget_all' && 'oneOf' in value[key] ? ( { title='test title' is_open_object setIsOpenObject={() => jest.fn()} + is_stream_types={false} />, ); const type = await screen.findByText('number'); @@ -34,6 +35,7 @@ describe('SchemaBodyHeader', () => { title='test title' is_open_object setIsOpenObject={() => jest.fn()} + is_stream_types={false} />, ); const type = await screen.findByText('array'); @@ -52,6 +54,7 @@ describe('SchemaBodyHeader', () => { title='test title' is_open_object setIsOpenObject={() => jest.fn()} + is_stream_types={false} />, ); const type = await screen.findByText('integer'); @@ -70,6 +73,7 @@ describe('SchemaBodyHeader', () => { title='test title' is_open_object setIsOpenObject={() => jest.fn()} + is_stream_types={false} />, ); const type = await screen.findByText('string'); @@ -88,6 +92,7 @@ describe('SchemaBodyHeader', () => { title='test title' is_open_object setIsOpenObject={() => jest.fn()} + is_stream_types={false} />, ); const type = await screen.findByText(/number/i); @@ -106,6 +111,7 @@ describe('SchemaBodyHeader', () => { title='test title' is_open_object setIsOpenObject={() => jest.fn()} + is_stream_types={false} />, ); const type = await screen.findByText(/string/i); @@ -124,6 +130,7 @@ describe('SchemaBodyHeader', () => { title='test title' is_open_object setIsOpenObject={() => jest.fn()} + is_stream_types={false} />, ); const type = await screen.findByText(/array/i); @@ -142,9 +149,33 @@ describe('SchemaBodyHeader', () => { title='test title' is_open_object setIsOpenObject={() => jest.fn()} + is_stream_types={false} />, ); const type = await screen.findByText(/integer/i); expect(type).toBeVisible(); }); + + it('should render the SchemaBodyHeader with oneOf stream_types array if is_stream_types is true', async () => { + render( + jest.fn()} + is_stream_types={true} + />, + ); + const oneOfType = await screen.findByText(/one of/i); + const stream_types = await screen.findByText(/stream_types/i); + const array_type = await screen.findByText(/array/i); + expect(oneOfType).toBeVisible(); + expect(stream_types).toBeVisible(); + expect(array_type).toBeVisible(); + }); }); diff --git a/src/features/Apiexplorer/Schema/RecursiveContent/SchemaBodyHeader/index.tsx b/src/features/Apiexplorer/Schema/RecursiveContent/SchemaBodyHeader/index.tsx index 49fa46fac..c60e22018 100644 --- a/src/features/Apiexplorer/Schema/RecursiveContent/SchemaBodyHeader/index.tsx +++ b/src/features/Apiexplorer/Schema/RecursiveContent/SchemaBodyHeader/index.tsx @@ -12,7 +12,7 @@ type TSchemaBodyHeader = { setIsOpenObject: (boolean) => void; examples: string[]; enum; - is_stream_types?: boolean; + is_stream_types: boolean; }; const SchemaBodyHeader = ({ diff --git a/src/features/Apiexplorer/Schema/RecursiveContent/SchemaObjectContent/__tests__/SchemaObjectContent.test.tsx b/src/features/Apiexplorer/Schema/RecursiveContent/SchemaObjectContent/__tests__/SchemaObjectContent.test.tsx index d23730213..f3f38e184 100644 --- a/src/features/Apiexplorer/Schema/RecursiveContent/SchemaObjectContent/__tests__/SchemaObjectContent.test.tsx +++ b/src/features/Apiexplorer/Schema/RecursiveContent/SchemaObjectContent/__tests__/SchemaObjectContent.test.tsx @@ -21,6 +21,37 @@ const fake_properties = { }, }; +const stream_types_schema = { + properties: { + test_property: { + description: 'property description', + oneOf: 'this is oneOf key', + }, + }, + definitions: { + stream_types: { + description: 'This stream_types description', + type: 'string', + enum: [ + 'balance', + 'candles', + 'cashier_payments', + 'p2p_advert', + 'p2p_advertiser', + 'p2p_order', + 'proposal', + 'proposal_open_contract', + 'ticks', + 'transaction', + 'trading_platform_asset_listing', + 'website_status', + 'p2p_settings', + 'crypto_estimations', + ], + }, + }, +}; + describe('SchemaObjectContent', () => { it('should be able to open a nested object item', async () => { render(); @@ -96,4 +127,24 @@ describe('SchemaObjectContent', () => { const schema = await screen.findByTitle('JSON'); expect(schema).toBeVisible(); }); + + it('should open StreamTypesObject upon clicking stream_types button', async () => { + render( + , + ); + + const button = await screen.findByRole('button', { name: /stream_types/i }); + expect(button).toBeVisible(); + + await userEvent.click(button); + + const streamTypesObject = await screen.getByTestId('dt_stream_types_object'); + expect(streamTypesObject).toBeVisible(); + }); }); diff --git a/src/features/Apiexplorer/Schema/RecursiveContent/SchemaObjectContent/index.tsx b/src/features/Apiexplorer/Schema/RecursiveContent/SchemaObjectContent/index.tsx index 24fc84279..5a3c77dc5 100644 --- a/src/features/Apiexplorer/Schema/RecursiveContent/SchemaObjectContent/index.tsx +++ b/src/features/Apiexplorer/Schema/RecursiveContent/SchemaObjectContent/index.tsx @@ -14,7 +14,6 @@ type TSchemaObjectContent = { is_stream_types?: boolean; }; -//json schema also here full obj export default function SchemaObjectContent({ key_value, properties, diff --git a/src/features/Apiexplorer/Schema/RecursiveContent/StreamTypesObject/__tests__/StreamTypesObject.test.tsx b/src/features/Apiexplorer/Schema/RecursiveContent/StreamTypesObject/__tests__/StreamTypesObject.test.tsx new file mode 100644 index 000000000..ad1b93b36 --- /dev/null +++ b/src/features/Apiexplorer/Schema/RecursiveContent/StreamTypesObject/__tests__/StreamTypesObject.test.tsx @@ -0,0 +1,67 @@ +import React from 'react'; +import userEvent from '@testing-library/user-event'; +import { screen, render } from '@testing-library/react'; +import StreamTypesObject from '..'; + +describe('StreamTypesObject', () => { + const json_schema = { + stream_types: { + description: 'This stream_types description', + type: 'string', + enum: [ + 'balance', + 'candles', + 'cashier_payments', + 'p2p_advert', + 'p2p_advertiser', + 'p2p_order', + 'proposal', + 'proposal_open_contract', + 'ticks', + 'transaction', + 'trading_platform_asset_listing', + 'website_status', + 'p2p_settings', + 'crypto_estimations', + ], + }, + }; + + it('should render button that opens jsonschema', async () => { + render(); + + const schema_button = await screen.findByText('{}'); + + expect(schema_button).toBeVisible(); + + await userEvent.click(schema_button); + + const schema = await screen.findByTitle('JSON'); + expect(schema).toBeVisible(); + }); + + it('should render the header of the object', () => { + render(); + + const header_title = screen.getAllByText(/stream_types/)[0]; + expect(header_title).toBeInTheDocument(); + + const header_description = screen.getByText(/This stream_types description/i); + expect(header_description).toBeInTheDocument(); + }); + + it('should render the body of StreamTypesObject', () => { + render(); + + const type = screen.getByText(/enum/i); + expect(type).toBeInTheDocument(); + + const enum_type = screen.getByText(/string/i); + expect(enum_type).toBeInTheDocument(); + + json_schema.stream_types.enum.map((item) => { + const enum_name = screen.getByText(item); + expect(enum_name).toBeInTheDocument(); + }); + }); +}); diff --git a/src/features/Apiexplorer/Schema/RecursiveContent/StreamTypesObject/index.tsx b/src/features/Apiexplorer/Schema/RecursiveContent/StreamTypesObject/index.tsx index 1592269b0..fb4555692 100644 --- a/src/features/Apiexplorer/Schema/RecursiveContent/StreamTypesObject/index.tsx +++ b/src/features/Apiexplorer/Schema/RecursiveContent/StreamTypesObject/index.tsx @@ -1,6 +1,7 @@ -import React from 'react'; +import React, { Suspense } from 'react'; import StreamTypesHeader from './StreamTypesHeader'; import StreamTypesBody from './StreamTypesBody'; +import SourceButton from '../../SourceButton/SourceButton'; import styles from '../../Schema.module.scss'; type TStreamTypesObject = { @@ -8,31 +9,38 @@ type TStreamTypesObject = { stream_types: { description: string; type: string; - enum: Array< - | 'balance' - | 'candles' - | 'cashier_payments' - | 'p2p_advert' - | 'p2p_advertiser' - | 'p2p_order' - | 'proposal' - | 'proposal_open_contract' - | 'ticks' - | 'transaction' - | 'trading_platform_asset_listing' - | 'website_status' - | 'p2p_settings' - | 'crypto_estimations' - >; + enum; }; }; }; +const ReactJson = React.lazy(() => import('react-json-view')); + const StreamTypesObject = ({ definitions }: TStreamTypesObject) => { + const [is_code_open, setIsCodeOpen] = React.useState(false); + let data = ''; + try { + data = JSON.stringify(definitions.stream_types, null, 2); + } catch (error) { + data = ''; + console.error('There was an issue stringifying JSON data: ', error); + } return ( -
+
+ - + {is_code_open ? ( + + Loading...
}> + + + + ) : ( + + )}
); }; diff --git a/src/features/Apiexplorer/Schema/Schema.module.scss b/src/features/Apiexplorer/Schema/Schema.module.scss index 4848a8d40..e84c890f6 100644 --- a/src/features/Apiexplorer/Schema/Schema.module.scss +++ b/src/features/Apiexplorer/Schema/Schema.module.scss @@ -304,14 +304,44 @@ } .streamTypesContainer { - border-radius: 6px; margin-top: rem(1); margin-bottom: rem(2.4); + &:hover { + > .sourceButtonMain { + opacity: 1; + margin: 10px; + } + } + + .streamTypesHeader { + padding: rem(1); + border: none; + background: #151717; + border-top-left-radius: 6px; + border-top-right-radius: 6px; + + .streamTypesTitle { + font-size: rem(1.6); + color: var(--ifm-color-white); + font-weight: bold; + } + .streamTypesDescription { + display: flex; + padding: rem(0.5) 0; + gap: rem(2); + justify-content: space-between; + color: var(--ifm-color-white); + font-size: rem(1.4); + } + } + .streamTypesBody { background-color: rgba(219, 219, 219, 0.05); display: flex; padding: rem(1); + border-bottom-left-radius: 6px; + border-bottom-right-radius: 6px; .streamTypesObject { display: flex; @@ -352,24 +382,4 @@ } } } - - .streamTypesHeader { - padding: rem(1); - border: none; - background: #151717; - - .streamTypesTitle { - font-size: rem(1.6); - color: var(--ifm-color-white); - font-weight: bold; - } - .streamTypesDescription { - display: flex; - padding: rem(0.5) 0; - gap: rem(2); - justify-content: space-between; - color: var(--ifm-color-white); - font-size: rem(1.4); - } - } }