From 2d65bfa3c6c5cfdaf06f93f211595551a0a05cbe Mon Sep 17 00:00:00 2001 From: Viktor Nagy Date: Wed, 22 May 2024 11:27:47 +0200 Subject: [PATCH] feat: advanced fields --- .../src/components/session-lost.tsx | 4 +- .../src/viewcontrols/browse-view.tsx | 4 +- .../src/viewcontrols/edit-view.tsx | 4 +- .../test/__mocks__/schema.ts | 72 ++++++++++++++++++- .../test/browse-view.test.tsx | 53 +++++++++++++- .../sn-controls-react/test/edit-view.test.tsx | 61 +++++++++++++++- .../sn-controls-react/test/new-view.test.tsx | 42 ++++++++++- 7 files changed, 227 insertions(+), 13 deletions(-) diff --git a/packages/sn-authentication-oidc-react/src/components/session-lost.tsx b/packages/sn-authentication-oidc-react/src/components/session-lost.tsx index 67b3489df..4de378591 100644 --- a/packages/sn-authentication-oidc-react/src/components/session-lost.tsx +++ b/packages/sn-authentication-oidc-react/src/components/session-lost.tsx @@ -1,6 +1,6 @@ import { Button, Container, Typography } from '@material-ui/core' import { History } from 'history' -import React, { ElementType } from 'react' +import React from 'react' import { getUserManager } from '../authentication-service' import { authenticateUser } from '../oidc-service' @@ -20,7 +20,7 @@ export const SessionLost = ({ onAuthenticate }: SessionLostProps) => ( type SessionLostContainerProps = { history: History - SessionLostComponentOverride?: ElementType + SessionLostComponentOverride?: any } export const SessionLostContainer = ({ history, SessionLostComponentOverride }: SessionLostContainerProps) => { diff --git a/packages/sn-controls-react/src/viewcontrols/browse-view.tsx b/packages/sn-controls-react/src/viewcontrols/browse-view.tsx index 6c1a0a494..789114b5a 100644 --- a/packages/sn-controls-react/src/viewcontrols/browse-view.tsx +++ b/packages/sn-controls-react/src/viewcontrols/browse-view.tsx @@ -141,7 +141,7 @@ export const BrowseView: React.FC = (props) => { .map((field) => renderField(field))} {advancedFields.length > 0 && ( - <> + @@ -156,7 +156,7 @@ export const BrowseView: React.FC = (props) => { .filter((i) => advancedFields.includes(i.fieldSettings.Name)) .sort((item1, item2) => (item2.fieldSettings.FieldIndex || 0) - (item1.fieldSettings.FieldIndex || 0)) .map((field) => renderField(field))} - + )} diff --git a/packages/sn-controls-react/src/viewcontrols/edit-view.tsx b/packages/sn-controls-react/src/viewcontrols/edit-view.tsx index d0c9ac4b5..63af4f7f9 100644 --- a/packages/sn-controls-react/src/viewcontrols/edit-view.tsx +++ b/packages/sn-controls-react/src/viewcontrols/edit-view.tsx @@ -201,7 +201,7 @@ export const EditView: React.FC = (props) => { .map((field) => renderField(field))} {advancedFields.length > 0 && ( - <> + @@ -216,7 +216,7 @@ export const EditView: React.FC = (props) => { .filter((i) => advancedFields.includes(i.fieldSettings.Name)) .sort((item1, item2) => (item2.fieldSettings.FieldIndex || 0) - (item1.fieldSettings.FieldIndex || 0)) .map((field) => renderField(field))} - + )}
diff --git a/packages/sn-controls-react/test/__mocks__/schema.ts b/packages/sn-controls-react/test/__mocks__/schema.ts index 16d31002f..cdf43a097 100644 --- a/packages/sn-controls-react/test/__mocks__/schema.ts +++ b/packages/sn-controls-react/test/__mocks__/schema.ts @@ -463,7 +463,73 @@ export const schema = [ Description: '$Ctd-GenericContent,Description', Icon: 'Content', AllowedChildTypes: [], - HandlerName: 'a', - FieldSettings: [] - } + HandlerName: 'Handlers.TestContentTypeHandler', + FieldSettings: [ + { + Type: 'ShortTextFieldSetting', + Name: 'NonAdvanced1', + FieldClassName: 'SenseNet.ContentRepository.Fields.ShortTextField', + DisplayName: 'Non advanced field #3', + Description: '', + ReadOnly: false, + Compulsory: false, + VisibleBrowse: FieldSettings.FieldVisibility.Show, + VisibleEdit: FieldSettings.FieldVisibility.Show, + VisibleNew: FieldSettings.FieldVisibility.Show, + ControlHint: 'sn:ColorPicker', + } as FieldSettings.ShortTextFieldSetting, + { + Type: 'ShortTextFieldSetting', + Name: 'NonAdvanced2', + FieldClassName: 'SenseNet.ContentRepository.Fields.ShortTextField', + DisplayName: 'Non advanced field #3', + Description: '', + ReadOnly: false, + Compulsory: false, + VisibleBrowse: FieldSettings.FieldVisibility.Show, + VisibleEdit: FieldSettings.FieldVisibility.Show, + VisibleNew: FieldSettings.FieldVisibility.Show, + ControlHint: 'sn:ColorPicker', + } as FieldSettings.ShortTextFieldSetting, + { + Type: 'DateTimeFieldSetting', + DateTimeMode: FieldSettings.DateTimeMode.DateAndTime, + Name: 'NonAdvanced3', + FieldClassName: 'SenseNet.ContentRepository.Fields.DateTimeField', + DisplayName: 'Non advanced field #3', + Description: 'Content was last modified on this date.', + ReadOnly: false, + Compulsory: false, + VisibleBrowse: FieldSettings.FieldVisibility.Show, + VisibleEdit: FieldSettings.FieldVisibility.Show, + VisibleNew: FieldSettings.FieldVisibility.Show, + } as FieldSettings.DateTimeFieldSetting, + { + Type: 'ShortTextFieldSetting', + Name: 'Advanced1', + FieldClassName: 'SenseNet.ContentRepository.Fields.ShortTextField', + DisplayName: 'Advanced field #1', + Description: '', + ReadOnly: false, + Compulsory: false, + VisibleBrowse: FieldSettings.FieldVisibility.Advanced, + VisibleEdit: FieldSettings.FieldVisibility.Advanced, + VisibleNew: FieldSettings.FieldVisibility.Advanced, + ControlHint: 'sn:ColorPicker', + } as FieldSettings.ShortTextFieldSetting, + { + Type: 'DateTimeFieldSetting', + DateTimeMode: FieldSettings.DateTimeMode.DateAndTime, + Name: 'Advanced2', + FieldClassName: 'SenseNet.ContentRepository.Fields.DateTimeField', + DisplayName: 'Advanced field #2', + Description: 'Content was last modified on this date.', + ReadOnly: false, + Compulsory: false, + VisibleBrowse: FieldSettings.FieldVisibility.Advanced, + VisibleEdit: FieldSettings.FieldVisibility.Advanced, + VisibleNew: FieldSettings.FieldVisibility.Advanced, + } as FieldSettings.DateTimeFieldSetting, + ], + }, ] diff --git a/packages/sn-controls-react/test/browse-view.test.tsx b/packages/sn-controls-react/test/browse-view.test.tsx index 62da58b78..f6ad8cff2 100644 --- a/packages/sn-controls-react/test/browse-view.test.tsx +++ b/packages/sn-controls-react/test/browse-view.test.tsx @@ -1,6 +1,7 @@ +import { IconButton } from '@material-ui/core' import { Repository } from '@sensenet/client-core' import { GenericContent, VersioningMode } from '@sensenet/default-content-types' -import { mount } from 'enzyme' +import { mount, shallow } from 'enzyme' import React from 'react' import { act } from 'react-dom/test-utils' import { @@ -53,6 +54,18 @@ export const testFile: GenericContent = { 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis nec iaculis lectus, sed blandit urna. Nullam in auctor odio, eu eleifend diam. Curabitur rutrum ullamcorper nunc, sit amet consectetur turpis elementum ac. Aenean lorem lorem, feugiat sit amet sem at, accumsan cursus leo.', } +export const testContent: GenericContent = { + Id: 1, + Name: 'TestContent', + DisplayName: 'Test content', + Path: '/Root/Content/TestContent', + Type: 'TestContentType', + Index: 42, + VersioningMode: [VersioningMode.Option0], + AllowedChildTypes: [1, 2], + Description: 'Lorem ipsum short description.', +} + describe('Browse view component', () => { afterAll(() => { // Restore console.errors @@ -84,4 +97,42 @@ describe('Browse view component', () => { expect(wrapper.find(Avatar)).toHaveLength(1) expect(wrapper.find(ColorPicker)).toHaveLength(2) }) + + //Advanced field tests + it('Advanced field header should be visible', () => { + const wrapper = mount() + wrapper.update() + + const element = wrapper.find('[data-test="advanced-field-container"]') + expect(element.exists()).toBe(true) + + wrapper.unmount() + }) + it('Advanced fields should be invisible by default', () => { + const wrapper = shallow() + const element = wrapper.find('[data-test="advanced-field-container"]') + expect(element.find(DatePicker).exists()).toBe(false) + expect(element.find(ShortText).exists()).toBe(false) + }) + it('Advanced fields should be visible after clicking on show icon', () => { + const wrapper = shallow() + wrapper.update() + + wrapper.find('[data-test="advanced-field-container"]').find(IconButton).simulate('click') + wrapper.update() + + const element = wrapper.find('[data-test="advanced-field-container"]') + expect(element.find(DatePicker).exists()).toBe(true) + expect(element.find(ShortText).exists()).toBe(true) + }) + it('Should render advanced fields in the right section', async () => { + const wrapper = mount() + wrapper.update() + + const parent = wrapper.find('[data-test="advanced-field-container"]') + expect(parent.find(DatePicker)).toHaveLength(1) + expect(parent.find(ShortText)).toHaveLength(1) + + wrapper.unmount() + }) }) diff --git a/packages/sn-controls-react/test/edit-view.test.tsx b/packages/sn-controls-react/test/edit-view.test.tsx index 1c91a4791..611ab35e9 100644 --- a/packages/sn-controls-react/test/edit-view.test.tsx +++ b/packages/sn-controls-react/test/edit-view.test.tsx @@ -1,7 +1,9 @@ +import { IconButton } from '@material-ui/core' import { Repository } from '@sensenet/client-core' import { GenericContent, VersioningMode } from '@sensenet/default-content-types' -import { shallow } from 'enzyme' +import { mount, ReactWrapper, shallow } from 'enzyme' import React from 'react' +import { act } from 'react-dom/test-utils' import { AllowedChildTypes, AutoComplete, @@ -44,6 +46,18 @@ export const testFile: GenericContent = { 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis nec iaculis lectus, sed blandit urna. Nullam in auctor odio, eu eleifend diam. Curabitur rutrum ullamcorper nunc, sit amet consectetur turpis elementum ac. Aenean lorem lorem, feugiat sit amet sem at, accumsan cursus leo.', } +export const testContent: GenericContent = { + Id: 1, + Name: 'TestContent', + DisplayName: 'Test content', + Path: '/Root/Content/TestContent', + Type: 'TestContentType', + Index: 42, + VersioningMode: [VersioningMode.Option0], + AllowedChildTypes: [1, 2], + Description: 'Lorem ipsum short description.', +} + describe('Edit view component', () => { it('should render all components', () => { const wrapper = shallow() @@ -76,4 +90,49 @@ describe('Edit view component', () => { wrapper.find('[component="form"]').simulate('submit', { preventDefault: jest.fn() }) expect(onSubmit).toBeCalledWith({ VersioningMode: '1' }, 'GenericContent') }) + //Advanced field tests + it('Advanced field header should be visible', () => { + const wrapper = mount( + , + ) + wrapper.update() + + const element = wrapper.find('[data-test="advanced-field-container"]') + expect(element.exists()).toBe(true) + + wrapper.unmount() + }) + it('Advanced fields should be invisible by default', () => { + const wrapper = shallow( + , + ) + const element = wrapper.find('[data-test="advanced-field-container"]') + expect(element.find(DatePicker).exists()).toBe(false) + expect(element.find(ShortText).exists()).toBe(false) + }) + it('Advanced fields should be visible after clicking on show icon', () => { + const wrapper = shallow( + , + ) + wrapper.update() + + wrapper.find('[data-test="advanced-field-container"]').find(IconButton).simulate('click') + wrapper.update() + + const element = wrapper.find('[data-test="advanced-field-container"]') + expect(element.find(DatePicker).exists()).toBe(true) + expect(element.find(ShortText).exists()).toBe(true) + }) + it('Should render advanced fields in the right section', async () => { + const wrapper = mount( + , + ) + wrapper.update() + + const parent = wrapper.find('[data-test="advanced-field-container"]') + expect(parent.find(DatePicker)).toHaveLength(1) + expect(parent.find(ShortText)).toHaveLength(1) + + wrapper.unmount() + }) }) diff --git a/packages/sn-controls-react/test/new-view.test.tsx b/packages/sn-controls-react/test/new-view.test.tsx index 4aa4f9d0b..4f9328145 100644 --- a/packages/sn-controls-react/test/new-view.test.tsx +++ b/packages/sn-controls-react/test/new-view.test.tsx @@ -1,7 +1,8 @@ +import { IconButton } from '@material-ui/core' import Typography from '@material-ui/core/Typography' import { Repository } from '@sensenet/client-core' import { GenericContent, VersioningMode } from '@sensenet/default-content-types' -import { shallow } from 'enzyme' +import { mount, shallow } from 'enzyme' import React from 'react' import { AllowedChildTypes, @@ -73,11 +74,48 @@ describe('New view component', () => { it('should handle change', () => { const onSubmit = jest.fn() const wrapper = shallow( - , + , ).dive() const onChange = wrapper.find(CheckboxGroup).first().prop('fieldOnChange') onChange?.('VersioningMode', VersioningMode.Option1) wrapper.find('[component="form"]').simulate('submit', { preventDefault: jest.fn() }) expect(onSubmit).toBeCalledWith({ VersioningMode: '1' }, 'GenericContent') }) + //Advanced field tests + it('Advanced field header should be visible', () => { + const wrapper = mount() + wrapper.update() + + const element = wrapper.find('[data-test="advanced-field-container"]') + expect(element.exists()).toBe(true) + + wrapper.unmount() + }) + it('Advanced fields should be invisible by default', () => { + const wrapper = shallow() + const element = wrapper.find('[data-test="advanced-field-container"]') + expect(element.find(DatePicker).exists()).toBe(false) + expect(element.find(ShortText).exists()).toBe(false) + }) + it('Advanced fields should be visible after clicking on show icon', () => { + const wrapper = shallow() + wrapper.update() + + wrapper.find('[data-test="advanced-field-container"]').find(IconButton).simulate('click') + wrapper.update() + + const element = wrapper.find('[data-test="advanced-field-container"]') + expect(element.find(DatePicker).exists()).toBe(true) + expect(element.find(ShortText).exists()).toBe(true) + }) + it('Should render advanced fields in the right section', async () => { + const wrapper = mount() + wrapper.update() + + const parent = wrapper.find('[data-test="advanced-field-container"]') + expect(parent.find(DatePicker)).toHaveLength(1) + expect(parent.find(ShortText)).toHaveLength(1) + + wrapper.unmount() + }) })