public async Task PrOpenedNoDuplicates() { var context = new DefaultHttpContext(); var request = context.Request; var sc = new ServiceCollection(); sc.AddSingleton(sp => new PullRequestOpenDuplicateHandler(githubClientFactory.Object)); var serviceProvider = sc.BuildServiceProvider(); var builder = new EventDispatchConfigBuilder(sc) .Add <PullRequestOpenDuplicateHandler>(PullRequestOpenDuplicateHandler.GitHubWebhookEventName); var dispatcher = new EventDispatchService(serviceProvider, builder); var function = new GitHubMonitorFunction(dispatcher, GetConfig()); ParseRequestFile( await File.ReadAllTextAsync(Path.Combine(Directory.GetCurrentDirectory(), @"pr_opened.txt")), request); githubClient.Setup(x => x.PullRequest.GetAllForRepository(RepositoryId)).ReturnsAsync(new List <PullRequest>().AsReadOnly()); githubClient.Setup(x => x.PullRequest.GetAllForRepository(RepositoryId, It.IsAny <PullRequestRequest>())).ReturnsAsync(new List <PullRequest>().AsReadOnly()); SetupAhkMonitorYml(); var response = (ObjectResult)await function.Run(request, logger); Assert.IsNotNull(response); Assert.IsInstanceOfType(response, typeof(OkObjectResult)); var webhookResult = response.Value as WebhookResult; Assert.IsNotNull(webhookResult); Assert.IsTrue(webhookResult.Messages.Any(m => m.Equals("PullRequestOpenDuplicateHandler -> no action needed: pull request open is ok, there are no other PRs"))); }
public async Task CommentEdited() { var context = new DefaultHttpContext(); var request = context.Request; var sc = new ServiceCollection(); sc.AddSingleton(sp => new IssueCommentEditDeleteHandler(githubClientFactory.Object)); var serviceProvider = sc.BuildServiceProvider(); var builder = new EventDispatchConfigBuilder(sc) .Add <IssueCommentEditDeleteHandler>(IssueCommentEditDeleteHandler.GitHubWebhookEventName); var dispatcher = new EventDispatchService(serviceProvider, builder); var function = new GitHubMonitorFunction(dispatcher, GetConfig()); ParseRequestFile( await File.ReadAllTextAsync(Path.Combine(Directory.GetCurrentDirectory(), @"comment_edited.txt")), request); githubClient.Setup(x => x.Issue.Comment.Create(RepositoryId, 1, "comment protection warning")).Verifiable(); SetupAhkMonitorYml(); var response = (ObjectResult)await function.Run(request, logger); Assert.IsNotNull(response); Assert.IsInstanceOfType(response, typeof(OkObjectResult)); var webhookResult = response.Value as WebhookResult; Assert.IsNotNull(webhookResult); githubClient.Verify(x => x.Issue.Comment.Create(RepositoryId, 1, "comment protection warning"), Times.Once); Assert.IsTrue(webhookResult.Messages.Any(m => m.Equals("IssueCommentEditDeleteHandler -> action performed: comment action resulting in warning"))); }
public async Task BranchCreate() { var context = new DefaultHttpContext(); var request = context.Request; var sc = new ServiceCollection(); sc.AddSingleton(sp => new BranchProtectionRuleHandler(githubClientFactory.Object)); var serviceProvider = sc.BuildServiceProvider(); var builder = new EventDispatchConfigBuilder(sc) .Add <BranchProtectionRuleHandler>(BranchProtectionRuleHandler.GitHubWebhookEventName); var dispatcher = new EventDispatchService(serviceProvider, builder); var function = new GitHubMonitorFunction(dispatcher, GetConfig()); ParseRequestFile( await File.ReadAllTextAsync(Path.Combine(Directory.GetCurrentDirectory(), @"branch_create.txt")), request); githubClient.Setup(x => x.Repository.Branch.UpdateBranchProtection(RepositoryId, "master", It.IsAny <BranchProtectionSettingsUpdate>())) .Verifiable(); SetupAhkMonitorYml(); var response = (ObjectResult)await function.Run(request, logger); Assert.IsNotNull(response); Assert.IsInstanceOfType(response, typeof(OkObjectResult)); var webhookResult = response.Value as WebhookResult; Assert.IsNotNull(webhookResult); githubClient.Verify(x => x.Repository.Branch.UpdateBranchProtection(RepositoryId, "master", It.IsAny <BranchProtectionSettingsUpdate>()), Times.Once); Assert.IsTrue(webhookResult.Messages.Any(m => m.Equals("BranchProtectionRuleHandler -> action performed: branch protection rule applied"))); }
public async Task CommentEditedOwn() { var context = new DefaultHttpContext(); var request = context.Request; var sc = new ServiceCollection(); sc.AddSingleton(sp => new IssueCommentEditDeleteHandler(githubClientFactory.Object)); var serviceProvider = sc.BuildServiceProvider(); var builder = new EventDispatchConfigBuilder(sc) .Add <IssueCommentEditDeleteHandler>(IssueCommentEditDeleteHandler.GitHubWebhookEventName); var dispatcher = new EventDispatchService(serviceProvider, builder); var function = new GitHubMonitorFunction(dispatcher, GetConfig()); ParseRequestFile( await File.ReadAllTextAsync(Path.Combine(Directory.GetCurrentDirectory(), @"comment_edited_own.txt")), request); SetupAhkMonitorYml(); var response = (ObjectResult)await function.Run(request, logger); Assert.IsNotNull(response); Assert.IsInstanceOfType(response, typeof(OkObjectResult)); var webhookResult = response.Value as WebhookResult; Assert.IsNotNull(webhookResult); Assert.IsTrue(webhookResult.Messages.Any(m => m.Equals("IssueCommentEditDeleteHandler -> no action needed: comment action edited by abcabc allowed, referencing own comment"))); }
public async Task PrMergeCommand() { var context = new DefaultHttpContext(); var request = context.Request; var sc = new ServiceCollection(); sc.AddSingleton(sp => new PullRequestCommentCommandHandler(githubClientFactory.Object)); var serviceProvider = sc.BuildServiceProvider(); var builder = new EventDispatchConfigBuilder(sc) .Add <PullRequestCommentCommandHandler>(PullRequestCommentCommandHandler.GitHubWebhookEventName); var dispatcher = new EventDispatchService(serviceProvider, builder); var function = new GitHubMonitorFunction(dispatcher, GetConfig()); ParseRequestFile( await File.ReadAllTextAsync(Path.Combine(Directory.GetCurrentDirectory(), @"pr_merge_command.txt")), request); SetupAhkMonitorYml(); githubClient.Setup(x => x.PullRequest.Merge(RepositoryId, 2, It.IsAny <MergePullRequest>())) .ReturnsAsync(new PullRequestMerge("sha", true, "msg")); var response = (ObjectResult)await function.Run(request, logger); Assert.IsNotNull(response); Assert.IsInstanceOfType(response, typeof(OkObjectResult)); var webhookResult = response.Value as WebhookResult; Assert.IsNotNull(webhookResult); githubClient.Verify(x => x.PullRequest.Merge(RepositoryId, 2, It.IsAny <MergePullRequest>()), Times.Once); Assert.IsTrue(webhookResult.Messages.Any(m => m.Equals("PullRequestCommentCommandHandler -> action performed: merged pull request #2 pr1"))); }
public async Task PrInvalidCommandRejected() { var context = new DefaultHttpContext(); var request = context.Request; var sc = new ServiceCollection(); sc.AddSingleton(sp => new PullRequestCommentCommandHandler(githubClientFactory.Object)); var serviceProvider = sc.BuildServiceProvider(); var builder = new EventDispatchConfigBuilder(sc) .Add <PullRequestCommentCommandHandler>(PullRequestCommentCommandHandler.GitHubWebhookEventName); var dispatcher = new EventDispatchService(serviceProvider, builder); var function = new GitHubMonitorFunction(dispatcher, GetConfig()); ParseRequestFile( await File.ReadAllTextAsync(Path.Combine(Directory.GetCurrentDirectory(), @"pr_invalid_command_rejected.txt")), request); SetupAhkMonitorYml(); var response = (ObjectResult)await function.Run(request, logger); Assert.IsNotNull(response); Assert.IsInstanceOfType(response, typeof(OkObjectResult)); var webhookResult = response.Value as WebhookResult; Assert.IsNotNull(webhookResult); Assert.IsTrue(webhookResult.Messages.Any(m => m.Equals("PullRequestCommentCommandHandler -> no action needed: invalid command: +invalid_command_aksdjalsk"))); }
public async Task PrMergeCommandPermissionsEnforced() { var context = new DefaultHttpContext(); var request = context.Request; var sc = new ServiceCollection(); sc.AddSingleton(sp => new PullRequestCommentCommandHandler(githubClientFactory.Object)); var serviceProvider = sc.BuildServiceProvider(); var builder = new EventDispatchConfigBuilder(sc) .Add <PullRequestCommentCommandHandler>(PullRequestCommentCommandHandler.GitHubWebhookEventName); var dispatcher = new EventDispatchService(serviceProvider, builder); var function = new GitHubMonitorFunction(dispatcher, GetConfig()); ParseRequestFile( await File.ReadAllTextAsync(Path.Combine(Directory.GetCurrentDirectory(), @"pr_merge_command_permissions_enforced.txt")), request); SetupAhkMonitorYml(); var response = (ObjectResult)await function.Run(request, logger); Assert.IsNotNull(response); Assert.IsInstanceOfType(response, typeof(OkObjectResult)); var webhookResult = response.Value as WebhookResult; Assert.IsNotNull(webhookResult); Assert.IsTrue(webhookResult.Messages.Any(m => m.Equals("PullRequestCommentCommandHandler -> payload error: aabbcc is not allowed to execute the command: +ok"))); }
public static async Task <TResponse> InvokeAndGetResponseAs <TResponse>(this GitHubMonitorFunction function, Action <HttpRequest> configureRequest) where TResponse : IActionResult { var result = await function.Invoke(configureRequest); Assert.IsInstanceOfType(result, typeof(TResponse)); return((TResponse)result); }
public static Task <IActionResult> Invoke(this GitHubMonitorFunction function, Action <HttpRequest> configureRequest) { var req = new DefaultHttpRequest(new DefaultHttpContext()); configureRequest(req); return(function.Run(req, Microsoft.Extensions.Logging.Abstractions.NullLogger.Instance)); }
public async Task NoAppConfigsReturnsError() { var eds = new Mock <Services.IEventDispatchService>(); var func = new GitHubMonitorFunction(eds.Object, Options.Create(new GitHubMonitorConfig())); var resp = await func.InvokeAndGetResponseAs <ObjectResult>(req => { }); Assert.AreEqual(StatusCodes.Status500InternalServerError, resp.StatusCode); eds.Verify(s => s.Process(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <WebhookResult>(), NullLogger.Instance), Times.Never()); }
public async Task EmptyRequestResultsInHttp400() { var context = new DefaultHttpContext(); var request = context.Request; var function = new GitHubMonitorFunction(new NullEventDispatchService(), GetConfig()); ObjectResult response = (ObjectResult)await function.Run(request, logger); Assert.AreEqual(StatusCodes.Status400BadRequest, response?.StatusCode); }
public async Task PrOpenedWithDuplicates() { var context = new DefaultHttpContext(); var request = context.Request; var sc = new ServiceCollection(); sc.AddSingleton(sp => new PullRequestOpenDuplicateHandler(githubClientFactory.Object)); var serviceProvider = sc.BuildServiceProvider(); var builder = new EventDispatchConfigBuilder(sc) .Add <PullRequestOpenDuplicateHandler>(PullRequestOpenDuplicateHandler.GitHubWebhookEventName); var dispatcher = new EventDispatchService(serviceProvider, builder); var function = new GitHubMonitorFunction(dispatcher, GetConfig()); ParseRequestFile( await File.ReadAllTextAsync(Path.Combine(Directory.GetCurrentDirectory(), @"pr_opened.txt")), request); var prs = new List <PullRequest>() { new PullRequest(5748988117, "", "", "", "", "", "", "", 1, ItemState.Open, "", "", DateTimeOffset.Now, DateTimeOffset.Now, null, null, new GitReference(), new GitReference(), new User(), new User(), new List <User>().AsReadOnly(), false, true, MergeableState.Clean, null, "", 0, 0, 0, 0, 0, new Milestone(), false, true, new List <User>().AsReadOnly(), new List <Team>().AsReadOnly(), new List <Label>().AsReadOnly()), new PullRequest(5748988118, "", "", "", "", "", "", "", 2, ItemState.Open, "", "", DateTimeOffset.Now, DateTimeOffset.Now, null, null, new GitReference(), new GitReference(), new User(), new User(), new List <User>().AsReadOnly(), false, true, MergeableState.Clean, null, "", 0, 0, 0, 0, 0, new Milestone(), false, true, new List <User>().AsReadOnly(), new List <Team>().AsReadOnly(), new List <Label>().AsReadOnly()) }.AsReadOnly(); githubClient.Setup(x => x.PullRequest.GetAllForRepository(RepositoryId)).ReturnsAsync(prs); githubClient.Setup(x => x.PullRequest.GetAllForRepository(RepositoryId, It.IsAny <PullRequestRequest>())).ReturnsAsync(prs); githubClient.Setup(x => x.Issue.Comment.Create(It.IsAny <int>(), It.IsAny <int>(), It.IsAny <string>())).Verifiable(); SetupAhkMonitorYml(false); var response = (ObjectResult)await function.Run(request, logger); Assert.IsNotNull(response); Assert.IsInstanceOfType(response, typeof(OkObjectResult)); var webhookResult = response.Value as WebhookResult; Assert.IsNotNull(webhookResult); githubClient.Verify(x => x.Issue.Comment.Create(RepositoryId, 1, "multiple PR protection warning"), Times.Never); githubClient.Verify(x => x.Issue.Comment.Create(RepositoryId, 2, "multiple PR protection warning"), Times.Once); Assert.IsTrue(webhookResult.Messages.Any(m => m.Equals("PullRequestOpenDuplicateHandler -> action performed: pull request open handled with multiple open PRs; pull request open is ok, there are no other closed PRs"))); }
public async Task InvalidSignatureRejected() { var context = new DefaultHttpContext(); var request = context.Request; var function = new GitHubMonitorFunction(new NullEventDispatchService(), GetConfig()); var fileContent = await File.ReadAllTextAsync(Path.Combine(Directory.GetCurrentDirectory(), @"invalid_signature_rejected.txt")); ParseRequestFile(fileContent, request, false); var response = (ObjectResult)await function.Run(request, logger); Assert.AreEqual(StatusCodes.Status400BadRequest, response?.StatusCode); var errorProperty = response?.Value.GetType().GetProperty("error"); Assert.AreEqual("Payload signature not valid", errorProperty?.GetValue(response.Value)); }
public async Task MissingParametersRejectedWithHttp500() { var context = new DefaultHttpContext(); var request = context.Request; var dispatcher = new NullEventDispatchService(); var functionAppIdNull = new GitHubMonitorFunction(dispatcher, GetConfig(null)); var functionPrivateKeyNull = new GitHubMonitorFunction(dispatcher, GetConfig(AppId, null)); var functionWebhookSecretNull = new GitHubMonitorFunction(dispatcher, GetConfig(AppId, PrivateKey, null)); var responseAppidNull = (ObjectResult)await functionAppIdNull.Run(request, logger); var responsePrivateKeyNull = (ObjectResult)await functionPrivateKeyNull.Run(request, logger); var responseWebhookSecretNull = (ObjectResult)await functionWebhookSecretNull.Run(request, logger); Assert.AreEqual(StatusCodes.Status500InternalServerError, responseAppidNull?.StatusCode); Assert.AreEqual(StatusCodes.Status500InternalServerError, responsePrivateKeyNull?.StatusCode); Assert.AreEqual(StatusCodes.Status500InternalServerError, responseWebhookSecretNull?.StatusCode); }
public async Task ValidSignatureAccepted() { var context = new DefaultHttpContext(); var request = context.Request; var function = new GitHubMonitorFunction(new NullEventDispatchService(), GetConfig()); var fileContent = await File.ReadAllTextAsync(Path.Combine(Directory.GetCurrentDirectory(), @"valid_signature_accepted.txt")); ParseRequestFile(fileContent, request, false); var contentBytes = new byte[request.Body.Length]; await request.Body.ReadAsync(contentBytes, 0, contentBytes.Length); request.Body.Seek(0, SeekOrigin.Begin); var response = (ObjectResult)await function.Run(request, logger); Assert.AreEqual("{}", Encoding.UTF8.GetString(contentBytes)); Assert.AreEqual(StatusCodes.Status200OK, response?.StatusCode); }
public async Task ExceptionsAreLogged() { var context = new DefaultHttpContext(); var request = context.Request; var throwingDispatcher = new Mock <IEventDispatchService>(); throwingDispatcher.Setup(x => x.Process(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <WebhookResult>())) .Throws(new Exception("test exception")); var function = new GitHubMonitorFunction(throwingDispatcher.Object, GetConfig()); var fileContent = await File.ReadAllTextAsync(Path.Combine(Directory.GetCurrentDirectory(), @"valid_signature_accepted.txt")); ParseRequestFile(fileContent, request, false); var response = (ObjectResult)await function.Run(request, logger); Assert.IsNotNull(response); var messagesField = typeof(WebhookResult).GetField("Messages"); var messages = messagesField?.GetValue(response.Value) as List <string>; Assert.IsNotNull(messages); Assert.IsTrue(messages.First().Contains("test exception")); }
public static async Task <TResponse> InvokeWithContentAndGetResponseAs <TResponse>(this GitHubMonitorFunction function, SampleCallbackData data) where TResponse : IActionResult { var result = await function.Invoke(req => configureRequest(req, data)); Assert.IsInstanceOfType(result, typeof(TResponse)); return((TResponse)result); }