diff --git a/src/Abstractions/TaskOptions.cs b/src/Abstractions/TaskOptions.cs index c38144b61..7c0d54ee2 100644 --- a/src/Abstractions/TaskOptions.cs +++ b/src/Abstractions/TaskOptions.cs @@ -30,6 +30,17 @@ public TaskOptions(TaskRetryOptions? retry = null, IDictionary? this.Tags = tags; } + /// + /// Initializes a new instance of the class by copying from another instance. + /// + /// The task options to copy from. + public TaskOptions(TaskOptions options) + { + Check.NotNull(options); + this.Retry = options.Retry; + this.Tags = options.Tags; + } + /// /// Gets the task retry options. /// @@ -96,12 +107,29 @@ public SubOrchestrationOptions(TaskOptions options, string? instanceId = null) : base(options) { this.InstanceId = instanceId; - if (instanceId is null && options is SubOrchestrationOptions derived) + if (options is SubOrchestrationOptions derived) { - this.InstanceId = derived.InstanceId; + if (instanceId is null) + { + this.InstanceId = derived.InstanceId; + } + + this.Version = derived.Version; } } + /// + /// Initializes a new instance of the class by copying from another instance. + /// + /// The sub-orchestration options to copy from. + public SubOrchestrationOptions(SubOrchestrationOptions options) + : base(options) + { + Check.NotNull(options); + this.InstanceId = options.InstanceId; + this.Version = options.Version; + } + /// /// Gets the orchestration instance ID. /// @@ -116,15 +144,51 @@ public SubOrchestrationOptions(TaskOptions options, string? instanceId = null) /// /// Options for submitting new orchestrations via the client. /// -/// -/// The unique ID of the orchestration instance to schedule. If not specified, a new GUID value is used. -/// -/// -/// The time when the orchestration instance should start executing. If not specified or if a date-time in the past -/// is specified, the orchestration instance will be scheduled immediately. -/// -public record StartOrchestrationOptions(string? InstanceId = null, DateTimeOffset? StartAt = null) +public record StartOrchestrationOptions { + /// + /// Initializes a new instance of the class. + /// + /// + /// The unique ID of the orchestration instance to schedule. If not specified, a new GUID value is used. + /// + /// + /// The time when the orchestration instance should start executing. If not specified or if a date-time in the past + /// is specified, the orchestration instance will be scheduled immediately. + /// +#pragma warning disable SA1313 // Parameter names should begin with lower-case letter - using PascalCase to maintain backward compatibility with positional record syntax + public StartOrchestrationOptions(string? InstanceId = null, DateTimeOffset? StartAt = null) +#pragma warning restore SA1313 + { + this.InstanceId = InstanceId; + this.StartAt = StartAt; + } + + /// + /// Initializes a new instance of the class by copying from another instance. + /// + /// The start orchestration options to copy from. + public StartOrchestrationOptions(StartOrchestrationOptions options) + { + Check.NotNull(options); + this.InstanceId = options.InstanceId; + this.StartAt = options.StartAt; + this.Tags = options.Tags; + this.Version = options.Version; + this.DedupeStatuses = options.DedupeStatuses; + } + + /// + /// Gets the unique ID of the orchestration instance to schedule. If not specified, a new GUID value is used. + /// + public string? InstanceId { get; init; } + + /// + /// Gets the time when the orchestration instance should start executing. If not specified or if a date-time in the past + /// is specified, the orchestration instance will be scheduled immediately. + /// + public DateTimeOffset? StartAt { get; init; } + /// /// Gets the tags to associate with the orchestration instance. /// diff --git a/test/Abstractions.Tests/TaskOptionsTests.cs b/test/Abstractions.Tests/TaskOptionsTests.cs index 3e805a9ef..1576a91b9 100644 --- a/test/Abstractions.Tests/TaskOptionsTests.cs +++ b/test/Abstractions.Tests/TaskOptionsTests.cs @@ -148,4 +148,98 @@ public void WithDedupeStatuses_ConvertsAllEnumValuesToStrings() result.DedupeStatuses.Should().Contain(status.ToString()); } } + + [Fact] + public void TaskOptions_CopyConstructor_CopiesAllProperties() + { + // Arrange + RetryPolicy policy = new(3, TimeSpan.FromSeconds(1)); + TaskRetryOptions retry = new(policy); + Dictionary tags = new() { { "key1", "value1" }, { "key2", "value2" } }; + TaskOptions original = new(retry, tags); + + // Act + TaskOptions copy = new(original); + + // Assert + copy.Retry.Should().Be(original.Retry); + copy.Tags.Should().BeSameAs(original.Tags); + } + + [Fact] + public void SubOrchestrationOptions_CopyConstructor_CopiesAllProperties() + { + // Arrange + RetryPolicy policy = new(3, TimeSpan.FromSeconds(1)); + TaskRetryOptions retry = new(policy); + Dictionary tags = new() { { "key1", "value1" }, { "key2", "value2" } }; + string instanceId = Guid.NewGuid().ToString(); + TaskVersion version = new("1.0"); + SubOrchestrationOptions original = new(retry, instanceId) + { + Tags = tags, + Version = version, + }; + + // Act + SubOrchestrationOptions copy = new(original); + + // Assert + copy.Retry.Should().Be(original.Retry); + copy.Tags.Should().BeSameAs(original.Tags); + copy.InstanceId.Should().Be(original.InstanceId); + copy.Version.Should().Be(original.Version); + } + + [Fact] + public void SubOrchestrationOptions_CopyFromTaskOptions_CopiesVersionWhenSourceIsSubOrchestration() + { + // Arrange + RetryPolicy policy = new(3, TimeSpan.FromSeconds(1)); + TaskRetryOptions retry = new(policy); + Dictionary tags = new() { { "key1", "value1" } }; + string instanceId = Guid.NewGuid().ToString(); + TaskVersion version = new("1.0"); + SubOrchestrationOptions original = new(retry, instanceId) + { + Tags = tags, + Version = version, + }; + + // Act + SubOrchestrationOptions copy = new(original as TaskOptions); + + // Assert + copy.Retry.Should().Be(original.Retry); + copy.Tags.Should().BeSameAs(original.Tags); + copy.InstanceId.Should().Be(original.InstanceId); + copy.Version.Should().Be(original.Version); + } + + [Fact] + public void StartOrchestrationOptions_CopyConstructor_CopiesAllProperties() + { + // Arrange + string instanceId = Guid.NewGuid().ToString(); + DateTimeOffset startAt = DateTimeOffset.UtcNow.AddHours(1); + Dictionary tags = new() { { "key1", "value1" }, { "key2", "value2" } }; + TaskVersion version = new("1.0"); + List dedupeStatuses = new() { "Completed", "Failed" }; + StartOrchestrationOptions original = new(instanceId, startAt) + { + Tags = tags, + Version = version, + DedupeStatuses = dedupeStatuses, + }; + + // Act + StartOrchestrationOptions copy = new(original); + + // Assert + copy.InstanceId.Should().Be(original.InstanceId); + copy.StartAt.Should().Be(original.StartAt); + copy.Tags.Should().BeSameAs(original.Tags); + copy.Version.Should().Be(original.Version); + copy.DedupeStatuses.Should().BeSameAs(original.DedupeStatuses); + } }