2021-05-11 01:10:19 -04:00
package libraryelements
2021-03-01 09:33:17 -05:00
import (
2026-04-22 14:08:09 -04:00
"encoding/json"
2021-03-01 09:33:17 -05:00
"testing"
"github.com/google/go-cmp/cmp"
2021-10-11 08:30:59 -04:00
"github.com/stretchr/testify/require"
2025-04-24 10:10:03 -04:00
2025-10-09 08:38:52 -04:00
"github.com/grafana/grafana/pkg/services/folder"
"github.com/grafana/grafana/pkg/services/libraryelements/model"
"github.com/grafana/grafana/pkg/util"
2025-09-08 09:49:49 -04:00
"github.com/grafana/grafana/pkg/util/testutil"
2025-04-24 10:10:03 -04:00
"github.com/grafana/grafana/pkg/web"
2021-03-01 09:33:17 -05:00
)
2025-04-24 10:10:03 -04:00
func TestIntegration_PatchLibraryElement ( t * testing . T ) {
2025-09-08 09:49:49 -04:00
testutil . SkipIntegrationTestInShortMode ( t )
2021-05-11 01:10:19 -04:00
scenarioWithPanel ( t , "When an admin tries to patch a library panel that does not exist, it should fail" ,
2021-03-01 09:33:17 -05:00
func ( t * testing . T , sc scenarioContext ) {
2023-02-01 11:32:05 -05:00
cmd := model . PatchLibraryElementCommand { Kind : int64 ( model . PanelElement ) , Version : 1 }
2021-10-11 08:30:59 -04:00
sc . ctx . Req = web . SetURLParams ( sc . ctx . Req , map [ string ] string { ":uid" : "unknown" } )
2021-11-29 04:18:01 -05:00
sc . reqContext . Req . Body = mockRequestBody ( cmd )
resp := sc . service . patchHandler ( sc . reqContext )
2021-03-01 09:33:17 -05:00
require . Equal ( t , 404 , resp . Status ( ) )
} )
2021-05-11 01:10:19 -04:00
scenarioWithPanel ( t , "When an admin tries to patch a library panel that exists, it should succeed" ,
2021-03-01 09:33:17 -05:00
func ( t * testing . T , sc scenarioContext ) {
2025-07-29 17:52:57 -04:00
newFolder := & folder . Folder {
ID : 2 ,
OrgID : 1 ,
UID : "uid_for_NewFolder" ,
Title : "NewFolder" ,
}
sc . folderSvc . ExpectedFolder = newFolder
sc . folderSvc . ExpectedFolders = [ ] * folder . Folder { newFolder }
2023-02-01 11:32:05 -05:00
cmd := model . PatchLibraryElementCommand {
2024-04-09 06:27:43 -04:00
FolderID : newFolder . ID , // nolint:staticcheck
FolderUID : & newFolder . UID ,
Name : "Panel - New name" ,
2021-03-01 09:33:17 -05:00
Model : [ ] byte ( `
{
"datasource" : "${DS_GDEV-TESTDATA}" ,
2021-03-24 08:43:51 -04:00
"description" : "An updated description" ,
2021-03-01 09:33:17 -05:00
"id" : 1 ,
"title" : "Model - New name" ,
2021-03-24 08:43:51 -04:00
"type" : "graph"
2021-03-01 09:33:17 -05:00
}
` ) ,
2023-02-01 11:32:05 -05:00
Kind : int64 ( model . PanelElement ) ,
2021-03-02 07:33:26 -05:00
Version : 1 ,
2021-03-01 09:33:17 -05:00
}
2021-10-11 08:30:59 -04:00
sc . ctx . Req = web . SetURLParams ( sc . ctx . Req , map [ string ] string { ":uid" : sc . initialResult . Result . UID } )
2021-11-29 04:18:01 -05:00
sc . reqContext . Req . Body = mockRequestBody ( cmd )
resp := sc . service . patchHandler ( sc . reqContext )
2021-03-01 09:33:17 -05:00
require . Equal ( t , 200 , resp . Status ( ) )
var result = validateAndUnMarshalResponse ( t , resp )
2021-05-11 01:10:19 -04:00
var expected = libraryElementResult {
Result : libraryElement {
2021-03-24 08:43:51 -04:00
ID : 1 ,
OrgID : 1 ,
2023-11-06 11:31:15 -05:00
FolderID : newFolder . ID , // nolint:staticcheck
2024-04-09 06:27:43 -04:00
FolderUID : newFolder . UID ,
2021-03-24 08:43:51 -04:00
UID : sc . initialResult . Result . UID ,
Name : "Panel - New name" ,
2023-02-01 11:32:05 -05:00
Kind : int64 ( model . PanelElement ) ,
2021-03-24 08:43:51 -04:00
Type : "graph" ,
Description : "An updated description" ,
2023-08-30 11:46:47 -04:00
Model : map [ string ] any {
2021-03-24 08:43:51 -04:00
"datasource" : "${DS_GDEV-TESTDATA}" ,
"description" : "An updated description" ,
"id" : float64 ( 1 ) ,
2021-09-01 07:27:43 -04:00
"title" : "Model - New name" ,
2021-03-24 08:43:51 -04:00
"type" : "graph" ,
2021-03-01 09:33:17 -05:00
} ,
2021-03-02 07:33:26 -05:00
Version : 2 ,
2023-02-01 11:32:05 -05:00
Meta : model . LibraryElementDTOMeta {
2022-05-05 04:04:54 -04:00
FolderName : "NewFolder" ,
2025-01-27 04:51:41 -05:00
FolderUID : "uid_for_NewFolder" ,
2021-05-12 02:48:17 -04:00
ConnectedDashboards : 0 ,
Created : sc . initialResult . Result . Meta . Created ,
Updated : result . Result . Meta . Updated ,
2025-10-09 08:38:52 -04:00
CreatedBy : model . LibraryElementDTOMetaUser {
2023-01-29 23:14:12 -05:00
Id : 1 ,
2021-05-11 01:10:19 -04:00
Name : userInDbName ,
2023-01-29 23:14:12 -05:00
AvatarUrl : userInDbAvatar ,
2021-03-01 09:33:17 -05:00
} ,
2025-10-09 08:38:52 -04:00
UpdatedBy : model . LibraryElementDTOMetaUser {
2023-01-29 23:14:12 -05:00
Id : 1 ,
2021-03-01 09:33:17 -05:00
Name : "signed_in_user" ,
2026-04-13 10:12:51 -04:00
AvatarUrl : "/avatar/00c249f3bdb8ead55b7b551e293907924d644158062bddc4e29a578ec3f89018" ,
2021-03-01 09:33:17 -05:00
} ,
} ,
} ,
}
if diff := cmp . Diff ( expected , result , getCompareOptions ( ) ... ) ; diff != "" {
t . Fatalf ( "Result mismatch (-want +got):\n%s" , diff )
}
} )
2021-05-11 01:10:19 -04:00
scenarioWithPanel ( t , "When an admin tries to patch a library panel with folder only, it should change folder successfully and return correct result" ,
2021-03-01 09:33:17 -05:00
func ( t * testing . T , sc scenarioContext ) {
2025-07-29 17:52:57 -04:00
newFolder := & folder . Folder {
ID : 2 ,
OrgID : 1 ,
UID : "uid_for_NewFolder" ,
Title : "NewFolder" ,
}
sc . folderSvc . ExpectedFolder = newFolder
sc . folderSvc . ExpectedFolders = [ ] * folder . Folder { newFolder }
2023-02-01 11:32:05 -05:00
cmd := model . PatchLibraryElementCommand {
2024-04-09 06:27:43 -04:00
FolderID : newFolder . ID , // nolint:staticcheck
FolderUID : & newFolder . UID ,
Kind : int64 ( model . PanelElement ) ,
Version : 1 ,
2021-03-01 09:33:17 -05:00
}
2021-10-11 08:30:59 -04:00
sc . ctx . Req = web . SetURLParams ( sc . ctx . Req , map [ string ] string { ":uid" : sc . initialResult . Result . UID } )
2021-11-29 04:18:01 -05:00
sc . reqContext . Req . Body = mockRequestBody ( cmd )
resp := sc . service . patchHandler ( sc . reqContext )
2021-03-01 09:33:17 -05:00
require . Equal ( t , 200 , resp . Status ( ) )
var result = validateAndUnMarshalResponse ( t , resp )
2023-11-06 11:31:15 -05:00
// nolint:staticcheck
2022-11-10 04:41:03 -05:00
sc . initialResult . Result . FolderID = newFolder . ID
2024-04-09 06:27:43 -04:00
sc . initialResult . Result . FolderUID = newFolder . UID
2021-05-11 01:10:19 -04:00
sc . initialResult . Result . Meta . CreatedBy . Name = userInDbName
2023-01-29 23:14:12 -05:00
sc . initialResult . Result . Meta . CreatedBy . AvatarUrl = userInDbAvatar
2021-10-22 03:19:25 -04:00
sc . initialResult . Result . Meta . Updated = result . Result . Meta . Updated
2021-03-02 07:33:26 -05:00
sc . initialResult . Result . Version = 2
2022-05-05 04:04:54 -04:00
sc . initialResult . Result . Meta . FolderName = "NewFolder"
2025-01-27 04:51:41 -05:00
sc . initialResult . Result . Meta . FolderUID = "uid_for_NewFolder"
2021-03-01 09:33:17 -05:00
if diff := cmp . Diff ( sc . initialResult . Result , result . Result , getCompareOptions ( ) ... ) ; diff != "" {
t . Fatalf ( "Result mismatch (-want +got):\n%s" , diff )
}
} )
2021-09-01 07:27:43 -04:00
scenarioWithPanel ( t , "When an admin tries to patch a library panel with name only, it should change name successfully and return correct result" ,
2021-03-01 09:33:17 -05:00
func ( t * testing . T , sc scenarioContext ) {
2023-02-01 11:32:05 -05:00
cmd := model . PatchLibraryElementCommand {
2023-11-06 11:31:01 -05:00
FolderID : - 1 , // nolint:staticcheck
2021-03-01 09:33:17 -05:00
Name : "New Name" ,
2023-02-01 11:32:05 -05:00
Kind : int64 ( model . PanelElement ) ,
2021-03-02 07:33:26 -05:00
Version : 1 ,
2021-03-01 09:33:17 -05:00
}
2021-10-11 08:30:59 -04:00
sc . ctx . Req = web . SetURLParams ( sc . ctx . Req , map [ string ] string { ":uid" : sc . initialResult . Result . UID } )
2021-11-29 04:18:01 -05:00
sc . ctx . Req . Body = mockRequestBody ( cmd )
resp := sc . service . patchHandler ( sc . reqContext )
2021-03-01 09:33:17 -05:00
var result = validateAndUnMarshalResponse ( t , resp )
sc . initialResult . Result . Name = "New Name"
2021-05-11 01:10:19 -04:00
sc . initialResult . Result . Meta . CreatedBy . Name = userInDbName
2023-01-29 23:14:12 -05:00
sc . initialResult . Result . Meta . CreatedBy . AvatarUrl = userInDbAvatar
2021-10-22 03:19:25 -04:00
sc . initialResult . Result . Meta . Updated = result . Result . Meta . Updated
2021-09-01 07:27:43 -04:00
sc . initialResult . Result . Model [ "title" ] = "Text - Library Panel"
2021-03-02 07:33:26 -05:00
sc . initialResult . Result . Version = 2
2021-03-01 09:33:17 -05:00
if diff := cmp . Diff ( sc . initialResult . Result , result . Result , getCompareOptions ( ) ... ) ; diff != "" {
t . Fatalf ( "Result mismatch (-want +got):\n%s" , diff )
}
} )
2021-09-10 05:22:13 -04:00
scenarioWithPanel ( t , "When an admin tries to patch a library panel with a nonexistent UID, it should change UID successfully and return correct result" ,
func ( t * testing . T , sc scenarioContext ) {
2023-02-01 11:32:05 -05:00
cmd := model . PatchLibraryElementCommand {
2023-11-06 11:31:01 -05:00
FolderID : - 1 , // nolint:staticcheck
2021-09-10 05:22:13 -04:00
UID : util . GenerateShortUID ( ) ,
2023-02-01 11:32:05 -05:00
Kind : int64 ( model . PanelElement ) ,
2021-09-10 05:22:13 -04:00
Version : 1 ,
}
2021-10-11 08:30:59 -04:00
sc . ctx . Req = web . SetURLParams ( sc . ctx . Req , map [ string ] string { ":uid" : sc . initialResult . Result . UID } )
2021-11-29 04:18:01 -05:00
sc . ctx . Req . Body = mockRequestBody ( cmd )
resp := sc . service . patchHandler ( sc . reqContext )
2021-09-10 05:22:13 -04:00
var result = validateAndUnMarshalResponse ( t , resp )
sc . initialResult . Result . UID = cmd . UID
sc . initialResult . Result . Meta . CreatedBy . Name = userInDbName
2023-01-29 23:14:12 -05:00
sc . initialResult . Result . Meta . CreatedBy . AvatarUrl = userInDbAvatar
2021-10-22 03:19:25 -04:00
sc . initialResult . Result . Meta . Updated = result . Result . Meta . Updated
2021-09-10 05:22:13 -04:00
sc . initialResult . Result . Model [ "title" ] = "Text - Library Panel"
sc . initialResult . Result . Version = 2
if diff := cmp . Diff ( sc . initialResult . Result , result . Result , getCompareOptions ( ) ... ) ; diff != "" {
t . Fatalf ( "Result mismatch (-want +got):\n%s" , diff )
}
} )
scenarioWithPanel ( t , "When an admin tries to patch a library panel with an invalid UID, it should fail" ,
func ( t * testing . T , sc scenarioContext ) {
2023-02-01 11:32:05 -05:00
cmd := model . PatchLibraryElementCommand {
2023-11-06 11:31:01 -05:00
FolderID : - 1 , // nolint:staticcheck
2021-09-10 05:22:13 -04:00
UID : "Testing an invalid UID" ,
2023-02-01 11:32:05 -05:00
Kind : int64 ( model . PanelElement ) ,
2021-09-10 05:22:13 -04:00
Version : 1 ,
}
2021-10-11 08:30:59 -04:00
sc . ctx . Req = web . SetURLParams ( sc . ctx . Req , map [ string ] string { ":uid" : sc . initialResult . Result . UID } )
2021-11-29 04:18:01 -05:00
sc . ctx . Req . Body = mockRequestBody ( cmd )
resp := sc . service . patchHandler ( sc . reqContext )
2021-09-10 05:22:13 -04:00
require . Equal ( t , 400 , resp . Status ( ) )
} )
scenarioWithPanel ( t , "When an admin tries to patch a library panel with an UID that is too long, it should fail" ,
func ( t * testing . T , sc scenarioContext ) {
2023-02-01 11:32:05 -05:00
cmd := model . PatchLibraryElementCommand {
2024-04-09 06:27:43 -04:00
FolderID : - 1 , // nolint:staticcheck
FolderUID : & sc . folder . UID ,
UID : "j6T00KRZzj6T00KRZzj6T00KRZzj6T00KRZzj6T00K" ,
Kind : int64 ( model . PanelElement ) ,
Version : 1 ,
2021-09-10 05:22:13 -04:00
}
2021-10-11 08:30:59 -04:00
sc . ctx . Req = web . SetURLParams ( sc . ctx . Req , map [ string ] string { ":uid" : sc . initialResult . Result . UID } )
2021-11-29 04:18:01 -05:00
sc . ctx . Req . Body = mockRequestBody ( cmd )
resp := sc . service . patchHandler ( sc . reqContext )
2021-09-10 05:22:13 -04:00
require . Equal ( t , 400 , resp . Status ( ) )
} )
scenarioWithPanel ( t , "When an admin tries to patch a library panel with an existing UID, it should fail" ,
func ( t * testing . T , sc scenarioContext ) {
2023-11-20 15:44:51 -05:00
// nolint:staticcheck
2024-04-09 06:27:43 -04:00
command := getCreatePanelCommand ( sc . folder . ID , sc . folder . UID , "Existing UID" )
2021-09-10 05:22:13 -04:00
command . UID = util . GenerateShortUID ( )
2021-11-29 04:18:01 -05:00
sc . reqContext . Req . Body = mockRequestBody ( command )
resp := sc . service . createHandler ( sc . reqContext )
2021-09-10 05:22:13 -04:00
require . Equal ( t , 200 , resp . Status ( ) )
2023-02-01 11:32:05 -05:00
cmd := model . PatchLibraryElementCommand {
2024-04-09 06:27:43 -04:00
FolderID : - 1 , // nolint:staticcheck
FolderUID : & sc . folder . UID ,
UID : command . UID ,
Kind : int64 ( model . PanelElement ) ,
Version : 1 ,
2021-09-10 05:22:13 -04:00
}
2021-10-11 08:30:59 -04:00
sc . ctx . Req = web . SetURLParams ( sc . ctx . Req , map [ string ] string { ":uid" : sc . initialResult . Result . UID } )
2021-11-29 04:18:01 -05:00
sc . ctx . Req . Body = mockRequestBody ( cmd )
resp = sc . service . patchHandler ( sc . reqContext )
2021-09-10 05:22:13 -04:00
require . Equal ( t , 400 , resp . Status ( ) )
} )
2021-09-01 07:27:43 -04:00
scenarioWithPanel ( t , "When an admin tries to patch a library panel with model only, it should change model successfully, sync type and description fields and return correct result" ,
2021-03-01 09:33:17 -05:00
func ( t * testing . T , sc scenarioContext ) {
2023-02-01 11:32:05 -05:00
cmd := model . PatchLibraryElementCommand {
2023-11-06 11:31:01 -05:00
FolderID : - 1 , // nolint:staticcheck
2021-03-24 08:43:51 -04:00
Model : [ ] byte ( ` { "title": "New Model Title", "name": "New Model Name", "type":"graph", "description": "New description" } ` ) ,
2023-02-01 11:32:05 -05:00
Kind : int64 ( model . PanelElement ) ,
2021-03-02 07:33:26 -05:00
Version : 1 ,
2021-03-01 09:33:17 -05:00
}
2021-10-11 08:30:59 -04:00
sc . ctx . Req = web . SetURLParams ( sc . ctx . Req , map [ string ] string { ":uid" : sc . initialResult . Result . UID } )
2021-11-29 04:18:01 -05:00
sc . ctx . Req . Body = mockRequestBody ( cmd )
resp := sc . service . patchHandler ( sc . reqContext )
2021-03-01 09:33:17 -05:00
var result = validateAndUnMarshalResponse ( t , resp )
2021-03-24 08:43:51 -04:00
sc . initialResult . Result . Type = "graph"
sc . initialResult . Result . Description = "New description"
2023-08-30 11:46:47 -04:00
sc . initialResult . Result . Model = map [ string ] any {
2021-09-01 07:27:43 -04:00
"title" : "New Model Title" ,
2021-03-24 08:43:51 -04:00
"name" : "New Model Name" ,
"type" : "graph" ,
"description" : "New description" ,
2021-03-01 09:33:17 -05:00
}
2021-05-11 01:10:19 -04:00
sc . initialResult . Result . Meta . CreatedBy . Name = userInDbName
2023-01-29 23:14:12 -05:00
sc . initialResult . Result . Meta . CreatedBy . AvatarUrl = userInDbAvatar
2021-10-22 03:19:25 -04:00
sc . initialResult . Result . Meta . Updated = result . Result . Meta . Updated
2021-03-24 08:43:51 -04:00
sc . initialResult . Result . Version = 2
if diff := cmp . Diff ( sc . initialResult . Result , result . Result , getCompareOptions ( ) ... ) ; diff != "" {
t . Fatalf ( "Result mismatch (-want +got):\n%s" , diff )
}
} )
2021-09-01 07:27:43 -04:00
scenarioWithPanel ( t , "When an admin tries to patch a library panel with model.description only, it should change model successfully, sync type and description fields and return correct result" ,
2021-03-24 08:43:51 -04:00
func ( t * testing . T , sc scenarioContext ) {
2023-02-01 11:32:05 -05:00
cmd := model . PatchLibraryElementCommand {
2023-11-06 11:31:01 -05:00
FolderID : - 1 , // nolint:staticcheck
2021-03-24 08:43:51 -04:00
Model : [ ] byte ( ` { "description": "New description" } ` ) ,
2023-02-01 11:32:05 -05:00
Kind : int64 ( model . PanelElement ) ,
2021-03-24 08:43:51 -04:00
Version : 1 ,
}
2021-10-11 08:30:59 -04:00
sc . ctx . Req = web . SetURLParams ( sc . ctx . Req , map [ string ] string { ":uid" : sc . initialResult . Result . UID } )
2021-11-29 04:18:01 -05:00
sc . ctx . Req . Body = mockRequestBody ( cmd )
resp := sc . service . patchHandler ( sc . reqContext )
2021-03-24 08:43:51 -04:00
var result = validateAndUnMarshalResponse ( t , resp )
sc . initialResult . Result . Type = "text"
sc . initialResult . Result . Description = "New description"
2023-08-30 11:46:47 -04:00
sc . initialResult . Result . Model = map [ string ] any {
2021-03-24 08:43:51 -04:00
"type" : "text" ,
"description" : "New description" ,
}
2021-05-11 01:10:19 -04:00
sc . initialResult . Result . Meta . CreatedBy . Name = userInDbName
2023-01-29 23:14:12 -05:00
sc . initialResult . Result . Meta . CreatedBy . AvatarUrl = userInDbAvatar
2021-10-22 03:19:25 -04:00
sc . initialResult . Result . Meta . Updated = result . Result . Meta . Updated
2021-03-24 08:43:51 -04:00
sc . initialResult . Result . Version = 2
if diff := cmp . Diff ( sc . initialResult . Result , result . Result , getCompareOptions ( ) ... ) ; diff != "" {
t . Fatalf ( "Result mismatch (-want +got):\n%s" , diff )
}
} )
2021-09-01 07:27:43 -04:00
scenarioWithPanel ( t , "When an admin tries to patch a library panel with model.type only, it should change model successfully, sync type and description fields and return correct result" ,
2021-03-24 08:43:51 -04:00
func ( t * testing . T , sc scenarioContext ) {
2023-02-01 11:32:05 -05:00
cmd := model . PatchLibraryElementCommand {
2023-11-06 11:31:01 -05:00
FolderID : - 1 , // nolint:staticcheck
2021-03-24 08:43:51 -04:00
Model : [ ] byte ( ` { "type": "graph" } ` ) ,
2023-02-01 11:32:05 -05:00
Kind : int64 ( model . PanelElement ) ,
2021-03-24 08:43:51 -04:00
Version : 1 ,
}
2021-10-11 08:30:59 -04:00
sc . ctx . Req = web . SetURLParams ( sc . ctx . Req , map [ string ] string { ":uid" : sc . initialResult . Result . UID } )
2021-11-29 04:18:01 -05:00
sc . ctx . Req . Body = mockRequestBody ( cmd )
resp := sc . service . patchHandler ( sc . reqContext )
2021-03-24 08:43:51 -04:00
var result = validateAndUnMarshalResponse ( t , resp )
sc . initialResult . Result . Type = "graph"
sc . initialResult . Result . Description = "A description"
2023-08-30 11:46:47 -04:00
sc . initialResult . Result . Model = map [ string ] any {
2021-03-24 08:43:51 -04:00
"type" : "graph" ,
"description" : "A description" ,
}
2021-05-11 01:10:19 -04:00
sc . initialResult . Result . Meta . CreatedBy . Name = userInDbName
2023-01-29 23:14:12 -05:00
sc . initialResult . Result . Meta . CreatedBy . AvatarUrl = userInDbAvatar
2021-10-22 03:19:25 -04:00
sc . initialResult . Result . Meta . Updated = result . Result . Meta . Updated
2021-03-02 07:33:26 -05:00
sc . initialResult . Result . Version = 2
2021-03-01 09:33:17 -05:00
if diff := cmp . Diff ( sc . initialResult . Result , result . Result , getCompareOptions ( ) ... ) ; diff != "" {
t . Fatalf ( "Result mismatch (-want +got):\n%s" , diff )
}
} )
2021-10-22 03:19:25 -04:00
scenarioWithPanel ( t , "When another admin tries to patch a library panel, it should change UpdatedBy successfully and return correct result" ,
func ( t * testing . T , sc scenarioContext ) {
2023-11-06 11:31:01 -05:00
// nolint:staticcheck
2023-02-01 11:32:05 -05:00
cmd := model . PatchLibraryElementCommand { FolderID : - 1 , Version : 1 , Kind : int64 ( model . PanelElement ) }
2022-08-11 07:28:55 -04:00
sc . reqContext . UserID = 2
2021-10-22 03:19:25 -04:00
sc . ctx . Req = web . SetURLParams ( sc . ctx . Req , map [ string ] string { ":uid" : sc . initialResult . Result . UID } )
2021-11-29 04:18:01 -05:00
sc . ctx . Req . Body = mockRequestBody ( cmd )
resp := sc . service . patchHandler ( sc . reqContext )
2021-10-22 03:19:25 -04:00
var result = validateAndUnMarshalResponse ( t , resp )
2023-01-29 23:14:12 -05:00
sc . initialResult . Result . Meta . UpdatedBy . Id = int64 ( 2 )
2021-10-22 03:19:25 -04:00
sc . initialResult . Result . Meta . CreatedBy . Name = userInDbName
2023-01-29 23:14:12 -05:00
sc . initialResult . Result . Meta . CreatedBy . AvatarUrl = userInDbAvatar
2021-10-22 03:19:25 -04:00
sc . initialResult . Result . Meta . Updated = result . Result . Meta . Updated
sc . initialResult . Result . Version = 2
if diff := cmp . Diff ( sc . initialResult . Result , result . Result , getCompareOptions ( ) ... ) ; diff != "" {
t . Fatalf ( "Result mismatch (-want +got):\n%s" , diff )
}
} )
2021-03-01 09:33:17 -05:00
2025-10-28 09:30:39 -04:00
scenarioWithPanel ( t , "When an admin tries to patch a library panel with a name that already exists, it should pass" ,
2021-03-01 09:33:17 -05:00
func ( t * testing . T , sc scenarioContext ) {
2023-11-20 15:44:51 -05:00
// nolint:staticcheck
2024-04-09 06:27:43 -04:00
command := getCreatePanelCommand ( sc . folder . ID , sc . folder . UID , "Another Panel" )
2021-11-29 04:18:01 -05:00
sc . ctx . Req . Body = mockRequestBody ( command )
resp := sc . service . createHandler ( sc . reqContext )
2021-03-01 09:33:17 -05:00
var result = validateAndUnMarshalResponse ( t , resp )
2023-02-01 11:32:05 -05:00
cmd := model . PatchLibraryElementCommand {
2025-05-15 10:55:19 -04:00
Name : "Text - Library Panel" ,
Version : 1 ,
Kind : int64 ( model . PanelElement ) ,
FolderUID : & sc . folder . UID ,
2021-03-01 09:33:17 -05:00
}
2021-10-11 08:30:59 -04:00
sc . ctx . Req = web . SetURLParams ( sc . ctx . Req , map [ string ] string { ":uid" : result . Result . UID } )
2021-11-29 04:18:01 -05:00
sc . ctx . Req . Body = mockRequestBody ( cmd )
resp = sc . service . patchHandler ( sc . reqContext )
2025-10-28 09:30:39 -04:00
require . Equal ( t , 200 , resp . Status ( ) )
2021-03-01 09:33:17 -05:00
} )
2025-10-28 09:30:39 -04:00
scenarioWithPanel ( t , "When an admin tries to patch a library panel with a folder where a library panel with the same name already exists, it should pass" ,
2021-03-01 09:33:17 -05:00
func ( t * testing . T , sc scenarioContext ) {
2025-07-29 17:52:57 -04:00
newFolder := & folder . Folder {
ID : 2 ,
OrgID : 1 ,
UID : "uid_for_NewFolder" ,
Title : "NewFolder" ,
}
sc . folderSvc . ExpectedFolder = newFolder
sc . folderSvc . ExpectedFolders = [ ] * folder . Folder { newFolder }
2023-11-20 15:44:51 -05:00
// nolint:staticcheck
2024-04-09 06:27:43 -04:00
command := getCreatePanelCommand ( newFolder . ID , newFolder . UID , "Text - Library Panel" )
2021-11-29 04:18:01 -05:00
sc . ctx . Req . Body = mockRequestBody ( command )
2025-07-29 17:52:57 -04:00
sc . service . createHandler ( sc . reqContext )
2023-02-01 11:32:05 -05:00
cmd := model . PatchLibraryElementCommand {
2025-07-29 17:52:57 -04:00
FolderID : newFolder . ID , // nolint:staticcheck
FolderUID : & newFolder . UID ,
2024-04-09 06:27:43 -04:00
Version : 1 ,
Kind : int64 ( model . PanelElement ) ,
2021-03-01 09:33:17 -05:00
}
2025-07-29 17:52:57 -04:00
sc . ctx . Req = web . SetURLParams ( sc . ctx . Req , map [ string ] string { ":uid" : sc . initialResult . Result . UID } )
2021-11-29 04:18:01 -05:00
sc . ctx . Req . Body = mockRequestBody ( cmd )
2025-07-29 17:52:57 -04:00
resp := sc . service . patchHandler ( sc . reqContext )
2025-10-28 09:30:39 -04:00
require . Equal ( t , 200 , resp . Status ( ) )
2021-03-01 09:33:17 -05:00
} )
2021-05-11 01:10:19 -04:00
scenarioWithPanel ( t , "When an admin tries to patch a library panel in another org, it should fail" ,
2021-03-01 09:33:17 -05:00
func ( t * testing . T , sc scenarioContext ) {
2025-07-29 17:52:57 -04:00
sc . folderSvc . ExpectedFolder = nil
sc . folderSvc . ExpectedError = folder . ErrFolderNotFound
2023-02-01 11:32:05 -05:00
cmd := model . PatchLibraryElementCommand {
2024-04-09 06:27:43 -04:00
FolderID : sc . folder . ID , // nolint:staticcheck
FolderUID : & sc . folder . UID ,
Version : 1 ,
Kind : int64 ( model . PanelElement ) ,
2021-03-01 09:33:17 -05:00
}
2022-08-11 07:28:55 -04:00
sc . reqContext . OrgID = 2
2021-10-11 08:30:59 -04:00
sc . ctx . Req = web . SetURLParams ( sc . ctx . Req , map [ string ] string { ":uid" : sc . initialResult . Result . UID } )
2021-11-29 04:18:01 -05:00
sc . ctx . Req . Body = mockRequestBody ( cmd )
resp := sc . service . patchHandler ( sc . reqContext )
2024-04-09 06:27:43 -04:00
require . Equal ( t , 400 , resp . Status ( ) )
2021-03-01 09:33:17 -05:00
} )
2021-03-02 07:33:26 -05:00
2021-05-11 01:10:19 -04:00
scenarioWithPanel ( t , "When an admin tries to patch a library panel with an old version number, it should fail" ,
2021-03-02 07:33:26 -05:00
func ( t * testing . T , sc scenarioContext ) {
2023-02-01 11:32:05 -05:00
cmd := model . PatchLibraryElementCommand {
2024-04-09 06:27:43 -04:00
FolderID : sc . folder . ID , // nolint:staticcheck
FolderUID : & sc . folder . UID ,
Version : 1 ,
Kind : int64 ( model . PanelElement ) ,
2021-03-02 07:33:26 -05:00
}
2021-10-11 08:30:59 -04:00
sc . ctx . Req = web . SetURLParams ( sc . ctx . Req , map [ string ] string { ":uid" : sc . initialResult . Result . UID } )
2021-11-29 04:18:01 -05:00
sc . ctx . Req . Body = mockRequestBody ( cmd )
resp := sc . service . patchHandler ( sc . reqContext )
2021-03-02 07:33:26 -05:00
require . Equal ( t , 200 , resp . Status ( ) )
2021-11-29 04:18:01 -05:00
sc . ctx . Req . Body = mockRequestBody ( cmd )
resp = sc . service . patchHandler ( sc . reqContext )
2021-03-02 07:33:26 -05:00
require . Equal ( t , 412 , resp . Status ( ) )
} )
2026-04-22 14:08:09 -04:00
// Regression: getAllLibraryElements reads library_element.folder_uid directly from
// the table, so PATCH must keep that column in sync with folder_id or the list view
// diverges from GET-by-UID (which derives the UID from folder_id).
scenarioWithPanel ( t , "When an admin moves a library panel to another folder, the list endpoint reflects the new folder" ,
func ( t * testing . T , sc scenarioContext ) {
destFolder := & folder . Folder {
ID : 2 ,
OrgID : 1 ,
UID : "uid_for_DestFolder" ,
Title : "DestFolder" ,
}
sc . folderSvc . ExpectedFolder = destFolder
sc . folderSvc . ExpectedFolders = [ ] * folder . Folder { sc . folder , destFolder }
moveCmd := model . PatchLibraryElementCommand {
FolderID : destFolder . ID , // nolint:staticcheck
FolderUID : & destFolder . UID ,
Kind : int64 ( model . PanelElement ) ,
Version : 1 ,
}
sc . ctx . Req = web . SetURLParams ( sc . ctx . Req , map [ string ] string { ":uid" : sc . initialResult . Result . UID } )
sc . reqContext . Req . Body = mockRequestBody ( moveCmd )
require . Equal ( t , 200 , sc . service . patchHandler ( sc . reqContext ) . Status ( ) )
require . NoError ( t , sc . reqContext . Req . ParseForm ( ) )
sc . reqContext . Req . Form . Set ( "folderFilterUIDs" , destFolder . UID )
resp := sc . service . getAllHandler ( sc . reqContext )
require . Equal ( t , 200 , resp . Status ( ) )
var atDest libraryElementsSearch
require . NoError ( t , json . Unmarshal ( resp . Body ( ) , & atDest ) )
require . Len ( t , atDest . Result . Elements , 1 , "moved panel should appear when filtering by destination folder" )
require . Equal ( t , sc . initialResult . Result . UID , atDest . Result . Elements [ 0 ] . UID )
require . Equal ( t , destFolder . UID , atDest . Result . Elements [ 0 ] . FolderUID )
require . Equal ( t , destFolder . UID , atDest . Result . Elements [ 0 ] . Meta . FolderUID )
sc . reqContext . Req . Form . Set ( "folderFilterUIDs" , sc . folder . UID )
resp = sc . service . getAllHandler ( sc . reqContext )
require . Equal ( t , 200 , resp . Status ( ) )
var atOrig libraryElementsSearch
require . NoError ( t , json . Unmarshal ( resp . Body ( ) , & atOrig ) )
require . Empty ( t , atOrig . Result . Elements , "moved panel should not appear in original folder" )
} )
scenarioWithPanel ( t , "When an admin moves a library panel to the root folder, the list endpoint reflects the move" ,
func ( t * testing . T , sc scenarioContext ) {
rootUID := ""
moveCmd := model . PatchLibraryElementCommand {
FolderUID : & rootUID ,
Kind : int64 ( model . PanelElement ) ,
Version : 1 ,
}
sc . ctx . Req = web . SetURLParams ( sc . ctx . Req , map [ string ] string { ":uid" : sc . initialResult . Result . UID } )
sc . reqContext . Req . Body = mockRequestBody ( moveCmd )
require . Equal ( t , 200 , sc . service . patchHandler ( sc . reqContext ) . Status ( ) )
require . NoError ( t , sc . reqContext . Req . ParseForm ( ) )
sc . reqContext . Req . Form . Set ( "folderFilter" , "0" )
resp := sc . service . getAllHandler ( sc . reqContext )
require . Equal ( t , 200 , resp . Status ( ) )
var listed libraryElementsSearch
require . NoError ( t , json . Unmarshal ( resp . Body ( ) , & listed ) )
require . Len ( t , listed . Result . Elements , 1 , "panel should appear in root after move-to-root" )
require . Equal ( t , sc . initialResult . Result . UID , listed . Result . Elements [ 0 ] . UID )
require . Equal ( t , "" , listed . Result . Elements [ 0 ] . FolderUID )
require . Equal ( t , "" , listed . Result . Elements [ 0 ] . Meta . FolderUID )
} )
scenarioWithPanel ( t , "When an admin patches a library panel without folderUid, it should stay in its existing folder" ,
func ( t * testing . T , sc scenarioContext ) {
renameCmd := model . PatchLibraryElementCommand {
FolderID : - 1 , // nolint:staticcheck
Name : "Renamed" ,
Kind : int64 ( model . PanelElement ) ,
Version : 1 ,
}
sc . ctx . Req = web . SetURLParams ( sc . ctx . Req , map [ string ] string { ":uid" : sc . initialResult . Result . UID } )
sc . reqContext . Req . Body = mockRequestBody ( renameCmd )
require . Equal ( t , 200 , sc . service . patchHandler ( sc . reqContext ) . Status ( ) )
require . NoError ( t , sc . reqContext . Req . ParseForm ( ) )
sc . reqContext . Req . Form . Set ( "folderFilterUIDs" , sc . folder . UID )
resp := sc . service . getAllHandler ( sc . reqContext )
require . Equal ( t , 200 , resp . Status ( ) )
var listed libraryElementsSearch
require . NoError ( t , json . Unmarshal ( resp . Body ( ) , & listed ) )
require . Len ( t , listed . Result . Elements , 1 , "panel should remain in its original folder when folderUid is not patched" )
require . Equal ( t , sc . folder . UID , listed . Result . Elements [ 0 ] . FolderUID )
require . Equal ( t , sc . folder . UID , listed . Result . Elements [ 0 ] . Meta . FolderUID )
} )
2021-03-01 09:33:17 -05:00
}