-
Notifications
You must be signed in to change notification settings - Fork 75
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add main config section with header behind feature flag (#14702)
Co-authored-by: JamalAlabdullah <[email protected]>
- Loading branch information
1 parent
f2104d9
commit 937fecd
Showing
8 changed files
with
228 additions
and
135 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
100 changes: 28 additions & 72 deletions
100
...ackages/ux-editor/src/components/Properties/PropertiesHeader/ComponentMainConfig.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,98 +1,54 @@ | ||
import React from 'react'; | ||
import type { FormItem } from '@altinn/ux-editor/types/FormItem'; | ||
import { ComponentType } from 'app-shared/types/ComponentType'; | ||
import { screen } from '@testing-library/react'; | ||
import { renderWithProviders } from '../../../testing/mocks'; | ||
import { ComponentMainConfig } from './ComponentMainConfig'; | ||
import type { FormItem } from '../../../types/FormItem'; | ||
import { ComponentType } from 'app-shared/types/ComponentType'; | ||
import userEvent from '@testing-library/user-event'; | ||
import { component1Mock } from '@altinn/ux-editor/testing/layoutMock'; | ||
import { addFeatureFlagToLocalStorage, FeatureFlag } from 'app-shared/utils/featureToggleUtils'; | ||
import { textMock } from '@studio/testing/mocks/i18nMock'; | ||
import { typedLocalStorage } from '@studio/pure-functions'; | ||
import { renderWithProviders } from '../../../testing/mocks'; | ||
import { createQueryClientMock } from 'app-shared/mocks/queryClientMock'; | ||
import { QueryKey } from 'app-shared/types/QueryKey'; | ||
import { app, org } from '@studio/testing/testids'; | ||
import { | ||
layoutSet1NameMock, | ||
layoutSet2NameMock, | ||
layoutSetsExtendedMock, | ||
layoutSetsMock, | ||
} from '../../../testing/layoutSetsMock'; | ||
import { layout1NameMock, layoutMock } from '../../../testing/layoutMock'; | ||
import { layoutSetsExtendedMock } from '@altinn/ux-editor/testing/layoutSetsMock'; | ||
|
||
const summary2Component: FormItem = { | ||
const summary2ComponentMock: FormItem = { | ||
id: '0', | ||
type: ComponentType.Summary2, | ||
itemType: 'COMPONENT', | ||
target: {}, | ||
}; | ||
|
||
describe('ComponentMainConfig', () => { | ||
describe('Summary2', () => { | ||
beforeEach(() => { | ||
jest.clearAllMocks(); | ||
}); | ||
afterEach(() => { | ||
jest.clearAllMocks(); | ||
typedLocalStorage.removeItem('featureFlags'); | ||
}); | ||
|
||
it('should render summary2 config', async () => { | ||
const user = userEvent.setup(); | ||
render(summary2Component); | ||
expect(summary2AccordionButton()).toBeInTheDocument(); | ||
await user.click(summary2AccordionButton()); | ||
expect(summary2AddOverrideButton()).toBeInTheDocument(); | ||
}); | ||
it('should render summary2 config when the component type matches', async () => { | ||
renderComponentMainConfig(summary2ComponentMock); | ||
|
||
it('should display overrides', async () => { | ||
const user = userEvent.setup(); | ||
const summary2ComponentWithOverrides = { | ||
...summary2Component, | ||
overrides: [{ componentId: '0' }], | ||
}; | ||
render(summary2ComponentWithOverrides); | ||
await user.click(summary2AccordionButton()); | ||
expect(summary2CollapsedButton(1)).toBeInTheDocument(); | ||
}); | ||
const targetHeader = screen.getByText(textMock('ux_editor.component_properties.target')); | ||
expect(targetHeader).toBeInTheDocument(); | ||
}); | ||
|
||
it('should call handleComponentChange when adding overrides', async () => { | ||
const user = userEvent.setup(); | ||
render(summary2Component); | ||
await user.click(summary2AccordionButton()); | ||
await user.click(summary2AddOverrideButton()); | ||
expect(handleComponentChange).toHaveBeenCalledTimes(1); | ||
}); | ||
it('should render header config when feature flag is set, but the type does not match', async () => { | ||
addFeatureFlagToLocalStorage(FeatureFlag.MainConfig); | ||
renderComponentMainConfig(component1Mock); | ||
|
||
it('should call handleComponentChange when changing target', async () => { | ||
const user = userEvent.setup(); | ||
render(summary2Component); | ||
await user.selectOptions(summary2TargetLayoutSet(), layoutSet2NameMock); | ||
expect(handleComponentChange).toHaveBeenCalledTimes(1); | ||
}); | ||
const sectionHeader = textMock('ux_editor.component_properties.main_configuration'); | ||
const headerMainConfig = screen.getByText(sectionHeader); | ||
expect(headerMainConfig).toBeInTheDocument(); | ||
}); | ||
}); | ||
|
||
const summary2AccordionButton = () => | ||
screen.getByRole('button', { name: /ux_editor.component_properties.summary.override.title/ }); | ||
const summary2AddOverrideButton = () => | ||
screen.getByRole('button', { name: /ux_editor.component_properties.summary.add_override/ }); | ||
const summary2CollapsedButton = (n: number) => | ||
screen.getByRole('button', { | ||
name: new RegExp(`ux_editor.component_properties.summary.overrides.nth.*:${n}}`), | ||
}); | ||
|
||
const summary2TargetLayoutSet = () => | ||
screen.getByRole('combobox', { name: /ux_editor.component_properties.target_layoutSet_id/ }); | ||
|
||
const handleComponentChange = jest.fn(); | ||
const render = (component: FormItem) => { | ||
const renderComponentMainConfig = (component: FormItem) => { | ||
const handleComponentChange = jest.fn(); | ||
const queryClient = createQueryClientMock(); | ||
queryClient.setQueryData([QueryKey.FormLayouts, org, app, layoutSet1NameMock], { | ||
[layout1NameMock]: layoutMock, | ||
}); | ||
queryClient.setQueryData([QueryKey.LayoutSets, org, app], layoutSetsMock); | ||
queryClient.setQueryData([QueryKey.LayoutSetsExtended, org, app], layoutSetsExtendedMock); | ||
renderWithProviders( | ||
return renderWithProviders( | ||
<ComponentMainConfig component={component} handleComponentChange={handleComponentChange} />, | ||
{ | ||
queryClient, | ||
appContextProps: { | ||
selectedFormLayoutSetName: layoutSet1NameMock, | ||
selectedFormLayoutName: layout1NameMock, | ||
}, | ||
}, | ||
{ queryClient }, | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
23 changes: 23 additions & 0 deletions
23
frontend/packages/ux-editor/src/components/Properties/PropertiesHeader/HeaderMainConfig.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import React from 'react'; | ||
import { StudioHeading } from '@studio/components'; | ||
import { RequiredIndicator } from '../../RequiredIndicator'; | ||
import classes from './HeaderMainConfig.module.css'; | ||
import { useTranslation } from 'react-i18next'; | ||
|
||
type HeaderMainConfigProps = { | ||
children?: React.ReactNode; | ||
}; | ||
|
||
export const HeaderMainConfig = ({ children }: Partial<HeaderMainConfigProps>): JSX.Element => { | ||
const { t } = useTranslation(); | ||
|
||
return ( | ||
<div className={classes.componentMainConfig}> | ||
<StudioHeading size='2xs'> | ||
{t('ux_editor.component_properties.main_configuration')} | ||
<RequiredIndicator /> | ||
</StudioHeading> | ||
{children} | ||
</div> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
98 changes: 98 additions & 0 deletions
98
.../src/components/Properties/PropertiesHeader/SpecificMainConfig/SummaryMainConfig.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
import React from 'react'; | ||
import { screen } from '@testing-library/react'; | ||
import { renderWithProviders } from '../../../../testing/mocks'; | ||
import { SummaryMainConfig } from './SummaryMainConfig'; | ||
import type { FormItem } from '../../../../types/FormItem'; | ||
import { ComponentType } from 'app-shared/types/ComponentType'; | ||
import userEvent from '@testing-library/user-event'; | ||
import { createQueryClientMock } from 'app-shared/mocks/queryClientMock'; | ||
import { QueryKey } from 'app-shared/types/QueryKey'; | ||
import { app, org } from '@studio/testing/testids'; | ||
import { | ||
layoutSet1NameMock, | ||
layoutSet2NameMock, | ||
layoutSetsExtendedMock, | ||
layoutSetsMock, | ||
} from '../../../../testing/layoutSetsMock'; | ||
import { layout1NameMock, layoutMock } from '../../../../testing/layoutMock'; | ||
|
||
const summary2Component: FormItem = { | ||
id: '0', | ||
type: ComponentType.Summary2, | ||
itemType: 'COMPONENT', | ||
target: {}, | ||
}; | ||
|
||
describe('ComponentMainConfig', () => { | ||
describe('Summary2', () => { | ||
beforeEach(() => { | ||
jest.clearAllMocks(); | ||
}); | ||
|
||
it('should render summary2 config', async () => { | ||
const user = userEvent.setup(); | ||
render(summary2Component); | ||
expect(summary2AccordionButton()).toBeInTheDocument(); | ||
await user.click(summary2AccordionButton()); | ||
expect(summary2AddOverrideButton()).toBeInTheDocument(); | ||
}); | ||
|
||
it('should display overrides', async () => { | ||
const user = userEvent.setup(); | ||
const summary2ComponentWithOverrides = { | ||
...summary2Component, | ||
overrides: [{ componentId: '0' }], | ||
}; | ||
render(summary2ComponentWithOverrides); | ||
await user.click(summary2AccordionButton()); | ||
expect(summary2CollapsedButton(1)).toBeInTheDocument(); | ||
}); | ||
|
||
it('should call handleComponentChange when adding overrides', async () => { | ||
const user = userEvent.setup(); | ||
render(summary2Component); | ||
await user.click(summary2AccordionButton()); | ||
await user.click(summary2AddOverrideButton()); | ||
expect(handleComponentChange).toHaveBeenCalledTimes(1); | ||
}); | ||
|
||
it('should call handleComponentChange when changing target', async () => { | ||
const user = userEvent.setup(); | ||
render(summary2Component); | ||
await user.selectOptions(summary2TargetLayoutSet(), layoutSet2NameMock); | ||
expect(handleComponentChange).toHaveBeenCalledTimes(1); | ||
}); | ||
}); | ||
}); | ||
|
||
const summary2AccordionButton = () => | ||
screen.getByRole('button', { name: /ux_editor.component_properties.summary.override.title/ }); | ||
const summary2AddOverrideButton = () => | ||
screen.getByRole('button', { name: /ux_editor.component_properties.summary.add_override/ }); | ||
const summary2CollapsedButton = (n: number) => | ||
screen.getByRole('button', { | ||
name: new RegExp(`ux_editor.component_properties.summary.overrides.nth.*:${n}}`), | ||
}); | ||
|
||
const summary2TargetLayoutSet = () => | ||
screen.getByRole('combobox', { name: /ux_editor.component_properties.target_layoutSet_id/ }); | ||
|
||
const handleComponentChange = jest.fn(); | ||
const render = (component: FormItem<ComponentType.Summary2>) => { | ||
const queryClient = createQueryClientMock(); | ||
queryClient.setQueryData([QueryKey.FormLayouts, org, app, layoutSet1NameMock], { | ||
[layout1NameMock]: layoutMock, | ||
}); | ||
queryClient.setQueryData([QueryKey.LayoutSets, org, app], layoutSetsMock); | ||
queryClient.setQueryData([QueryKey.LayoutSetsExtended, org, app], layoutSetsExtendedMock); | ||
renderWithProviders( | ||
<SummaryMainConfig component={component} handleComponentChange={handleComponentChange} />, | ||
{ | ||
queryClient, | ||
appContextProps: { | ||
selectedFormLayoutSetName: layoutSet1NameMock, | ||
selectedFormLayoutName: layout1NameMock, | ||
}, | ||
}, | ||
); | ||
}; |
Oops, something went wrong.