test: add validation and event tests for organization and API key

Adds unit tests for the `AddOrganization` and `AddAPIKey` commands. 
These tests validate various scenarios, including success cases, 
handling of already existing organizations or keys, and ensuring 
required fields are checked. The
changes enhance test coverage and ensure robustness of the command 
logic.
This commit is contained in:
2025-11-21 12:49:23 +01:00
parent 06aeedc3b0
commit 862060875b
3 changed files with 825 additions and 0 deletions
+390
View File
@@ -7,10 +7,68 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"gitlab.com/unboundsoftware/eventsourced/eventsourced"
"gitlab.com/unboundsoftware/schemas/hash"
)
// AddOrganization tests
func TestAddOrganization_Validate_Success(t *testing.T) {
cmd := AddOrganization{
Name: "Test Org",
Initiator: "user@example.com",
}
org := &Organization{} // New organization with no identity
err := cmd.Validate(context.Background(), org)
assert.NoError(t, err)
}
func TestAddOrganization_Validate_AlreadyExists(t *testing.T) {
cmd := AddOrganization{
Name: "Test Org",
Initiator: "user@example.com",
}
org := &Organization{
BaseAggregate: eventsourced.BaseAggregateFromString("existing-org-id"),
}
err := cmd.Validate(context.Background(), org)
require.Error(t, err)
assert.Contains(t, err.Error(), "already exists")
}
func TestAddOrganization_Validate_EmptyName(t *testing.T) {
cmd := AddOrganization{
Name: "",
Initiator: "user@example.com",
}
org := &Organization{}
err := cmd.Validate(context.Background(), org)
require.Error(t, err)
assert.Contains(t, err.Error(), "name is required")
}
func TestAddOrganization_Event(t *testing.T) {
cmd := AddOrganization{
Name: "Test Org",
Initiator: "user@example.com",
}
event := cmd.Event(context.Background())
require.NotNil(t, event)
orgEvent, ok := event.(*OrganizationAdded)
require.True(t, ok)
assert.Equal(t, "Test Org", orgEvent.Name)
assert.Equal(t, "user@example.com", orgEvent.Initiator)
}
// AddAPIKey tests
func TestAddAPIKey_Event(t *testing.T) {
type fields struct {
Name string
@@ -74,3 +132,335 @@ func TestAddAPIKey_Event(t *testing.T) {
})
}
}
func TestAddAPIKey_Validate_Success(t *testing.T) {
cmd := AddAPIKey{
Name: "production-key",
Key: "us_ak_1234567890123456",
Refs: []string{"main"},
Read: true,
Publish: false,
Initiator: "user@example.com",
}
org := &Organization{
BaseAggregate: eventsourced.BaseAggregateFromString("org-123"),
APIKeys: []APIKey{},
}
err := cmd.Validate(context.Background(), org)
assert.NoError(t, err)
}
func TestAddAPIKey_Validate_OrganizationNotExists(t *testing.T) {
cmd := AddAPIKey{
Name: "production-key",
Key: "us_ak_1234567890123456",
Refs: []string{"main"},
Read: true,
Publish: false,
Initiator: "user@example.com",
}
org := &Organization{} // No identity means it doesn't exist
err := cmd.Validate(context.Background(), org)
require.Error(t, err)
assert.Contains(t, err.Error(), "does not exist")
}
func TestAddAPIKey_Validate_DuplicateKeyName(t *testing.T) {
cmd := AddAPIKey{
Name: "existing-key",
Key: "us_ak_1234567890123456",
Refs: []string{"main"},
Read: true,
Publish: false,
Initiator: "user@example.com",
}
org := &Organization{
BaseAggregate: eventsourced.BaseAggregateFromString("org-123"),
APIKeys: []APIKey{
{
Name: "existing-key",
Key: "hashed-key",
},
},
}
err := cmd.Validate(context.Background(), org)
require.Error(t, err)
assert.Contains(t, err.Error(), "already exist")
assert.Contains(t, err.Error(), "existing-key")
}
// UpdateSubGraph tests
func TestUpdateSubGraph_Validate_Success(t *testing.T) {
url := "http://example.com/graphql"
cmd := UpdateSubGraph{
OrganizationId: "org-123",
Ref: "main",
Service: "users",
Url: &url,
Sdl: "type Query { hello: String }",
Initiator: "user@example.com",
}
subGraph := &SubGraph{
BaseAggregate: eventsourced.BaseAggregateFromString("subgraph-123"),
}
err := cmd.Validate(context.Background(), subGraph)
assert.NoError(t, err)
}
func TestUpdateSubGraph_Validate_MissingRef(t *testing.T) {
url := "http://example.com/graphql"
cmd := UpdateSubGraph{
OrganizationId: "org-123",
Ref: "",
Service: "users",
Url: &url,
Sdl: "type Query { hello: String }",
Initiator: "user@example.com",
}
subGraph := &SubGraph{
BaseAggregate: eventsourced.BaseAggregateFromString("subgraph-123"),
}
err := cmd.Validate(context.Background(), subGraph)
require.Error(t, err)
assert.Contains(t, err.Error(), "ref is missing")
}
func TestUpdateSubGraph_Validate_RefWhitespaceOnly(t *testing.T) {
url := "http://example.com/graphql"
cmd := UpdateSubGraph{
OrganizationId: "org-123",
Ref: " ",
Service: "users",
Url: &url,
Sdl: "type Query { hello: String }",
Initiator: "user@example.com",
}
subGraph := &SubGraph{
BaseAggregate: eventsourced.BaseAggregateFromString("subgraph-123"),
}
err := cmd.Validate(context.Background(), subGraph)
require.Error(t, err)
assert.Contains(t, err.Error(), "ref is missing")
}
func TestUpdateSubGraph_Validate_MissingService(t *testing.T) {
url := "http://example.com/graphql"
cmd := UpdateSubGraph{
OrganizationId: "org-123",
Ref: "main",
Service: "",
Url: &url,
Sdl: "type Query { hello: String }",
Initiator: "user@example.com",
}
subGraph := &SubGraph{
BaseAggregate: eventsourced.BaseAggregateFromString("subgraph-123"),
}
err := cmd.Validate(context.Background(), subGraph)
require.Error(t, err)
assert.Contains(t, err.Error(), "service is missing")
}
func TestUpdateSubGraph_Validate_ServiceWhitespaceOnly(t *testing.T) {
url := "http://example.com/graphql"
cmd := UpdateSubGraph{
OrganizationId: "org-123",
Ref: "main",
Service: " ",
Url: &url,
Sdl: "type Query { hello: String }",
Initiator: "user@example.com",
}
subGraph := &SubGraph{
BaseAggregate: eventsourced.BaseAggregateFromString("subgraph-123"),
}
err := cmd.Validate(context.Background(), subGraph)
require.Error(t, err)
assert.Contains(t, err.Error(), "service is missing")
}
func TestUpdateSubGraph_Validate_MissingSDL(t *testing.T) {
url := "http://example.com/graphql"
cmd := UpdateSubGraph{
OrganizationId: "org-123",
Ref: "main",
Service: "users",
Url: &url,
Sdl: "",
Initiator: "user@example.com",
}
subGraph := &SubGraph{
BaseAggregate: eventsourced.BaseAggregateFromString("subgraph-123"),
}
err := cmd.Validate(context.Background(), subGraph)
require.Error(t, err)
assert.Contains(t, err.Error(), "SDL is missing")
}
func TestUpdateSubGraph_Validate_SDLWhitespaceOnly(t *testing.T) {
url := "http://example.com/graphql"
cmd := UpdateSubGraph{
OrganizationId: "org-123",
Ref: "main",
Service: "users",
Url: &url,
Sdl: " \n\t ",
Initiator: "user@example.com",
}
subGraph := &SubGraph{
BaseAggregate: eventsourced.BaseAggregateFromString("subgraph-123"),
}
err := cmd.Validate(context.Background(), subGraph)
require.Error(t, err)
assert.Contains(t, err.Error(), "SDL is missing")
}
func TestUpdateSubGraph_Validate_MissingURL_NoExistingURL(t *testing.T) {
cmd := UpdateSubGraph{
OrganizationId: "org-123",
Ref: "main",
Service: "users",
Url: nil,
Sdl: "type Query { hello: String }",
Initiator: "user@example.com",
}
subGraph := &SubGraph{
BaseAggregate: eventsourced.BaseAggregateFromString("subgraph-123"),
Url: nil, // No existing URL
}
err := cmd.Validate(context.Background(), subGraph)
require.Error(t, err)
assert.Contains(t, err.Error(), "url is missing")
}
func TestUpdateSubGraph_Validate_MissingURL_HasExistingURL(t *testing.T) {
existingURL := "http://example.com/graphql"
cmd := UpdateSubGraph{
OrganizationId: "org-123",
Ref: "main",
Service: "users",
Url: nil,
Sdl: "type Query { hello: String }",
Initiator: "user@example.com",
}
subGraph := &SubGraph{
BaseAggregate: eventsourced.BaseAggregateFromString("subgraph-123"),
Url: &existingURL, // Has existing URL, so nil is OK
}
err := cmd.Validate(context.Background(), subGraph)
assert.NoError(t, err)
}
func TestUpdateSubGraph_Validate_EmptyURL_NoExistingURL(t *testing.T) {
emptyURL := ""
cmd := UpdateSubGraph{
OrganizationId: "org-123",
Ref: "main",
Service: "users",
Url: &emptyURL,
Sdl: "type Query { hello: String }",
Initiator: "user@example.com",
}
subGraph := &SubGraph{
BaseAggregate: eventsourced.BaseAggregateFromString("subgraph-123"),
Url: nil,
}
err := cmd.Validate(context.Background(), subGraph)
require.Error(t, err)
assert.Contains(t, err.Error(), "url is missing")
}
func TestUpdateSubGraph_Validate_URLWhitespaceOnly_NoExistingURL(t *testing.T) {
whitespaceURL := " "
cmd := UpdateSubGraph{
OrganizationId: "org-123",
Ref: "main",
Service: "users",
Url: &whitespaceURL,
Sdl: "type Query { hello: String }",
Initiator: "user@example.com",
}
subGraph := &SubGraph{
BaseAggregate: eventsourced.BaseAggregateFromString("subgraph-123"),
Url: nil,
}
err := cmd.Validate(context.Background(), subGraph)
require.Error(t, err)
assert.Contains(t, err.Error(), "url is missing")
}
func TestUpdateSubGraph_Validate_WrongAggregateType(t *testing.T) {
url := "http://example.com/graphql"
cmd := UpdateSubGraph{
OrganizationId: "org-123",
Ref: "main",
Service: "users",
Url: &url,
Sdl: "type Query { hello: String }",
Initiator: "user@example.com",
}
// Pass wrong aggregate type
org := &Organization{
BaseAggregate: eventsourced.BaseAggregateFromString("org-123"),
}
err := cmd.Validate(context.Background(), org)
require.Error(t, err)
assert.Contains(t, err.Error(), "not a SubGraph")
}
func TestUpdateSubGraph_Event(t *testing.T) {
url := "http://example.com/graphql"
wsURL := "ws://example.com/graphql"
cmd := UpdateSubGraph{
OrganizationId: "org-123",
Ref: "main",
Service: "users",
Url: &url,
WSUrl: &wsURL,
Sdl: "type Query { hello: String }",
Initiator: "user@example.com",
}
event := cmd.Event(context.Background())
require.NotNil(t, event)
subGraphEvent, ok := event.(*SubGraphUpdated)
require.True(t, ok)
assert.Equal(t, "org-123", subGraphEvent.OrganizationId)
assert.Equal(t, "main", subGraphEvent.Ref)
assert.Equal(t, "users", subGraphEvent.Service)
assert.Equal(t, url, *subGraphEvent.Url)
assert.Equal(t, wsURL, *subGraphEvent.WSUrl)
assert.Equal(t, "type Query { hello: String }", subGraphEvent.Sdl)
assert.Equal(t, "user@example.com", subGraphEvent.Initiator)
}