2022-02-16 07:15:44 -06:00
package service
2021-03-17 10:06:10 -05:00
import (
2021-11-03 08:10:39 -05:00
"context"
2021-03-17 10:06:10 -05:00
"testing"
2022-05-17 13:52:22 -05:00
"github.com/stretchr/testify/assert"
2023-04-21 09:08:52 -05:00
"github.com/stretchr/testify/mock"
2022-05-17 13:52:22 -05:00
"github.com/stretchr/testify/require"
2021-03-17 10:06:10 -05:00
"github.com/grafana/grafana/pkg/components/simplejson"
2022-10-19 08:02:15 -05:00
"github.com/grafana/grafana/pkg/infra/db"
2023-04-21 09:08:52 -05:00
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/accesscontrol/actest"
2022-03-10 05:58:18 -06:00
accesscontrolmock "github.com/grafana/grafana/pkg/services/accesscontrol/mock"
2023-08-30 09:51:18 -05:00
"github.com/grafana/grafana/pkg/services/auth/identity"
2022-06-30 08:31:54 -05:00
"github.com/grafana/grafana/pkg/services/dashboards"
2022-02-16 07:15:44 -06:00
"github.com/grafana/grafana/pkg/services/dashboards/database"
2022-03-10 05:58:18 -06:00
"github.com/grafana/grafana/pkg/services/featuremgmt"
2023-03-03 09:56:33 -06:00
"github.com/grafana/grafana/pkg/services/folder/folderimpl"
2023-01-26 02:21:10 -06:00
"github.com/grafana/grafana/pkg/services/folder/foldertest"
2021-03-17 10:06:10 -05:00
"github.com/grafana/grafana/pkg/services/guardian"
2022-08-10 04:56:48 -05:00
"github.com/grafana/grafana/pkg/services/org"
2022-11-14 13:08:10 -06:00
"github.com/grafana/grafana/pkg/services/quota/quotatest"
2022-09-21 07:04:01 -05:00
"github.com/grafana/grafana/pkg/services/tag/tagimpl"
2022-08-10 04:56:48 -05:00
"github.com/grafana/grafana/pkg/services/user"
2022-03-10 05:58:18 -06:00
"github.com/grafana/grafana/pkg/setting"
2024-02-09 08:35:39 -06:00
"github.com/grafana/grafana/pkg/tests/testsuite"
2021-03-17 10:06:10 -05:00
)
const testOrgID int64 = 1
2024-02-09 08:35:39 -06:00
func TestMain ( m * testing . M ) {
testsuite . Run ( m )
}
2022-05-24 04:04:03 -05:00
func TestIntegrationIntegratedDashboardService ( t * testing . T ) {
2022-06-10 10:46:21 -05:00
if testing . Short ( ) {
t . Skip ( "skipping integration test" )
}
2021-03-17 10:06:10 -05:00
t . Run ( "Given saved folders and dashboards in organization A" , func ( t * testing . T ) {
// Basic validation tests
permissionScenario ( t , "When saving a dashboard with non-existing id" , true ,
func ( t * testing . T , sc * permissionScenarioContext ) {
2023-01-16 09:33:55 -06:00
cmd := dashboards . SaveDashboardCommand {
OrgID : testOrgID ,
2023-08-30 10:46:47 -05:00
Dashboard : simplejson . NewFromAny ( map [ string ] any {
2021-03-17 10:06:10 -05:00
"id" : float64 ( 123412321 ) ,
"title" : "Expect error" ,
} ) ,
}
2022-11-14 13:08:10 -06:00
err := callSaveWithError ( t , cmd , sc . sqlStore )
2022-06-30 08:31:54 -05:00
assert . Equal ( t , dashboards . ErrDashboardNotFound , err )
2021-03-17 10:06:10 -05:00
} )
// Given other organization
t . Run ( "Given organization B" , func ( t * testing . T ) {
const otherOrgId int64 = 2
permissionScenario ( t , "When creating a dashboard with same id as dashboard in organization A" ,
true , func ( t * testing . T , sc * permissionScenarioContext ) {
2023-01-16 09:33:55 -06:00
cmd := dashboards . SaveDashboardCommand {
OrgID : otherOrgId ,
2023-08-30 10:46:47 -05:00
Dashboard : simplejson . NewFromAny ( map [ string ] any {
2023-01-16 09:33:55 -06:00
"id" : sc . savedDashInFolder . ID ,
2021-03-17 10:06:10 -05:00
"title" : "Expect error" ,
} ) ,
Overwrite : false ,
}
2022-11-14 13:08:10 -06:00
err := callSaveWithError ( t , cmd , sc . sqlStore )
2022-06-30 08:31:54 -05:00
assert . Equal ( t , dashboards . ErrDashboardNotFound , err )
2021-03-17 10:06:10 -05:00
} )
permissionScenario ( t , "When creating a dashboard with same uid as dashboard in organization A, it should create a new dashboard in org B" ,
true , func ( t * testing . T , sc * permissionScenarioContext ) {
const otherOrgId int64 = 2
2023-01-16 09:33:55 -06:00
cmd := dashboards . SaveDashboardCommand {
OrgID : otherOrgId ,
2023-08-30 10:46:47 -05:00
Dashboard : simplejson . NewFromAny ( map [ string ] any {
2023-01-16 09:33:55 -06:00
"uid" : sc . savedDashInFolder . UID ,
2021-03-17 10:06:10 -05:00
"title" : "Dash with existing uid in other org" ,
} ) ,
Overwrite : false ,
}
res := callSaveWithResult ( t , cmd , sc . sqlStore )
require . NotNil ( t , res )
2023-01-16 09:33:55 -06:00
_ , err := sc . dashboardStore . GetDashboard ( context . Background ( ) , & dashboards . GetDashboardQuery {
OrgID : otherOrgId ,
UID : sc . savedDashInFolder . UID ,
2022-02-04 10:21:06 -06:00
} )
2021-03-17 10:06:10 -05:00
require . NoError ( t , err )
} )
} )
t . Run ( "Given user has no permission to save" , func ( t * testing . T ) {
const canSave = false
permissionScenario ( t , "When creating a new dashboard in the General folder" , canSave ,
func ( t * testing . T , sc * permissionScenarioContext ) {
2022-10-19 08:02:15 -05:00
sqlStore := db . InitTestDB ( t )
2023-01-16 09:33:55 -06:00
cmd := dashboards . SaveDashboardCommand {
OrgID : testOrgID ,
2023-08-30 10:46:47 -05:00
Dashboard : simplejson . NewFromAny ( map [ string ] any {
2021-03-17 10:06:10 -05:00
"title" : "Dash" ,
} ) ,
2023-01-16 09:33:55 -06:00
UserID : 10000 ,
2021-03-17 10:06:10 -05:00
Overwrite : true ,
}
2022-11-14 13:08:10 -06:00
err := callSaveWithError ( t , cmd , sqlStore )
2022-06-30 08:31:54 -05:00
assert . Equal ( t , dashboards . ErrDashboardUpdateAccessDenied , err )
2021-03-17 10:06:10 -05:00
2023-08-30 09:51:18 -05:00
userID , err := identity . IntIdentifier ( sc . dashboardGuardianMock . User . GetNamespacedID ( ) )
require . NoError ( t , err )
2022-12-15 08:34:17 -06:00
assert . Equal ( t , "" , sc . dashboardGuardianMock . DashUID )
2023-01-20 07:58:47 -06:00
assert . Equal ( t , cmd . OrgID , sc . dashboardGuardianMock . OrgID )
2023-08-30 09:51:18 -05:00
assert . Equal ( t , cmd . UserID , userID )
2021-03-17 10:06:10 -05:00
} )
permissionScenario ( t , "When creating a new dashboard in other folder, it should create dashboard guardian for other folder with correct arguments and rsult in access denied error" ,
canSave , func ( t * testing . T , sc * permissionScenarioContext ) {
2023-01-16 09:33:55 -06:00
cmd := dashboards . SaveDashboardCommand {
OrgID : testOrgID ,
2023-08-30 10:46:47 -05:00
Dashboard : simplejson . NewFromAny ( map [ string ] any {
2021-03-17 10:06:10 -05:00
"title" : "Dash" ,
} ) ,
2023-10-24 02:04:45 -05:00
FolderUID : sc . otherSavedFolder . UID ,
2023-01-16 09:33:55 -06:00
UserID : 10000 ,
2021-03-17 10:06:10 -05:00
Overwrite : true ,
}
2022-11-14 13:08:10 -06:00
err := callSaveWithError ( t , cmd , sc . sqlStore )
2022-06-30 08:31:54 -05:00
require . Equal ( t , dashboards . ErrDashboardUpdateAccessDenied , err )
2021-03-17 10:06:10 -05:00
2023-08-30 09:51:18 -05:00
userID , err := identity . IntIdentifier ( sc . dashboardGuardianMock . User . GetNamespacedID ( ) )
require . NoError ( t , err )
2023-01-16 09:33:55 -06:00
assert . Equal ( t , sc . otherSavedFolder . ID , sc . dashboardGuardianMock . DashID )
2023-01-20 07:58:47 -06:00
assert . Equal ( t , cmd . OrgID , sc . dashboardGuardianMock . OrgID )
2023-08-30 09:51:18 -05:00
assert . Equal ( t , cmd . UserID , userID )
2021-03-17 10:06:10 -05:00
} )
2022-05-09 05:01:03 -05:00
permissionScenario ( t , "When creating a new dashboard by existing title in folder, it should create dashboard guardian for dashboard with correct arguments and result in access denied error" ,
2021-03-17 10:06:10 -05:00
canSave , func ( t * testing . T , sc * permissionScenarioContext ) {
2023-01-16 09:33:55 -06:00
cmd := dashboards . SaveDashboardCommand {
OrgID : testOrgID ,
2023-08-30 10:46:47 -05:00
Dashboard : simplejson . NewFromAny ( map [ string ] any {
2021-03-17 10:06:10 -05:00
"title" : sc . savedDashInFolder . Title ,
} ) ,
2023-10-24 02:04:45 -05:00
FolderUID : sc . savedFolder . UID ,
2023-01-16 09:33:55 -06:00
UserID : 10000 ,
2021-03-17 10:06:10 -05:00
Overwrite : true ,
}
2022-11-14 13:08:10 -06:00
err := callSaveWithError ( t , cmd , sc . sqlStore )
2022-06-30 08:31:54 -05:00
require . Equal ( t , dashboards . ErrDashboardUpdateAccessDenied , err )
2021-03-17 10:06:10 -05:00
2023-08-30 09:51:18 -05:00
userID , err := identity . IntIdentifier ( sc . dashboardGuardianMock . User . GetNamespacedID ( ) )
require . NoError ( t , err )
2023-01-16 09:33:55 -06:00
assert . Equal ( t , sc . savedDashInFolder . UID , sc . dashboardGuardianMock . DashUID )
2023-01-20 07:58:47 -06:00
assert . Equal ( t , cmd . OrgID , sc . dashboardGuardianMock . OrgID )
2023-08-30 09:51:18 -05:00
assert . Equal ( t , cmd . UserID , userID )
2021-03-17 10:06:10 -05:00
} )
2022-05-09 05:01:03 -05:00
permissionScenario ( t , "When creating a new dashboard by existing UID in folder, it should create dashboard guardian for dashboard with correct arguments and result in access denied error" ,
2021-03-17 10:06:10 -05:00
canSave , func ( t * testing . T , sc * permissionScenarioContext ) {
2023-01-16 09:33:55 -06:00
cmd := dashboards . SaveDashboardCommand {
OrgID : testOrgID ,
2023-08-30 10:46:47 -05:00
Dashboard : simplejson . NewFromAny ( map [ string ] any {
2023-01-16 09:33:55 -06:00
"uid" : sc . savedDashInFolder . UID ,
2021-03-17 10:06:10 -05:00
"title" : "New dash" ,
} ) ,
2023-10-24 02:04:45 -05:00
FolderUID : sc . savedFolder . UID ,
2023-01-16 09:33:55 -06:00
UserID : 10000 ,
2021-03-17 10:06:10 -05:00
Overwrite : true ,
}
2022-11-14 13:08:10 -06:00
err := callSaveWithError ( t , cmd , sc . sqlStore )
2022-06-30 08:31:54 -05:00
require . Equal ( t , dashboards . ErrDashboardUpdateAccessDenied , err )
2021-03-17 10:06:10 -05:00
2023-08-30 09:51:18 -05:00
userID , err := identity . IntIdentifier ( sc . dashboardGuardianMock . User . GetNamespacedID ( ) )
require . NoError ( t , err )
2023-01-16 09:33:55 -06:00
assert . Equal ( t , sc . savedDashInFolder . UID , sc . dashboardGuardianMock . DashUID )
2023-01-20 07:58:47 -06:00
assert . Equal ( t , cmd . OrgID , sc . dashboardGuardianMock . OrgID )
2023-08-30 09:51:18 -05:00
assert . Equal ( t , cmd . UserID , userID )
2021-03-17 10:06:10 -05:00
} )
permissionScenario ( t , "When updating a dashboard by existing id in the General folder, it should create dashboard guardian for dashboard with correct arguments and result in access denied error" ,
canSave , func ( t * testing . T , sc * permissionScenarioContext ) {
2023-01-16 09:33:55 -06:00
cmd := dashboards . SaveDashboardCommand {
OrgID : testOrgID ,
2023-08-30 10:46:47 -05:00
Dashboard : simplejson . NewFromAny ( map [ string ] any {
2023-01-16 09:33:55 -06:00
"id" : sc . savedDashInGeneralFolder . ID ,
2021-03-17 10:06:10 -05:00
"title" : "Dash" ,
} ) ,
2023-10-24 02:04:45 -05:00
FolderUID : sc . savedDashInGeneralFolder . FolderUID ,
2023-01-16 09:33:55 -06:00
UserID : 10000 ,
2021-03-17 10:06:10 -05:00
Overwrite : true ,
}
2022-11-14 13:08:10 -06:00
err := callSaveWithError ( t , cmd , sc . sqlStore )
2022-06-30 08:31:54 -05:00
assert . Equal ( t , dashboards . ErrDashboardUpdateAccessDenied , err )
2021-03-17 10:06:10 -05:00
2023-08-30 09:51:18 -05:00
userID , err := identity . IntIdentifier ( sc . dashboardGuardianMock . User . GetNamespacedID ( ) )
require . NoError ( t , err )
2023-01-16 09:33:55 -06:00
assert . Equal ( t , sc . savedDashInGeneralFolder . UID , sc . dashboardGuardianMock . DashUID )
2023-01-20 07:58:47 -06:00
assert . Equal ( t , cmd . OrgID , sc . dashboardGuardianMock . OrgID )
2023-08-30 09:51:18 -05:00
assert . Equal ( t , cmd . UserID , userID )
2021-03-17 10:06:10 -05:00
} )
permissionScenario ( t , "When updating a dashboard by existing id in other folder, it should create dashboard guardian for dashboard with correct arguments and result in access denied error" ,
canSave , func ( t * testing . T , sc * permissionScenarioContext ) {
2023-01-16 09:33:55 -06:00
cmd := dashboards . SaveDashboardCommand {
OrgID : testOrgID ,
2023-08-30 10:46:47 -05:00
Dashboard : simplejson . NewFromAny ( map [ string ] any {
2023-01-16 09:33:55 -06:00
"id" : sc . savedDashInFolder . ID ,
2021-03-17 10:06:10 -05:00
"title" : "Dash" ,
} ) ,
2023-10-24 02:04:45 -05:00
FolderUID : sc . savedDashInFolder . FolderUID ,
2023-01-16 09:33:55 -06:00
UserID : 10000 ,
2021-03-17 10:06:10 -05:00
Overwrite : true ,
}
2022-11-14 13:08:10 -06:00
err := callSaveWithError ( t , cmd , sc . sqlStore )
2022-06-30 08:31:54 -05:00
require . Equal ( t , dashboards . ErrDashboardUpdateAccessDenied , err )
2021-03-17 10:06:10 -05:00
2023-08-30 09:51:18 -05:00
userID , err := identity . IntIdentifier ( sc . dashboardGuardianMock . User . GetNamespacedID ( ) )
require . NoError ( t , err )
2023-01-16 09:33:55 -06:00
assert . Equal ( t , sc . savedDashInFolder . UID , sc . dashboardGuardianMock . DashUID )
2023-01-20 07:58:47 -06:00
assert . Equal ( t , cmd . OrgID , sc . dashboardGuardianMock . OrgID )
2023-08-30 09:51:18 -05:00
assert . Equal ( t , cmd . UserID , userID )
2021-03-17 10:06:10 -05:00
} )
2022-05-09 05:01:03 -05:00
permissionScenario ( t , "When moving a dashboard by existing ID to other folder from General folder, it should create dashboard guardian for dashboard with correct arguments and result in access denied error" ,
2021-03-17 10:06:10 -05:00
canSave , func ( t * testing . T , sc * permissionScenarioContext ) {
2023-01-16 09:33:55 -06:00
cmd := dashboards . SaveDashboardCommand {
OrgID : testOrgID ,
2023-08-30 10:46:47 -05:00
Dashboard : simplejson . NewFromAny ( map [ string ] any {
2023-01-16 09:33:55 -06:00
"id" : sc . savedDashInGeneralFolder . ID ,
2021-03-17 10:06:10 -05:00
"title" : "Dash" ,
} ) ,
2023-10-24 02:04:45 -05:00
FolderUID : sc . otherSavedFolder . UID ,
2023-01-16 09:33:55 -06:00
UserID : 10000 ,
2021-03-17 10:06:10 -05:00
Overwrite : true ,
}
2022-11-14 13:08:10 -06:00
err := callSaveWithError ( t , cmd , sc . sqlStore )
2022-06-30 08:31:54 -05:00
require . Equal ( t , dashboards . ErrDashboardUpdateAccessDenied , err )
2021-03-17 10:06:10 -05:00
2023-08-30 09:51:18 -05:00
userID , err := identity . IntIdentifier ( sc . dashboardGuardianMock . User . GetNamespacedID ( ) )
require . NoError ( t , err )
2023-01-16 09:33:55 -06:00
assert . Equal ( t , sc . savedDashInGeneralFolder . UID , sc . dashboardGuardianMock . DashUID )
2023-01-20 07:58:47 -06:00
assert . Equal ( t , cmd . OrgID , sc . dashboardGuardianMock . OrgID )
2023-08-30 09:51:18 -05:00
assert . Equal ( t , cmd . UserID , userID )
2021-03-17 10:06:10 -05:00
} )
2022-05-09 05:01:03 -05:00
permissionScenario ( t , "When moving a dashboard by existing id to the General folder from other folder, it should create dashboard guardian for dashboard with correct arguments and result in access denied error" ,
2021-03-17 10:06:10 -05:00
canSave , func ( t * testing . T , sc * permissionScenarioContext ) {
2023-01-16 09:33:55 -06:00
cmd := dashboards . SaveDashboardCommand {
OrgID : testOrgID ,
2023-08-30 10:46:47 -05:00
Dashboard : simplejson . NewFromAny ( map [ string ] any {
2023-01-16 09:33:55 -06:00
"id" : sc . savedDashInFolder . ID ,
2021-03-17 10:06:10 -05:00
"title" : "Dash" ,
} ) ,
2023-10-24 02:04:45 -05:00
FolderUID : "" ,
2023-01-16 09:33:55 -06:00
UserID : 10000 ,
2021-03-17 10:06:10 -05:00
Overwrite : true ,
}
2022-11-14 13:08:10 -06:00
err := callSaveWithError ( t , cmd , sc . sqlStore )
2022-06-30 08:31:54 -05:00
assert . Equal ( t , dashboards . ErrDashboardUpdateAccessDenied , err )
2021-03-17 10:06:10 -05:00
2023-08-30 09:51:18 -05:00
userID , err := identity . IntIdentifier ( sc . dashboardGuardianMock . User . GetNamespacedID ( ) )
require . NoError ( t , err )
2023-01-16 09:33:55 -06:00
assert . Equal ( t , sc . savedDashInFolder . UID , sc . dashboardGuardianMock . DashUID )
2023-01-20 07:58:47 -06:00
assert . Equal ( t , cmd . OrgID , sc . dashboardGuardianMock . OrgID )
2023-08-30 09:51:18 -05:00
assert . Equal ( t , cmd . UserID , userID )
2021-03-17 10:06:10 -05:00
} )
2022-05-09 05:01:03 -05:00
permissionScenario ( t , "When moving a dashboard by existing uid to other folder from General folder, it should create dashboard guardian for dashboard with correct arguments and result in access denied error" ,
2021-03-17 10:06:10 -05:00
canSave , func ( t * testing . T , sc * permissionScenarioContext ) {
2023-01-16 09:33:55 -06:00
cmd := dashboards . SaveDashboardCommand {
OrgID : testOrgID ,
2023-08-30 10:46:47 -05:00
Dashboard : simplejson . NewFromAny ( map [ string ] any {
2023-01-16 09:33:55 -06:00
"uid" : sc . savedDashInGeneralFolder . UID ,
2021-03-17 10:06:10 -05:00
"title" : "Dash" ,
} ) ,
2023-10-24 02:04:45 -05:00
FolderUID : sc . otherSavedFolder . UID ,
2023-01-16 09:33:55 -06:00
UserID : 10000 ,
2021-03-17 10:06:10 -05:00
Overwrite : true ,
}
2022-11-14 13:08:10 -06:00
err := callSaveWithError ( t , cmd , sc . sqlStore )
2022-06-30 08:31:54 -05:00
require . Equal ( t , dashboards . ErrDashboardUpdateAccessDenied , err )
2021-03-17 10:06:10 -05:00
2023-08-30 09:51:18 -05:00
userID , err := identity . IntIdentifier ( sc . dashboardGuardianMock . User . GetNamespacedID ( ) )
require . NoError ( t , err )
2023-01-16 09:33:55 -06:00
assert . Equal ( t , sc . savedDashInGeneralFolder . UID , sc . dashboardGuardianMock . DashUID )
2023-01-20 07:58:47 -06:00
assert . Equal ( t , cmd . OrgID , sc . dashboardGuardianMock . OrgID )
2023-08-30 09:51:18 -05:00
assert . Equal ( t , cmd . UserID , userID )
2021-03-17 10:06:10 -05:00
} )
2022-05-09 05:01:03 -05:00
permissionScenario ( t , "When moving a dashboard by existing UID to the General folder from other folder, it should create dashboard guardian for dashboard with correct arguments and result in access denied error" ,
2021-03-17 10:06:10 -05:00
canSave , func ( t * testing . T , sc * permissionScenarioContext ) {
2023-01-16 09:33:55 -06:00
cmd := dashboards . SaveDashboardCommand {
OrgID : testOrgID ,
2023-08-30 10:46:47 -05:00
Dashboard : simplejson . NewFromAny ( map [ string ] any {
2023-01-16 09:33:55 -06:00
"uid" : sc . savedDashInFolder . UID ,
2021-03-17 10:06:10 -05:00
"title" : "Dash" ,
} ) ,
2023-10-24 02:04:45 -05:00
FolderUID : "" ,
2023-01-16 09:33:55 -06:00
UserID : 10000 ,
2021-03-17 10:06:10 -05:00
Overwrite : true ,
}
2022-11-14 13:08:10 -06:00
err := callSaveWithError ( t , cmd , sc . sqlStore )
2022-06-30 08:31:54 -05:00
require . Equal ( t , dashboards . ErrDashboardUpdateAccessDenied , err )
2021-03-17 10:06:10 -05:00
2023-08-30 09:51:18 -05:00
userID , err := identity . IntIdentifier ( sc . dashboardGuardianMock . User . GetNamespacedID ( ) )
require . NoError ( t , err )
2023-01-16 09:33:55 -06:00
assert . Equal ( t , sc . savedDashInFolder . UID , sc . dashboardGuardianMock . DashUID )
2023-01-20 07:58:47 -06:00
assert . Equal ( t , cmd . OrgID , sc . dashboardGuardianMock . OrgID )
2023-08-30 09:51:18 -05:00
assert . Equal ( t , cmd . UserID , userID )
2021-03-17 10:06:10 -05:00
} )
} )
t . Run ( "Given user has permission to save" , func ( t * testing . T ) {
const canSave = true
t . Run ( "and overwrite flag is set to false" , func ( t * testing . T ) {
const shouldOverwrite = false
permissionScenario ( t , "When creating a dashboard in General folder with same name as dashboard in other folder" ,
canSave , func ( t * testing . T , sc * permissionScenarioContext ) {
2023-01-16 09:33:55 -06:00
cmd := dashboards . SaveDashboardCommand {
OrgID : testOrgID ,
2023-08-30 10:46:47 -05:00
Dashboard : simplejson . NewFromAny ( map [ string ] any {
2021-03-17 10:06:10 -05:00
"id" : nil ,
"title" : sc . savedDashInFolder . Title ,
} ) ,
2023-10-24 02:04:45 -05:00
FolderUID : "" ,
2021-03-17 10:06:10 -05:00
Overwrite : shouldOverwrite ,
}
res := callSaveWithResult ( t , cmd , sc . sqlStore )
require . NotNil ( t , res )
2023-01-16 09:33:55 -06:00
_ , err := sc . dashboardStore . GetDashboard ( context . Background ( ) , & dashboards . GetDashboardQuery {
ID : res . ID ,
OrgID : cmd . OrgID ,
2022-02-04 10:21:06 -06:00
} )
2021-03-17 10:06:10 -05:00
require . NoError ( t , err )
} )
permissionScenario ( t , "When creating a dashboard in other folder with same name as dashboard in General folder" ,
canSave , func ( t * testing . T , sc * permissionScenarioContext ) {
2023-01-16 09:33:55 -06:00
cmd := dashboards . SaveDashboardCommand {
OrgID : testOrgID ,
2023-08-30 10:46:47 -05:00
Dashboard : simplejson . NewFromAny ( map [ string ] any {
2021-03-17 10:06:10 -05:00
"id" : nil ,
"title" : sc . savedDashInGeneralFolder . Title ,
} ) ,
2023-10-24 02:04:45 -05:00
FolderUID : sc . savedFolder . UID ,
2021-03-17 10:06:10 -05:00
Overwrite : shouldOverwrite ,
}
res := callSaveWithResult ( t , cmd , sc . sqlStore )
require . NotNil ( t , res )
2023-01-16 09:33:55 -06:00
assert . NotEqual ( t , sc . savedDashInGeneralFolder . ID , res . ID )
2021-03-17 10:06:10 -05:00
2023-01-16 09:33:55 -06:00
_ , err := sc . dashboardStore . GetDashboard ( context . Background ( ) , & dashboards . GetDashboardQuery {
ID : res . ID ,
OrgID : cmd . OrgID ,
2022-02-04 10:21:06 -06:00
} )
2021-03-17 10:06:10 -05:00
require . NoError ( t , err )
} )
permissionScenario ( t , "When creating a folder with same name as dashboard in other folder" ,
canSave , func ( t * testing . T , sc * permissionScenarioContext ) {
2023-01-16 09:33:55 -06:00
cmd := dashboards . SaveDashboardCommand {
OrgID : testOrgID ,
2023-08-30 10:46:47 -05:00
Dashboard : simplejson . NewFromAny ( map [ string ] any {
2021-03-17 10:06:10 -05:00
"id" : nil ,
"title" : sc . savedDashInFolder . Title ,
} ) ,
IsFolder : true ,
Overwrite : shouldOverwrite ,
}
res := callSaveWithResult ( t , cmd , sc . sqlStore )
require . NotNil ( t , res )
2023-01-16 09:33:55 -06:00
assert . NotEqual ( t , sc . savedDashInGeneralFolder . ID , res . ID )
2021-03-17 10:06:10 -05:00
assert . True ( t , res . IsFolder )
2023-01-16 09:33:55 -06:00
_ , err := sc . dashboardStore . GetDashboard ( context . Background ( ) , & dashboards . GetDashboardQuery {
ID : res . ID ,
OrgID : cmd . OrgID ,
2022-02-04 10:21:06 -06:00
} )
2021-03-17 10:06:10 -05:00
require . NoError ( t , err )
} )
permissionScenario ( t , "When saving a dashboard without id and uid and unique title in folder" ,
canSave , func ( t * testing . T , sc * permissionScenarioContext ) {
2023-01-16 09:33:55 -06:00
cmd := dashboards . SaveDashboardCommand {
OrgID : testOrgID ,
2023-08-30 10:46:47 -05:00
Dashboard : simplejson . NewFromAny ( map [ string ] any {
2021-03-17 10:06:10 -05:00
"title" : "Dash without id and uid" ,
} ) ,
Overwrite : shouldOverwrite ,
}
res := callSaveWithResult ( t , cmd , sc . sqlStore )
require . NotNil ( t , res )
2023-01-16 09:33:55 -06:00
assert . Greater ( t , res . ID , int64 ( 0 ) )
assert . NotEmpty ( t , res . UID )
_ , err := sc . dashboardStore . GetDashboard ( context . Background ( ) , & dashboards . GetDashboardQuery {
ID : res . ID ,
OrgID : cmd . OrgID ,
2022-02-04 10:21:06 -06:00
} )
2021-03-17 10:06:10 -05:00
require . NoError ( t , err )
} )
permissionScenario ( t , "When saving a dashboard when dashboard id is zero " , canSave ,
func ( t * testing . T , sc * permissionScenarioContext ) {
2023-01-16 09:33:55 -06:00
cmd := dashboards . SaveDashboardCommand {
OrgID : testOrgID ,
2023-08-30 10:46:47 -05:00
Dashboard : simplejson . NewFromAny ( map [ string ] any {
2021-03-17 10:06:10 -05:00
"id" : 0 ,
"title" : "Dash with zero id" ,
} ) ,
Overwrite : shouldOverwrite ,
}
res := callSaveWithResult ( t , cmd , sc . sqlStore )
require . NotNil ( t , res )
2023-01-16 09:33:55 -06:00
_ , err := sc . dashboardStore . GetDashboard ( context . Background ( ) , & dashboards . GetDashboardQuery {
ID : res . ID ,
OrgID : cmd . OrgID ,
2022-02-04 10:21:06 -06:00
} )
2021-03-17 10:06:10 -05:00
require . NoError ( t , err )
} )
permissionScenario ( t , "When saving a dashboard in non-existing folder" , canSave ,
func ( t * testing . T , sc * permissionScenarioContext ) {
2023-01-16 09:33:55 -06:00
cmd := dashboards . SaveDashboardCommand {
OrgID : testOrgID ,
2023-08-30 10:46:47 -05:00
Dashboard : simplejson . NewFromAny ( map [ string ] any {
2021-03-17 10:06:10 -05:00
"title" : "Expect error" ,
} ) ,
2023-10-24 02:04:45 -05:00
FolderUID : "123412321" ,
2021-03-17 10:06:10 -05:00
Overwrite : shouldOverwrite ,
}
2022-11-14 13:08:10 -06:00
err := callSaveWithError ( t , cmd , sc . sqlStore )
2023-11-16 05:11:35 -06:00
assert . Equal ( t , dashboards . ErrFolderNotFound , err )
2021-03-17 10:06:10 -05:00
} )
permissionScenario ( t , "When updating an existing dashboard by id without current version" , canSave ,
func ( t * testing . T , sc * permissionScenarioContext ) {
2023-01-16 09:33:55 -06:00
cmd := dashboards . SaveDashboardCommand {
OrgID : 1 ,
2023-08-30 10:46:47 -05:00
Dashboard : simplejson . NewFromAny ( map [ string ] any {
2023-01-16 09:33:55 -06:00
"id" : sc . savedDashInGeneralFolder . ID ,
2021-03-17 10:06:10 -05:00
"title" : "test dash 23" ,
} ) ,
2023-10-24 02:04:45 -05:00
FolderUID : sc . savedFolder . UID ,
2021-03-17 10:06:10 -05:00
Overwrite : shouldOverwrite ,
}
2022-11-14 13:08:10 -06:00
err := callSaveWithError ( t , cmd , sc . sqlStore )
2022-06-30 08:31:54 -05:00
assert . Equal ( t , dashboards . ErrDashboardVersionMismatch , err )
2021-03-17 10:06:10 -05:00
} )
permissionScenario ( t , "When updating an existing dashboard by id with current version" , canSave ,
func ( t * testing . T , sc * permissionScenarioContext ) {
2023-01-16 09:33:55 -06:00
cmd := dashboards . SaveDashboardCommand {
OrgID : 1 ,
2023-08-30 10:46:47 -05:00
Dashboard : simplejson . NewFromAny ( map [ string ] any {
2023-01-16 09:33:55 -06:00
"id" : sc . savedDashInGeneralFolder . ID ,
2021-03-17 10:06:10 -05:00
"title" : "Updated title" ,
"version" : sc . savedDashInGeneralFolder . Version ,
} ) ,
2023-10-24 02:04:45 -05:00
FolderUID : sc . savedFolder . UID ,
2021-03-17 10:06:10 -05:00
Overwrite : shouldOverwrite ,
}
res := callSaveWithResult ( t , cmd , sc . sqlStore )
require . NotNil ( t , res )
2023-01-16 09:33:55 -06:00
_ , err := sc . dashboardStore . GetDashboard ( context . Background ( ) , & dashboards . GetDashboardQuery {
ID : sc . savedDashInGeneralFolder . ID ,
OrgID : cmd . OrgID ,
2022-02-04 10:21:06 -06:00
} )
2021-03-17 10:06:10 -05:00
require . NoError ( t , err )
} )
permissionScenario ( t , "When updating an existing dashboard by uid without current version" , canSave ,
func ( t * testing . T , sc * permissionScenarioContext ) {
2023-01-16 09:33:55 -06:00
cmd := dashboards . SaveDashboardCommand {
OrgID : 1 ,
2023-08-30 10:46:47 -05:00
Dashboard : simplejson . NewFromAny ( map [ string ] any {
2023-01-16 09:33:55 -06:00
"uid" : sc . savedDashInFolder . UID ,
2021-03-17 10:06:10 -05:00
"title" : "test dash 23" ,
} ) ,
2023-10-24 02:04:45 -05:00
FolderUID : "" ,
2021-03-17 10:06:10 -05:00
Overwrite : shouldOverwrite ,
}
2022-11-14 13:08:10 -06:00
err := callSaveWithError ( t , cmd , sc . sqlStore )
2022-06-30 08:31:54 -05:00
assert . Equal ( t , dashboards . ErrDashboardVersionMismatch , err )
2021-03-17 10:06:10 -05:00
} )
permissionScenario ( t , "When updating an existing dashboard by uid with current version" , canSave ,
func ( t * testing . T , sc * permissionScenarioContext ) {
2023-01-16 09:33:55 -06:00
cmd := dashboards . SaveDashboardCommand {
OrgID : 1 ,
2023-08-30 10:46:47 -05:00
Dashboard : simplejson . NewFromAny ( map [ string ] any {
2023-01-16 09:33:55 -06:00
"uid" : sc . savedDashInFolder . UID ,
2021-03-17 10:06:10 -05:00
"title" : "Updated title" ,
"version" : sc . savedDashInFolder . Version ,
} ) ,
2023-10-24 02:04:45 -05:00
FolderUID : "" ,
2021-03-17 10:06:10 -05:00
Overwrite : shouldOverwrite ,
}
res := callSaveWithResult ( t , cmd , sc . sqlStore )
require . NotNil ( t , res )
2023-01-16 09:33:55 -06:00
_ , err := sc . dashboardStore . GetDashboard ( context . Background ( ) , & dashboards . GetDashboardQuery {
ID : sc . savedDashInFolder . ID ,
OrgID : cmd . OrgID ,
2022-02-04 10:21:06 -06:00
} )
2021-03-17 10:06:10 -05:00
require . NoError ( t , err )
} )
permissionScenario ( t , "When creating a dashboard with same name as dashboard in other folder" ,
canSave , func ( t * testing . T , sc * permissionScenarioContext ) {
2023-01-16 09:33:55 -06:00
cmd := dashboards . SaveDashboardCommand {
OrgID : testOrgID ,
2023-08-30 10:46:47 -05:00
Dashboard : simplejson . NewFromAny ( map [ string ] any {
2021-03-17 10:06:10 -05:00
"id" : nil ,
"title" : sc . savedDashInFolder . Title ,
} ) ,
2023-10-24 02:04:45 -05:00
FolderUID : sc . savedDashInFolder . FolderUID ,
2021-03-17 10:06:10 -05:00
Overwrite : shouldOverwrite ,
}
2022-11-14 13:08:10 -06:00
err := callSaveWithError ( t , cmd , sc . sqlStore )
2022-06-30 08:31:54 -05:00
assert . Equal ( t , dashboards . ErrDashboardWithSameNameInFolderExists , err )
2021-03-17 10:06:10 -05:00
} )
permissionScenario ( t , "When creating a dashboard with same name as dashboard in General folder" ,
canSave , func ( t * testing . T , sc * permissionScenarioContext ) {
2023-01-16 09:33:55 -06:00
cmd := dashboards . SaveDashboardCommand {
OrgID : testOrgID ,
2023-08-30 10:46:47 -05:00
Dashboard : simplejson . NewFromAny ( map [ string ] any {
2021-03-17 10:06:10 -05:00
"id" : nil ,
"title" : sc . savedDashInGeneralFolder . Title ,
} ) ,
2023-10-24 02:04:45 -05:00
FolderUID : sc . savedDashInGeneralFolder . FolderUID ,
2021-03-17 10:06:10 -05:00
Overwrite : shouldOverwrite ,
}
2022-11-14 13:08:10 -06:00
err := callSaveWithError ( t , cmd , sc . sqlStore )
2022-06-30 08:31:54 -05:00
assert . Equal ( t , dashboards . ErrDashboardWithSameNameInFolderExists , err )
2021-03-17 10:06:10 -05:00
} )
permissionScenario ( t , "When creating a folder with same name as existing folder" , canSave ,
func ( t * testing . T , sc * permissionScenarioContext ) {
2023-01-16 09:33:55 -06:00
cmd := dashboards . SaveDashboardCommand {
OrgID : testOrgID ,
2023-08-30 10:46:47 -05:00
Dashboard : simplejson . NewFromAny ( map [ string ] any {
2021-03-17 10:06:10 -05:00
"id" : nil ,
"title" : sc . savedFolder . Title ,
} ) ,
IsFolder : true ,
Overwrite : shouldOverwrite ,
}
2022-11-14 13:08:10 -06:00
err := callSaveWithError ( t , cmd , sc . sqlStore )
2022-06-30 08:31:54 -05:00
assert . Equal ( t , dashboards . ErrDashboardWithSameNameInFolderExists , err )
2021-03-17 10:06:10 -05:00
} )
} )
t . Run ( "and overwrite flag is set to true" , func ( t * testing . T ) {
const shouldOverwrite = true
permissionScenario ( t , "When updating an existing dashboard by id without current version" , canSave ,
func ( t * testing . T , sc * permissionScenarioContext ) {
2023-01-16 09:33:55 -06:00
cmd := dashboards . SaveDashboardCommand {
OrgID : 1 ,
2023-08-30 10:46:47 -05:00
Dashboard : simplejson . NewFromAny ( map [ string ] any {
2023-01-16 09:33:55 -06:00
"id" : sc . savedDashInGeneralFolder . ID ,
2021-03-17 10:06:10 -05:00
"title" : "Updated title" ,
} ) ,
2023-10-24 02:04:45 -05:00
FolderUID : sc . savedFolder . UID ,
2021-03-17 10:06:10 -05:00
Overwrite : shouldOverwrite ,
}
res := callSaveWithResult ( t , cmd , sc . sqlStore )
require . NotNil ( t , res )
2023-01-16 09:33:55 -06:00
_ , err := sc . dashboardStore . GetDashboard ( context . Background ( ) , & dashboards . GetDashboardQuery {
ID : sc . savedDashInGeneralFolder . ID ,
OrgID : cmd . OrgID ,
2022-02-04 10:21:06 -06:00
} )
2021-03-17 10:06:10 -05:00
require . NoError ( t , err )
} )
permissionScenario ( t , "When updating an existing dashboard by uid without current version" , canSave ,
func ( t * testing . T , sc * permissionScenarioContext ) {
2023-01-16 09:33:55 -06:00
cmd := dashboards . SaveDashboardCommand {
OrgID : 1 ,
2023-08-30 10:46:47 -05:00
Dashboard : simplejson . NewFromAny ( map [ string ] any {
2023-01-16 09:33:55 -06:00
"uid" : sc . savedDashInFolder . UID ,
2021-03-17 10:06:10 -05:00
"title" : "Updated title" ,
} ) ,
2023-10-24 02:04:45 -05:00
FolderUID : "" ,
2021-03-17 10:06:10 -05:00
Overwrite : shouldOverwrite ,
}
res := callSaveWithResult ( t , cmd , sc . sqlStore )
require . NotNil ( t , res )
2023-01-16 09:33:55 -06:00
_ , err := sc . dashboardStore . GetDashboard ( context . Background ( ) , & dashboards . GetDashboardQuery {
ID : sc . savedDashInFolder . ID ,
OrgID : cmd . OrgID ,
2022-02-04 10:21:06 -06:00
} )
2021-03-17 10:06:10 -05:00
require . NoError ( t , err )
} )
permissionScenario ( t , "When updating uid for existing dashboard using id" , canSave ,
func ( t * testing . T , sc * permissionScenarioContext ) {
2023-01-16 09:33:55 -06:00
cmd := dashboards . SaveDashboardCommand {
OrgID : 1 ,
2023-08-30 10:46:47 -05:00
Dashboard : simplejson . NewFromAny ( map [ string ] any {
2023-01-16 09:33:55 -06:00
"id" : sc . savedDashInFolder . ID ,
2021-03-17 10:06:10 -05:00
"uid" : "new-uid" ,
"title" : sc . savedDashInFolder . Title ,
} ) ,
Overwrite : shouldOverwrite ,
}
res := callSaveWithResult ( t , cmd , sc . sqlStore )
require . NotNil ( t , res )
2023-01-16 09:33:55 -06:00
assert . Equal ( t , sc . savedDashInFolder . ID , res . ID )
assert . Equal ( t , "new-uid" , res . UID )
2021-03-17 10:06:10 -05:00
2023-01-16 09:33:55 -06:00
_ , err := sc . dashboardStore . GetDashboard ( context . Background ( ) , & dashboards . GetDashboardQuery {
ID : sc . savedDashInFolder . ID ,
OrgID : cmd . OrgID ,
2022-02-04 10:21:06 -06:00
} )
2021-03-17 10:06:10 -05:00
require . NoError ( t , err )
} )
permissionScenario ( t , "When updating uid to an existing uid for existing dashboard using id" , canSave ,
func ( t * testing . T , sc * permissionScenarioContext ) {
2023-01-16 09:33:55 -06:00
cmd := dashboards . SaveDashboardCommand {
OrgID : 1 ,
2023-08-30 10:46:47 -05:00
Dashboard : simplejson . NewFromAny ( map [ string ] any {
2023-01-16 09:33:55 -06:00
"id" : sc . savedDashInFolder . ID ,
"uid" : sc . savedDashInGeneralFolder . UID ,
2021-03-17 10:06:10 -05:00
"title" : sc . savedDashInFolder . Title ,
} ) ,
Overwrite : shouldOverwrite ,
}
2022-11-14 13:08:10 -06:00
err := callSaveWithError ( t , cmd , sc . sqlStore )
2022-06-30 08:31:54 -05:00
assert . Equal ( t , dashboards . ErrDashboardWithSameUIDExists , err )
2021-03-17 10:06:10 -05:00
} )
permissionScenario ( t , "When creating a dashboard with same name as dashboard in other folder" , canSave ,
func ( t * testing . T , sc * permissionScenarioContext ) {
2023-01-16 09:33:55 -06:00
cmd := dashboards . SaveDashboardCommand {
OrgID : testOrgID ,
2023-08-30 10:46:47 -05:00
Dashboard : simplejson . NewFromAny ( map [ string ] any {
2021-03-17 10:06:10 -05:00
"id" : nil ,
"title" : sc . savedDashInFolder . Title ,
} ) ,
2023-10-24 02:04:45 -05:00
FolderUID : sc . savedDashInFolder . FolderUID ,
2021-03-17 10:06:10 -05:00
Overwrite : shouldOverwrite ,
}
res := callSaveWithResult ( t , cmd , sc . sqlStore )
require . NotNil ( t , res )
2023-01-16 09:33:55 -06:00
assert . Equal ( t , sc . savedDashInFolder . ID , res . ID )
assert . Equal ( t , sc . savedDashInFolder . UID , res . UID )
2021-03-17 10:06:10 -05:00
2023-01-16 09:33:55 -06:00
_ , err := sc . dashboardStore . GetDashboard ( context . Background ( ) , & dashboards . GetDashboardQuery {
ID : res . ID ,
OrgID : cmd . OrgID ,
2022-02-04 10:21:06 -06:00
} )
2021-03-17 10:06:10 -05:00
require . NoError ( t , err )
} )
permissionScenario ( t , "When creating a dashboard with same name as dashboard in General folder" , canSave ,
func ( t * testing . T , sc * permissionScenarioContext ) {
2023-01-16 09:33:55 -06:00
cmd := dashboards . SaveDashboardCommand {
OrgID : testOrgID ,
2023-08-30 10:46:47 -05:00
Dashboard : simplejson . NewFromAny ( map [ string ] any {
2021-03-17 10:06:10 -05:00
"id" : nil ,
"title" : sc . savedDashInGeneralFolder . Title ,
} ) ,
2023-10-24 02:04:45 -05:00
FolderUID : sc . savedDashInGeneralFolder . FolderUID ,
2021-03-17 10:06:10 -05:00
Overwrite : shouldOverwrite ,
}
res := callSaveWithResult ( t , cmd , sc . sqlStore )
require . NotNil ( t , res )
2023-01-16 09:33:55 -06:00
assert . Equal ( t , sc . savedDashInGeneralFolder . ID , res . ID )
assert . Equal ( t , sc . savedDashInGeneralFolder . UID , res . UID )
2021-03-17 10:06:10 -05:00
2023-01-16 09:33:55 -06:00
_ , err := sc . dashboardStore . GetDashboard ( context . Background ( ) , & dashboards . GetDashboardQuery {
ID : res . ID ,
OrgID : cmd . OrgID ,
2022-02-04 10:21:06 -06:00
} )
2021-03-17 10:06:10 -05:00
require . NoError ( t , err )
} )
permissionScenario ( t , "When updating existing folder to a dashboard using id" , canSave ,
func ( t * testing . T , sc * permissionScenarioContext ) {
2023-01-16 09:33:55 -06:00
cmd := dashboards . SaveDashboardCommand {
OrgID : 1 ,
2023-08-30 10:46:47 -05:00
Dashboard : simplejson . NewFromAny ( map [ string ] any {
2023-01-16 09:33:55 -06:00
"id" : sc . savedFolder . ID ,
2021-03-17 10:06:10 -05:00
"title" : "new title" ,
} ) ,
IsFolder : false ,
Overwrite : shouldOverwrite ,
}
2022-11-14 13:08:10 -06:00
err := callSaveWithError ( t , cmd , sc . sqlStore )
2022-06-30 08:31:54 -05:00
assert . Equal ( t , dashboards . ErrDashboardTypeMismatch , err )
2021-03-17 10:06:10 -05:00
} )
permissionScenario ( t , "When updating existing dashboard to a folder using id" , canSave ,
func ( t * testing . T , sc * permissionScenarioContext ) {
2023-01-16 09:33:55 -06:00
cmd := dashboards . SaveDashboardCommand {
OrgID : 1 ,
2023-08-30 10:46:47 -05:00
Dashboard : simplejson . NewFromAny ( map [ string ] any {
2023-01-16 09:33:55 -06:00
"id" : sc . savedDashInFolder . ID ,
2021-03-17 10:06:10 -05:00
"title" : "new folder title" ,
} ) ,
IsFolder : true ,
Overwrite : shouldOverwrite ,
}
2022-11-14 13:08:10 -06:00
err := callSaveWithError ( t , cmd , sc . sqlStore )
2022-06-30 08:31:54 -05:00
assert . Equal ( t , dashboards . ErrDashboardTypeMismatch , err )
2021-03-17 10:06:10 -05:00
} )
permissionScenario ( t , "When updating existing folder to a dashboard using uid" , canSave ,
func ( t * testing . T , sc * permissionScenarioContext ) {
2023-01-16 09:33:55 -06:00
cmd := dashboards . SaveDashboardCommand {
OrgID : 1 ,
2023-08-30 10:46:47 -05:00
Dashboard : simplejson . NewFromAny ( map [ string ] any {
2023-01-16 09:33:55 -06:00
"uid" : sc . savedFolder . UID ,
2021-03-17 10:06:10 -05:00
"title" : "new title" ,
} ) ,
IsFolder : false ,
Overwrite : shouldOverwrite ,
}
2022-11-14 13:08:10 -06:00
err := callSaveWithError ( t , cmd , sc . sqlStore )
2022-06-30 08:31:54 -05:00
assert . Equal ( t , dashboards . ErrDashboardTypeMismatch , err )
2021-03-17 10:06:10 -05:00
} )
permissionScenario ( t , "When updating existing dashboard to a folder using uid" , canSave ,
func ( t * testing . T , sc * permissionScenarioContext ) {
2023-01-16 09:33:55 -06:00
cmd := dashboards . SaveDashboardCommand {
OrgID : 1 ,
2023-08-30 10:46:47 -05:00
Dashboard : simplejson . NewFromAny ( map [ string ] any {
2023-01-16 09:33:55 -06:00
"uid" : sc . savedDashInFolder . UID ,
2021-03-17 10:06:10 -05:00
"title" : "new folder title" ,
} ) ,
IsFolder : true ,
Overwrite : shouldOverwrite ,
}
2022-11-14 13:08:10 -06:00
err := callSaveWithError ( t , cmd , sc . sqlStore )
2022-06-30 08:31:54 -05:00
assert . Equal ( t , dashboards . ErrDashboardTypeMismatch , err )
2021-03-17 10:06:10 -05:00
} )
permissionScenario ( t , "When updating existing folder to a dashboard using title" , canSave ,
func ( t * testing . T , sc * permissionScenarioContext ) {
2023-01-16 09:33:55 -06:00
cmd := dashboards . SaveDashboardCommand {
OrgID : 1 ,
2023-08-30 10:46:47 -05:00
Dashboard : simplejson . NewFromAny ( map [ string ] any {
2021-03-17 10:06:10 -05:00
"title" : sc . savedFolder . Title ,
} ) ,
IsFolder : false ,
Overwrite : shouldOverwrite ,
}
2022-11-14 13:08:10 -06:00
err := callSaveWithError ( t , cmd , sc . sqlStore )
2022-06-30 08:31:54 -05:00
assert . Equal ( t , dashboards . ErrDashboardWithSameNameAsFolder , err )
2021-03-17 10:06:10 -05:00
} )
permissionScenario ( t , "When updating existing dashboard to a folder using title" , canSave ,
func ( t * testing . T , sc * permissionScenarioContext ) {
2023-01-16 09:33:55 -06:00
cmd := dashboards . SaveDashboardCommand {
OrgID : 1 ,
2023-08-30 10:46:47 -05:00
Dashboard : simplejson . NewFromAny ( map [ string ] any {
2021-03-17 10:06:10 -05:00
"title" : sc . savedDashInGeneralFolder . Title ,
} ) ,
IsFolder : true ,
Overwrite : shouldOverwrite ,
}
2022-11-14 13:08:10 -06:00
err := callSaveWithError ( t , cmd , sc . sqlStore )
2022-06-30 08:31:54 -05:00
assert . Equal ( t , dashboards . ErrDashboardFolderWithSameNameAsDashboard , err )
2021-03-17 10:06:10 -05:00
} )
} )
} )
} )
}
type permissionScenarioContext struct {
dashboardGuardianMock * guardian . FakeDashboardGuardian
2022-10-14 14:33:06 -05:00
sqlStore db . DB
2022-06-30 08:31:54 -05:00
dashboardStore dashboards . Store
2023-01-16 09:33:55 -06:00
savedFolder * dashboards . Dashboard
savedDashInFolder * dashboards . Dashboard
otherSavedFolder * dashboards . Dashboard
savedDashInGeneralFolder * dashboards . Dashboard
2021-03-17 10:06:10 -05:00
}
type permissionScenarioFunc func ( t * testing . T , sc * permissionScenarioContext )
func permissionScenario ( t * testing . T , desc string , canSave bool , fn permissionScenarioFunc ) {
t . Helper ( )
2023-04-21 09:08:52 -05:00
guardianMock := & guardian . FakeDashboardGuardian {
2021-03-17 10:06:10 -05:00
CanSaveValue : canSave ,
}
t . Run ( desc , func ( t * testing . T ) {
2023-11-13 09:55:15 -06:00
features := featuremgmt . WithFeatures ( )
2022-08-11 08:37:31 -05:00
cfg := setting . NewCfg ( )
2022-10-19 08:02:15 -05:00
sqlStore := db . InitTestDB ( t )
2022-11-14 13:08:10 -06:00
quotaService := quotatest . New ( false , nil )
2023-04-21 09:08:52 -05:00
ac := actest . FakeAccessControl { ExpectedEvaluate : true }
2023-11-13 09:55:15 -06:00
dashboardStore , err := database . ProvideDashboardStore ( sqlStore , cfg , features , tagimpl . ProvideService ( sqlStore ) , quotaService )
2022-11-14 13:08:10 -06:00
require . NoError ( t , err )
2023-03-03 09:56:33 -06:00
folderStore := folderimpl . ProvideDashboardFolderStore ( sqlStore )
2023-04-21 09:08:52 -05:00
folderPermissions := accesscontrolmock . NewMockedPermissionsService ( )
folderPermissions . On ( "SetPermissions" , mock . Anything , mock . Anything , mock . Anything , mock . Anything ) . Return ( [ ] accesscontrol . ResourcePermission { } , nil )
dashboardPermissions := accesscontrolmock . NewMockedPermissionsService ( )
dashboardService , err := ProvideDashboardServiceImpl (
2024-03-14 09:36:35 -05:00
cfg , dashboardStore , folderStore ,
2022-06-01 13:16:26 -05:00
featuremgmt . WithFeatures ( ) ,
2023-04-21 09:08:52 -05:00
folderPermissions ,
dashboardPermissions ,
ac ,
2023-01-26 02:21:10 -06:00
foldertest . NewFakeService ( ) ,
2023-12-05 09:13:31 -06:00
nil ,
2022-06-01 13:16:26 -05:00
)
2023-04-14 04:17:23 -05:00
require . NoError ( t , err )
2023-08-28 02:49:10 -05:00
guardian . InitAccessControlGuardian ( cfg , ac , dashboardService )
2021-03-17 10:06:10 -05:00
savedFolder := saveTestFolder ( t , "Saved folder" , testOrgID , sqlStore )
2024-01-26 09:36:35 -06:00
savedDashInFolder := saveTestDashboard ( t , "Saved dash in folder" , testOrgID , savedFolder . UID , sqlStore )
saveTestDashboard ( t , "Other saved dash in folder" , testOrgID , savedFolder . UID , sqlStore )
savedDashInGeneralFolder := saveTestDashboard ( t , "Saved dashboard in general folder" , testOrgID , "" , sqlStore )
2021-03-17 10:06:10 -05:00
otherSavedFolder := saveTestFolder ( t , "Other saved folder" , testOrgID , sqlStore )
require . Equal ( t , "Saved folder" , savedFolder . Title )
require . Equal ( t , "saved-folder" , savedFolder . Slug )
2023-01-16 09:33:55 -06:00
require . NotEqual ( t , int64 ( 0 ) , savedFolder . ID )
2021-03-17 10:06:10 -05:00
require . True ( t , savedFolder . IsFolder )
2023-01-16 09:33:55 -06:00
require . NotEmpty ( t , savedFolder . UID )
2021-03-17 10:06:10 -05:00
require . Equal ( t , "Saved dash in folder" , savedDashInFolder . Title )
require . Equal ( t , "saved-dash-in-folder" , savedDashInFolder . Slug )
2023-01-16 09:33:55 -06:00
require . NotEqual ( t , int64 ( 0 ) , savedDashInFolder . ID )
2021-03-17 10:06:10 -05:00
require . False ( t , savedDashInFolder . IsFolder )
2023-01-16 09:33:55 -06:00
require . NotEmpty ( t , savedDashInFolder . UID )
2021-03-17 10:06:10 -05:00
origNewDashboardGuardian := guardian . New
t . Cleanup ( func ( ) {
guardian . New = origNewDashboardGuardian
} )
2023-04-21 09:08:52 -05:00
guardian . MockDashboardGuardian ( guardianMock )
2021-03-17 10:06:10 -05:00
sc := & permissionScenarioContext {
2023-04-21 09:08:52 -05:00
dashboardGuardianMock : guardianMock ,
2021-03-17 10:06:10 -05:00
sqlStore : sqlStore ,
savedDashInFolder : savedDashInFolder ,
otherSavedFolder : otherSavedFolder ,
savedDashInGeneralFolder : savedDashInGeneralFolder ,
savedFolder : savedFolder ,
2022-05-17 13:52:22 -05:00
dashboardStore : dashboardStore ,
2021-03-17 10:06:10 -05:00
}
fn ( t , sc )
} )
}
2023-01-16 09:33:55 -06:00
func callSaveWithResult ( t * testing . T , cmd dashboards . SaveDashboardCommand , sqlStore db . DB ) * dashboards . Dashboard {
2021-03-17 10:06:10 -05:00
t . Helper ( )
2023-11-13 09:55:15 -06:00
features := featuremgmt . WithFeatures ( )
2021-03-17 10:06:10 -05:00
dto := toSaveDashboardDto ( cmd )
2022-05-05 10:31:14 -05:00
cfg := setting . NewCfg ( )
2022-11-14 13:08:10 -06:00
quotaService := quotatest . New ( false , nil )
2023-11-13 09:55:15 -06:00
dashboardStore , err := database . ProvideDashboardStore ( sqlStore , cfg , features , tagimpl . ProvideService ( sqlStore ) , quotaService )
2022-11-14 13:08:10 -06:00
require . NoError ( t , err )
2023-03-03 09:56:33 -06:00
folderStore := folderimpl . ProvideDashboardFolderStore ( sqlStore )
2023-04-21 09:08:52 -05:00
folderPermissions := accesscontrolmock . NewMockedPermissionsService ( )
folderPermissions . On ( "SetPermissions" , mock . Anything , mock . Anything , mock . Anything , mock . Anything ) . Return ( [ ] accesscontrol . ResourcePermission { } , nil )
dashboardPermissions := accesscontrolmock . NewMockedPermissionsService ( )
dashboardPermissions . On ( "SetPermissions" , mock . Anything , mock . Anything , mock . Anything , mock . Anything ) . Return ( [ ] accesscontrol . ResourcePermission { } , nil )
2023-04-14 04:17:23 -05:00
service , err := ProvideDashboardServiceImpl (
2024-03-14 09:36:35 -05:00
cfg , dashboardStore , folderStore ,
2022-05-10 08:48:47 -05:00
featuremgmt . WithFeatures ( ) ,
2023-04-21 09:08:52 -05:00
folderPermissions ,
dashboardPermissions ,
actest . FakeAccessControl { } ,
2023-01-26 02:21:10 -06:00
foldertest . NewFakeService ( ) ,
2023-12-05 09:13:31 -06:00
nil ,
2022-03-10 05:58:18 -06:00
)
2023-04-14 04:17:23 -05:00
require . NoError ( t , err )
2022-03-10 05:58:18 -06:00
res , err := service . SaveDashboard ( context . Background ( ) , & dto , false )
2021-03-17 10:06:10 -05:00
require . NoError ( t , err )
return res
}
2023-01-16 09:33:55 -06:00
func callSaveWithError ( t * testing . T , cmd dashboards . SaveDashboardCommand , sqlStore db . DB ) error {
2023-11-13 09:55:15 -06:00
features := featuremgmt . WithFeatures ( )
2021-03-17 10:06:10 -05:00
dto := toSaveDashboardDto ( cmd )
2022-05-05 10:31:14 -05:00
cfg := setting . NewCfg ( )
2022-11-14 13:08:10 -06:00
quotaService := quotatest . New ( false , nil )
2023-11-13 09:55:15 -06:00
dashboardStore , err := database . ProvideDashboardStore ( sqlStore , cfg , features , tagimpl . ProvideService ( sqlStore ) , quotaService )
2022-11-14 13:08:10 -06:00
require . NoError ( t , err )
2023-03-03 09:56:33 -06:00
folderStore := folderimpl . ProvideDashboardFolderStore ( sqlStore )
2023-04-14 04:17:23 -05:00
service , err := ProvideDashboardServiceImpl (
2024-03-14 09:36:35 -05:00
cfg , dashboardStore , folderStore ,
2022-05-10 08:48:47 -05:00
featuremgmt . WithFeatures ( ) ,
accesscontrolmock . NewMockedPermissionsService ( ) ,
accesscontrolmock . NewMockedPermissionsService ( ) ,
2023-04-21 09:08:52 -05:00
actest . FakeAccessControl { } ,
2023-01-26 02:21:10 -06:00
foldertest . NewFakeService ( ) ,
2023-12-05 09:13:31 -06:00
nil ,
2022-03-10 05:58:18 -06:00
)
2023-04-14 04:17:23 -05:00
require . NoError ( t , err )
2022-11-14 13:08:10 -06:00
_ , err = service . SaveDashboard ( context . Background ( ) , & dto , false )
2021-03-17 10:06:10 -05:00
return err
}
2024-01-26 09:36:35 -06:00
func saveTestDashboard ( t * testing . T , title string , orgID int64 , folderUID string , sqlStore db . DB ) * dashboards . Dashboard {
2021-03-17 10:06:10 -05:00
t . Helper ( )
2023-01-16 09:33:55 -06:00
cmd := dashboards . SaveDashboardCommand {
2023-10-24 02:04:45 -05:00
OrgID : orgID ,
FolderUID : folderUID ,
IsFolder : false ,
2023-08-30 10:46:47 -05:00
Dashboard : simplejson . NewFromAny ( map [ string ] any {
2021-03-17 10:06:10 -05:00
"id" : nil ,
"title" : title ,
} ) ,
}
2022-06-30 08:31:54 -05:00
dto := dashboards . SaveDashboardDTO {
2023-01-16 09:33:55 -06:00
OrgID : orgID ,
2021-03-17 10:06:10 -05:00
Dashboard : cmd . GetDashboardModel ( ) ,
2022-08-10 04:56:48 -05:00
User : & user . SignedInUser {
2022-08-11 06:28:55 -05:00
UserID : 1 ,
2022-08-10 04:56:48 -05:00
OrgRole : org . RoleAdmin ,
2021-03-17 10:06:10 -05:00
} ,
}
2023-11-13 09:55:15 -06:00
features := featuremgmt . WithFeatures ( )
2022-05-05 10:31:14 -05:00
cfg := setting . NewCfg ( )
2022-11-14 13:08:10 -06:00
quotaService := quotatest . New ( false , nil )
2023-11-13 09:55:15 -06:00
dashboardStore , err := database . ProvideDashboardStore ( sqlStore , cfg , features , tagimpl . ProvideService ( sqlStore ) , quotaService )
2022-11-14 13:08:10 -06:00
require . NoError ( t , err )
2023-03-03 09:56:33 -06:00
folderStore := folderimpl . ProvideDashboardFolderStore ( sqlStore )
2023-04-21 09:08:52 -05:00
dashboardPermissions := accesscontrolmock . NewMockedPermissionsService ( )
dashboardPermissions . On ( "SetPermissions" , mock . Anything , mock . Anything , mock . Anything , mock . Anything ) . Return ( [ ] accesscontrol . ResourcePermission { } , nil )
2023-04-14 04:17:23 -05:00
service , err := ProvideDashboardServiceImpl (
2024-03-14 09:36:35 -05:00
cfg , dashboardStore , folderStore ,
2023-11-13 09:55:15 -06:00
features ,
2022-06-07 04:02:20 -05:00
accesscontrolmock . NewMockedPermissionsService ( ) ,
2023-04-21 09:08:52 -05:00
dashboardPermissions ,
actest . FakeAccessControl { } ,
2023-01-26 02:21:10 -06:00
foldertest . NewFakeService ( ) ,
2023-12-05 09:13:31 -06:00
nil ,
2022-03-10 05:58:18 -06:00
)
2023-04-14 04:17:23 -05:00
require . NoError ( t , err )
2022-03-10 05:58:18 -06:00
res , err := service . SaveDashboard ( context . Background ( ) , & dto , false )
2023-04-21 09:08:52 -05:00
2021-03-17 10:06:10 -05:00
require . NoError ( t , err )
return res
}
2023-01-16 09:33:55 -06:00
func saveTestFolder ( t * testing . T , title string , orgID int64 , sqlStore db . DB ) * dashboards . Dashboard {
2021-03-17 10:06:10 -05:00
t . Helper ( )
2023-01-16 09:33:55 -06:00
cmd := dashboards . SaveDashboardCommand {
2023-10-24 02:04:45 -05:00
OrgID : orgID ,
FolderUID : "" ,
IsFolder : true ,
2023-08-30 10:46:47 -05:00
Dashboard : simplejson . NewFromAny ( map [ string ] any {
2021-03-17 10:06:10 -05:00
"id" : nil ,
"title" : title ,
} ) ,
}
2022-06-30 08:31:54 -05:00
dto := dashboards . SaveDashboardDTO {
2023-01-16 09:33:55 -06:00
OrgID : orgID ,
2021-03-17 10:06:10 -05:00
Dashboard : cmd . GetDashboardModel ( ) ,
2022-08-10 04:56:48 -05:00
User : & user . SignedInUser {
2023-04-21 09:08:52 -05:00
OrgID : orgID ,
2022-08-11 06:28:55 -05:00
UserID : 1 ,
2022-08-10 04:56:48 -05:00
OrgRole : org . RoleAdmin ,
2023-04-21 09:08:52 -05:00
Permissions : map [ int64 ] map [ string ] [ ] string {
orgID : { dashboards . ActionFoldersWrite : { dashboards . ScopeFoldersAll } , dashboards . ActionDashboardsWrite : { dashboards . ScopeDashboardsAll } } ,
} ,
2021-03-17 10:06:10 -05:00
} ,
}
2023-11-13 09:55:15 -06:00
features := featuremgmt . WithFeatures ( )
2022-05-05 10:31:14 -05:00
cfg := setting . NewCfg ( )
2022-11-14 13:08:10 -06:00
quotaService := quotatest . New ( false , nil )
2023-11-13 09:55:15 -06:00
dashboardStore , err := database . ProvideDashboardStore ( sqlStore , cfg , features , tagimpl . ProvideService ( sqlStore ) , quotaService )
2022-11-14 13:08:10 -06:00
require . NoError ( t , err )
2023-03-03 09:56:33 -06:00
folderStore := folderimpl . ProvideDashboardFolderStore ( sqlStore )
2023-04-21 09:08:52 -05:00
folderPermissions := accesscontrolmock . NewMockedPermissionsService ( )
folderPermissions . On ( "SetPermissions" , mock . Anything , mock . Anything , mock . Anything , mock . Anything ) . Return ( [ ] accesscontrol . ResourcePermission { } , nil )
2023-04-14 04:17:23 -05:00
service , err := ProvideDashboardServiceImpl (
2024-03-14 09:36:35 -05:00
cfg , dashboardStore , folderStore ,
2022-05-10 08:48:47 -05:00
featuremgmt . WithFeatures ( ) ,
2023-04-21 09:08:52 -05:00
folderPermissions ,
2022-06-07 04:02:20 -05:00
accesscontrolmock . NewMockedPermissionsService ( ) ,
2023-04-21 09:08:52 -05:00
actest . FakeAccessControl { } ,
2023-01-26 02:21:10 -06:00
foldertest . NewFakeService ( ) ,
2023-12-05 09:13:31 -06:00
nil ,
2022-03-10 05:58:18 -06:00
)
2023-04-14 04:17:23 -05:00
require . NoError ( t , err )
2022-03-10 05:58:18 -06:00
res , err := service . SaveDashboard ( context . Background ( ) , & dto , false )
2021-03-17 10:06:10 -05:00
require . NoError ( t , err )
return res
}
2023-01-16 09:33:55 -06:00
func toSaveDashboardDto ( cmd dashboards . SaveDashboardCommand ) dashboards . SaveDashboardDTO {
2021-03-17 10:06:10 -05:00
dash := ( & cmd ) . GetDashboardModel ( )
2022-06-30 08:31:54 -05:00
return dashboards . SaveDashboardDTO {
2021-03-17 10:06:10 -05:00
Dashboard : dash ,
Message : cmd . Message ,
2023-01-16 09:33:55 -06:00
OrgID : cmd . OrgID ,
User : & user . SignedInUser { UserID : cmd . UserID } ,
2021-03-17 10:06:10 -05:00
Overwrite : cmd . Overwrite ,
}
}