Skip to content

Commit

Permalink
#81. [Issues] Add statuses, add transition rules.
Browse files Browse the repository at this point in the history
  • Loading branch information
sys27 committed Aug 22, 2024
1 parent f0db4b1 commit 989a37a
Show file tree
Hide file tree
Showing 25 changed files with 377 additions and 95 deletions.
1 change: 1 addition & 0 deletions Pyro.Api/Pyro.Contracts/Responses/Issues/IssueResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ public record IssueResponse(
Guid Id,
int IssueNumber,
string Title,
StatusResponse Status,
UserResponse Author,
DateTimeOffset CreatedAt,
UserResponse? Assignee,
Expand Down
6 changes: 6 additions & 0 deletions Pyro.Api/Pyro.Contracts/Responses/Issues/StatusResponse.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// Copyright (c) Dmytro Kyshchenko. All rights reserved.
// Licensed under the GPL-3.0 license. See LICENSE file in the project root for full license information.

namespace Pyro.Contracts.Responses.Issues;

public record StatusResponse(Guid Id, string Name);
Original file line number Diff line number Diff line change
Expand Up @@ -64,16 +64,23 @@ public async Task CreateComment()
var currentUser = new CurrentUser(Guid.NewGuid(), "TestUser", [], []);
var author = new User(currentUser.Id, currentUser.Login);
var command = new CreateIssueComment("test", 1, "text");
var gitRepository = new GitRepository
{
Id = Guid.NewGuid(),
Name = "test",
};
var issue = new Issue
{
Id = Guid.NewGuid(),
IssueNumber = command.IssueNumber,
Title = "title",
Repository = new GitRepository
Status = new Status
{
Id = Guid.NewGuid(),
Name = "test",
Name = "status",
Repository = gitRepository,
},
RepositoryId = gitRepository.Id,
Author = author,
CreatedAt = DateTimeOffset.Now,
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ public async Task CreateIssueAndAssignToUser(User? assignee)
Assert.Multiple(() =>
{
Assert.That(issue.Title, Is.EqualTo(command.Title));
Assert.That(issue.Repository.Name, Is.EqualTo(command.RepositoryName));
Assert.That(issue.RepositoryId, Is.EqualTo(repository.Id));
Assert.That(issue.Author, Is.EqualTo(author));
Assert.That(issue.CreatedAt, Is.EqualTo(now));
Assert.That(issue.Assignee, Is.EqualTo(assignee));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,23 @@ public void MissingIssueComment()
const int issueNumber = 1;
var currentUser = new CurrentUser(Guid.NewGuid(), "User", [], []);
var author = new User(currentUser.Id, currentUser.Login);
var gitRepository = new GitRepository
{
Id = Guid.NewGuid(),
Name = "test",
};
var issue = new Issue
{
Id = Guid.NewGuid(),
IssueNumber = issueNumber,
Title = "title",
Repository = new GitRepository
Status = new Status
{
Id = Guid.NewGuid(),
Name = "test",
Name = "Open",
Repository = gitRepository,
},
RepositoryId = gitRepository.Id,
Author = author,
CreatedAt = DateTimeOffset.Now,
};
Expand All @@ -68,16 +75,23 @@ public void CurrentUserCantUpdateIssueComment()
const int issueNumber = 1;
var currentUser = new CurrentUser(Guid.NewGuid(), "User", [], []);
var author = new User(currentUser.Id, currentUser.Login);
var gitRepository = new GitRepository
{
Id = Guid.NewGuid(),
Name = "test",
};
var issue = new Issue
{
Id = Guid.NewGuid(),
IssueNumber = issueNumber,
Title = "title",
Repository = new GitRepository
Status = new Status
{
Id = Guid.NewGuid(),
Name = "test",
Name = "Open",
Repository = gitRepository,
},
RepositoryId = gitRepository.Id,
Author = author,
CreatedAt = DateTimeOffset.Now,
};
Expand Down Expand Up @@ -105,16 +119,23 @@ public async Task UpdateIssueComment()
const int issueNumber = 1;
var currentUser = new CurrentUser(Guid.NewGuid(), "User", [], []);
var author = new User(currentUser.Id, currentUser.Login);
var gitRepository = new GitRepository
{
Id = Guid.NewGuid(),
Name = "test",
};
var issue = new Issue
{
Id = Guid.NewGuid(),
IssueNumber = issueNumber,
Title = "title",
Repository = new GitRepository
Status = new Status
{
Id = Guid.NewGuid(),
Name = "test",
Name = "Open",
Repository = gitRepository,
},
RepositoryId = gitRepository.Id,
Author = author,
CreatedAt = DateTimeOffset.Now,
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,23 @@ public void MissingRepository()
{
var currentUser = new CurrentUser(Guid.NewGuid(), "User", [], []);
var command = new UpdateIssue("repo", 1, "title", null, []);
var gitRepository = new GitRepository
{
Id = Guid.NewGuid(),
Name = "test",
};
var issue = new Issue
{
Id = Guid.NewGuid(),
IssueNumber = command.IssueNumber,
Title = "title",
Repository = new GitRepository
Status = new Status
{
Id = Guid.NewGuid(),
Name = "test",
Name = "Open",
Repository = gitRepository,
},
RepositoryId = gitRepository.Id,
Author = new User(Guid.NewGuid(), "test"),
CreatedAt = DateTimeOffset.Now,
};
Expand Down Expand Up @@ -80,7 +87,13 @@ public void CurrentUserCantUpdateIssue()
Id = Guid.NewGuid(),
IssueNumber = command.IssueNumber,
Title = "title",
Repository = gitRepository,
Status = new Status
{
Id = Guid.NewGuid(),
Name = "Open",
Repository = gitRepository,
},
RepositoryId = gitRepository.Id,
Author = new User(Guid.NewGuid(), "test"),
CreatedAt = DateTimeOffset.Now,
};
Expand Down Expand Up @@ -139,7 +152,13 @@ public async Task UpdateIssue()
Id = Guid.NewGuid(),
IssueNumber = 1,
Title = "title",
Repository = gitRepository,
Status = new Status
{
Id = Guid.NewGuid(),
Name = "Open",
Repository = gitRepository,
},
RepositoryId = gitRepository.Id,
Author = author,
CreatedAt = DateTimeOffset.Now,
};
Expand Down
22 changes: 18 additions & 4 deletions Pyro.Api/Pyro.Domain.Issues.UnitTests/Models/IssueCommentTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,23 @@ public void AddCommentTest()
var createdAt = DateTimeOffset.Now;
var user = new User(Guid.NewGuid(), "user");

var gitRepository = new GitRepository
{
Id = Guid.NewGuid(),
Name = "test",
};
var issue = new Issue
{
Id = Guid.NewGuid(),
IssueNumber = 1,
Title = "title",
Repository = new GitRepository
Status = new Status
{
Id = Guid.NewGuid(),
Name = "test",
Name = "status",
Repository = gitRepository,
},
RepositoryId = gitRepository.Id,
Author = user,
CreatedAt = DateTimeOffset.Now,
};
Expand All @@ -43,16 +50,23 @@ public void DeleteCommentTest()
{
var user = new User(Guid.NewGuid(), "user");

var gitRepository = new GitRepository
{
Id = Guid.NewGuid(),
Name = "test",
};
var issue = new Issue
{
Id = Guid.NewGuid(),
IssueNumber = 1,
Title = "title",
Repository = new GitRepository
Status = new Status
{
Id = Guid.NewGuid(),
Name = "test",
Name = "status",
Repository = gitRepository,
},
RepositoryId = gitRepository.Id,
Author = user,
CreatedAt = DateTimeOffset.Now,
};
Expand Down
22 changes: 18 additions & 4 deletions Pyro.Api/Pyro.Domain.Issues.UnitTests/Models/IssueTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,23 @@ public void AssignToTest()
{
var user = new User(Guid.NewGuid(), "user");

var gitRepository = new GitRepository
{
Id = Guid.NewGuid(),
Name = "test",
};
var issue = new Issue
{
Id = Guid.NewGuid(),
IssueNumber = 1,
Title = "title",
Repository = new GitRepository
Status = new Status
{
Id = Guid.NewGuid(),
Name = "test",
Name = "status",
Repository = gitRepository,
},
RepositoryId = gitRepository.Id,
Author = user,
CreatedAt = DateTimeOffset.Now,
};
Expand All @@ -32,16 +39,23 @@ public void AssignToTest()
public void AddExistingLabel()
{
var user = new User(Guid.NewGuid(), "user");
var gitRepository = new GitRepository
{
Id = Guid.NewGuid(),
Name = "test",
};
var issue = new Issue
{
Id = Guid.NewGuid(),
IssueNumber = 1,
Title = "title",
Repository = new GitRepository
Status = new Status
{
Id = Guid.NewGuid(),
Name = "test",
Name = "status",
Repository = gitRepository,
},
RepositoryId = gitRepository.Id,
Author = user,
CreatedAt = DateTimeOffset.Now,
};
Expand Down
3 changes: 2 additions & 1 deletion Pyro.Api/Pyro.Domain.Issues/Commands/CreateIssue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ public async Task<Issue> Handle(CreateIssue request, CancellationToken cancellat
var issue = new Issue
{
Title = request.Title,
Repository = repository,
Status = null!, // TODO:
RepositoryId = repository.Id,
Author = author,
CreatedAt = timeProvider.GetUtcNow(),
};
Expand Down
5 changes: 5 additions & 0 deletions Pyro.Api/Pyro.Domain.Issues/GitRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,15 @@ namespace Pyro.Domain.Issues;

public class GitRepository : Entity
{
private readonly List<Status> statuses = [];

public required string Name { get; init; }

public IReadOnlyList<Label> Labels { get; init; } = new List<Label>();

public IReadOnlyList<Status> Statuses
=> statuses;

public Label? GetLabel(Guid labelId)
=> Labels.FirstOrDefault(x => x.Id == labelId);
}
4 changes: 3 additions & 1 deletion Pyro.Api/Pyro.Domain.Issues/Issue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ public class Issue : Entity

public required string Title { get; set; }

public required GitRepository Repository { get; init; }
public required Status Status { get; init; }

public required Guid RepositoryId { get; init; }

public required User Author { get; init; }

Expand Down
22 changes: 22 additions & 0 deletions Pyro.Api/Pyro.Domain.Issues/Status.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright (c) Dmytro Kyshchenko. All rights reserved.
// Licensed under the GPL-3.0 license. See LICENSE file in the project root for full license information.

using Pyro.Domain.Shared.Models;

namespace Pyro.Domain.Issues;

public class Status : Entity
{
private readonly List<StatusTranslation> fromTranslations = [];
private readonly List<StatusTranslation> toTranslations = [];

public required string Name { get; init; }

public required GitRepository Repository { get; init; }

public IReadOnlyList<StatusTranslation> FromTranslations
=> fromTranslations;

public IReadOnlyList<StatusTranslation> ToTranslations
=> toTranslations;
}
13 changes: 13 additions & 0 deletions Pyro.Api/Pyro.Domain.Issues/StatusTranslation.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright (c) Dmytro Kyshchenko. All rights reserved.
// Licensed under the GPL-3.0 license. See LICENSE file in the project root for full license information.

using Pyro.Domain.Shared.Models;

namespace Pyro.Domain.Issues;

public class StatusTranslation : Entity
{
public required Status From { get; init; }

public required Status To { get; init; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ public CreateLabelValidator()
.MaximumLength(50);

RuleFor(x => x.Color)
.NotEmpty()
.InclusiveBetween(0, 0xFFFFFF);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,21 @@ public void Configure(EntityTypeBuilder<Issue> builder)
.ValueGeneratedOnAdd()
.HasValueGenerator<IssueNumberValueGenerator>();

builder.Property<Guid>("RepositoryId")
builder.Property<Guid>("StatusId")
.IsRequired();

builder.HasOne(x => x.Repository)
builder.HasOne(x => x.Status)
.WithMany()
.HasForeignKey("RepositoryId")
.HasForeignKey("StatusId")
.OnDelete(DeleteBehavior.NoAction)
.HasConstraintName("FK_Issue_Status");

builder.Property(x => x.RepositoryId)
.IsRequired();

builder.HasOne<GitRepository>()
.WithMany()
.HasForeignKey(x => x.RepositoryId)
.OnDelete(DeleteBehavior.Cascade);

builder.Property<Guid>("AuthorId")
Expand Down
Loading

0 comments on commit 989a37a

Please sign in to comment.