2017-12-20 17:52:21 -06:00
package api
import (
"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"
2017-12-20 17:52:21 -06:00
"github.com/grafana/grafana/pkg/services/annotations"
. "github.com/smartystreets/goconvey/convey"
)
func TestAnnotationsApiEndpoint ( t * testing . T ) {
Convey ( "Given an annotation without a dashboard id" , t , func ( ) {
cmd := dtos . PostAnnotationsCmd {
2019-08-16 03:49:30 -05:00
Time : 1000 ,
Text : "annotation text" ,
Tags : [ ] string { "tag1" , "tag2" } ,
2017-12-20 17:52:21 -06:00
}
updateCmd := dtos . UpdateAnnotationsCmd {
2019-08-16 03:49:30 -05:00
Time : 1000 ,
Text : "annotation text" ,
Tags : [ ] string { "tag1" , "tag2" } ,
2017-12-20 17:52:21 -06:00
}
2019-01-27 05:49:22 -06:00
patchCmd := dtos . PatchAnnotationsCmd {
Time : 1000 ,
Text : "annotation text" ,
Tags : [ ] string { "tag1" , "tag2" } ,
}
2017-12-20 17:52:21 -06:00
Convey ( "When user is an Org Viewer" , func ( ) {
2020-03-04 05:57:20 -06:00
role := models . ROLE_VIEWER
2017-12-20 17:52:21 -06:00
Convey ( "Should not be allowed to save an annotation" , func ( ) {
postAnnotationScenario ( "When calling POST on" , "/api/annotations" , "/api/annotations" , role , cmd , func ( sc * scenarioContext ) {
sc . fakeReqWithParams ( "POST" , sc . url , map [ string ] string { } ) . exec ( )
So ( sc . resp . Code , ShouldEqual , 403 )
} )
putAnnotationScenario ( "When calling PUT on" , "/api/annotations/1" , "/api/annotations/:annotationId" , role , updateCmd , func ( sc * scenarioContext ) {
sc . fakeReqWithParams ( "PUT" , sc . url , map [ string ] string { } ) . exec ( )
So ( sc . resp . Code , ShouldEqual , 403 )
} )
2019-01-27 05:49:22 -06:00
patchAnnotationScenario ( "When calling PATCH on" , "/api/annotations/1" , "/api/annotations/:annotationId" , role , patchCmd , func ( sc * scenarioContext ) {
sc . fakeReqWithParams ( "PATCH" , sc . url , map [ string ] string { } ) . exec ( )
So ( sc . resp . Code , ShouldEqual , 403 )
} )
2017-12-20 17:52:21 -06:00
loggedInUserScenarioWithRole ( "When calling DELETE on" , "DELETE" , "/api/annotations/1" , "/api/annotations/:annotationId" , role , func ( sc * scenarioContext ) {
2018-03-22 16:13:46 -05:00
sc . handlerFunc = DeleteAnnotationByID
2017-12-20 17:52:21 -06:00
sc . fakeReqWithParams ( "DELETE" , sc . url , map [ string ] string { } ) . exec ( )
So ( sc . resp . Code , ShouldEqual , 403 )
} )
} )
} )
Convey ( "When user is an Org Editor" , func ( ) {
2020-03-04 05:57:20 -06:00
role := models . ROLE_EDITOR
2017-12-20 17:52:21 -06:00
Convey ( "Should be able to save an annotation" , func ( ) {
postAnnotationScenario ( "When calling POST on" , "/api/annotations" , "/api/annotations" , role , cmd , func ( sc * scenarioContext ) {
sc . fakeReqWithParams ( "POST" , sc . url , map [ string ] string { } ) . exec ( )
So ( sc . resp . Code , ShouldEqual , 200 )
} )
putAnnotationScenario ( "When calling PUT on" , "/api/annotations/1" , "/api/annotations/:annotationId" , role , updateCmd , func ( sc * scenarioContext ) {
sc . fakeReqWithParams ( "PUT" , sc . url , map [ string ] string { } ) . exec ( )
So ( sc . resp . Code , ShouldEqual , 200 )
} )
2019-01-27 05:49:22 -06:00
patchAnnotationScenario ( "When calling PATCH on" , "/api/annotations/1" , "/api/annotations/:annotationId" , role , patchCmd , func ( sc * scenarioContext ) {
sc . fakeReqWithParams ( "PATCH" , sc . url , map [ string ] string { } ) . exec ( )
So ( sc . resp . Code , ShouldEqual , 200 )
} )
2017-12-20 17:52:21 -06:00
loggedInUserScenarioWithRole ( "When calling DELETE on" , "DELETE" , "/api/annotations/1" , "/api/annotations/:annotationId" , role , func ( sc * scenarioContext ) {
2018-03-22 16:13:46 -05:00
sc . handlerFunc = DeleteAnnotationByID
2017-12-20 17:52:21 -06:00
sc . fakeReqWithParams ( "DELETE" , sc . url , map [ string ] string { } ) . exec ( )
So ( sc . resp . Code , ShouldEqual , 200 )
} )
} )
} )
} )
Convey ( "Given an annotation with a dashboard id and the dashboard does not have an acl" , t , func ( ) {
cmd := dtos . PostAnnotationsCmd {
Time : 1000 ,
Text : "annotation text" ,
Tags : [ ] string { "tag1" , "tag2" } ,
DashboardId : 1 ,
PanelId : 1 ,
}
updateCmd := dtos . UpdateAnnotationsCmd {
2019-08-16 03:49:30 -05:00
Time : 1000 ,
Text : "annotation text" ,
Tags : [ ] string { "tag1" , "tag2" } ,
Id : 1 ,
2017-12-20 17:52:21 -06:00
}
2019-01-27 05:49:22 -06:00
patchCmd := dtos . PatchAnnotationsCmd {
Time : 8000 ,
Text : "annotation text 50" ,
Tags : [ ] string { "foo" , "bar" } ,
Id : 1 ,
}
2018-06-25 06:58:49 -05:00
deleteCmd := dtos . DeleteAnnotationsCmd {
DashboardId : 1 ,
PanelId : 1 ,
}
2020-03-04 05:57:20 -06:00
viewerRole := models . ROLE_VIEWER
editorRole := models . ROLE_EDITOR
2017-12-20 17:52:21 -06:00
2020-03-04 05:57:20 -06:00
aclMockResp := [ ] * models . DashboardAclInfoDTO {
{ Role : & viewerRole , Permission : models . PERMISSION_VIEW } ,
{ Role : & editorRole , Permission : models . PERMISSION_EDIT } ,
2017-12-20 17:52:21 -06:00
}
2020-03-04 05:57:20 -06:00
bus . AddHandler ( "test" , func ( query * models . GetDashboardAclInfoListQuery ) error {
2017-12-20 17:52:21 -06:00
query . Result = aclMockResp
return nil
} )
2020-03-04 05:57:20 -06:00
bus . AddHandler ( "test" , func ( query * models . GetTeamsByUserQuery ) error {
query . Result = [ ] * models . TeamDTO { }
2017-12-20 17:52:21 -06:00
return nil
} )
Convey ( "When user is an Org Viewer" , func ( ) {
2020-03-04 05:57:20 -06:00
role := models . ROLE_VIEWER
2017-12-20 17:52:21 -06:00
Convey ( "Should not be allowed to save an annotation" , func ( ) {
postAnnotationScenario ( "When calling POST on" , "/api/annotations" , "/api/annotations" , role , cmd , func ( sc * scenarioContext ) {
sc . fakeReqWithParams ( "POST" , sc . url , map [ string ] string { } ) . exec ( )
So ( sc . resp . Code , ShouldEqual , 403 )
} )
putAnnotationScenario ( "When calling PUT on" , "/api/annotations/1" , "/api/annotations/:annotationId" , role , updateCmd , func ( sc * scenarioContext ) {
sc . fakeReqWithParams ( "PUT" , sc . url , map [ string ] string { } ) . exec ( )
So ( sc . resp . Code , ShouldEqual , 403 )
} )
2019-01-27 05:49:22 -06:00
patchAnnotationScenario ( "When calling PATCH on" , "/api/annotations/1" , "/api/annotations/:annotationId" , role , patchCmd , func ( sc * scenarioContext ) {
sc . fakeReqWithParams ( "PATCH" , sc . url , map [ string ] string { } ) . exec ( )
So ( sc . resp . Code , ShouldEqual , 403 )
} )
2017-12-20 17:52:21 -06:00
loggedInUserScenarioWithRole ( "When calling DELETE on" , "DELETE" , "/api/annotations/1" , "/api/annotations/:annotationId" , role , func ( sc * scenarioContext ) {
2018-03-22 16:13:46 -05:00
sc . handlerFunc = DeleteAnnotationByID
2017-12-20 17:52:21 -06:00
sc . fakeReqWithParams ( "DELETE" , sc . url , map [ string ] string { } ) . exec ( )
So ( sc . resp . Code , ShouldEqual , 403 )
} )
} )
} )
Convey ( "When user is an Org Editor" , func ( ) {
2020-03-04 05:57:20 -06:00
role := models . ROLE_EDITOR
2017-12-20 17:52:21 -06:00
Convey ( "Should be able to save an annotation" , func ( ) {
postAnnotationScenario ( "When calling POST on" , "/api/annotations" , "/api/annotations" , role , cmd , func ( sc * scenarioContext ) {
sc . fakeReqWithParams ( "POST" , sc . url , map [ string ] string { } ) . exec ( )
So ( sc . resp . Code , ShouldEqual , 200 )
} )
putAnnotationScenario ( "When calling PUT on" , "/api/annotations/1" , "/api/annotations/:annotationId" , role , updateCmd , func ( sc * scenarioContext ) {
sc . fakeReqWithParams ( "PUT" , sc . url , map [ string ] string { } ) . exec ( )
So ( sc . resp . Code , ShouldEqual , 200 )
} )
2019-01-27 05:49:22 -06:00
patchAnnotationScenario ( "When calling PATCH on" , "/api/annotations/1" , "/api/annotations/:annotationId" , role , patchCmd , func ( sc * scenarioContext ) {
sc . fakeReqWithParams ( "PATCH" , sc . url , map [ string ] string { } ) . exec ( )
So ( sc . resp . Code , ShouldEqual , 200 )
} )
2017-12-20 17:52:21 -06:00
loggedInUserScenarioWithRole ( "When calling DELETE on" , "DELETE" , "/api/annotations/1" , "/api/annotations/:annotationId" , role , func ( sc * scenarioContext ) {
2018-03-22 16:13:46 -05:00
sc . handlerFunc = DeleteAnnotationByID
2017-12-20 17:52:21 -06:00
sc . fakeReqWithParams ( "DELETE" , sc . url , map [ string ] string { } ) . exec ( )
So ( sc . resp . Code , ShouldEqual , 200 )
} )
} )
} )
2018-06-25 06:58:49 -05:00
Convey ( "When user is an Admin" , func ( ) {
2020-03-04 05:57:20 -06:00
role := models . ROLE_ADMIN
2018-06-25 06:58:49 -05:00
Convey ( "Should be able to do anything" , func ( ) {
postAnnotationScenario ( "When calling POST on" , "/api/annotations" , "/api/annotations" , role , cmd , func ( sc * scenarioContext ) {
sc . fakeReqWithParams ( "POST" , sc . url , map [ string ] string { } ) . exec ( )
So ( sc . resp . Code , ShouldEqual , 200 )
} )
putAnnotationScenario ( "When calling PUT on" , "/api/annotations/1" , "/api/annotations/:annotationId" , role , updateCmd , func ( sc * scenarioContext ) {
sc . fakeReqWithParams ( "PUT" , sc . url , map [ string ] string { } ) . exec ( )
So ( sc . resp . Code , ShouldEqual , 200 )
} )
2019-01-27 05:49:22 -06:00
patchAnnotationScenario ( "When calling PATCH on" , "/api/annotations/1" , "/api/annotations/:annotationId" , role , patchCmd , func ( sc * scenarioContext ) {
sc . fakeReqWithParams ( "PATCH" , sc . url , map [ string ] string { } ) . exec ( )
So ( sc . resp . Code , ShouldEqual , 200 )
} )
2018-06-25 06:58:49 -05:00
deleteAnnotationsScenario ( "When calling POST on" , "/api/annotations/mass-delete" , "/api/annotations/mass-delete" , role , deleteCmd , func ( sc * scenarioContext ) {
sc . fakeReqWithParams ( "POST" , sc . url , map [ string ] string { } ) . exec ( )
So ( sc . resp . Code , ShouldEqual , 200 )
} )
} )
} )
2017-12-20 17:52:21 -06:00
} )
}
type fakeAnnotationsRepo struct {
}
func ( repo * fakeAnnotationsRepo ) Delete ( params * annotations . DeleteParams ) error {
return nil
}
func ( repo * fakeAnnotationsRepo ) Save ( item * annotations . Item ) error {
item . Id = 1
return nil
}
func ( repo * fakeAnnotationsRepo ) Update ( item * annotations . Item ) error {
return nil
}
func ( repo * fakeAnnotationsRepo ) Find ( query * annotations . ItemQuery ) ( [ ] * annotations . ItemDTO , error ) {
2017-12-21 01:34:57 -06:00
annotations := [ ] * annotations . ItemDTO { { Id : 1 } }
2017-12-20 17:52:21 -06:00
return annotations , nil
}
var fakeAnnoRepo * fakeAnnotationsRepo
2020-03-04 05:57:20 -06:00
func postAnnotationScenario ( desc string , url string , routePattern string , role models . RoleType , cmd dtos . PostAnnotationsCmd , fn scenarioFunc ) {
2017-12-20 17:52:21 -06:00
Convey ( desc + " " + url , func ( ) {
defer bus . ClearBusHandlers ( )
2018-01-30 06:17:48 -06:00
sc := setupScenarioContext ( url )
2020-03-04 05:57:20 -06:00
sc . defaultHandler = Wrap ( func ( c * models . ReqContext ) Response {
2017-12-20 17:52:21 -06:00
sc . context = c
sc . context . UserId = TestUserID
sc . context . OrgId = TestOrgID
sc . context . OrgRole = role
return PostAnnotation ( c , cmd )
} )
fakeAnnoRepo = & fakeAnnotationsRepo { }
annotations . SetRepository ( fakeAnnoRepo )
sc . m . Post ( routePattern , sc . defaultHandler )
fn ( sc )
} )
}
2020-03-04 05:57:20 -06:00
func putAnnotationScenario ( desc string , url string , routePattern string , role models . RoleType , cmd dtos . UpdateAnnotationsCmd , fn scenarioFunc ) {
2017-12-20 17:52:21 -06:00
Convey ( desc + " " + url , func ( ) {
defer bus . ClearBusHandlers ( )
2018-01-30 06:17:48 -06:00
sc := setupScenarioContext ( url )
2020-03-04 05:57:20 -06:00
sc . defaultHandler = Wrap ( func ( c * models . ReqContext ) Response {
2017-12-20 17:52:21 -06:00
sc . context = c
sc . context . UserId = TestUserID
sc . context . OrgId = TestOrgID
sc . context . OrgRole = role
return UpdateAnnotation ( c , cmd )
} )
fakeAnnoRepo = & fakeAnnotationsRepo { }
annotations . SetRepository ( fakeAnnoRepo )
sc . m . Put ( routePattern , sc . defaultHandler )
fn ( sc )
} )
}
2018-06-25 06:58:49 -05:00
2020-03-04 05:57:20 -06:00
func patchAnnotationScenario ( desc string , url string , routePattern string , role models . RoleType , cmd dtos . PatchAnnotationsCmd , fn scenarioFunc ) {
2019-01-27 05:49:22 -06:00
Convey ( desc + " " + url , func ( ) {
defer bus . ClearBusHandlers ( )
sc := setupScenarioContext ( url )
2020-03-04 05:57:20 -06:00
sc . defaultHandler = Wrap ( func ( c * models . ReqContext ) Response {
2019-01-27 05:49:22 -06:00
sc . context = c
sc . context . UserId = TestUserID
sc . context . OrgId = TestOrgID
sc . context . OrgRole = role
return PatchAnnotation ( c , cmd )
} )
fakeAnnoRepo = & fakeAnnotationsRepo { }
annotations . SetRepository ( fakeAnnoRepo )
sc . m . Patch ( routePattern , sc . defaultHandler )
fn ( sc )
} )
}
2020-03-04 05:57:20 -06:00
func deleteAnnotationsScenario ( desc string , url string , routePattern string , role models . RoleType , cmd dtos . DeleteAnnotationsCmd , fn scenarioFunc ) {
2018-06-25 06:58:49 -05:00
Convey ( desc + " " + url , func ( ) {
defer bus . ClearBusHandlers ( )
sc := setupScenarioContext ( url )
2020-03-04 05:57:20 -06:00
sc . defaultHandler = Wrap ( func ( c * models . ReqContext ) Response {
2018-06-25 06:58:49 -05:00
sc . context = c
sc . context . UserId = TestUserID
sc . context . OrgId = TestOrgID
sc . context . OrgRole = role
return DeleteAnnotations ( c , cmd )
} )
fakeAnnoRepo = & fakeAnnotationsRepo { }
annotations . SetRepository ( fakeAnnoRepo )
sc . m . Post ( routePattern , sc . defaultHandler )
fn ( sc )
} )
}