@ -19,9 +19,7 @@ const mockDashboardDto: DashboardWithAccessInfo<DashboardV2Spec> = {
name : 'dash-uid' ,
resourceVersion : '1' ,
creationTimestamp : '1' ,
annotations : {
[ AnnoKeyFolder ] : 'new-folder' ,
} ,
annotations : { } ,
} ,
spec : {
. . . defaultDashboardV2Spec ( ) ,
@ -29,7 +27,9 @@ const mockDashboardDto: DashboardWithAccessInfo<DashboardV2Spec> = {
access : { } ,
} ;
// Create a mock put function that we can spy on
// Create mock get and put functions that we can spy on
const mockGet = jest . fn ( ) . mockResolvedValue ( mockDashboardDto ) ;
const mockPut = jest . fn ( ) . mockImplementation ( ( url , data ) = > {
return {
apiVersion : 'dashboard.grafana.app/v2alpha1' ,
@ -48,7 +48,7 @@ const mockPut = jest.fn().mockImplementation((url, data) => {
jest . mock ( '@grafana/runtime' , ( ) = > ( {
. . . jest . requireActual ( '@grafana/runtime' ) ,
getBackendSrv : ( ) = > ( {
get : ( ) = > mockDashboardDto ,
get : mockGet ,
put : mockPut ,
} ) ,
config : {
@ -66,6 +66,14 @@ describe('v2 dashboard API', () => {
} ) ;
it ( 'should provide folder annotations' , async ( ) = > {
mockGet . mockResolvedValueOnce ( {
. . . mockDashboardDto ,
metadata : {
. . . mockDashboardDto . metadata ,
annotations : { [ AnnoKeyFolder ] : 'new-folder' } ,
} ,
} ) ;
jest . spyOn ( backendSrv , 'getFolderByUid' ) . mockResolvedValue ( {
id : 1 ,
uid : 'new-folder' ,
@ -94,104 +102,168 @@ describe('v2 dashboard API', () => {
} ) ;
it ( 'throws an error if folder is not found' , async ( ) = > {
jest . spyOn ( backendSrv , 'getFolderByUid' ) . mockRejectedValue ( { message : 'folder not found' , status : 'not-found' } ) ;
mockGet . mockResolvedValueOnce ( {
. . . mockDashboardDto ,
metadata : {
. . . mockDashboardDto . metadata ,
annotations : { [ AnnoKeyFolder ] : 'new-folder' } ,
} ,
} ) ;
jest
. spyOn ( backendSrv , 'getFolderByUid' )
. mockRejectedValueOnce ( { message : 'folder not found' , status : 'not-found' } ) ;
const api = new K8sDashboardV2API ( ) ;
await expect ( api . getDashboardDTO ( 'test' ) ) . rejects . toThrow ( 'Failed to load folder' ) ;
} ) ;
} ) ;
describe ( 'v2 dashboard API - Save' , ( ) = > {
beforeEach ( ( ) = > {
jest . clearAllMocks ( ) ;
} ) ;
describe ( 'v2 dashboard API - Save' , ( ) = > {
beforeEach ( ( ) = > {
jest . clearAllMocks ( ) ;
} ) ;
const defaultSaveCommand = {
dashboard : defaultDashboardV2Spec ( ) ,
message : 'test save' ,
folderUid : 'test-folder' ,
k8s : {
name : 'test-dash' ,
labels : {
[ DeprecatedInternalId ] : '123' ,
} ,
const defaultSaveCommand = {
dashboard : defaultDashboardV2Spec ( ) ,
message : 'test save' ,
folderUid : 'test-folder' ,
k8s : {
name : 'test-dash' ,
labels : {
[ DeprecatedInternalId ] : '123' ,
} ,
annotations : {
[ AnnoKeyFolder ] : 'new-folder' ,
annotations : {
[ AnnoKeyFolder ] : 'new-folder' ,
} ,
} ,
} ,
} ;
} ;
it ( 'should create new dashboard' , async ( ) = > {
const api = new K8sDashboardV2API ( ) ;
const result = await api . saveDashboard ( {
. . . defaultSaveCommand ,
dashboard : {
. . . defaultSaveCommand . dashboard ,
title : 'test-dashboard' ,
} ,
} ) ;
it ( 'should create new dashboard' , async ( ) = > {
const api = new K8sDashboardV2API ( ) ;
const result = await api . saveDashboard ( {
. . . defaultSaveCommand ,
dashboard : {
. . . defaultSaveCommand . dashboard ,
title : 'test-dashboard' ,
} ,
} ) ;
expect ( result ) . toEqual ( {
id : 123 ,
uid : 'test-dash' ,
url : '/d/test-dash/testdashboard' ,
slug : '' ,
status : 'success' ,
version : 2 ,
expect ( result ) . toEqual ( {
id : 123 ,
uid : 'test-dash' ,
url : '/d/test-dash/testdashboard' ,
slug : '' ,
status : 'success' ,
version : 2 ,
} ) ;
} ) ;
} ) ;
it ( 'should update existing dashboard' , async ( ) = > {
const api = new K8sDashboardV2API ( ) ;
it ( 'should update existing dashboard' , async ( ) = > {
const api = new K8sDashboardV2API ( ) ;
const result = await api . saveDashboard ( {
. . . defaultSaveCommand ,
dashboard : {
. . . defaultSaveCommand . dashboard ,
title : 'chaing-title-dashboard' ,
} ,
k8s : {
. . . defaultSaveCommand . k8s ,
name : 'existing-dash' ,
} ,
const result = await api . saveDashboard ( {
. . . defaultSaveCommand ,
dashboard : {
. . . defaultSaveCommand . dashboard ,
title : 'chaing-title-dashboard' ,
} ,
k8s : {
. . . defaultSaveCommand . k8s ,
name : 'existing-dash' ,
} ,
} ) ;
expect ( result . version ) . toBe ( 2 ) ;
} ) ;
expect ( result . version ) . toBe ( 2 ) ;
} ) ;
it ( 'should update existing dashboard that is store in a folder' , async ( ) = > {
const api = new K8sDashboardV2API ( ) ;
await api . saveDashboard ( {
dashboard : {
. . . defaultSaveCommand . dashboard ,
title : 'chaing-title-dashboard' ,
} ,
folderUid : 'folderUidXyz' ,
k8s : {
name : 'existing-dash' ,
annotations : {
[ AnnoKeyFolder ] : 'folderUidXyz' ,
[ AnnoKeyFolderUrl ] : 'url folder used in the client' ,
[ AnnoKeyFolderId ] : 42 ,
[ AnnoKeyFolderTitle ] : 'title folder used in the client' ,
it ( 'should update existing dashboard that is store in a folder' , async ( ) = > {
const api = new K8sDashboardV2API ( ) ;
await api . saveDashboard ( {
dashboard : {
. . . defaultSaveCommand . dashboard ,
title : 'chaing-title-dashboard' ,
} ,
} ,
} ) ;
expect ( mockPut ) . toHaveBeenCalledTimes ( 1 ) ;
expect ( mockPut ) . toHaveBeenCalledWith (
'/apis/dashboard.grafana.app/v2alpha1/namespaces/default/dashboards/existing-dash' ,
{
metadata : {
folderUid : 'folderUidXyz' ,
k8s : {
name : 'existing-dash' ,
annotations : {
[ AnnoKeyFolder ] : 'folderUidXyz' ,
[ AnnoKeyFolderUrl ] : 'url folder used in the client' ,
[ AnnoKeyFolderId ] : 42 ,
[ AnnoKeyFolderTitle ] : 'title folder used in the client' ,
} ,
} ,
spec : {
. . . defaultSaveCommand . dashboard ,
title : 'chaing-title-dashboard' ,
} ) ;
expect ( mockPut ) . toHaveBeenCalledTimes ( 1 ) ;
expect ( mockPut ) . toHaveBeenCalledWith (
'/apis/dashboard.grafana.app/v2alpha1/namespaces/default/dashboards/existing-dash' ,
{
metadata : {
name : 'existing-dash' ,
annotations : {
[ AnnoKeyFolder ] : 'folderUidXyz' ,
} ,
} ,
spec : {
. . . defaultSaveCommand . dashboard ,
title : 'chaing-title-dashboard' ,
} ,
}
) ;
} ) ;
} ) ;
describe ( 'version error handling' , ( ) = > {
it ( 'should throw DashboardVersionError for v0alpha1 conversion error' , async ( ) = > {
const mockDashboardWithError = {
. . . mockDashboardDto ,
status : {
conversion : {
failed : true ,
error : 'backend conversion not yet implemented' ,
storedVersion : 'v0alpha1' ,
} ,
} ,
} ;
mockGet . mockResolvedValueOnce ( mockDashboardWithError ) ;
const api = new K8sDashboardV2API ( ) ;
await expect ( api . getDashboardDTO ( 'test' ) ) . rejects . toThrow ( 'backend conversion not yet implemented' ) ;
} ) ;
it ( 'should throw DashboardVersionError for v1alpha1 conversion error' , async ( ) = > {
const mockDashboardWithError = {
. . . mockDashboardDto ,
status : {
conversion : {
failed : true ,
error : 'backend conversion not yet implemented' ,
storedVersion : 'v1alpha1' ,
} ,
} ,
} ;
mockGet . mockResolvedValueOnce ( mockDashboardWithError ) ;
const api = new K8sDashboardV2API ( ) ;
await expect ( api . getDashboardDTO ( 'test' ) ) . rejects . toThrow ( 'backend conversion not yet implemented' ) ;
} ) ;
it ( 'should not throw for other conversion errors' , async ( ) = > {
const mockDashboardWithError = {
. . . mockDashboardDto ,
status : {
conversion : {
failed : true ,
error : 'other-error' ,
storedVersion : 'v2alpha1' ,
} ,
} ,
}
) ;
} ;
mockGet . mockResolvedValueOnce ( mockDashboardWithError ) ;
const api = new K8sDashboardV2API ( ) ;
await expect ( api . getDashboardDTO ( 'test' ) ) . resolves . toBeDefined ( ) ;
} ) ;
} ) ;
} ) ;