diff --git a/Modules/Relationships/src/Relationships.Domain/Aggregates/RelationshipTemplates/RelationshipTemplate.CanBeCollectedWithPasswordTests.cs b/Modules/Relationships/src/Relationships.Domain/Aggregates/RelationshipTemplates/RelationshipTemplate.CanBeCollectedWithPasswordTests.cs new file mode 100644 index 0000000000..e183151289 --- /dev/null +++ b/Modules/Relationships/src/Relationships.Domain/Aggregates/RelationshipTemplates/RelationshipTemplate.CanBeCollectedWithPasswordTests.cs @@ -0,0 +1,90 @@ +using Backbone.Modules.Relationships.Domain.TestHelpers; +using Backbone.UnitTestTools.BaseClasses; +using Backbone.UnitTestTools.Data; +using FluentAssertions; +using Xunit; + +namespace Backbone.Modules.Relationships.Domain.Aggregates.RelationshipTemplates; + +public class RelationshipTemplateCanBeCollectedWithPasswordTests : AbstractTestsBase +{ + [Fact] + public void Can_collect_without_a_password_when_no_password_is_defined() + { + // Arrange + var creator = TestDataGenerator.CreateRandomIdentityAddress(); + var collector = TestDataGenerator.CreateRandomIdentityAddress(); + + var template = TestData.CreateRelationshipTemplate(creator); + + // Act + var result = template.CanBeCollectedUsingPassword(collector, null); + + // Assert + result.Should().BeTrue(); + } + + [Fact] + public void Can_collect_with_correct_password() + { + // Arrange + var creator = TestDataGenerator.CreateRandomIdentityAddress(); + var collector = TestDataGenerator.CreateRandomIdentityAddress(); + + var template = TestData.CreateRelationshipTemplate(creator, password: [1]); + + // Act + var result = template.CanBeCollectedUsingPassword(collector, [1]); + + // Assert + result.Should().BeTrue(); + } + + [Fact] + public void Cannot_collect_with_incorrect_password() + { + // Arrange + var creator = TestDataGenerator.CreateRandomIdentityAddress(); + var collector = TestDataGenerator.CreateRandomIdentityAddress(); + + var template = TestData.CreateRelationshipTemplate(creator, password: [1]); + + // Act + var result = template.CanBeCollectedUsingPassword(collector, [2]); + + // Assert + result.Should().BeFalse(); + } + + [Fact] + public void Can_collect_as_owner_without_a_password() + { + // Arrange + var creator = TestDataGenerator.CreateRandomIdentityAddress(); + + var template = TestData.CreateRelationshipTemplate(creator, password: [1]); + + // Act + var result = template.CanBeCollectedUsingPassword(creator, null); + + // Assert + result.Should().BeTrue(); + } + + [Fact] + public void Can_collect_without_password_when_template_is_already_allocated_by_me() + { + // Arrange + var creator = TestDataGenerator.CreateRandomIdentityAddress(); + var collector = TestDataGenerator.CreateRandomIdentityAddress(); + + var template = TestData.CreateRelationshipTemplate(creator, password: [1]); + template.AllocateFor(collector, TestDataGenerator.CreateRandomDeviceId()); + + // Act + var result = template.CanBeCollectedUsingPassword(collector, null); + + // Assert + result.Should().BeTrue(); + } +} diff --git a/Modules/Relationships/src/Relationships.Domain/Aggregates/RelationshipTemplates/RelationshipTemplate.cs b/Modules/Relationships/src/Relationships.Domain/Aggregates/RelationshipTemplates/RelationshipTemplate.cs index 67ca001ad7..7c2e3d3306 100644 --- a/Modules/Relationships/src/Relationships.Domain/Aggregates/RelationshipTemplates/RelationshipTemplate.cs +++ b/Modules/Relationships/src/Relationships.Domain/Aggregates/RelationshipTemplates/RelationshipTemplate.cs @@ -70,12 +70,15 @@ public void AllocateFor(IdentityAddress identity, DeviceId device) public bool IsAllocatedBy(IdentityAddress identity) { - return Allocations.All(x => x.AllocatedBy != identity); + return Allocations.Any(x => x.AllocatedBy == identity); } - public bool CanBeCollectedUsingPassword(IdentityAddress address, byte[]? password) + public bool CanBeCollectedUsingPassword(IdentityAddress activeIdentity, byte[]? password) { - return Password == null || password != null && Password.SequenceEqual(password) || CreatedBy == address; + return Password == null || + password != null && Password.SequenceEqual(password) || + CreatedBy == activeIdentity || // The owner shouldn't need a password to get the template + Allocations.Any(a => a.AllocatedBy == activeIdentity); // if the template has already been allocated by the active identity, it doesn't need to pass the password again } #region Expressions diff --git a/Modules/Relationships/src/Relationships.Domain/TestHelpers/TestData.cs b/Modules/Relationships/src/Relationships.Domain/TestHelpers/TestData.cs index fbdadddfc2..c7f4fcebdd 100644 --- a/Modules/Relationships/src/Relationships.Domain/TestHelpers/TestData.cs +++ b/Modules/Relationships/src/Relationships.Domain/TestHelpers/TestData.cs @@ -15,9 +15,9 @@ public static class TestData public static readonly RelationshipTemplate RELATIONSHIP_TEMPLATE_OF_1 = new(IDENTITY_1, DEVICE_1, 1, null, []); public static readonly RelationshipTemplate RELATIONSHIP_TEMPLATE_OF_2 = new(IDENTITY_2, DEVICE_2, 1, null, []); - public static RelationshipTemplate CreateRelationshipTemplate(IdentityAddress creatorAddress, IdentityAddress? forIdentityAddress) + public static RelationshipTemplate CreateRelationshipTemplate(IdentityAddress creatorAddress, IdentityAddress? forIdentityAddress = null, byte[]? password = null) { - return new RelationshipTemplate(creatorAddress, DeviceId.New(), 999, null, [], forIdentityAddress); + return new RelationshipTemplate(creatorAddress, DeviceId.New(), 999, null, [], forIdentityAddress, password); } public static Relationship CreatePendingRelationship(IdentityAddress? from = null, IdentityAddress? to = null)