1+ import type { Features } from '$/api/features' ;
12import { QueryClient , QueryClientProvider } from '@tanstack/react-query' ;
23import { fireEvent , render , screen , waitFor , within } from '@testing-library/react' ;
34import userEvent from '@testing-library/user-event' ;
@@ -20,6 +21,8 @@ vi.mock('$/api/nodes', () => ({
2021 getNodeFlags : api . getNodeFlags ,
2122} ) ) ;
2223
24+ vi . mock ( '$/api/features' , ( ) => ( { getFeatures : ( ) => mockFeatures ( ) } ) ) ;
25+
2326vi . mock ( '$/api/extensions' , ( ) => ( {
2427 getNodeExtensions : api . getNodeExtensions ,
2528} ) ) ;
@@ -46,6 +49,8 @@ vi.mock('$/components/forms/CodeEditor', () => ({
4649 ) ,
4750} ) ) ;
4851
52+ const baseFeatures : Features = { posture : false , service_config : false , accelerated : false , file_explorer : false } ;
53+ const mockFeatures = vi . fn < ( ) => Promise < Features > > ( ) ;
4954const ENV_CFG = '{"options":{"a":"1"}}' ;
5055const APPLIED_CFG = '{"options":{"a":"2"}}' ;
5156
@@ -83,6 +88,7 @@ describe('NodeConfigTab', () => {
8388 api . getNodeConfig . mockResolvedValue ( makeConfig ( ) ) ;
8489 api . putNodeConfig . mockResolvedValue ( makeConfig ( { override : '{"x":1}' } ) ) ;
8590 api . deleteNodeConfig . mockResolvedValue ( makeConfig ( ) ) ;
91+ mockFeatures . mockResolvedValue ( { ...baseFeatures , osctrld : true } ) ;
8692 } ) ;
8793
8894 it ( 'shows the applied configuration read-only by default' , async ( ) => {
@@ -259,4 +265,24 @@ describe('NodeConfigTab', () => {
259265 expect ( await screen . findByText ( 'No extensions apply to this host.' ) ) . toBeInTheDocument ( ) ;
260266 expect ( api . getNodeExtensions ) . toHaveBeenCalledWith ( 'prod' , 'uuid-1' ) ;
261267 } ) ;
268+ it . each ( [ [ 'false' , { osctrld : false } ] , [ 'absent' , { } ] ] ) ( 'hides Flags, Extensions and Osquery version when osctrld is %s' , async ( _l , extra ) => {
269+ mockFeatures . mockResolvedValue ( { ...baseFeatures , ...extra } ) ;
270+ renderTab ( ) ;
271+ expect ( await screen . findByLabelText ( 'Applied configuration' ) ) . toBeInTheDocument ( ) ;
272+ await waitFor ( ( ) => expect ( mockFeatures ) . toHaveBeenCalled ( ) ) ;
273+ for ( const n of [ 'Flags' , 'Extensions' , 'Osquery version' , 'Configuration' ] ) {
274+ expect ( screen . queryByRole ( 'button' , { name : n } ) ) . not . toBeInTheDocument ( ) ;
275+ }
276+ expect ( screen . getByRole ( 'button' , { name : 'Edit override' } ) ) . toBeInTheDocument ( ) ;
277+ expect ( api . getNodeFlags ) . not . toHaveBeenCalled ( ) ;
278+ expect ( api . getNodeExtensions ) . not . toHaveBeenCalled ( ) ;
279+ } ) ;
280+
281+ it ( 'shows no kind switcher while features load' , async ( ) => {
282+ mockFeatures . mockReturnValue ( new Promise ( ( ) => { } ) ) ;
283+ renderTab ( ) ;
284+ expect ( await screen . findByLabelText ( 'Applied configuration' ) ) . toBeInTheDocument ( ) ;
285+ expect ( screen . queryByRole ( 'group' , { name : 'Override type' } ) ) . not . toBeInTheDocument ( ) ;
286+ expect ( api . getNodeFlags ) . not . toHaveBeenCalled ( ) ;
287+ } ) ;
262288} ) ;
0 commit comments