public async Task WorkItemManager_ExecuteCommand_Invoke()
        {
            // arrange
            var manager = new WorkItemManager(new InMemoryDataProvider(), new InMemoryDescriptorProvider(
                                                  WorkItemDescriptor.Create("BAR", new PropertyDescriptor[] {
                PropertyDescriptor.Create("A", "String", initialValue: "a"),
                PropertyDescriptor.Create("B", "String"),
            },
                                                                            stages: new StageDescriptor[] {
                new StageDescriptor("stage-aa", new PropertyValueConditionDescriptor("A", "aa"),
                                    Array.Empty <StagePropertyDescriptor>(),
                                    new CommandDescriptor[] {
                    new ChangePropertyValueCommandDescriptor("make-bb", "MakeBBC", "B", "bbc")
                }),
            })
                                                  ));

            var issue = await manager.CreateAsync("FOO", "BAR", new Property[] {
                new Property("A", "String", "aa"),
                new Property("B", "String", "bb"),
            });

            // act
            var result = await manager.ExecuteCommandAsync("FOO", issue.Id, "make-bb");

            // assert
            Assert.True(result.Success);
            Assert.Collection(result.UpdatedWorkItem.Properties,
                              p => { Assert.Equal("aa", p.Value); Assert.Equal("A", p.Name); },
                              p => { Assert.Equal("bbc", p.Value); Assert.Equal("B", p.Name); }
                              );
        }
        public async Task ImmutableValidator_Validate_InternalEditSuccess()
        {
            // arrange
            WorkItemManager manager = BuildManager();

            var properties = new Property[] {
                new Property("A", "String", "aa"),
                new Property("B", "String", string.Empty),
            };

            // act
            var result1 = await manager.CreateAsync("FOO", "BAR", properties);

            var result = await manager.ExecuteCommandAsync("FOO", result1.CreatedWorkItem.Id, "set");

            // assert
            Assert.NotNull(result);
            Assert.True(result.Success);
            Assert.NotNull(result.UpdatedWorkItem);
            Assert.Empty(result.Errors);
        }
        public async Task WorkItemManager_ExecuteCommand_NotFound()
        {
            // arrange
            var manager = new WorkItemManager(new InMemoryDataProvider(), new InMemoryDescriptorProvider(
                                                  WorkItemDescriptor.Create("BAR", new PropertyDescriptor[] {
                PropertyDescriptor.Create("A", "String", initialValue: "a"),
                PropertyDescriptor.Create("B", "String"),
            })
                                                  ));

            var issue = await manager.CreateAsync("FOO", "BAR", new Property[] {
                new Property("A", "String", "aa"),
                new Property("B", "String", "bb"),
            });

            // act
            var result = await manager.ExecuteCommandAsync("FOO", issue.Id, "Close");

            // assert
            Assert.False(result.Success);
        }
        public static async Task <int> ExecuteAsync(WorkItemManager manager, string?projectCode, string?id, string?command)
        {
            if (manager is null)
            {
                throw new ArgumentNullException(nameof(manager));
            }

            if (string.IsNullOrWhiteSpace(projectCode))
            {
                throw new ArgumentException("message", nameof(projectCode));
            }

            if (string.IsNullOrWhiteSpace(id))
            {
                throw new ArgumentException("message", nameof(id));
            }

            if (string.IsNullOrWhiteSpace(command))
            {
                throw new ArgumentNullException(nameof(command));
            }

            var result = await manager.ExecuteCommandAsync(projectCode, id, command);

            if (result.Success)
            {
                Console.WriteLine($"Updated WorkItem and execute command {command} in project {result.UpdatedWorkItem?.ProjectCode} with id {result.UpdatedWorkItem?.Id}");
            }
            else
            {
                Console.WriteLine($"Failed to update WorkItem and execute command {command}");

                foreach (var error in result.Errors)
                {
                    Console.WriteLine($"{error.Property}: {error.Message}");
                }
            }

            return(result.Success ? 0 : 1);
        }