@ -3,6 +3,8 @@ import userEvent from '@testing-library/user-event';
import React from 'react' ;
import { select } from 'react-select-event' ;
import { config } from '@grafana/runtime' ;
import { setupMockedDataSource } from '../../__mocks__/CloudWatchDataSource' ;
import { GetDimensionKeysRequest } from '../../resources/types' ;
import { VariableQueryType } from '../../types' ;
@ -23,6 +25,12 @@ const defaultQuery = {
const ds = setupMockedDataSource ( ) ;
const originalFormFeatureToggleValue = config . featureToggles . awsDatasourcesNewFormStyling ;
const cleanupFeatureToggle = ( ) = > {
config . featureToggles . awsDatasourcesNewFormStyling = originalFormFeatureToggleValue ;
} ;
ds . datasource . resources . getRegions = jest . fn ( ) . mockResolvedValue ( [
{ label : 'a1' , value : 'a1' } ,
{ label : 'b1' , value : 'b1' } ,
@ -75,195 +83,216 @@ describe('VariableEditor', () => {
beforeEach ( ( ) = > {
onChange . mockClear ( ) ;
} ) ;
describe ( 'and a new variable is created' , ( ) = > {
it ( 'should trigger a query using the first query type in the array' , async ( ) = > {
const props = defaultProps ;
props . query = defaultQuery ;
render ( < VariableQueryEditor { ...props } / > ) ;
function run() {
describe ( 'and a new variable is created' , ( ) = > {
it ( 'should trigger a query using the first query type in the array' , async ( ) = > {
const props = defaultProps ;
props . query = defaultQuery ;
render ( < VariableQueryEditor { ...props } / > ) ;
await waitFor ( ( ) = > {
const querySelect = screen . queryByRole ( 'combobox' , { name : 'Query type' } ) ;
expect ( querySelect ) . toBeInTheDocument ( ) ;
expect ( screen . queryByText ( 'Regions' ) ) . toBeInTheDocument ( ) ;
// Should not render any fields besides Query Type
const regionSelect = screen . queryByRole ( 'combobox' , { name : 'Region' } ) ;
expect ( regionSelect ) . not . toBeInTheDocument ( ) ;
await waitFor ( ( ) = > {
const querySelect = screen . queryByRole ( 'combobox' , { name : 'Query type' } ) ;
expect ( querySelect ) . toBeInTheDocument ( ) ;
expect ( screen . queryByText ( 'Regions' ) ) . toBeInTheDocument ( ) ;
// Should not render any fields besides Query Type
const regionSelect = screen . queryByRole ( 'combobox' , { name : 'Region' } ) ;
expect ( regionSelect ) . not . toBeInTheDocument ( ) ;
} ) ;
} ) ;
} ) ;
} ) ;
describe ( 'and an existing variable is edited' , ( ) = > {
it ( 'should trigger new query using the saved query type' , async ( ) = > {
const props = defaultProps ;
props . query = {
. . . defaultQuery ,
queryType : VariableQueryType.Metrics ,
namespace : 'z2' ,
region : 'a1' ,
} ;
render ( < VariableQueryEditor { ...props } / > ) ;
await waitFor ( ( ) = > {
const querySelect = screen . queryByRole ( 'combobox' , { name : 'Query type' } ) ;
expect ( querySelect ) . toBeInTheDocument ( ) ;
expect ( screen . queryByText ( 'Metrics' ) ) . toBeInTheDocument ( ) ;
const regionSelect = screen . queryByRole ( 'combobox' , { name : 'Region' } ) ;
expect ( regionSelect ) . toBeInTheDocument ( ) ;
expect ( screen . queryByText ( 'a1' ) ) . toBeInTheDocument ( ) ;
const namespaceSelect = screen . queryByRole ( 'combobox' , { name : 'Namespace' } ) ;
expect ( namespaceSelect ) . toBeInTheDocument ( ) ;
expect ( screen . queryByText ( 'z2' ) ) . toBeInTheDocument ( ) ;
// Should only render Query Type, Region, and Namespace selectors
const metricSelect = screen . queryByRole ( 'combobox' , { name : 'Metric' } ) ;
expect ( metricSelect ) . not . toBeInTheDocument ( ) ;
} ) ;
} ) ;
it ( 'should parse dimensionFilters correctly' , async ( ) = > {
const props = defaultProps ;
props . query = {
. . . defaultQuery ,
queryType : VariableQueryType.DimensionValues ,
namespace : 'z2' ,
region : 'a1' ,
metricName : 'i3' ,
dimensionKey : 's4' ,
dimensionFilters : { s4 : 'foo' } ,
} ;
await act ( async ( ) = > {
describe ( 'and an existing variable is edited' , ( ) = > {
it ( 'should trigger new query using the saved query type' , async ( ) = > {
const props = defaultProps ;
props . query = {
. . . defaultQuery ,
queryType : VariableQueryType.Metrics ,
namespace : 'z2' ,
region : 'a1' ,
} ;
render ( < VariableQueryEditor { ...props } / > ) ;
} ) ;
const filterItem = screen . getByTestId ( 'cloudwatch-dimensions-filter-item' ) ;
expect ( filterItem ) . toBeInTheDocument ( ) ;
expect ( within ( filterItem ) . getByText ( 's4' ) ) . toBeInTheDocument ( ) ;
expect ( within ( filterItem ) . getByText ( 'foo' ) ) . toBeInTheDocument ( ) ;
// change filter key
const keySelect = screen . getByRole ( 'combobox' , { name : 'Dimensions filter key' } ) ;
// confirms getDimensionKeys was called with filter and that the element uses keysForDimensionFilter
await select ( keySelect , 'v4' , {
container : document.body ,
} ) ;
expect ( ds . datasource . resources . getDimensionKeys ) . toHaveBeenCalledWith ( {
namespace : 'z2' ,
region : 'a1' ,
metricName : 'i3' ,
dimensionFilters : undefined ,
} ) ;
expect ( onChange ) . toHaveBeenCalledWith ( {
. . . defaultQuery ,
queryType : VariableQueryType.DimensionValues ,
namespace : 'z2' ,
region : 'a1' ,
metricName : 'i3' ,
dimensionKey : 's4' ,
dimensionFilters : { v4 : undefined } ,
await waitFor ( ( ) = > {
const querySelect = screen . queryByRole ( 'combobox' , { name : 'Query type' } ) ;
expect ( querySelect ) . toBeInTheDocument ( ) ;
expect ( screen . queryByText ( 'Metrics' ) ) . toBeInTheDocument ( ) ;
const regionSelect = screen . queryByRole ( 'combobox' , { name : 'Region' } ) ;
expect ( regionSelect ) . toBeInTheDocument ( ) ;
expect ( screen . queryByText ( 'a1' ) ) . toBeInTheDocument ( ) ;
const namespaceSelect = screen . queryByRole ( 'combobox' , { name : 'Namespace' } ) ;
expect ( namespaceSelect ) . toBeInTheDocument ( ) ;
expect ( screen . queryByText ( 'z2' ) ) . toBeInTheDocument ( ) ;
// Should only render Query Type, Region, and Namespace selectors
const metricSelect = screen . queryByRole ( 'combobox' , { name : 'Metric' } ) ;
expect ( metricSelect ) . not . toBeInTheDocument ( ) ;
} ) ;
} ) ;
it ( 'should parse dimensionFilters correctly' , async ( ) = > {
const props = defaultProps ;
props . query = {
. . . defaultQuery ,
queryType : VariableQueryType.DimensionValues ,
namespace : 'z2' ,
region : 'a1' ,
metricName : 'i3' ,
dimensionKey : 's4' ,
dimensionFilters : { s4 : 'foo' } ,
} ;
await act ( async ( ) = > {
render ( < VariableQueryEditor { ...props } / > ) ;
} ) ;
const filterItem = screen . getByTestId ( 'cloudwatch-dimensions-filter-item' ) ;
expect ( filterItem ) . toBeInTheDocument ( ) ;
expect ( within ( filterItem ) . getByText ( 's4' ) ) . toBeInTheDocument ( ) ;
expect ( within ( filterItem ) . getByText ( 'foo' ) ) . toBeInTheDocument ( ) ;
// set filter value
const valueSelect = screen . getByRole ( 'combobox' , { name : 'Dimensions filter value' } ) ;
await select ( valueSelect , 'bar' , {
container : document.body ,
} ) ;
expect ( onChange ) . toHaveBeenCalledWith ( {
. . . defaultQuery ,
queryType : VariableQueryType.DimensionValues ,
namespace : 'z2' ,
region : 'a1' ,
metricName : 'i3' ,
dimensionKey : 's4' ,
dimensionFilters : { v4 : 'bar' } ,
} ) ;
} ) ;
it ( 'should parse multiFilters correctly' , async ( ) = > {
const props = defaultProps ;
props . query = {
. . . defaultQuery ,
queryType : VariableQueryType.EC2InstanceAttributes ,
region : 'a1' ,
attributeName : 'Tags.blah' ,
ec2Filters : { s4 : [ 'foo' , 'bar' ] } ,
} ;
render ( < VariableQueryEditor { ...props } / > ) ;
// change filter key
const keySelect = screen . getByRole ( 'combobox' , { name : 'Dimensions filter key' } ) ;
// confirms getDimensionKeys was called with filter and that the element uses keysForDimensionFilter
await select ( keySelect , 'v4' , {
container : document.body ,
} ) ;
expect ( ds . datasource . resources . getDimensionKeys ) . toHaveBeenCalledWith ( {
namespace : 'z2' ,
region : 'a1' ,
metricName : 'i3' ,
dimensionFilters : undefined ,
} ) ;
expect ( onChange ) . toHaveBeenCalledWith ( {
. . . defaultQuery ,
queryType : VariableQueryType.DimensionValues ,
namespace : 'z2' ,
region : 'a1' ,
metricName : 'i3' ,
dimensionKey : 's4' ,
dimensionFilters : { v4 : undefined } ,
} ) ;
await waitFor ( ( ) = > {
expect ( screen . getByDisplayValue ( 'Tags.blah' ) ) . toBeInTheDocument ( ) ;
// set filter value
const valueSelect = screen . getByRole ( 'combobox' , { name : 'Dimensions filter value' } ) ;
await select ( valueSelect , 'bar' , {
container : document.body ,
} ) ;
expect ( onChange ) . toHaveBeenCalledWith ( {
. . . defaultQuery ,
queryType : VariableQueryType.DimensionValues ,
namespace : 'z2' ,
region : 'a1' ,
metricName : 'i3' ,
dimensionKey : 's4' ,
dimensionFilters : { v4 : 'bar' } ,
} ) ;
} ) ;
it ( 'should parse multiFilters correctly' , async ( ) = > {
const props = defaultProps ;
props . query = {
. . . defaultQuery ,
queryType : VariableQueryType.EC2InstanceAttributes ,
region : 'a1' ,
attributeName : 'Tags.blah' ,
ec2Filters : { s4 : [ 'foo' , 'bar' ] } ,
} ;
render ( < VariableQueryEditor { ...props } / > ) ;
await waitFor ( ( ) = > {
expect ( screen . getByDisplayValue ( 'Tags.blah' ) ) . toBeInTheDocument ( ) ;
} ) ;
const filterItem = screen . getByTestId ( 'cloudwatch-multifilter-item' ) ;
expect ( filterItem ) . toBeInTheDocument ( ) ;
expect ( within ( filterItem ) . getByDisplayValue ( 'foo, bar' ) ) . toBeInTheDocument ( ) ;
const filterItem = screen . getByTestId ( 'cloudwatch-multifilter-item' ) ;
expect ( filterItem ) . toBeInTheDocument ( ) ;
expect ( within ( filterItem ) . getByDisplayValue ( 'foo, bar' ) ) . toBeInTheDocument ( ) ;
// set filter value
const valueElement = screen . getByTestId ( 'cloudwatch-multifilter-item-value' ) ;
expect ( valueElement ) . toBeInTheDocument ( ) ;
await userEvent . type ( valueElement ! , ',baz' ) ;
fireEvent . blur ( valueElement ! ) ;
// set filter value
const valueElement = screen . getByTestId ( 'cloudwatch-multifilter-item-value' ) ;
expect ( valueElement ) . toBeInTheDocument ( ) ;
await userEvent . type ( valueElement ! , ',baz' ) ;
fireEvent . blur ( valueElement ! ) ;
expect ( screen . getByDisplayValue ( 'foo, bar, baz' ) ) . toBeInTheDocument ( ) ;
expect ( onChange ) . toHaveBeenCalledWith ( {
. . . defaultQuery ,
queryType : VariableQueryType.EC2InstanceAttributes ,
region : 'a1' ,
attributeName : 'Tags.blah' ,
ec2Filters : { s4 : [ 'foo' , 'bar' , 'baz' ] } ,
expect ( screen . getByDisplayValue ( 'foo, bar, baz' ) ) . toBeInTheDocument ( ) ;
expect ( onChange ) . toHaveBeenCalledWith ( {
. . . defaultQuery ,
queryType : VariableQueryType.EC2InstanceAttributes ,
region : 'a1' ,
attributeName : 'Tags.blah' ,
ec2Filters : { s4 : [ 'foo' , 'bar' , 'baz' ] } ,
} ) ;
} ) ;
} ) ;
} ) ;
describe ( 'and a different region is selected' , ( ) = > {
it ( 'should clear invalid fields' , async ( ) = > {
const props = defaultProps ;
props . query = {
. . . defaultQuery ,
queryType : VariableQueryType.DimensionValues ,
namespace : 'z2' ,
region : 'a1' ,
metricName : 'i3' ,
dimensionKey : 's4' ,
dimensionFilters : { s4 : 'foo' } ,
} ;
render ( < VariableQueryEditor { ...props } / > ) ;
describe ( 'and a different region is selected' , ( ) = > {
it ( 'should clear invalid fields' , async ( ) = > {
const props = defaultProps ;
props . query = {
. . . defaultQuery ,
queryType : VariableQueryType.DimensionValues ,
namespace : 'z2' ,
region : 'a1' ,
metricName : 'i3' ,
dimensionKey : 's4' ,
dimensionFilters : { s4 : 'foo' } ,
} ;
render ( < VariableQueryEditor { ...props } / > ) ;
const querySelect = screen . queryByLabelText ( 'Query type' ) ;
expect ( querySelect ) . toBeInTheDocument ( ) ;
expect ( screen . queryByText ( 'Dimension Values' ) ) . toBeInTheDocument ( ) ;
const regionSelect = screen . getByRole ( 'combobox' , { name : 'Region' } ) ;
await waitFor ( ( ) = >
select ( regionSelect , 'b1' , {
container : document.body ,
} )
) ;
const querySelect = screen . queryByLabelText ( 'Query type' ) ;
expect ( querySelect ) . toBeInTheDocument ( ) ;
expect ( screen . queryByText ( 'Dimension Values' ) ) . toBeInTheDocument ( ) ;
const regionSelect = screen . getByRole ( 'combobox' , { name : 'Region' } ) ;
await waitFor ( ( ) = >
select ( regionSelect , 'b1' , {
container : document.body ,
} )
) ;
expect ( ds . datasource . resources . getMetrics ) . toHaveBeenCalledWith ( { namespace : 'z2' , region : 'b1' } ) ;
expect ( ds . datasource . resources . getDimensionKeys ) . toHaveBeenCalledWith ( { namespace : 'z2' , region : 'b1' } ) ;
expect ( props . onChange ) . toHaveBeenCalledWith ( {
. . . defaultQuery ,
refId : 'CloudWatchVariableQueryEditor-VariableQuery' ,
queryType : VariableQueryType.DimensionValues ,
namespace : 'z2' ,
region : 'b1' ,
// metricName i3 exists in the new region and should not be removed
metricName : 'i3' ,
// dimensionKey s4 and valueDimension do not exist in the new region and should be removed
dimensionKey : '' ,
dimensionFilters : { } ,
expect ( ds . datasource . resources . getMetrics ) . toHaveBeenCalledWith ( { namespace : 'z2' , region : 'b1' } ) ;
expect ( ds . datasource . resources . getDimensionKeys ) . toHaveBeenCalledWith ( { namespace : 'z2' , region : 'b1' } ) ;
expect ( props . onChange ) . toHaveBeenCalledWith ( {
. . . defaultQuery ,
refId : 'CloudWatchVariableQueryEditor-VariableQuery' ,
queryType : VariableQueryType.DimensionValues ,
namespace : 'z2' ,
region : 'b1' ,
// metricName i3 exists in the new region and should not be removed
metricName : 'i3' ,
// dimensionKey s4 and valueDimension do not exist in the new region and should be removed
dimensionKey : '' ,
dimensionFilters : { } ,
} ) ;
} ) ;
} ) ;
} ) ;
describe ( 'LogGroups queryType is selected' , ( ) = > {
it ( 'should only render region and prefix' , async ( ) = > {
const props = defaultProps ;
props . query = {
. . . defaultQuery ,
queryType : VariableQueryType.LogGroups ,
} ;
render ( < VariableQueryEditor { ...props } / > ) ;
describe ( 'LogGroups queryType is selected' , ( ) = > {
it ( 'should only render region and prefix' , async ( ) = > {
const props = defaultProps ;
props . query = {
. . . defaultQuery ,
queryType : VariableQueryType.LogGroups ,
} ;
render ( < VariableQueryEditor { ...props } / > ) ;
await waitFor ( ( ) = > {
screen . getByLabelText ( 'Log group prefix' ) ;
screen . getByLabelText ( 'Region' ) ;
await waitFor ( ( ) = > {
screen . getByLabelText ( 'Log group prefix' ) ;
screen . getByLabelText ( 'Region' ) ;
} ) ;
expect ( screen . queryByLabelText ( 'Namespace' ) ) . not . toBeInTheDocument ( ) ;
} ) ;
} ) ;
}
expect ( screen . queryByLabelText ( 'Namespace' ) ) . not . toBeInTheDocument ( ) ;
describe ( 'variable editor with awsDatasourcesNewFormStyling feature toggle enabled' , ( ) = > {
beforeAll ( ( ) = > {
config . featureToggles . awsDatasourcesNewFormStyling = false ;
} ) ;
afterAll ( ( ) = > {
cleanupFeatureToggle ( ) ;
} ) ;
run ( ) ;
describe ( 'variable editor with awsDatasourcesNewFormStyling feature toggle enabled' , ( ) = > {
beforeAll ( ( ) = > {
config . featureToggles . awsDatasourcesNewFormStyling = true ;
} ) ;
afterAll ( ( ) = > {
cleanupFeatureToggle ( ) ;
} ) ;
run ( ) ;
} ) ;
} ) ;
} ) ;