public void Test_Process_Returns_NoResult_If_ObjectAttributesNoteableType_Not_Supported() { using (AutoMock autoMock = AutoMock.GetLoose(this.output.Capture())) { autoMock.Mock <IMockCanHandle>() .Setup(p => p.CanHandle(It.IsAny <string>())) .Returns(false); var processor = autoMock.Create <MockGitlabProcessor>(); RequestProcessResult result = processor.Process(new JObject { [GitlabKeys.ObjectKind] = GitlabKeys.ObjectKindNote, [GitlabKeys.ObjectAttributes] = new JObject { [GitlabKeys.NoteableType] = "some-unsupported-type" } }); Assert.False(result.Success); Assert.True(result.NoResult); Assert.Null(result.Reason); autoMock.Mock <IMockCanHandle>() .Verify(p => p.CanHandle("some-unsupported-type"), Times.Once); } }
public void Test_TryFormat_Returns_Positive_If_Message_Was_Formatted(string createdAt, string updatedAt, string expectedText) { using (AutoMock mock = AutoMock.GetLoose(this.output.Capture())) { var formatter = mock.Create <CommentSnippetMessageFormatter>(); var request = new JObject { [GitlabKeys.User] = new JObject { [GitlabKeys.Name] = "A-User-Name" }, [GitlabKeys.Project] = new JObject { [GitlabKeys.Name] = "A-Project-Name", [GitlabKeys.WebUrl] = "A-Web-Url" }, [GitlabKeys.ObjectAttributes] = new JObject { [GitlabKeys.Note] = "A-Note", [GitlabKeys.Url] = "A-Url", [GitlabKeys.CreatedAt] = createdAt, [GitlabKeys.UpdatedAt] = updatedAt } }; RequestProcessResult result = formatter.TryFormat(request, out string msg); Assert.True(result.Success); Assert.False(result.NoResult); Assert.Null(result.Reason); string expected = $"[A-Project-Name](A-Web-Url). *A-User-Name* has [{expectedText}](A-Url) on the code snippet!\r\n\r\nA-Note"; Assert.Equal(expected, msg); } }
public void Test_Process_Does_Not_Call_MessageClient_If_The_Message_Was_Not_Formatted() { using (AutoMock autoMock = AutoMock.GetLoose(this.output.Capture())) { string mockFormatterResult; autoMock.Mock <IMergeRequestMessageFormatter>() .Setup(p => p.TryFormat(It.IsAny <JObject>(), out mockFormatterResult)) .Returns(RequestProcessResult.CreateFailure("some-reason")); var processor = autoMock.Create <MergeRequestGitlabProcessor>(); var request = new JObject { [GitlabKeys.ObjectKind] = GitlabKeys.ObjectKindMergeRequest }; RequestProcessResult result = processor.Process(request); Assert.False(result.Success); Assert.False(result.NoResult); Assert.Equal("some-reason", result.Reason); autoMock.Mock <IMergeRequestMessageFormatter>() .Verify(p => p.TryFormat(request, out mockFormatterResult), Times.Once); autoMock.Mock <IMessageClient>() .Verify(p => p.ScheduleDelivery(It.IsAny <string>()), Times.Never); } }
public void Test_Process_Calls_MessageClient_If_The_Message_Was_Formatted() { using (AutoMock autoMock = AutoMock.GetLoose(this.output.Capture())) { string mockFormatterResult = "some-result"; autoMock.Mock <IPipelineMessageFormatter>() .Setup(p => p.TryFormat(It.IsAny <JObject>(), out mockFormatterResult)) .Returns(RequestProcessResult.CreateSuccess()); var processor = autoMock.Create <PipelineFailureGitlabProcessor>(); var request = new JObject { [GitlabKeys.ObjectKind] = GitlabKeys.ObjectKindPipeline, [GitlabKeys.ObjectAttributes] = new JObject { [GitlabKeys.Status] = GitlabKeys.StatusFailed } }; RequestProcessResult result = processor.Process(request); Assert.True(result.Success); Assert.False(result.NoResult); Assert.Null(result.Reason); autoMock.Mock <IPipelineMessageFormatter>() .Verify(p => p.TryFormat(request, out mockFormatterResult), Times.Once); autoMock.Mock <IMessageClient>() .Verify(p => p.ScheduleDelivery(mockFormatterResult), Times.Once); } }
public void Test_TryFormat_Returns_Negative_If_Request_Has_No_Required_Attributes() { using (AutoMock mock = AutoMock.GetLoose(this.output.Capture())) { var formatter = mock.Create <PipelineMessageFormatter>(); RequestProcessResult result = formatter.TryFormat(new JObject(), out string _); Assert.False(result.Success); Assert.False(result.NoResult); string expected1 = $"1. The json object is missing the field: \"{GitlabKeys.Project}\"{Environment.NewLine}" + $"2. The json object is missing the field: \"{GitlabKeys.ObjectAttributes}\"{Environment.NewLine}" + $"3. The json object is missing the field: \"{GitlabKeys.Commit}\""; Assert.Equal(expected1, result.Reason); var request2 = new JObject { [GitlabKeys.Project] = new JObject(), [GitlabKeys.ObjectAttributes] = new JObject(), [GitlabKeys.Commit] = new JObject() }; result = formatter.TryFormat(request2, out string _); Assert.False(result.Success); Assert.False(result.NoResult); string expected2 = $"1. The json object is missing the field: \"{GitlabKeys.Project}.{GitlabKeys.Name}\"{Environment.NewLine}" + $"2. The json object is missing the field: \"{GitlabKeys.Project}.{GitlabKeys.WebUrl}\"{Environment.NewLine}" + $"3. The json object is missing the field: \"{GitlabKeys.Project}.{GitlabKeys.PathWithNamespace}\"{Environment.NewLine}" + $"4. The json object is missing the field: \"{GitlabKeys.ObjectAttributes}.{GitlabKeys.Ref}\"{Environment.NewLine}" + $"5. The json object is missing the field: \"{GitlabKeys.ObjectAttributes}.{GitlabKeys.Id}\"{Environment.NewLine}" + $"6. The json object is missing the field: \"{GitlabKeys.Commit}.{GitlabKeys.Id}\"{Environment.NewLine}" + $"7. The json object is missing the field: \"{GitlabKeys.Commit}.{GitlabKeys.Message}\"{Environment.NewLine}" + $"8. The json object is missing the field: \"{GitlabKeys.Commit}.{GitlabKeys.Url}\"{Environment.NewLine}" + $"9. The json object is missing the field: \"{GitlabKeys.Commit}.{GitlabKeys.Author}\""; Assert.Equal(expected2, result.Reason); } }
public async Task <IActionResult> Hook() { IActionResult result; using (var reader = new StreamReader(this.Request.Body)) { string json = await reader.ReadToEndAsync(); if (this.logger.IsEnabled(LogLevel.Trace)) { this.logger.LogTrace(json); } this.logger.LogDebug("Parsing and processing the incoming request"); JObject obj = JObject.Parse(json); RequestProcessResult processResult = this.gitlabProcessService.ProcessRequest(obj); this.logger.LogDebug("The processing result was: {0}", processResult); result = processResult.Success ? (IActionResult)this.Ok() : this.BadRequest(processResult.Reason); } return(result); }
public void Test_ProcessRequest_Returns_The_First_Successful_Result() { var m1 = new Mock <IGitlabProcessor>(); m1.Setup(p => p.Process(It.IsAny <JObject>())) .Returns(RequestProcessResult.CreateNoResult()); //no result var m2 = new Mock <IGitlabProcessor>(); m2.Setup(p => p.Process(It.IsAny <JObject>())) .Returns(RequestProcessResult.CreateSuccess()); //success var m3 = new Mock <IGitlabProcessor>(); m3.Setup(p => p.Process(It.IsAny <JObject>())) .Returns(RequestProcessResult.CreateNoResult()); //should not have been called using (AutoMock mock = AutoMock.GetLoose(builder => { builder.RegisterXUnit(this.output); builder.RegisterInstance(m1.Object); builder.RegisterInstance(m2.Object); builder.RegisterInstance(m3.Object); })) { var service = mock.Create <GitlabProcessServiceImpl>(); JObject request = JObject.Parse("{prop:'value'}"); RequestProcessResult result = service.ProcessRequest(request); Assert.True(result.Success); m1.Verify(p => p.Process(request), Times.Once); m2.Verify(p => p.Process(request), Times.Once); m3.Verify(p => p.Process(request), Times.Never); } }
public RequestProcessResult Process(JObject request) { RequestProcessResult result; string objectKind = request[GitlabKeys.ObjectKind]?.ToString(); this.logger.LogTrace("The request object kind was determined as: \"{0}\"", objectKind); if (string.Equals(objectKind, GitlabKeys.ObjectKindMergeRequest, StringComparison.InvariantCultureIgnoreCase)) { result = this.formatter.TryFormat(request, out string message); if (result.Success) { this.logger.LogDebug("Successfully formatted the message: \"{0}\"", message); this.messageClient.ScheduleDelivery(message); } else { this.logger.LogDebug("Could not format the message: {@0}", result); } } else { this.logger.LogTrace("Can not handle the request of the \"{0}\" object kind", objectKind); result = RequestProcessResult.CreateNoResult(); } return(result); }
public RequestProcessResult Process(JObject request) { RequestProcessResult result; string objectKind = request[GitlabKeys.ObjectKind]?.ToString(); this.logger.LogTrace("The request object kind was determined as: \"{0}\"", objectKind); if (string.Equals(objectKind, GitlabKeys.ObjectKindNote, StringComparison.InvariantCultureIgnoreCase)) { var errors = new JTokenErrors(); string noteableType = request.RequireChild(GitlabKeys.ObjectAttributes, errors)?.RequireString(GitlabKeys.NoteableType, errors); this.logger.LogDebug("The noteable type was determined as \"{0}\"", noteableType); if (errors.HasAny) { string error = errors.Compose(); result = RequestProcessResult.CreateFailure(error); this.logger.LogDebug("The request processing was rejected with message: \"{0}\"", error); } else { if (this.CanHandle(noteableType)) { result = this.TryFormat(request, out string message); if (result.Success) { this.logger.LogDebug("Successfully formatted the message: \"{0}\"", message); this.messageClient.ScheduleDelivery(message); } else { this.logger.LogDebug("Could not format the message: {@0}", result); } } else { this.logger.LogDebug("Can not handle the request with the \"{0}\" noteable type", noteableType); result = RequestProcessResult.CreateNoResult(); } } } else { this.logger.LogTrace("Can not handle the request of the \"{0}\" object kind", objectKind); result = RequestProcessResult.CreateNoResult(); } return(result); }
public void Test_Process_Returns_NoResult_If_ObjectKind_Not_Supported() { using (AutoMock autoMock = AutoMock.GetLoose(this.output.Capture())) { var processor = autoMock.Create <PipelineFailureGitlabProcessor>(); RequestProcessResult result = processor.Process(new JObject { [GitlabKeys.ObjectKind] = "some-unknown-kind" }); Assert.False(result.Success); Assert.True(result.NoResult); Assert.Null(result.Reason); } }
public void Test_Process_Returns_Failure_If_ObjectAttributes_Missing() { using (AutoMock autoMock = AutoMock.GetLoose(this.output.Capture())) { var processor = autoMock.Create <PipelineFailureGitlabProcessor>(); RequestProcessResult result = processor.Process(new JObject { [GitlabKeys.ObjectKind] = GitlabKeys.ObjectKindPipeline }); Assert.False(result.Success); Assert.False(result.NoResult); string expected = $"1. The json object is missing the field: \"{GitlabKeys.ObjectAttributes}\""; Assert.Equal(expected, result.Reason); } }
public RequestProcessResult TryFormat(JObject request, out string message) { if (request == null) { throw new ArgumentNullException(nameof(request)); } var errors = new JTokenErrors(); JToken authorNode = request.RequireChild(GitlabKeys.User, errors); JToken assigneeNode = request.RequireChild(GitlabKeys.Assignee, errors); JToken projectNode = request.RequireChild(GitlabKeys.Project, errors); JToken attributesNode = request.RequireChild(GitlabKeys.ObjectAttributes, errors); UserInfo author = UserInfo.TryRead(authorNode, errors); UserInfo assignee = UserInfo.TryRead(assigneeNode, errors); ProjectInfo projectInfo = ProjectInfo.TryRead(projectNode, errors); string sourceBranch = attributesNode?.RequireString(GitlabKeys.SourceBranch, errors); string targetBranch = attributesNode?.RequireString(GitlabKeys.TargetBranch, errors); string state = attributesNode?.RequireString(GitlabKeys.State, errors); string title = attributesNode?.RequireString(GitlabKeys.Title, errors); string url = attributesNode?.RequireString(GitlabKeys.Url, errors); string iid = attributesNode?.RequireString(GitlabKeys.Iid, errors); string createdAt = attributesNode?[GitlabKeys.CreatedAt]?.ToString(); string updatedAt = attributesNode?[GitlabKeys.UpdatedAt]?.ToString(); RequestProcessResult result; if (errors.HasAny) { string error = errors.Compose(); this.logger.LogDebug("The request processing was rejected with error: \"{0}\"", error); message = null; result = RequestProcessResult.CreateFailure(error); } else { state = MergeRequestMessageFormatter.GetMergeRequestState(state, createdAt, updatedAt); message = $"[{projectInfo.Name}]({projectInfo.Url}). The merge request [#{iid} {title}]({url}) (branch [{sourceBranch}]({projectInfo.Url}/tree/{sourceBranch}) to [{targetBranch}]({projectInfo.Url}/tree/{targetBranch})) was {state} by [{author.Name}]({projectInfo.Server}{author.UserName}).\r\nAssignee [{assignee.Name}]({projectInfo.Server}{assignee.UserName})."; this.logger.LogTrace("Composed the message: \"{0}\"", message); result = RequestProcessResult.CreateSuccess(); } return(result); }
public void Test_ProcessRequest_Returns_Failure_If_No_Success_Result_Received() { using (AutoMock mock = AutoMock.GetLoose(this.output.Capture())) { mock.Mock <IGitlabProcessor>() .Setup(p => p.Process(It.IsAny <JObject>())) .Returns(RequestProcessResult.CreateNoResult()); var service = mock.Create <GitlabProcessServiceImpl>(); JObject request = JObject.Parse("{prop:'value'}"); RequestProcessResult result = service.ProcessRequest(request); Assert.False(result.Success); Assert.Equal("The system is not capable of processing such requests", result.Reason); } }
public RequestProcessResult TryFormat(JObject request, out string message) { if (request == null) { throw new ArgumentNullException(nameof(request)); } var errors = new JTokenErrors(); JToken author = request.RequireChild(GitlabKeys.User, errors); JToken project = request.RequireChild(GitlabKeys.Project, errors); JToken attributes = request.RequireChild(GitlabKeys.ObjectAttributes, errors); JToken mergeRequest = request.RequireChild(GitlabKeys.MergeRequest, errors); string authorName = author?.RequireString(GitlabKeys.Name, errors); string projectName = project?.RequireString(GitlabKeys.Name, errors); string projectUrl = project?.RequireString(GitlabKeys.WebUrl, errors); string snippetText = attributes?.RequireString(GitlabKeys.Note, errors); string snippetUrl = attributes?.RequireString(GitlabKeys.Url, errors); string createdAt = attributes?[GitlabKeys.CreatedAt]?.ToString(); string updatedAt = attributes?[GitlabKeys.UpdatedAt]?.ToString(); string mrTitle = mergeRequest?.RequireString(GitlabKeys.Title, errors); string mrIid = mergeRequest?.RequireString(GitlabKeys.Iid, errors); RequestProcessResult result; if (errors.HasAny) { string error = errors.Compose(); this.logger.LogDebug("The request processing was rejected with error: \"{0}\"", error); message = null; result = RequestProcessResult.CreateFailure(error); } else { string commentAction = CommentRequestMessageFormatter.GetCommentAction(createdAt, updatedAt); message = $"[{projectName}]({projectUrl}). *{authorName}* has [{commentAction}]({snippetUrl}) on the MR [#{mrIid} {mrTitle}]({projectUrl}/merge_requests/{mrIid})!\r\n\r\n{snippetText}"; this.logger.LogTrace("Composed the message: \"{0}\"", message); result = RequestProcessResult.CreateSuccess(); } return(result); }
public void Test_TryFormat_Returns_Positive_If_Message_Was_Formatted(string state, string createdAt, string updatedAt, string expectedText) { using (AutoMock mock = AutoMock.GetLoose(this.output.Capture())) { var formatter = mock.Create <MergeRequestMessageFormatter>(); var request = new JObject { [GitlabKeys.User] = new JObject { [GitlabKeys.Name] = "A-User", [GitlabKeys.UserName] = "A-User-Name" }, [GitlabKeys.Assignee] = new JObject { [GitlabKeys.Name] = "An-Assignee", [GitlabKeys.UserName] = "An-Assignee-Name" }, [GitlabKeys.Project] = new JObject { [GitlabKeys.Name] = "A-Project-Name", [GitlabKeys.WebUrl] = "A-Web-Url/namespace", [GitlabKeys.PathWithNamespace] = "namespace" }, [GitlabKeys.ObjectAttributes] = new JObject { [GitlabKeys.SourceBranch] = "A-Source-Branch", [GitlabKeys.TargetBranch] = "A-Target-Branch", [GitlabKeys.State] = state, [GitlabKeys.Title] = "A-Title", [GitlabKeys.Url] = "A-Url", [GitlabKeys.Iid] = "A-Iid", [GitlabKeys.CreatedAt] = createdAt, [GitlabKeys.UpdatedAt] = updatedAt } }; RequestProcessResult result = formatter.TryFormat(request, out string msg); Assert.True(result.Success); Assert.False(result.NoResult); Assert.Null(result.Reason); string expected = $"[A-Project-Name](A-Web-Url/namespace). The merge request [#A-Iid A-Title](A-Url) (branch [A-Source-Branch](A-Web-Url/namespace/tree/A-Source-Branch) to [A-Target-Branch](A-Web-Url/namespace/tree/A-Target-Branch)) was {expectedText} by [A-User](A-Web-Url/A-User-Name).\r\nAssignee [An-Assignee](A-Web-Url/An-Assignee-Name)."; Assert.Equal(expected, msg); } }
public void Test_TryFormat_Returns_Positive_If_Message_Was_Formatted() { using (AutoMock mock = AutoMock.GetLoose(this.output.Capture())) { var formatter = mock.Create <PipelineMessageFormatter>(); var request = new JObject { [GitlabKeys.Project] = new JObject { [GitlabKeys.Name] = "A-Project-Name", [GitlabKeys.WebUrl] = "A-Web-Url/Group/Project", [GitlabKeys.PathWithNamespace] = "/Group/Project" }, [GitlabKeys.ObjectAttributes] = new JObject { [GitlabKeys.Ref] = "A-Ref", [GitlabKeys.Id] = "A-Id" }, [GitlabKeys.Commit] = new JObject { [GitlabKeys.Id] = "us8dii909989ac978ac6a8w5ca8", [GitlabKeys.Message] = "A-Commit-Message", [GitlabKeys.Url] = "A-Commit-Url", [GitlabKeys.Author] = new JObject { [GitlabKeys.Name] = "A-Commit-Author", [GitlabKeys.Email] = "A-Commit-Email" } } }; RequestProcessResult result = formatter.TryFormat(request, out string msg); Assert.True(result.Success); Assert.False(result.NoResult); Assert.Null(result.Reason); const string expected = "[A-Project-Name](A-Web-Url/Group/Project). The pipeline [A-Id](A-Web-Url/Group/Project/pipelines/A-Id) has failed for the branch [A-Ref](A-Web-Url/Group/Project/tree/A-Ref)!" + "\r\n\r\nThe last commit [us8dii9](A-Commit-Url) by *A-Commit-Author*\r\nA-Commit-Message"; Assert.Equal(expected, msg); } }
public RequestProcessResult TryFormat(JObject request, out string message) { if (request == null) { throw new ArgumentNullException(nameof(request)); } var errors = new JTokenErrors(); JToken projectNode = request.RequireChild(GitlabKeys.Project, errors); JToken attributesNode = request.RequireChild(GitlabKeys.ObjectAttributes, errors); JToken commitNode = request.RequireChild(GitlabKeys.Commit, errors); ProjectInfo project = ProjectInfo.TryRead(projectNode, errors); string branchName = attributesNode?.RequireString(GitlabKeys.Ref, errors); string pipelineId = attributesNode?.RequireString(GitlabKeys.Id, errors); CommitInfo commit = CommitInfo.TryRead(commitNode, errors); RequestProcessResult result; if (errors.HasAny) { string error = errors.Compose(); this.logger.LogDebug("The request processing was rejected with error: \"{0}\"", error); message = null; result = RequestProcessResult.CreateFailure(error); } else { message = $"[{project.Name}]({project.Url}). The pipeline [{pipelineId}]({project.Url}/pipelines/{pipelineId}) has failed for the branch [{branchName}]({project.Url}/tree/{branchName})!\r\n\r\n" + $"The last commit [{commit.Hash}]({commit.Url}) by *{commit.AuthorName}*\r\n{commit.Message}"; this.logger.LogTrace("Composed the message: \"{0}\"", message); result = RequestProcessResult.CreateSuccess(); } return(result); }
public void Test_Process_Calls_MessageClient_If_The_Message_Was_Formatted() { using (AutoMock autoMock = AutoMock.GetLoose(this.output.Capture())) { autoMock.Mock <IMockCanHandle>() .Setup(p => p.CanHandle(It.IsAny <string>())) .Returns(true); string mockFormatterResult = "some-result"; autoMock.Mock <IMockFormatter>() .Setup(p => p.TryFormat(It.IsAny <JObject>(), out mockFormatterResult)) .Returns(RequestProcessResult.CreateSuccess()); var processor = autoMock.Create <MockGitlabProcessor>(); var request = new JObject { [GitlabKeys.ObjectKind] = GitlabKeys.ObjectKindNote, [GitlabKeys.ObjectAttributes] = new JObject { [GitlabKeys.NoteableType] = GitlabKeys.NoteableTypeSnippet } }; RequestProcessResult result = processor.Process(request); Assert.True(result.Success); Assert.False(result.NoResult); Assert.Null(result.Reason); autoMock.Mock <IMockCanHandle>() .Verify(p => p.CanHandle(GitlabKeys.NoteableTypeSnippet), Times.Once); autoMock.Mock <IMockFormatter>() .Verify(p => p.TryFormat(request, out mockFormatterResult), Times.Once); autoMock.Mock <IMessageClient>() .Verify(p => p.ScheduleDelivery(mockFormatterResult), Times.Once); } }
protected override RequestProcessResult TryFormat(JObject request, out string message) { RequestProcessResult result = this.formatter.TryFormat(request, out message); return(result); }