* WIP: mutator added, start working on validator * first validator iteration * second validator iteration * wip: working on integration tests * re-working mutation and validation, using Connection interface * fixing some rebase things * fixing integration tests * formatting * fixing unit tests * k8s codegen * linting * moving tests which are available only for enterprise * addressing comments: using repo config for connections, updating tests * addressing comments: adding some more info in the app and installation * fixing app data * addressing comments: updating connection implementation * addressing comments * formatting * fixing tests
171 lines
5.6 KiB
Go
171 lines
5.6 KiB
Go
package provisioning
|
|
|
|
import (
|
|
"context"
|
|
"encoding/base64"
|
|
"encoding/json"
|
|
"net/http"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
|
|
|
provisioning "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1"
|
|
"github.com/grafana/grafana/pkg/util/testutil"
|
|
)
|
|
|
|
func TestIntegrationProvisioning_ConnectionRepositories(t *testing.T) {
|
|
testutil.SkipIntegrationTestInShortMode(t)
|
|
|
|
helper := runGrafana(t)
|
|
ctx := context.Background()
|
|
privateKeyBase64 := base64.StdEncoding.EncodeToString([]byte(testPrivateKeyPEM))
|
|
|
|
// Create a connection for testing
|
|
connection := &unstructured.Unstructured{Object: map[string]any{
|
|
"apiVersion": "provisioning.grafana.app/v0alpha1",
|
|
"kind": "Connection",
|
|
"metadata": map[string]any{
|
|
"name": "connection-repositories-test",
|
|
"namespace": "default",
|
|
},
|
|
"spec": map[string]any{
|
|
"type": "github",
|
|
"github": map[string]any{
|
|
"appID": "123456",
|
|
"installationID": "454545",
|
|
},
|
|
},
|
|
"secure": map[string]any{
|
|
"privateKey": map[string]any{
|
|
"create": privateKeyBase64,
|
|
},
|
|
},
|
|
}}
|
|
_, err := helper.CreateGithubConnection(t, ctx, connection)
|
|
require.NoError(t, err)
|
|
|
|
t.Run("endpoint returns not implemented", func(t *testing.T) {
|
|
var statusCode int
|
|
result := helper.AdminREST.Get().
|
|
Namespace("default").
|
|
Resource("connections").
|
|
Name("connection-repositories-test").
|
|
SubResource("repositories").
|
|
Do(ctx).
|
|
StatusCode(&statusCode)
|
|
|
|
require.Error(t, result.Error(), "should return error for not implemented endpoint")
|
|
require.Equal(t, http.StatusMethodNotAllowed, statusCode, "should return 405 Method Not Allowed")
|
|
require.True(t, apierrors.IsMethodNotSupported(result.Error()), "error should be MethodNotSupported")
|
|
})
|
|
|
|
t.Run("admin can access endpoint (gets not implemented)", func(t *testing.T) {
|
|
var statusCode int
|
|
result := helper.AdminREST.Get().
|
|
Namespace("default").
|
|
Resource("connections").
|
|
Name("connection-repositories-test").
|
|
SubResource("repositories").
|
|
Do(ctx).StatusCode(&statusCode)
|
|
|
|
// Endpoint exists but returns not implemented
|
|
require.Error(t, result.Error(), "should return error")
|
|
require.True(t, apierrors.IsMethodNotSupported(result.Error()), "error should be MethodNotSupported")
|
|
// Status code should be 405 (Method Not Allowed) for method not supported
|
|
require.Equal(t, http.StatusMethodNotAllowed, statusCode)
|
|
})
|
|
|
|
t.Run("editor cannot access endpoint", func(t *testing.T) {
|
|
var statusCode int
|
|
result := helper.EditorREST.Get().
|
|
Namespace("default").
|
|
Resource("connections").
|
|
Name("connection-repositories-test").
|
|
SubResource("repositories").
|
|
Do(ctx).StatusCode(&statusCode)
|
|
|
|
require.Error(t, result.Error(), "editor should not be able to access repositories endpoint")
|
|
require.Equal(t, http.StatusForbidden, statusCode, "should return 403 Forbidden")
|
|
require.True(t, apierrors.IsForbidden(result.Error()), "error should be forbidden")
|
|
})
|
|
|
|
t.Run("viewer cannot access endpoint", func(t *testing.T) {
|
|
var statusCode int
|
|
result := helper.ViewerREST.Get().
|
|
Namespace("default").
|
|
Resource("connections").
|
|
Name("connection-repositories-test").
|
|
SubResource("repositories").
|
|
Do(ctx).StatusCode(&statusCode)
|
|
|
|
require.Error(t, result.Error(), "viewer should not be able to access repositories endpoint")
|
|
require.Equal(t, http.StatusForbidden, statusCode, "should return 403 Forbidden")
|
|
require.True(t, apierrors.IsForbidden(result.Error()), "error should be forbidden")
|
|
})
|
|
|
|
t.Run("non-GET methods are rejected", func(t *testing.T) {
|
|
configBytes, _ := json.Marshal(map[string]any{})
|
|
|
|
var statusCode int
|
|
result := helper.AdminREST.Post().
|
|
Namespace("default").
|
|
Resource("connections").
|
|
Name("connection-repositories-test").
|
|
SubResource("repositories").
|
|
Body(configBytes).
|
|
SetHeader("Content-Type", "application/json").
|
|
Do(ctx).StatusCode(&statusCode)
|
|
|
|
require.Error(t, result.Error(), "POST should not be allowed")
|
|
require.True(t, apierrors.IsMethodNotSupported(result.Error()), "error should be MethodNotSupported")
|
|
})
|
|
}
|
|
|
|
func TestIntegrationProvisioning_ConnectionRepositoriesResponseType(t *testing.T) {
|
|
testutil.SkipIntegrationTestInShortMode(t)
|
|
|
|
helper := runGrafana(t)
|
|
ctx := context.Background()
|
|
privateKeyBase64 := base64.StdEncoding.EncodeToString([]byte(testPrivateKeyPEM))
|
|
|
|
// Create a connection for testing
|
|
connection := &unstructured.Unstructured{Object: map[string]any{
|
|
"apiVersion": "provisioning.grafana.app/v0alpha1",
|
|
"kind": "Connection",
|
|
"metadata": map[string]any{
|
|
"name": "connection-repositories-test",
|
|
"namespace": "default",
|
|
},
|
|
"spec": map[string]any{
|
|
"type": "github",
|
|
"github": map[string]any{
|
|
"appID": "123456",
|
|
"installationID": "454545",
|
|
},
|
|
},
|
|
"secure": map[string]any{
|
|
"privateKey": map[string]any{
|
|
"create": privateKeyBase64,
|
|
},
|
|
},
|
|
}}
|
|
_, err := helper.CreateGithubConnection(t, ctx, connection)
|
|
require.NoError(t, err)
|
|
|
|
t.Run("verify ExternalRepositoryList type exists in API", func(t *testing.T) {
|
|
// Verify the type is registered and can be instantiated
|
|
list := &provisioning.ExternalRepositoryList{}
|
|
require.NotNil(t, list)
|
|
// Verify it has the expected structure (Items is a slice, nil by default is fine)
|
|
require.IsType(t, []provisioning.ExternalRepository{}, list.Items)
|
|
// Can create items
|
|
list.Items = []provisioning.ExternalRepository{
|
|
{Name: "test", Owner: "owner", URL: "https://example.com/repo"},
|
|
}
|
|
require.Len(t, list.Items, 1)
|
|
require.Equal(t, "test", list.Items[0].Name)
|
|
})
|
|
}
|