1- import { render , screen } from '@testing-library/react' ;
1+ import { render , screen , within } from '@testing-library/react' ;
22import { vi } from 'vitest' ;
33
44import ConfigurationEditor from './topic-configuration' ;
@@ -12,62 +12,118 @@ vi.mock('@tanstack/react-router', async (importOriginal) => {
1212 } ;
1313} ) ;
1414
15+ const mockIsFeatureFlagEnabled = vi . fn < ( flag : string ) => boolean > ( ) ;
16+ vi . mock ( '../../../config' , async ( importOriginal ) => {
17+ const actual = await importOriginal < typeof import ( '../../../config' ) > ( ) ;
18+ return {
19+ ...actual ,
20+ isServerless : ( ) => false ,
21+ isFeatureFlagEnabled : ( flag : string ) => mockIsFeatureFlagEnabled ( flag ) ,
22+ } ;
23+ } ) ;
24+
1525import type { ConfigEntryExtended } from '../../../state/rest-interfaces' ;
1626
27+ const makeEntry = ( overrides : Partial < ConfigEntryExtended > & { category : string } ) : ConfigEntryExtended => ( {
28+ name : 'test.option' ,
29+ value : '' ,
30+ source : '' ,
31+ type : 'STRING' ,
32+ isExplicitlySet : false ,
33+ isDefaultValue : false ,
34+ isReadOnly : false ,
35+ isSensitive : false ,
36+ synonyms : [ ] ,
37+ currentValue : '' ,
38+ ...overrides ,
39+ } ) ;
40+
1741describe ( 'TopicConfiguration' , ( ) => {
18- test ( 'renders groups in the correct order' , ( ) => {
19- // Generate an out of order set of test options
20- const entries : ConfigEntryExtended [ ] = [
21- 'Retention' ,
22- 'Tiered Storage' ,
23- 'Storage Internals' ,
24- 'Compression' ,
25- 'Compaction' ,
26- 'Replication' ,
27- 'Iceberg' ,
28- '' , // unknown options should appear at the end as 'Other'
29- 'Message Handling' ,
30- 'Write Caching' ,
31- 'Schema Registry and Validation' ,
32- ] . map ( ( category ) => ( {
33- name : 'test.option' ,
34- category,
35- value : '' ,
36- source : '' ,
37- type : 'STRING' ,
38- isExplicitlySet : false ,
39- isDefaultValue : false ,
40- isReadOnly : false ,
41- isSensitive : false ,
42- synonyms : [ ] ,
43- currentValue : '' ,
44- } ) ) ;
45-
46- const { container } = render (
47- < ConfigurationEditor
48- entries = { entries }
49- onForceRefresh = { ( ) => {
50- // no op - test callback
51- } }
52- targetTopic = ""
53- />
54- ) ;
55- expect ( screen . getByTestId ( 'config-group-table' ) ) . toBeVisible ( ) ;
56-
57- const groups = container . querySelectorAll ( '.configGroupTitle' ) ;
58-
59- expect ( Array . from ( groups ) . map ( ( g ) => g . textContent ) ) . toEqual ( [
60- 'Retention' ,
61- 'Compaction' ,
62- 'Replication' ,
63- 'Tiered Storage' ,
64- 'Write Caching' ,
65- 'Iceberg' ,
66- 'Schema Registry and Validation' ,
67- 'Message Handling' ,
68- 'Compression' ,
69- 'Storage Internals' ,
70- 'Other' ,
71- ] ) ;
42+ describe ( 'legacy layout (enableNewTopicPage off)' , ( ) => {
43+ beforeEach ( ( ) => mockIsFeatureFlagEnabled . mockReturnValue ( false ) ) ;
44+
45+ test ( 'renders groups in the correct order' , ( ) => {
46+ // Generate an out of order set of test options
47+ const entries : ConfigEntryExtended [ ] = [
48+ 'Retention' ,
49+ 'Tiered Storage' ,
50+ 'Storage Internals' ,
51+ 'Compression' ,
52+ 'Compaction' ,
53+ 'Replication' ,
54+ 'Iceberg' ,
55+ '' , // unknown options should appear at the end as 'Other'
56+ 'Message Handling' ,
57+ 'Write Caching' ,
58+ 'Schema Registry and Validation' ,
59+ ] . map ( ( category ) => makeEntry ( { category } ) ) ;
60+
61+ const { container } = render (
62+ < ConfigurationEditor
63+ entries = { entries }
64+ onForceRefresh = { ( ) => {
65+ // no op - test callback
66+ } }
67+ targetTopic = ""
68+ />
69+ ) ;
70+ expect ( screen . getByTestId ( 'config-group-table' ) ) . toBeVisible ( ) ;
71+
72+ const groups = container . querySelectorAll ( '.configGroupTitle' ) ;
73+
74+ expect ( Array . from ( groups ) . map ( ( g ) => g . textContent ) ) . toEqual ( [
75+ 'Retention' ,
76+ 'Compaction' ,
77+ 'Replication' ,
78+ 'Tiered Storage' ,
79+ 'Write Caching' ,
80+ 'Iceberg' ,
81+ 'Schema Registry and Validation' ,
82+ 'Message Handling' ,
83+ 'Compression' ,
84+ 'Storage Internals' ,
85+ 'Other' ,
86+ ] ) ;
87+ } ) ;
88+ } ) ;
89+
90+ describe ( 'grouped layout (enableNewTopicPage on)' , ( ) => {
91+ beforeEach ( ( ) => mockIsFeatureFlagEnabled . mockReturnValue ( true ) ) ;
92+
93+ test ( 'renders a sidebar and titled sections, collapsing unmapped categories into Other' , ( ) => {
94+ const entries : ConfigEntryExtended [ ] = [
95+ makeEntry ( { name : 'retention.ms' , category : 'Retention' , isExplicitlySet : true } ) ,
96+ makeEntry ( { name : 'cleanup.policy' , category : 'Compaction' } ) ,
97+ makeEntry ( { name : 'redpanda.iceberg.mode' , category : 'Iceberg' } ) ,
98+ ] ;
99+
100+ render (
101+ < ConfigurationEditor
102+ entries = { entries }
103+ onForceRefresh = { ( ) => {
104+ // no op - test callback
105+ } }
106+ targetTopic = "my-topic"
107+ />
108+ ) ;
109+
110+ // Sidebar lists each visible category; unmapped 'Iceberg' collapses into 'Other'.
111+ const nav = screen . getByRole ( 'navigation' , { name : 'Configuration categories' } ) ;
112+ expect ( within ( nav ) . getByText ( 'Retention' ) ) . toBeVisible ( ) ;
113+ expect ( within ( nav ) . getByText ( 'Compaction' ) ) . toBeVisible ( ) ;
114+ expect ( within ( nav ) . getByText ( 'Other' ) ) . toBeVisible ( ) ;
115+ expect ( within ( nav ) . queryByText ( 'Iceberg' ) ) . not . toBeInTheDocument ( ) ;
116+
117+ // Each visible category renders as a titled section.
118+ const retentionSection = screen . getByRole ( 'heading' , { name : 'Retention' } ) . closest ( 'section' ) as HTMLElement ;
119+ expect ( retentionSection ) . toBeVisible ( ) ;
120+
121+ // Only modified rows get a badge; the explicitly-set retention.ms row shows 'Modified',
122+ // and the default cleanup.policy row shows no badge.
123+ expect ( within ( retentionSection ) . getByText ( 'Modified' ) ) . toBeVisible ( ) ;
124+ const compactionSection = screen . getByRole ( 'heading' , { name : 'Compaction' } ) . closest ( 'section' ) as HTMLElement ;
125+ expect ( within ( compactionSection ) . queryByText ( 'Modified' ) ) . not . toBeInTheDocument ( ) ;
126+ expect ( within ( compactionSection ) . queryByText ( 'Default' ) ) . not . toBeInTheDocument ( ) ;
127+ } ) ;
72128 } ) ;
73129} ) ;
0 commit comments