grafana/pkg/services/ngalert/api/api_provisioning_test.go
2022-05-06 14:33:30 -05:00

173 lines
5.0 KiB
Go

package api
import (
"context"
"fmt"
"net/http"
"testing"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models"
apimodels "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
domain "github.com/grafana/grafana/pkg/services/ngalert/models"
"github.com/grafana/grafana/pkg/services/ngalert/provisioning"
"github.com/grafana/grafana/pkg/services/ngalert/store"
"github.com/grafana/grafana/pkg/web"
"github.com/stretchr/testify/require"
)
func TestProvisioningApi(t *testing.T) {
t.Run("successful GET policies returns 200", func(t *testing.T) {
sut := createProvisioningSrvSut()
rc := createTestRequestCtx()
response := sut.RouteGetPolicyTree(&rc)
require.Equal(t, 200, response.Status())
})
t.Run("successful PUT policies returns 202", func(t *testing.T) {
sut := createProvisioningSrvSut()
rc := createTestRequestCtx()
tree := apimodels.Route{}
response := sut.RoutePutPolicyTree(&rc, tree)
require.Equal(t, 202, response.Status())
})
t.Run("when new policy tree is invalid", func(t *testing.T) {
t.Run("PUT policies returns 400", func(t *testing.T) {
sut := createProvisioningSrvSut()
sut.policies = &fakeRejectingNotificationPolicyService{}
rc := createTestRequestCtx()
tree := apimodels.Route{}
response := sut.RoutePutPolicyTree(&rc, tree)
require.Equal(t, 400, response.Status())
expBody := `{"error":"invalid object specification: invalid policy tree","message":"invalid object specification: invalid policy tree"}`
require.Equal(t, expBody, string(response.Body()))
})
})
t.Run("when org has no AM config", func(t *testing.T) {
t.Run("GET policies returns 404", func(t *testing.T) {
sut := createProvisioningSrvSut()
rc := createTestRequestCtx()
rc.SignedInUser.OrgId = 2
response := sut.RouteGetPolicyTree(&rc)
require.Equal(t, 404, response.Status())
})
t.Run("POST policies returns 404", func(t *testing.T) {
sut := createProvisioningSrvSut()
rc := createTestRequestCtx()
rc.SignedInUser.OrgId = 2
response := sut.RouteGetPolicyTree(&rc)
require.Equal(t, 404, response.Status())
})
})
t.Run("when an unspecified error occurrs", func(t *testing.T) {
t.Run("GET policies returns 500", func(t *testing.T) {
sut := createProvisioningSrvSut()
sut.policies = &fakeFailingNotificationPolicyService{}
rc := createTestRequestCtx()
response := sut.RouteGetPolicyTree(&rc)
require.Equal(t, 500, response.Status())
require.NotEmpty(t, response.Body())
require.Contains(t, string(response.Body()), "something went wrong")
})
t.Run("PUT policies returns 500", func(t *testing.T) {
sut := createProvisioningSrvSut()
sut.policies = &fakeFailingNotificationPolicyService{}
rc := createTestRequestCtx()
tree := apimodels.Route{}
response := sut.RoutePutPolicyTree(&rc, tree)
require.Equal(t, 500, response.Status())
require.NotEmpty(t, response.Body())
require.Contains(t, string(response.Body()), "something went wrong")
})
})
}
func createProvisioningSrvSut() ProvisioningSrv {
return ProvisioningSrv{
log: log.NewNopLogger(),
policies: newFakeNotificationPolicyService(),
}
}
func createTestRequestCtx() models.ReqContext {
return models.ReqContext{
Context: &web.Context{
Req: &http.Request{},
},
SignedInUser: &models.SignedInUser{
OrgId: 1,
},
}
}
type fakeNotificationPolicyService struct {
tree apimodels.Route
prov domain.Provenance
}
func newFakeNotificationPolicyService() *fakeNotificationPolicyService {
return &fakeNotificationPolicyService{
tree: apimodels.Route{
Receiver: "some-receiver",
},
prov: domain.ProvenanceNone,
}
}
func (f *fakeNotificationPolicyService) GetPolicyTree(ctx context.Context, orgID int64) (apimodels.Route, error) {
if orgID != 1 {
return apimodels.Route{}, store.ErrNoAlertmanagerConfiguration
}
result := f.tree
result.Provenance = f.prov
return result, nil
}
func (f *fakeNotificationPolicyService) UpdatePolicyTree(ctx context.Context, orgID int64, tree apimodels.Route, p domain.Provenance) error {
if orgID != 1 {
return store.ErrNoAlertmanagerConfiguration
}
f.tree = tree
f.prov = p
return nil
}
type fakeFailingNotificationPolicyService struct{}
func (f *fakeFailingNotificationPolicyService) GetPolicyTree(ctx context.Context, orgID int64) (apimodels.Route, error) {
return apimodels.Route{}, fmt.Errorf("something went wrong")
}
func (f *fakeFailingNotificationPolicyService) UpdatePolicyTree(ctx context.Context, orgID int64, tree apimodels.Route, p domain.Provenance) error {
return fmt.Errorf("something went wrong")
}
type fakeRejectingNotificationPolicyService struct{}
func (f *fakeRejectingNotificationPolicyService) GetPolicyTree(ctx context.Context, orgID int64) (apimodels.Route, error) {
return apimodels.Route{}, nil
}
func (f *fakeRejectingNotificationPolicyService) UpdatePolicyTree(ctx context.Context, orgID int64, tree apimodels.Route, p domain.Provenance) error {
return fmt.Errorf("%w: invalid policy tree", provisioning.ErrValidation)
}