mirror of
https://github.com/grafana/grafana.git
synced 2024-11-26 02:40:26 -06:00
Add unit tests for the removeSSOSettings API method (#78476)
add unit tests for the removeSSOSettings api method
This commit is contained in:
parent
4fd1d92332
commit
f0d3e27ea7
@ -1,3 +1,149 @@
|
||||
package api
|
||||
|
||||
// TODO: add tests when you implement the final version of the API endpoint
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/mock"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/grafana/grafana/pkg/api/routing"
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol/acimpl"
|
||||
"github.com/grafana/grafana/pkg/services/org"
|
||||
"github.com/grafana/grafana/pkg/services/ssosettings"
|
||||
"github.com/grafana/grafana/pkg/services/ssosettings/ssosettingstests"
|
||||
"github.com/grafana/grafana/pkg/services/user"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"github.com/grafana/grafana/pkg/web/webtest"
|
||||
)
|
||||
|
||||
func TestSSOSettingsAPI_Delete(t *testing.T) {
|
||||
type TestCase struct {
|
||||
desc string
|
||||
key string
|
||||
action string
|
||||
scope string
|
||||
expectedError error
|
||||
expectedServiceCall bool
|
||||
expectedStatusCode int
|
||||
}
|
||||
|
||||
tests := []TestCase{
|
||||
{
|
||||
desc: "successfully deletes SSO settings",
|
||||
key: "azuread",
|
||||
action: "settings:write",
|
||||
scope: "settings:auth.azuread:*",
|
||||
expectedError: nil,
|
||||
expectedServiceCall: true,
|
||||
expectedStatusCode: http.StatusNoContent,
|
||||
},
|
||||
{
|
||||
desc: "fails when action doesn't match",
|
||||
key: "azuread",
|
||||
action: "settings:read",
|
||||
scope: "settings:auth.azuread:*",
|
||||
expectedError: nil,
|
||||
expectedServiceCall: false,
|
||||
expectedStatusCode: http.StatusForbidden,
|
||||
},
|
||||
{
|
||||
desc: "fails when scope doesn't match",
|
||||
key: "azuread",
|
||||
action: "settings:write",
|
||||
scope: "settings:auth.azuread:read",
|
||||
expectedError: nil,
|
||||
expectedServiceCall: false,
|
||||
expectedStatusCode: http.StatusForbidden,
|
||||
},
|
||||
{
|
||||
desc: "fails when scope contains another provider",
|
||||
key: "azuread",
|
||||
action: "settings:write",
|
||||
scope: "settings:auth.github:*",
|
||||
expectedError: nil,
|
||||
expectedServiceCall: false,
|
||||
expectedStatusCode: http.StatusForbidden,
|
||||
},
|
||||
{
|
||||
desc: "fails with not found when key is empty",
|
||||
key: "",
|
||||
action: "settings:write",
|
||||
scope: "settings:auth.azuread:*",
|
||||
expectedError: nil,
|
||||
expectedServiceCall: false,
|
||||
expectedStatusCode: http.StatusNotFound,
|
||||
},
|
||||
{
|
||||
desc: "fails with not found when key was not found",
|
||||
key: "azuread",
|
||||
action: "settings:write",
|
||||
scope: "settings:auth.azuread:*",
|
||||
expectedError: ssosettings.ErrNotFound,
|
||||
expectedServiceCall: true,
|
||||
expectedStatusCode: http.StatusNotFound,
|
||||
},
|
||||
{
|
||||
desc: "fails with internal server error when service returns an error",
|
||||
key: "azuread",
|
||||
action: "settings:write",
|
||||
scope: "settings:auth.azuread:*",
|
||||
expectedError: errors.New("something went wrong"),
|
||||
expectedServiceCall: true,
|
||||
expectedStatusCode: http.StatusInternalServerError,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.desc, func(t *testing.T) {
|
||||
service := ssosettingstests.NewMockService(t)
|
||||
if tt.expectedServiceCall {
|
||||
service.On("Delete", mock.Anything, tt.key).Return(tt.expectedError).Once()
|
||||
}
|
||||
server := setupTests(t, service)
|
||||
|
||||
path := fmt.Sprintf("/api/v1/sso-settings/%s", tt.key)
|
||||
req := server.NewRequest(http.MethodDelete, path, nil)
|
||||
webtest.RequestWithSignedInUser(req, &user.SignedInUser{
|
||||
OrgRole: org.RoleEditor,
|
||||
OrgID: 1,
|
||||
Permissions: getPermissionsForActionAndScope(tt.action, tt.scope),
|
||||
})
|
||||
res, err := server.SendJSON(req)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, tt.expectedStatusCode, res.StatusCode)
|
||||
require.NoError(t, res.Body.Close())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func getPermissionsForActionAndScope(action, scope string) map[int64]map[string][]string {
|
||||
return map[int64]map[string][]string{
|
||||
1: accesscontrol.GroupScopesByAction([]accesscontrol.Permission{{
|
||||
Action: action, Scope: scope,
|
||||
}}),
|
||||
}
|
||||
}
|
||||
|
||||
func setupTests(t *testing.T, service ssosettings.Service) *webtest.Server {
|
||||
t.Helper()
|
||||
|
||||
cfg := setting.NewCfg()
|
||||
logger := log.NewNopLogger()
|
||||
|
||||
api := &Api{
|
||||
Log: logger,
|
||||
RouteRegister: routing.NewRouteRegister(),
|
||||
AccessControl: acimpl.ProvideAccessControl(cfg),
|
||||
SSOSettingsService: service,
|
||||
}
|
||||
|
||||
api.RegisterAPIEndpoints()
|
||||
|
||||
return webtest.NewServer(t, api.RouteRegister)
|
||||
}
|
||||
|
@ -16,6 +16,8 @@ var (
|
||||
)
|
||||
|
||||
// Service is a SSO settings service
|
||||
//
|
||||
//go:generate mockery --name Service --structname MockService --outpkg ssosettingstests --filename service_mock.go --output ./ssosettingstests/
|
||||
type Service interface {
|
||||
// List returns all SSO settings from DB and config files
|
||||
List(ctx context.Context, requester identity.Requester) ([]*models.SSOSetting, error)
|
||||
|
137
pkg/services/ssosettings/ssosettingstests/service_mock.go
Normal file
137
pkg/services/ssosettings/ssosettingstests/service_mock.go
Normal file
@ -0,0 +1,137 @@
|
||||
// Code generated by mockery v2.37.1. DO NOT EDIT.
|
||||
|
||||
package ssosettingstests
|
||||
|
||||
import (
|
||||
context "context"
|
||||
|
||||
identity "github.com/grafana/grafana/pkg/services/auth/identity"
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
|
||||
models "github.com/grafana/grafana/pkg/services/ssosettings/models"
|
||||
|
||||
ssosettings "github.com/grafana/grafana/pkg/services/ssosettings"
|
||||
)
|
||||
|
||||
// MockService is an autogenerated mock type for the Service type
|
||||
type MockService struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
// Delete provides a mock function with given fields: ctx, provider
|
||||
func (_m *MockService) Delete(ctx context.Context, provider string) error {
|
||||
ret := _m.Called(ctx, provider)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string) error); ok {
|
||||
r0 = rf(ctx, provider)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// GetForProvider provides a mock function with given fields: ctx, provider
|
||||
func (_m *MockService) GetForProvider(ctx context.Context, provider string) (*models.SSOSetting, error) {
|
||||
ret := _m.Called(ctx, provider)
|
||||
|
||||
var r0 *models.SSOSetting
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string) (*models.SSOSetting, error)); ok {
|
||||
return rf(ctx, provider)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string) *models.SSOSetting); ok {
|
||||
r0 = rf(ctx, provider)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*models.SSOSetting)
|
||||
}
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(context.Context, string) error); ok {
|
||||
r1 = rf(ctx, provider)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// List provides a mock function with given fields: ctx, requester
|
||||
func (_m *MockService) List(ctx context.Context, requester identity.Requester) ([]*models.SSOSetting, error) {
|
||||
ret := _m.Called(ctx, requester)
|
||||
|
||||
var r0 []*models.SSOSetting
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, identity.Requester) ([]*models.SSOSetting, error)); ok {
|
||||
return rf(ctx, requester)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, identity.Requester) []*models.SSOSetting); ok {
|
||||
r0 = rf(ctx, requester)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]*models.SSOSetting)
|
||||
}
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(context.Context, identity.Requester) error); ok {
|
||||
r1 = rf(ctx, requester)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// Patch provides a mock function with given fields: ctx, provider, data
|
||||
func (_m *MockService) Patch(ctx context.Context, provider string, data map[string]interface{}) error {
|
||||
ret := _m.Called(ctx, provider, data)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string, map[string]interface{}) error); ok {
|
||||
r0 = rf(ctx, provider, data)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// RegisterReloadable provides a mock function with given fields: ctx, provider, reloadable
|
||||
func (_m *MockService) RegisterReloadable(ctx context.Context, provider string, reloadable ssosettings.Reloadable) {
|
||||
_m.Called(ctx, provider, reloadable)
|
||||
}
|
||||
|
||||
// Reload provides a mock function with given fields: ctx, provider
|
||||
func (_m *MockService) Reload(ctx context.Context, provider string) {
|
||||
_m.Called(ctx, provider)
|
||||
}
|
||||
|
||||
// Upsert provides a mock function with given fields: ctx, provider, data
|
||||
func (_m *MockService) Upsert(ctx context.Context, provider string, data map[string]interface{}) error {
|
||||
ret := _m.Called(ctx, provider, data)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, string, map[string]interface{}) error); ok {
|
||||
r0 = rf(ctx, provider, data)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// NewMockService creates a new instance of MockService. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
|
||||
// The first argument is typically a *testing.T value.
|
||||
func NewMockService(t interface {
|
||||
mock.TestingT
|
||||
Cleanup(func())
|
||||
}) *MockService {
|
||||
mock := &MockService{}
|
||||
mock.Mock.Test(t)
|
||||
|
||||
t.Cleanup(func() { mock.AssertExpectations(t) })
|
||||
|
||||
return mock
|
||||
}
|
Loading…
Reference in New Issue
Block a user