mirror of https://github.com/grafana/grafana.git
				
				
				
			
		
			
				
	
	
		
			930 lines
		
	
	
		
			32 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			930 lines
		
	
	
		
			32 KiB
		
	
	
	
		
			Go
		
	
	
	
| //go:build integration
 | |
| // +build integration
 | |
| 
 | |
| package dashboards
 | |
| 
 | |
| import (
 | |
| 	"testing"
 | |
| 
 | |
| 	"github.com/grafana/grafana/pkg/components/simplejson"
 | |
| 	"github.com/grafana/grafana/pkg/dashboards"
 | |
| 	"github.com/grafana/grafana/pkg/services/guardian"
 | |
| 	"github.com/grafana/grafana/pkg/services/sqlstore"
 | |
| 	"github.com/stretchr/testify/assert"
 | |
| 	"github.com/stretchr/testify/require"
 | |
| 
 | |
| 	"github.com/grafana/grafana/pkg/models"
 | |
| )
 | |
| 
 | |
| const testOrgID int64 = 1
 | |
| 
 | |
| func TestIntegratedDashboardService(t *testing.T) {
 | |
| 	t.Run("Given saved folders and dashboards in organization A", func(t *testing.T) {
 | |
| 		origUpdateAlerting := UpdateAlerting
 | |
| 		t.Cleanup(func() {
 | |
| 			UpdateAlerting = origUpdateAlerting
 | |
| 		})
 | |
| 		UpdateAlerting = func(store dashboards.Store, orgID int64, dashboard *models.Dashboard, user *models.SignedInUser) error {
 | |
| 			return nil
 | |
| 		}
 | |
| 
 | |
| 		// Basic validation tests
 | |
| 
 | |
| 		permissionScenario(t, "When saving a dashboard with non-existing id", true,
 | |
| 			func(t *testing.T, sc *permissionScenarioContext) {
 | |
| 				cmd := models.SaveDashboardCommand{
 | |
| 					OrgId: testOrgID,
 | |
| 					Dashboard: simplejson.NewFromAny(map[string]interface{}{
 | |
| 						"id":    float64(123412321),
 | |
| 						"title": "Expect error",
 | |
| 					}),
 | |
| 				}
 | |
| 
 | |
| 				err := callSaveWithError(cmd, sc.sqlStore)
 | |
| 				assert.Equal(t, models.ErrDashboardNotFound, err)
 | |
| 			})
 | |
| 
 | |
| 		// 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) {
 | |
| 					cmd := models.SaveDashboardCommand{
 | |
| 						OrgId: otherOrgId,
 | |
| 						Dashboard: simplejson.NewFromAny(map[string]interface{}{
 | |
| 							"id":    sc.savedDashInFolder.Id,
 | |
| 							"title": "Expect error",
 | |
| 						}),
 | |
| 						Overwrite: false,
 | |
| 					}
 | |
| 
 | |
| 					err := callSaveWithError(cmd, sc.sqlStore)
 | |
| 					assert.Equal(t, models.ErrDashboardNotFound, err)
 | |
| 				})
 | |
| 
 | |
| 			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
 | |
| 					cmd := models.SaveDashboardCommand{
 | |
| 						OrgId: otherOrgId,
 | |
| 						Dashboard: simplejson.NewFromAny(map[string]interface{}{
 | |
| 							"uid":   sc.savedDashInFolder.Uid,
 | |
| 							"title": "Dash with existing uid in other org",
 | |
| 						}),
 | |
| 						Overwrite: false,
 | |
| 					}
 | |
| 
 | |
| 					res := callSaveWithResult(t, cmd, sc.sqlStore)
 | |
| 					require.NotNil(t, res)
 | |
| 
 | |
| 					dash, err := sc.sqlStore.GetDashboard(0, otherOrgId, sc.savedDashInFolder.Uid, "")
 | |
| 					require.NoError(t, err)
 | |
| 
 | |
| 					assert.NotEqual(t, sc.savedDashInFolder.Id, dash.Id)
 | |
| 					assert.Equal(t, res.Id, dash.Id)
 | |
| 					assert.Equal(t, otherOrgId, dash.OrgId)
 | |
| 					assert.Equal(t, sc.savedDashInFolder.Uid, dash.Uid)
 | |
| 				})
 | |
| 		})
 | |
| 
 | |
| 		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) {
 | |
| 					sqlStore := sqlstore.InitTestDB(t)
 | |
| 					cmd := models.SaveDashboardCommand{
 | |
| 						OrgId: testOrgID,
 | |
| 						Dashboard: simplejson.NewFromAny(map[string]interface{}{
 | |
| 							"title": "Dash",
 | |
| 						}),
 | |
| 						UserId:    10000,
 | |
| 						Overwrite: true,
 | |
| 					}
 | |
| 
 | |
| 					err := callSaveWithError(cmd, sqlStore)
 | |
| 					assert.Equal(t, models.ErrDashboardUpdateAccessDenied, err)
 | |
| 
 | |
| 					assert.Equal(t, int64(0), sc.dashboardGuardianMock.DashId)
 | |
| 					assert.Equal(t, cmd.OrgId, sc.dashboardGuardianMock.OrgId)
 | |
| 					assert.Equal(t, cmd.UserId, sc.dashboardGuardianMock.User.UserId)
 | |
| 				})
 | |
| 
 | |
| 			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) {
 | |
| 					cmd := models.SaveDashboardCommand{
 | |
| 						OrgId: testOrgID,
 | |
| 						Dashboard: simplejson.NewFromAny(map[string]interface{}{
 | |
| 							"title": "Dash",
 | |
| 						}),
 | |
| 						FolderId:  sc.otherSavedFolder.Id,
 | |
| 						UserId:    10000,
 | |
| 						Overwrite: true,
 | |
| 					}
 | |
| 
 | |
| 					err := callSaveWithError(cmd, sc.sqlStore)
 | |
| 					require.Equal(t, models.ErrDashboardUpdateAccessDenied, err)
 | |
| 
 | |
| 					assert.Equal(t, sc.otherSavedFolder.Id, sc.dashboardGuardianMock.DashId)
 | |
| 					assert.Equal(t, cmd.OrgId, sc.dashboardGuardianMock.OrgId)
 | |
| 					assert.Equal(t, cmd.UserId, sc.dashboardGuardianMock.User.UserId)
 | |
| 				})
 | |
| 
 | |
| 			permissionScenario(t, "When creating a new dashboard by existing title in folder, it should create dashboard guardian for folder with correct arguments and result in access denied error",
 | |
| 				canSave, func(t *testing.T, sc *permissionScenarioContext) {
 | |
| 					cmd := models.SaveDashboardCommand{
 | |
| 						OrgId: testOrgID,
 | |
| 						Dashboard: simplejson.NewFromAny(map[string]interface{}{
 | |
| 							"title": sc.savedDashInFolder.Title,
 | |
| 						}),
 | |
| 						FolderId:  sc.savedFolder.Id,
 | |
| 						UserId:    10000,
 | |
| 						Overwrite: true,
 | |
| 					}
 | |
| 
 | |
| 					err := callSaveWithError(cmd, sc.sqlStore)
 | |
| 					require.Equal(t, models.ErrDashboardUpdateAccessDenied, err)
 | |
| 
 | |
| 					assert.Equal(t, sc.savedFolder.Id, sc.dashboardGuardianMock.DashId)
 | |
| 					assert.Equal(t, cmd.OrgId, sc.dashboardGuardianMock.OrgId)
 | |
| 					assert.Equal(t, cmd.UserId, sc.dashboardGuardianMock.User.UserId)
 | |
| 				})
 | |
| 
 | |
| 			permissionScenario(t, "When creating a new dashboard by existing UID in folder, it should create dashboard guardian for folder with correct arguments and result in access denied error",
 | |
| 				canSave, func(t *testing.T, sc *permissionScenarioContext) {
 | |
| 					cmd := models.SaveDashboardCommand{
 | |
| 						OrgId: testOrgID,
 | |
| 						Dashboard: simplejson.NewFromAny(map[string]interface{}{
 | |
| 							"uid":   sc.savedDashInFolder.Uid,
 | |
| 							"title": "New dash",
 | |
| 						}),
 | |
| 						FolderId:  sc.savedFolder.Id,
 | |
| 						UserId:    10000,
 | |
| 						Overwrite: true,
 | |
| 					}
 | |
| 
 | |
| 					err := callSaveWithError(cmd, sc.sqlStore)
 | |
| 					require.Equal(t, models.ErrDashboardUpdateAccessDenied, err)
 | |
| 
 | |
| 					assert.Equal(t, sc.savedFolder.Id, sc.dashboardGuardianMock.DashId)
 | |
| 					assert.Equal(t, cmd.OrgId, sc.dashboardGuardianMock.OrgId)
 | |
| 					assert.Equal(t, cmd.UserId, sc.dashboardGuardianMock.User.UserId)
 | |
| 				})
 | |
| 
 | |
| 			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) {
 | |
| 					cmd := models.SaveDashboardCommand{
 | |
| 						OrgId: testOrgID,
 | |
| 						Dashboard: simplejson.NewFromAny(map[string]interface{}{
 | |
| 							"id":    sc.savedDashInGeneralFolder.Id,
 | |
| 							"title": "Dash",
 | |
| 						}),
 | |
| 						FolderId:  sc.savedDashInGeneralFolder.FolderId,
 | |
| 						UserId:    10000,
 | |
| 						Overwrite: true,
 | |
| 					}
 | |
| 
 | |
| 					err := callSaveWithError(cmd, sc.sqlStore)
 | |
| 					assert.Equal(t, models.ErrDashboardUpdateAccessDenied, err)
 | |
| 
 | |
| 					assert.Equal(t, sc.savedDashInGeneralFolder.Id, sc.dashboardGuardianMock.DashId)
 | |
| 					assert.Equal(t, cmd.OrgId, sc.dashboardGuardianMock.OrgId)
 | |
| 					assert.Equal(t, cmd.UserId, sc.dashboardGuardianMock.User.UserId)
 | |
| 				})
 | |
| 
 | |
| 			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) {
 | |
| 					cmd := models.SaveDashboardCommand{
 | |
| 						OrgId: testOrgID,
 | |
| 						Dashboard: simplejson.NewFromAny(map[string]interface{}{
 | |
| 							"id":    sc.savedDashInFolder.Id,
 | |
| 							"title": "Dash",
 | |
| 						}),
 | |
| 						FolderId:  sc.savedDashInFolder.FolderId,
 | |
| 						UserId:    10000,
 | |
| 						Overwrite: true,
 | |
| 					}
 | |
| 
 | |
| 					err := callSaveWithError(cmd, sc.sqlStore)
 | |
| 					require.Equal(t, models.ErrDashboardUpdateAccessDenied, err)
 | |
| 
 | |
| 					assert.Equal(t, sc.savedDashInFolder.Id, sc.dashboardGuardianMock.DashId)
 | |
| 					assert.Equal(t, cmd.OrgId, sc.dashboardGuardianMock.OrgId)
 | |
| 					assert.Equal(t, cmd.UserId, sc.dashboardGuardianMock.User.UserId)
 | |
| 				})
 | |
| 
 | |
| 			permissionScenario(t, "When moving a dashboard by existing ID to other folder from General folder, it should create dashboard guardian for other folder with correct arguments and result in access denied error",
 | |
| 				canSave, func(t *testing.T, sc *permissionScenarioContext) {
 | |
| 					cmd := models.SaveDashboardCommand{
 | |
| 						OrgId: testOrgID,
 | |
| 						Dashboard: simplejson.NewFromAny(map[string]interface{}{
 | |
| 							"id":    sc.savedDashInGeneralFolder.Id,
 | |
| 							"title": "Dash",
 | |
| 						}),
 | |
| 						FolderId:  sc.otherSavedFolder.Id,
 | |
| 						UserId:    10000,
 | |
| 						Overwrite: true,
 | |
| 					}
 | |
| 
 | |
| 					err := callSaveWithError(cmd, sc.sqlStore)
 | |
| 					require.Equal(t, models.ErrDashboardUpdateAccessDenied, err)
 | |
| 
 | |
| 					assert.Equal(t, sc.otherSavedFolder.Id, sc.dashboardGuardianMock.DashId)
 | |
| 					assert.Equal(t, cmd.OrgId, sc.dashboardGuardianMock.OrgId)
 | |
| 					assert.Equal(t, cmd.UserId, sc.dashboardGuardianMock.User.UserId)
 | |
| 				})
 | |
| 
 | |
| 			permissionScenario(t, "When moving a dashboard by existing id to the General folder from other folder, it should create dashboard guardian for General folder with correct arguments and result in access denied error",
 | |
| 				canSave, func(t *testing.T, sc *permissionScenarioContext) {
 | |
| 					cmd := models.SaveDashboardCommand{
 | |
| 						OrgId: testOrgID,
 | |
| 						Dashboard: simplejson.NewFromAny(map[string]interface{}{
 | |
| 							"id":    sc.savedDashInFolder.Id,
 | |
| 							"title": "Dash",
 | |
| 						}),
 | |
| 						FolderId:  0,
 | |
| 						UserId:    10000,
 | |
| 						Overwrite: true,
 | |
| 					}
 | |
| 
 | |
| 					err := callSaveWithError(cmd, sc.sqlStore)
 | |
| 					assert.Equal(t, models.ErrDashboardUpdateAccessDenied, err)
 | |
| 
 | |
| 					assert.Equal(t, int64(0), sc.dashboardGuardianMock.DashId)
 | |
| 					assert.Equal(t, cmd.OrgId, sc.dashboardGuardianMock.OrgId)
 | |
| 					assert.Equal(t, cmd.UserId, sc.dashboardGuardianMock.User.UserId)
 | |
| 				})
 | |
| 
 | |
| 			permissionScenario(t, "When moving a dashboard by existing uid to other folder from General folder, it should create dashboard guardian for other folder with correct arguments and result in access denied error",
 | |
| 				canSave, func(t *testing.T, sc *permissionScenarioContext) {
 | |
| 					cmd := models.SaveDashboardCommand{
 | |
| 						OrgId: testOrgID,
 | |
| 						Dashboard: simplejson.NewFromAny(map[string]interface{}{
 | |
| 							"uid":   sc.savedDashInGeneralFolder.Uid,
 | |
| 							"title": "Dash",
 | |
| 						}),
 | |
| 						FolderId:  sc.otherSavedFolder.Id,
 | |
| 						UserId:    10000,
 | |
| 						Overwrite: true,
 | |
| 					}
 | |
| 
 | |
| 					err := callSaveWithError(cmd, sc.sqlStore)
 | |
| 					require.Equal(t, models.ErrDashboardUpdateAccessDenied, err)
 | |
| 
 | |
| 					assert.Equal(t, sc.otherSavedFolder.Id, sc.dashboardGuardianMock.DashId)
 | |
| 					assert.Equal(t, cmd.OrgId, sc.dashboardGuardianMock.OrgId)
 | |
| 					assert.Equal(t, cmd.UserId, sc.dashboardGuardianMock.User.UserId)
 | |
| 				})
 | |
| 
 | |
| 			permissionScenario(t, "When moving a dashboard by existing UID to the General folder from other folder, it should create dashboard guardian for General folder with correct arguments and result in access denied error",
 | |
| 				canSave, func(t *testing.T, sc *permissionScenarioContext) {
 | |
| 					cmd := models.SaveDashboardCommand{
 | |
| 						OrgId: testOrgID,
 | |
| 						Dashboard: simplejson.NewFromAny(map[string]interface{}{
 | |
| 							"uid":   sc.savedDashInFolder.Uid,
 | |
| 							"title": "Dash",
 | |
| 						}),
 | |
| 						FolderId:  0,
 | |
| 						UserId:    10000,
 | |
| 						Overwrite: true,
 | |
| 					}
 | |
| 
 | |
| 					err := callSaveWithError(cmd, sc.sqlStore)
 | |
| 					require.Equal(t, models.ErrDashboardUpdateAccessDenied, err)
 | |
| 
 | |
| 					assert.Equal(t, int64(0), sc.dashboardGuardianMock.DashId)
 | |
| 					assert.Equal(t, cmd.OrgId, sc.dashboardGuardianMock.OrgId)
 | |
| 					assert.Equal(t, cmd.UserId, sc.dashboardGuardianMock.User.UserId)
 | |
| 				})
 | |
| 		})
 | |
| 
 | |
| 		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) {
 | |
| 						cmd := models.SaveDashboardCommand{
 | |
| 							OrgId: testOrgID,
 | |
| 							Dashboard: simplejson.NewFromAny(map[string]interface{}{
 | |
| 								"id":    nil,
 | |
| 								"title": sc.savedDashInFolder.Title,
 | |
| 							}),
 | |
| 							FolderId:  0,
 | |
| 							Overwrite: shouldOverwrite,
 | |
| 						}
 | |
| 
 | |
| 						res := callSaveWithResult(t, cmd, sc.sqlStore)
 | |
| 						require.NotNil(t, res)
 | |
| 
 | |
| 						dash, err := sc.sqlStore.GetDashboard(res.Id, cmd.OrgId, "", "")
 | |
| 						require.NoError(t, err)
 | |
| 						assert.Equal(t, res.Id, dash.Id)
 | |
| 						assert.Equal(t, int64(0), dash.FolderId)
 | |
| 					})
 | |
| 
 | |
| 				permissionScenario(t, "When creating a dashboard in other folder with same name as dashboard in General folder",
 | |
| 					canSave, func(t *testing.T, sc *permissionScenarioContext) {
 | |
| 						cmd := models.SaveDashboardCommand{
 | |
| 							OrgId: testOrgID,
 | |
| 							Dashboard: simplejson.NewFromAny(map[string]interface{}{
 | |
| 								"id":    nil,
 | |
| 								"title": sc.savedDashInGeneralFolder.Title,
 | |
| 							}),
 | |
| 							FolderId:  sc.savedFolder.Id,
 | |
| 							Overwrite: shouldOverwrite,
 | |
| 						}
 | |
| 
 | |
| 						res := callSaveWithResult(t, cmd, sc.sqlStore)
 | |
| 						require.NotNil(t, res)
 | |
| 
 | |
| 						assert.NotEqual(t, sc.savedDashInGeneralFolder.Id, res.Id)
 | |
| 
 | |
| 						dash, err := sc.sqlStore.GetDashboard(res.Id, cmd.OrgId, "", "")
 | |
| 						require.NoError(t, err)
 | |
| 						assert.Equal(t, sc.savedFolder.Id, dash.FolderId)
 | |
| 					})
 | |
| 
 | |
| 				permissionScenario(t, "When creating a folder with same name as dashboard in other folder",
 | |
| 					canSave, func(t *testing.T, sc *permissionScenarioContext) {
 | |
| 						cmd := models.SaveDashboardCommand{
 | |
| 							OrgId: testOrgID,
 | |
| 							Dashboard: simplejson.NewFromAny(map[string]interface{}{
 | |
| 								"id":    nil,
 | |
| 								"title": sc.savedDashInFolder.Title,
 | |
| 							}),
 | |
| 							IsFolder:  true,
 | |
| 							Overwrite: shouldOverwrite,
 | |
| 						}
 | |
| 
 | |
| 						res := callSaveWithResult(t, cmd, sc.sqlStore)
 | |
| 						require.NotNil(t, res)
 | |
| 
 | |
| 						assert.NotEqual(t, sc.savedDashInGeneralFolder.Id, res.Id)
 | |
| 						assert.True(t, res.IsFolder)
 | |
| 
 | |
| 						dash, err := sc.sqlStore.GetDashboard(res.Id, cmd.OrgId, "", "")
 | |
| 						require.NoError(t, err)
 | |
| 						assert.Equal(t, int64(0), dash.FolderId)
 | |
| 						assert.True(t, dash.IsFolder)
 | |
| 					})
 | |
| 
 | |
| 				permissionScenario(t, "When saving a dashboard without id and uid and unique title in folder",
 | |
| 					canSave, func(t *testing.T, sc *permissionScenarioContext) {
 | |
| 						cmd := models.SaveDashboardCommand{
 | |
| 							OrgId: testOrgID,
 | |
| 							Dashboard: simplejson.NewFromAny(map[string]interface{}{
 | |
| 								"title": "Dash without id and uid",
 | |
| 							}),
 | |
| 							Overwrite: shouldOverwrite,
 | |
| 						}
 | |
| 
 | |
| 						res := callSaveWithResult(t, cmd, sc.sqlStore)
 | |
| 						require.NotNil(t, res)
 | |
| 
 | |
| 						assert.Greater(t, res.Id, int64(0))
 | |
| 						assert.NotEmpty(t, res.Uid)
 | |
| 						dash, err := sc.sqlStore.GetDashboard(res.Id, cmd.OrgId, "", "")
 | |
| 						require.NoError(t, err)
 | |
| 						assert.Equal(t, res.Id, dash.Id)
 | |
| 						assert.Equal(t, res.Uid, dash.Uid)
 | |
| 					})
 | |
| 
 | |
| 				permissionScenario(t, "When saving a dashboard when dashboard id is zero ", canSave,
 | |
| 					func(t *testing.T, sc *permissionScenarioContext) {
 | |
| 						cmd := models.SaveDashboardCommand{
 | |
| 							OrgId: testOrgID,
 | |
| 							Dashboard: simplejson.NewFromAny(map[string]interface{}{
 | |
| 								"id":    0,
 | |
| 								"title": "Dash with zero id",
 | |
| 							}),
 | |
| 							Overwrite: shouldOverwrite,
 | |
| 						}
 | |
| 
 | |
| 						res := callSaveWithResult(t, cmd, sc.sqlStore)
 | |
| 						require.NotNil(t, res)
 | |
| 
 | |
| 						dash, err := sc.sqlStore.GetDashboard(res.Id, cmd.OrgId, "", "")
 | |
| 						require.NoError(t, err)
 | |
| 						assert.Equal(t, res.Id, dash.Id)
 | |
| 					})
 | |
| 
 | |
| 				permissionScenario(t, "When saving a dashboard in non-existing folder", canSave,
 | |
| 					func(t *testing.T, sc *permissionScenarioContext) {
 | |
| 						cmd := models.SaveDashboardCommand{
 | |
| 							OrgId: testOrgID,
 | |
| 							Dashboard: simplejson.NewFromAny(map[string]interface{}{
 | |
| 								"title": "Expect error",
 | |
| 							}),
 | |
| 							FolderId:  123412321,
 | |
| 							Overwrite: shouldOverwrite,
 | |
| 						}
 | |
| 
 | |
| 						err := callSaveWithError(cmd, sc.sqlStore)
 | |
| 						assert.Equal(t, models.ErrDashboardFolderNotFound, err)
 | |
| 					})
 | |
| 
 | |
| 				permissionScenario(t, "When updating an existing dashboard by id without current version", canSave,
 | |
| 					func(t *testing.T, sc *permissionScenarioContext) {
 | |
| 						cmd := models.SaveDashboardCommand{
 | |
| 							OrgId: 1,
 | |
| 							Dashboard: simplejson.NewFromAny(map[string]interface{}{
 | |
| 								"id":    sc.savedDashInGeneralFolder.Id,
 | |
| 								"title": "test dash 23",
 | |
| 							}),
 | |
| 							FolderId:  sc.savedFolder.Id,
 | |
| 							Overwrite: shouldOverwrite,
 | |
| 						}
 | |
| 
 | |
| 						err := callSaveWithError(cmd, sc.sqlStore)
 | |
| 						assert.Equal(t, models.ErrDashboardVersionMismatch, err)
 | |
| 					})
 | |
| 
 | |
| 				permissionScenario(t, "When updating an existing dashboard by id with current version", canSave,
 | |
| 					func(t *testing.T, sc *permissionScenarioContext) {
 | |
| 						cmd := models.SaveDashboardCommand{
 | |
| 							OrgId: 1,
 | |
| 							Dashboard: simplejson.NewFromAny(map[string]interface{}{
 | |
| 								"id":      sc.savedDashInGeneralFolder.Id,
 | |
| 								"title":   "Updated title",
 | |
| 								"version": sc.savedDashInGeneralFolder.Version,
 | |
| 							}),
 | |
| 							FolderId:  sc.savedFolder.Id,
 | |
| 							Overwrite: shouldOverwrite,
 | |
| 						}
 | |
| 
 | |
| 						res := callSaveWithResult(t, cmd, sc.sqlStore)
 | |
| 						require.NotNil(t, res)
 | |
| 
 | |
| 						dash, err := sc.sqlStore.GetDashboard(sc.savedDashInGeneralFolder.Id, cmd.OrgId, "", "")
 | |
| 						require.NoError(t, err)
 | |
| 						assert.Equal(t, "Updated title", dash.Title)
 | |
| 						assert.Equal(t, sc.savedFolder.Id, dash.FolderId)
 | |
| 						assert.Greater(t, dash.Version, sc.savedDashInGeneralFolder.Version)
 | |
| 					})
 | |
| 
 | |
| 				permissionScenario(t, "When updating an existing dashboard by uid without current version", canSave,
 | |
| 					func(t *testing.T, sc *permissionScenarioContext) {
 | |
| 						cmd := models.SaveDashboardCommand{
 | |
| 							OrgId: 1,
 | |
| 							Dashboard: simplejson.NewFromAny(map[string]interface{}{
 | |
| 								"uid":   sc.savedDashInFolder.Uid,
 | |
| 								"title": "test dash 23",
 | |
| 							}),
 | |
| 							FolderId:  0,
 | |
| 							Overwrite: shouldOverwrite,
 | |
| 						}
 | |
| 
 | |
| 						err := callSaveWithError(cmd, sc.sqlStore)
 | |
| 						assert.Equal(t, models.ErrDashboardVersionMismatch, err)
 | |
| 					})
 | |
| 
 | |
| 				permissionScenario(t, "When updating an existing dashboard by uid with current version", canSave,
 | |
| 					func(t *testing.T, sc *permissionScenarioContext) {
 | |
| 						cmd := models.SaveDashboardCommand{
 | |
| 							OrgId: 1,
 | |
| 							Dashboard: simplejson.NewFromAny(map[string]interface{}{
 | |
| 								"uid":     sc.savedDashInFolder.Uid,
 | |
| 								"title":   "Updated title",
 | |
| 								"version": sc.savedDashInFolder.Version,
 | |
| 							}),
 | |
| 							FolderId:  0,
 | |
| 							Overwrite: shouldOverwrite,
 | |
| 						}
 | |
| 
 | |
| 						res := callSaveWithResult(t, cmd, sc.sqlStore)
 | |
| 						require.NotNil(t, res)
 | |
| 
 | |
| 						dash, err := sc.sqlStore.GetDashboard(sc.savedDashInFolder.Id, cmd.OrgId, "", "")
 | |
| 						require.NoError(t, err)
 | |
| 						assert.Equal(t, "Updated title", dash.Title)
 | |
| 						assert.Equal(t, int64(0), dash.FolderId)
 | |
| 						assert.Greater(t, dash.Version, sc.savedDashInFolder.Version)
 | |
| 					})
 | |
| 
 | |
| 				permissionScenario(t, "When creating a dashboard with same name as dashboard in other folder",
 | |
| 					canSave, func(t *testing.T, sc *permissionScenarioContext) {
 | |
| 						cmd := models.SaveDashboardCommand{
 | |
| 							OrgId: testOrgID,
 | |
| 							Dashboard: simplejson.NewFromAny(map[string]interface{}{
 | |
| 								"id":    nil,
 | |
| 								"title": sc.savedDashInFolder.Title,
 | |
| 							}),
 | |
| 							FolderId:  sc.savedDashInFolder.FolderId,
 | |
| 							Overwrite: shouldOverwrite,
 | |
| 						}
 | |
| 
 | |
| 						err := callSaveWithError(cmd, sc.sqlStore)
 | |
| 						assert.Equal(t, models.ErrDashboardWithSameNameInFolderExists, err)
 | |
| 					})
 | |
| 
 | |
| 				permissionScenario(t, "When creating a dashboard with same name as dashboard in General folder",
 | |
| 					canSave, func(t *testing.T, sc *permissionScenarioContext) {
 | |
| 						cmd := models.SaveDashboardCommand{
 | |
| 							OrgId: testOrgID,
 | |
| 							Dashboard: simplejson.NewFromAny(map[string]interface{}{
 | |
| 								"id":    nil,
 | |
| 								"title": sc.savedDashInGeneralFolder.Title,
 | |
| 							}),
 | |
| 							FolderId:  sc.savedDashInGeneralFolder.FolderId,
 | |
| 							Overwrite: shouldOverwrite,
 | |
| 						}
 | |
| 
 | |
| 						err := callSaveWithError(cmd, sc.sqlStore)
 | |
| 						assert.Equal(t, models.ErrDashboardWithSameNameInFolderExists, err)
 | |
| 					})
 | |
| 
 | |
| 				permissionScenario(t, "When creating a folder with same name as existing folder", canSave,
 | |
| 					func(t *testing.T, sc *permissionScenarioContext) {
 | |
| 						cmd := models.SaveDashboardCommand{
 | |
| 							OrgId: testOrgID,
 | |
| 							Dashboard: simplejson.NewFromAny(map[string]interface{}{
 | |
| 								"id":    nil,
 | |
| 								"title": sc.savedFolder.Title,
 | |
| 							}),
 | |
| 							IsFolder:  true,
 | |
| 							Overwrite: shouldOverwrite,
 | |
| 						}
 | |
| 
 | |
| 						err := callSaveWithError(cmd, sc.sqlStore)
 | |
| 						assert.Equal(t, models.ErrDashboardWithSameNameInFolderExists, err)
 | |
| 					})
 | |
| 			})
 | |
| 
 | |
| 			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) {
 | |
| 						cmd := models.SaveDashboardCommand{
 | |
| 							OrgId: 1,
 | |
| 							Dashboard: simplejson.NewFromAny(map[string]interface{}{
 | |
| 								"id":    sc.savedDashInGeneralFolder.Id,
 | |
| 								"title": "Updated title",
 | |
| 							}),
 | |
| 							FolderId:  sc.savedFolder.Id,
 | |
| 							Overwrite: shouldOverwrite,
 | |
| 						}
 | |
| 
 | |
| 						res := callSaveWithResult(t, cmd, sc.sqlStore)
 | |
| 						require.NotNil(t, res)
 | |
| 
 | |
| 						dash, err := sc.sqlStore.GetDashboard(sc.savedDashInGeneralFolder.Id, cmd.OrgId, "", "")
 | |
| 						require.NoError(t, err)
 | |
| 						assert.Equal(t, "Updated title", dash.Title)
 | |
| 						assert.Equal(t, sc.savedFolder.Id, dash.FolderId)
 | |
| 						assert.Greater(t, dash.Version, sc.savedDashInGeneralFolder.Version)
 | |
| 					})
 | |
| 
 | |
| 				permissionScenario(t, "When updating an existing dashboard by uid without current version", canSave,
 | |
| 					func(t *testing.T, sc *permissionScenarioContext) {
 | |
| 						cmd := models.SaveDashboardCommand{
 | |
| 							OrgId: 1,
 | |
| 							Dashboard: simplejson.NewFromAny(map[string]interface{}{
 | |
| 								"uid":   sc.savedDashInFolder.Uid,
 | |
| 								"title": "Updated title",
 | |
| 							}),
 | |
| 							FolderId:  0,
 | |
| 							Overwrite: shouldOverwrite,
 | |
| 						}
 | |
| 
 | |
| 						res := callSaveWithResult(t, cmd, sc.sqlStore)
 | |
| 						require.NotNil(t, res)
 | |
| 
 | |
| 						dash, err := sc.sqlStore.GetDashboard(sc.savedDashInFolder.Id, cmd.OrgId, "", "")
 | |
| 						require.NoError(t, err)
 | |
| 						assert.Equal(t, "Updated title", dash.Title)
 | |
| 						assert.Equal(t, int64(0), dash.FolderId)
 | |
| 						assert.Greater(t, dash.Version, sc.savedDashInFolder.Version)
 | |
| 					})
 | |
| 
 | |
| 				permissionScenario(t, "When updating uid for existing dashboard using id", canSave,
 | |
| 					func(t *testing.T, sc *permissionScenarioContext) {
 | |
| 						cmd := models.SaveDashboardCommand{
 | |
| 							OrgId: 1,
 | |
| 							Dashboard: simplejson.NewFromAny(map[string]interface{}{
 | |
| 								"id":    sc.savedDashInFolder.Id,
 | |
| 								"uid":   "new-uid",
 | |
| 								"title": sc.savedDashInFolder.Title,
 | |
| 							}),
 | |
| 							Overwrite: shouldOverwrite,
 | |
| 						}
 | |
| 
 | |
| 						res := callSaveWithResult(t, cmd, sc.sqlStore)
 | |
| 						require.NotNil(t, res)
 | |
| 						assert.Equal(t, sc.savedDashInFolder.Id, res.Id)
 | |
| 						assert.Equal(t, "new-uid", res.Uid)
 | |
| 
 | |
| 						dash, err := sc.sqlStore.GetDashboard(sc.savedDashInFolder.Id, cmd.OrgId, "", "")
 | |
| 						require.NoError(t, err)
 | |
| 						assert.Equal(t, "new-uid", dash.Uid)
 | |
| 						assert.Greater(t, dash.Version, sc.savedDashInFolder.Version)
 | |
| 					})
 | |
| 
 | |
| 				permissionScenario(t, "When updating uid to an existing uid for existing dashboard using id", canSave,
 | |
| 					func(t *testing.T, sc *permissionScenarioContext) {
 | |
| 						cmd := models.SaveDashboardCommand{
 | |
| 							OrgId: 1,
 | |
| 							Dashboard: simplejson.NewFromAny(map[string]interface{}{
 | |
| 								"id":    sc.savedDashInFolder.Id,
 | |
| 								"uid":   sc.savedDashInGeneralFolder.Uid,
 | |
| 								"title": sc.savedDashInFolder.Title,
 | |
| 							}),
 | |
| 							Overwrite: shouldOverwrite,
 | |
| 						}
 | |
| 
 | |
| 						err := callSaveWithError(cmd, sc.sqlStore)
 | |
| 						assert.Equal(t, models.ErrDashboardWithSameUIDExists, err)
 | |
| 					})
 | |
| 
 | |
| 				permissionScenario(t, "When creating a dashboard with same name as dashboard in other folder", canSave,
 | |
| 					func(t *testing.T, sc *permissionScenarioContext) {
 | |
| 						cmd := models.SaveDashboardCommand{
 | |
| 							OrgId: testOrgID,
 | |
| 							Dashboard: simplejson.NewFromAny(map[string]interface{}{
 | |
| 								"id":    nil,
 | |
| 								"title": sc.savedDashInFolder.Title,
 | |
| 							}),
 | |
| 							FolderId:  sc.savedDashInFolder.FolderId,
 | |
| 							Overwrite: shouldOverwrite,
 | |
| 						}
 | |
| 
 | |
| 						res := callSaveWithResult(t, cmd, sc.sqlStore)
 | |
| 						require.NotNil(t, res)
 | |
| 						assert.Equal(t, sc.savedDashInFolder.Id, res.Id)
 | |
| 						assert.Equal(t, sc.savedDashInFolder.Uid, res.Uid)
 | |
| 
 | |
| 						dash, err := sc.sqlStore.GetDashboard(res.Id, cmd.OrgId, "", "")
 | |
| 						require.NoError(t, err)
 | |
| 						assert.Equal(t, res.Id, dash.Id)
 | |
| 						assert.Equal(t, res.Uid, dash.Uid)
 | |
| 					})
 | |
| 
 | |
| 				permissionScenario(t, "When creating a dashboard with same name as dashboard in General folder", canSave,
 | |
| 					func(t *testing.T, sc *permissionScenarioContext) {
 | |
| 						cmd := models.SaveDashboardCommand{
 | |
| 							OrgId: testOrgID,
 | |
| 							Dashboard: simplejson.NewFromAny(map[string]interface{}{
 | |
| 								"id":    nil,
 | |
| 								"title": sc.savedDashInGeneralFolder.Title,
 | |
| 							}),
 | |
| 							FolderId:  sc.savedDashInGeneralFolder.FolderId,
 | |
| 							Overwrite: shouldOverwrite,
 | |
| 						}
 | |
| 
 | |
| 						res := callSaveWithResult(t, cmd, sc.sqlStore)
 | |
| 						require.NotNil(t, res)
 | |
| 						assert.Equal(t, sc.savedDashInGeneralFolder.Id, res.Id)
 | |
| 						assert.Equal(t, sc.savedDashInGeneralFolder.Uid, res.Uid)
 | |
| 
 | |
| 						dash, err := sc.sqlStore.GetDashboard(res.Id, cmd.OrgId, "", "")
 | |
| 						require.NoError(t, err)
 | |
| 						assert.Equal(t, res.Id, dash.Id)
 | |
| 						assert.Equal(t, res.Uid, dash.Uid)
 | |
| 					})
 | |
| 
 | |
| 				permissionScenario(t, "When updating existing folder to a dashboard using id", canSave,
 | |
| 					func(t *testing.T, sc *permissionScenarioContext) {
 | |
| 						cmd := models.SaveDashboardCommand{
 | |
| 							OrgId: 1,
 | |
| 							Dashboard: simplejson.NewFromAny(map[string]interface{}{
 | |
| 								"id":    sc.savedFolder.Id,
 | |
| 								"title": "new title",
 | |
| 							}),
 | |
| 							IsFolder:  false,
 | |
| 							Overwrite: shouldOverwrite,
 | |
| 						}
 | |
| 
 | |
| 						err := callSaveWithError(cmd, sc.sqlStore)
 | |
| 						assert.Equal(t, models.ErrDashboardTypeMismatch, err)
 | |
| 					})
 | |
| 
 | |
| 				permissionScenario(t, "When updating existing dashboard to a folder using id", canSave,
 | |
| 					func(t *testing.T, sc *permissionScenarioContext) {
 | |
| 						cmd := models.SaveDashboardCommand{
 | |
| 							OrgId: 1,
 | |
| 							Dashboard: simplejson.NewFromAny(map[string]interface{}{
 | |
| 								"id":    sc.savedDashInFolder.Id,
 | |
| 								"title": "new folder title",
 | |
| 							}),
 | |
| 							IsFolder:  true,
 | |
| 							Overwrite: shouldOverwrite,
 | |
| 						}
 | |
| 
 | |
| 						err := callSaveWithError(cmd, sc.sqlStore)
 | |
| 						assert.Equal(t, models.ErrDashboardTypeMismatch, err)
 | |
| 					})
 | |
| 
 | |
| 				permissionScenario(t, "When updating existing folder to a dashboard using uid", canSave,
 | |
| 					func(t *testing.T, sc *permissionScenarioContext) {
 | |
| 						cmd := models.SaveDashboardCommand{
 | |
| 							OrgId: 1,
 | |
| 							Dashboard: simplejson.NewFromAny(map[string]interface{}{
 | |
| 								"uid":   sc.savedFolder.Uid,
 | |
| 								"title": "new title",
 | |
| 							}),
 | |
| 							IsFolder:  false,
 | |
| 							Overwrite: shouldOverwrite,
 | |
| 						}
 | |
| 
 | |
| 						err := callSaveWithError(cmd, sc.sqlStore)
 | |
| 						assert.Equal(t, models.ErrDashboardTypeMismatch, err)
 | |
| 					})
 | |
| 
 | |
| 				permissionScenario(t, "When updating existing dashboard to a folder using uid", canSave,
 | |
| 					func(t *testing.T, sc *permissionScenarioContext) {
 | |
| 						cmd := models.SaveDashboardCommand{
 | |
| 							OrgId: 1,
 | |
| 							Dashboard: simplejson.NewFromAny(map[string]interface{}{
 | |
| 								"uid":   sc.savedDashInFolder.Uid,
 | |
| 								"title": "new folder title",
 | |
| 							}),
 | |
| 							IsFolder:  true,
 | |
| 							Overwrite: shouldOverwrite,
 | |
| 						}
 | |
| 
 | |
| 						err := callSaveWithError(cmd, sc.sqlStore)
 | |
| 						assert.Equal(t, models.ErrDashboardTypeMismatch, err)
 | |
| 					})
 | |
| 
 | |
| 				permissionScenario(t, "When updating existing folder to a dashboard using title", canSave,
 | |
| 					func(t *testing.T, sc *permissionScenarioContext) {
 | |
| 						cmd := models.SaveDashboardCommand{
 | |
| 							OrgId: 1,
 | |
| 							Dashboard: simplejson.NewFromAny(map[string]interface{}{
 | |
| 								"title": sc.savedFolder.Title,
 | |
| 							}),
 | |
| 							IsFolder:  false,
 | |
| 							Overwrite: shouldOverwrite,
 | |
| 						}
 | |
| 
 | |
| 						err := callSaveWithError(cmd, sc.sqlStore)
 | |
| 						assert.Equal(t, models.ErrDashboardWithSameNameAsFolder, err)
 | |
| 					})
 | |
| 
 | |
| 				permissionScenario(t, "When updating existing dashboard to a folder using title", canSave,
 | |
| 					func(t *testing.T, sc *permissionScenarioContext) {
 | |
| 						cmd := models.SaveDashboardCommand{
 | |
| 							OrgId: 1,
 | |
| 							Dashboard: simplejson.NewFromAny(map[string]interface{}{
 | |
| 								"title": sc.savedDashInGeneralFolder.Title,
 | |
| 							}),
 | |
| 							IsFolder:  true,
 | |
| 							Overwrite: shouldOverwrite,
 | |
| 						}
 | |
| 
 | |
| 						err := callSaveWithError(cmd, sc.sqlStore)
 | |
| 						assert.Equal(t, models.ErrDashboardFolderWithSameNameAsDashboard, err)
 | |
| 					})
 | |
| 			})
 | |
| 		})
 | |
| 	})
 | |
| }
 | |
| 
 | |
| type permissionScenarioContext struct {
 | |
| 	dashboardGuardianMock    *guardian.FakeDashboardGuardian
 | |
| 	sqlStore                 *sqlstore.SQLStore
 | |
| 	savedFolder              *models.Dashboard
 | |
| 	savedDashInFolder        *models.Dashboard
 | |
| 	otherSavedFolder         *models.Dashboard
 | |
| 	savedDashInGeneralFolder *models.Dashboard
 | |
| }
 | |
| 
 | |
| type permissionScenarioFunc func(t *testing.T, sc *permissionScenarioContext)
 | |
| 
 | |
| func permissionScenario(t *testing.T, desc string, canSave bool, fn permissionScenarioFunc) {
 | |
| 	t.Helper()
 | |
| 
 | |
| 	mock := &guardian.FakeDashboardGuardian{
 | |
| 		CanSaveValue: canSave,
 | |
| 	}
 | |
| 
 | |
| 	t.Run(desc, func(t *testing.T) {
 | |
| 		sqlStore := sqlstore.InitTestDB(t)
 | |
| 
 | |
| 		savedFolder := saveTestFolder(t, "Saved folder", testOrgID, sqlStore)
 | |
| 		savedDashInFolder := saveTestDashboard(t, "Saved dash in folder", testOrgID, savedFolder.Id, sqlStore)
 | |
| 		saveTestDashboard(t, "Other saved dash in folder", testOrgID, savedFolder.Id, sqlStore)
 | |
| 		savedDashInGeneralFolder := saveTestDashboard(t, "Saved dashboard in general folder", testOrgID, 0, sqlStore)
 | |
| 		otherSavedFolder := saveTestFolder(t, "Other saved folder", testOrgID, sqlStore)
 | |
| 
 | |
| 		require.Equal(t, "Saved folder", savedFolder.Title)
 | |
| 		require.Equal(t, "saved-folder", savedFolder.Slug)
 | |
| 		require.NotEqual(t, int64(0), savedFolder.Id)
 | |
| 		require.True(t, savedFolder.IsFolder)
 | |
| 		require.Equal(t, int64(0), savedFolder.FolderId)
 | |
| 		require.NotEmpty(t, savedFolder.Uid)
 | |
| 
 | |
| 		require.Equal(t, "Saved dash in folder", savedDashInFolder.Title)
 | |
| 		require.Equal(t, "saved-dash-in-folder", savedDashInFolder.Slug)
 | |
| 		require.NotEqual(t, int64(0), savedDashInFolder.Id)
 | |
| 		require.False(t, savedDashInFolder.IsFolder)
 | |
| 		require.Equal(t, savedFolder.Id, savedDashInFolder.FolderId)
 | |
| 		require.NotEmpty(t, savedDashInFolder.Uid)
 | |
| 
 | |
| 		origNewDashboardGuardian := guardian.New
 | |
| 		t.Cleanup(func() {
 | |
| 			guardian.New = origNewDashboardGuardian
 | |
| 		})
 | |
| 		guardian.MockDashboardGuardian(mock)
 | |
| 
 | |
| 		sc := &permissionScenarioContext{
 | |
| 			dashboardGuardianMock:    mock,
 | |
| 			sqlStore:                 sqlStore,
 | |
| 			savedDashInFolder:        savedDashInFolder,
 | |
| 			otherSavedFolder:         otherSavedFolder,
 | |
| 			savedDashInGeneralFolder: savedDashInGeneralFolder,
 | |
| 			savedFolder:              savedFolder,
 | |
| 		}
 | |
| 
 | |
| 		fn(t, sc)
 | |
| 	})
 | |
| }
 | |
| 
 | |
| func callSaveWithResult(t *testing.T, cmd models.SaveDashboardCommand, sqlStore *sqlstore.SQLStore) *models.Dashboard {
 | |
| 	t.Helper()
 | |
| 
 | |
| 	dto := toSaveDashboardDto(cmd)
 | |
| 	res, err := NewService(sqlStore).SaveDashboard(&dto, false)
 | |
| 	require.NoError(t, err)
 | |
| 
 | |
| 	return res
 | |
| }
 | |
| 
 | |
| func callSaveWithError(cmd models.SaveDashboardCommand, sqlStore *sqlstore.SQLStore) error {
 | |
| 	dto := toSaveDashboardDto(cmd)
 | |
| 	_, err := NewService(sqlStore).SaveDashboard(&dto, false)
 | |
| 	return err
 | |
| }
 | |
| 
 | |
| func saveTestDashboard(t *testing.T, title string, orgID, folderID int64, sqlStore *sqlstore.SQLStore) *models.Dashboard {
 | |
| 	t.Helper()
 | |
| 
 | |
| 	cmd := models.SaveDashboardCommand{
 | |
| 		OrgId:    orgID,
 | |
| 		FolderId: folderID,
 | |
| 		IsFolder: false,
 | |
| 		Dashboard: simplejson.NewFromAny(map[string]interface{}{
 | |
| 			"id":    nil,
 | |
| 			"title": title,
 | |
| 		}),
 | |
| 	}
 | |
| 
 | |
| 	dto := SaveDashboardDTO{
 | |
| 		OrgId:     orgID,
 | |
| 		Dashboard: cmd.GetDashboardModel(),
 | |
| 		User: &models.SignedInUser{
 | |
| 			UserId:  1,
 | |
| 			OrgRole: models.ROLE_ADMIN,
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	res, err := NewService(sqlStore).SaveDashboard(&dto, false)
 | |
| 	require.NoError(t, err)
 | |
| 
 | |
| 	return res
 | |
| }
 | |
| 
 | |
| func saveTestFolder(t *testing.T, title string, orgID int64, sqlStore *sqlstore.SQLStore) *models.Dashboard {
 | |
| 	t.Helper()
 | |
| 	cmd := models.SaveDashboardCommand{
 | |
| 		OrgId:    orgID,
 | |
| 		FolderId: 0,
 | |
| 		IsFolder: true,
 | |
| 		Dashboard: simplejson.NewFromAny(map[string]interface{}{
 | |
| 			"id":    nil,
 | |
| 			"title": title,
 | |
| 		}),
 | |
| 	}
 | |
| 
 | |
| 	dto := SaveDashboardDTO{
 | |
| 		OrgId:     orgID,
 | |
| 		Dashboard: cmd.GetDashboardModel(),
 | |
| 		User: &models.SignedInUser{
 | |
| 			UserId:  1,
 | |
| 			OrgRole: models.ROLE_ADMIN,
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	res, err := NewService(sqlStore).SaveDashboard(&dto, false)
 | |
| 	require.NoError(t, err)
 | |
| 
 | |
| 	return res
 | |
| }
 | |
| 
 | |
| func toSaveDashboardDto(cmd models.SaveDashboardCommand) SaveDashboardDTO {
 | |
| 	dash := (&cmd).GetDashboardModel()
 | |
| 
 | |
| 	return SaveDashboardDTO{
 | |
| 		Dashboard: dash,
 | |
| 		Message:   cmd.Message,
 | |
| 		OrgId:     cmd.OrgId,
 | |
| 		User:      &models.SignedInUser{UserId: cmd.UserId},
 | |
| 		Overwrite: cmd.Overwrite,
 | |
| 	}
 | |
| }
 |