diff --git a/Source/.editorconfig b/Source/.editorconfig index ff4d6c486..e4992cb14 100644 --- a/Source/.editorconfig +++ b/Source/.editorconfig @@ -9,6 +9,7 @@ dotnet_diagnostic.IDE0001.severity = warning dotnet_diagnostic.IDE0002.severity = warning # IDE0003 and IDE0009 +dotnet_diagnostic.SA0001.severity = none dotnet_diagnostic.IDE0003.severity = warning dotnet_diagnostic.IDE0009.severity = warning dotnet_style_qualification_for_field = false:warning diff --git a/Source/Application/Kysect.Shreks.Application.Abstractions/Google/ITableUpdateQueue.cs b/Source/Application/Kysect.Shreks.Application.Abstractions/Google/ITableUpdateQueue.cs index fc81f5c84..eb2e2ded1 100644 --- a/Source/Application/Kysect.Shreks.Application.Abstractions/Google/ITableUpdateQueue.cs +++ b/Source/Application/Kysect.Shreks.Application.Abstractions/Google/ITableUpdateQueue.cs @@ -3,5 +3,6 @@ public interface ITableUpdateQueue { void EnqueueSubmissionsQueueUpdate(Guid subjectCourseId, Guid studentGroupId); + void EnqueueCoursePointsUpdate(Guid subjectCourseId); } \ No newline at end of file diff --git a/Source/Application/Kysect.Shreks.Application.Dto/Querying/QueryParameter.cs b/Source/Application/Kysect.Shreks.Application.Dto/Querying/QueryParameter.cs index 75f3e4b83..bd3bd04f5 100644 --- a/Source/Application/Kysect.Shreks.Application.Dto/Querying/QueryParameter.cs +++ b/Source/Application/Kysect.Shreks.Application.Dto/Querying/QueryParameter.cs @@ -9,6 +9,7 @@ public QueryParameter(T type, string pattern) } public T Type { get; set; } + public string Pattern { get; set; } public void Deconstruct(out T type, out string pattern) diff --git a/Source/Application/Kysect.Shreks.Application.Dto/Study/StudyGroupDto.cs b/Source/Application/Kysect.Shreks.Application.Dto/Study/StudyGroupDto.cs index 2c50344c4..59bbdc540 100644 --- a/Source/Application/Kysect.Shreks.Application.Dto/Study/StudyGroupDto.cs +++ b/Source/Application/Kysect.Shreks.Application.Dto/Study/StudyGroupDto.cs @@ -9,6 +9,7 @@ public StudyGroupDto(Guid id, string name) } public Guid Id { get; set; } + public string Name { get; set; } public void Deconstruct(out Guid id, out string name) diff --git a/Source/Application/Kysect.Shreks.Application.GithubWorkflow.Abstractions/ISubjectCourseGithubOrganizationInviteSender.cs b/Source/Application/Kysect.Shreks.Application.GithubWorkflow.Abstractions/ISubjectCourseGithubOrganizationInviteSender.cs index 4355141ba..7e5f8a3ac 100644 --- a/Source/Application/Kysect.Shreks.Application.GithubWorkflow.Abstractions/ISubjectCourseGithubOrganizationInviteSender.cs +++ b/Source/Application/Kysect.Shreks.Application.GithubWorkflow.Abstractions/ISubjectCourseGithubOrganizationInviteSender.cs @@ -1,10 +1,5 @@ namespace Kysect.Shreks.Application.GithubWorkflow.Abstractions; -public interface ISubjectCourseGithubOrganizationManager -{ - Task UpdateOrganizations(CancellationToken cancellationToken); -} - public interface ISubjectCourseGithubOrganizationInviteSender { Task Invite(string organizationName, IReadOnlyCollection usernames); diff --git a/Source/Application/Kysect.Shreks.Application.GithubWorkflow.Abstractions/ISubjectCourseGithubOrganizationManager.cs b/Source/Application/Kysect.Shreks.Application.GithubWorkflow.Abstractions/ISubjectCourseGithubOrganizationManager.cs new file mode 100644 index 000000000..b2683db32 --- /dev/null +++ b/Source/Application/Kysect.Shreks.Application.GithubWorkflow.Abstractions/ISubjectCourseGithubOrganizationManager.cs @@ -0,0 +1,6 @@ +namespace Kysect.Shreks.Application.GithubWorkflow.Abstractions; + +public interface ISubjectCourseGithubOrganizationManager +{ + Task UpdateOrganizations(CancellationToken cancellationToken); +} \ No newline at end of file diff --git a/Source/Application/Kysect.Shreks.Application.GithubWorkflow.Abstractions/ISubjectCourseGithubOrganizationRepositoryManager.cs b/Source/Application/Kysect.Shreks.Application.GithubWorkflow.Abstractions/ISubjectCourseGithubOrganizationRepositoryManager.cs index 59633d0f1..75b9a4cfa 100644 --- a/Source/Application/Kysect.Shreks.Application.GithubWorkflow.Abstractions/ISubjectCourseGithubOrganizationRepositoryManager.cs +++ b/Source/Application/Kysect.Shreks.Application.GithubWorkflow.Abstractions/ISubjectCourseGithubOrganizationRepositoryManager.cs @@ -3,6 +3,8 @@ public interface ISubjectCourseGithubOrganizationRepositoryManager { Task> GetRepositories(string organization); + Task CreateRepositoryFromTemplate(string organization, string newRepositoryName, string templateName); + Task AddAdminPermission(string organization, string repositoryName, string username); } \ No newline at end of file diff --git a/Source/Application/Kysect.Shreks.Application.GithubWorkflow.Abstractions/Kysect.Shreks.Application.GithubWorkflow.Abstractions.csproj b/Source/Application/Kysect.Shreks.Application.GithubWorkflow.Abstractions/Kysect.Shreks.Application.GithubWorkflow.Abstractions.csproj index 5fad1cdd4..436074fa6 100644 --- a/Source/Application/Kysect.Shreks.Application.GithubWorkflow.Abstractions/Kysect.Shreks.Application.GithubWorkflow.Abstractions.csproj +++ b/Source/Application/Kysect.Shreks.Application.GithubWorkflow.Abstractions/Kysect.Shreks.Application.GithubWorkflow.Abstractions.csproj @@ -9,12 +9,12 @@ - - + + - + \ No newline at end of file diff --git a/Source/Application/Kysect.Shreks.Application.GithubWorkflow.Abstractions/Models/TestEnvironmentConfiguration.cs b/Source/Application/Kysect.Shreks.Application.GithubWorkflow.Abstractions/Models/TestEnvironmentConfiguration.cs index 6dede218c..d6a8fd1b3 100644 --- a/Source/Application/Kysect.Shreks.Application.GithubWorkflow.Abstractions/Models/TestEnvironmentConfiguration.cs +++ b/Source/Application/Kysect.Shreks.Application.GithubWorkflow.Abstractions/Models/TestEnvironmentConfiguration.cs @@ -3,6 +3,8 @@ namespace Kysect.Shreks.Application.GithubWorkflow.Abstractions.Models; public class TestEnvironmentConfiguration { public string Organization { get; init; } = string.Empty; + public string TemplateRepository { get; init; } = string.Empty; + public IReadOnlyList Users { get; init; } = new List(); } \ No newline at end of file diff --git a/Source/Application/Kysect.Shreks.Application.GithubWorkflow/Factories/GithubSubmissionFactory.cs b/Source/Application/Kysect.Shreks.Application.GithubWorkflow/Factories/GithubSubmissionFactory.cs index 3efe92579..279c3f288 100644 --- a/Source/Application/Kysect.Shreks.Application.GithubWorkflow/Factories/GithubSubmissionFactory.cs +++ b/Source/Application/Kysect.Shreks.Application.GithubWorkflow/Factories/GithubSubmissionFactory.cs @@ -88,8 +88,7 @@ public async Task CreateAsync(Guid userId, Guid assignmentId, Cancel .WithSpecification(studentAssignmentSubmissionsSpec) .CountAsync(cancellationToken); - return new GithubSubmission - ( + return new GithubSubmission( count + 1, student, groupAssignment, @@ -97,8 +96,7 @@ public async Task CreateAsync(Guid userId, Guid assignmentId, Cancel _payload, _organizationName, _repositoryName, - _pullRequestNumber - ); + _pullRequestNumber); } private async Task FindStudentByRepositoryName( diff --git a/Source/Application/Kysect.Shreks.Application.GithubWorkflow/OrganizationManagement/SubjectCourseGithubOrganizationManager.cs b/Source/Application/Kysect.Shreks.Application.GithubWorkflow/OrganizationManagement/SubjectCourseGithubOrganizationManager.cs index 0265b1415..853d38771 100644 --- a/Source/Application/Kysect.Shreks.Application.GithubWorkflow/OrganizationManagement/SubjectCourseGithubOrganizationManager.cs +++ b/Source/Application/Kysect.Shreks.Application.GithubWorkflow/OrganizationManagement/SubjectCourseGithubOrganizationManager.cs @@ -40,7 +40,10 @@ public async Task UpdateOrganizations(CancellationToken cancellationToken) await _context.SubjectCourses.GetAllGithubUsers(subjectAssociation.SubjectCourse.Id); var usernames = githubUserAssociations.Select(a => a.GithubUsername).ToList(); await _inviteSender.Invite(subjectAssociation.GithubOrganizationName, usernames); - await GenerateRepositories(_repositoryManager, usernames, subjectAssociation.GithubOrganizationName, + await GenerateRepositories( + _repositoryManager, + usernames, + subjectAssociation.GithubOrganizationName, subjectAssociation.TemplateRepositoryName); } } diff --git a/Source/Application/Kysect.Shreks.Application.Google/Services/SubjectCourseTableService.cs b/Source/Application/Kysect.Shreks.Application.Google/Services/SubjectCourseTableService.cs index 1f0b4c83c..ecb2b5cb0 100644 --- a/Source/Application/Kysect.Shreks.Application.Google/Services/SubjectCourseTableService.cs +++ b/Source/Application/Kysect.Shreks.Application.Google/Services/SubjectCourseTableService.cs @@ -40,7 +40,8 @@ public Task GetSubjectCourseTableId(Guid subjectCourseId, CancellationTo if (spreadsheetAssociation is not null) return spreadsheetAssociation.SpreadsheetId; - _logger.LogInformation("Spreadsheet of course {SubjectCourseId} was not found and will be created.", + _logger.LogInformation( + "Spreadsheet of course {SubjectCourseId} was not found and will be created", subjectCourseId); SubjectCourse subjectCourse = await _context.SubjectCourses.GetByIdAsync(id, cancellationToken); @@ -52,7 +53,9 @@ public Task GetSubjectCourseTableId(Guid subjectCourseId, CancellationTo _context.SubjectCourseAssociations.Add(spreadsheetAssociation); await _context.SaveChangesAsync(cancellationToken); - _logger.LogInformation("Successfully created spreadsheet of course {SubjectCourseId}.", subjectCourseId); + _logger.LogInformation( + "Successfully created spreadsheet of course {SubjectCourseId}", + subjectCourseId); _tableIdCache.TryRemove(id, out _); return spreadsheetId; diff --git a/Source/Application/Kysect.Shreks.Application.Google/Services/TableUpdateQueue.cs b/Source/Application/Kysect.Shreks.Application.Google/Services/TableUpdateQueue.cs index 4634e2cd4..c973e0571 100644 --- a/Source/Application/Kysect.Shreks.Application.Google/Services/TableUpdateQueue.cs +++ b/Source/Application/Kysect.Shreks.Application.Google/Services/TableUpdateQueue.cs @@ -11,7 +11,8 @@ public TableUpdateQueue() PointsUpdateSubjectCourseIds = new ConcurrentHashSet(); } - public ConcurrentHashSet<(Guid, Guid)> QueueUpdateSubjectCourseGroupIds { get; } + public ConcurrentHashSet<(Guid SubjectCourseId, Guid StudentGroupId)> QueueUpdateSubjectCourseGroupIds { get; } + public ConcurrentHashSet PointsUpdateSubjectCourseIds { get; } public void EnqueueSubmissionsQueueUpdate(Guid subjectCourseId, Guid studentGroupId) diff --git a/Source/Application/Kysect.Shreks.Application.Handlers/Github/CreateGithubSubmissionHandler.cs b/Source/Application/Kysect.Shreks.Application.Handlers/Github/CreateGithubSubmissionHandler.cs index 940e25985..571b478bb 100644 --- a/Source/Application/Kysect.Shreks.Application.Handlers/Github/CreateGithubSubmissionHandler.cs +++ b/Source/Application/Kysect.Shreks.Application.Handlers/Github/CreateGithubSubmissionHandler.cs @@ -19,14 +19,12 @@ public CreateGithubSubmissionHandler(IShreksDatabaseContext context) public async Task Handle(Command request, CancellationToken cancellationToken) { - var factory = new GithubSubmissionFactory - ( + var factory = new GithubSubmissionFactory( _context, request.OrganizationName, request.RepositoryName, request.PullRequestNumber, - request.Payload - ); + request.Payload); Submission submission = await factory.CreateAsync( request.IssuerId, request.AssignmentId, cancellationToken); diff --git a/Source/Application/Kysect.Shreks.Application.Handlers/GithubEvents/PullRequestUpdatedHandler.cs b/Source/Application/Kysect.Shreks.Application.Handlers/GithubEvents/PullRequestUpdatedHandler.cs index 9ae7193f7..76bc84d4d 100644 --- a/Source/Application/Kysect.Shreks.Application.Handlers/GithubEvents/PullRequestUpdatedHandler.cs +++ b/Source/Application/Kysect.Shreks.Application.Handlers/GithubEvents/PullRequestUpdatedHandler.cs @@ -36,14 +36,12 @@ public async Task Handle(Command request, CancellationToken cancellati ISubmissionWorkflow workflow = await _submissionWorkflowService.GetSubjectCourseWorkflowAsync( subjectCourse.Id, cancellationToken); - var submissionFactory = new GithubSubmissionFactory - ( + var submissionFactory = new GithubSubmissionFactory( _context, request.OrganizationName, request.RepositoryName, request.PullRequestNumber, - request.Payload - ); + request.Payload); SubmissionUpdateResult result = await workflow.SubmissionUpdatedAsync( request.IssuerId, request.UserId, request.AssignmentId, submissionFactory, cancellationToken); diff --git a/Source/Application/Kysect.Shreks.Application.Handlers/Google/SubjectCourseGroupQueueUpdatedHandler.cs b/Source/Application/Kysect.Shreks.Application.Handlers/Google/SubjectCourseGroupQueueUpdatedHandler.cs index d4fa9070b..c26612e60 100644 --- a/Source/Application/Kysect.Shreks.Application.Handlers/Google/SubjectCourseGroupQueueUpdatedHandler.cs +++ b/Source/Application/Kysect.Shreks.Application.Handlers/Google/SubjectCourseGroupQueueUpdatedHandler.cs @@ -50,8 +50,11 @@ public async Task Handle( } catch (Exception e) { - _logger.LogError(e, "Error while updating queue for subject course {SubjectCourseId} group {GroupId}", - notification.SubjectCourseId, notification.GroupId); + _logger.LogError( + e, + "Error while updating queue for subject course {SubjectCourseId} group {GroupId}", + notification.SubjectCourseId, + notification.GroupId); } } diff --git a/Source/Application/Kysect.Shreks.Application.Handlers/Google/SubjectCoursePointsUpdatedHandler.cs b/Source/Application/Kysect.Shreks.Application.Handlers/Google/SubjectCoursePointsUpdatedHandler.cs index bf0c524d1..44aa1bd5d 100644 --- a/Source/Application/Kysect.Shreks.Application.Handlers/Google/SubjectCoursePointsUpdatedHandler.cs +++ b/Source/Application/Kysect.Shreks.Application.Handlers/Google/SubjectCoursePointsUpdatedHandler.cs @@ -37,7 +37,9 @@ public async Task Handle(SubjectCoursePointsUpdatedNotification notification, Ca } catch (Exception e) { - _logger.LogError(e, "Error updating course points for subject course {SubjectCourseId}", + _logger.LogError( + e, + "Error updating course points for subject course {SubjectCourseId}", notification.SubjectCourseId); } } @@ -46,7 +48,8 @@ private async Task ExecuteAsync( SubjectCoursePointsUpdatedNotification notification, CancellationToken cancellationToken) { - _logger.LogInformation("Start updating for points sheet of course {SubjectCourseId}.", + _logger.LogInformation( + "Start updating for points sheet of course {SubjectCourseId}.", notification.SubjectCourseId); _logger.LogInformation("Started to collecting all course {courseId} points", notification.SubjectCourseId); @@ -69,8 +72,12 @@ private async Task ExecuteAsync( foreach ((StudentPointsDto student, AssignmentPointsDto studentPoints, AssignmentDto assignment) in table) { - _logger.LogTrace("\t{Student} - {Assignment}: {Points}, banned: {Banned}", - student.Student.GitHubUsername, assignment.Title, studentPoints.Points, studentPoints.IsBanned); + _logger.LogTrace( + "\t{Student} - {Assignment}: {Points}, banned: {Banned}", + student.Student.GitHubUsername, + assignment.Title, + studentPoints.Points, + studentPoints.IsBanned); } } @@ -79,7 +86,8 @@ private async Task ExecuteAsync( await _sheet.UpdateAsync(spreadsheetId, points, cancellationToken); - _logger.LogInformation("Successfully updated points sheet of course {SubjectCourseId}.", + _logger.LogInformation( + "Successfully updated points sheet of course {SubjectCourseId}", notification.SubjectCourseId); } } \ No newline at end of file diff --git a/Source/Application/Kysect.Shreks.Application.Handlers/Identity/LoginHandler.cs b/Source/Application/Kysect.Shreks.Application.Handlers/Identity/LoginHandler.cs index 6c8581ee4..63d3694fd 100644 --- a/Source/Application/Kysect.Shreks.Application.Handlers/Identity/LoginHandler.cs +++ b/Source/Application/Kysect.Shreks.Application.Handlers/Identity/LoginHandler.cs @@ -43,26 +43,22 @@ public async Task Handle(Query request, CancellationToken cancellation JwtSecurityToken token = GetToken(claims); string? tokenString = new JwtSecurityTokenHandler().WriteToken(token); - return new Response - ( + return new Response( tokenString, token.ValidTo, - new ReadOnlyCollection(roles) - ); + new ReadOnlyCollection(roles)); } private JwtSecurityToken GetToken(IEnumerable authClaims) { var authSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration.Secret)); - var token = new JwtSecurityToken - ( + var token = new JwtSecurityToken( _configuration.Issuer, _configuration.Audience, expires: DateTime.UtcNow.AddHours(_configuration.ExpiresHours), claims: authClaims, - signingCredentials: new SigningCredentials(authSigningKey, SecurityAlgorithms.HmacSha256) - ); + signingCredentials: new SigningCredentials(authSigningKey, SecurityAlgorithms.HmacSha256)); return token; } diff --git a/Source/Application/Kysect.Shreks.Application.Handlers/Kysect.Shreks.Application.Handlers.csproj b/Source/Application/Kysect.Shreks.Application.Handlers/Kysect.Shreks.Application.Handlers.csproj index 19bfedeaa..f5767a019 100644 --- a/Source/Application/Kysect.Shreks.Application.Handlers/Kysect.Shreks.Application.Handlers.csproj +++ b/Source/Application/Kysect.Shreks.Application.Handlers/Kysect.Shreks.Application.Handlers.csproj @@ -7,22 +7,22 @@ - - - - - - + + + + + + - - - + + + - + \ No newline at end of file diff --git a/Source/Application/Kysect.Shreks.Application.Handlers/Study/Assignments/CreateAssignmentHandler.cs b/Source/Application/Kysect.Shreks.Application.Handlers/Study/Assignments/CreateAssignmentHandler.cs index 8132861d8..79eacadf3 100644 --- a/Source/Application/Kysect.Shreks.Application.Handlers/Study/Assignments/CreateAssignmentHandler.cs +++ b/Source/Application/Kysect.Shreks.Application.Handlers/Study/Assignments/CreateAssignmentHandler.cs @@ -31,8 +31,7 @@ public async Task Handle(Command request, CancellationToken cancellati request.Order, new Points(request.MinPoints), new Points(request.MaxPoints), - subjectCourse - ); + subjectCourse); _context.Assignments.Add(assignment); await _context.SaveChangesAsync(cancellationToken); diff --git a/Source/Application/Kysect.Shreks.Application.Handlers/Study/SubjectCourseGroup/GetSubjectCourseGroupByCourseIdHandler.cs b/Source/Application/Kysect.Shreks.Application.Handlers/Study/SubjectCourseGroup/GetSubjectCourseGroupsByIdHandler.cs similarity index 100% rename from Source/Application/Kysect.Shreks.Application.Handlers/Study/SubjectCourseGroup/GetSubjectCourseGroupByCourseIdHandler.cs rename to Source/Application/Kysect.Shreks.Application.Handlers/Study/SubjectCourseGroup/GetSubjectCourseGroupsByIdHandler.cs diff --git a/Source/Application/Kysect.Shreks.Application.Handlers/Users/UpdateUserGithubUsernameHandler.cs b/Source/Application/Kysect.Shreks.Application.Handlers/Users/UpdateUserGithubUsernameHandler.cs index abe8779f9..10421900a 100644 --- a/Source/Application/Kysect.Shreks.Application.Handlers/Users/UpdateUserGithubUsernameHandler.cs +++ b/Source/Application/Kysect.Shreks.Application.Handlers/Users/UpdateUserGithubUsernameHandler.cs @@ -54,7 +54,6 @@ public async Task Handle(Command request, CancellationToken cancellati await _context.UserAssociations.AddAsync(association, cancellationToken); await _context.SaveChangesAsync(cancellationToken); - UserDto? dto = _mapper.Map(user); return new Response(dto); diff --git a/Source/Application/Kysect.Shreks.Application/Extensions/EnumerableExtensions.cs b/Source/Application/Kysect.Shreks.Application/Extensions/EnumerableExtensions.cs index c2728c63e..875b600e1 100644 --- a/Source/Application/Kysect.Shreks.Application/Extensions/EnumerableExtensions.cs +++ b/Source/Application/Kysect.Shreks.Application/Extensions/EnumerableExtensions.cs @@ -2,12 +2,14 @@ namespace Kysect.Shreks.Application.Extensions; public static class EnumerableExtensions { - public static IEnumerable WhereNotNull(this IEnumerable enumerable) where T : class + public static IEnumerable WhereNotNull(this IEnumerable enumerable) + where T : class { return enumerable.Where(x => x is not null).Select(x => x!); } - public static IEnumerable WhereNotNull(this IEnumerable enumerable) where T : struct + public static IEnumerable WhereNotNull(this IEnumerable enumerable) + where T : struct { return enumerable.Where(x => x is not null).Select(x => x!.Value); } diff --git a/Source/Application/Kysect.Shreks.Application/Factories/SubjectCourseDtoFactory.cs b/Source/Application/Kysect.Shreks.Application/Factories/SubjectCourseDtoFactory.cs index 4e622c4f4..09e9f69b3 100644 --- a/Source/Application/Kysect.Shreks.Application/Factories/SubjectCourseDtoFactory.cs +++ b/Source/Application/Kysect.Shreks.Application/Factories/SubjectCourseDtoFactory.cs @@ -19,13 +19,15 @@ public static SubjectCourseDto CreateFrom(SubjectCourse subjectCourse) case GithubSubjectCourseAssociation githubSubjectCourseAssociation: string githubValue = $"Repo: {githubSubjectCourseAssociation.GithubOrganizationName}, Template: {githubSubjectCourseAssociation.TemplateRepositoryName}"; - associations.Add(new SubjectCourseAssociationDto(nameof(GithubSubjectCourseAssociation), + associations.Add(new SubjectCourseAssociationDto( + nameof(GithubSubjectCourseAssociation), githubValue)); break; case GoogleTableSubjectCourseAssociation googleTableSubjectCourseAssociation: string googleValue = $"SpreadsheetId: {googleTableSubjectCourseAssociation.SpreadsheetId}"; - associations.Add(new SubjectCourseAssociationDto(nameof(GoogleTableSubjectCourseAssociation), + associations.Add(new SubjectCourseAssociationDto( + nameof(GoogleTableSubjectCourseAssociation), googleValue)); break; @@ -38,7 +40,11 @@ public static SubjectCourseDto CreateFrom(SubjectCourse subjectCourse) ? (SubmissionStateWorkflowTypeDto)subjectCourse.WorkflowType : null; - return new SubjectCourseDto(subjectCourse.Id, subjectCourse.Subject.Id, subjectCourse.Title, workflowType, + return new SubjectCourseDto( + subjectCourse.Id, + subjectCourse.Subject.Id, + subjectCourse.Title, + workflowType, associations); } } \ No newline at end of file diff --git a/Source/Application/Kysect.Shreks.Application/Factories/SubmissionRateDtoFactory.cs b/Source/Application/Kysect.Shreks.Application/Factories/SubmissionRateDtoFactory.cs index e2a5d8862..ce43c7648 100644 --- a/Source/Application/Kysect.Shreks.Application/Factories/SubmissionRateDtoFactory.cs +++ b/Source/Application/Kysect.Shreks.Application/Factories/SubmissionRateDtoFactory.cs @@ -16,8 +16,7 @@ public static SubmissionRateDto CreateFromSubmission(Submission submission) if (submission.Rating is not null) rating = submission.Rating * 100; - var dto = new SubmissionRateDto - ( + var dto = new SubmissionRateDto( submission.Code, submission.State.Kind.ToString(), submission.SubmissionDate.Value, @@ -26,8 +25,7 @@ public static SubmissionRateDto CreateFromSubmission(Submission submission) maxRowPoints.Value, submission.ExtraPoints?.Value, submission.PointPenalty?.Value, - submission.EffectivePoints?.Value - ); + submission.EffectivePoints?.Value); return dto; } diff --git a/Source/Application/Kysect.Shreks.Application/Queries/Students/StudentGithubQueryLink.cs b/Source/Application/Kysect.Shreks.Application/Queries/Students/StudentGithubQueryLink.cs index 5dfdc02a5..ff0a8fb20 100644 --- a/Source/Application/Kysect.Shreks.Application/Queries/Students/StudentGithubQueryLink.cs +++ b/Source/Application/Kysect.Shreks.Application/Queries/Students/StudentGithubQueryLink.cs @@ -23,6 +23,7 @@ public StudentGithubQueryLink(IPatternMatcher matcher) return null; #pragma warning disable CS8602 + // TODO: Possible NRE if there is no GH User Association. return query.Where(_matcher.Match( x => x.User.Associations.OfType().FirstOrDefault().GithubUsername, diff --git a/Source/Application/Kysect.Shreks.Application/Queries/Students/StudentGroupQueryLink.cs b/Source/Application/Kysect.Shreks.Application/Queries/Students/StudentGroupQueryLink.cs index 7a9842589..c036e496d 100644 --- a/Source/Application/Kysect.Shreks.Application/Queries/Students/StudentGroupQueryLink.cs +++ b/Source/Application/Kysect.Shreks.Application/Queries/Students/StudentGroupQueryLink.cs @@ -22,6 +22,7 @@ public StudentGroupQueryLink(IPatternMatcher matcher) return null; #pragma warning disable CS8602 + // TODO: If student is not assigned to group when something could explode. return query.Where(_matcher.Match(x => x.Group.Name, parameter.Pattern)); #pragma warning restore CS8602 diff --git a/Source/Application/Kysect.Shreks.Application/Services/SubmissionWorkflowService.cs b/Source/Application/Kysect.Shreks.Application/Services/SubmissionWorkflowService.cs index c8c2f1c83..ae340ae1a 100644 --- a/Source/Application/Kysect.Shreks.Application/Services/SubmissionWorkflowService.cs +++ b/Source/Application/Kysect.Shreks.Application/Services/SubmissionWorkflowService.cs @@ -57,7 +57,8 @@ null or SubmissionStateWorkflowType.ReviewOnly SubmissionStateWorkflowType.ReviewWithDefense => new ReviewWithDefenceSubmissionWorkflow(_permissionValidator, _context, _tableUpdateQueue), - _ => throw new ArgumentOutOfRangeException(nameof(subjectCourseId), + _ => throw new ArgumentOutOfRangeException( + nameof(subjectCourseId), $@"Invalid WorkflowType {subjectCourse.WorkflowType:G}"), }; } diff --git a/Source/Application/Kysect.Shreks.Application/Submissions/Workflows/ReviewOnlySubmissionWorkflow.cs b/Source/Application/Kysect.Shreks.Application/Submissions/Workflows/ReviewOnlySubmissionWorkflow.cs index 272659543..ffb964b6b 100644 --- a/Source/Application/Kysect.Shreks.Application/Submissions/Workflows/ReviewOnlySubmissionWorkflow.cs +++ b/Source/Application/Kysect.Shreks.Application/Submissions/Workflows/ReviewOnlySubmissionWorkflow.cs @@ -56,7 +56,9 @@ public async Task SubmissionNotAcceptedAsync( CancellationToken cancellationToken) { await _permissionValidator.EnsureSubmissionMentorAsync(issuerId, submissionId, cancellationToken); - Submission submission = await ExecuteSubmissionCommandAsync(submissionId, cancellationToken, + Submission submission = await ExecuteSubmissionCommandAsync( + submissionId, + cancellationToken, static x => x.Rate(0, 0)); SubmissionRateDto submissionRateDto = SubmissionRateDtoFactory.CreateFromSubmission(submission); diff --git a/Source/Application/Kysect.Shreks.Application/Validators/PermissionValidator.cs b/Source/Application/Kysect.Shreks.Application/Validators/PermissionValidator.cs index 0d5d5d6f8..966cf421a 100644 --- a/Source/Application/Kysect.Shreks.Application/Validators/PermissionValidator.cs +++ b/Source/Application/Kysect.Shreks.Application/Validators/PermissionValidator.cs @@ -16,6 +16,11 @@ public PermissionValidator(IShreksDatabaseContext context) _context = context; } + public static bool IsRepositoryOwner(string username, string repositoryName) + { + return string.Equals(username, repositoryName, StringComparison.OrdinalIgnoreCase); + } + public async Task IsOrganizationMentor(Guid senderId, string organizationName) { return await _context.SubjectCourseAssociations @@ -40,9 +45,4 @@ public async Task EnsureSubmissionMentorAsync( if (await IsSubmissionMentorAsync(userId, submissionId, cancellationToken) is false) throw new UnauthorizedException(); } - - public static bool IsRepositoryOwner(string username, string repositoryName) - { - return string.Equals(username, repositoryName, StringComparison.CurrentCultureIgnoreCase); - } } \ No newline at end of file diff --git a/Source/Application/Kysect.Shreks.DataAccess.Abstractions/IShreksDatabaseContext.cs b/Source/Application/Kysect.Shreks.DataAccess.Abstractions/IShreksDatabaseContext.cs index 16da5a014..e8c8e14a1 100644 --- a/Source/Application/Kysect.Shreks.DataAccess.Abstractions/IShreksDatabaseContext.cs +++ b/Source/Application/Kysect.Shreks.DataAccess.Abstractions/IShreksDatabaseContext.cs @@ -11,20 +11,29 @@ namespace Kysect.Shreks.DataAccess.Abstractions; public interface IShreksDatabaseContext { DbSet Users { get; } + DbSet Students { get; } + DbSet Mentors { get; } DbSet Assignments { get; } + DbSet GroupAssignments { get; } + DbSet StudentGroups { get; } + DbSet Subjects { get; } + DbSet SubjectCourses { get; } + DbSet SubjectCourseGroups { get; } DbSet Submissions { get; } + DbSet SubmissionAssociations { get; } DbSet UserAssociations { get; } + DbSet SubjectCourseAssociations { get; } Task SaveChangesAsync(CancellationToken cancellationToken); diff --git a/Source/DeveloperEnvironment/Kysect.Shreks.DeveloperEnvironment/SeedTestDataHandler.cs b/Source/DeveloperEnvironment/Kysect.Shreks.DeveloperEnvironment/DeveloperEnvironmentSeeder.cs similarity index 100% rename from Source/DeveloperEnvironment/Kysect.Shreks.DeveloperEnvironment/SeedTestDataHandler.cs rename to Source/DeveloperEnvironment/Kysect.Shreks.DeveloperEnvironment/DeveloperEnvironmentSeeder.cs diff --git a/Source/DeveloperEnvironment/Kysect.Shreks.DeveloperEnvironment/Kysect.Shreks.DeveloperEnvironment.csproj b/Source/DeveloperEnvironment/Kysect.Shreks.DeveloperEnvironment/Kysect.Shreks.DeveloperEnvironment.csproj index 87ecaec1d..a107c8291 100644 --- a/Source/DeveloperEnvironment/Kysect.Shreks.DeveloperEnvironment/Kysect.Shreks.DeveloperEnvironment.csproj +++ b/Source/DeveloperEnvironment/Kysect.Shreks.DeveloperEnvironment/Kysect.Shreks.DeveloperEnvironment.csproj @@ -7,7 +7,7 @@ - + diff --git a/Source/Directory.Build.props b/Source/Directory.Build.props index 932304c87..011d282e4 100644 --- a/Source/Directory.Build.props +++ b/Source/Directory.Build.props @@ -3,5 +3,12 @@ latest True true + 1591;SA1633;SA1101;SA1503;SA1309;SA1601;SA1201;SA1502;SA1127;SA1128 + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + \ No newline at end of file diff --git a/Source/Directory.Packages.props b/Source/Directory.Packages.props index d3ed7c256..d68bb1df4 100644 --- a/Source/Directory.Packages.props +++ b/Source/Directory.Packages.props @@ -56,7 +56,7 @@ - + @@ -64,6 +64,7 @@ + diff --git a/Source/Domain/Kysect.Shreks.Common/Exceptions/DomainInvalidOperationException.cs b/Source/Domain/Kysect.Shreks.Common/Exceptions/DomainInvalidOperationException.cs index 21d9e2ef2..b6d0df479 100644 --- a/Source/Domain/Kysect.Shreks.Common/Exceptions/DomainInvalidOperationException.cs +++ b/Source/Domain/Kysect.Shreks.Common/Exceptions/DomainInvalidOperationException.cs @@ -4,11 +4,13 @@ namespace Kysect.Shreks.Common.Exceptions; public class DomainInvalidOperationException : ShreksDomainException { - public DomainInvalidOperationException(string? message) : base(message) { } + public DomainInvalidOperationException(string? message) + : base(message) { } public static DomainInvalidOperationException UserNotFoundByGithubUsername(string githubUsername) { - return new DomainInvalidOperationException(string.Format(UserMessages.UserNotFoundByGithubUsername, + return new DomainInvalidOperationException(string.Format( + UserMessages.UserNotFoundByGithubUsername, githubUsername)); } diff --git a/Source/Domain/Kysect.Shreks.Common/Exceptions/EntityNotFoundException.cs b/Source/Domain/Kysect.Shreks.Common/Exceptions/EntityNotFoundException.cs index cf8b806c8..150624a67 100644 --- a/Source/Domain/Kysect.Shreks.Common/Exceptions/EntityNotFoundException.cs +++ b/Source/Domain/Kysect.Shreks.Common/Exceptions/EntityNotFoundException.cs @@ -4,7 +4,8 @@ namespace Kysect.Shreks.Common.Exceptions; public class EntityNotFoundException : NotFoundException { - public EntityNotFoundException(string? message) : base(message) { } + public EntityNotFoundException(string? message) + : base(message) { } public static EntityNotFoundException For(Guid id) { @@ -16,19 +17,25 @@ public static EntityNotFoundException AssignmentWasNotFound( string subjectCourseTitle, string subjectCourseAssignments) { - return new EntityNotFoundException(string.Format(UserMessages.AssignmentNotFound, branchName, - subjectCourseTitle, subjectCourseAssignments)); + return new EntityNotFoundException(string.Format( + UserMessages.AssignmentNotFound, + branchName, + subjectCourseTitle, + subjectCourseAssignments)); } public static EntityNotFoundException SubjectCourseForOrganizationNotFound(string organization) { - return new EntityNotFoundException(string.Format(UserMessages.SubjectCourseForOrganizationNotFound, + return new EntityNotFoundException(string.Format( + UserMessages.SubjectCourseForOrganizationNotFound, organization)); } public static EntityNotFoundException UserNotFoundInSubjectCourse(Guid userId, string subjectCourse) { - return new EntityNotFoundException(string.Format(UserMessages.UserNotFoundInSubjectCourse, userId, + return new EntityNotFoundException(string.Format( + UserMessages.UserNotFoundInSubjectCourse, + userId, subjectCourse)); } diff --git a/Source/Domain/Kysect.Shreks.Common/Exceptions/InvalidUserInputException.cs b/Source/Domain/Kysect.Shreks.Common/Exceptions/InvalidUserInputException.cs index 1ba5674ad..492d94623 100644 --- a/Source/Domain/Kysect.Shreks.Common/Exceptions/InvalidUserInputException.cs +++ b/Source/Domain/Kysect.Shreks.Common/Exceptions/InvalidUserInputException.cs @@ -4,7 +4,8 @@ namespace Kysect.Shreks.Common.Exceptions; public class InvalidUserInputException : ShreksDomainException { - public InvalidUserInputException(string? message) : base(message) { } + public InvalidUserInputException(string? message) + : base(message) { } public static InvalidUserInputException FailedToParseUserCommand() { diff --git a/Source/Domain/Kysect.Shreks.Common/Exceptions/NotFoundException.cs b/Source/Domain/Kysect.Shreks.Common/Exceptions/NotFoundException.cs index 74ad703f1..5a1a76e8a 100644 --- a/Source/Domain/Kysect.Shreks.Common/Exceptions/NotFoundException.cs +++ b/Source/Domain/Kysect.Shreks.Common/Exceptions/NotFoundException.cs @@ -3,6 +3,10 @@ namespace Kysect.Shreks.Common.Exceptions; public abstract class NotFoundException : ShreksDomainException { protected NotFoundException() { } - protected NotFoundException(string? message) : base(message) { } - protected NotFoundException(string? message, Exception? innerException) : base(message, innerException) { } + + protected NotFoundException(string? message) + : base(message) { } + + protected NotFoundException(string? message, Exception? innerException) + : base(message, innerException) { } } \ No newline at end of file diff --git a/Source/Domain/Kysect.Shreks.Common/Exceptions/ShreksDomainException.cs b/Source/Domain/Kysect.Shreks.Common/Exceptions/ShreksDomainException.cs index ebde2a1cb..1e81fe3f3 100644 --- a/Source/Domain/Kysect.Shreks.Common/Exceptions/ShreksDomainException.cs +++ b/Source/Domain/Kysect.Shreks.Common/Exceptions/ShreksDomainException.cs @@ -3,6 +3,8 @@ namespace Kysect.Shreks.Common.Exceptions; public abstract class ShreksDomainException : Exception { protected ShreksDomainException() { } + protected ShreksDomainException(string? message) : base(message) { } + protected ShreksDomainException(string? message, Exception? innerException) : base(message, innerException) { } } \ No newline at end of file diff --git a/Source/Domain/Kysect.Shreks.Common/Exceptions/UnauthorizedException.cs b/Source/Domain/Kysect.Shreks.Common/Exceptions/UnauthorizedException.cs index 7eba20551..b738bf07a 100644 --- a/Source/Domain/Kysect.Shreks.Common/Exceptions/UnauthorizedException.cs +++ b/Source/Domain/Kysect.Shreks.Common/Exceptions/UnauthorizedException.cs @@ -6,7 +6,8 @@ public class UnauthorizedException : ShreksDomainException { public UnauthorizedException(string? message) : base(message) { } - public UnauthorizedException() : base(UserMessages.UnauthorizedExceptionMessage) { } + public UnauthorizedException() + : base(UserMessages.UnauthorizedExceptionMessage) { } public static UnauthorizedException DoesNotHavePermissionForActivateSubmission() { diff --git a/Source/Domain/Kysect.Shreks.Common/Exceptions/UnsupportedOperationException.cs b/Source/Domain/Kysect.Shreks.Common/Exceptions/UnsupportedOperationException.cs index 098227542..24807f5e5 100644 --- a/Source/Domain/Kysect.Shreks.Common/Exceptions/UnsupportedOperationException.cs +++ b/Source/Domain/Kysect.Shreks.Common/Exceptions/UnsupportedOperationException.cs @@ -2,5 +2,6 @@ public class UnsupportedOperationException : ShreksDomainException { - public UnsupportedOperationException(string? message) : base(message) { } + public UnsupportedOperationException(string? message) + : base(message) { } } \ No newline at end of file diff --git a/Source/Domain/Kysect.Shreks.Common/Logging/PrefixLoggerProxy.cs b/Source/Domain/Kysect.Shreks.Common/Logging/PrefixLoggerProxy.cs index 39fc8fbc2..b3a29e8fa 100644 --- a/Source/Domain/Kysect.Shreks.Common/Logging/PrefixLoggerProxy.cs +++ b/Source/Domain/Kysect.Shreks.Common/Logging/PrefixLoggerProxy.cs @@ -20,8 +20,12 @@ public void Log( Exception? exception, Func formatter) { - _logger.Log(logLevel, eventId, PrepareMessage(state), exception, - (s, e) => $"{PrepareMessage(formatter(state, e))}"); + _logger.Log( + logLevel, + eventId, + PrepareMessage(state), + exception, + (_, e) => $"{PrepareMessage(formatter(state, e))}"); } public bool IsEnabled(LogLevel logLevel) diff --git a/Source/Domain/Kysect.Shreks.Core/DeadlinePolicies/AbsoluteDeadlinePolicy.cs b/Source/Domain/Kysect.Shreks.Core/DeadlinePolicies/AbsoluteDeadlinePolicy.cs index d9c32d097..cbe12bd25 100644 --- a/Source/Domain/Kysect.Shreks.Core/DeadlinePolicies/AbsoluteDeadlinePolicy.cs +++ b/Source/Domain/Kysect.Shreks.Core/DeadlinePolicies/AbsoluteDeadlinePolicy.cs @@ -4,7 +4,8 @@ namespace Kysect.Shreks.Core.DeadlinePolicies; public class AbsoluteDeadlinePolicy : DeadlinePolicy { - public AbsoluteDeadlinePolicy(TimeSpan spanBeforeActivation, Points absoluteValue) : base(spanBeforeActivation) + public AbsoluteDeadlinePolicy(TimeSpan spanBeforeActivation, Points absoluteValue) + : base(spanBeforeActivation) { AbsoluteValue = absoluteValue; } diff --git a/Source/Domain/Kysect.Shreks.Core/DeadlinePolicies/CappingDeadlinePolicy.cs b/Source/Domain/Kysect.Shreks.Core/DeadlinePolicies/CappingDeadlinePolicy.cs index 914c21614..5218556f9 100644 --- a/Source/Domain/Kysect.Shreks.Core/DeadlinePolicies/CappingDeadlinePolicy.cs +++ b/Source/Domain/Kysect.Shreks.Core/DeadlinePolicies/CappingDeadlinePolicy.cs @@ -4,7 +4,8 @@ namespace Kysect.Shreks.Core.DeadlinePolicies; public class CappingDeadlinePolicy : DeadlinePolicy { - public CappingDeadlinePolicy(TimeSpan spanBeforeActivation, double cap) : base(spanBeforeActivation) + public CappingDeadlinePolicy(TimeSpan spanBeforeActivation, double cap) + : base(spanBeforeActivation) { Cap = new Points(cap); } diff --git a/Source/Domain/Kysect.Shreks.Core/DeadlinePolicies/FractionDeadlinePolicy.cs b/Source/Domain/Kysect.Shreks.Core/DeadlinePolicies/FractionDeadlinePolicy.cs index 97273c3b0..680eff0a7 100644 --- a/Source/Domain/Kysect.Shreks.Core/DeadlinePolicies/FractionDeadlinePolicy.cs +++ b/Source/Domain/Kysect.Shreks.Core/DeadlinePolicies/FractionDeadlinePolicy.cs @@ -4,7 +4,8 @@ namespace Kysect.Shreks.Core.DeadlinePolicies; public class FractionDeadlinePolicy : DeadlinePolicy { - public FractionDeadlinePolicy(TimeSpan spanBeforeActivation, Fraction fraction) : base(spanBeforeActivation) + public FractionDeadlinePolicy(TimeSpan spanBeforeActivation, Fraction fraction) + : base(spanBeforeActivation) { Fraction = fraction; } diff --git a/Source/Domain/Kysect.Shreks.Core/Kysect.Shreks.Core.csproj b/Source/Domain/Kysect.Shreks.Core/Kysect.Shreks.Core.csproj index 20daf6356..b70e914e4 100644 --- a/Source/Domain/Kysect.Shreks.Core/Kysect.Shreks.Core.csproj +++ b/Source/Domain/Kysect.Shreks.Core/Kysect.Shreks.Core.csproj @@ -9,7 +9,7 @@ - + diff --git a/Source/Domain/Kysect.Shreks.Core/Queue/Building/IQueueBuilder.cs b/Source/Domain/Kysect.Shreks.Core/Queue/Building/IQueueEvaluatorBuilder.cs similarity index 100% rename from Source/Domain/Kysect.Shreks.Core/Queue/Building/IQueueBuilder.cs rename to Source/Domain/Kysect.Shreks.Core/Queue/Building/IQueueEvaluatorBuilder.cs diff --git a/Source/Domain/Kysect.Shreks.Core/Study/Assignment.cs b/Source/Domain/Kysect.Shreks.Core/Study/Assignment.cs index 0e28303c2..355f56a2c 100644 --- a/Source/Domain/Kysect.Shreks.Core/Study/Assignment.cs +++ b/Source/Domain/Kysect.Shreks.Core/Study/Assignment.cs @@ -32,11 +32,17 @@ public Assignment( } public string Title { get; set; } + public string ShortName { get; set; } + public int Order { get; set; } + public Points MinPoints { get; protected set; } + public Points MaxPoints { get; protected set; } + public virtual SubjectCourse SubjectCourse { get; protected init; } + public virtual IReadOnlyCollection GroupAssignments => _groupAssignments; public void UpdateMinPoints(Points value) diff --git a/Source/Domain/Kysect.Shreks.Core/Study/GroupAssignment.cs b/Source/Domain/Kysect.Shreks.Core/Study/GroupAssignment.cs index 987c266cc..bace16b4d 100644 --- a/Source/Domain/Kysect.Shreks.Core/Study/GroupAssignment.cs +++ b/Source/Domain/Kysect.Shreks.Core/Study/GroupAssignment.cs @@ -28,6 +28,7 @@ public GroupAssignment(StudentGroup group, Assignment assignment, DateOnly deadl public virtual Assignment Assignment { get; protected init; } public DateOnly Deadline { get; set; } + public virtual IReadOnlyCollection Submissions => _submissions; public override string ToString() diff --git a/Source/Domain/Kysect.Shreks.Core/Study/StudentAssignment.cs b/Source/Domain/Kysect.Shreks.Core/Study/StudentAssignment.cs index 9b149fd6a..6beb3b426 100644 --- a/Source/Domain/Kysect.Shreks.Core/Study/StudentAssignment.cs +++ b/Source/Domain/Kysect.Shreks.Core/Study/StudentAssignment.cs @@ -38,10 +38,7 @@ public StudentAssignment(Student student, GroupAssignment assignment) .Where(x => x.State.IsTerminalEffectiveState); (Submission submission, Points? points, bool isBanned) = submissions - .Select(s => - ( - submission: s, points: s.EffectivePoints, isBanned: s.State.Kind is SubmissionStateKind.Banned - )) + .Select(s => (submission: s, points: s.EffectivePoints, isBanned: s.State.Kind is SubmissionStateKind.Banned)) .OrderByDescending(x => x.isBanned) .ThenByDescending(x => x.points) .FirstOrDefault(); diff --git a/Source/Domain/Kysect.Shreks.Core/Study/StudentGroup.cs b/Source/Domain/Kysect.Shreks.Core/Study/StudentGroup.cs index 0157bb5e5..e6ef5600a 100644 --- a/Source/Domain/Kysect.Shreks.Core/Study/StudentGroup.cs +++ b/Source/Domain/Kysect.Shreks.Core/Study/StudentGroup.cs @@ -18,6 +18,7 @@ public StudentGroup(string name) } public string Name { get; set; } + public virtual IReadOnlyCollection Students => _students; public override string ToString() diff --git a/Source/Domain/Kysect.Shreks.Core/Study/Subject.cs b/Source/Domain/Kysect.Shreks.Core/Study/Subject.cs index 66013b629..197e6c16d 100644 --- a/Source/Domain/Kysect.Shreks.Core/Study/Subject.cs +++ b/Source/Domain/Kysect.Shreks.Core/Study/Subject.cs @@ -7,7 +7,8 @@ public partial class Subject : IEntity { private readonly HashSet _courses; - public Subject(string title) : this(Guid.NewGuid()) + public Subject(string title) + : this(Guid.NewGuid()) { ArgumentNullException.ThrowIfNull(title); @@ -16,6 +17,7 @@ public Subject(string title) : this(Guid.NewGuid()) } public string Title { get; set; } + public virtual IReadOnlyCollection Courses => _courses; public void AddCourse(SubjectCourse course) diff --git a/Source/Domain/Kysect.Shreks.Core/Study/SubjectCourse.cs b/Source/Domain/Kysect.Shreks.Core/Study/SubjectCourse.cs index b37a18893..3174424db 100644 --- a/Source/Domain/Kysect.Shreks.Core/Study/SubjectCourse.cs +++ b/Source/Domain/Kysect.Shreks.Core/Study/SubjectCourse.cs @@ -15,8 +15,8 @@ public partial class SubjectCourse : IEntity private readonly HashSet _groups; private readonly HashSet _mentors; - public SubjectCourse(Subject subject, string title, SubmissionStateWorkflowType? workflowType) : this( - Guid.NewGuid()) + public SubjectCourse(Subject subject, string title, SubmissionStateWorkflowType? workflowType) + : this(Guid.NewGuid()) { Subject = subject; Title = title; @@ -30,12 +30,19 @@ public SubjectCourse(Subject subject, string title, SubmissionStateWorkflowType? } public virtual Subject Subject { get; protected init; } + public string Title { get; set; } + public SubmissionStateWorkflowType? WorkflowType { get; set; } + public virtual IReadOnlyCollection Groups => _groups; + public virtual IReadOnlyCollection Assignments => _assignments; + public virtual IReadOnlyCollection Associations => _associations; + public virtual IReadOnlyCollection Mentors => _mentors; + public virtual IReadOnlyCollection DeadlinePolicies => _deadlinePolicies; public override string ToString() diff --git a/Source/Domain/Kysect.Shreks.Core/SubjectCourseAssociations/GithubSubjectCourseAssociation.cs b/Source/Domain/Kysect.Shreks.Core/SubjectCourseAssociations/GithubSubjectCourseAssociation.cs index eff2e6379..ceeb69cfb 100644 --- a/Source/Domain/Kysect.Shreks.Core/SubjectCourseAssociations/GithubSubjectCourseAssociation.cs +++ b/Source/Domain/Kysect.Shreks.Core/SubjectCourseAssociations/GithubSubjectCourseAssociation.cs @@ -15,5 +15,6 @@ public GithubSubjectCourseAssociation( } public string GithubOrganizationName { get; protected set; } + public string TemplateRepositoryName { get; protected set; } } \ No newline at end of file diff --git a/Source/Domain/Kysect.Shreks.Core/SubjectCourseAssociations/SubjectCourseAssociation.cs b/Source/Domain/Kysect.Shreks.Core/SubjectCourseAssociations/SubjectCourseAssociation.cs index c4a8144ce..de87ae56a 100644 --- a/Source/Domain/Kysect.Shreks.Core/SubjectCourseAssociations/SubjectCourseAssociation.cs +++ b/Source/Domain/Kysect.Shreks.Core/SubjectCourseAssociations/SubjectCourseAssociation.cs @@ -5,7 +5,8 @@ namespace Kysect.Shreks.Core.SubjectCourseAssociations; public abstract partial class SubjectCourseAssociation : IEntity { - protected SubjectCourseAssociation(SubjectCourse subjectCourse) : this(Guid.NewGuid()) + protected SubjectCourseAssociation(SubjectCourse subjectCourse) + : this(Guid.NewGuid()) { SubjectCourse = subjectCourse; } diff --git a/Source/Domain/Kysect.Shreks.Core/SubmissionAssociations/GithubSubmissionAssociation.cs b/Source/Domain/Kysect.Shreks.Core/SubmissionAssociations/GithubSubmissionAssociation.cs index 11c7e129f..1127cc996 100644 --- a/Source/Domain/Kysect.Shreks.Core/SubmissionAssociations/GithubSubmissionAssociation.cs +++ b/Source/Domain/Kysect.Shreks.Core/SubmissionAssociations/GithubSubmissionAssociation.cs @@ -8,7 +8,8 @@ public GithubSubmissionAssociation( GithubSubmission submission, string organization, string repository, - long prNumber) : base(submission) + long prNumber) + : base(submission) { Repository = repository; PrNumber = prNumber; @@ -16,6 +17,8 @@ public GithubSubmissionAssociation( } public string Organization { get; protected set; } + public string Repository { get; protected set; } + public long PrNumber { get; protected set; } } \ No newline at end of file diff --git a/Source/Domain/Kysect.Shreks.Core/SubmissionAssociations/SubmissionAssociation.cs b/Source/Domain/Kysect.Shreks.Core/SubmissionAssociations/SubmissionAssociation.cs index 068ba7c7c..a8e2e0733 100644 --- a/Source/Domain/Kysect.Shreks.Core/SubmissionAssociations/SubmissionAssociation.cs +++ b/Source/Domain/Kysect.Shreks.Core/SubmissionAssociations/SubmissionAssociation.cs @@ -5,7 +5,8 @@ namespace Kysect.Shreks.Core.SubmissionAssociations; public abstract partial class SubmissionAssociation : IEntity { - protected SubmissionAssociation(Submission submission) : this(Guid.NewGuid()) + protected SubmissionAssociation(Submission submission) + : this(Guid.NewGuid()) { Submission = submission; } diff --git a/Source/Domain/Kysect.Shreks.Core/Submissions/GithubSubmission.cs b/Source/Domain/Kysect.Shreks.Core/Submissions/GithubSubmission.cs index ecb6c3993..44b006ae7 100644 --- a/Source/Domain/Kysect.Shreks.Core/Submissions/GithubSubmission.cs +++ b/Source/Domain/Kysect.Shreks.Core/Submissions/GithubSubmission.cs @@ -18,13 +18,11 @@ public GithubSubmission( long prNumber) : base(code, student, groupAssignment, submissionDate, payload) { - var association = new GithubSubmissionAssociation - ( + var association = new GithubSubmissionAssociation( this, organization, repository, - prNumber - ); + prNumber); AddAssociation(association); } diff --git a/Source/Domain/Kysect.Shreks.Core/Submissions/States/ActiveSubmissionState.cs b/Source/Domain/Kysect.Shreks.Core/Submissions/States/ActiveSubmissionState.cs index da74b0741..70ffa7292 100644 --- a/Source/Domain/Kysect.Shreks.Core/Submissions/States/ActiveSubmissionState.cs +++ b/Source/Domain/Kysect.Shreks.Core/Submissions/States/ActiveSubmissionState.cs @@ -8,6 +8,7 @@ namespace Kysect.Shreks.Core.Submissions.States; public class ActiveSubmissionState : ISubmissionState { public SubmissionStateKind Kind => SubmissionStateKind.Active; + public bool IsTerminalEffectiveState => false; public ISubmissionState MoveToRated(Fraction? rating, Points? extraPoints) diff --git a/Source/Domain/Kysect.Shreks.Core/Submissions/States/BannedSubmissionState.cs b/Source/Domain/Kysect.Shreks.Core/Submissions/States/BannedSubmissionState.cs index 1a2837d87..8ec9192c8 100644 --- a/Source/Domain/Kysect.Shreks.Core/Submissions/States/BannedSubmissionState.cs +++ b/Source/Domain/Kysect.Shreks.Core/Submissions/States/BannedSubmissionState.cs @@ -8,6 +8,7 @@ namespace Kysect.Shreks.Core.Submissions.States; public class BannedSubmissionState : ISubmissionState { public SubmissionStateKind Kind => SubmissionStateKind.Banned; + public bool IsTerminalEffectiveState => true; public ISubmissionState MoveToRated(Fraction? rating, Points? extraPoints) diff --git a/Source/Domain/Kysect.Shreks.Core/Submissions/States/CompletedSubmissionState.cs b/Source/Domain/Kysect.Shreks.Core/Submissions/States/CompletedSubmissionState.cs index 34d7b3bca..b65af01b4 100644 --- a/Source/Domain/Kysect.Shreks.Core/Submissions/States/CompletedSubmissionState.cs +++ b/Source/Domain/Kysect.Shreks.Core/Submissions/States/CompletedSubmissionState.cs @@ -8,6 +8,7 @@ namespace Kysect.Shreks.Core.Submissions.States; public class CompletedSubmissionState : ISubmissionState { public SubmissionStateKind Kind => SubmissionStateKind.Completed; + public bool IsTerminalEffectiveState => true; public ISubmissionState MoveToRated(Fraction? rating, Points? extraPoints) diff --git a/Source/Domain/Kysect.Shreks.Core/Submissions/States/DeletedSubmissionState.cs b/Source/Domain/Kysect.Shreks.Core/Submissions/States/DeletedSubmissionState.cs index 2a8d27cfc..30473ddbd 100644 --- a/Source/Domain/Kysect.Shreks.Core/Submissions/States/DeletedSubmissionState.cs +++ b/Source/Domain/Kysect.Shreks.Core/Submissions/States/DeletedSubmissionState.cs @@ -8,6 +8,7 @@ namespace Kysect.Shreks.Core.Submissions.States; public class DeletedSubmissionState : ISubmissionState { public SubmissionStateKind Kind => SubmissionStateKind.Deleted; + public bool IsTerminalEffectiveState => false; public ISubmissionState MoveToRated(Fraction? rating, Points? extraPoints) diff --git a/Source/Domain/Kysect.Shreks.Core/Submissions/States/ISubmissionState.cs b/Source/Domain/Kysect.Shreks.Core/Submissions/States/ISubmissionState.cs index 6bed778f2..3b99bff31 100644 --- a/Source/Domain/Kysect.Shreks.Core/Submissions/States/ISubmissionState.cs +++ b/Source/Domain/Kysect.Shreks.Core/Submissions/States/ISubmissionState.cs @@ -9,17 +9,25 @@ public interface ISubmissionState SubmissionStateKind Kind { get; } /// - /// Determines whether the state is terminal, yet relevant for the system + /// Gets a value indicating whether the state is terminal, yet relevant for the system. /// bool IsTerminalEffectiveState { get; } ISubmissionState MoveToRated(Fraction? rating, Points? extraPoints); + ISubmissionState MoveToPointsUpdated(Fraction? rating, Points? extraPoints); + ISubmissionState MoveToBanned(); + ISubmissionState MoveToActivated(); + ISubmissionState MoveToDeactivated(); + ISubmissionState MoveToDateUpdated(SpbDateTime newDate); + ISubmissionState MoveToDeleted(); + ISubmissionState MoveToCompleted(); + ISubmissionState MoveToReviewed(); } \ No newline at end of file diff --git a/Source/Domain/Kysect.Shreks.Core/Submissions/States/InactiveSubmissionState.cs b/Source/Domain/Kysect.Shreks.Core/Submissions/States/InactiveSubmissionState.cs index 714668bb6..27b1a64a2 100644 --- a/Source/Domain/Kysect.Shreks.Core/Submissions/States/InactiveSubmissionState.cs +++ b/Source/Domain/Kysect.Shreks.Core/Submissions/States/InactiveSubmissionState.cs @@ -8,6 +8,7 @@ namespace Kysect.Shreks.Core.Submissions.States; public class InactiveSubmissionState : ISubmissionState { public SubmissionStateKind Kind => SubmissionStateKind.Inactive; + public bool IsTerminalEffectiveState => false; public ISubmissionState MoveToRated(Fraction? rating, Points? extraPoints) diff --git a/Source/Domain/Kysect.Shreks.Core/Submissions/States/ReviewedSubmissionState.cs b/Source/Domain/Kysect.Shreks.Core/Submissions/States/ReviewedSubmissionState.cs index d0a216d28..e06cf18ac 100644 --- a/Source/Domain/Kysect.Shreks.Core/Submissions/States/ReviewedSubmissionState.cs +++ b/Source/Domain/Kysect.Shreks.Core/Submissions/States/ReviewedSubmissionState.cs @@ -8,6 +8,7 @@ namespace Kysect.Shreks.Core.Submissions.States; public class ReviewedSubmissionState : ISubmissionState { public SubmissionStateKind Kind => SubmissionStateKind.Reviewed; + public bool IsTerminalEffectiveState => false; public ISubmissionState MoveToRated(Fraction? rating, Points? extraPoints) diff --git a/Source/Domain/Kysect.Shreks.Core/Submissions/Submission.cs b/Source/Domain/Kysect.Shreks.Core/Submissions/Submission.cs index 18289aeec..b4c788f25 100644 --- a/Source/Domain/Kysect.Shreks.Core/Submissions/Submission.cs +++ b/Source/Domain/Kysect.Shreks.Core/Submissions/Submission.cs @@ -36,27 +36,35 @@ protected Submission( } public int Code { get; protected init; } + public string Payload { get; set; } + public Fraction? Rating { get; private set; } + public Points? ExtraPoints { get; set; } + public SpbDateTime SubmissionDate { get; private set; } + public virtual Student Student { get; protected init; } + public virtual GroupAssignment GroupAssignment { get; protected init; } + public virtual IReadOnlyCollection Associations => _associations; public Points? Points => Rating is null ? default : GroupAssignment.Assignment.MaxPoints * Rating; /// - /// Points with deadline policy applied + /// Gets points with deadline policy applied. /// public Points? EffectivePoints => GetEffectivePoints(); /// - /// Points subtracted by deadline policy + /// Gets points subtracted by deadline policy. /// public Points? PointPenalty => GetPointPenalty(); public bool IsRated => Rating is not null; + public DateOnly SubmissionDateOnly => SubmissionDate.AsDateOnly(); public ISubmissionState State { get; private set; } diff --git a/Source/Domain/Kysect.Shreks.Core/UserAssociations/GithubUserAssociation.cs b/Source/Domain/Kysect.Shreks.Core/UserAssociations/GithubUserAssociation.cs index a36639eba..4f0ff5a9e 100644 --- a/Source/Domain/Kysect.Shreks.Core/UserAssociations/GithubUserAssociation.cs +++ b/Source/Domain/Kysect.Shreks.Core/UserAssociations/GithubUserAssociation.cs @@ -4,7 +4,8 @@ namespace Kysect.Shreks.Core.UserAssociations; public partial class GithubUserAssociation : UserAssociation { - public GithubUserAssociation(User user, string githubUsername) : base(user) + public GithubUserAssociation(User user, string githubUsername) + : base(user) { GithubUsername = githubUsername; } diff --git a/Source/Domain/Kysect.Shreks.Core/UserAssociations/IsuUserAssociation.cs b/Source/Domain/Kysect.Shreks.Core/UserAssociations/IsuUserAssociation.cs index d144036b3..fe59fb119 100644 --- a/Source/Domain/Kysect.Shreks.Core/UserAssociations/IsuUserAssociation.cs +++ b/Source/Domain/Kysect.Shreks.Core/UserAssociations/IsuUserAssociation.cs @@ -4,7 +4,8 @@ namespace Kysect.Shreks.Core.UserAssociations; public partial class IsuUserAssociation : UserAssociation { - public IsuUserAssociation(User user, int universityId) : base(user) + public IsuUserAssociation(User user, int universityId) + : base(user) { UniversityId = universityId; } diff --git a/Source/Domain/Kysect.Shreks.Core/UserAssociations/UserAssociation.cs b/Source/Domain/Kysect.Shreks.Core/UserAssociations/UserAssociation.cs index b32e18355..ac0dff405 100644 --- a/Source/Domain/Kysect.Shreks.Core/UserAssociations/UserAssociation.cs +++ b/Source/Domain/Kysect.Shreks.Core/UserAssociations/UserAssociation.cs @@ -5,7 +5,8 @@ namespace Kysect.Shreks.Core.UserAssociations; public abstract partial class UserAssociation : IEntity { - protected UserAssociation(User user) : this(Guid.NewGuid()) + protected UserAssociation(User user) + : this(Guid.NewGuid()) { User = user; user.AddAssociation(this); diff --git a/Source/Domain/Kysect.Shreks.Core/Users/Mentor.cs b/Source/Domain/Kysect.Shreks.Core/Users/Mentor.cs index 1f9323494..452ebc5d3 100644 --- a/Source/Domain/Kysect.Shreks.Core/Users/Mentor.cs +++ b/Source/Domain/Kysect.Shreks.Core/Users/Mentor.cs @@ -5,7 +5,8 @@ namespace Kysect.Shreks.Core.Users; public partial class Mentor : IEntity { - public Mentor(User user, SubjectCourse course) : this(userId: user.Id, courseId: course.Id) + public Mentor(User user, SubjectCourse course) + : this(userId: user.Id, courseId: course.Id) { User = user; Course = course; diff --git a/Source/Domain/Kysect.Shreks.Core/Users/Student.cs b/Source/Domain/Kysect.Shreks.Core/Users/Student.cs index bf738669f..f149608b8 100644 --- a/Source/Domain/Kysect.Shreks.Core/Users/Student.cs +++ b/Source/Domain/Kysect.Shreks.Core/Users/Student.cs @@ -7,7 +7,8 @@ namespace Kysect.Shreks.Core.Users; public partial class Student : IEntity { - public Student(User user, StudentGroup group) : this(user.Id) + public Student(User user, StudentGroup group) + : this(user.Id) { User = user; Group = group; diff --git a/Source/Domain/Kysect.Shreks.Core/Users/User.cs b/Source/Domain/Kysect.Shreks.Core/Users/User.cs index bf9174ca7..802fb75dc 100644 --- a/Source/Domain/Kysect.Shreks.Core/Users/User.cs +++ b/Source/Domain/Kysect.Shreks.Core/Users/User.cs @@ -8,7 +8,8 @@ public partial class User : IEntity { private readonly HashSet _associations; - public User(string firstName, string middleName, string lastName) : this(Guid.NewGuid()) + public User(string firstName, string middleName, string lastName) + : this(Guid.NewGuid()) { ArgumentNullException.ThrowIfNull(firstName); ArgumentNullException.ThrowIfNull(middleName); @@ -22,7 +23,9 @@ public User(string firstName, string middleName, string lastName) : this(Guid.Ne } public string FirstName { get; set; } + public string MiddleName { get; set; } + public string LastName { get; set; } public virtual IReadOnlyCollection Associations => _associations; diff --git a/Source/Domain/Kysect.Shreks.Core/ValueObject/Points.cs b/Source/Domain/Kysect.Shreks.Core/ValueObject/Points.cs index 0aba3e5f1..486101fcc 100644 --- a/Source/Domain/Kysect.Shreks.Core/ValueObject/Points.cs +++ b/Source/Domain/Kysect.Shreks.Core/ValueObject/Points.cs @@ -13,22 +13,7 @@ public Points(double value) public double Value { get; } - public static Points None => new Points(); - - public int CompareTo(Points other) - { - return Value.CompareTo(other.Value); - } - - public static Points Min(Points a, Points b) - { - return a < b ? a : b; - } - - public static Points Max(Points a, Points b) - { - return a > b ? a : b; - } + public static Points None => default; public static implicit operator Points(double value) { @@ -60,6 +45,21 @@ public static implicit operator Points(double value) return a.Value < b.Value; } + public int CompareTo(Points other) + { + return Value.CompareTo(other.Value); + } + + public static Points Min(Points a, Points b) + { + return a < b ? a : b; + } + + public static Points Max(Points a, Points b) + { + return a > b ? a : b; + } + public override string ToString() { return Value.ToString(CultureInfo.InvariantCulture); diff --git a/Source/Infrastructure/Integration/Kysect.Shreks.Integration.Github/Client/InstallationClientFactory.cs b/Source/Infrastructure/Integration/Kysect.Shreks.Integration.Github/Client/InstallationClientFactory.cs index 1ec653c50..beee36d99 100644 --- a/Source/Infrastructure/Integration/Kysect.Shreks.Integration.Github/Client/InstallationClientFactory.cs +++ b/Source/Infrastructure/Integration/Kysect.Shreks.Integration.Github/Client/InstallationClientFactory.cs @@ -23,7 +23,8 @@ public GitHubClient GetClient(long installationId) private GitHubClient CreateInstallationClient(long installationId) { - return new GitHubClient(new ProductHeaderValue($"Installation-{installationId}"), + return new GitHubClient( + new ProductHeaderValue($"Installation-{installationId}"), new InstallationCredentialStore(_gitHubAppClient, installationId)); } } \ No newline at end of file diff --git a/Source/Infrastructure/Integration/Kysect.Shreks.Integration.Github/CredentialStores/InstallationCredentialStore.cs b/Source/Infrastructure/Integration/Kysect.Shreks.Integration.Github/CredentialStores/InstallationCredentialStore.cs index b1ae64c44..3d07596c2 100644 --- a/Source/Infrastructure/Integration/Kysect.Shreks.Integration.Github/CredentialStores/InstallationCredentialStore.cs +++ b/Source/Infrastructure/Integration/Kysect.Shreks.Integration.Github/CredentialStores/InstallationCredentialStore.cs @@ -24,15 +24,16 @@ public InstallationCredentialStore(IGitHubClient gitHubAppClient, long installat public Task GetCredentials() { - //check if token has expired or is already refreshing in async task + // check if token has expired or is already refreshing in async task if (!IsTokenExpired() || _tokenRefreshState.IsRefreshing()) return _task; lock (_lock) { - //check if while waiting for lock token was already set refreshing + // check if while waiting for lock token was already set refreshing if (!_tokenRefreshState.TrySetStartRefreshing()) return _task; - //check if it is not refreshing because it was successfully refreshed while we were waiting for lock + + // check if it is not refreshing because it was successfully refreshed while we were waiting for lock if (IsTokenExpired()) { _task = RefreshToken(); @@ -80,9 +81,9 @@ private struct TokenRefreshState { private enum State { - NotRefreshing, //refreshing task is not running - StartRefreshing, //refreshing task is being created - Refreshing, //refreshing task is running + NotRefreshing, // refreshing task is not running + StartRefreshing, // refreshing task is being created + Refreshing, // refreshing task is running } private volatile int _state; @@ -102,17 +103,21 @@ public void SetNotRefreshing() _state = (int)State.NotRefreshing; } - //if not refreshing, advance to starting refreshing (creating refreshing task) + // if not refreshing, advance to starting refreshing (creating refreshing task) public bool TrySetStartRefreshing() { - return Interlocked.CompareExchange(ref _state, (int)State.StartRefreshing, + return Interlocked.CompareExchange( + ref _state, + (int)State.StartRefreshing, (int)State.NotRefreshing) == (int)State.NotRefreshing; } - //if started refreshing, advance to actually refreshing (task is running) + // if started refreshing, advance to actually refreshing (task is running) public bool TrySetRefreshing() { - return Interlocked.CompareExchange(ref _state, (int)State.Refreshing, + return Interlocked.CompareExchange( + ref _state, + (int)State.Refreshing, (int)State.StartRefreshing) == (int)State.StartRefreshing; } } diff --git a/Source/Infrastructure/Integration/Kysect.Shreks.Integration.Github/Exceptions/InfrastructureInvalidOperationException.cs b/Source/Infrastructure/Integration/Kysect.Shreks.Integration.Github/Exceptions/InfrastructureInvalidOperationException.cs index 11c2950f6..212abc42b 100644 --- a/Source/Infrastructure/Integration/Kysect.Shreks.Integration.Github/Exceptions/InfrastructureInvalidOperationException.cs +++ b/Source/Infrastructure/Integration/Kysect.Shreks.Integration.Github/Exceptions/InfrastructureInvalidOperationException.cs @@ -2,5 +2,6 @@ namespace Kysect.Shreks.Integration.Github.Exceptions; public class InfrastructureInvalidOperationException : ShreksInfrastructureException { - public InfrastructureInvalidOperationException(string? message) : base(message) { } + public InfrastructureInvalidOperationException(string? message) + : base(message) { } } \ No newline at end of file diff --git a/Source/Infrastructure/Integration/Kysect.Shreks.Integration.Github/Exceptions/ShreksInfrastructureException.cs b/Source/Infrastructure/Integration/Kysect.Shreks.Integration.Github/Exceptions/ShreksInfrastructureException.cs index 42af4c43c..3d2028304 100644 --- a/Source/Infrastructure/Integration/Kysect.Shreks.Integration.Github/Exceptions/ShreksInfrastructureException.cs +++ b/Source/Infrastructure/Integration/Kysect.Shreks.Integration.Github/Exceptions/ShreksInfrastructureException.cs @@ -3,6 +3,10 @@ namespace Kysect.Shreks.Integration.Github.Exceptions; public abstract class ShreksInfrastructureException : Exception { protected ShreksInfrastructureException() { } - protected ShreksInfrastructureException(string? message) : base(message) { } - protected ShreksInfrastructureException(string? message, Exception? inner) : base(message, inner) { } + + protected ShreksInfrastructureException(string? message) + : base(message) { } + + protected ShreksInfrastructureException(string? message, Exception? inner) + : base(message, inner) { } } \ No newline at end of file diff --git a/Source/Infrastructure/Integration/Kysect.Shreks.Integration.Github/Extensions/ServiceCollectionExtensions.cs b/Source/Infrastructure/Integration/Kysect.Shreks.Integration.Github/Extensions/ServiceCollectionExtensions.cs index fc2465c1d..b2816cd3e 100644 --- a/Source/Infrastructure/Integration/Kysect.Shreks.Integration.Github/Extensions/ServiceCollectionExtensions.cs +++ b/Source/Infrastructure/Integration/Kysect.Shreks.Integration.Github/Extensions/ServiceCollectionExtensions.cs @@ -59,14 +59,14 @@ private static IServiceCollection AddClientFactory( new MemoryCacheEntryOptions() .SetSize(cacheConfiguration.CacheEntryConfiguration.EntrySize) .SetAbsoluteExpiration(cacheConfiguration.CacheEntryConfiguration.AbsoluteExpiration) - .SetSlidingExpiration(cacheConfiguration.CacheEntryConfiguration.SlidingExpiration) - )); + .SetSlidingExpiration(cacheConfiguration.CacheEntryConfiguration.SlidingExpiration))); services.AddSingleton(serviceProvider => { GitHubJwtFactory githubJwtFactory = serviceProvider.GetService()!; - var appClient = new GitHubClient(new ProductHeaderValue("Kysect.Shreks"), + var appClient = new GitHubClient( + new ProductHeaderValue("Kysect.Shreks"), new GithubAppCredentialStore(githubJwtFactory)); return appClient; }); @@ -98,7 +98,9 @@ private static IServiceCollection AddClientFactory( IInstallationClientFactory installationClientFactory = serviceProvider.GetRequiredService(); - return new ServiceOrganizationGithubClientProvider(appClient, installationClientFactory, + return new ServiceOrganizationGithubClientProvider( + appClient, + installationClientFactory, serviceOrganizationName); }); diff --git a/Source/Infrastructure/Integration/Kysect.Shreks.Integration.Github/Helpers/CacheConfiguration.cs b/Source/Infrastructure/Integration/Kysect.Shreks.Integration.Github/Helpers/CacheConfiguration.cs index f1df644ef..52f8c8321 100644 --- a/Source/Infrastructure/Integration/Kysect.Shreks.Integration.Github/Helpers/CacheConfiguration.cs +++ b/Source/Infrastructure/Integration/Kysect.Shreks.Integration.Github/Helpers/CacheConfiguration.cs @@ -3,7 +3,9 @@ namespace Kysect.Shreks.Integration.Github.Helpers; public class CacheConfiguration : IShreksConfiguration { public int SizeLimit { get; init; } + public TimeSpan Expiration { get; init; } + public CacheEntryConfiguration CacheEntryConfiguration { get; init; } = null!; public void Verify() diff --git a/Source/Infrastructure/Integration/Kysect.Shreks.Integration.Github/Helpers/CacheEntryConfiguration.cs b/Source/Infrastructure/Integration/Kysect.Shreks.Integration.Github/Helpers/CacheEntryConfiguration.cs index c4015c95c..32d0f1e9e 100644 --- a/Source/Infrastructure/Integration/Kysect.Shreks.Integration.Github/Helpers/CacheEntryConfiguration.cs +++ b/Source/Infrastructure/Integration/Kysect.Shreks.Integration.Github/Helpers/CacheEntryConfiguration.cs @@ -3,7 +3,9 @@ namespace Kysect.Shreks.Integration.Github.Helpers; public class CacheEntryConfiguration : IShreksConfiguration { public int EntrySize { get; init; } + public TimeSpan SlidingExpiration { get; init; } + public TimeSpan AbsoluteExpiration { get; init; } public void Verify() diff --git a/Source/Infrastructure/Integration/Kysect.Shreks.Integration.Github/Helpers/GithubAppConfiguration.cs b/Source/Infrastructure/Integration/Kysect.Shreks.Integration.Github/Helpers/GithubAppConfiguration.cs index 4055ca11f..676eaac41 100644 --- a/Source/Infrastructure/Integration/Kysect.Shreks.Integration.Github/Helpers/GithubAppConfiguration.cs +++ b/Source/Infrastructure/Integration/Kysect.Shreks.Integration.Github/Helpers/GithubAppConfiguration.cs @@ -3,9 +3,13 @@ public class GithubAppConfiguration : IShreksConfiguration { public string? PrivateKey { get; init; } + public int AppIntegrationId { get; init; } + public int JwtExpirationSeconds { get; init; } + public string? GithubAppSecret { get; init; } + public string? ServiceOrganizationName { get; init; } public void Verify() @@ -13,7 +17,6 @@ public void Verify() ArgumentNullException.ThrowIfNull(GithubAppSecret, nameof(GithubAppSecret)); ArgumentNullException.ThrowIfNull(PrivateKey, nameof(PrivateKey)); - if (JwtExpirationSeconds <= 0) { const string message = $"Expiration in {nameof(GithubIntegrationConfiguration)} must be greater than 0"; diff --git a/Source/Infrastructure/Integration/Kysect.Shreks.Integration.Github/Helpers/GithubAuthConfiguration.cs b/Source/Infrastructure/Integration/Kysect.Shreks.Integration.Github/Helpers/GithubAuthConfiguration.cs index 37db15166..747ae32bf 100644 --- a/Source/Infrastructure/Integration/Kysect.Shreks.Integration.Github/Helpers/GithubAuthConfiguration.cs +++ b/Source/Infrastructure/Integration/Kysect.Shreks.Integration.Github/Helpers/GithubAuthConfiguration.cs @@ -3,6 +3,7 @@ public class GithubAuthConfiguration : IShreksConfiguration { public string? OAuthClientId { get; set; } + public string? OAuthClientSecret { get; set; } public void Verify() diff --git a/Source/Infrastructure/Integration/Kysect.Shreks.Integration.Github/Helpers/GithubIntegrationConfiguration.cs b/Source/Infrastructure/Integration/Kysect.Shreks.Integration.Github/Helpers/GithubIntegrationConfiguration.cs index 5b5f5b8b4..5a34175da 100644 --- a/Source/Infrastructure/Integration/Kysect.Shreks.Integration.Github/Helpers/GithubIntegrationConfiguration.cs +++ b/Source/Infrastructure/Integration/Kysect.Shreks.Integration.Github/Helpers/GithubIntegrationConfiguration.cs @@ -3,6 +3,7 @@ namespace Kysect.Shreks.Integration.Github.Helpers; public class GithubIntegrationConfiguration : IShreksConfiguration { public GithubAuthConfiguration GithubAuthConfiguration { get; set; } = null!; + public GithubAppConfiguration GithubAppConfiguration { get; set; } = null!; public void Verify() diff --git a/Source/Infrastructure/Integration/Kysect.Shreks.Integration.Github/Invites/SubjectCourseGithubOrganizationRepositoryManager.cs b/Source/Infrastructure/Integration/Kysect.Shreks.Integration.Github/Invites/SubjectCourseGithubOrganizationRepositoryManager.cs index ecbd3a409..6c0c990ea 100644 --- a/Source/Infrastructure/Integration/Kysect.Shreks.Integration.Github/Invites/SubjectCourseGithubOrganizationRepositoryManager.cs +++ b/Source/Infrastructure/Integration/Kysect.Shreks.Integration.Github/Invites/SubjectCourseGithubOrganizationRepositoryManager.cs @@ -41,7 +41,8 @@ public async Task AddAdminPermission(string organization, string repositoryName, { GitHubClient client = await _clientProvider.GetClient(organization); - await client.Repository.Collaborator.Add(organization, + await client.Repository.Collaborator.Add( + organization, repositoryName, username, new CollaboratorRequest(Permission.Admin)); diff --git a/Source/Infrastructure/Integration/Kysect.Shreks.Integration.Google/Models/GoogleIntegrationConfiguration.cs b/Source/Infrastructure/Integration/Kysect.Shreks.Integration.Google/Models/GoogleIntegrationConfiguration.cs index 46eb2f3b9..61c9aee90 100644 --- a/Source/Infrastructure/Integration/Kysect.Shreks.Integration.Google/Models/GoogleIntegrationConfiguration.cs +++ b/Source/Infrastructure/Integration/Kysect.Shreks.Integration.Google/Models/GoogleIntegrationConfiguration.cs @@ -3,6 +3,8 @@ public class GoogleIntegrationConfiguration { public string ClientSecrets { get; set; } = string.Empty; + public string GoogleDriveId { get; set; } = string.Empty; + public bool EnableGoogleIntegration { get; set; } } \ No newline at end of file diff --git a/Source/Infrastructure/Integration/Kysect.Shreks.Integration.Google/Tables/LabsTable.cs b/Source/Infrastructure/Integration/Kysect.Shreks.Integration.Google/Tables/LabsTable.cs index acf266b23..f27c93110 100644 --- a/Source/Infrastructure/Integration/Kysect.Shreks.Integration.Google/Tables/LabsTable.cs +++ b/Source/Infrastructure/Integration/Kysect.Shreks.Integration.Google/Tables/LabsTable.cs @@ -7,12 +7,16 @@ using Kysect.Shreks.Application.Dto.Users; using Kysect.Shreks.Integration.Google.Extensions; using Kysect.Shreks.Integration.Google.Providers; +using System.Diagnostics.CodeAnalysis; using System.Drawing; using System.Globalization; using static FluentSpreadsheets.ComponentFactory; namespace Kysect.Shreks.Integration.Google.Tables; +[SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1110:Opening parenthesis or bracket should be on declaration line", Justification = "FluentSpreadsheets components setup readability is messy with this rule applied")] +[SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1111:Closing parenthesis should be on line of last parameter", Justification = "FluentSpreadsheets components setup readability is messy with this rule applied")] +[SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1009:Closing parenthesis should be spaced correctly", Justification = "FluentSpreadsheets components setup readability is messy with this rule applied")] public class LabsTable : RowTable { private static readonly IComponent BlankLabel = Label(string.Empty); diff --git a/Source/Infrastructure/Integration/Kysect.Shreks.Integration.Google/Tables/PointsTable.cs b/Source/Infrastructure/Integration/Kysect.Shreks.Integration.Google/Tables/PointsTable.cs index e6c034e45..10ff96789 100644 --- a/Source/Infrastructure/Integration/Kysect.Shreks.Integration.Google/Tables/PointsTable.cs +++ b/Source/Infrastructure/Integration/Kysect.Shreks.Integration.Google/Tables/PointsTable.cs @@ -16,8 +16,7 @@ public class PointsTable : RowTable private const int ReferenceRowShift = 2; private const string ReferenceHeaderRange = "1:1"; - private static readonly IRowComponent Header = Row - ( + private static readonly IRowComponent Header = Row( Label("ISU").WithColumnWidth(0.8).WithFrozenRows(), Label("ФИО").WithColumnWidth(2), Label("Группа"), @@ -27,8 +26,7 @@ public class PointsTable : RowTable Label("Экзамен"), Label("Сумма"), Label("Оценка"), - Label("Комментарий").WithColumnWidth(2.7).WithTrailingMediumBorder() - ); + Label("Комментарий").WithColumnWidth(2.7).WithTrailingMediumBorder()); protected override IComponent Customize(IComponent component) { @@ -53,8 +51,7 @@ protected override IEnumerable RenderRows(CourseStudentsDto model private static IRowComponent GetRowReference() { - return Row - ( + return Row( Label(AssignedReference), Label(AssignedReference), Label(AssignedReference), @@ -64,8 +61,7 @@ private static IRowComponent GetRowReference() Empty(), Label(GetTotalFunction), Label(PointsFormula), - Empty().WithTrailingMediumBorder() - ); + Empty().WithTrailingMediumBorder()); } private static string AssignedReference(Index index) diff --git a/Source/Infrastructure/Integration/Kysect.Shreks.Integration.Google/Tables/QueueTable.cs b/Source/Infrastructure/Integration/Kysect.Shreks.Integration.Google/Tables/QueueTable.cs index 948740595..b6767e11c 100644 --- a/Source/Infrastructure/Integration/Kysect.Shreks.Integration.Google/Tables/QueueTable.cs +++ b/Source/Infrastructure/Integration/Kysect.Shreks.Integration.Google/Tables/QueueTable.cs @@ -6,6 +6,7 @@ using Kysect.Shreks.Application.Dto.Users; using Kysect.Shreks.Integration.Google.Extensions; using Kysect.Shreks.Integration.Google.Providers; +using System.Diagnostics.CodeAnalysis; using System.Drawing; using static FluentSpreadsheets.ComponentFactory; @@ -13,15 +14,13 @@ namespace Kysect.Shreks.Integration.Google.Tables; public class QueueTable : RowTable { - private static readonly IRowComponent Header = Row - ( + private static readonly IRowComponent Header = Row( Label("ФИО").WithColumnWidth(2).WithFrozenRows(), Label("Группа"), Label("Лабораторная работа").WithColumnWidth(1.2), Label("Дата").WithColumnWidth(1.2), Label("Статус"), - Label("GitHub").WithColumnWidth(3.2).WithTrailingMediumBorder() - ); + Label("GitHub").WithColumnWidth(3.2).WithTrailingMediumBorder()); private readonly ICultureInfoProvider _cultureInfoProvider; @@ -38,6 +37,9 @@ protected override IComponent Customize(IComponent component) return component.WithDefaultStyle(); } + [SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1110:Opening parenthesis or bracket should be on declaration line", Justification = "FluentSpreadsheets components setup readability is messy with this rule applied")] + [SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1111:Closing parenthesis should be on line of last parameter", Justification = "FluentSpreadsheets components setup readability is messy with this rule applied")] + [SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1009:Closing parenthesis should be spaced correctly", Justification = "FluentSpreadsheets components setup readability is messy with this rule applied")] protected override IEnumerable RenderRows(SubmissionsQueueDto model) { yield return Header; diff --git a/Source/Infrastructure/Kysect.Shreks.DataAccess/Context/ShreksDatabaseContext.cs b/Source/Infrastructure/Kysect.Shreks.DataAccess/Context/ShreksDatabaseContext.cs index 0a49ff0ff..184e226ae 100644 --- a/Source/Infrastructure/Kysect.Shreks.DataAccess/Context/ShreksDatabaseContext.cs +++ b/Source/Infrastructure/Kysect.Shreks.DataAccess/Context/ShreksDatabaseContext.cs @@ -16,20 +16,33 @@ namespace Kysect.Shreks.DataAccess.Context; public class ShreksDatabaseContext : DbContext, IShreksDatabaseContext { - public ShreksDatabaseContext(DbContextOptions options) : base(options) { } + public ShreksDatabaseContext(DbContextOptions options) + : base(options) { } public DbSet Users { get; protected init; } = null!; + public DbSet Students { get; protected init; } = null!; + public DbSet Mentors { get; protected init; } = null!; + public DbSet Assignments { get; protected init; } = null!; + public DbSet GroupAssignments { get; protected init; } = null!; + public DbSet StudentGroups { get; protected init; } = null!; + public DbSet Subjects { get; protected init; } = null!; + public DbSet SubjectCourses { get; protected init; } = null!; + public DbSet SubjectCourseGroups { get; protected init; } = null!; + public DbSet Submissions { get; protected init; } = null!; + public DbSet SubmissionAssociations { get; protected init; } = null!; + public DbSet UserAssociations { get; protected init; } = null!; + public DbSet SubjectCourseAssociations { get; protected init; } = null!; protected override void OnModelCreating(ModelBuilder modelBuilder) @@ -52,7 +65,8 @@ protected override void ConfigureConventions(ModelConfigurationBuilder configura configurationBuilder.Properties().HaveConversion(); configurationBuilder.Properties().HaveConversion(); configurationBuilder.Properties().HaveConversion(); - //configurationBuilder.Properties().HaveConversion(); + + // configurationBuilder.Properties().HaveConversion(); configurationBuilder.Properties().HaveConversion(); configurationBuilder.Properties().HaveConversion(); } diff --git a/Source/Infrastructure/Kysect.Shreks.DataAccess/Migrations/20220903004757_Initial.cs b/Source/Infrastructure/Kysect.Shreks.DataAccess/Migrations/20220903004757_Initial.cs index d95a577f3..c23fb063f 100644 --- a/Source/Infrastructure/Kysect.Shreks.DataAccess/Migrations/20220903004757_Initial.cs +++ b/Source/Infrastructure/Kysect.Shreks.DataAccess/Migrations/20220903004757_Initial.cs @@ -13,7 +13,7 @@ protected override void Up(MigrationBuilder migrationBuilder) columns: table => new { Id = table.Column(type: "uuid", nullable: false), - Name = table.Column(type: "text", nullable: false) + Name = table.Column(type: "text", nullable: false), }, constraints: table => { @@ -25,7 +25,7 @@ protected override void Up(MigrationBuilder migrationBuilder) columns: table => new { Id = table.Column(type: "uuid", nullable: false), - Title = table.Column(type: "text", nullable: false) + Title = table.Column(type: "text", nullable: false), }, constraints: table => { @@ -36,7 +36,7 @@ protected override void Up(MigrationBuilder migrationBuilder) name: "SubmissionQueues", columns: table => new { - Id = table.Column(type: "uuid", nullable: false) + Id = table.Column(type: "uuid", nullable: false), }, constraints: table => { @@ -50,7 +50,7 @@ protected override void Up(MigrationBuilder migrationBuilder) Id = table.Column(type: "uuid", nullable: false), FirstName = table.Column(type: "text", nullable: false), MiddleName = table.Column(type: "text", nullable: false), - LastName = table.Column(type: "text", nullable: false) + LastName = table.Column(type: "text", nullable: false), }, constraints: table => { @@ -63,7 +63,7 @@ protected override void Up(MigrationBuilder migrationBuilder) { Id = table.Column(type: "uuid", nullable: false), SubjectId = table.Column(type: "uuid", nullable: false), - Title = table.Column(type: "text", nullable: false) + Title = table.Column(type: "text", nullable: false), }, constraints: table => { @@ -84,7 +84,7 @@ protected override void Up(MigrationBuilder migrationBuilder) Position = table.Column(type: "integer", nullable: false), SortingOrder = table.Column(type: "integer", nullable: false), Discriminator = table.Column(type: "text", nullable: false), - SubmissionQueueId = table.Column(type: "uuid", nullable: true) + SubmissionQueueId = table.Column(type: "uuid", nullable: true), }, constraints: table => { @@ -104,7 +104,7 @@ protected override void Up(MigrationBuilder migrationBuilder) Discriminator = table.Column(type: "text", nullable: false), SubmissionQueueId = table.Column(type: "uuid", nullable: true), CourseId = table.Column(type: "uuid", nullable: true), - State = table.Column(type: "integer", nullable: true) + State = table.Column(type: "integer", nullable: true), }, constraints: table => { @@ -121,7 +121,7 @@ protected override void Up(MigrationBuilder migrationBuilder) columns: table => new { UserId = table.Column(type: "uuid", nullable: false), - GroupId = table.Column(type: "uuid", nullable: false) + GroupId = table.Column(type: "uuid", nullable: false), }, constraints: table => { @@ -148,7 +148,7 @@ protected override void Up(MigrationBuilder migrationBuilder) UserId = table.Column(type: "uuid", nullable: false), Discriminator = table.Column(type: "text", nullable: false), GithubUsername = table.Column(type: "text", nullable: true), - UniversityId = table.Column(type: "integer", nullable: true) + UniversityId = table.Column(type: "integer", nullable: true), }, constraints: table => { @@ -171,7 +171,7 @@ protected override void Up(MigrationBuilder migrationBuilder) Order = table.Column(type: "integer", nullable: false), MinPoints = table.Column(type: "double precision", nullable: false), MaxPoints = table.Column(type: "double precision", nullable: false), - SubjectCourseId = table.Column(type: "uuid", nullable: false) + SubjectCourseId = table.Column(type: "uuid", nullable: false), }, constraints: table => { @@ -194,7 +194,7 @@ protected override void Up(MigrationBuilder migrationBuilder) SubjectCourseId = table.Column(type: "uuid", nullable: true), AbsoluteValue = table.Column(type: "double precision", nullable: true), Cap = table.Column(type: "double precision", nullable: true), - Fraction = table.Column(type: "double precision", nullable: true) + Fraction = table.Column(type: "double precision", nullable: true), }, constraints: table => { @@ -211,7 +211,7 @@ protected override void Up(MigrationBuilder migrationBuilder) columns: table => new { CourseId = table.Column(type: "uuid", nullable: false), - UserId = table.Column(type: "uuid", nullable: false) + UserId = table.Column(type: "uuid", nullable: false), }, constraints: table => { @@ -239,7 +239,7 @@ protected override void Up(MigrationBuilder migrationBuilder) Discriminator = table.Column(type: "text", nullable: false), GithubOrganizationName = table.Column(type: "text", nullable: true), TemplateRepositoryName = table.Column(type: "text", nullable: true), - SpreadsheetId = table.Column(type: "text", nullable: true) + SpreadsheetId = table.Column(type: "text", nullable: true), }, constraints: table => { @@ -258,7 +258,7 @@ protected override void Up(MigrationBuilder migrationBuilder) { StudentGroupId = table.Column(type: "uuid", nullable: false), SubjectCourseId = table.Column(type: "uuid", nullable: false), - QueueId = table.Column(type: "uuid", nullable: false) + QueueId = table.Column(type: "uuid", nullable: false), }, constraints: table => { @@ -288,7 +288,7 @@ protected override void Up(MigrationBuilder migrationBuilder) columns: table => new { FiltersId = table.Column(type: "uuid", nullable: false), - GroupsId = table.Column(type: "uuid", nullable: false) + GroupsId = table.Column(type: "uuid", nullable: false), }, constraints: table => { @@ -312,7 +312,7 @@ protected override void Up(MigrationBuilder migrationBuilder) columns: table => new { AssignmentsId = table.Column(type: "uuid", nullable: false), - FiltersId = table.Column(type: "uuid", nullable: false) + FiltersId = table.Column(type: "uuid", nullable: false), }, constraints: table => { @@ -337,7 +337,7 @@ protected override void Up(MigrationBuilder migrationBuilder) { AssignmentId = table.Column(type: "uuid", nullable: false), GroupId = table.Column(type: "uuid", nullable: false), - Deadline = table.Column(type: "date", nullable: false) + Deadline = table.Column(type: "date", nullable: false), }, constraints: table => { @@ -370,7 +370,7 @@ protected override void Up(MigrationBuilder migrationBuilder) Payload = table.Column(type: "text", nullable: false), Rating = table.Column(type: "double precision", nullable: true), ExtraPoints = table.Column(type: "double precision", nullable: true), - Discriminator = table.Column(type: "text", nullable: false) + Discriminator = table.Column(type: "text", nullable: false), }, constraints: table => { @@ -398,7 +398,7 @@ protected override void Up(MigrationBuilder migrationBuilder) Discriminator = table.Column(type: "text", nullable: false), Organization = table.Column(type: "text", nullable: true), Repository = table.Column(type: "text", nullable: true), - PrNumber = table.Column(type: "bigint", nullable: true) + PrNumber = table.Column(type: "bigint", nullable: true), }, constraints: table => { diff --git a/Source/Infrastructure/Kysect.Shreks.DataAccess/Migrations/20220911160107_RemovedQueuePersistense.cs b/Source/Infrastructure/Kysect.Shreks.DataAccess/Migrations/20220911160107_RemovedQueuePersistense.cs index 2f7853b46..81c06e5aa 100644 --- a/Source/Infrastructure/Kysect.Shreks.DataAccess/Migrations/20220911160107_RemovedQueuePersistense.cs +++ b/Source/Infrastructure/Kysect.Shreks.DataAccess/Migrations/20220911160107_RemovedQueuePersistense.cs @@ -49,7 +49,7 @@ protected override void Down(MigrationBuilder migrationBuilder) name: "SubmissionQueues", columns: table => new { - Id = table.Column(type: "uuid", nullable: false) + Id = table.Column(type: "uuid", nullable: false), }, constraints: table => { @@ -64,7 +64,7 @@ protected override void Down(MigrationBuilder migrationBuilder) Discriminator = table.Column(type: "text", nullable: false), Position = table.Column(type: "integer", nullable: false), SortingOrder = table.Column(type: "integer", nullable: false), - SubmissionQueueId = table.Column(type: "uuid", nullable: true) + SubmissionQueueId = table.Column(type: "uuid", nullable: true), }, constraints: table => { @@ -84,7 +84,7 @@ protected override void Down(MigrationBuilder migrationBuilder) Discriminator = table.Column(type: "text", nullable: false), SubmissionQueueId = table.Column(type: "uuid", nullable: true), CourseId = table.Column(type: "uuid", nullable: true), - State = table.Column(type: "integer", nullable: true) + State = table.Column(type: "integer", nullable: true), }, constraints: table => { @@ -101,7 +101,7 @@ protected override void Down(MigrationBuilder migrationBuilder) columns: table => new { AssignmentsId = table.Column(type: "uuid", nullable: false), - FiltersId = table.Column(type: "uuid", nullable: false) + FiltersId = table.Column(type: "uuid", nullable: false), }, constraints: table => { @@ -125,7 +125,7 @@ protected override void Down(MigrationBuilder migrationBuilder) columns: table => new { FiltersId = table.Column(type: "uuid", nullable: false), - GroupsId = table.Column(type: "uuid", nullable: false) + GroupsId = table.Column(type: "uuid", nullable: false), }, constraints: table => { diff --git a/Source/Infrastructure/Kysect.Shreks.DataAccess/ValueConverters/DateOnlyConverter.cs b/Source/Infrastructure/Kysect.Shreks.DataAccess/ValueConverters/DateOnlyConverter.cs index 1280329d6..33e9f87e3 100644 --- a/Source/Infrastructure/Kysect.Shreks.DataAccess/ValueConverters/DateOnlyConverter.cs +++ b/Source/Infrastructure/Kysect.Shreks.DataAccess/ValueConverters/DateOnlyConverter.cs @@ -4,7 +4,10 @@ namespace Kysect.Shreks.DataAccess.ValueConverters; public class DateOnlyConverter : ValueConverter { - public DateOnlyConverter() : base( + public DateOnlyConverter() + : base( x => x.ToDateTime(new TimeOnly(0)), - x => DateOnly.FromDateTime(x)) { } + x => DateOnly.FromDateTime(x)) + { + } } \ No newline at end of file diff --git a/Source/Infrastructure/Kysect.Shreks.DataAccess/ValueConverters/FractionValueConverter.cs b/Source/Infrastructure/Kysect.Shreks.DataAccess/ValueConverters/FractionValueConverter.cs index fa67b9e98..5bec9cae6 100644 --- a/Source/Infrastructure/Kysect.Shreks.DataAccess/ValueConverters/FractionValueConverter.cs +++ b/Source/Infrastructure/Kysect.Shreks.DataAccess/ValueConverters/FractionValueConverter.cs @@ -5,5 +5,6 @@ namespace Kysect.Shreks.DataAccess.ValueConverters; public class FractionValueConverter : ValueConverter { - public FractionValueConverter() : base(x => x.Value, x => new Fraction(x)) { } + public FractionValueConverter() + : base(x => x.Value, x => new Fraction(x)) { } } \ No newline at end of file diff --git a/Source/Infrastructure/Kysect.Shreks.DataAccess/ValueConverters/PointsValueConverter.cs b/Source/Infrastructure/Kysect.Shreks.DataAccess/ValueConverters/PointsValueConverter.cs index f039fbdf4..e1ee18159 100644 --- a/Source/Infrastructure/Kysect.Shreks.DataAccess/ValueConverters/PointsValueConverter.cs +++ b/Source/Infrastructure/Kysect.Shreks.DataAccess/ValueConverters/PointsValueConverter.cs @@ -5,5 +5,6 @@ namespace Kysect.Shreks.DataAccess.ValueConverters; public class PointsValueConverter : ValueConverter { - public PointsValueConverter() : base(x => x.Value, x => new Points(x)) { } + public PointsValueConverter() + : base(x => x.Value, x => new Points(x)) { } } \ No newline at end of file diff --git a/Source/Infrastructure/Kysect.Shreks.DataAccess/ValueConverters/SpbDateTimeValueConverter.cs b/Source/Infrastructure/Kysect.Shreks.DataAccess/ValueConverters/SpbDateTimeValueConverter.cs index ae5240fe9..1c3e897aa 100644 --- a/Source/Infrastructure/Kysect.Shreks.DataAccess/ValueConverters/SpbDateTimeValueConverter.cs +++ b/Source/Infrastructure/Kysect.Shreks.DataAccess/ValueConverters/SpbDateTimeValueConverter.cs @@ -5,7 +5,8 @@ namespace Kysect.Shreks.DataAccess.ValueConverters; public class SpbDateTimeValueConverter : ValueConverter { - public SpbDateTimeValueConverter() : base( + public SpbDateTimeValueConverter() + : base( x => Calendar.ToUtc(x), x => Calendar.FromUtc(x)) { } } \ No newline at end of file diff --git a/Source/Infrastructure/Kysect.Shreks.DataAccess/ValueConverters/TimeSpanConverter.cs b/Source/Infrastructure/Kysect.Shreks.DataAccess/ValueConverters/TimeSpanConverter.cs index bde7d8e54..fab4846ce 100644 --- a/Source/Infrastructure/Kysect.Shreks.DataAccess/ValueConverters/TimeSpanConverter.cs +++ b/Source/Infrastructure/Kysect.Shreks.DataAccess/ValueConverters/TimeSpanConverter.cs @@ -4,5 +4,6 @@ namespace Kysect.Shreks.DataAccess.ValueConverters; public class TimeSpanConverter : ValueConverter { - public TimeSpanConverter() : base(x => x.Ticks, x => TimeSpan.FromTicks(x)) { } + public TimeSpanConverter() + : base(x => x.Ticks, x => TimeSpan.FromTicks(x)) { } } \ No newline at end of file diff --git a/Source/Infrastructure/Kysect.Shreks.Identity/Entities/ShreksIdentityRole.cs b/Source/Infrastructure/Kysect.Shreks.Identity/Entities/ShreksIdentityRole.cs index c718aa436..a0346ffd7 100644 --- a/Source/Infrastructure/Kysect.Shreks.Identity/Entities/ShreksIdentityRole.cs +++ b/Source/Infrastructure/Kysect.Shreks.Identity/Entities/ShreksIdentityRole.cs @@ -6,7 +6,8 @@ public class ShreksIdentityRole : IdentityRole { public const string AdminRoleName = "Admin"; - public ShreksIdentityRole(string roleName) : base(roleName) { } + public ShreksIdentityRole(string roleName) + : base(roleName) { } protected ShreksIdentityRole() { } } \ No newline at end of file diff --git a/Source/Infrastructure/Kysect.Shreks.Identity/ShreksIdentityContext.cs b/Source/Infrastructure/Kysect.Shreks.Identity/ShreksIdentityContext.cs index a96b4ca7d..11bb34bbc 100644 --- a/Source/Infrastructure/Kysect.Shreks.Identity/ShreksIdentityContext.cs +++ b/Source/Infrastructure/Kysect.Shreks.Identity/ShreksIdentityContext.cs @@ -6,7 +6,8 @@ namespace Kysect.Shreks.Identity; public sealed class ShreksIdentityContext : IdentityDbContext { - public ShreksIdentityContext(DbContextOptions options) : base(options) + public ShreksIdentityContext(DbContextOptions options) + : base(options) { Database.EnsureCreated(); } diff --git a/Source/Infrastructure/Kysect.Shreks.Mapping/Profiles/SubjectCourseProfile.cs b/Source/Infrastructure/Kysect.Shreks.Mapping/Profiles/SubjectCourseProfile.cs index df711d712..2d283cd2e 100644 --- a/Source/Infrastructure/Kysect.Shreks.Mapping/Profiles/SubjectCourseProfile.cs +++ b/Source/Infrastructure/Kysect.Shreks.Mapping/Profiles/SubjectCourseProfile.cs @@ -5,9 +5,9 @@ namespace Kysect.Shreks.Mapping.Profiles; -internal class SubjectCourserProfile : Profile +internal class SubjectCourseProfile : Profile { - public SubjectCourserProfile() + public SubjectCourseProfile() { CreateMap(); diff --git a/Source/Infrastructure/Kysect.Shreks.Mapping/Profiles/SubmissionProfile.cs b/Source/Infrastructure/Kysect.Shreks.Mapping/Profiles/SubmissionProfile.cs index 8ce9ef0af..0b7a4c032 100644 --- a/Source/Infrastructure/Kysect.Shreks.Mapping/Profiles/SubmissionProfile.cs +++ b/Source/Infrastructure/Kysect.Shreks.Mapping/Profiles/SubmissionProfile.cs @@ -20,9 +20,11 @@ public SubmissionProfile() .ForCtorParam(nameof(SubmissionDto.State), opt => opt.MapFrom(x => x.State.Kind)); CreateMap() - .ForCtorParam(nameof(QueueSubmissionDto.Submission), + .ForCtorParam( + nameof(QueueSubmissionDto.Submission), opt => opt.MapFrom(x => x)) - .ForCtorParam(nameof(QueueSubmissionDto.Student), + .ForCtorParam( + nameof(QueueSubmissionDto.Student), opt => opt.MapFrom(x => x.Student)); } } \ No newline at end of file diff --git a/Source/Infrastructure/Kysect.Shreks.Mapping/Profiles/UserProfile.cs b/Source/Infrastructure/Kysect.Shreks.Mapping/Profiles/UserProfile.cs index 325d1809e..68580f6fe 100644 --- a/Source/Infrastructure/Kysect.Shreks.Mapping/Profiles/UserProfile.cs +++ b/Source/Infrastructure/Kysect.Shreks.Mapping/Profiles/UserProfile.cs @@ -11,9 +11,11 @@ public UserProfile() { CreateMap(); CreateMap() - .ForCtorParam(nameof(StudentDto.UniversityId), + .ForCtorParam( + nameof(StudentDto.UniversityId), opt => opt.MapFrom(x => x.User.FindAssociation()!.UniversityId)) - .ForCtorParam(nameof(StudentDto.GitHubUsername), + .ForCtorParam( + nameof(StudentDto.GitHubUsername), opt => opt.MapFrom(x => x.User.FindAssociation()!.GithubUsername)); } } \ No newline at end of file diff --git a/Source/Infrastructure/Kysect.Shreks.Seeding/EntityGenerators/DeadlinePolicy/DeadlinePolicyGenerator.cs b/Source/Infrastructure/Kysect.Shreks.Seeding/EntityGenerators/DeadlinePolicy/DeadlinePolicyGenerator.cs index 9cc32aaf3..a584c09dd 100644 --- a/Source/Infrastructure/Kysect.Shreks.Seeding/EntityGenerators/DeadlinePolicy/DeadlinePolicyGenerator.cs +++ b/Source/Infrastructure/Kysect.Shreks.Seeding/EntityGenerators/DeadlinePolicy/DeadlinePolicyGenerator.cs @@ -9,7 +9,8 @@ public class DeadlinePolicyGenerator : EntityGeneratorBase { private readonly Faker _faker; - public DeadlinePolicyGenerator(EntityGeneratorOptions options, Faker faker) : base(options) + public DeadlinePolicyGenerator(EntityGeneratorOptions options, Faker faker) + : base(options) { _faker = faker; } diff --git a/Source/Infrastructure/Kysect.Shreks.Seeding/EntityGenerators/Study/AssignmentGenerator.cs b/Source/Infrastructure/Kysect.Shreks.Seeding/EntityGenerators/Study/AssignmentGenerator.cs index d7078a57a..5fde24daa 100644 --- a/Source/Infrastructure/Kysect.Shreks.Seeding/EntityGenerators/Study/AssignmentGenerator.cs +++ b/Source/Infrastructure/Kysect.Shreks.Seeding/EntityGenerators/Study/AssignmentGenerator.cs @@ -26,15 +26,13 @@ protected override Assignment Generate(int index) int assignmentOrder = index + 1; - var assignment = new Assignment - ( + var assignment = new Assignment( _faker.Commerce.Product(), $"lab-{assignmentOrder}", assignmentOrder, _faker.Random.Points(0, 5), _faker.Random.Points(5, 10), - subjectCourse - ); + subjectCourse); subjectCourse.AddAssignment(assignment); diff --git a/Source/Infrastructure/Kysect.Shreks.Seeding/EntityGenerators/Study/GroupAssignmentGenerator.cs b/Source/Infrastructure/Kysect.Shreks.Seeding/EntityGenerators/Study/GroupAssignmentGenerator.cs index 1a7938876..2ea17f43d 100644 --- a/Source/Infrastructure/Kysect.Shreks.Seeding/EntityGenerators/Study/GroupAssignmentGenerator.cs +++ b/Source/Infrastructure/Kysect.Shreks.Seeding/EntityGenerators/Study/GroupAssignmentGenerator.cs @@ -36,12 +36,10 @@ protected override GroupAssignment Generate(int index) StudentGroup group = _groupGenerator.GeneratedEntities[groupNumber]; Assignment assignment = _assignmentGenerator.GeneratedEntities[assignmentNumber]; - var groupAssignment = new GroupAssignment - ( + var groupAssignment = new GroupAssignment( group, assignment, - DateOnly.FromDateTime(_faker.Date.Future()) - ); + DateOnly.FromDateTime(_faker.Date.Future())); assignment.AddGroupAssignment(groupAssignment); diff --git a/Source/Infrastructure/Kysect.Shreks.Seeding/EntityGenerators/Study/StudentGroupGenerator.cs b/Source/Infrastructure/Kysect.Shreks.Seeding/EntityGenerators/Study/StudentGroupGenerator.cs index 7986dc064..547c28f7f 100644 --- a/Source/Infrastructure/Kysect.Shreks.Seeding/EntityGenerators/Study/StudentGroupGenerator.cs +++ b/Source/Infrastructure/Kysect.Shreks.Seeding/EntityGenerators/Study/StudentGroupGenerator.cs @@ -11,7 +11,8 @@ public class StudentGroupGenerator : EntityGeneratorBase private readonly Faker _faker; - public StudentGroupGenerator(EntityGeneratorOptions options, Faker faker) : base(options) + public StudentGroupGenerator(EntityGeneratorOptions options, Faker faker) + : base(options) { _faker = faker; } diff --git a/Source/Infrastructure/Kysect.Shreks.Seeding/EntityGenerators/Study/SubjectGenerator.cs b/Source/Infrastructure/Kysect.Shreks.Seeding/EntityGenerators/Study/SubjectGenerator.cs index 39b251ed0..ca15d67ec 100644 --- a/Source/Infrastructure/Kysect.Shreks.Seeding/EntityGenerators/Study/SubjectGenerator.cs +++ b/Source/Infrastructure/Kysect.Shreks.Seeding/EntityGenerators/Study/SubjectGenerator.cs @@ -8,7 +8,8 @@ public class SubjectGenerator : EntityGeneratorBase { private readonly Faker _faker; - public SubjectGenerator(EntityGeneratorOptions options, Faker faker) : base(options) + public SubjectGenerator(EntityGeneratorOptions options, Faker faker) + : base(options) { _faker = faker; } diff --git a/Source/Infrastructure/Kysect.Shreks.Seeding/EntityGenerators/Submissions/GithubSubmissionGenerator.cs b/Source/Infrastructure/Kysect.Shreks.Seeding/EntityGenerators/Submissions/GithubSubmissionGenerator.cs index 833537877..09b4677b0 100644 --- a/Source/Infrastructure/Kysect.Shreks.Seeding/EntityGenerators/Submissions/GithubSubmissionGenerator.cs +++ b/Source/Infrastructure/Kysect.Shreks.Seeding/EntityGenerators/Submissions/GithubSubmissionGenerator.cs @@ -45,8 +45,7 @@ protected override GithubSubmission Generate(int index) int submissionCount = groupAssignment.Submissions.Count(x => x.Student.Equals(student)); - var submission = new GithubSubmission - ( + var submission = new GithubSubmission( submissionCount + 1, student, groupAssignment, @@ -54,8 +53,7 @@ protected override GithubSubmission Generate(int index) _faker.Internet.Url(), _faker.Company.CompanyName(), _faker.Commerce.ProductName(), - _faker.Random.Long(0, 100) - ); + _faker.Random.Long(0, 100)); groupAssignment.AddSubmission(submission); diff --git a/Source/Infrastructure/Kysect.Shreks.Seeding/EntityGenerators/User/StudentGenerator.cs b/Source/Infrastructure/Kysect.Shreks.Seeding/EntityGenerators/User/StudentGenerator.cs index 69b00fcd7..3464678ec 100644 --- a/Source/Infrastructure/Kysect.Shreks.Seeding/EntityGenerators/User/StudentGenerator.cs +++ b/Source/Infrastructure/Kysect.Shreks.Seeding/EntityGenerators/User/StudentGenerator.cs @@ -12,7 +12,8 @@ public class StudentGenerator : EntityGeneratorBase public StudentGenerator( EntityGeneratorOptions options, IEntityGenerator studentGroupGenerator, - IEntityGenerator userGenerator) : base(options) + IEntityGenerator userGenerator) + : base(options) { _studentGroupGenerator = studentGroupGenerator; _userGenerator = userGenerator; diff --git a/Source/Infrastructure/Kysect.Shreks.Seeding/EntityGenerators/User/UserGenerator.cs b/Source/Infrastructure/Kysect.Shreks.Seeding/EntityGenerators/User/UserGenerator.cs index bec1656b3..4870a1c5a 100644 --- a/Source/Infrastructure/Kysect.Shreks.Seeding/EntityGenerators/User/UserGenerator.cs +++ b/Source/Infrastructure/Kysect.Shreks.Seeding/EntityGenerators/User/UserGenerator.cs @@ -9,18 +9,17 @@ public class UserGenerator : EntityGeneratorBase { private readonly Faker _faker; - public UserGenerator(EntityGeneratorOptions options, Faker faker) : base(options) + public UserGenerator(EntityGeneratorOptions options, Faker faker) + : base(options) { _faker = faker; } protected override User Generate(int index) { - return new User - ( + return new User( _faker.Name.FirstName(), _faker.Name.MiddleName(), - _faker.Name.LastName() - ); + _faker.Name.LastName()); } } \ No newline at end of file diff --git a/Source/Infrastructure/Kysect.Shreks.Seeding/EntityGenerators/UserAssociations/GithubUserAssociationGenerator.cs b/Source/Infrastructure/Kysect.Shreks.Seeding/EntityGenerators/UserAssociations/GithubUserAssociationGenerator.cs index cac88b66a..37be566d7 100644 --- a/Source/Infrastructure/Kysect.Shreks.Seeding/EntityGenerators/UserAssociations/GithubUserAssociationGenerator.cs +++ b/Source/Infrastructure/Kysect.Shreks.Seeding/EntityGenerators/UserAssociations/GithubUserAssociationGenerator.cs @@ -13,7 +13,8 @@ public class GithubUserAssociationGenerator : EntityGeneratorBase options, Faker faker, - IEntityGenerator userGenerator) : base(options) + IEntityGenerator userGenerator) + : base(options) { _faker = faker; _userGenerator = userGenerator; diff --git a/Source/Infrastructure/Kysect.Shreks.Seeding/EntityGenerators/UserAssociations/IsuUserAssociationGenerator.cs b/Source/Infrastructure/Kysect.Shreks.Seeding/EntityGenerators/UserAssociations/IsuUserAssociationGenerator.cs index 9b59484e7..b4dc69241 100644 --- a/Source/Infrastructure/Kysect.Shreks.Seeding/EntityGenerators/UserAssociations/IsuUserAssociationGenerator.cs +++ b/Source/Infrastructure/Kysect.Shreks.Seeding/EntityGenerators/UserAssociations/IsuUserAssociationGenerator.cs @@ -17,7 +17,8 @@ public class IsuUserAssociationGenerator : EntityGeneratorBase options, Faker faker, - IEntityGenerator userGenerator) : base(options) + IEntityGenerator userGenerator) + : base(options) { _faker = faker; _userGenerator = userGenerator; diff --git a/Source/Playground/Kysect.Shreks.ApiClientGeneration/Program.cs b/Source/Playground/Kysect.Shreks.ApiClientGeneration/Program.cs index be67c4abf..0847c97f7 100644 --- a/Source/Playground/Kysect.Shreks.ApiClientGeneration/Program.cs +++ b/Source/Playground/Kysect.Shreks.ApiClientGeneration/Program.cs @@ -27,7 +27,6 @@ OperationNameGenerator = new MultipleClientsFromFirstTagAndPathSegmentsOperationNameGenerator(), }; - var generator = new CSharpClientGenerator(document, settings); string code = generator.GenerateFile(); diff --git a/Source/Playground/Kysect.Shreks.DataImport/Program.cs b/Source/Playground/Kysect.Shreks.DataImport/Program.cs index a5687a8dc..839cf93d8 100644 --- a/Source/Playground/Kysect.Shreks.DataImport/Program.cs +++ b/Source/Playground/Kysect.Shreks.DataImport/Program.cs @@ -22,8 +22,8 @@ LoginResponse? loginResponse = await identityClient.LoginAsync(new LoginRequest { - Username = "", - Password = "", + Username = string.Empty, + Password = string.Empty, }); client.DefaultRequestHeaders.Add("Authorization", $"Bearer {loginResponse.Token}"); @@ -32,7 +32,7 @@ var studentClient = new StudentClient(baseUrl, client); var userClient = new UserClient(baseUrl, client) { - ReadResponseAsString = true + ReadResponseAsString = true, }; ICollection? createdGroups = await studyGroupClient.StudyGroupGetAsync(); @@ -111,7 +111,7 @@ ShortName = $"lab-{x.Index}", MinPoints = 0, MaxPoints = x.MaxPoints, - Title = x.Title + Title = x.Title, }); foreach (CreateAssignmentRequest? assignmentRequest in assignmentRequests) @@ -125,14 +125,15 @@ .Select(x => { LabConfig lab = labs.Single(xx => xx.Index.Equals(x.assignment.Order)); - return groupAssignmentClient.GroupAssignmentPostAsync(x.group.Id, x.assignment.Id, + return groupAssignmentClient.GroupAssignmentPostAsync( + x.group.Id, + x.assignment.Id, new DateTimeOffset(lab.Deadline)); }); foreach (Task task in groupAssignments) await task; - IEnumerable? tasks = Enumerable.Range(1, 5).Select(x => { var span = TimeSpan.FromDays(x * 7); diff --git a/Source/Presentation/Kysect.Shreks.Commands/Contexts/BaseContext.cs b/Source/Presentation/Kysect.Shreks.Commands/Contexts/BaseContext.cs index 2ad1d0dd9..477f4e881 100644 --- a/Source/Presentation/Kysect.Shreks.Commands/Contexts/BaseContext.cs +++ b/Source/Presentation/Kysect.Shreks.Commands/Contexts/BaseContext.cs @@ -11,5 +11,6 @@ public BaseContext(Guid issuerId, IMediator mediator) } public Guid IssuerId { get; } + public IMediator Mediator { get; } } \ No newline at end of file diff --git a/Source/Presentation/Kysect.Shreks.Commands/Contexts/PayloadAndAssignmentContext.cs b/Source/Presentation/Kysect.Shreks.Commands/Contexts/PayloadAndAssignmentContext.cs index 6861d774b..8d10d9070 100644 --- a/Source/Presentation/Kysect.Shreks.Commands/Contexts/PayloadAndAssignmentContext.cs +++ b/Source/Presentation/Kysect.Shreks.Commands/Contexts/PayloadAndAssignmentContext.cs @@ -12,5 +12,6 @@ public PayloadAndAssignmentContext(Guid issuerId, IMediator mediator, Guid assig } public Guid AssignmentId { get; } + public string Payload { get; } } \ No newline at end of file diff --git a/Source/Presentation/Kysect.Shreks.Commands/Contexts/SubmissionContext.cs b/Source/Presentation/Kysect.Shreks.Commands/Contexts/SubmissionContext.cs index ef07305f3..f9f6c0f92 100644 --- a/Source/Presentation/Kysect.Shreks.Commands/Contexts/SubmissionContext.cs +++ b/Source/Presentation/Kysect.Shreks.Commands/Contexts/SubmissionContext.cs @@ -4,7 +4,8 @@ namespace Kysect.Shreks.Commands.Contexts; public class SubmissionContext : BaseContext { - public SubmissionContext(Guid issuerId, IMediator mediator, Guid submissionId) : base(issuerId, mediator) + public SubmissionContext(Guid issuerId, IMediator mediator, Guid submissionId) + : base(issuerId, mediator) { SubmissionId = submissionId; } diff --git a/Source/Presentation/Kysect.Shreks.Commands/Contexts/UpdateContext.cs b/Source/Presentation/Kysect.Shreks.Commands/Contexts/UpdateContext.cs index fd35b9557..caa67632f 100644 --- a/Source/Presentation/Kysect.Shreks.Commands/Contexts/UpdateContext.cs +++ b/Source/Presentation/Kysect.Shreks.Commands/Contexts/UpdateContext.cs @@ -23,6 +23,7 @@ public UpdateContext( } public AssignmentDto Assignment { get; } + public UserDto Student { get; } public Task GetDefaultSubmissionAsync(CancellationToken cancellationToken) diff --git a/Source/Presentation/Kysect.Shreks.Commands/Result/BaseShreksCommandResult.cs b/Source/Presentation/Kysect.Shreks.Commands/Result/BaseShreksCommandResult.cs index e3b8f7ac6..4be6d2766 100644 --- a/Source/Presentation/Kysect.Shreks.Commands/Result/BaseShreksCommandResult.cs +++ b/Source/Presentation/Kysect.Shreks.Commands/Result/BaseShreksCommandResult.cs @@ -9,6 +9,7 @@ private BaseShreksCommandResult(bool isSuccess, string message) } public bool IsSuccess { get; } + public string Message { get; } public static BaseShreksCommandResult Success(string message) diff --git a/Source/Presentation/Kysect.Shreks.Commands/SubmissionCommands/ActivateCommand.cs b/Source/Presentation/Kysect.Shreks.Commands/SubmissionCommands/ActivateCommand.cs index 45bf100b2..1e77ebb86 100644 --- a/Source/Presentation/Kysect.Shreks.Commands/SubmissionCommands/ActivateCommand.cs +++ b/Source/Presentation/Kysect.Shreks.Commands/SubmissionCommands/ActivateCommand.cs @@ -15,8 +15,10 @@ public async Task ExecuteAsync( ILogger logger, CancellationToken cancellationToken) { - logger.LogInformation("Handle /activate command for submission {SubmissionId} from user {IssuerId}", - context.SubmissionId, context.IssuerId); + logger.LogInformation( + "Handle /activate command for submission {SubmissionId} from user {IssuerId}", + context.SubmissionId, + context.IssuerId); var command = new ActivateSubmission.Command(context.SubmissionId); ActivateSubmission.Response response = await context.Mediator.Send(command, cancellationToken); diff --git a/Source/Presentation/Kysect.Shreks.Commands/SubmissionCommands/DeactivateCommand.cs b/Source/Presentation/Kysect.Shreks.Commands/SubmissionCommands/DeactivateCommand.cs index 478055132..9b0799f83 100644 --- a/Source/Presentation/Kysect.Shreks.Commands/SubmissionCommands/DeactivateCommand.cs +++ b/Source/Presentation/Kysect.Shreks.Commands/SubmissionCommands/DeactivateCommand.cs @@ -15,8 +15,10 @@ public async Task ExecuteAsync( ILogger logger, CancellationToken cancellationToken) { - logger.LogInformation("Handle /deactivate command for submission {SubmissionId} from user {IssuerId}", - context.SubmissionId, context.IssuerId); + logger.LogInformation( + "Handle /deactivate command for submission {SubmissionId} from user {IssuerId}", + context.SubmissionId, + context.IssuerId); var command = new DeactivateSubmission.Command(context.SubmissionId); DeactivateSubmission.Response response = await context.Mediator.Send(command, cancellationToken); diff --git a/Source/Presentation/Kysect.Shreks.Commands/SubmissionCommands/DeleteCommand.cs b/Source/Presentation/Kysect.Shreks.Commands/SubmissionCommands/DeleteCommand.cs index 47c27bf45..7fdfd46bc 100644 --- a/Source/Presentation/Kysect.Shreks.Commands/SubmissionCommands/DeleteCommand.cs +++ b/Source/Presentation/Kysect.Shreks.Commands/SubmissionCommands/DeleteCommand.cs @@ -15,8 +15,10 @@ public async Task ExecuteAsync( ILogger logger, CancellationToken cancellationToken) { - logger.LogInformation("Handle /delete command for submission {SubmissionId} from user {IssuerId}", - context.SubmissionId, context.IssuerId); + logger.LogInformation( + "Handle /delete command for submission {SubmissionId} from user {IssuerId}", + context.SubmissionId, + context.IssuerId); var command = new DeleteSubmission.Command(context.IssuerId, context.SubmissionId); DeleteSubmission.Response response = await context.Mediator.Send(command, cancellationToken); diff --git a/Source/Presentation/Kysect.Shreks.Commands/SubmissionCommands/RateCommand.cs b/Source/Presentation/Kysect.Shreks.Commands/SubmissionCommands/RateCommand.cs index 58e102d36..d1aba3f8e 100644 --- a/Source/Presentation/Kysect.Shreks.Commands/SubmissionCommands/RateCommand.cs +++ b/Source/Presentation/Kysect.Shreks.Commands/SubmissionCommands/RateCommand.cs @@ -27,8 +27,10 @@ public async Task ExecuteAsync( ILogger logger, CancellationToken cancellationToken) { - logger.LogInformation("Handle /rate command from {IssuerId} with arguments: {Args}", - context.IssuerId, ToLogLine()); + logger.LogInformation( + "Handle /rate command from {IssuerId} with arguments: {Args}", + context.IssuerId, + ToLogLine()); var command = new RateSubmission.Command(context.IssuerId, context.SubmissionId, RatingPercent, ExtraPoints); RateSubmission.Response response = await context.Mediator.Send(command, cancellationToken); diff --git a/Source/Presentation/Kysect.Shreks.Commands/SubmissionCommands/UpdateCommand.cs b/Source/Presentation/Kysect.Shreks.Commands/SubmissionCommands/UpdateCommand.cs index cdc8bf339..a5faa4684 100644 --- a/Source/Presentation/Kysect.Shreks.Commands/SubmissionCommands/UpdateCommand.cs +++ b/Source/Presentation/Kysect.Shreks.Commands/SubmissionCommands/UpdateCommand.cs @@ -37,8 +37,10 @@ public async Task ExecuteAsync( ILogger logger, CancellationToken cancellationToken) { - logger.LogInformation("Handle /update command from {IssuerId} with arguments: {Args}", - context.IssuerId, ToLogLine()); + logger.LogInformation( + "Handle /update command from {IssuerId} with arguments: {Args}", + context.IssuerId, + ToLogLine()); SubmissionDto submission = SubmissionCode is null ? await context.GetDefaultSubmissionAsync(cancellationToken) diff --git a/Source/Presentation/Kysect.Shreks.Controllers/AssignmentController.cs b/Source/Presentation/Kysect.Shreks.Controllers/AssignmentsController.cs similarity index 100% rename from Source/Presentation/Kysect.Shreks.Controllers/AssignmentController.cs rename to Source/Presentation/Kysect.Shreks.Controllers/AssignmentsController.cs diff --git a/Source/Presentation/Kysect.Shreks.Controllers/IControllerProjectMarker.cs b/Source/Presentation/Kysect.Shreks.Controllers/IControllerProjectMarker.cs index 04e12e948..2e681426e 100644 --- a/Source/Presentation/Kysect.Shreks.Controllers/IControllerProjectMarker.cs +++ b/Source/Presentation/Kysect.Shreks.Controllers/IControllerProjectMarker.cs @@ -1,3 +1,3 @@ namespace Kysect.Shreks.Controllers; -public interface IControllersProjectMarker { } \ No newline at end of file +public interface IControllerProjectMarker { } \ No newline at end of file diff --git a/Source/Presentation/Kysect.Shreks.Controllers/InternalController.cs b/Source/Presentation/Kysect.Shreks.Controllers/InternalController.cs index 848b57189..d4ac16391 100644 --- a/Source/Presentation/Kysect.Shreks.Controllers/InternalController.cs +++ b/Source/Presentation/Kysect.Shreks.Controllers/InternalController.cs @@ -38,7 +38,8 @@ public async Task SeedTestData([FromQuery] string environment) } catch (UserNotAcknowledgedEnvironmentException e) { - return StatusCode((int)HttpStatusCode.BadRequest, + return StatusCode( + (int)HttpStatusCode.BadRequest, new ProblemDetails { Status = (int)HttpStatusCode.BadRequest, diff --git a/Source/Presentation/Kysect.Shreks.Controllers/Kysect.Shreks.Controllers.csproj b/Source/Presentation/Kysect.Shreks.Controllers/Kysect.Shreks.Controllers.csproj index 41c0cce82..c997ad0bb 100644 --- a/Source/Presentation/Kysect.Shreks.Controllers/Kysect.Shreks.Controllers.csproj +++ b/Source/Presentation/Kysect.Shreks.Controllers/Kysect.Shreks.Controllers.csproj @@ -6,16 +6,16 @@ enable latest True - 1701;1702;CA1062 + 1701;1702;CA1062;SA1101;SA1309;SA1633;SA1503;SA1127;SA1128;SA1502 - - - - - - + + + + + + \ No newline at end of file diff --git a/Source/Presentation/Kysect.Shreks.Controllers/StudentController.cs b/Source/Presentation/Kysect.Shreks.Controllers/StudentController.cs index d9319bb3d..ccfbe1d5f 100644 --- a/Source/Presentation/Kysect.Shreks.Controllers/StudentController.cs +++ b/Source/Presentation/Kysect.Shreks.Controllers/StudentController.cs @@ -30,12 +30,11 @@ public async Task> Create(CreateStudentRequest request) { (string? firstName, string? middleName, string? lastName, Guid groupId) = request; - var command = new CreateStudent.Command - ( + var command = new CreateStudent.Command( firstName ?? string.Empty, middleName ?? string.Empty, - lastName ?? string.Empty, groupId - ); + lastName ?? string.Empty, + groupId); CreateStudent.Response response = await _mediator.Send(command); return Ok(response.Student); diff --git a/Source/Presentation/Kysect.Shreks.Presentation.GitHub/ContextFactories/SubmissionCommandContextFactory.cs b/Source/Presentation/Kysect.Shreks.Presentation.GitHub/ContextFactories/SubmissionCommandContextFactory.cs index 3808dbacd..25eae0cbd 100644 --- a/Source/Presentation/Kysect.Shreks.Presentation.GitHub/ContextFactories/SubmissionCommandContextFactory.cs +++ b/Source/Presentation/Kysect.Shreks.Presentation.GitHub/ContextFactories/SubmissionCommandContextFactory.cs @@ -64,13 +64,11 @@ public async Task PayloadAndAssignmentContextAsync( var query = new GetAssignment.Query(_pullRequestDescriptor.Organization, _pullRequestDescriptor.BranchName); GetAssignment.Response response = await _mediator.Send(query, cancellationToken); - return new PayloadAndAssignmentContext - ( + return new PayloadAndAssignmentContext( user.Id, _mediator, response.Assignment.Id, - _pullRequestDescriptor.Payload - ); + _pullRequestDescriptor.Payload); } public async Task CreateSubmissionContextAsync(CancellationToken cancellationToken) @@ -82,15 +80,13 @@ public async Task CreateSubmissionContextAsync(Cancella async Task CreateFunc(CancellationToken ct) { - var command = new CreateGithubSubmission.Command - ( + var command = new CreateGithubSubmission.Command( user.Id, response.Assignment.Id, _pullRequestDescriptor.Organization, _pullRequestDescriptor.Repository, _pullRequestDescriptor.PrNumber, - _pullRequestDescriptor.Payload - ); + _pullRequestDescriptor.Payload); CreateGithubSubmission.Response commandResponse = await _mediator.Send(command, ct); @@ -100,19 +96,19 @@ async Task CreateFunc(CancellationToken ct) return new CreateSubmissionContext(user.Id, _mediator, CreateFunc, _pullRequestDescriptor.Payload); } - private async Task GetIssuerAsync(CancellationToken cancellationToken) + public async Task GetStudentAsync(CancellationToken cancellationToken) { - var query = new GetUserByGithubUsername.Query(_pullRequestDescriptor.Sender); + var query = new GetUserByGithubUsername.Query(_pullRequestDescriptor.Repository); GetUserByGithubUsername.Response response = await _mediator.Send(query, cancellationToken); return response.User; } - public async Task GetStudentAsync(CancellationToken cancellationToken) + private async Task GetIssuerAsync(CancellationToken cancellationToken) { - var query = new GetUserByGithubUsername.Query(_pullRequestDescriptor.Repository); + var query = new GetUserByGithubUsername.Query(_pullRequestDescriptor.Sender); GetUserByGithubUsername.Response response = await _mediator.Send(query, cancellationToken); - + return response.User; } } \ No newline at end of file diff --git a/Source/Presentation/Kysect.Shreks.Presentation.GitHub/Notifiers/IActionNotifier.cs b/Source/Presentation/Kysect.Shreks.Presentation.GitHub/Notifiers/IActionNotifier.cs index de487b3e5..479f4a527 100644 --- a/Source/Presentation/Kysect.Shreks.Presentation.GitHub/Notifiers/IActionNotifier.cs +++ b/Source/Presentation/Kysect.Shreks.Presentation.GitHub/Notifiers/IActionNotifier.cs @@ -5,6 +5,8 @@ namespace Kysect.Shreks.Presentation.GitHub.Notifiers; public interface IActionNotifier { Task SendComment(WebhookEvent webhookEvent, long issueNumber, string message); + Task SendCommitComment(WebhookEvent webhookEvent, string sha, string message); + Task ReactInComments(WebhookEvent webhookEvent, long commentId, bool isSuccessful); } \ No newline at end of file diff --git a/Source/Presentation/Kysect.Shreks.Presentation.GitHub/Processing/ShreksWebhookEventHandler.cs b/Source/Presentation/Kysect.Shreks.Presentation.GitHub/Processing/ShreksWebhookEventHandler.cs index 89acbaf4b..a6dd1bddb 100644 --- a/Source/Presentation/Kysect.Shreks.Presentation.GitHub/Processing/ShreksWebhookEventHandler.cs +++ b/Source/Presentation/Kysect.Shreks.Presentation.GitHub/Processing/ShreksWebhookEventHandler.cs @@ -62,16 +62,14 @@ public async Task ProcessPullRequestUpdate( AssignmentDto assignment = await GetAssignmentAsync( prDescriptor.Organization, prDescriptor.BranchName, cancellationToken); - var command = new PullRequestUpdated.Command - ( + var command = new PullRequestUpdated.Command( issuer.Id, user.Id, assignment.Id, prDescriptor.Organization, prDescriptor.Repository, prDescriptor.PrNumber, - prDescriptor.Payload - ); + prDescriptor.Payload); PullRequestUpdated.Response response = await _mediator.Send(command, cancellationToken); SubmissionUpdateResult result = response.Message; @@ -191,6 +189,15 @@ public async Task ProcessIssueCommentCreate( await eventNotifier.ReactToUserComment(result.IsSuccess); } + private static async Task NotifySubmissionActionMessage( + SubmissionActionMessageDto message, + IPullRequestEventNotifier eventNotifier, + ILogger logger) + { + await eventNotifier.SendCommentToPullRequest(message.Message); + logger.LogInformation("Notify: {Message}", message.Message); + } + private async Task GetUserAsync( string username, CancellationToken cancellationToken) @@ -254,13 +261,4 @@ private async Task ExecuteCommand( return result; } - - private static async Task NotifySubmissionActionMessage( - SubmissionActionMessageDto message, - IPullRequestEventNotifier eventNotifier, - ILogger logger) - { - await eventNotifier.SendCommentToPullRequest(message.Message); - logger.LogInformation("Notify: {Message}", message.Message); - } } \ No newline at end of file diff --git a/Source/Presentation/Kysect.Shreks.Presentation.GitHub/Processing/ShreksWebhookEventProcessor.cs b/Source/Presentation/Kysect.Shreks.Presentation.GitHub/Processing/ShreksWebhookEventProcessor.cs index bc0c2b9da..a53eb1a15 100644 --- a/Source/Presentation/Kysect.Shreks.Presentation.GitHub/Processing/ShreksWebhookEventProcessor.cs +++ b/Source/Presentation/Kysect.Shreks.Presentation.GitHub/Processing/ShreksWebhookEventProcessor.cs @@ -51,17 +51,18 @@ protected override async Task ProcessPullRequestWebhookAsync( string pullRequestAction = action; - repositoryLogger.LogInformation("{MethodName}: {EventName} with type {Action}", - methodName, pullRequestEvent.GetType().Name, pullRequestAction); + repositoryLogger.LogInformation( + "{MethodName}: {EventName} with type {Action}", + methodName, + pullRequestEvent.GetType().Name, + pullRequestAction); - var pullRequestCommitEventNotifier = new PullRequestCommitEventNotifier - ( + var pullRequestCommitEventNotifier = new PullRequestCommitEventNotifier( _actionNotifier, pullRequestEvent, pullRequestEvent.PullRequest.Head.Sha, pullRequestEvent.PullRequest.Number, - repositoryLogger - ); + repositoryLogger); try { @@ -69,19 +70,29 @@ protected override async Task ProcessPullRequestWebhookAsync( { case PullRequestActionValue.Synchronize: case PullRequestActionValue.Opened: - await _handler.ProcessPullRequestUpdate(githubPullRequestDescriptor, repositoryLogger, - pullRequestCommitEventNotifier, default); + await _handler.ProcessPullRequestUpdate( + githubPullRequestDescriptor, + repositoryLogger, + pullRequestCommitEventNotifier, + default); break; case PullRequestActionValue.Reopened: - await _handler.ProcessPullRequestReopen(githubPullRequestDescriptor, repositoryLogger, - pullRequestCommitEventNotifier, default); + await _handler.ProcessPullRequestReopen( + githubPullRequestDescriptor, + repositoryLogger, + pullRequestCommitEventNotifier, + default); break; case PullRequestActionValue.Closed: bool merged = pullRequestEvent.PullRequest.Merged ?? false; - await _handler.ProcessPullRequestClosed(merged, githubPullRequestDescriptor, repositoryLogger, - pullRequestCommitEventNotifier, default); + await _handler.ProcessPullRequestClosed( + merged, + githubPullRequestDescriptor, + repositoryLogger, + pullRequestCommitEventNotifier, + default); break; case PullRequestActionValue.Assigned: @@ -91,7 +102,8 @@ await _handler.ProcessPullRequestClosed(merged, githubPullRequestDescriptor, rep break; default: - repositoryLogger.LogWarning("Unsupported pull request webhook type was received: {Action}", + repositoryLogger.LogWarning( + "Unsupported pull request webhook type was received: {Action}", pullRequestAction); break; } @@ -123,11 +135,17 @@ protected override async Task ProcessPullRequestReviewWebhookAsync( string pullRequestReviewAction = action; - repositoryLogger.LogInformation("{MethodName}: {Name} with type {Action}", - methodName, pullRequestReviewEvent.GetType().Name, pullRequestReviewAction); + repositoryLogger.LogInformation( + "{MethodName}: {Name} with type {Action}", + methodName, + pullRequestReviewEvent.GetType().Name, + pullRequestReviewAction); - var pullRequestEventNotifier = new PullRequestEventNotifier(_actionNotifier, pullRequestReviewEvent, - pullRequestReviewEvent.PullRequest.Number, repositoryLogger); + var pullRequestEventNotifier = new PullRequestEventNotifier( + _actionNotifier, + pullRequestReviewEvent, + pullRequestReviewEvent.PullRequest.Number, + repositoryLogger); try { @@ -136,28 +154,42 @@ protected override async Task ProcessPullRequestReviewWebhookAsync( switch (pullRequestReviewAction1) { case PullRequestReviewActionValue.Submitted when pullRequestReviewEvent.Review.State == "approved": - await _handler.ProcessPullRequestReviewApprove(pullRequestReviewEvent.Review.Body, - githubPullRequestDescriptor, repositoryLogger, pullRequestEventNotifier, default); + await _handler.ProcessPullRequestReviewApprove( + pullRequestReviewEvent.Review.Body, + githubPullRequestDescriptor, + repositoryLogger, + pullRequestEventNotifier, + default); break; case PullRequestReviewActionValue.Submitted when pullRequestReviewEvent.Review.State == "changes_requested": - await _handler.ProcessPullRequestReviewRequestChanges(pullRequestReviewEvent.Review.Body, - githubPullRequestDescriptor, repositoryLogger, pullRequestEventNotifier, default); + await _handler.ProcessPullRequestReviewRequestChanges( + pullRequestReviewEvent.Review.Body, + githubPullRequestDescriptor, + repositoryLogger, + pullRequestEventNotifier, + default); break; case PullRequestReviewActionValue.Submitted when pullRequestReviewEvent.Review.State == "commented": - await _handler.ProcessPullRequestReviewComment(pullRequestReviewEvent.Review.Body, - githubPullRequestDescriptor, repositoryLogger, pullRequestEventNotifier, default); + await _handler.ProcessPullRequestReviewComment( + pullRequestReviewEvent.Review.Body, + githubPullRequestDescriptor, + repositoryLogger, + pullRequestEventNotifier, + default); break; case PullRequestReviewActionValue.Edited: case PullRequestReviewActionValue.Dismissed: - repositoryLogger.LogWarning("Pull request review action {Action} is not supported", + repositoryLogger.LogWarning( + "Pull request review action {Action} is not supported", pullRequestReviewAction1); break; default: - repositoryLogger.LogWarning("Pull request review for pr {PrLink} is not processed", + repositoryLogger.LogWarning( + "Pull request review for pr {PrLink} is not processed", githubPullRequestDescriptor.Payload); break; } @@ -183,14 +215,14 @@ protected override async Task ProcessIssueCommentWebhookAsync( if (IsSenderBotOrNull(issueCommentEvent)) { - repositoryLogger.LogTrace( - $"{methodName} was skipped because sender is bot or null"); + repositoryLogger.LogTrace($"{methodName} was skipped because sender is bot or null"); return; } if (IsPullRequestCommand(issueCommentEvent) is false) { - repositoryLogger.LogTrace("Skipping commit in {IssueId}. Issue comments is not supported", + repositoryLogger.LogTrace( + "Skipping commit in {IssueId}. Issue comments is not supported", issueCommentEvent.Issue.Id); return; @@ -198,24 +230,36 @@ protected override async Task ProcessIssueCommentWebhookAsync( string issueCommentAction = action; - repositoryLogger.LogInformation("{MethodName}: {EventName} with type {Action}", - methodName, issueCommentEvent.GetType().Name, issueCommentAction); + repositoryLogger.LogInformation( + "{MethodName}: {EventName} with type {Action}", + methodName, + issueCommentEvent.GetType().Name, + issueCommentAction); - var pullRequestCommentEventNotifier = new PullRequestCommentEventNotifier(_actionNotifier, issueCommentEvent, - issueCommentEvent.Comment.Id, issueCommentEvent.Issue.Number, repositoryLogger); + var pullRequestCommentEventNotifier = new PullRequestCommentEventNotifier( + _actionNotifier, + issueCommentEvent, + issueCommentEvent.Comment.Id, + issueCommentEvent.Issue.Number, + repositoryLogger); try { switch (issueCommentAction) { case IssueCommentActionValue.Created: - await _handler.ProcessIssueCommentCreate(issueCommentEvent.Comment.Body, - githubPullRequestDescriptor, repositoryLogger, pullRequestCommentEventNotifier, default); + await _handler.ProcessIssueCommentCreate( + issueCommentEvent.Comment.Body, + githubPullRequestDescriptor, + repositoryLogger, + pullRequestCommentEventNotifier, + default); break; case IssueCommentActionValue.Deleted: case IssueCommentActionValue.Edited: - repositoryLogger.LogTrace("Pull request comment {Action} event will be ignored", + repositoryLogger.LogTrace( + "Pull request comment {Action} event will be ignored", issueCommentAction); break; } @@ -239,7 +283,7 @@ private bool IsSenderBotOrNull(WebhookEvent webhookEvent) return webhookEvent.Sender is null || webhookEvent.Sender.Type == UserType.Bot; } - public GithubPullRequestDescriptor CreateDescriptor(PullRequestEvent @event) + private GithubPullRequestDescriptor CreateDescriptor(PullRequestEvent @event) { string login = @event.Sender!.Login; string payload = @event.PullRequest.HtmlUrl; @@ -259,7 +303,7 @@ public GithubPullRequestDescriptor CreateDescriptor(PullRequestEvent @event) return pullRequestDescriptor; } - public GithubPullRequestDescriptor CreateDescriptor(PullRequestReviewEvent pullRequestReviewEvent) + private GithubPullRequestDescriptor CreateDescriptor(PullRequestReviewEvent pullRequestReviewEvent) { return new GithubPullRequestDescriptor( pullRequestReviewEvent.Sender!.Login, diff --git a/Source/Presentation/Kysect.Shreks.WebApi.Sdk/Exceptions/RequestFailedException.cs b/Source/Presentation/Kysect.Shreks.WebApi.Sdk/Exceptions/RequestFailedException.cs index eb79daf67..b45cde19e 100644 --- a/Source/Presentation/Kysect.Shreks.WebApi.Sdk/Exceptions/RequestFailedException.cs +++ b/Source/Presentation/Kysect.Shreks.WebApi.Sdk/Exceptions/RequestFailedException.cs @@ -4,7 +4,8 @@ namespace Kysect.Shreks.WebApi.Sdk.Exceptions; public class RequestFailedException : ShreksSdkException { - private RequestFailedException(string message, HttpStatusCode code) : base(message) + private RequestFailedException(string message, HttpStatusCode code) + : base(message) { Code = code; } diff --git a/Source/Presentation/Kysect.Shreks.WebApi.Sdk/Exceptions/ShreksSdkException.cs b/Source/Presentation/Kysect.Shreks.WebApi.Sdk/Exceptions/ShreksSdkException.cs index ba32af4e1..a897bd3ab 100644 --- a/Source/Presentation/Kysect.Shreks.WebApi.Sdk/Exceptions/ShreksSdkException.cs +++ b/Source/Presentation/Kysect.Shreks.WebApi.Sdk/Exceptions/ShreksSdkException.cs @@ -2,5 +2,6 @@ namespace Kysect.Shreks.WebApi.Sdk.Exceptions; public class ShreksSdkException : Exception { - private protected ShreksSdkException(string message) : base(message) { } + private protected ShreksSdkException(string message) + : base(message) { } } \ No newline at end of file diff --git a/Source/Presentation/Kysect.Shreks.WebApi.Sdk/Exceptions/UnauthorizedException.cs b/Source/Presentation/Kysect.Shreks.WebApi.Sdk/Exceptions/UnauthorizedException.cs index 5ec6b8fda..5f9c9baf2 100644 --- a/Source/Presentation/Kysect.Shreks.WebApi.Sdk/Exceptions/UnauthorizedException.cs +++ b/Source/Presentation/Kysect.Shreks.WebApi.Sdk/Exceptions/UnauthorizedException.cs @@ -2,5 +2,6 @@ namespace Kysect.Shreks.WebApi.Sdk.Exceptions; public class UnauthorizedException : ShreksSdkException { - public UnauthorizedException(string message = "") : base(message) { } + public UnauthorizedException(string message = "") + : base(message) { } } \ No newline at end of file diff --git a/Source/Presentation/Kysect.Shreks.WebApi/Configuration/WebApiConfiguration.cs b/Source/Presentation/Kysect.Shreks.WebApi/Configuration/WebApiConfiguration.cs index 25b657342..8bcef40e9 100644 --- a/Source/Presentation/Kysect.Shreks.WebApi/Configuration/WebApiConfiguration.cs +++ b/Source/Presentation/Kysect.Shreks.WebApi/Configuration/WebApiConfiguration.cs @@ -27,9 +27,14 @@ public WebApiConfiguration(IConfiguration configuration) } public GoogleIntegrationConfiguration GoogleIntegrationConfiguration { get; } + public CacheConfiguration CacheConfiguration { get; } + public GithubIntegrationConfiguration GithubIntegrationConfiguration { get; } + public TestEnvironmentConfiguration? TestEnvironmentConfiguration { get; } + public PostgresConfiguration PostgresConfiguration { get; } + public DbNamesConfiguration DbNamesConfiguration { get; } } \ No newline at end of file diff --git a/Source/Presentation/Kysect.Shreks.WebApi/Extensions/ServiceCollectionExtensions.cs b/Source/Presentation/Kysect.Shreks.WebApi/Extensions/ServiceCollectionExtensions.cs index 91f548540..e04183e68 100644 --- a/Source/Presentation/Kysect.Shreks.WebApi/Extensions/ServiceCollectionExtensions.cs +++ b/Source/Presentation/Kysect.Shreks.WebApi/Extensions/ServiceCollectionExtensions.cs @@ -28,7 +28,7 @@ internal static IServiceCollection ConfigureServiceCollection( serviceCollection .AddControllers(x => x.Filters.Add()) .AddNewtonsoftJson() - .AddApplicationPart(typeof(IControllersProjectMarker).Assembly) + .AddApplicationPart(typeof(IControllerProjectMarker).Assembly) .AddControllersAsServices(); serviceCollection @@ -50,7 +50,8 @@ internal static IServiceCollection ConfigureServiceCollection( serviceCollection .AddGoogleIntegrationServices(webApiConfiguration) - .AddGithubServices(webApiConfiguration.CacheConfiguration, + .AddGithubServices( + webApiConfiguration.CacheConfiguration, webApiConfiguration.GithubIntegrationConfiguration) .AddGithubWorkflowServices(); diff --git a/Source/Presentation/Kysect.Shreks.WebApi/Extensions/StartupExtensions.cs b/Source/Presentation/Kysect.Shreks.WebApi/Extensions/StartupExtensions.cs index 75563e8f5..713fc3082 100644 --- a/Source/Presentation/Kysect.Shreks.WebApi/Extensions/StartupExtensions.cs +++ b/Source/Presentation/Kysect.Shreks.WebApi/Extensions/StartupExtensions.cs @@ -12,7 +12,6 @@ internal static WebApplication Configure( app.UseRequestLogging(); if (app.Environment.IsDevelopment()) - //await app.Services.UseDatabaseSeeders(); app.UseWebAssemblyDebugging(); app.UseSwagger(); diff --git a/Source/Presentation/Kysect.Shreks.WebApi/Extensions/WebApplicationExtensions.cs b/Source/Presentation/Kysect.Shreks.WebApi/Extensions/WebApplicationExtensions.cs index d313f9b1b..be7d608e8 100644 --- a/Source/Presentation/Kysect.Shreks.WebApi/Extensions/WebApplicationExtensions.cs +++ b/Source/Presentation/Kysect.Shreks.WebApi/Extensions/WebApplicationExtensions.cs @@ -12,11 +12,11 @@ public static IApplicationBuilder UseRequestLogging(this WebApplication webAppli options.IncludeQueryInRequestPath = true; options.Logger = new LoggerConfiguration() .MinimumLevel.Verbose() - .WriteTo.File(Path.Join(BaseDirectoryName, "RequestLog_.log"), + .WriteTo.File( + Path.Join(BaseDirectoryName, "RequestLog_.log"), outputTemplate: "{Timestamp:o} {Message}{NewLine}", rollingInterval: RollingInterval.Day, - retainedFileCountLimit: 30 - ) + retainedFileCountLimit: 30) .CreateLogger(); }); } diff --git a/Source/Presentation/Kysect.Shreks.WebApi/Program.cs b/Source/Presentation/Kysect.Shreks.WebApi/Program.cs index 4461134ac..7139c887f 100644 --- a/Source/Presentation/Kysect.Shreks.WebApi/Program.cs +++ b/Source/Presentation/Kysect.Shreks.WebApi/Program.cs @@ -16,7 +16,8 @@ public static async Task Main(string[] args) IConfigurationSection identityConfigurationSection = builder.Configuration.GetSection("Identity").GetSection("IdentityConfiguration"); - builder.Services.ConfigureServiceCollection(webApiConfiguration, + builder.Services.ConfigureServiceCollection( + webApiConfiguration, identityConfigurationSection, builder.Environment.IsDevelopment()); diff --git a/Source/Presentation/Kysect.Shreks.WebUI.AdminPanel/ExceptionHandling/ExceptionManager.cs b/Source/Presentation/Kysect.Shreks.WebUI.AdminPanel/ExceptionHandling/ExceptionManager.cs index d6be3235d..c8d1b0104 100644 --- a/Source/Presentation/Kysect.Shreks.WebUI.AdminPanel/ExceptionHandling/ExceptionManager.cs +++ b/Source/Presentation/Kysect.Shreks.WebUI.AdminPanel/ExceptionHandling/ExceptionManager.cs @@ -35,6 +35,7 @@ public void Dismiss(ExceptionMessage exception) } public event Action? ExceptionAdded; + public event Action? ExceptionDismissed; protected virtual void OnExceptionAdded(ExceptionMessage obj) diff --git a/Source/Presentation/Kysect.Shreks.WebUI.AdminPanel/ExceptionHandling/IExceptionStore.cs b/Source/Presentation/Kysect.Shreks.WebUI.AdminPanel/ExceptionHandling/IExceptionStore.cs index 8c16cb883..a5067f05f 100644 --- a/Source/Presentation/Kysect.Shreks.WebUI.AdminPanel/ExceptionHandling/IExceptionStore.cs +++ b/Source/Presentation/Kysect.Shreks.WebUI.AdminPanel/ExceptionHandling/IExceptionStore.cs @@ -5,8 +5,10 @@ namespace Kysect.Shreks.WebUI.AdminPanel.ExceptionHandling; public interface IExceptionStore { IReadOnlyCollection Exceptions { get; } + void Dismiss(ExceptionMessage exception); event Action ExceptionAdded; + event Action ExceptionDismissed; } \ No newline at end of file diff --git a/Source/Presentation/Kysect.Shreks.WebUI.AdminPanel/ExceptionHandling/ISafeExecutor.cs b/Source/Presentation/Kysect.Shreks.WebUI.AdminPanel/ExceptionHandling/ISafeExecutor.cs index 3e0b71c1f..cb31a1c90 100644 --- a/Source/Presentation/Kysect.Shreks.WebUI.AdminPanel/ExceptionHandling/ISafeExecutor.cs +++ b/Source/Presentation/Kysect.Shreks.WebUI.AdminPanel/ExceptionHandling/ISafeExecutor.cs @@ -5,5 +5,6 @@ namespace Kysect.Shreks.WebUI.AdminPanel.ExceptionHandling; public interface ISafeExecutor { ISafeExecutionBuilder Execute(Func action); + ISafeExecutionBuilder Execute(Func> action); } \ No newline at end of file diff --git a/Source/Presentation/Kysect.Shreks.WebUI.AdminPanel/Exceptions/AdminPanelException.cs b/Source/Presentation/Kysect.Shreks.WebUI.AdminPanel/Exceptions/AdminPanelException.cs index d0fa0b546..4a3cc8e3c 100644 --- a/Source/Presentation/Kysect.Shreks.WebUI.AdminPanel/Exceptions/AdminPanelException.cs +++ b/Source/Presentation/Kysect.Shreks.WebUI.AdminPanel/Exceptions/AdminPanelException.cs @@ -2,5 +2,6 @@ namespace Kysect.Shreks.WebUI.AdminPanel.Exceptions; public abstract class AdminPanelException : Exception { - protected AdminPanelException(string? message) : base(message) { } + protected AdminPanelException(string? message) + : base(message) { } } \ No newline at end of file diff --git a/Source/Presentation/Kysect.Shreks.WebUI.AdminPanel/SafeExecution/ISafeExecutionBuilder.cs b/Source/Presentation/Kysect.Shreks.WebUI.AdminPanel/SafeExecution/ISafeExecutionBuilder.cs index a0d256c4c..3f294563d 100644 --- a/Source/Presentation/Kysect.Shreks.WebUI.AdminPanel/SafeExecution/ISafeExecutionBuilder.cs +++ b/Source/Presentation/Kysect.Shreks.WebUI.AdminPanel/SafeExecution/ISafeExecutionBuilder.cs @@ -3,9 +3,11 @@ namespace Kysect.Shreks.WebUI.AdminPanel.SafeExecution; public interface ISafeExecutionBuilder : IAsyncDisposable { string? Title { get; set; } + bool ShowExceptionDetails { get; set; } void OnFailAsync(Func action) where TException : Exception; + void OnSuccessAsync(Func action); } @@ -16,5 +18,6 @@ public interface ISafeExecutionBuilder : IAsyncDisposable bool ShowExceptionDetails { get; set; } void OnFailAsync(Func action) where TException : Exception; + void OnSuccessAsync(Func action); } \ No newline at end of file diff --git a/Source/Presentation/Kysect.Shreks.WebUI.AdminPanel/SafeExecution/SafeExecutionBuilder.cs b/Source/Presentation/Kysect.Shreks.WebUI.AdminPanel/SafeExecution/SafeExecutionBuilder.cs index 3a0d35ac0..6de109a05 100644 --- a/Source/Presentation/Kysect.Shreks.WebUI.AdminPanel/SafeExecution/SafeExecutionBuilder.cs +++ b/Source/Presentation/Kysect.Shreks.WebUI.AdminPanel/SafeExecution/SafeExecutionBuilder.cs @@ -30,6 +30,7 @@ public SafeExecutionBuilder( } public string? Title { get; set; } + public bool ShowExceptionDetails { get; set; } public void OnFailAsync(Func action) where TException : Exception @@ -51,7 +52,10 @@ public async ValueTask DisposeAsync() await Task.WhenAll(handleTasks); } - catch (OperationCanceledException) { } + catch (OperationCanceledException) + { + // ignored + } catch (Exception e) { IEnumerable handleTasks = _errorHandlers.Select(x => x.Handle(e)); @@ -72,7 +76,9 @@ public async ValueTask DisposeAsync() } } +#pragma warning disable SA1402 public class SafeExecutionBuilder : ISafeExecutionBuilder +#pragma warning restore SA1402 { private readonly Func> _action; private readonly List _errorHandlers; @@ -97,6 +103,7 @@ public SafeExecutionBuilder( } public string? Title { get; set; } + public bool ShowExceptionDetails { get; set; } public void OnFailAsync(Func action) where TException : Exception @@ -118,7 +125,10 @@ public async ValueTask DisposeAsync() await Task.WhenAll(handleTasks); } - catch (OperationCanceledException) { } + catch (OperationCanceledException) + { + // ignored + } catch (Exception e) { IEnumerable handleTasks = _errorHandlers.Select(x => x.Handle(e)); diff --git a/Source/Tests/Kysect.Shreks.Tests.Handlers/GithubEvents/PullRequestUpdatedTests.cs b/Source/Tests/Kysect.Shreks.Tests.Handlers/GithubEvents/PullRequestUpdatedTests.cs index 6628e0943..7df658bc7 100644 --- a/Source/Tests/Kysect.Shreks.Tests.Handlers/GithubEvents/PullRequestUpdatedTests.cs +++ b/Source/Tests/Kysect.Shreks.Tests.Handlers/GithubEvents/PullRequestUpdatedTests.cs @@ -23,16 +23,14 @@ public async Task Handle_ShouldCreateSubmission_WhenStudentHadNoSubmissionOnAssi ISubmissionWorkflowService workflowService = Provider.GetRequiredService(); - var command = new PullRequestUpdated.Command - ( + var command = new PullRequestUpdated.Command( student.UserId, student.UserId, groupAssignment.AssignmentId, organizationName, repositoryName, 1, - "payload" - ); + "payload"); var handler = new PullRequestUpdatedHandler(Context, workflowService); @@ -53,16 +51,14 @@ public async Task Handle_ShouldCreateSubmissionWhenStudentHadNotSubmissionOnAssi ISubmissionWorkflowService workflowService = Provider.GetRequiredService(); - var command = new PullRequestUpdated.Command - ( + var command = new PullRequestUpdated.Command( mentor.UserId, student.UserId, groupAssignment.AssignmentId, organizationName, repositoryName, 1, - "payload" - ); + "payload"); var handler = new PullRequestUpdatedHandler(Context, workflowService); @@ -83,16 +79,14 @@ public async Task Handle_ShouldThrowWhenStudentHadNoSubmissionOnAssignmentAndIss ISubmissionWorkflowService workflowService = Provider.GetRequiredService(); - var command = new PullRequestUpdated.Command - ( + var command = new PullRequestUpdated.Command( issuer.Id, student.UserId, groupAssignment.AssignmentId, organizationName, repositoryName, 1, - "payload" - ); + "payload"); var handler = new PullRequestUpdatedHandler(Context, workflowService); @@ -111,16 +105,14 @@ public async Task Handle_ShouldUpdateSubmission_WhenStudentHadSubmissionOnAssign ISubmissionWorkflowService workflowService = Provider.GetRequiredService(); - var command = new PullRequestUpdated.Command - ( + var command = new PullRequestUpdated.Command( student.UserId, student.UserId, groupAssignment.AssignmentId, organizationName, repositoryName, 1, - "payload" - ); + "payload"); var handler = new PullRequestUpdatedHandler(Context, workflowService); @@ -141,16 +133,14 @@ public async Task Handle_ShouldUpdateSubmissionWhenStudentHadSubmissionOnAssignm ISubmissionWorkflowService workflowService = Provider.GetRequiredService(); - var command = new PullRequestUpdated.Command - ( + var command = new PullRequestUpdated.Command( mentor.UserId, student.UserId, groupAssignment.AssignmentId, organizationName, repositoryName, 1, - "payload" - ); + "payload"); var handler = new PullRequestUpdatedHandler(Context, workflowService); @@ -171,16 +161,14 @@ public async Task Handle_ShouldThrowWhenStudentHadSubmissionOnAssignmentAndIssue ISubmissionWorkflowService workflowService = Provider.GetRequiredService(); - var command = new PullRequestUpdated.Command - ( + var command = new PullRequestUpdated.Command( issuer.Id, student.UserId, groupAssignment.AssignmentId, organizationName, repositoryName, 1, - "payload" - ); + "payload"); var handler = new PullRequestUpdatedHandler(Context, workflowService); diff --git a/Source/Tests/Kysect.Shreks.Tests.Handlers/Kysect.Shreks.Tests.Handlers.csproj b/Source/Tests/Kysect.Shreks.Tests.Handlers/Kysect.Shreks.Tests.Handlers.csproj index 4d17337fc..2897e955f 100644 --- a/Source/Tests/Kysect.Shreks.Tests.Handlers/Kysect.Shreks.Tests.Handlers.csproj +++ b/Source/Tests/Kysect.Shreks.Tests.Handlers/Kysect.Shreks.Tests.Handlers.csproj @@ -4,7 +4,7 @@ net6.0 enable enable - 1701;1702;IL2121;CA1707 + 1701;1702;IL2121;CA1707;1591;SA1633;SA1101;SA1503;SA1309;SA1601;SA1201 false diff --git a/Source/Tests/Kysect.Shreks.Tests.Handlers/Students/GetStudentsBySubjectCourseIdTests.cs b/Source/Tests/Kysect.Shreks.Tests.Handlers/Students/GetStudentsBySubjectCourseIdTests.cs index fb63228e1..c401d26cb 100644 --- a/Source/Tests/Kysect.Shreks.Tests.Handlers/Students/GetStudentsBySubjectCourseIdTests.cs +++ b/Source/Tests/Kysect.Shreks.Tests.Handlers/Students/GetStudentsBySubjectCourseIdTests.cs @@ -6,7 +6,7 @@ namespace Kysect.Shreks.Tests.Handlers.Students; -public class StudentHandlerTest : TestBase +public class GetStudentsBySubjectCourseIdTests : TestBase { [Fact] public async Task Handle_Should_NoThrow() diff --git a/Source/Tests/Kysect.Shreks.Tests.Services/Kysect.Shreks.Tests.Services.csproj b/Source/Tests/Kysect.Shreks.Tests.Services/Kysect.Shreks.Tests.Services.csproj index 1b55dfccc..cbdef96ea 100644 --- a/Source/Tests/Kysect.Shreks.Tests.Services/Kysect.Shreks.Tests.Services.csproj +++ b/Source/Tests/Kysect.Shreks.Tests.Services/Kysect.Shreks.Tests.Services.csproj @@ -4,7 +4,7 @@ net6.0 enable enable - 1701;1702;IL2121;CA1707 + 1701;1702;IL2121;CA1707;1591;SA1633;SA1101;SA1503;SA1309;SA1601;SA1201 false diff --git a/Source/Tests/Kysect.Shreks.Tests/GithubWorkflow/Tools/GithubApplicationTestContextGenerator.cs b/Source/Tests/Kysect.Shreks.Tests/GithubWorkflow/Tools/GithubApplicationTestContextGenerator.cs index b304d2712..2d77d79be 100644 --- a/Source/Tests/Kysect.Shreks.Tests/GithubWorkflow/Tools/GithubApplicationTestContextGenerator.cs +++ b/Source/Tests/Kysect.Shreks.Tests/GithubWorkflow/Tools/GithubApplicationTestContextGenerator.cs @@ -46,8 +46,10 @@ public async Task Create() Subject subject = _subjectGenerator.Generate(); var subjectCourse = new SubjectCourse(subject, _faker.Commerce.ProductName(), SubmissionStateWorkflowType.ReviewOnly); - var githubSubjectCourseAssociation = new GithubSubjectCourseAssociation(subjectCourse, - _faker.Company.CompanyName(), _faker.Commerce.ProductName()); + var githubSubjectCourseAssociation = new GithubSubjectCourseAssociation( + subjectCourse, + _faker.Company.CompanyName(), + _faker.Commerce.ProductName()); var subjectCourseGroup = new SubjectCourseGroup(subjectCourse, group); var assignment = new Assignment(_faker.Hacker.Verb(), "task-0", 1, new Points(0), new Points(10), subjectCourse); diff --git a/Source/Tests/Kysect.Shreks.Tests/GithubWorkflow/Tools/TestEventNotifier.cs b/Source/Tests/Kysect.Shreks.Tests/GithubWorkflow/Tools/TestEventNotifier.cs index bbb7dbded..9283e44d4 100644 --- a/Source/Tests/Kysect.Shreks.Tests/GithubWorkflow/Tools/TestEventNotifier.cs +++ b/Source/Tests/Kysect.Shreks.Tests/GithubWorkflow/Tools/TestEventNotifier.cs @@ -5,6 +5,7 @@ namespace Kysect.Shreks.Tests.GithubWorkflow.Tools; public class TestEventNotifier : IPullRequestCommitEventNotifier { public ICollection PullRequestMessages { get; } = Array.Empty(); + public ICollection CommitMessages { get; } = Array.Empty(); public Task SendCommentToPullRequest(string message) diff --git a/Source/Tests/Kysect.Shreks.Tests/Kysect.Shreks.Tests.csproj b/Source/Tests/Kysect.Shreks.Tests/Kysect.Shreks.Tests.csproj index 30353755a..99a6a2a64 100644 --- a/Source/Tests/Kysect.Shreks.Tests/Kysect.Shreks.Tests.csproj +++ b/Source/Tests/Kysect.Shreks.Tests/Kysect.Shreks.Tests.csproj @@ -6,7 +6,7 @@ latest True false - 1701;1702;IL2121;CA1707 + 1701;1702;IL2121;CA1707;SA1633;SA1309;SA1101;SA1518;SA1502 diff --git a/Source/Tests/Kysect.Shreks.Tests/TestBase.cs b/Source/Tests/Kysect.Shreks.Tests/TestBase.cs index e0baa5ee8..ee7acb7fc 100644 --- a/Source/Tests/Kysect.Shreks.Tests/TestBase.cs +++ b/Source/Tests/Kysect.Shreks.Tests/TestBase.cs @@ -44,6 +44,7 @@ public TestBase() // TODO: Do not call virtual methods in constructor #pragma warning disable CA2214 + // ReSharper disable once VirtualMemberCallInConstructor ConfigureServices(collection); #pragma warning restore CA2214 @@ -59,7 +60,9 @@ public TestBase() } protected ShreksDatabaseContext Context { get; } + protected IMapper Mapper { get; } + protected IServiceProvider Provider { get; } public void Dispose()