Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Set up CI with Azure Pipelines + added new plugin for content comparison #3

Open
wants to merge 31 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
a3c3f13
Set up CI with Azure Pipelines
cpoDesign Nov 20, 2023
6be4544
Update azure-pipelines.yml for Azure Pipelines
cpoDesign Nov 20, 2023
57f7ad2
Update azure-pipelines.yml for Azure Pipelines
cpoDesign Nov 21, 2023
c4e50e5
Update azure-pipelines.yml for Azure Pipelines
cpoDesign Nov 21, 2023
d7a48bb
Update azure-pipelines.yml for Azure Pipelines
cpoDesign Nov 21, 2023
8f488fa
Update azure-pipelines.yml for Azure Pipelines
cpoDesign Nov 21, 2023
bc7ff3d
Update azure-pipelines.yml for Azure Pipelines
cpoDesign Nov 21, 2023
3e99be4
Update azure-pipelines.yml for Azure Pipelines
cpoDesign Nov 27, 2023
56b1ee0
Update azure-pipelines.yml for Azure Pipelines
cpoDesign Nov 27, 2023
08da3a2
Update azure-pipelines.yml for Azure Pipelines
cpoDesign Nov 27, 2023
f9f3d05
Update azure-pipelines.yml for Azure Pipelines
cpoDesign Nov 27, 2023
22b86e1
Added config file
cpoDesign Nov 27, 2023
674ec20
Update azure-pipelines.yml for Azure Pipelines
cpoDesign Nov 27, 2023
095dd80
Update azure-pipelines.yml for Azure Pipelines
cpoDesign Nov 27, 2023
a397b2b
Update azure-pipelines.yml for Azure Pipelines
cpoDesign Nov 27, 2023
1119ac9
Update azure-pipelines.yml for Azure Pipelines
cpoDesign Nov 27, 2023
acc9c28
Update azure-pipelines.yml for Azure Pipelines
cpoDesign Nov 27, 2023
38bf62e
Update azure-pipelines.yml for Azure Pipelines
cpoDesign Nov 27, 2023
17b18cb
Update azure-pipelines.yml for Azure Pipelines
cpoDesign Nov 27, 2023
69ba626
Update azure-pipelines.yml for Azure Pipelines
cpoDesign Nov 27, 2023
d99edac
Update azure-pipelines.yml for Azure Pipelines
cpoDesign Nov 27, 2023
a464df7
Update azure-pipelines.yml for Azure Pipelines
cpoDesign Nov 27, 2023
297bba6
Update azure-pipelines.yml for Azure Pipelines
cpoDesign Nov 27, 2023
fc0daf3
Update azure-pipelines.yml for Azure Pipelines
cpoDesign Nov 27, 2023
150c872
Update azure-pipelines.yml for Azure Pipelines
cpoDesign Nov 27, 2023
82addcb
Merged in latest version of code from main
cpoDesign Nov 28, 2023
ad0b429
Added exclusion of publishing except from main branch
cpoDesign Nov 28, 2023
7b61c35
Added a new plugin
cpoDesign Nov 30, 2023
cc5bdb3
Updated implementation to add enhanced comparissonOnJsonValues
cpoDesign Dec 1, 2023
96d0b40
Solved last issues with comparison
cpoDesign Dec 1, 2023
5e79631
Removed redundant tests
cpoDesign Dec 1, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
177 changes: 177 additions & 0 deletions APITestingRunner.Unit.Tests/Plugins/StringPluginTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
using APITestingRunner.ApiRequest;
using APITestingRunner.Configuration;
using APITestingRunner.IoOperations;
using APITestingRunner.Plugins;
using FluentAssertions;
using Microsoft.Extensions.Logging;
using Moq;

namespace APITestingRunner.Unit.Tests.Plugins
{
[TestClass]
public class StringPluginTests
{
private IPlugin? _stringComparisonPlugin = new StringComparisonPlugin();

private TestLogger _logger = new();

[TestInitialize]
public void Initialize()
{
_stringComparisonPlugin = new StringComparisonPlugin();
IConfig baseConfig = new Config()
{
UrlBase = "http://localhost:7055",
CompareUrlBase = string.Empty,
CompareUrlPath = string.Empty,
UrlPath = "/WeatherForecast",
UrlParam = null,
RequestBody = null,
HeaderParam = null,
DBConnectionString = null,
DBQuery = null,
DBFields = null,
RequestType = RequestType.GET,
ResultsStoreOption = StoreResultsOption.None,
ConfigMode = TesterConfigMode.Run,
OutputLocation = DirectoryServices.AssemblyDirectory,
ResultFileNamePattern = null,
ContentReplacements = null
};

_logger = new TestLogger();
_stringComparisonPlugin.ApplyConfig(ref baseConfig, _logger);
}

[TestMethod]
public void NoDifferencesReported()
{
var json1 = "{\"name\":\"John\",\"age\":30,\"city\":\"New York\"}";
var json2 = "{\"name\":\"John\",\"age\":30,\"city\":\"New York\"}";
var apiResult1 = CreateApiResultForJsonResponse(json1);
var apiResult2 = CreateApiResultForJsonResponse(json2);

_ = _stringComparisonPlugin.ProcessComparison(apiResult1, apiResult2, ComparisonStatus.NewFile);
_ = _logger.Messages.Should().HaveCount(1);
_ = _logger.Messages.First().Item2.Should().Contain("Source and target has same length.");
}


[TestMethod]
public void DifferentLength_isReported()
{
var json1 = "{\"name\":\"John\",\"age\":30,\"city\":\"New York\"}";
var json2 = "{\"age\":30,\"city\":\"New York\",\"name\":\"John\",\"country\":\"USA\"}";
var apiResult1 = CreateApiResultForJsonResponse(json1);
var apiResult2 = CreateApiResultForJsonResponse(json2);

_ = _stringComparisonPlugin.ProcessComparison(apiResult1, apiResult2, ComparisonStatus.NewFile);
var loggerMessages = _logger.Messages.Select(x => x.Item2);
_ = loggerMessages.Should().HaveCountGreaterThan(1);
_ = loggerMessages.Should().ContainMatch("Source is different in length: 42 < 58");
}

[TestMethod]
public void DifferentLength_KeyMissingIsReported_FromTarget()
{
var json1 = "{\"name\":\"John\",\"age\":30,\"city\":\"New York\"}";
var json2 = "{\"age\":30,\"city\":\"New York\",\"name\":\"John\",\"country\":\"USA\"}";

var apiResult1 = CreateApiResultForJsonResponse(json1);
var apiResult2 = CreateApiResultForJsonResponse(json2);

var loggerMessages = _logger.Messages.Select(x => x.Item2);
_ = _stringComparisonPlugin.ProcessComparison(apiResult1, apiResult2, ComparisonStatus.NewFile);
_ = _logger.Messages.Should().HaveCountGreaterThan(1);
_ = loggerMessages.Should().ContainMatch("Difference at path '.country' for property 'country'");
_ = loggerMessages.Should().ContainMatch("Missing path in source at path: '.country' for property 'country'");
}

[TestMethod]
public void DifferentLength_KeyMissingIsReported_FromSource()
{
var json1 = "{\"name\":\"John\",\"age\":30,\"city\":\"New York\", \"country\":\"USA\"}";
var json2 = "{\"age\":30,\"city\":\"New York\",\"name\":\"John\"}";

var apiResult1 = CreateApiResultForJsonResponse(json1);
var apiResult2 = CreateApiResultForJsonResponse(json2);

_ = _stringComparisonPlugin.ProcessComparison(apiResult1, apiResult2, ComparisonStatus.NewFile);

var loggerMessages = _logger.Messages.Select(x => x.Item2);

_ = loggerMessages.Should().HaveCountGreaterThan(1);
_ = loggerMessages.Should().ContainMatch("Difference at path '.country' for property 'country'");
_ = loggerMessages.Should().ContainMatch("Missing path in source at path: '.country' for property 'country'");
}

[TestMethod]
public void Different_DifferentValueIsReported()
{
var json1 = "{\"name\":\"John\",\"age\":30,\"city\":\"New York\"}";
var json2 = "{\"name\":\"John\",\"age\":30,\"city\":\"New Yorks\"}";

var apiResult1 = CreateApiResultForJsonResponse(json1);
var apiResult2 = CreateApiResultForJsonResponse(json2);

_ = _stringComparisonPlugin.ProcessComparison(apiResult1, apiResult2, ComparisonStatus.NewFile);
var loggerMessages = _logger.Messages.Select(x => x.Item2);
_ = loggerMessages.Should().HaveCount(4);
_ = loggerMessages.Should().ContainMatch("Difference at path '' for property 'Root'");
_ = loggerMessages.Should().ContainMatch("Difference at path '.city' for property 'city'");
_ = loggerMessages.Should().ContainMatch("DiffValue is: New York <> New Yorks");
}
[TestMethod]
public void StringPlugin_ArrayValues()
{
var json1 = "{\"name\":\"John\",\"age\":30,\"city\":\"New York\",\"hobbies\":[\"reading\",\"traveling\"]}";
var json2 = "{\"age\":30,\"city\":\"New York\",\"name\":\"John\",\"hobbies\":[\"reading\",\"cooking\"]}";

var apiResult1 = CreateApiResultForJsonResponse(json1);
var apiResult2 = CreateApiResultForJsonResponse(json2);

_ = _stringComparisonPlugin.ProcessComparison(apiResult1, apiResult2, ComparisonStatus.NewFile);
var loggerMessages = _logger.Messages.Select(x => x.Item2);
_ = loggerMessages.Should().HaveCount(5);
_ = loggerMessages.Should().ContainMatch("Difference at path '.hobbies' for property 'hobbies'");
_ = loggerMessages.Should().ContainMatch("Difference at path '.hobbies[1]' for property 'hobbies'");
_ = loggerMessages.Should().ContainMatch("DiffValue is: traveling <> cooking");
}

[TestMethod]
public void Different_DeepArrayNestingComparison()
{
var json1 = "{\"name\":\"John\",\"age\":30,\"city\":\"New York\",\"hobbies\":[{\"type\":\"reading\",\"locations\":[{\"name\":\"Library\",\"hours\":9},{\"name\":\"Park\",\"hours\":5}]}]}";
var json2 = "{\"age\":30,\"city\":\"New York\",\"name\":\"John\",\"hobbies\":[{\"type\":\"reading\",\"locations\":[{\"name\":\"Library\",\"hours\":9},{\"name\":\"Beach\",\"hours\":8}]}]}";

var apiResult1 = CreateApiResultForJsonResponse(json1);
var apiResult2 = CreateApiResultForJsonResponse(json2);

_ = _stringComparisonPlugin.ProcessComparison(apiResult1, apiResult2, ComparisonStatus.NewFile);
_ = _logger.Messages.Should().HaveCount(9);
var loggerMessages = _logger.Messages.Select(x => x.Item2);
_ = loggerMessages.Should().ContainMatch("Difference at path '.hobbies' for property 'hobbies'");
_ = loggerMessages.Should().ContainMatch("Difference at path '.hobbies[0]' for property 'hobbies'");
_ = loggerMessages.Should().ContainMatch("Difference at path '.hobbies[0].locations' for property 'locations'");
_ = loggerMessages.Should().ContainMatch("Difference at path '.hobbies[0].locations[1]' for property 'locations'");
_ = loggerMessages.Should().ContainMatch("Difference at path '.hobbies[0].locations[1].name' for property 'name'");
_ = loggerMessages.Should().ContainMatch("DiffValue is: Park <> Beach");
_ = loggerMessages.Should().ContainMatch("Difference at path '.hobbies[0].locations[1].hours' for property 'hours'");
}


private static ApiCallResult CreateApiResultForJsonResponse(string json1)
{
return new ApiCallResult
{
StatusCode = System.Net.HttpStatusCode.Continue,
ResponseContent = json1,
Headers = new List<KeyValuePair<string, string>>(),
Url = string.Empty,
DataQueryResult = new Database.DataQueryResult(),
IsSuccessStatusCode = true,
CompareResults = new List<string>()
};
}
}
}
45 changes: 45 additions & 0 deletions APITestingRunner.Unit.Tests/TestRunnerTests/CustomResponse.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using System.Text;
using WireMock;
using WireMock.ResponseBuilders;
using WireMock.ResponseProviders;
using WireMock.Settings;
using WireMock.Types;
using WireMock.Util;

namespace APITestingRunner.Unit.Tests.TestRunnerTests
{
public class CustomResponse : IResponseProvider
{
private static int _count = 0;
public async Task<(IResponseMessage Message, IMapping? Mapping)> ProvideResponseAsync(IMapping mapping, IRequestMessage requestMessage, WireMockServerSettings settings)
{
ResponseMessage response;
if (_count % 2 == 0)
{
response = new ResponseMessage() { StatusCode = 200 };
SetBody(response, @"{ ""msg"": ""Hello from wiremock!"" }");
}
else
{
response = new ResponseMessage() { StatusCode = 500 };
SetBody(response, @"{ ""msg"": ""Hello some error from wiremock!"" }");
}

_count++;
(ResponseMessage, IMapping) tuple = (response, null);
return await Task.FromResult(tuple);
}


private void SetBody(ResponseMessage response, string body)
{
response.BodyDestination = BodyDestinationFormat.SameAsSource;
response.BodyData = new BodyData
{
Encoding = Encoding.UTF8,
DetectedBodyType = BodyType.String,
BodyAsString = body
};
}
}
}
57 changes: 0 additions & 57 deletions APITestingRunner.Unit.Tests/TestRunnerTests/DataComparisonTests.cs

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public void PopulateRequestBody_ShouldThrowExcpetion_becauseOfNoDataQueryResult(

Action action = () => TestRunner.PopulateRequestBody(config, null);

_ = action.Should().Throw<ArgumentException>().WithMessage("Value cannot be null. (Parameter 'dataQueryResult')");
_ = action.Should().Throw<ArgumentException>().WithMessage("Value cannot be null. (Parameter 'DataQueryResult')");
}

[TestMethod]
Expand Down
Loading