Add unit tests for AddFeedback operation, Token.IsValid

This commit is contained in:
Denis-Cosmin Nutiu 2021-07-11 16:26:01 +03:00
parent d83f9fbaa0
commit 9d6b36d9ee
18 changed files with 366 additions and 27 deletions

View file

@ -10,3 +10,8 @@ dotnet --version
``` ```
This is a side project and it's still work in progress, therefore the lack of documentation. The goal is to create a Web Application for managing Feedback. This is a side project and it's still work in progress, therefore the lack of documentation. The goal is to create a Web Application for managing Feedback.
## Architecture
TODO

View file

@ -5,9 +5,9 @@
/// </summary> /// </summary>
public interface IDatabaseSettings public interface IDatabaseSettings
{ {
public string FeedbackCollectionName { get; set; } public string FeedbacksCollectionName { get; set; }
public string TokensCollectionName { get; set; } public string TokensCollectionName { get; set; }
public string FeedbackReceiverCollectionName { get; set; } public string FeedbackReceiversCollectionName { get; set; }
public string ConnectionString { get; set; } public string ConnectionString { get; set; }
public string DatabaseName { get; set; } public string DatabaseName { get; set; }
} }

View file

@ -19,7 +19,7 @@ namespace Retroactiune.Core.Services
public FeedbackReceiversService(IMongoClient client, IDatabaseSettings settings) public FeedbackReceiversService(IMongoClient client, IDatabaseSettings settings)
{ {
var database = client.GetDatabase(settings.DatabaseName); var database = client.GetDatabase(settings.DatabaseName);
_collection = database.GetCollection<FeedbackReceiver>(settings.FeedbackReceiverCollectionName); _collection = database.GetCollection<FeedbackReceiver>(settings.FeedbackReceiversCollectionName);
} }
public async Task CreateManyAsync(IEnumerable<FeedbackReceiver> items) public async Task CreateManyAsync(IEnumerable<FeedbackReceiver> items)

View file

@ -13,12 +13,11 @@ namespace Retroactiune.Core.Services
public FeedbacksService(IMongoClient client, IDatabaseSettings settings) public FeedbacksService(IMongoClient client, IDatabaseSettings settings)
{ {
var database = client.GetDatabase(settings.DatabaseName); var database = client.GetDatabase(settings.DatabaseName);
_collection = database.GetCollection<Feedback>(settings.FeedbackCollectionName); _collection = database.GetCollection<Feedback>(settings.FeedbacksCollectionName);
} }
public async Task AddFeedbackAsync(Feedback feedback, FeedbackReceiver receiver) public async Task AddFeedbackAsync(Feedback feedback, FeedbackReceiver receiver)
{ {
// TODO: Unit test.
Guard.Against.Null(feedback, nameof(feedback)); Guard.Against.Null(feedback, nameof(feedback));
Guard.Against.Null(receiver, nameof(receiver)); Guard.Against.Null(receiver, nameof(receiver));

View file

@ -120,7 +120,7 @@ namespace Retroactiune.Core.Services
public async Task MarkTokenAsUsedAsync(Token token) public async Task MarkTokenAsUsedAsync(Token token)
{ {
// TODO: Unit test. Guard.Against.Null(token, nameof(token));
var filterBuilder = new FilterDefinitionBuilder<Token>(); var filterBuilder = new FilterDefinitionBuilder<Token>();
var updateBuilder = new UpdateDefinitionBuilder<Token>(); var updateBuilder = new UpdateDefinitionBuilder<Token>();
await _collection.UpdateOneAsync(filterBuilder.Eq(i => i.Id, token.Id), await _collection.UpdateOneAsync(filterBuilder.Eq(i => i.Id, token.Id),

View file

@ -8,9 +8,9 @@ namespace Retroactiune.Infrastructure
/// </summary> /// </summary>
public class DatabaseSettings : IDatabaseSettings public class DatabaseSettings : IDatabaseSettings
{ {
public string FeedbackCollectionName { get; set; } public string FeedbacksCollectionName { get; set; }
public string TokensCollectionName { get; set; } public string TokensCollectionName { get; set; }
public string FeedbackReceiverCollectionName { get; set; } public string FeedbackReceiversCollectionName { get; set; }
public string ConnectionString { get; set; } public string ConnectionString { get; set; }
public string DatabaseName { get; set; } public string DatabaseName { get; set; }
} }

View file

@ -156,7 +156,7 @@ namespace Retroactiune.IntegrationTests.Retroactiune.WebAPI.Controllers
var feedbackReceiver = new FeedbackReceiver var feedbackReceiver = new FeedbackReceiver
{ {
Id = ObjectId.GenerateNewId().ToString(), Id = ObjectId.GenerateNewId().ToString(),
Description = "blam", Description = "blame",
CreatedAt = DateTime.UtcNow, CreatedAt = DateTime.UtcNow,
Name = "test" Name = "test"
}; };
@ -406,5 +406,44 @@ namespace Retroactiune.IntegrationTests.Retroactiune.WebAPI.Controllers
Assert.Single(items); Assert.Single(items);
Assert.Equal(feedbackReceivers[1], items[0]); Assert.Equal(feedbackReceivers[1], items[0]);
} }
[Fact]
public async Task Test_AddFeedback_Happy()
{
// Setup
await _mongoDb.DropAsync();
var feedbackReceiver = new FeedbackReceiver();
var token = new Token
{
FeedbackReceiverId = feedbackReceiver.Id
};
await _mongoDb.FeedbackReceiverCollection.InsertOneAsync(feedbackReceiver);
await _mongoDb.TokensCollection.InsertOneAsync(token);
// Test
var feedback = new FeedbackInDto
{
TokenId = token.Id,
Description = "ok",
Rating = 4
};
var content = JsonSerializer.Serialize(feedback);
var response = await _client.PostAsync($"api/v1/feedback_receivers/{feedbackReceiver.Id}/feedbacks",
new StringContent(content, Encoding.UTF8, "application/json"));
// Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var feedbacksCursor = await _mongoDb.FeedbacksCollection.FindAsync(FilterDefinition<Feedback>.Empty);
var feedbacks = await feedbacksCursor.ToListAsync();
Assert.Equal("ok", feedbacks.ElementAt(0).Description);
Assert.Equal(4u, feedbacks.ElementAt(0).Rating);
Assert.Equal(feedbackReceiver.Id, feedbacks.ElementAt(0).FeedbackReceiverId);
var tokensCursor = await _mongoDb.TokensCollection.FindAsync(FilterDefinition<Token>.Empty);
var tokens = await tokensCursor.ToListAsync();
Assert.NotNull(tokens.ElementAt(0).TimeUsed);
}
} }
} }

View file

@ -15,10 +15,13 @@ namespace Retroactiune.IntegrationTests.Retroactiune.WebAPI.Fixtures
private IMongoDatabase Database { get; } private IMongoDatabase Database { get; }
public IMongoCollection<FeedbackReceiver> FeedbackReceiverCollection => public IMongoCollection<FeedbackReceiver> FeedbackReceiverCollection =>
Database.GetCollection<FeedbackReceiver>(_settings.FeedbackReceiverCollectionName); Database.GetCollection<FeedbackReceiver>(_settings.FeedbackReceiversCollectionName);
public IMongoCollection<Token> TokensCollection => public IMongoCollection<Token> TokensCollection =>
Database.GetCollection<Token>(_settings.TokensCollectionName); Database.GetCollection<Token>(_settings.TokensCollectionName);
public IMongoCollection<Feedback> FeedbacksCollection =>
Database.GetCollection<Feedback>(_settings.FeedbacksCollectionName);
public MongoDbFixture(IOptions<DatabaseSettings> options) public MongoDbFixture(IOptions<DatabaseSettings> options)
{ {
@ -32,8 +35,8 @@ namespace Retroactiune.IntegrationTests.Retroactiune.WebAPI.Fixtures
await Task.WhenAll( await Task.WhenAll(
new List<Task>() new List<Task>()
{ {
Database.DropCollectionAsync(_settings.FeedbackCollectionName), Database.DropCollectionAsync(_settings.FeedbacksCollectionName),
Database.DropCollectionAsync(_settings.FeedbackReceiverCollectionName), Database.DropCollectionAsync(_settings.FeedbackReceiversCollectionName),
Database.DropCollectionAsync(_settings.TokensCollectionName) Database.DropCollectionAsync(_settings.TokensCollectionName)
}); });
} }

View file

@ -0,0 +1,46 @@
using System;
using AutoFixture.Xunit2;
using Retroactiune.Core.Entities;
using Xunit;
namespace Retroactiune.Tests.Retroactiune.Core.Entities
{
public class TestToken
{
[Theory, AutoData]
public void Test_IsValid_Null(Token token)
{
Assert.Throws<ArgumentNullException>(() =>
{
token.IsValid(null);
});
}
[Theory, AutoData]
public void Test_IsValid_Expired(Token token, FeedbackReceiver feedbackReceiver)
{
token.FeedbackReceiverId = feedbackReceiver.Id;
token.ExpiryTime = new DateTime(1970, 01, 01);
token.TimeUsed = null;
Assert.False(token.IsValid(feedbackReceiver));
}
[Theory, AutoData]
public void Test_IsValid_Used(Token token, FeedbackReceiver feedbackReceiver)
{
token.FeedbackReceiverId = feedbackReceiver.Id;
token.ExpiryTime = DateTime.UtcNow.AddDays(10);
token.TimeUsed = DateTime.UtcNow;
Assert.False(token.IsValid(feedbackReceiver));
}
[Theory, AutoData]
public void Test_IsValid_Valid(Token token, FeedbackReceiver feedbackReceiver)
{
token.FeedbackReceiverId = feedbackReceiver.Id;
token.ExpiryTime = DateTime.UtcNow.AddDays(10);
token.TimeUsed = null;
Assert.True(token.IsValid(feedbackReceiver));
}
}
}

View file

@ -24,7 +24,7 @@ namespace Retroactiune.Tests.Retroactiune.Core.Services
var mongoCollectionMock = new Mock<IMongoCollection<FeedbackReceiver>>(); var mongoCollectionMock = new Mock<IMongoCollection<FeedbackReceiver>>();
mongoSettingsMock.SetupGet(i => i.DatabaseName).Returns("MyDB"); mongoSettingsMock.SetupGet(i => i.DatabaseName).Returns("MyDB");
mongoSettingsMock.SetupGet(i => i.FeedbackReceiverCollectionName).Returns("feedback_receiver"); mongoSettingsMock.SetupGet(i => i.FeedbackReceiversCollectionName).Returns("feedback_receiver");
mongoClientMock mongoClientMock
.Setup(stub => stub.GetDatabase(It.IsAny<string>(), It.IsAny<MongoDatabaseSettings>())) .Setup(stub => stub.GetDatabase(It.IsAny<string>(), It.IsAny<MongoDatabaseSettings>()))
@ -59,7 +59,7 @@ namespace Retroactiune.Tests.Retroactiune.Core.Services
var mongoCollectionMock = new Mock<IMongoCollection<FeedbackReceiver>>(); var mongoCollectionMock = new Mock<IMongoCollection<FeedbackReceiver>>();
mongoSettingsMock.SetupGet(i => i.DatabaseName).Returns("MyDB"); mongoSettingsMock.SetupGet(i => i.DatabaseName).Returns("MyDB");
mongoSettingsMock.SetupGet(i => i.FeedbackReceiverCollectionName).Returns("feedback_receiver"); mongoSettingsMock.SetupGet(i => i.FeedbackReceiversCollectionName).Returns("feedback_receiver");
mongoClientMock mongoClientMock
.Setup(i => i.GetDatabase(It.IsAny<string>(), It.IsAny<MongoDatabaseSettings>())) .Setup(i => i.GetDatabase(It.IsAny<string>(), It.IsAny<MongoDatabaseSettings>()))
@ -100,7 +100,7 @@ namespace Retroactiune.Tests.Retroactiune.Core.Services
var mongoCollectionMock = new Mock<IMongoCollection<FeedbackReceiver>>(); var mongoCollectionMock = new Mock<IMongoCollection<FeedbackReceiver>>();
mongoSettingsMock.SetupGet(i => i.DatabaseName).Returns("MyDB"); mongoSettingsMock.SetupGet(i => i.DatabaseName).Returns("MyDB");
mongoSettingsMock.SetupGet(i => i.FeedbackReceiverCollectionName).Returns("feedback_receiver"); mongoSettingsMock.SetupGet(i => i.FeedbackReceiversCollectionName).Returns("feedback_receiver");
mongoClientMock mongoClientMock
.Setup(i => i.GetDatabase(It.IsAny<string>(), It.IsAny<MongoDatabaseSettings>())) .Setup(i => i.GetDatabase(It.IsAny<string>(), It.IsAny<MongoDatabaseSettings>()))
@ -141,7 +141,7 @@ namespace Retroactiune.Tests.Retroactiune.Core.Services
var mongoCollectionMock = new Mock<IMongoCollection<FeedbackReceiver>>(); var mongoCollectionMock = new Mock<IMongoCollection<FeedbackReceiver>>();
mongoSettingsMock.SetupGet(i => i.DatabaseName).Returns("MyDB"); mongoSettingsMock.SetupGet(i => i.DatabaseName).Returns("MyDB");
mongoSettingsMock.SetupGet(i => i.FeedbackReceiverCollectionName).Returns("feedback_receiver"); mongoSettingsMock.SetupGet(i => i.FeedbackReceiversCollectionName).Returns("feedback_receiver");
mongoClientMock mongoClientMock
.Setup(stub => stub.GetDatabase(It.IsAny<string>(), It.IsAny<MongoDatabaseSettings>())) .Setup(stub => stub.GetDatabase(It.IsAny<string>(), It.IsAny<MongoDatabaseSettings>()))
@ -177,7 +177,7 @@ namespace Retroactiune.Tests.Retroactiune.Core.Services
var mongoCursorMock = new Mock<IAsyncCursor<FeedbackReceiver>>(); var mongoCursorMock = new Mock<IAsyncCursor<FeedbackReceiver>>();
mongoSettingsMock.SetupGet(i => i.DatabaseName).Returns("MyDB"); mongoSettingsMock.SetupGet(i => i.DatabaseName).Returns("MyDB");
mongoSettingsMock.SetupGet(i => i.FeedbackReceiverCollectionName).Returns("feedback_receiver"); mongoSettingsMock.SetupGet(i => i.FeedbackReceiversCollectionName).Returns("feedback_receiver");
mongoClientMock mongoClientMock
.Setup(stub => stub.GetDatabase(It.IsAny<string>(), It.IsAny<MongoDatabaseSettings>())) .Setup(stub => stub.GetDatabase(It.IsAny<string>(), It.IsAny<MongoDatabaseSettings>()))

View file

@ -0,0 +1,85 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using AutoFixture.Xunit2;
using MongoDB.Driver;
using Moq;
using Retroactiune.Core.Entities;
using Retroactiune.Core.Interfaces;
using Retroactiune.Core.Services;
using Xunit;
namespace Retroactiune.Tests.Retroactiune.Core.Services
{
public class TestFeedbacksService
{
[Fact]
public async Task Test_AddFeedbackAsync_NullGuards()
{
// Setup
var mongoDatabaseMock = new Mock<IMongoDatabase>();
var mongoClientMock = new Mock<IMongoClient>();
var mongoSettingsMock = new Mock<IDatabaseSettings>();
var mongoCollectionMock = new Mock<IMongoCollection<Feedback>>();
mongoSettingsMock.SetupGet(i => i.DatabaseName).Returns("MyDB");
mongoSettingsMock.SetupGet(i => i.FeedbacksCollectionName).Returns("feedbacks");
mongoClientMock
.Setup(stub => stub.GetDatabase(It.IsAny<string>(),
It.IsAny<MongoDatabaseSettings>()))
.Returns(mongoDatabaseMock.Object);
mongoDatabaseMock
.Setup(i => i.GetCollection<Feedback>(It.IsAny<string>(),
It.IsAny<MongoCollectionSettings>()))
.Returns(mongoCollectionMock.Object);
// Test & Assert
var service = new FeedbacksService(mongoClientMock.Object, mongoSettingsMock.Object);
await Assert.ThrowsAsync<ArgumentNullException>(async () =>
{
await service.AddFeedbackAsync(null, new FeedbackReceiver());
});
await Assert.ThrowsAsync<ArgumentNullException>(async () =>
{
await service.AddFeedbackAsync(new Feedback(), null);
});
}
[Theory, AutoData]
public async Task Test_AddFeedbackAsync_Ok(Feedback feedback, FeedbackReceiver feedbackReceiver)
{
// Setup
var mongoDatabaseMock = new Mock<IMongoDatabase>();
var mongoClientMock = new Mock<IMongoClient>();
var mongoSettingsMock = new Mock<IDatabaseSettings>();
var mongoCollectionMock = new Mock<IMongoCollection<Feedback>>();
mongoSettingsMock.SetupGet(i => i.DatabaseName).Returns("MyDB");
mongoSettingsMock.SetupGet(i => i.FeedbacksCollectionName).Returns("feedbacks");
mongoClientMock
.Setup(stub => stub.GetDatabase(It.IsAny<string>(),
It.IsAny<MongoDatabaseSettings>()))
.Returns(mongoDatabaseMock.Object);
mongoDatabaseMock
.Setup(i => i.GetCollection<Feedback>(It.IsAny<string>(),
It.IsAny<MongoCollectionSettings>()))
.Returns(mongoCollectionMock.Object);
// Test
var service = new FeedbacksService(mongoClientMock.Object, mongoSettingsMock.Object);
await service.AddFeedbackAsync(feedback, feedbackReceiver);
// Assert
feedback.FeedbackReceiverId = feedbackReceiver.Id;
mongoCollectionMock.Verify(
i => i.InsertOneAsync(
feedback,
It.IsAny<InsertOneOptions>(),
It.IsAny<CancellationToken>()));
}
}
}

View file

@ -2,6 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using AutoFixture.Xunit2;
using MongoDB.Driver; using MongoDB.Driver;
using Moq; using Moq;
using Retroactiune.Core.Entities; using Retroactiune.Core.Entities;
@ -255,6 +256,7 @@ namespace Retroactiune.Tests.Retroactiune.Core.Services
mongoCollectionMock.Setup(i => mongoCollectionMock.Setup(i =>
i.DeleteManyAsync(It.IsAny<FilterDefinition<Token>>(), It.IsAny<CancellationToken>())) i.DeleteManyAsync(It.IsAny<FilterDefinition<Token>>(), It.IsAny<CancellationToken>()))
.ThrowsAsync(new GenericServiceException("op failed")); .ThrowsAsync(new GenericServiceException("op failed"));
// Test // Test
var service = new TokensService(mongoClientMock.Object, mongoSettingsMock.Object); var service = new TokensService(mongoClientMock.Object, mongoSettingsMock.Object);
await Assert.ThrowsAsync<GenericServiceException>(async () => await Assert.ThrowsAsync<GenericServiceException>(async () =>
@ -269,5 +271,45 @@ namespace Retroactiune.Tests.Retroactiune.Core.Services
It.IsAny<FilterDefinition<Token>>(), It.IsAny<FilterDefinition<Token>>(),
It.IsAny<CancellationToken>()), Times.Once); It.IsAny<CancellationToken>()), Times.Once);
} }
[Theory, AutoData]
public async Task Test_MarkTokenAsUsedAsync(Token token)
{
// Setup
var mongoDatabaseMock = new Mock<IMongoDatabase>();
var mongoClientMock = new Mock<IMongoClient>();
var mongoSettingsMock = new Mock<IDatabaseSettings>();
var mongoCollectionMock = new Mock<IMongoCollection<Token>>();
mongoSettingsMock.SetupGet(i => i.DatabaseName).Returns("MyDB");
mongoSettingsMock.SetupGet(i => i.TokensCollectionName).Returns("tokens");
mongoClientMock
.Setup(stub => stub.GetDatabase(It.IsAny<string>(),
It.IsAny<MongoDatabaseSettings>()))
.Returns(mongoDatabaseMock.Object);
mongoDatabaseMock
.Setup(i => i.GetCollection<Token>(It.IsAny<string>(),
It.IsAny<MongoCollectionSettings>()))
.Returns(mongoCollectionMock.Object);
// Test
var tokensService = new TokensService(mongoClientMock.Object, mongoSettingsMock.Object);
await tokensService.MarkTokenAsUsedAsync(token);
// Assert
await Assert.ThrowsAsync<ArgumentNullException>(async () =>
{
await tokensService.MarkTokenAsUsedAsync(null);
});
mongoCollectionMock.Verify(i =>
i.UpdateOneAsync(
It.IsAny<FilterDefinition<Token>>(),
It.IsAny<UpdateDefinition<Token>>(),
It.IsAny<UpdateOptions>(),
It.IsAny<CancellationToken>()));
}
} }
} }

View file

@ -24,8 +24,4 @@
<ProjectReference Include="..\Retroactiune.WebAPI\Retroactiune.WebAPI.csproj" /> <ProjectReference Include="..\Retroactiune.WebAPI\Retroactiune.WebAPI.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Folder Include="Retroactiune.Core" />
</ItemGroup>
</Project> </Project>

View file

@ -1,4 +1,5 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using AutoFixture.Xunit2; using AutoFixture.Xunit2;
@ -200,5 +201,123 @@ namespace Retroactiune.Tests.Retroactiune.WebAPI.Controllers
Assert.IsType<OkObjectResult>(result); Assert.IsType<OkObjectResult>(result);
mockService.Verify(s => s.FindAsync(filterArr, offset, limit), Times.Once); mockService.Verify(s => s.FindAsync(filterArr, offset, limit), Times.Once);
} }
// Invalid token
// happy
[Theory, AutoData]
public async Task AddFeedback_No_FeedbackReceiver(FeedbackInDto requestBody)
{
// Arrange
var mapper = TestUtils.GetMapper();
var feedbackReceiversService = new Mock<IFeedbackReceiversService>();
var tokensService = new Mock<ITokensService>();
var feedbacksService = new Mock<IFeedbacksService>();
var logger = new Mock<ILogger<FeedbackReceiversController>>();
// Test
var controller = new FeedbackReceiversController(feedbackReceiversService.Object, tokensService.Object,
feedbacksService.Object, mapper, null,
logger.Object);
var result = await controller.AddFeedback("guid-test", requestBody);
// Assert
Assert.IsType<BadRequestObjectResult>(result);
}
[Theory, AutoData]
public async Task AddFeedback_No_Token(FeedbackInDto requestBody)
{
// Arrange
var mapper = TestUtils.GetMapper();
var feedbackReceiversService = new Mock<IFeedbackReceiversService>();
var tokensService = new Mock<ITokensService>();
var feedbacksService = new Mock<IFeedbacksService>();
var logger = new Mock<ILogger<FeedbackReceiversController>>();
feedbackReceiversService
.Setup(i => i.FindAsync(It.IsAny<IEnumerable<string>>(), It.IsAny<int?>(), It.IsAny<int?>()))
.ReturnsAsync(new[] {new FeedbackReceiver()});
// Test
var controller = new FeedbackReceiversController(feedbackReceiversService.Object, tokensService.Object,
feedbacksService.Object, mapper, null,
logger.Object);
var result = await controller.AddFeedback("guid-test", requestBody);
// Assert
Assert.IsType<BadRequestObjectResult>(result);
}
[Theory, AutoData]
public async Task AddFeedback_Invalid_Token(FeedbackInDto requestBody)
{
// Arrange
var mapper = TestUtils.GetMapper();
var feedbackReceiversService = new Mock<IFeedbackReceiversService>();
var tokensService = new Mock<ITokensService>();
var feedbacksService = new Mock<IFeedbacksService>();
var logger = new Mock<ILogger<FeedbackReceiversController>>();
feedbackReceiversService
.Setup(i => i.FindAsync(It.IsAny<IEnumerable<string>>(), It.IsAny<int?>(), It.IsAny<int?>()))
.ReturnsAsync(new[] {new FeedbackReceiver()});
tokensService.Setup(i => i.FindAsync(It.IsAny<TokenListFilters>()))
.ReturnsAsync(new[]
{
new Token
{
FeedbackReceiverId = "batman",
TimeUsed = DateTime.UtcNow
}
});
// Test
var controller = new FeedbackReceiversController(feedbackReceiversService.Object, tokensService.Object,
feedbacksService.Object, mapper, null,
logger.Object);
var result = await controller.AddFeedback("guid-test", requestBody);
// Assert
Assert.IsType<BadRequestObjectResult>(result);
}
[Theory, AutoData]
public async Task AddFeedback_Happy(FeedbackInDto requestBody)
{
// Arrange
var mapper = TestUtils.GetMapper();
var feedbackReceiversService = new Mock<IFeedbackReceiversService>();
var tokensService = new Mock<ITokensService>();
var feedbacksService = new Mock<IFeedbacksService>();
var logger = new Mock<ILogger<FeedbackReceiversController>>();
feedbackReceiversService
.Setup(i => i.FindAsync(It.IsAny<IEnumerable<string>>(), It.IsAny<int?>(), It.IsAny<int?>()))
.ReturnsAsync(new[] {new FeedbackReceiver
{
Id = "batman"
}});
tokensService.Setup(i => i.FindAsync(It.IsAny<TokenListFilters>()))
.ReturnsAsync(new[]
{
new Token
{
FeedbackReceiverId = "batman",
TimeUsed = null
}
});
// Test
var controller = new FeedbackReceiversController(feedbackReceiversService.Object, tokensService.Object,
feedbacksService.Object, mapper, null, logger.Object);
var result = await controller.AddFeedback("guid-test", requestBody);
// Assert
Assert.IsType<OkResult>(result);
}
} }
} }

View file

@ -181,7 +181,6 @@ namespace Retroactiune.Controllers
[ProducesResponseType(typeof(BasicResponse), StatusCodes.Status400BadRequest)] [ProducesResponseType(typeof(BasicResponse), StatusCodes.Status400BadRequest)]
public async Task<IActionResult> AddFeedback(string guid, [FromBody] FeedbackInDto feedbackInDto) public async Task<IActionResult> AddFeedback(string guid, [FromBody] FeedbackInDto feedbackInDto)
{ {
// TODO: Unit & integration test.
var receivers = await _feedbackReceiversService.FindAsync(new[] {guid}, limit: 1); var receivers = await _feedbackReceiversService.FindAsync(new[] {guid}, limit: 1);
var tokenEnum = await _tokensService.FindAsync(new TokenListFilters var tokenEnum = await _tokensService.FindAsync(new TokenListFilters
{ {
@ -219,5 +218,7 @@ namespace Retroactiune.Controllers
_feedbacksService.AddFeedbackAsync(feedback, feedbackReceivers[0])); _feedbacksService.AddFeedbackAsync(feedback, feedbackReceivers[0]));
return Ok(); return Ok();
} }
// TODO: Implement get for feedbacks.
} }
} }

View file

@ -18,6 +18,10 @@ namespace Retroactiune
[ExcludeFromCodeCoverage] [ExcludeFromCodeCoverage]
public class Startup public class Startup
{ {
// TODO: Support for Sentry.
// TODO: Support for Prometheus.
// TODO: External auth provider.
// TODO: UI?
public Startup(IConfiguration configuration) public Startup(IConfiguration configuration)
{ {
Configuration = configuration; Configuration = configuration;

View file

@ -1,8 +1,8 @@
{ {
"DatabaseSettings": { "DatabaseSettings": {
"FeedbackCollectionName": "feedbacks", "FeedbacksCollectionName": "feedbacks",
"TokensCollectionName": "tokens", "TokensCollectionName": "tokens",
"FeedbackReceiverCollectionName": "feedback_receivers", "FeedbackReceiversCollectionName": "feedback_receivers",
"ConnectionString": "mongodb://localhost:27017", "ConnectionString": "mongodb://localhost:27017",
"DatabaseName": "RetroactiuneTesting" "DatabaseName": "RetroactiuneTesting"
} }

View file

@ -1,8 +1,8 @@
{ {
"DatabaseSettings": { "DatabaseSettings": {
"FeedbackCollectionName": "feedbacks", "FeedbacksCollectionName": "feedbacks",
"TokensCollectionName": "tokens", "TokensCollectionName": "tokens",
"FeedbackReceiverCollectionName": "feedback_receivers", "FeedbackReceiversCollectionName": "feedback_receivers",
"ConnectionString": "mongodb://localhost:27017", "ConnectionString": "mongodb://localhost:27017",
"DatabaseName": "Retroactiune" "DatabaseName": "Retroactiune"
}, },