From ced74ac550519969fbf49d9a3da9556217bcd3d2 Mon Sep 17 00:00:00 2001 From: Damir Abdulganiev Date: Thu, 3 Feb 2022 13:29:02 +0300 Subject: [PATCH] [Fixes #1534] No originally selected custom parameters in topic's edit tab (#1538) - Fixes No originally selected custom parameters in topic's edit tab #1534 - Adds test case for CustomParams to verify fix - Updates CustomParamsField to use predefined value - Renames INDEX_PREFIX to TOPIC_CUSTOM_PARAMS_PREFIX and moves it to constants file - Removes unused configs from Topic/Edit component - Rewrites DangerZone styled's - Rewrites DangerZone tests - Adds margin to DangerZone to match TopicForm width - Adds simple Topic/Edit test - Changes sonar-project.properties file's sonar.exclusions to correctly ignore paths Signed-off-by: Roman Zabaluev Co-authored-by: Roman Zabaluev --- .github/workflows/backend.yml | 2 +- .github/workflows/e2e-checks.yaml | 2 +- kafka-ui-react-app/sonar-project.properties | 2 +- .../Edit/DangerZone/DangerZone.styled.tsx | 9 +- .../Topic/Edit/DangerZone/DangerZone.tsx | 24 +- .../src/components/Topics/Topic/Edit/Edit.tsx | 42 +- .../Topic/Edit/__test__/DangerZone.spec.tsx | 116 ++++ .../Topics/Topic/Edit/__test__/Edit.spec.tsx | 34 ++ .../Topics/Topic/Edit/__test__/fixtures.ts | 553 ++++++++++++++++++ .../Topic/Edit/__tests__/DangerZone.spec.tsx | 64 -- .../__snapshots__/DangerZone.spec.tsx.snap | 360 ------------ .../Form/CustomParams/CustomParamField.tsx | 3 +- .../shared/Form/CustomParams/CustomParams.tsx | 10 +- .../CustomParamField.spec.tsx | 0 .../CustomParams.spec.tsx | 45 +- .../Form/CustomParams/__test__/fixtures.ts | 15 + .../Topics/shared/Form/TopicForm.tsx | 6 +- kafka-ui-react-app/src/lib/constants.ts | 1 + 18 files changed, 789 insertions(+), 499 deletions(-) create mode 100644 kafka-ui-react-app/src/components/Topics/Topic/Edit/__test__/DangerZone.spec.tsx create mode 100644 kafka-ui-react-app/src/components/Topics/Topic/Edit/__test__/Edit.spec.tsx create mode 100644 kafka-ui-react-app/src/components/Topics/Topic/Edit/__test__/fixtures.ts delete mode 100644 kafka-ui-react-app/src/components/Topics/Topic/Edit/__tests__/DangerZone.spec.tsx delete mode 100644 kafka-ui-react-app/src/components/Topics/Topic/Edit/__tests__/__snapshots__/DangerZone.spec.tsx.snap rename kafka-ui-react-app/src/components/Topics/shared/Form/CustomParams/{__tests__ => __test__}/CustomParamField.spec.tsx (100%) rename kafka-ui-react-app/src/components/Topics/shared/Form/CustomParams/{__tests__ => __test__}/CustomParams.spec.tsx (87%) create mode 100644 kafka-ui-react-app/src/components/Topics/shared/Form/CustomParams/__test__/fixtures.ts diff --git a/.github/workflows/backend.yml b/.github/workflows/backend.yml index 677d4407a1..79c4bd2454 100644 --- a/.github/workflows/backend.yml +++ b/.github/workflows/backend.yml @@ -19,7 +19,7 @@ jobs: - name: compose app id: step_five run: | - docker-compose -f ./docker/kafka-ui.yaml up -d + docker-compose -f ./documentation/compose/kafka-ui.yaml up -d - name: Set up JDK 1.13 uses: actions/setup-java@v1 with: diff --git a/.github/workflows/e2e-checks.yaml b/.github/workflows/e2e-checks.yaml index 6ff3723258..8e1156c761 100644 --- a/.github/workflows/e2e-checks.yaml +++ b/.github/workflows/e2e-checks.yaml @@ -39,7 +39,7 @@ jobs: id: compose_app # use the following command until #819 will be fixed run: | - docker-compose -f ./docker/kafka-ui-connectors.yaml up -d + docker-compose -f ./documentation/compose/kafka-ui-connectors.yaml up -d - name: e2e run env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any diff --git a/kafka-ui-react-app/sonar-project.properties b/kafka-ui-react-app/sonar-project.properties index 976dbb0df4..d58df0d700 100644 --- a/kafka-ui-react-app/sonar-project.properties +++ b/kafka-ui-react-app/sonar-project.properties @@ -2,7 +2,7 @@ sonar.projectKey=provectus_kafka-ui_frontend sonar.organization=provectus sonar.sources=. -sonar.exclusions="**/__test?__/**,src/setupWorker.ts,src/setupTests.ts,**/fixtures.ts,src/lib/testHelpers.tsx" +sonar.exclusions=**/__test?__/**,src/setupWorker.ts,src/setupTests.ts,**/fixtures.ts,src/lib/testHelpers.tsx sonar.typescript.lcov.reportPaths=./coverage/lcov.info sonar.testExecutionReportPaths=./test-report.xml diff --git a/kafka-ui-react-app/src/components/Topics/Topic/Edit/DangerZone/DangerZone.styled.tsx b/kafka-ui-react-app/src/components/Topics/Topic/Edit/DangerZone/DangerZone.styled.tsx index c3be24fd91..c481c96394 100644 --- a/kafka-ui-react-app/src/components/Topics/Topic/Edit/DangerZone/DangerZone.styled.tsx +++ b/kafka-ui-react-app/src/components/Topics/Topic/Edit/DangerZone/DangerZone.styled.tsx @@ -1,12 +1,11 @@ import styled from 'styled-components'; -export const DangerZoneWrapperStyled = styled.div` - margin-top: 16px; +export const Wrapper = styled.div` + margin: 16px; padding: 8px 16px; border: 1px solid ${({ theme }) => theme.dangerZone.borderColor}; box-sizing: border-box; border-radius: 8px; - margin-bottom: 16px; & > div { display: flex; @@ -15,13 +14,13 @@ export const DangerZoneWrapperStyled = styled.div` } `; -export const DangerZoneTitleStyled = styled.h1` +export const Title = styled.h1` color: ${({ theme }) => theme.dangerZone.color}; font-size: 20px; padding-bottom: 16px; `; -export const DagerZoneFormStyled = styled.form` +export const Form = styled.form` display: flex; align-items: flex-end; gap: 16px; diff --git a/kafka-ui-react-app/src/components/Topics/Topic/Edit/DangerZone/DangerZone.tsx b/kafka-ui-react-app/src/components/Topics/Topic/Edit/DangerZone/DangerZone.tsx index 606179237a..4bb7bf5072 100644 --- a/kafka-ui-react-app/src/components/Topics/Topic/Edit/DangerZone/DangerZone.tsx +++ b/kafka-ui-react-app/src/components/Topics/Topic/Edit/DangerZone/DangerZone.tsx @@ -7,11 +7,7 @@ import { InputLabel } from 'components/common/Input/InputLabel.styled'; import React from 'react'; import { FormProvider, useForm } from 'react-hook-form'; -import { - DagerZoneFormStyled, - DangerZoneTitleStyled, - DangerZoneWrapperStyled, -} from './DangerZone.styled'; +import * as S from './DangerZone.styled'; export interface Props { clusterName: string; @@ -109,12 +105,13 @@ const DangerZone: React.FC = ({ ); }; return ( - - Danger Zone + + Danger Zone
-
@@ -137,12 +134,11 @@ const DangerZone: React.FC = ({ buttonSize="M" type="submit" disabled={!partitionsMethods.formState.isDirty} - data-testid="partitionsSubmit" > Submit
-
+
= ({ -
@@ -185,12 +182,11 @@ const DangerZone: React.FC = ({ buttonSize="M" type="submit" disabled={!replicationFactorMethods.formState.isDirty} - data-testid="replicationFactorSubmit" > Submit
-
+
@@ -207,7 +203,7 @@ const DangerZone: React.FC = ({ Are you sure you want to update the replication factor?
-
+ ); }; diff --git a/kafka-ui-react-app/src/components/Topics/Topic/Edit/Edit.tsx b/kafka-ui-react-app/src/components/Topics/Topic/Edit/Edit.tsx index 2bde287b97..17f49f5488 100644 --- a/kafka-ui-react-app/src/components/Topics/Topic/Edit/Edit.tsx +++ b/kafka-ui-react-app/src/components/Topics/Topic/Edit/Edit.tsx @@ -7,21 +7,19 @@ import { TopicWithDetailedInfo, TopicFormData, } from 'redux/interfaces'; -import { TopicConfig } from 'generated-sources'; import { useForm, FormProvider } from 'react-hook-form'; -import { camelCase } from 'lodash'; import TopicForm from 'components/Topics/shared/Form/TopicForm'; import { clusterTopicPath } from 'lib/paths'; import { useHistory } from 'react-router'; import { yupResolver } from '@hookform/resolvers/yup'; import { topicFormValidationSchema } from 'lib/yupExtended'; -import { TOPIC_CUSTOM_PARAMS } from 'lib/constants'; +import { TOPIC_CUSTOM_PARAMS_PREFIX, TOPIC_CUSTOM_PARAMS } from 'lib/constants'; import styled from 'styled-components'; import PageHeading from 'components/common/PageHeading/PageHeading'; import DangerZoneContainer from './DangerZone/DangerZoneContainer'; -interface Props { +export interface Props { clusterName: ClusterName; topicName: TopicName; topic?: TopicWithDetailedInfo; @@ -64,27 +62,18 @@ const topicParams = (topic: TopicWithDetailedInfo | undefined) => { const { name, replicationFactor } = topic; - const configs = topic.config?.reduce( - (result: { [key: string]: TopicConfig['value'] }, param) => ({ - ...result, - [camelCase(param.name)]: param.value || param.defaultValue, - }), - {} - ); - return { ...DEFAULTS, name, partitions: topic.partitionCount || DEFAULTS.partitions, replicationFactor, - customParams: topic.config + [TOPIC_CUSTOM_PARAMS_PREFIX]: topic.config ?.filter( (el) => el.value !== el.defaultValue && Object.keys(TOPIC_CUSTOM_PARAMS).includes(el.name) ) .map((el) => ({ name: el.name, value: el.value })), - ...configs, }; }; @@ -99,8 +88,10 @@ const Edit: React.FC = ({ fetchTopicConfig, updateTopic, }) => { - const defaultValues = topicParams(topic); - + const defaultValues = React.useMemo( + () => topicParams(topic), + [topicParams, topic] + ); const methods = useForm({ defaultValues, resolver: yupResolver(topicFormValidationSchema), @@ -147,17 +138,14 @@ const Edit: React.FC = ({
-
- - - -
+ + + {topic && ( ) => + render( + + ); + +const clickOnDialogSubmitButton = () => { + userEvent.click( + within(screen.getByRole('dialog')).getByRole('button', { + name: 'Submit', + }) + ); +}; +describe('DangerZone', () => { + it('renders', () => { + renderComponent(); + + const numberOfPartitionsEditForm = screen.getByRole('form', { + name: 'Edit number of partitions', + }); + expect(numberOfPartitionsEditForm).toBeInTheDocument(); + expect( + within(numberOfPartitionsEditForm).getByRole('spinbutton', { + name: 'Number of partitions *', + }) + ).toBeInTheDocument(); + expect( + within(numberOfPartitionsEditForm).getByRole('button', { name: 'Submit' }) + ).toBeInTheDocument(); + + const replicationFactorEditForm = screen.getByRole('form', { + name: 'Edit replication factor', + }); + expect(replicationFactorEditForm).toBeInTheDocument(); + expect( + within(replicationFactorEditForm).getByRole('spinbutton', { + name: 'Replication Factor *', + }) + ).toBeInTheDocument(); + expect( + within(replicationFactorEditForm).getByRole('button', { name: 'Submit' }) + ).toBeInTheDocument(); + }); + + it('calls updateTopicPartitionsCount', async () => { + const mockUpdateTopicPartitionsCount = jest.fn(); + renderComponent({ + updateTopicPartitionsCount: mockUpdateTopicPartitionsCount, + }); + const numberOfPartitionsEditForm = screen.getByRole('form', { + name: 'Edit number of partitions', + }); + + userEvent.type( + within(numberOfPartitionsEditForm).getByRole('spinbutton'), + '4' + ); + userEvent.click(within(numberOfPartitionsEditForm).getByRole('button')); + + await waitFor(() => expect(screen.getByRole('dialog')).toBeInTheDocument()); + await waitFor(() => clickOnDialogSubmitButton()); + + expect(mockUpdateTopicPartitionsCount).toHaveBeenCalledTimes(1); + }); + + it('calls updateTopicReplicationFactor', async () => { + const mockUpdateTopicReplicationFactor = jest.fn(); + renderComponent({ + updateTopicReplicationFactor: mockUpdateTopicReplicationFactor, + }); + + const replicationFactorEditForm = screen.getByRole('form', { + name: 'Edit replication factor', + }); + expect( + within(replicationFactorEditForm).getByRole('spinbutton', { + name: 'Replication Factor *', + }) + ).toBeInTheDocument(); + expect( + within(replicationFactorEditForm).getByRole('button', { name: 'Submit' }) + ).toBeInTheDocument(); + + userEvent.type( + within(replicationFactorEditForm).getByRole('spinbutton'), + '4' + ); + userEvent.click(within(replicationFactorEditForm).getByRole('button')); + + await waitFor(() => expect(screen.getByRole('dialog')).toBeInTheDocument()); + await waitFor(() => clickOnDialogSubmitButton()); + + await waitFor(() => { + expect(mockUpdateTopicReplicationFactor).toHaveBeenCalledTimes(1); + }); + }); +}); diff --git a/kafka-ui-react-app/src/components/Topics/Topic/Edit/__test__/Edit.spec.tsx b/kafka-ui-react-app/src/components/Topics/Topic/Edit/__test__/Edit.spec.tsx new file mode 100644 index 0000000000..bc13e8ec5f --- /dev/null +++ b/kafka-ui-react-app/src/components/Topics/Topic/Edit/__test__/Edit.spec.tsx @@ -0,0 +1,34 @@ +import React from 'react'; +import Edit, { Props } from 'components/Topics/Topic/Edit/Edit'; +import { screen } from '@testing-library/react'; +import { render } from 'lib/testHelpers'; + +import { topicName, clusterName, topicWithInfo } from './fixtures'; + +const renderComponent = (props?: Partial) => + render( + + ); + +describe('DangerZone', () => { + it('renders', () => { + renderComponent(); + + expect( + screen.getByRole('heading', { name: `Edit ${topicName}` }) + ).toBeInTheDocument(); + expect( + screen.getByRole('heading', { name: `Danger Zone` }) + ).toBeInTheDocument(); + }); +}); diff --git a/kafka-ui-react-app/src/components/Topics/Topic/Edit/__test__/fixtures.ts b/kafka-ui-react-app/src/components/Topics/Topic/Edit/__test__/fixtures.ts new file mode 100644 index 0000000000..4d4d562b4c --- /dev/null +++ b/kafka-ui-react-app/src/components/Topics/Topic/Edit/__test__/fixtures.ts @@ -0,0 +1,553 @@ +import { CleanUpPolicy, ConfigSource, TopicConfig } from 'generated-sources'; +import { TopicWithDetailedInfo } from 'redux/interfaces/topic'; + +export const clusterName = 'testCluster'; +export const topicName = 'testTopic'; + +export const config: TopicConfig[] = [ + { + name: 'compression.type', + value: 'producer', + defaultValue: 'producer', + source: ConfigSource.DYNAMIC_TOPIC_CONFIG, + isSensitive: false, + isReadOnly: false, + synonyms: [ + { + name: 'compression.type', + value: 'producer', + source: ConfigSource.DYNAMIC_TOPIC_CONFIG, + }, + { + name: 'compression.type', + value: 'producer', + source: ConfigSource.DEFAULT_CONFIG, + }, + ], + }, + { + name: 'confluent.value.schema.validation', + value: 'false', + source: ConfigSource.DEFAULT_CONFIG, + isSensitive: false, + isReadOnly: false, + synonyms: [], + }, + { + name: 'leader.replication.throttled.replicas', + value: '', + defaultValue: '', + source: ConfigSource.DEFAULT_CONFIG, + isSensitive: false, + isReadOnly: false, + synonyms: [], + }, + { + name: 'confluent.key.subject.name.strategy', + value: 'io.confluent.kafka.serializers.subject.TopicNameStrategy', + source: ConfigSource.DEFAULT_CONFIG, + isSensitive: false, + isReadOnly: false, + synonyms: [], + }, + { + name: 'message.downconversion.enable', + value: 'true', + defaultValue: 'true', + source: ConfigSource.DEFAULT_CONFIG, + isSensitive: false, + isReadOnly: false, + synonyms: [ + { + name: 'log.message.downconversion.enable', + value: 'true', + source: ConfigSource.DEFAULT_CONFIG, + }, + ], + }, + { + name: 'min.insync.replicas', + value: '1', + defaultValue: '1', + source: ConfigSource.DYNAMIC_TOPIC_CONFIG, + isSensitive: false, + isReadOnly: false, + synonyms: [ + { + name: 'min.insync.replicas', + value: '1', + source: ConfigSource.DYNAMIC_TOPIC_CONFIG, + }, + { + name: 'min.insync.replicas', + value: '1', + source: ConfigSource.DEFAULT_CONFIG, + }, + ], + }, + { + name: 'segment.jitter.ms', + value: '0', + defaultValue: '0', + source: ConfigSource.DEFAULT_CONFIG, + isSensitive: false, + isReadOnly: false, + synonyms: [], + }, + { + name: 'cleanup.policy', + value: 'delete', + defaultValue: 'delete', + source: ConfigSource.DYNAMIC_TOPIC_CONFIG, + isSensitive: false, + isReadOnly: false, + synonyms: [ + { + name: 'cleanup.policy', + value: 'delete', + source: ConfigSource.DYNAMIC_TOPIC_CONFIG, + }, + { + name: 'log.cleanup.policy', + value: 'delete', + source: ConfigSource.DEFAULT_CONFIG, + }, + ], + }, + { + name: 'flush.ms', + value: '9223372036854775807', + defaultValue: '9223372036854775807', + source: ConfigSource.DEFAULT_CONFIG, + isSensitive: false, + isReadOnly: false, + synonyms: [], + }, + { + name: 'confluent.tier.local.hotset.ms', + value: '86400000', + source: ConfigSource.DEFAULT_CONFIG, + isSensitive: false, + isReadOnly: false, + synonyms: [ + { + name: 'confluent.tier.local.hotset.ms', + value: '86400000', + source: ConfigSource.DEFAULT_CONFIG, + }, + ], + }, + { + name: 'follower.replication.throttled.replicas', + value: '', + defaultValue: '', + source: ConfigSource.DEFAULT_CONFIG, + isSensitive: false, + isReadOnly: false, + synonyms: [], + }, + { + name: 'confluent.tier.local.hotset.bytes', + value: '-1', + source: ConfigSource.DEFAULT_CONFIG, + isSensitive: false, + isReadOnly: false, + synonyms: [ + { + name: 'confluent.tier.local.hotset.bytes', + value: '-1', + source: ConfigSource.DEFAULT_CONFIG, + }, + ], + }, + { + name: 'confluent.value.subject.name.strategy', + value: 'io.confluent.kafka.serializers.subject.TopicNameStrategy', + source: ConfigSource.DEFAULT_CONFIG, + isSensitive: false, + isReadOnly: false, + synonyms: [], + }, + { + name: 'segment.bytes', + value: '1073741824', + defaultValue: '1073741824', + source: ConfigSource.DEFAULT_CONFIG, + isSensitive: false, + isReadOnly: false, + synonyms: [ + { + name: 'log.segment.bytes', + value: '1073741824', + source: ConfigSource.DEFAULT_CONFIG, + }, + ], + }, + { + name: 'retention.ms', + value: '604800000', + defaultValue: '604800000', + source: ConfigSource.DYNAMIC_TOPIC_CONFIG, + isSensitive: false, + isReadOnly: false, + synonyms: [ + { + name: 'retention.ms', + value: '604800000', + source: ConfigSource.DYNAMIC_TOPIC_CONFIG, + }, + ], + }, + { + name: 'flush.messages', + value: '9223372036854775807', + defaultValue: '9223372036854775807', + source: ConfigSource.DEFAULT_CONFIG, + isSensitive: false, + isReadOnly: false, + synonyms: [ + { + name: 'log.flush.interval.messages', + value: '9223372036854775807', + source: ConfigSource.DEFAULT_CONFIG, + }, + ], + }, + { + name: 'confluent.tier.enable', + value: 'false', + source: ConfigSource.DEFAULT_CONFIG, + isSensitive: false, + isReadOnly: false, + synonyms: [ + { + name: 'confluent.tier.enable', + value: 'false', + source: ConfigSource.DEFAULT_CONFIG, + }, + ], + }, + { + name: 'confluent.tier.segment.hotset.roll.min.bytes', + value: '104857600', + source: ConfigSource.DEFAULT_CONFIG, + isSensitive: false, + isReadOnly: false, + synonyms: [ + { + name: 'confluent.tier.segment.hotset.roll.min.bytes', + value: '104857600', + source: ConfigSource.DEFAULT_CONFIG, + }, + ], + }, + { + name: 'confluent.segment.speculative.prefetch.enable', + value: 'false', + source: ConfigSource.DEFAULT_CONFIG, + isSensitive: false, + isReadOnly: false, + synonyms: [ + { + name: 'confluent.segment.speculative.prefetch.enable', + value: 'false', + source: ConfigSource.DEFAULT_CONFIG, + }, + ], + }, + { + name: 'message.format.version', + value: '2.7-IV2', + defaultValue: '2.7-IV2', + source: ConfigSource.DEFAULT_CONFIG, + isSensitive: false, + isReadOnly: false, + synonyms: [ + { + name: 'log.message.format.version', + value: '2.7-IV2', + source: ConfigSource.DEFAULT_CONFIG, + }, + ], + }, + { + name: 'max.compaction.lag.ms', + value: '9223372036854775807', + defaultValue: '9223372036854775807', + source: ConfigSource.DEFAULT_CONFIG, + isSensitive: false, + isReadOnly: false, + synonyms: [ + { + name: 'log.cleaner.max.compaction.lag.ms', + value: '9223372036854775807', + source: ConfigSource.DEFAULT_CONFIG, + }, + ], + }, + { + name: 'file.delete.delay.ms', + value: '60000', + defaultValue: '60000', + source: ConfigSource.DEFAULT_CONFIG, + isSensitive: false, + isReadOnly: false, + synonyms: [ + { + name: 'log.segment.delete.delay.ms', + value: '60000', + source: ConfigSource.DEFAULT_CONFIG, + }, + ], + }, + { + name: 'max.message.bytes', + value: '1000012', + defaultValue: '1000012', + source: ConfigSource.DYNAMIC_TOPIC_CONFIG, + isSensitive: false, + isReadOnly: false, + synonyms: [ + { + name: 'max.message.bytes', + value: '1000012', + source: ConfigSource.DYNAMIC_TOPIC_CONFIG, + }, + { + name: 'message.max.bytes', + value: '1048588', + source: ConfigSource.DEFAULT_CONFIG, + }, + ], + }, + { + name: 'min.compaction.lag.ms', + value: '0', + defaultValue: '0', + source: ConfigSource.DEFAULT_CONFIG, + isSensitive: false, + isReadOnly: false, + synonyms: [ + { + name: 'log.cleaner.min.compaction.lag.ms', + value: '0', + source: ConfigSource.DEFAULT_CONFIG, + }, + ], + }, + { + name: 'message.timestamp.type', + value: 'CreateTime', + defaultValue: 'CreateTime', + source: ConfigSource.DEFAULT_CONFIG, + isSensitive: false, + isReadOnly: false, + synonyms: [ + { + name: 'log.message.timestamp.type', + value: 'CreateTime', + source: ConfigSource.DEFAULT_CONFIG, + }, + ], + }, + { + name: 'preallocate', + value: 'false', + defaultValue: 'false', + source: ConfigSource.DEFAULT_CONFIG, + isSensitive: false, + isReadOnly: false, + synonyms: [ + { + name: 'log.preallocate', + value: 'false', + source: ConfigSource.DEFAULT_CONFIG, + }, + ], + }, + { + name: 'confluent.placement.constraints', + value: '', + source: ConfigSource.DEFAULT_CONFIG, + isSensitive: false, + isReadOnly: false, + synonyms: [], + }, + { + name: 'min.cleanable.dirty.ratio', + value: '0.5', + defaultValue: '0.5', + source: ConfigSource.DEFAULT_CONFIG, + isSensitive: false, + isReadOnly: false, + synonyms: [ + { + name: 'log.cleaner.min.cleanable.ratio', + value: '0.5', + source: ConfigSource.DEFAULT_CONFIG, + }, + ], + }, + { + name: 'index.interval.bytes', + value: '4096', + defaultValue: '4096', + source: ConfigSource.DEFAULT_CONFIG, + isSensitive: false, + isReadOnly: false, + synonyms: [ + { + name: 'log.index.interval.bytes', + value: '4096', + source: ConfigSource.DEFAULT_CONFIG, + }, + ], + }, + { + name: 'unclean.leader.election.enable', + value: 'false', + defaultValue: 'false', + source: ConfigSource.DEFAULT_CONFIG, + isSensitive: false, + isReadOnly: false, + synonyms: [ + { + name: 'unclean.leader.election.enable', + value: 'false', + source: ConfigSource.DEFAULT_CONFIG, + }, + ], + }, + { + name: 'retention.bytes', + value: '-1', + defaultValue: '-1', + source: ConfigSource.DYNAMIC_TOPIC_CONFIG, + isSensitive: false, + isReadOnly: false, + synonyms: [ + { + name: 'retention.bytes', + value: '-1', + source: ConfigSource.DYNAMIC_TOPIC_CONFIG, + }, + { + name: 'log.retention.bytes', + value: '-1', + source: ConfigSource.DEFAULT_CONFIG, + }, + ], + }, + { + name: 'delete.retention.ms', + value: '86400001', + defaultValue: '86400000', + source: ConfigSource.DYNAMIC_TOPIC_CONFIG, + isSensitive: false, + isReadOnly: false, + synonyms: [ + { + name: 'delete.retention.ms', + value: '86400001', + source: ConfigSource.DYNAMIC_TOPIC_CONFIG, + }, + { + name: 'log.cleaner.delete.retention.ms', + value: '86400000', + source: ConfigSource.DEFAULT_CONFIG, + }, + ], + }, + { + name: 'confluent.prefer.tier.fetch.ms', + value: '-1', + source: ConfigSource.DEFAULT_CONFIG, + isSensitive: false, + isReadOnly: false, + synonyms: [ + { + name: 'confluent.prefer.tier.fetch.ms', + value: '-1', + source: ConfigSource.DEFAULT_CONFIG, + }, + ], + }, + { + name: 'confluent.key.schema.validation', + value: 'false', + source: ConfigSource.DEFAULT_CONFIG, + isSensitive: false, + isReadOnly: false, + synonyms: [], + }, + { + name: 'segment.ms', + value: '604800000', + defaultValue: '604800000', + source: ConfigSource.DEFAULT_CONFIG, + isSensitive: false, + isReadOnly: false, + synonyms: [], + }, + { + name: 'message.timestamp.difference.max.ms', + value: '9223372036854775807', + defaultValue: '9223372036854775807', + source: ConfigSource.DEFAULT_CONFIG, + isSensitive: false, + isReadOnly: false, + synonyms: [ + { + name: 'log.message.timestamp.difference.max.ms', + value: '9223372036854775807', + source: ConfigSource.DEFAULT_CONFIG, + }, + ], + }, + { + name: 'segment.index.bytes', + value: '10485760', + defaultValue: '10485760', + source: ConfigSource.DEFAULT_CONFIG, + isSensitive: false, + isReadOnly: false, + synonyms: [ + { + name: 'log.index.size.max.bytes', + value: '10485760', + source: ConfigSource.DEFAULT_CONFIG, + }, + ], + }, +]; + +export const partitions = [ + { + partition: 0, + leader: 2, + replicas: [ + { + broker: 2, + leader: false, + inSync: true, + }, + ], + offsetMax: 0, + offsetMin: 0, + }, +]; + +export const topicWithInfo: TopicWithDetailedInfo = { + name: topicName, + internal: false, + partitionCount: 1, + replicationFactor: 1, + replicas: 1, + inSyncReplicas: 1, + segmentSize: 0, + segmentCount: 1, + underReplicatedPartitions: 0, + cleanUpPolicy: CleanUpPolicy.DELETE, + partitions, + config, +}; diff --git a/kafka-ui-react-app/src/components/Topics/Topic/Edit/__tests__/DangerZone.spec.tsx b/kafka-ui-react-app/src/components/Topics/Topic/Edit/__tests__/DangerZone.spec.tsx deleted file mode 100644 index 53bad85d63..0000000000 --- a/kafka-ui-react-app/src/components/Topics/Topic/Edit/__tests__/DangerZone.spec.tsx +++ /dev/null @@ -1,64 +0,0 @@ -import React from 'react'; -import DangerZone, { - Props, -} from 'components/Topics/Topic/Edit/DangerZone/DangerZone'; -import { screen, waitFor } from '@testing-library/react'; -import userEvent from '@testing-library/user-event'; -import { render } from 'lib/testHelpers'; - -const setupWrapper = (props?: Partial) => ( - -); - -describe('DangerZone', () => { - it('is rendered properly', () => { - const component = render(setupWrapper()); - expect(component.baseElement).toMatchSnapshot(); - }); - - it('calls updateTopicPartitionsCount', async () => { - const mockUpdateTopicPartitionsCount = jest.fn(); - render( - setupWrapper({ - updateTopicPartitionsCount: mockUpdateTopicPartitionsCount, - }) - ); - - userEvent.type(screen.getByLabelText('Number of partitions *'), '4'); - userEvent.click(screen.getByTestId('partitionsSubmit')); - - await waitFor(() => { - userEvent.click(screen.getAllByText('Submit')[1]); - expect(mockUpdateTopicPartitionsCount).toHaveBeenCalledTimes(1); - }); - }); - - it('calls updateTopicReplicationFactor', async () => { - const mockUpdateTopicReplicationFactor = jest.fn(); - render( - setupWrapper({ - updateTopicReplicationFactor: mockUpdateTopicReplicationFactor, - }) - ); - - userEvent.type(screen.getByLabelText('Replication Factor *'), '4'); - userEvent.click(screen.getByTestId('replicationFactorSubmit')); - await waitFor(() => { - userEvent.click(screen.getAllByText('Submit')[2]); - }); - - await waitFor(() => { - expect(mockUpdateTopicReplicationFactor).toHaveBeenCalledTimes(1); - }); - }); -}); diff --git a/kafka-ui-react-app/src/components/Topics/Topic/Edit/__tests__/__snapshots__/DangerZone.spec.tsx.snap b/kafka-ui-react-app/src/components/Topics/Topic/Edit/__tests__/__snapshots__/DangerZone.spec.tsx.snap deleted file mode 100644 index 74af8432fe..0000000000 --- a/kafka-ui-react-app/src/components/Topics/Topic/Edit/__tests__/__snapshots__/DangerZone.spec.tsx.snap +++ /dev/null @@ -1,360 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`DangerZone is rendered properly 1`] = ` -.c6 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: row; - -ms-flex-direction: row; - flex-direction: row; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - -webkit-box-pack: center; - -webkit-justify-content: center; - -ms-flex-pack: center; - justify-content: center; - padding: 0px 12px; - border: none; - border-radius: 4px; - white-space: nowrap; - background: #4F4FFF; - color: #FFFFFF; - font-size: 14px; - font-weight: 500; - height: 32px; -} - -.c6:hover:enabled { - background: #1717CF; - color: #FFFFFF; - cursor: pointer; -} - -.c6:active:enabled { - background: #1414B8; - color: #FFFFFF; -} - -.c6:disabled { - opacity: 0.5; - cursor: not-allowed; -} - -.c6 a { - color: #FFFFFF; -} - -.c6 i { - margin-right: 7px; -} - -.c5 { - border: 1px #ABB5BA solid; - border-radius: 4px; - height: 32px; - width: 100%; - padding-left: 12px; - font-size: 14px; -} - -.c5::-webkit-input-placeholder { - color: #ABB5BA; - font-size: 14px; -} - -.c5::-moz-placeholder { - color: #ABB5BA; - font-size: 14px; -} - -.c5:-ms-input-placeholder { - color: #ABB5BA; - font-size: 14px; -} - -.c5::placeholder { - color: #ABB5BA; - font-size: 14px; -} - -.c5:hover { - border-color: #73848C; -} - -.c5:focus { - outline: none; - border-color: #454F54; -} - -.c5:focus::-webkit-input-placeholder { - color: transparent; -} - -.c5:focus::-moz-placeholder { - color: transparent; -} - -.c5:focus:-ms-input-placeholder { - color: transparent; -} - -.c5:focus::placeholder { - color: transparent; -} - -.c5:disabled { - color: #ABB5BA; - border-color: #E3E6E8; - cursor: not-allowed; -} - -.c5:read-only { - color: #171A1C; - border: none; - background-color: #F1F2F3; - cursor: not-allowed; -} - -.c5:-moz-read-only:focus::placeholder { - color: #ABB5BA; -} - -.c5:read-only:focus::placeholder { - color: #ABB5BA; -} - -.c8 { - border: 1px #ABB5BA solid; - border-radius: 4px; - height: 40px; - width: 100%; - padding-left: 12px; - font-size: 14px; -} - -.c8::-webkit-input-placeholder { - color: #ABB5BA; - font-size: 14px; -} - -.c8::-moz-placeholder { - color: #ABB5BA; - font-size: 14px; -} - -.c8:-ms-input-placeholder { - color: #ABB5BA; - font-size: 14px; -} - -.c8::placeholder { - color: #ABB5BA; - font-size: 14px; -} - -.c8:hover { - border-color: #73848C; -} - -.c8:focus { - outline: none; - border-color: #454F54; -} - -.c8:focus::-webkit-input-placeholder { - color: transparent; -} - -.c8:focus::-moz-placeholder { - color: transparent; -} - -.c8:focus:-ms-input-placeholder { - color: transparent; -} - -.c8:focus::placeholder { - color: transparent; -} - -.c8:disabled { - color: #ABB5BA; - border-color: #E3E6E8; - cursor: not-allowed; -} - -.c8:read-only { - color: #171A1C; - border: none; - background-color: #F1F2F3; - cursor: not-allowed; -} - -.c8:-moz-read-only:focus::placeholder { - color: #ABB5BA; -} - -.c8:read-only:focus::placeholder { - color: #ABB5BA; -} - -.c7 { - color: #E51A1A; - font-size: 12px; -} - -.c4 { - position: relative; -} - -.c3 { - font-weight: 500; - font-size: 12px; - line-height: 20px; - color: #454F54; -} - -.c0 { - margin-top: 16px; - padding: 8px 16px; - border: 1px solid #E3E6E8; - box-sizing: border-box; - border-radius: 8px; - margin-bottom: 16px; -} - -.c0 > div { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; - gap: 8px; -} - -.c1 { - color: #E51A1A; - font-size: 20px; - padding-bottom: 16px; -} - -.c2 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: flex-end; - -webkit-box-align: flex-end; - -ms-flex-align: flex-end; - align-items: flex-end; - gap: 16px; -} - -.c2 > *:first-child { - -webkit-box-flex: 4; - -webkit-flex-grow: 4; - -ms-flex-positive: 4; - flex-grow: 4; -} - -.c2 > *:last-child { - -webkit-box-flex: 1; - -webkit-flex-grow: 1; - -ms-flex-positive: 1; - flex-grow: 1; -} - - -
-
-

- Danger Zone -

-
-
-
- -
- -
-
-
- -
-
-

-

-
- -
- -
-
-
- -
-
-

-

-
-
- -`; diff --git a/kafka-ui-react-app/src/components/Topics/shared/Form/CustomParams/CustomParamField.tsx b/kafka-ui-react-app/src/components/Topics/shared/Form/CustomParams/CustomParamField.tsx index 9c7d59e1c5..c076f76503 100644 --- a/kafka-ui-react-app/src/components/Topics/shared/Form/CustomParams/CustomParamField.tsx +++ b/kafka-ui-react-app/src/components/Topics/shared/Form/CustomParams/CustomParamField.tsx @@ -64,13 +64,14 @@ const CustomParamField: React.FC = ({ control={control} rules={{ required: 'Custom Parameter is required.' }} name={`customParams.${index}.name`} - render={({ field: { name, onChange } }) => ( + render={({ field: { value, name, onChange } }) => (