Extract Route validation from serialization methods so it can be re-used (#47649)

* Extract validation and reject invalid policies

* Validation in dedicated file

* Tests for validation

* Extract root route validation

* Update call and drop TODO

* empty commit to kick actions

* Normalization should be idempotent

* Cleaner representation of validation errors, chain errors properly

* Make internal validate unexported

* Fix missed rename

* Genericize error message

* Improve method names

* Rebase, fix

* Update asserts
This commit is contained in:
Alexander Weaver
2022-04-27 15:15:41 -05:00
committed by GitHub
parent 900d9bf9a1
commit 60ec10566f
8 changed files with 380 additions and 50 deletions
@@ -10,6 +10,7 @@ import (
"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"
@@ -35,7 +36,20 @@ func TestProvisioningApi(t *testing.T) {
require.Equal(t, 202, response.Status())
})
// TODO: we have not lifted out validation yet. Test that we are returning errors properly once validation has been lifted.
t.Run("when new policy tree is invalid", func(t *testing.T) {
t.Run("POST policies returns 400", func(t *testing.T) {
sut := createProvisioningSrvSut()
sut.policies = &fakeRejectingNotificationPolicyService{}
rc := createTestRequestCtx()
tree := apimodels.Route{}
response := sut.RoutePostPolicyTree(&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) {
@@ -146,3 +160,13 @@ func (f *fakeFailingNotificationPolicyService) GetPolicyTree(ctx context.Context
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)
}