using DodoSSH.Contracts; using DodoSSH.Domain; using DodoSSH.Domain.Authorization; namespace DodoSSH.Api.Tests; /// /// The team enums on the wire and the ones in the domain have to agree, and nothing but this makes them. /// /// /// /// The same hazard EntityTypeAlignmentTests exists for, one feature along and with a worse failure. /// TeamService maps to member by member, so a /// renumbering on one side does not fail to compile — it silently changes what a role means. Someone /// added as a viewer would come back as an admin, or the reverse, on the next deployment. /// /// /// Mapped by name in the service and asserted by value here, which is the pairing that /// catches the mistake: the service would go on compiling after a renumbering, and this would not go on /// passing. /// /// public sealed class TeamEnumAlignmentTests { [Fact] public void EveryWireRole_HasADomainRoleWithTheSameValue() { ((int)TeamMemberRole.Unspecified).ShouldBe((int)TeamRole.Unspecified); ((int)TeamMemberRole.Viewer).ShouldBe((int)TeamRole.Viewer); ((int)TeamMemberRole.Member).ShouldBe((int)TeamRole.Member); ((int)TeamMemberRole.Admin).ShouldBe((int)TeamRole.Admin); ((int)TeamMemberRole.Owner).ShouldBe((int)TeamRole.Owner); } [Fact] public void TheTwoRoleEnums_HaveTheSameNumberOfMembers() => Enum.GetValues().Length.ShouldBe(Enum.GetValues().Length); [Fact] public void EveryWireMembershipStatus_HasADomainStatusWithTheSameValue() { ((int)TeamMemberStatus.Unspecified).ShouldBe((int)MembershipStatus.Unspecified); ((int)TeamMemberStatus.Invited).ShouldBe((int)MembershipStatus.Invited); ((int)TeamMemberStatus.Active).ShouldBe((int)MembershipStatus.Active); ((int)TeamMemberStatus.Revoked).ShouldBe((int)MembershipStatus.Revoked); } [Fact] public void EveryWireGrantState_HasADomainStateWithTheSameValue() { ((int)VaultGrantState.Unspecified).ShouldBe((int)GrantState.Unspecified); ((int)VaultGrantState.Active).ShouldBe((int)GrantState.Active); ((int)VaultGrantState.AwaitingRewrap).ShouldBe((int)GrantState.AwaitingRewrap); ((int)VaultGrantState.Revoked).ShouldBe((int)GrantState.Revoked); } /// /// /// VaultSummary.Permissions is an opaque int on the wire, on purpose — the flags live in /// DodoSSH.Domain and no client project references that assembly. So the client repeats the one /// bit it needs as a literal in StoredVault.CanWrite, and this pins the value it copied. /// /// /// Asserted here rather than against StoredVault itself, which would mean a server test project /// taking a reference on a client assembly to check a constant. The consequence of drift is worth the /// literal either way: a Save button offered to somebody who is only a viewer of a team vault, ending /// in a 403 they can do nothing about — or no Save button for somebody who may write. /// /// [Fact] public void TheWriteFlag_IsTheBitTheClientCopied() { ((int)PermissionFlags.Read).ShouldBe(1 << 0); ((int)PermissionFlags.Write).ShouldBe(1 << 1); } }