Skip to content

Commit

Permalink
Refactors
Browse files Browse the repository at this point in the history
  • Loading branch information
mackmarton committed Oct 24, 2024
1 parent 0a0a9ab commit 4b6fcf8
Show file tree
Hide file tree
Showing 50 changed files with 243 additions and 300 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Threading.Tasks;
using Ahk.GitHub.Monitor.Services.GitHubClientFactory;
using Microsoft.Extensions.Hosting;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.Azure.Functions.Worker;
Expand All @@ -15,7 +16,7 @@ public async Task AppStartupSucceeds()
var host = new HostBuilder()
.ConfigureServices(services =>
{
services.AddSingleton<Services.IGitHubClientFactory, Services.GitHubClientFactory>();
services.AddSingleton<Services.IGitHubClientFactory, GitHubClientFactory>();
})
.Build();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Threading.Tasks;
using Ahk.GitHub.Monitor.Services.EventDispatch;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
Expand All @@ -16,7 +17,7 @@ public class FunctionInvokeTest
public async Task NoAppConfigsReturnsError()
{
var log = new Mock<ILogger<GitHubMonitorFunction>>();
var eds = new Mock<Services.IEventDispatchService>();
var eds = new Mock<IEventDispatchService>();
var func = new GitHubMonitorFunction(eds.Object, Options.Create(new GitHubMonitorConfig()), log.Object);

var resp = await func.InvokeAndGetResponseAs<ObjectResult>(req => { });
Expand All @@ -28,7 +29,7 @@ public async Task NoAppConfigsReturnsError()
[TestMethod]
public async Task MissingGitHubEventHeaderReturnsError()
{
var eds = new Mock<Services.IEventDispatchService>();
var eds = new Mock<IEventDispatchService>();
var func = FunctionBuilder.Create(eds.Object);

var resp = await func.InvokeAndGetResponseAs<ObjectResult>(req => req.Headers.Add("X-Hub-Signature-256", "dummy"));
Expand All @@ -40,7 +41,7 @@ public async Task MissingGitHubEventHeaderReturnsError()
[TestMethod]
public async Task MissingGitHubSignatureHeaderReturnsError()
{
var eds = new Mock<Services.IEventDispatchService>();
var eds = new Mock<IEventDispatchService>();
var func = FunctionBuilder.Create(eds.Object);

var resp = await func.InvokeAndGetResponseAs<ObjectResult>(req => req.Headers.Add("X-GitHub-Event", "dummy"));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using Ahk.GitHub.Monitor.Services.EventDispatch;
using Microsoft.Extensions.Options;
using Moq;

Expand All @@ -12,7 +13,7 @@ internal static class FunctionBuilder
GitHubWebhookSecret = "webhooksecret",
};

public static GitHubMonitorFunction Create(Services.IEventDispatchService dispatchService = null)
=> new GitHubMonitorFunction(dispatchService ?? new Mock<Services.IEventDispatchService>().Object, Options.Create(AppConfig), new Mock<Microsoft.Extensions.Logging.ILogger<GitHubMonitorFunction>>().Object);
public static GitHubMonitorFunction Create(IEventDispatchService dispatchService = null)
=> new GitHubMonitorFunction(dispatchService ?? new Mock<IEventDispatchService>().Object, Options.Create(AppConfig), new Mock<Microsoft.Extensions.Logging.ILogger<GitHubMonitorFunction>>().Object);
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Threading.Tasks;
using Ahk.GitHub.Monitor.Services.EventDispatch;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging.Abstractions;
Expand All @@ -13,7 +14,7 @@ public class SignatureValidationTest
[TestMethod]
public async Task InvalidGitHubSignatureHeaderReturnError()
{
var eds = new Mock<Services.IEventDispatchService>();
var eds = new Mock<IEventDispatchService>();
var func = FunctionBuilder.Create(eds.Object);

var wrongSignature = new SampleCallbackData(SampleData.BranchCreate.Body, "wrongsignature", SampleData.BranchCreate.EventName);
Expand All @@ -26,7 +27,7 @@ public async Task InvalidGitHubSignatureHeaderReturnError()
[TestMethod]
public async Task ValidGitHubSignatureAcceptedAndDispatched()
{
var eds = new Mock<Services.IEventDispatchService>();
var eds = new Mock<IEventDispatchService>();
eds.Setup(s => s.Process(SampleData.BranchCreate.EventName, It.IsAny<string>(), It.IsAny<WebhookResult>(), NullLogger.Instance)).Returns(Task.CompletedTask);

var ctx = FunctionBuilder.Create(eds.Object);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.Threading.Tasks;
using Ahk.GitHub.Monitor.EventHandlers;
using Ahk.GitHub.Monitor.Services;
using Ahk.GitHub.Monitor.Services.EventDispatch;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Ahk.GitHub.Monitor.EventHandlers;
using Ahk.GitHub.Monitor.EventHandlers.GradeComment;
using Ahk.GitHub.Monitor.EventHandlers.StatusTracking;
using Ahk.GitHub.Monitor.Services;
using Ahk.GitHub.Monitor.Services.GradeStore;
using Ahk.GitHub.Monitor.Services.StatusTrackingStore;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Ahk.GitHub.Monitor.Services;
using Ahk.GitHub.Monitor.Services.GradeStore;
using Moq;

namespace Ahk.GitHub.Monitor.Tests.UnitTests.EventHandlersTests
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Threading.Tasks;
using Ahk.GitHub.Monitor.Services;
using Ahk.GitHub.Monitor.Services.StatusTrackingStore;
using Ahk.GitHub.Monitor.Services.StatusTrackingStore.Dto;
using Moq;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using Ahk.GitHub.Monitor.Helpers;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Ahk.GitHub.Monitor.Tests.UnitTests
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using Ahk.GitHub.Monitor.Services;
using Microsoft.Extensions.Caching.Memory;
using Octokit;

namespace Ahk.GitHub.Monitor.EventHandlers
{
public class ActionWorkflowRunHandler(
Services.IGitHubClientFactory gitHubClientFactory,
Microsoft.Extensions.Caching.Memory.IMemoryCache cache,
Microsoft.Extensions.Logging.ILogger logger)
: RepositoryEventBase<WorkflowRunEventPayload>(gitHubClientFactory, cache, logger)
IGitHubClientFactory gitHubClientFactory,
IMemoryCache cache,
IServiceProvider serviceProvider)
: RepositoryEventBase<WorkflowRunEventPayload>(gitHubClientFactory, cache, serviceProvider)
{
public const int WorkflowRunThreshold = 5;
public const string GitHubWebhookEventName = "workflow_run";
private const string WarningText = ":exclamation: **You triggered too many automated evaluations; extra evaluations are penalized. Túl sok automata értékelést futtattál; az extra futtatások pontlevonással járnak.** ";

private const string WarningText =
":exclamation: **You triggered too many automated evaluations; extra evaluations are penalized. Túl sok automata értékelést futtattál; az extra futtatások pontlevonással járnak.** ";

protected override async Task<EventHandlerResult> executeCore(WorkflowRunEventPayload webhookPayload)
{
Expand All @@ -25,7 +29,8 @@ protected override async Task<EventHandlerResult> executeCore(WorkflowRunEventPa
if (await isUserOrganizationMember(webhookPayload, webhookPayload.Sender.Login))
return EventHandlerResult.NoActionNeeded("workflow_run ok, not triggered by student");

var workflowRuns = await GitHubClient.CountWorkflowRunsInRepository(webhookPayload.Repository.Owner.Login, webhookPayload.Repository.Name, webhookPayload.Sender.Login);
var workflowRuns = await GitHubClient.CountWorkflowRunsInRepository(
webhookPayload.Repository.Owner.Login, webhookPayload.Repository.Name, webhookPayload.Sender.Login);
if (workflowRuns <= WorkflowRunThreshold)
return EventHandlerResult.NoActionNeeded("workflow_run ok, has less then threshold");

Expand All @@ -40,7 +45,8 @@ protected override async Task<EventHandlerResult> executeCore(WorkflowRunEventPa

private async Task<int?> getMostRecentPullRequest(WorkflowRunEventPayload webhookPayload)
{
var list = await GitHubClient.PullRequest.GetAllForRepository(webhookPayload.Repository.Id, new PullRequestRequest() { State = ItemStateFilter.All });
var list = await GitHubClient.PullRequest.GetAllForRepository(webhookPayload.Repository.Id,
new PullRequestRequest() { State = ItemStateFilter.All });
return list.OrderByDescending(p => p.UpdatedAt).FirstOrDefault()?.Number;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ namespace Ahk.GitHub.Monitor.EventHandlers
public class BranchProtectionRuleHandler(
IGitHubClientFactory gitHubClientFactory,
IMemoryCache cache,
ILogger logger)
: RepositoryEventBase<CreateEventPayload>(gitHubClientFactory, cache, logger)
IServiceProvider serviceProvider)
: RepositoryEventBase<CreateEventPayload>(gitHubClientFactory, cache, serviceProvider)
{
public const string GitHubWebhookEventName = "create";

Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
using System;
using System.Threading.Tasks;
using Ahk.GitHub.Monitor.EventHandlers.GradeComment.Payload;
using Ahk.GitHub.Monitor.EventHandlers.StatusTracking;
using Ahk.GitHub.Monitor.Helpers;
using Ahk.GitHub.Monitor.Services;
using GradeManagement.Shared.Enums;
using Ahk.GitHub.Monitor.Services.GradeStore;
using Ahk.GitHub.Monitor.Services.StatusTrackingStore.Dto;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Logging;
using Octokit;

namespace Ahk.GitHub.Monitor.EventHandlers
namespace Ahk.GitHub.Monitor.EventHandlers.GradeComment
{
public abstract class GradeCommandHandlerBase<T>(
IGitHubClientFactory gitHubClientFactory,
IGradeStore gradeStore,
IMemoryCache cache,
ILogger logger,
IServiceProvider serviceProvider,
PullRequestStatusTrackingHandler pullRequestStatusTrackingHandler)
: RepositoryEventBase<T>(gitHubClientFactory, cache, logger)
: RepositoryEventBase<T>(gitHubClientFactory, cache, serviceProvider)
where T : ActivityPayload
{
private const string WarningText =
Expand All @@ -29,33 +31,31 @@ protected async Task<EventHandlerResult> processComment(ICommentPayload<T> webho
var gradeCommand = new GradeCommentParser(webhookPayload.CommentBody);
if (gradeCommand.IsMatch)
{
if (!await isAllowed(webhookPayload))
return await handleUserNotAllowed(webhookPayload);
if (!await this.isAllowed(webhookPayload))
return await this.handleUserNotAllowed(webhookPayload);

var pr = await getPullRequest(webhookPayload);
var pr = await this.getPullRequest(webhookPayload);
if (pr == null)
return await handleNotPr(webhookPayload);
return await this.handleNotPr(webhookPayload);

await handleApprove(webhookPayload, pr);
await handleStoreGrade(webhookPayload, gradeCommand, pr);
await this.handleApprove(webhookPayload, pr);
await this.handleStoreGrade(webhookPayload, gradeCommand, pr);

await handleReaction(webhookPayload, ReactionType.Plus1);
await this.handleReaction(webhookPayload, ReactionType.Plus1);
return EventHandlerResult.ActionPerformed(
$"comment operation to grade done; grades: {string.Join(" ", gradeCommand.GradesWithOrder.Values)}");
}
else
{
return EventHandlerResult.NoActionNeeded("not recognized as command");
}

return EventHandlerResult.NoActionNeeded("not recognized as command");
}

protected abstract Task handleReaction(ICommentPayload<T> webhookPayload, ReactionType reactionType);

protected async Task<PullRequest> getPullRequest(ICommentPayload<T> webhookPayload)
private async Task<PullRequest> getPullRequest(ICommentPayload<T> webhookPayload)
{
try
{
return await GitHubClient.PullRequest.Get(webhookPayload.Repository.Id,
return await this.GitHubClient.PullRequest.Get(webhookPayload.Repository.Id,
webhookPayload.PullRequestNumber);
}
catch (NotFoundException)
Expand All @@ -67,8 +67,7 @@ protected async Task<PullRequest> getPullRequest(ICommentPayload<T> webhookPaylo
private async Task handleStoreGrade(ICommentPayload<T> webhookPayload, GradeCommentParser gradeCommand,
PullRequest pr)
{
var neptun = await getNeptun(webhookPayload.Repository.Id, pr.Head.Ref);
Logger.LogInformation($"storing grades for {neptun}");
Logger.LogInformation($"storing grades for {webhookPayload.Repository.FullName}");
if (gradeCommand.HasGrades)
{
await gradeStore.StoreGrade(
Expand All @@ -92,12 +91,14 @@ private async Task handleApprove(ICommentPayload<T> webhookPayload, PullRequest
if (shouldMergePr)
{
Logger.LogInformation("PR is being merged");
await GitHubClient.PullRequest.Review.Create(webhookPayload.Repository.Id,
await this.GitHubClient.PullRequest.Review.Create(webhookPayload.Repository.Id,
webhookPayload.PullRequestNumber,
new PullRequestReviewCreate() { Event = PullRequestReviewEvent.Approve });
await GitHubClient.PullRequest.Merge(webhookPayload.Repository.Id, webhookPayload.PullRequestNumber,
await this.GitHubClient.PullRequest.Merge(webhookPayload.Repository.Id,
webhookPayload.PullRequestNumber,
new MergePullRequest());
await pullRequestStatusTrackingHandler.PrStatusChanged(webhookPayload.Repository.Url, webhookPayload.PullRequestUrl, PullRequestStatus.Merged);
await pullRequestStatusTrackingHandler.PrStatusChanged(webhookPayload.Repository.Url,
webhookPayload.PullRequestUrl, PullRequestStatus.Merged);
}
else
{
Expand All @@ -107,16 +108,16 @@ await GitHubClient.PullRequest.Merge(webhookPayload.Repository.Id, webhookPayloa

private async Task<EventHandlerResult> handleNotPr(ICommentPayload<T> webhookPayload)
{
await handleReaction(webhookPayload, ReactionType.Confused);
await this.handleReaction(webhookPayload, ReactionType.Confused);
return EventHandlerResult.ActionPerformed("comment operation to grade not called for PR");
}

private async Task<EventHandlerResult> handleUserNotAllowed(ICommentPayload<T> webhookPayload)
{
await handleReaction(webhookPayload, ReactionType.Confused);
await this.handleReaction(webhookPayload, ReactionType.Confused);

var comment = WarningText.Replace("{}", webhookPayload.CommentingUser, StringComparison.OrdinalIgnoreCase);
await GitHubClient.Issue.Comment.Create(webhookPayload.Repository.Id, webhookPayload.PullRequestNumber,
await this.GitHubClient.Issue.Comment.Create(webhookPayload.Repository.Id, webhookPayload.PullRequestNumber,
comment);

return EventHandlerResult.ActionPerformed("comment operation to grade not allowed for user");
Expand All @@ -131,7 +132,7 @@ private Task<bool> isAllowed(ICommentPayload<T> webhookPayload)
key: $"githubisorgmember{webhookPayload.Repository.Owner.Login}{webhookPayload.CommentingUser}",
factory: async cacheEntry =>
{
var isMember = await getIsUserOrgMember(webhookPayload.Repository.Owner.Login,
var isMember = await this.getIsUserOrgMember(webhookPayload.Repository.Owner.Login,
webhookPayload.CommentingUser);
cacheEntry.SetValue(isMember);
cacheEntry.SetAbsoluteExpiration(TimeSpan.FromHours(1));
Expand All @@ -143,7 +144,7 @@ private async Task<bool> getIsUserOrgMember(string org, string user)
{
try
{
return await GitHubClient.Organization.Member.CheckMember(org, user);
return await this.GitHubClient.Organization.Member.CheckMember(org, user);
}
catch (NotFoundException)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
using System;
using System.Threading.Tasks;
using Ahk.GitHub.Monitor.EventHandlers.GradeComment.Payload;
using Ahk.GitHub.Monitor.EventHandlers.StatusTracking;
using Ahk.GitHub.Monitor.Services;
using Ahk.GitHub.Monitor.Services.GradeStore;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Logging;
using Octokit;

namespace Ahk.GitHub.Monitor.EventHandlers
namespace Ahk.GitHub.Monitor.EventHandlers.GradeComment
{
public class GradeCommandIssueCommentHandler(
IGitHubClientFactory gitHubClientFactory,
IGradeStore gradeStore,
IMemoryCache cache,
ILogger<GitHubMonitorFunction> logger,
IServiceProvider serviceProvider,
PullRequestStatusTrackingHandler pullRequestStatusTrackingHandler)
: GradeCommandHandlerBase<IssueCommentPayload>(gitHubClientFactory, gradeStore, cache, logger, pullRequestStatusTrackingHandler)
: GradeCommandHandlerBase<IssueCommentPayload>(gitHubClientFactory, gradeStore, cache, serviceProvider,
pullRequestStatusTrackingHandler)
{
public const string GitHubWebhookEventName = "issue_comment";

Expand All @@ -24,14 +26,15 @@ protected override async Task<EventHandlerResult> executeCore(IssueCommentPayloa
return EventHandlerResult.PayloadError("no issue information in webhook payload");

if (webhookPayload.Action.Equals("created", StringComparison.OrdinalIgnoreCase))
return await processComment(new IssueCommentPayloadFacade(webhookPayload));
return await this.processComment(new IssueCommentPayloadFacade(webhookPayload));

return EventHandlerResult.EventNotOfInterest(webhookPayload.Action);
}

protected override Task handleReaction(ICommentPayload<IssueCommentPayload> webhookPayload,
ReactionType reactionType)
=> GitHubClient.Reaction.IssueComment.Create(webhookPayload.Repository.Id,
protected override Task handleReaction(
ICommentPayload<IssueCommentPayload> webhookPayload, ReactionType reactionType)
=> this.GitHubClient.Reaction.IssueComment.Create(
webhookPayload.Repository.Id,
webhookPayload.Payload.Comment.Id, new NewReaction(reactionType));
}
}
Loading

0 comments on commit 4b6fcf8

Please sign in to comment.