Skip to content

Commit

Permalink
Integratin tests (SQS + MySQL)
Browse files Browse the repository at this point in the history
  • Loading branch information
fabiogouw committed Aug 29, 2021
1 parent dfe0c0b commit f728f41
Show file tree
Hide file tree
Showing 22 changed files with 494 additions and 107 deletions.
129 changes: 121 additions & 8 deletions SuperSurvey.Adapters.Tests/MySQLPollRepositoryTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,63 @@
using DotNet.Testcontainers.Containers;
using FluentAssertions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using SuperSurvey.Domain;
using System.Text;

namespace SuperSurvey.Adapters.Tests;
[TestClass]
public class MySQLPollRepositoryTests
{
private readonly string CREATE_TABLE_SCRIPT =
private readonly string CREATE_TABLE_SCRIPT =
@"USE db;
CREATE TABLE `Polls` (
`Id` INT NOT NULL,
`Name` VARCHAR(255) NOT NULL,
`Expires` DATETIME NOT NULL,
`ExpiresAt` DATETIME NOT NULL,
`UpdatedAt` DATETIME NOT NULL,
KEY `Ix_Expires` (`Expires`) USING BTREE,
KEY `Ix_Expires` (`ExpiresAt`) USING BTREE,
PRIMARY KEY(`Id`)
);";
);
CREATE TABLE `Options` (
`Id` INT NOT NULL,
`PollId` INT NOT NULL,
`Description` VARCHAR(255) NOT NULL,
`VoteCount` INT NOT NULL,
`UpdatedAt` DATETIME NOT NULL,
PRIMARY KEY(`Id`),
FOREIGN KEY (PollId) REFERENCES Polls(Id)
);
";

[TestMethod]
[TestCategory("Integration")]
public async Task Should_ReturnActivePolls_When_RepositoryIsQueriedByExpirationDate()
{
var testcontainersBuilder = new TestcontainersBuilder<MySqlTestcontainer>()
.WithDatabase(new MySqlTestcontainerConfiguration
{
Database = "db",
Username = "davidbowie",
Password = "secret",
})
;

await using (var testcontainer = testcontainersBuilder.Build())
{
await testcontainer.StartAsync();
await CreateTables(testcontainer);
await ExecuteScript(testcontainer, @"
INSERT INTO Polls (Id, Name, ExpiresAt, UpdatedAt) VALUES (1, 'ABC', '2021-08-21T14:56', '2021-08-23T09:03');
INSERT INTO Polls (Id, Name, ExpiresAt, UpdatedAt) VALUES (2, 'ABC', '2021-08-23T14:56', '2021-08-23T09:03');
INSERT INTO Polls (Id, Name, ExpiresAt, UpdatedAt) VALUES (3, 'ABC', '2021-08-25T14:56', '2021-08-23T09:03');"
);

var sut = new MySQLPollRepository(testcontainer.ConnectionString);
var polls = await sut.GetAllActive(DateTime.Parse("2021-08-23T09:03"));

polls.Count.Should().Be(2);
}
}

[TestMethod]
[TestCategory("Integration")]
Expand All @@ -36,17 +77,89 @@ public async Task Should_ReturnExistingData_When_RepositoryIsQueriedById()
await using (var testcontainer = testcontainersBuilder.Build())
{
await testcontainer.StartAsync();
await testcontainer.CopyFileAsync("structure.sql", Encoding.ASCII.GetBytes(CREATE_TABLE_SCRIPT));
await testcontainer.CopyFileAsync("data.sql",
Encoding.ASCII.GetBytes("INSERT INTO Polls (Id, Name, Expires, UpdatedAt) VALUES (123, 'Teste ABC', '1981-06-08', '1981-06-08');"));
await testcontainer.ExecAsync(new []{ "/bin/sh", "-c", "mysql -udavidbowie -psecret db < /structure.sql", "" });
await CreateTables(testcontainer);
await ExecuteScript(testcontainer,
"INSERT INTO Polls (Id, Name, ExpiresAt, UpdatedAt) VALUES (123, 'ABC', '2021-08-25T14:56', '2021-08-23T09:03');"
);
await testcontainer.ExecAsync(new []{ "/bin/sh", "-c", "mysql -udavidbowie -psecret db < /data.sql", "" });

var sut = new MySQLPollRepository(testcontainer.ConnectionString);
var poll = await sut.GetById(123);

poll.Should().NotBeNull();
poll.Id.Should().Be(123);
poll.Name.Should().Be("ABC");
poll.ExpiresAt.Should().Be(DateTime.Parse("2021-08-25T14:56"));
poll.UpdatedAt.Should().Be(DateTime.Parse("2021-08-23T09:03"));
}
}

[TestMethod]
[TestCategory("Integration")]
public async Task Should_SavePollResults_When_DataIsUpdated()
{
var testcontainersBuilder = new TestcontainersBuilder<MySqlTestcontainer>()
.WithDatabase(new MySqlTestcontainerConfiguration
{
Database = "db",
Username = "davidbowie",
Password = "secret",
})
;

await using (var testcontainer = testcontainersBuilder.Build())
{
await testcontainer.StartAsync();
await CreateTables(testcontainer);
await ExecuteScript(testcontainer, @"
INSERT INTO Polls (Id, Name, ExpiresAt, UpdatedAt) VALUES (123, 'ABC', '2021-08-25T14:56', '2021-08-23T09:03');
INSERT INTO Options (Id, PollId, Description, VoteCount, UpdatedAt) VALUES (1, 123, 'ABC Option 1', 10, '2021-08-23T09:03');
INSERT INTO Options (Id, PollId, Description, VoteCount, UpdatedAt) VALUES (2, 123, 'ABC Option 2', 13, '2021-08-23T09:03');
");
await testcontainer.ExecAsync(new[] { "/bin/sh", "-c", "mysql -udavidbowie -psecret db < /data.sql", "" });

var poll = new Poll.Builder()
.WithId(123)
.WithName("New ABC")
.WithExpiresAt(DateTime.Parse("2021-08-25T14:56"))
.WithUpdatedAt(DateTime.Parse("2021-08-23T09:03"))
.WithOption(new Option.Builder()
.WithId(2)
.WithDescription("New ABC Option 2")
.WithVoteCount(20)
.WithUpdatedAt(DateTime.Parse("2021-08-23T09:03"))
.Build())
.WithOption(new Option.Builder()
.WithId(3)
.WithDescription("New ABC Option 3")
.WithVoteCount(10)
.WithUpdatedAt(DateTime.Parse("2021-08-23T09:03"))
.Build())
.Build();

var sut = new MySQLPollRepository(testcontainer.ConnectionString);

poll = await sut.Save(poll);

poll.Should().NotBeNull();
poll.Id.Should().Be(123);
poll.Name.Should().Be("New ABC");
poll.UpdatedAt.Should().NotBe(DateTime.Parse("2021-08-23T09:03"));
poll.Options.Count.Should().Be(2);
poll.Options.Single(o => o.Id == 2).Description.Should().Be("New ABC Option 2");
}
}

private async Task CreateTables(MySqlTestcontainer testcontainer)
{
await testcontainer.CopyFileAsync("structure.sql", Encoding.ASCII.GetBytes(CREATE_TABLE_SCRIPT));
await testcontainer.ExecAsync(new[] { "/bin/sh", "-c", "mysql -udavidbowie -psecret db < /structure.sql", "" });
}

private async Task ExecuteScript(MySqlTestcontainer testcontainer, string scriptContent)
{
string fileName = Guid.NewGuid().ToString();
await testcontainer.CopyFileAsync($"{ fileName }.sql", Encoding.ASCII.GetBytes(scriptContent));
await testcontainer.ExecAsync(new[] { "/bin/sh", "-c", $"mysql -udavidbowie -psecret db < /{ fileName }.sql", "" });
}
}
55 changes: 55 additions & 0 deletions SuperSurvey.Adapters.Tests/SQSVoteRepositoryTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
using Amazon.SQS;
using DotNet.Testcontainers.Builders;
using DotNet.Testcontainers.Containers;
using FluentAssertions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using SuperSurvey.UseCases.Ports.In;
using System.Text.Json;

namespace SuperSurvey.Adapters.Tests
{
[TestClass]
public class SQSVoteRepositoryTests
{
[TestMethod]
[TestCategory("Integration")]
public async Task Should_PostMessage_When_VoteCommandIsSaved()
{
int randomPort = Random.Shared.Next(49152, 65535);
var testcontainersBuilder = new TestcontainersBuilder<TestcontainersContainer>()
.WithImage("localstack/localstack:latest")
.WithEnvironment("SERVICES", "sqs")
.WithEnvironment("EDGE_PORT", "4566")
.WithPortBinding(randomPort, 4566)
.WithWaitStrategy(Wait.ForUnixContainer().UntilPortIsAvailable(4566))
;

await using (var testcontainer = testcontainersBuilder.Build())
{
string queueName = "my-queue";
await testcontainer.StartAsync();
var client = new AmazonSQSClient("test", "test", new AmazonSQSConfig()
{
ServiceURL = $"http://localhost:{ randomPort }"
});
await client.CreateQueueAsync(queueName);
var sut = new SQSVoteRepository(client, queueName);

var voteCommand = new VoteCommand()
{
PollId = 1,
SelectedOption = 999,
UserId = 2,
CreatedAt = DateTime.Now
};
await sut.Save(voteCommand);

string queueUrl = (await client.GetQueueUrlAsync(queueName)).QueueUrl;
var result = await client.ReceiveMessageAsync(queueUrl);
result.Messages.Count.Should().Be(1);
var message = result.Messages[0];
message.Body.Should().Be(JsonSerializer.Serialize(voteCommand));
}
}
}
}
13 changes: 7 additions & 6 deletions SuperSurvey.Adapters.Tests/VoteCounterHandlerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@ public class VoteCounterHandlerTests
[TestCategory("Integration")]
public async Task Should_ReadMessageFromQueue_When_MessageIsAvailable()
{
int randomPort = Random.Shared.Next(49152, 65535);
var testcontainersBuilder = new TestcontainersBuilder<TestcontainersContainer>()
.WithImage("localstack/localstack:latest")
.WithEnvironment("SERVICES", "sqs")
.WithEnvironment("EDGE_PORT", "4566")
.WithPortBinding(4566, 4566)
.WithPortBinding(randomPort, 4566)
.WithWaitStrategy(Wait.ForUnixContainer().UntilPortIsAvailable(4566))
;

Expand All @@ -30,20 +31,20 @@ public async Task Should_ReadMessageFromQueue_When_MessageIsAvailable()
await testcontainer.StartAsync();
var client = new AmazonSQSClient("test", "test", new AmazonSQSConfig()
{
ServiceURL = $"http://localhost:4566"
ServiceURL = $"http://localhost:{ randomPort }"
});
await client.CreateQueueAsync(queueName);
string queueUrl = (await client.GetQueueUrlAsync(queueName)).QueueUrl;
await client.SendMessageAsync(queueUrl, "test");

var useCaseMock = new Mock<CountVotesUseCase>();

var sut = new VoteCounterHandler(client, useCaseMock.Object, queueUrl);
var sut = new SQSVoteCounterHandler(client, useCaseMock.Object, queueUrl);

await sut.Execute();

var currentMessages = await client.ReceiveMessageAsync(queueUrl);
currentMessages.Messages.Count.Should().Be(0);
var result = await client.ReceiveMessageAsync(queueUrl);
result.Messages.Count.Should().Be(0);
}
}
}
Expand Down
Loading

0 comments on commit f728f41

Please sign in to comment.