verify / verify (push) Successful in 4m25s
Signed-off-by: Cole Speelman <crspeelman@gmail.com>
114 lines
5.0 KiB
Go
114 lines
5.0 KiB
Go
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
package organizations
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"gamertan.com/web/access"
|
|
)
|
|
|
|
type ownedRepositoryStub struct {
|
|
repositoryStub
|
|
setup OwnedOrganization
|
|
calls int
|
|
err error
|
|
}
|
|
|
|
func (repository *ownedRepositoryStub) CreateOwnedOrganization(_ context.Context, setup OwnedOrganization) error {
|
|
repository.calls++
|
|
repository.setup = setup
|
|
return repository.err
|
|
}
|
|
|
|
func TestOwnedOrganizationUsesConfiguredRoleAndAtomicRepository(t *testing.T) {
|
|
now := time.Unix(1000, 0).UTC()
|
|
repository := &ownedRepositoryStub{}
|
|
service, err := New(repository, Options{OwnerRole: "customer.owner", Now: func() time.Time { return now }})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
input := CreateOrganization{Slug: " CLIENT-BUSINESS ", Name: " Client Business ", OwnerUserID: "customer-12345", RequestID: "request-creation"}
|
|
organization, err := service.CreateOwnedOrganization(t.Context(), input)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
setup := repository.setup
|
|
if repository.calls != 1 || repository.organization.ID != "" || setup.Organization != organization || organization.Slug != "client-business" || organization.Name != "Client Business" {
|
|
t.Fatalf("unexpected creation: %+v", setup)
|
|
}
|
|
if setup.Membership.UserID != input.OwnerUserID || setup.OwnerBinding.SubjectKind != access.User || setup.OwnerBinding.SubjectID != input.OwnerUserID || setup.OwnerBinding.Role != "customer.owner" || setup.OwnerBinding.Scope != (access.Scope{OrganizationID: organization.ID}) || setup.OwnerBinding.GrantedBy != input.OwnerUserID {
|
|
t.Fatalf("unexpected owner: %+v", setup)
|
|
}
|
|
if setup.OrganizationAudit.RequestID != input.RequestID || setup.AccessAudit.RequestID != input.RequestID || setup.AccessAudit.ResourceID != setup.OwnerBinding.ID || !setup.OwnerBinding.GrantedAt.Equal(now) {
|
|
t.Fatalf("unexpected audits: %+v", setup)
|
|
}
|
|
}
|
|
|
|
func TestOwnedOrganizationFailsWithoutAtomicSupport(t *testing.T) {
|
|
repository := &repositoryStub{}
|
|
service, _ := New(repository, Options{OwnerRole: "customer.owner"})
|
|
organization, err := service.CreateOwnedOrganization(t.Context(), CreateOrganization{Slug: "client-business", Name: "Client Business", OwnerUserID: "customer-12345"})
|
|
if !errors.Is(err, ErrOwnedCreationUnsupported) || organization.ID != "" || repository.organization.ID != "" {
|
|
t.Fatalf("non-atomic fallback: organization=%+v err=%v", organization, err)
|
|
}
|
|
}
|
|
|
|
func TestOwnedOrganizationRejectsInvalidSetupBeforeStorage(t *testing.T) {
|
|
for _, test := range []struct {
|
|
name string
|
|
role string
|
|
request string
|
|
random string
|
|
}{
|
|
{name: "missing role", random: strings.Repeat("a", 200)},
|
|
{name: "bad request ID", role: "customer.owner", request: "request\nsecret", random: strings.Repeat("a", 200)},
|
|
{name: "random failure", role: "customer.owner", random: strings.Repeat("a", 40)},
|
|
} {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
repository := &ownedRepositoryStub{}
|
|
service, err := New(repository, Options{OwnerRole: test.role, Random: strings.NewReader(test.random)})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
organization, err := service.CreateOwnedOrganization(t.Context(), CreateOrganization{Slug: "client-business", Name: "Client Business", OwnerUserID: "customer-12345", RequestID: test.request})
|
|
if err == nil || organization.ID != "" || repository.calls != 0 {
|
|
t.Fatalf("organization=%+v calls=%d err=%v", organization, repository.calls, err)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestOwnedOrganizationDoesNotReturnUncommittedIdentity(t *testing.T) {
|
|
want := errors.New("durability failure")
|
|
repository := &ownedRepositoryStub{err: want}
|
|
service, _ := New(repository, Options{OwnerRole: "customer.owner"})
|
|
organization, err := service.CreateOwnedOrganization(t.Context(), CreateOrganization{Slug: "client-business", Name: "Client Business", OwnerUserID: "customer-12345"})
|
|
if !errors.Is(err, want) || organization.ID != "" || repository.calls != 1 {
|
|
t.Fatalf("organization=%+v calls=%d err=%v", organization, repository.calls, err)
|
|
}
|
|
}
|
|
|
|
func TestOwnedManagementHasNoPreflightOnlyFallback(t *testing.T) {
|
|
service, err := New(&repositoryStub{}, Options{OwnerRole: "customer.owner"})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
_, err = service.UpdateOwnedOrganization(t.Context(), UpdateOrganization{ID: "organization-12345", Slug: "business", Name: "Business", ActorUserID: "customer-12345", ExpectedRevision: 1})
|
|
if !errors.Is(err, ErrOwnedManagementUnsupported) {
|
|
t.Fatalf("profile fallback: %v", err)
|
|
}
|
|
err = service.ChangeOwnedMembershipStatus(t.Context(), MembershipStatusChange{OrganizationID: "organization-12345", UserID: "member-12345", ActorUserID: "customer-12345", ExpectedStatus: "active", Status: "suspended"})
|
|
if !errors.Is(err, ErrOwnedManagementUnsupported) {
|
|
t.Fatalf("status fallback: %v", err)
|
|
}
|
|
err = service.RemoveOwnedMembershipIfCurrent(t.Context(), MembershipRemoval{OrganizationID: "organization-12345", UserID: "member-12345", ActorUserID: "customer-12345", ExpectedStatus: "active"})
|
|
if !errors.Is(err, ErrOwnedManagementUnsupported) {
|
|
t.Fatalf("removal fallback: %v", err)
|
|
}
|
|
}
|