2018-01-29 06:51:01 -06:00
package api
2018-02-20 11:11:50 -06:00
import (
2018-02-21 04:24:54 -06:00
"encoding/json"
"fmt"
"testing"
"github.com/grafana/grafana/pkg/api/dtos"
"github.com/grafana/grafana/pkg/bus"
2020-03-04 05:57:20 -06:00
"github.com/grafana/grafana/pkg/models"
2018-03-06 16:59:45 -06:00
"github.com/grafana/grafana/pkg/services/dashboards"
2019-03-06 01:09:34 -06:00
"github.com/grafana/grafana/pkg/setting"
2018-02-21 04:24:54 -06:00
. "github.com/smartystreets/goconvey/convey"
2018-02-20 11:11:50 -06:00
)
2018-02-21 04:24:54 -06:00
func TestFoldersApiEndpoint ( t * testing . T ) {
Convey ( "Create/update folder response tests" , t , func ( ) {
Convey ( "Given a correct request for creating a folder" , func ( ) {
2020-03-04 05:57:20 -06:00
cmd := models . CreateFolderCommand {
2018-02-21 04:24:54 -06:00
Uid : "uid" ,
Title : "Folder" ,
}
mock := & fakeFolderService {
2020-03-04 05:57:20 -06:00
CreateFolderResult : & models . Folder { Id : 1 , Uid : "uid" , Title : "Folder" } ,
2018-02-21 04:24:54 -06:00
}
createFolderScenario ( "When calling POST on" , "/api/folders" , "/api/folders" , mock , cmd , func ( sc * scenarioContext ) {
callCreateFolder ( sc )
Convey ( "It should return correct response data" , func ( ) {
folder := dtos . Folder { }
err := json . NewDecoder ( sc . resp . Body ) . Decode ( & folder )
So ( err , ShouldBeNil )
So ( folder . Id , ShouldEqual , 1 )
So ( folder . Uid , ShouldEqual , "uid" )
So ( folder . Title , ShouldEqual , "Folder" )
} )
} )
} )
Convey ( "Given incorrect requests for creating a folder" , func ( ) {
testCases := [ ] struct {
Error error
ExpectedStatusCode int
} {
2020-03-04 05:57:20 -06:00
{ Error : models . ErrFolderWithSameUIDExists , ExpectedStatusCode : 400 } ,
{ Error : models . ErrFolderTitleEmpty , ExpectedStatusCode : 400 } ,
{ Error : models . ErrFolderSameNameExists , ExpectedStatusCode : 400 } ,
{ Error : models . ErrDashboardInvalidUid , ExpectedStatusCode : 400 } ,
2020-07-21 04:12:01 -05:00
{ Error : models . ErrDashboardUidTooLong , ExpectedStatusCode : 400 } ,
2020-03-04 05:57:20 -06:00
{ Error : models . ErrFolderAccessDenied , ExpectedStatusCode : 403 } ,
{ Error : models . ErrFolderNotFound , ExpectedStatusCode : 404 } ,
{ Error : models . ErrFolderVersionMismatch , ExpectedStatusCode : 412 } ,
{ Error : models . ErrFolderFailedGenerateUniqueUid , ExpectedStatusCode : 500 } ,
2018-02-21 04:24:54 -06:00
}
2020-03-04 05:57:20 -06:00
cmd := models . CreateFolderCommand {
2018-02-21 04:24:54 -06:00
Uid : "uid" ,
Title : "Folder" ,
}
for _ , tc := range testCases {
mock := & fakeFolderService {
CreateFolderError : tc . Error ,
}
createFolderScenario ( fmt . Sprintf ( "Expect '%s' error when calling POST on" , tc . Error . Error ( ) ) , "/api/folders" , "/api/folders" , mock , cmd , func ( sc * scenarioContext ) {
callCreateFolder ( sc )
if sc . resp . Code != tc . ExpectedStatusCode {
t . Errorf ( "For error '%s' expected status code %d, actual %d" , tc . Error , tc . ExpectedStatusCode , sc . resp . Code )
}
} )
}
} )
Convey ( "Given a correct request for updating a folder" , func ( ) {
2020-03-04 05:57:20 -06:00
cmd := models . UpdateFolderCommand {
2018-02-21 04:24:54 -06:00
Title : "Folder upd" ,
}
mock := & fakeFolderService {
2020-03-04 05:57:20 -06:00
UpdateFolderResult : & models . Folder { Id : 1 , Uid : "uid" , Title : "Folder upd" } ,
2018-02-21 04:24:54 -06:00
}
updateFolderScenario ( "When calling PUT on" , "/api/folders/uid" , "/api/folders/:uid" , mock , cmd , func ( sc * scenarioContext ) {
callUpdateFolder ( sc )
Convey ( "It should return correct response data" , func ( ) {
folder := dtos . Folder { }
err := json . NewDecoder ( sc . resp . Body ) . Decode ( & folder )
So ( err , ShouldBeNil )
So ( folder . Id , ShouldEqual , 1 )
So ( folder . Uid , ShouldEqual , "uid" )
So ( folder . Title , ShouldEqual , "Folder upd" )
} )
} )
} )
Convey ( "Given incorrect requests for updating a folder" , func ( ) {
testCases := [ ] struct {
Error error
ExpectedStatusCode int
} {
2020-03-04 05:57:20 -06:00
{ Error : models . ErrFolderWithSameUIDExists , ExpectedStatusCode : 400 } ,
{ Error : models . ErrFolderTitleEmpty , ExpectedStatusCode : 400 } ,
{ Error : models . ErrFolderSameNameExists , ExpectedStatusCode : 400 } ,
{ Error : models . ErrDashboardInvalidUid , ExpectedStatusCode : 400 } ,
2020-07-21 04:12:01 -05:00
{ Error : models . ErrDashboardUidTooLong , ExpectedStatusCode : 400 } ,
2020-03-04 05:57:20 -06:00
{ Error : models . ErrFolderAccessDenied , ExpectedStatusCode : 403 } ,
{ Error : models . ErrFolderNotFound , ExpectedStatusCode : 404 } ,
{ Error : models . ErrFolderVersionMismatch , ExpectedStatusCode : 412 } ,
{ Error : models . ErrFolderFailedGenerateUniqueUid , ExpectedStatusCode : 500 } ,
2018-02-21 04:24:54 -06:00
}
2020-03-04 05:57:20 -06:00
cmd := models . UpdateFolderCommand {
2018-02-21 04:24:54 -06:00
Title : "Folder upd" ,
}
for _ , tc := range testCases {
mock := & fakeFolderService {
UpdateFolderError : tc . Error ,
}
updateFolderScenario ( fmt . Sprintf ( "Expect '%s' error when calling PUT on" , tc . Error . Error ( ) ) , "/api/folders/uid" , "/api/folders/:uid" , mock , cmd , func ( sc * scenarioContext ) {
callUpdateFolder ( sc )
if sc . resp . Code != tc . ExpectedStatusCode {
t . Errorf ( "For error '%s' expected status code %d, actual %d" , tc . Error , tc . ExpectedStatusCode , sc . resp . Code )
}
} )
}
} )
} )
}
func callCreateFolder ( sc * scenarioContext ) {
sc . fakeReqWithParams ( "POST" , sc . url , map [ string ] string { } ) . exec ( )
}
2020-03-04 05:57:20 -06:00
func createFolderScenario ( desc string , url string , routePattern string , mock * fakeFolderService , cmd models . CreateFolderCommand , fn scenarioFunc ) {
2018-02-21 04:24:54 -06:00
Convey ( desc + " " + url , func ( ) {
defer bus . ClearBusHandlers ( )
2019-03-06 01:09:34 -06:00
hs := HTTPServer {
Bus : bus . GetBus ( ) ,
2019-03-12 07:59:53 -05:00
Cfg : setting . NewCfg ( ) ,
2019-03-06 01:09:34 -06:00
}
2018-02-21 04:24:54 -06:00
sc := setupScenarioContext ( url )
2020-03-04 05:57:20 -06:00
sc . defaultHandler = Wrap ( func ( c * models . ReqContext ) Response {
2018-02-21 04:24:54 -06:00
sc . context = c
2020-03-04 05:57:20 -06:00
sc . context . SignedInUser = & models . SignedInUser { OrgId : TestOrgID , UserId : TestUserID }
2018-02-21 04:24:54 -06:00
2019-03-06 01:09:34 -06:00
return hs . CreateFolder ( c , cmd )
2018-02-21 04:24:54 -06:00
} )
origNewFolderService := dashboards . NewFolderService
mockFolderService ( mock )
sc . m . Post ( routePattern , sc . defaultHandler )
2018-02-20 06:57:32 -06:00
2018-02-21 04:24:54 -06:00
defer func ( ) {
dashboards . NewFolderService = origNewFolderService
} ( )
2018-02-20 06:57:32 -06:00
2018-02-21 04:24:54 -06:00
fn ( sc )
} )
}
func callUpdateFolder ( sc * scenarioContext ) {
sc . fakeReqWithParams ( "PUT" , sc . url , map [ string ] string { } ) . exec ( )
}
2018-02-20 06:57:32 -06:00
2020-03-04 05:57:20 -06:00
func updateFolderScenario ( desc string , url string , routePattern string , mock * fakeFolderService , cmd models . UpdateFolderCommand , fn scenarioFunc ) {
2018-02-21 04:24:54 -06:00
Convey ( desc + " " + url , func ( ) {
defer bus . ClearBusHandlers ( )
2018-01-29 06:51:01 -06:00
2018-02-21 04:24:54 -06:00
sc := setupScenarioContext ( url )
2020-03-04 05:57:20 -06:00
sc . defaultHandler = Wrap ( func ( c * models . ReqContext ) Response {
2018-02-21 04:24:54 -06:00
sc . context = c
2020-03-04 05:57:20 -06:00
sc . context . SignedInUser = & models . SignedInUser { OrgId : TestOrgID , UserId : TestUserID }
2018-02-20 06:57:32 -06:00
2018-02-21 04:24:54 -06:00
return UpdateFolder ( c , cmd )
} )
2018-02-20 06:57:32 -06:00
2018-02-21 04:24:54 -06:00
origNewFolderService := dashboards . NewFolderService
mockFolderService ( mock )
2018-02-20 06:57:32 -06:00
2018-02-21 04:24:54 -06:00
sc . m . Put ( routePattern , sc . defaultHandler )
2018-02-20 06:57:32 -06:00
2018-02-21 04:24:54 -06:00
defer func ( ) {
dashboards . NewFolderService = origNewFolderService
} ( )
fn ( sc )
} )
}
2018-02-20 11:11:50 -06:00
type fakeFolderService struct {
2020-03-04 05:57:20 -06:00
GetFoldersResult [ ] * models . Folder
2018-02-20 11:11:50 -06:00
GetFoldersError error
2020-03-04 05:57:20 -06:00
GetFolderByUIDResult * models . Folder
2018-03-22 16:13:46 -05:00
GetFolderByUIDError error
2020-03-04 05:57:20 -06:00
GetFolderByIDResult * models . Folder
2018-03-22 16:13:46 -05:00
GetFolderByIDError error
2020-03-04 05:57:20 -06:00
CreateFolderResult * models . Folder
2018-02-20 11:11:50 -06:00
CreateFolderError error
2020-03-04 05:57:20 -06:00
UpdateFolderResult * models . Folder
2018-02-20 11:11:50 -06:00
UpdateFolderError error
2020-03-04 05:57:20 -06:00
DeleteFolderResult * models . Folder
2018-02-20 11:11:50 -06:00
DeleteFolderError error
DeletedFolderUids [ ] string
}
2020-03-04 05:57:20 -06:00
func ( s * fakeFolderService ) GetFolders ( limit int64 ) ( [ ] * models . Folder , error ) {
2018-02-20 11:11:50 -06:00
return s . GetFoldersResult , s . GetFoldersError
}
2020-03-04 05:57:20 -06:00
func ( s * fakeFolderService ) GetFolderByID ( id int64 ) ( * models . Folder , error ) {
2018-03-22 16:13:46 -05:00
return s . GetFolderByIDResult , s . GetFolderByIDError
2018-02-20 11:11:50 -06:00
}
2020-03-04 05:57:20 -06:00
func ( s * fakeFolderService ) GetFolderByUID ( uid string ) ( * models . Folder , error ) {
2018-03-22 16:13:46 -05:00
return s . GetFolderByUIDResult , s . GetFolderByUIDError
2018-02-20 11:11:50 -06:00
}
2020-03-04 05:57:20 -06:00
func ( s * fakeFolderService ) CreateFolder ( cmd * models . CreateFolderCommand ) error {
2018-02-21 04:24:54 -06:00
cmd . Result = s . CreateFolderResult
2018-02-20 11:11:50 -06:00
return s . CreateFolderError
}
2020-03-04 05:57:20 -06:00
func ( s * fakeFolderService ) UpdateFolder ( existingUID string , cmd * models . UpdateFolderCommand ) error {
2018-02-21 04:24:54 -06:00
cmd . Result = s . UpdateFolderResult
2018-02-20 11:11:50 -06:00
return s . UpdateFolderError
}
2020-03-04 05:57:20 -06:00
func ( s * fakeFolderService ) DeleteFolder ( uid string ) ( * models . Folder , error ) {
2018-02-20 11:11:50 -06:00
s . DeletedFolderUids = append ( s . DeletedFolderUids , uid )
return s . DeleteFolderResult , s . DeleteFolderError
}
func mockFolderService ( mock * fakeFolderService ) {
2020-03-04 05:57:20 -06:00
dashboards . NewFolderService = func ( orgId int64 , user * models . SignedInUser ) dashboards . FolderService {
2018-02-20 11:11:50 -06:00
return mock
}
}