-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
re #19767 - External orders - CRM bubble + hubspot sdk (#40)
* re #19767 - External orders - CRM bubble + hubspot sdk Added http client to retrieve pipelines. Added unit tests for the module. Updated deal model to include pipeline. Retrieving a deal will also retrieve the pipeline associated. * re #19767 - External orders - CRM bubble + hubspot sdk Implemented PR feedback * re #19767 - External orders - CRM bubble + hubspot sdk Fix feedback. Pass NotFoundException as paramater instead of manually creating it. * Test commit
- Loading branch information
1 parent
fafa8b6
commit 002b914
Showing
10 changed files
with
328 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
using HubSpot.Model.Pipelines; | ||
using Kralizek.Extensions.Http; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Net; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
|
||
namespace HubSpot | ||
{ | ||
public partial class HttpHubSpotClient : IHubSpotPipelineClient | ||
{ | ||
async Task<Pipeline> IHubSpotPipelineClient.GetByGuidAsync(string guid) | ||
{ | ||
try | ||
{ | ||
var result = await _client.GetAsync<Pipeline>($"/deals/v1/pipelines/{guid}"); | ||
return result; | ||
} | ||
catch (HttpException ex) when (ex.StatusCode == HttpStatusCode.NotFound) | ||
{ | ||
throw new NotFoundException("Pipeline not found", ex); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
12 changes: 12 additions & 0 deletions
12
src/HubSpot.Client/Model/Pipelines/IHubSpotPipelineClient.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
|
||
namespace HubSpot.Model.Pipelines | ||
{ | ||
public interface IHubSpotPipelineClient | ||
{ | ||
Task<Pipeline> GetByGuidAsync(string guid); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
using Newtonsoft.Json; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Text; | ||
|
||
namespace HubSpot.Model.Pipelines | ||
{ | ||
public class Pipeline | ||
{ | ||
[JsonProperty("active")] | ||
public bool IsActive { get; set; } | ||
|
||
[JsonProperty("displayOrder")] | ||
public int DisplayOrder { get; set; } | ||
|
||
[JsonProperty("label")] | ||
public string Label { get; set; } | ||
|
||
[JsonProperty("pipelineid")] | ||
public string Guid { get; set; } | ||
|
||
[JsonProperty("stages")] | ||
public IReadOnlyList<StageProperty> Stages { get; set; } | ||
} | ||
|
||
public class StageProperty | ||
{ | ||
[JsonProperty("active")] | ||
public bool IsActive { get; set; } | ||
|
||
[JsonProperty("closedWon")] | ||
public bool ClosedWon { get; set; } | ||
|
||
[JsonProperty("displayOrder")] | ||
public int DisplayOrder { get; set; } | ||
|
||
[JsonProperty("label")] | ||
public string Label { get; set; } | ||
|
||
[JsonProperty("probability")] | ||
public decimal Probability { get; set; } | ||
|
||
[JsonProperty("stageId")] | ||
public string StageID { get; set; } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
102 changes: 102 additions & 0 deletions
102
tests/Tests.HubSpot.Client/Pipelines/HubSpotPipelineClientTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
using AutoFixture; | ||
using AutoFixture.Idioms; | ||
using AutoFixture.NUnit3; | ||
using HubSpot; | ||
using HubSpot.Model.Pipelines; | ||
using Kralizek.Extensions.Http; | ||
using Moq; | ||
using NUnit.Framework; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Net; | ||
using System.Net.Http; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
|
||
namespace Tests.Pipelines | ||
{ | ||
[TestFixture] | ||
public class HubSpotPipelineClientTests | ||
{ | ||
[Test, CustomAutoData] | ||
public void Constructor_is_guarded_against_null_parameters(GuardClauseAssertion guardClauseAssertion) | ||
{ | ||
//Arrange | ||
|
||
//Act | ||
|
||
//Assert | ||
guardClauseAssertion.Verify(typeof(HttpHubSpotClient).GetConstructors()); | ||
} | ||
|
||
[Test, CustomAutoData] | ||
public void GetByGuidAsync_throws_NotFoundException_if_request_returns_NotFound_status([Frozen] IHttpRestClient httpRestClient, IHubSpotPipelineClient sut, string guid, IFixture fixture) | ||
{ | ||
//Arrange | ||
var httpException = fixture.Build<HttpException>().With(x => x.StatusCode, HttpStatusCode.NotFound).Create(); | ||
Mock.Get(httpRestClient) | ||
.Setup(p => p.SendAsync<Pipeline>(HttpMethod.Get, $"/deals/v1/pipelines/{guid}", null)) | ||
.Throws(httpException); | ||
|
||
//Act | ||
|
||
//Assert | ||
Assert.That(() => sut.GetByGuidAsync(guid), Throws.InstanceOf<NotFoundException>()); | ||
} | ||
|
||
[Test, CustomAutoData] | ||
public void GetByGuidAsync_invokes_http_client_get_method_once_with_guid([Frozen] IHttpRestClient httpRestClient, IHubSpotPipelineClient sut, string guid) | ||
{ | ||
//Arrange | ||
|
||
//Act | ||
sut.GetByGuidAsync(guid); | ||
|
||
//Assert | ||
Mock.Get(httpRestClient).Verify(p => p.SendAsync<Pipeline>(HttpMethod.Get, $"/deals/v1/pipelines/{guid}", null), Times.Once); | ||
} | ||
|
||
[Test, CustomAutoData] | ||
public async Task GetByGuidAsync_returns_null_if_API_retrieves_null([Frozen] IHttpRestClient httpRestClient, IHubSpotPipelineClient sut, string guid) | ||
{ | ||
//Arrange | ||
Mock.Get(httpRestClient) | ||
.Setup(p => p.SendAsync<Pipeline>(HttpMethod.Get, $"/deals/v1/pipelines/{guid}", null)).Returns(Task.FromResult((Pipeline)null)); | ||
|
||
//Act | ||
var result = await sut.GetByGuidAsync(guid); | ||
|
||
//Assert | ||
Assert.That(result, Is.Null); | ||
} | ||
|
||
[Test, CustomAutoData] | ||
public async Task GetByGuidAsync_returns_pipeline_retrieved_by_http_client_request([Frozen] IHttpRestClient httpRestClient,[Frozen] Pipeline pipeline, IHubSpotPipelineClient sut, string guid) | ||
{ | ||
//Arrange | ||
Mock.Get(httpRestClient) | ||
.Setup(p => p.SendAsync<Pipeline>(HttpMethod.Get, $"/deals/v1/pipelines/{guid}", null)).Returns(Task.FromResult(pipeline)); | ||
|
||
//Act | ||
var result = await sut.GetByGuidAsync(guid); | ||
|
||
//Assert | ||
Assert.That(result, Is.EqualTo(pipeline)); | ||
} | ||
|
||
[Test, CustomAutoData] | ||
public async Task GetByGuidAsync_returns_pipeline_with_valid_guid([Frozen] IHttpRestClient httpRestClient, IHubSpotPipelineClient sut, string guid, IFixture fixture) | ||
{ | ||
//Arrange | ||
var pipeline = fixture.Build<Pipeline>().With(x => x.Guid, guid).Create(); | ||
Mock.Get(httpRestClient) | ||
.Setup(p => p.SendAsync<Pipeline>(HttpMethod.Get, $"/deals/v1/pipelines/{guid}", null)).Returns(Task.FromResult(pipeline)); | ||
|
||
//Act | ||
var result = await sut.GetByGuidAsync(guid); | ||
|
||
//Assert | ||
Assert.That(result.Guid, Is.EqualTo(guid)); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
using AutoFixture; | ||
using AutoFixture.Idioms; | ||
using AutoFixture.NUnit3; | ||
using HubSpot; | ||
using HubSpot.Deals; | ||
using HubSpot.Model.Deals; | ||
using HubSpot.Model.Pipelines; | ||
using Kralizek.Extensions.Http; | ||
using Moq; | ||
using NUnit.Framework; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Net; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
|
||
namespace Tests.Deals | ||
{ | ||
[TestFixture] | ||
public class HubSpotDealConnectorTests | ||
{ | ||
[Test, CustomAutoData] | ||
public void Constructor_is_guarded_against_null_parameters(GuardClauseAssertion guardClauseAssertion) | ||
{ | ||
//Arrange | ||
|
||
//Act | ||
|
||
//Assert | ||
guardClauseAssertion.Verify(typeof(HubSpotDealConnector).GetConstructors()); | ||
} | ||
|
||
[Test, CustomAutoData] | ||
public void GetAsync_is_guarded_against_null_selector(HubSpotDealConnector sut) | ||
{ | ||
//Arrange | ||
|
||
//Act | ||
|
||
//Assert | ||
Assert.ThrowsAsync<ArgumentNullException>(async () => await sut.GetAsync<HubSpot.Deals.Deal>(null)); | ||
} | ||
|
||
[Test, CustomAutoData] | ||
public async Task GetAsync_invokes_selector_from_parameters_to_retrieve_deal([Frozen] IHubSpotClient hubSpotClient, [Frozen] IDealSelector dealSelector, HubSpotDealConnector sut) | ||
{ | ||
//Arrange | ||
|
||
//Act | ||
await sut.GetAsync<HubSpot.Deals.Deal>(dealSelector); | ||
|
||
//Assert | ||
Mock.Get(dealSelector).Verify(x => x.GetDeal(hubSpotClient), Times.Once); | ||
} | ||
|
||
[Test, CustomAutoData] | ||
public async Task GetAsync_invokes_deal_type_manager_to_convert_selector_result([Frozen] IDealTypeManager dealTypeManager, [Frozen] IHubSpotClient hubSpotClient, [Frozen] IDealSelector dealSelector, HubSpotDealConnector sut,HubSpot.Model.Deals.Deal deal) | ||
{ | ||
//Arrange | ||
Mock.Get(dealSelector).Setup(x => x.GetDeal(hubSpotClient)).Returns(Task.FromResult(deal)); | ||
|
||
//Act | ||
await sut.GetAsync<HubSpot.Deals.Deal>(dealSelector); | ||
|
||
//Assert | ||
Mock.Get(dealTypeManager).Verify(x => x.ConvertTo<HubSpot.Deals.Deal>(deal), Times.Once); | ||
} | ||
|
||
[Test, CustomAutoData] | ||
public async Task GetAsync_returns_converted_deal([Frozen] IDealTypeManager dealTypeManager, [Frozen] IHubSpotClient hubSpotClient, [Frozen] IDealSelector dealSelector, HubSpotDealConnector sut, IFixture fixture) | ||
{ | ||
//Arrange | ||
var convertedDeal = fixture.Build<HubSpot.Deals.Deal>().Without(x => x.Pipeline).Create(); | ||
Mock.Get(dealTypeManager).Setup(x => x.ConvertTo<HubSpot.Deals.Deal>(It.IsAny<HubSpot.Model.Deals.Deal>())).Returns(convertedDeal); | ||
Mock.Get(hubSpotClient).Setup(x => x.Pipelines.GetByGuidAsync(It.IsAny<string>())).Returns(Task.FromResult((Pipeline)null)); | ||
|
||
//Act | ||
var result = await sut.GetAsync<HubSpot.Deals.Deal>(dealSelector); | ||
|
||
//Assert | ||
Assert.That(result, Is.EqualTo(convertedDeal)); | ||
} | ||
|
||
[Test, CustomAutoData] | ||
public async Task GetAsync_returns_deal_with_pipeline_retrieved_by_http_client([Frozen] IDealTypeManager dealTypeManager, [Frozen] IHubSpotClient hubSpotClient, [Frozen] IDealSelector dealSelector, HubSpotDealConnector sut, IFixture fixture, Pipeline pipeline) | ||
{ | ||
//Arrange | ||
var convertedDeal = fixture.Build<HubSpot.Deals.Deal>().Without(x => x.Pipeline).Create(); | ||
Mock.Get(dealTypeManager).Setup(x => x.ConvertTo<HubSpot.Deals.Deal>(It.IsAny<HubSpot.Model.Deals.Deal>())).Returns(convertedDeal); | ||
Mock.Get(hubSpotClient).Setup(x => x.Pipelines.GetByGuidAsync(It.IsAny<string>())).Returns(Task.FromResult(pipeline)); | ||
|
||
//Act | ||
var result = await sut.GetAsync<HubSpot.Deals.Deal>(dealSelector); | ||
|
||
//Assert | ||
Assert.That(result.Pipeline, Is.EqualTo(pipeline)); | ||
} | ||
|
||
[Test, CustomAutoData] | ||
public async Task GetAsync_returns_null_if_deal_retrieving_throws_NotFoundException([Frozen] IHubSpotClient hubSpotClient, [Frozen] IDealSelector dealSelector, HubSpotDealConnector sut, NotFoundException notFoundException) | ||
{ | ||
//Arrange | ||
Mock.Get(dealSelector).Setup(x => x.GetDeal(hubSpotClient)).Throws(notFoundException); | ||
|
||
//Act | ||
var result = await sut.GetAsync<HubSpot.Deals.Deal>(dealSelector); | ||
|
||
//Assert | ||
Assert.That(result, Is.Null); | ||
} | ||
|
||
[Test, CustomAutoData] | ||
public async Task GetAsync_returns_null_if_pipeline_retrieving_throws_NotFoundeException([Frozen] IHubSpotClient hubSpotClient, [Frozen] IDealSelector dealSelector, HubSpotDealConnector sut, NotFoundException notFoundException) | ||
{ | ||
//Arrange | ||
Mock.Get(hubSpotClient).Setup(x => x.Pipelines.GetByGuidAsync(It.IsAny<string>())).Throws(notFoundException); | ||
|
||
//Act | ||
var result = await sut.GetAsync<HubSpot.Deals.Deal>(dealSelector); | ||
|
||
//Assert | ||
Assert.That(result, Is.Null); | ||
} | ||
} | ||
} |