Files
schemas/domain/events_test.go
T
argoyle ffcf41b85a feat: add commands for managing organizations and users
Introduce `AddUserToOrganization`, `RemoveAPIKey`, and 
`RemoveOrganization` commands to enhance organization 
management. Implement validation for user addition and 
API key removal. Update GraphQL schema to support new 
mutations and add caching for the new events, ensuring 
that organizations and their relationships are accurately 
represented in the cache.
2025-11-22 18:37:07 +01:00

255 lines
6.7 KiB
Go

package domain
import (
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"gitlab.com/unboundsoftware/eventsourced/eventsourced"
)
func TestOrganizationAdded_UpdateOrganization(t *testing.T) {
event := &OrganizationAdded{
BaseEvent: eventsourced.BaseEvent{
EventTime: eventsourced.EventTime{
Time: time.Now(),
},
},
Name: "Test Organization",
Initiator: "user@example.com",
}
org := &Organization{
BaseAggregate: eventsourced.BaseAggregateFromString("org-123"),
}
event.UpdateOrganization(org)
assert.Equal(t, "Test Organization", org.Name)
assert.Equal(t, []string{"user@example.com"}, org.Users)
assert.Equal(t, "user@example.com", org.CreatedBy)
assert.Equal(t, "user@example.com", org.ChangedBy)
assert.Equal(t, event.When(), org.CreatedAt)
assert.Equal(t, event.When(), org.ChangedAt)
}
func TestUserAddedToOrganization_UpdateOrganization(t *testing.T) {
event := &UserAddedToOrganization{
BaseEvent: eventsourced.BaseEvent{
EventTime: eventsourced.EventTime{
Time: time.Now(),
},
},
UserId: "new-user@example.com",
Initiator: "admin@example.com",
}
org := &Organization{
BaseAggregate: eventsourced.BaseAggregateFromString("org-123"),
Users: []string{"existing-user@example.com"},
}
event.UpdateOrganization(org)
assert.Len(t, org.Users, 2)
assert.Contains(t, org.Users, "existing-user@example.com")
assert.Contains(t, org.Users, "new-user@example.com")
assert.Equal(t, "admin@example.com", org.ChangedBy)
assert.Equal(t, event.When(), org.ChangedAt)
}
func TestUserAddedToOrganization_UpdateOrganization_DuplicateUser(t *testing.T) {
event := &UserAddedToOrganization{
BaseEvent: eventsourced.BaseEvent{
EventTime: eventsourced.EventTime{
Time: time.Now(),
},
},
UserId: "existing-user@example.com",
Initiator: "admin@example.com",
}
org := &Organization{
BaseAggregate: eventsourced.BaseAggregateFromString("org-123"),
Users: []string{"existing-user@example.com"},
ChangedBy: "previous-admin@example.com",
}
originalChangedBy := org.ChangedBy
originalChangedAt := org.ChangedAt
event.UpdateOrganization(org)
// User should not be added twice
assert.Len(t, org.Users, 1)
assert.Equal(t, "existing-user@example.com", org.Users[0])
// ChangedBy and ChangedAt should NOT be updated when user already exists (idempotent)
assert.Equal(t, originalChangedBy, org.ChangedBy)
assert.Equal(t, originalChangedAt, org.ChangedAt)
}
func TestAPIKeyRemoved_UpdateOrganization(t *testing.T) {
event := &APIKeyRemoved{
BaseEvent: eventsourced.BaseEvent{
EventTime: eventsourced.EventTime{
Time: time.Now(),
},
},
KeyName: "production-key",
Initiator: "admin@example.com",
}
org := &Organization{
BaseAggregate: eventsourced.BaseAggregateFromString("org-123"),
APIKeys: []APIKey{
{Name: "dev-key", Key: "hashed-key-1"},
{Name: "production-key", Key: "hashed-key-2"},
{Name: "staging-key", Key: "hashed-key-3"},
},
}
event.UpdateOrganization(org)
assert.Len(t, org.APIKeys, 2)
assert.Equal(t, "dev-key", org.APIKeys[0].Name)
assert.Equal(t, "staging-key", org.APIKeys[1].Name)
assert.Equal(t, "admin@example.com", org.ChangedBy)
assert.Equal(t, event.When(), org.ChangedAt)
}
func TestAPIKeyRemoved_UpdateOrganization_KeyNotFound(t *testing.T) {
event := &APIKeyRemoved{
BaseEvent: eventsourced.BaseEvent{
EventTime: eventsourced.EventTime{
Time: time.Now(),
},
},
KeyName: "non-existent-key",
Initiator: "admin@example.com",
}
org := &Organization{
BaseAggregate: eventsourced.BaseAggregateFromString("org-123"),
APIKeys: []APIKey{
{Name: "dev-key", Key: "hashed-key-1"},
{Name: "production-key", Key: "hashed-key-2"},
},
}
event.UpdateOrganization(org)
// No keys should be removed
assert.Len(t, org.APIKeys, 2)
assert.Equal(t, "dev-key", org.APIKeys[0].Name)
assert.Equal(t, "production-key", org.APIKeys[1].Name)
// But metadata should still be updated
assert.Equal(t, "admin@example.com", org.ChangedBy)
assert.Equal(t, event.When(), org.ChangedAt)
}
func TestAPIKeyRemoved_UpdateOrganization_OnlyKey(t *testing.T) {
event := &APIKeyRemoved{
BaseEvent: eventsourced.BaseEvent{
EventTime: eventsourced.EventTime{
Time: time.Now(),
},
},
KeyName: "only-key",
Initiator: "admin@example.com",
}
org := &Organization{
BaseAggregate: eventsourced.BaseAggregateFromString("org-123"),
APIKeys: []APIKey{
{Name: "only-key", Key: "hashed-key"},
},
}
event.UpdateOrganization(org)
// All keys should be removed
assert.Len(t, org.APIKeys, 0)
assert.Equal(t, "admin@example.com", org.ChangedBy)
assert.Equal(t, event.When(), org.ChangedAt)
}
func TestOrganizationRemoved_UpdateOrganization(t *testing.T) {
event := &OrganizationRemoved{
BaseEvent: eventsourced.BaseEvent{
EventTime: eventsourced.EventTime{
Time: time.Now(),
},
},
Initiator: "admin@example.com",
}
org := &Organization{
BaseAggregate: eventsourced.BaseAggregateFromString("org-123"),
Name: "Test Organization",
Users: []string{"user1@example.com", "user2@example.com"},
APIKeys: []APIKey{
{Name: "key1", Key: "hashed-key-1"},
},
CreatedBy: "creator@example.com",
CreatedAt: time.Now().Add(-24 * time.Hour),
}
event.UpdateOrganization(org)
// Organization data remains (soft delete), but metadata is updated
assert.Equal(t, "Test Organization", org.Name)
assert.Len(t, org.Users, 2)
assert.Len(t, org.APIKeys, 1)
// Metadata should be updated to reflect removal
assert.Equal(t, "admin@example.com", org.ChangedBy)
assert.Equal(t, event.When(), org.ChangedAt)
}
func TestAPIKeyAdded_EnrichFromAggregate(t *testing.T) {
orgId := "org-123"
aggregate := &Organization{
BaseAggregate: eventsourced.BaseAggregateFromString(orgId),
}
event := &APIKeyAdded{
Name: "test-key",
Key: "hashed-key",
Refs: []string{"main"},
Read: true,
Publish: false,
Initiator: "user@example.com",
}
event.EnrichFromAggregate(aggregate)
assert.Equal(t, orgId, event.OrganizationId)
}
func TestSubGraphUpdated_Event(t *testing.T) {
// Verify SubGraphUpdated event structure
url := "http://service.example.com"
wsUrl := "ws://service.example.com"
event := &SubGraphUpdated{
OrganizationId: "org-123",
Ref: "main",
Service: "users-service",
Url: &url,
WSUrl: &wsUrl,
Sdl: "type Query { user: User }",
Initiator: "system",
}
require.NotNil(t, event)
assert.Equal(t, "org-123", event.OrganizationId)
assert.Equal(t, "main", event.Ref)
assert.Equal(t, "users-service", event.Service)
assert.Equal(t, url, *event.Url)
assert.Equal(t, wsUrl, *event.WSUrl)
assert.Equal(t, "type Query { user: User }", event.Sdl)
assert.Equal(t, "system", event.Initiator)
}