Implement add feedback operation in FeedbackReceiversController.cs.
This commit is contained in:
parent
eca110d669
commit
398f1c7e2f
20 changed files with 214 additions and 102 deletions
|
@ -10,28 +10,23 @@ namespace Retroactiune.Core.Entities
|
|||
/// </summary>
|
||||
public class Feedback
|
||||
{
|
||||
private uint _rating;
|
||||
|
||||
public Feedback()
|
||||
{
|
||||
Id = ObjectId.GenerateNewId().ToString();
|
||||
CreatedAt = DateTime.UtcNow;
|
||||
}
|
||||
|
||||
[BsonId, JsonPropertyName("id")]
|
||||
[BsonRepresentation(BsonType.ObjectId)]
|
||||
public string Id { get; set; }
|
||||
|
||||
[JsonPropertyName("feedback_receiver_id")]
|
||||
[BsonRepresentation(BsonType.ObjectId)]
|
||||
public string FeedbackReceiverId { get; set; }
|
||||
|
||||
[JsonPropertyName("rating")]
|
||||
public uint Rating
|
||||
{
|
||||
get => _rating;
|
||||
set
|
||||
{
|
||||
if (value <= 5)
|
||||
{
|
||||
_rating = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ArgumentException();
|
||||
}
|
||||
}
|
||||
}
|
||||
public uint Rating { get; set; }
|
||||
|
||||
[JsonPropertyName("description")] public string Description { get; set; }
|
||||
|
||||
|
|
|
@ -11,6 +11,12 @@ namespace Retroactiune.Core.Entities
|
|||
/// </summary>
|
||||
public class FeedbackReceiver
|
||||
{
|
||||
public FeedbackReceiver()
|
||||
{
|
||||
Id = ObjectId.GenerateNewId().ToString();
|
||||
CreatedAt = DateTime.UtcNow;
|
||||
}
|
||||
|
||||
[BsonId, JsonPropertyName("id")]
|
||||
[BsonRepresentation(BsonType.ObjectId)]
|
||||
public string Id { get; set; }
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text.Json.Serialization;
|
||||
using Ardalis.GuardClauses;
|
||||
using MongoDB.Bson;
|
||||
using MongoDB.Bson.Serialization.Attributes;
|
||||
|
||||
|
@ -12,6 +13,13 @@ namespace Retroactiune.Core.Entities
|
|||
/// </summary>
|
||||
public class Token
|
||||
{
|
||||
|
||||
public Token()
|
||||
{
|
||||
Id = ObjectId.GenerateNewId().ToString();
|
||||
CreatedAt = DateTime.UtcNow;
|
||||
}
|
||||
|
||||
[BsonId, JsonPropertyName("id")]
|
||||
[BsonRepresentation(BsonType.ObjectId)]
|
||||
public string Id { get; set; }
|
||||
|
@ -41,5 +49,14 @@ namespace Retroactiune.Core.Entities
|
|||
{
|
||||
return RuntimeHelpers.GetHashCode(this);
|
||||
}
|
||||
|
||||
public bool IsValid(FeedbackReceiver feedbackReceiver)
|
||||
{
|
||||
Guard.Against.Null(feedbackReceiver, nameof(feedbackReceiver));
|
||||
var hasExpired = ExpiryTime != null && ExpiryTime <= DateTime.UtcNow;
|
||||
var differentFeedbackReceiver = !FeedbackReceiverId.Equals(feedbackReceiver.Id);
|
||||
var isUsed = TimeUsed != null;
|
||||
return !(hasExpired || differentFeedbackReceiver || isUsed);
|
||||
}
|
||||
}
|
||||
}
|
17
Retroactiune.Core/Interfaces/IFeedbacksService.cs
Normal file
17
Retroactiune.Core/Interfaces/IFeedbacksService.cs
Normal file
|
@ -0,0 +1,17 @@
|
|||
using System.Threading.Tasks;
|
||||
using Retroactiune.Core.Entities;
|
||||
|
||||
namespace Retroactiune.Core.Interfaces
|
||||
{
|
||||
public interface IFeedbacksService
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Adds Feedback to a FeedbackReceiver.
|
||||
/// </summary>
|
||||
/// <param name="feedback">The feedback.</param>
|
||||
/// <param name="receiver">The feedback receiver.</param>
|
||||
/// <returns></returns>
|
||||
public Task AddFeedbackAsync(Feedback feedback, FeedbackReceiver receiver);
|
||||
}
|
||||
}
|
|
@ -23,14 +23,14 @@ namespace Retroactiune.Core.Interfaces
|
|||
/// </summary>
|
||||
/// <param name="tokenIds">A list of tokens to delete.</param>
|
||||
/// <returns>The result of the delete operation.</returns>
|
||||
public Task DeleteTokens(IEnumerable<string> tokenIds);
|
||||
public Task DeleteTokensAsync(IEnumerable<string> tokenIds);
|
||||
|
||||
/// <summary>
|
||||
/// List and filters tokens.
|
||||
/// Finds and filters tokens.
|
||||
/// </summary>
|
||||
/// <param name="filters">Filters object for filtering results.</param>
|
||||
/// <returns>A list of tokens matching the filters.</returns>
|
||||
public Task<IEnumerable<Token>> ListTokens(TokenListFilters filters);
|
||||
public Task<IEnumerable<Token>> FindAsync(TokenListFilters filters);
|
||||
|
||||
/// <summary>
|
||||
/// Deletes tokens, by their associated FeedbackReceiverId.
|
||||
|
@ -38,5 +38,11 @@ namespace Retroactiune.Core.Interfaces
|
|||
/// <param name="feedbackReceiverIds">A list of FeedbackReceiverIDs.</param>
|
||||
/// <returns>The result of the delete operation.</returns>
|
||||
public Task DeleteManyByFeedbackReceiverIdAsync(IEnumerable<string> feedbackReceiverIds);
|
||||
|
||||
/// <summary>
|
||||
/// Marks the token as being used.
|
||||
/// </summary>
|
||||
/// <param name="token">The token.</param>
|
||||
public Task MarkTokenAsUsedAsync(Token token);
|
||||
}
|
||||
}
|
|
@ -5,6 +5,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Ardalis.GuardClauses" Version="3.2.0" />
|
||||
<PackageReference Include="MongoDB.Driver" Version="2.12.3" />
|
||||
</ItemGroup>
|
||||
|
||||
|
|
29
Retroactiune.Core/Services/FeedbacksService.cs
Normal file
29
Retroactiune.Core/Services/FeedbacksService.cs
Normal file
|
@ -0,0 +1,29 @@
|
|||
using System.Threading.Tasks;
|
||||
using Ardalis.GuardClauses;
|
||||
using MongoDB.Driver;
|
||||
using Retroactiune.Core.Entities;
|
||||
using Retroactiune.Core.Interfaces;
|
||||
|
||||
namespace Retroactiune.Core.Services
|
||||
{
|
||||
public class FeedbacksService : IFeedbacksService
|
||||
{
|
||||
private readonly IMongoCollection<Feedback> _collection;
|
||||
|
||||
public FeedbacksService(IMongoClient client, IDatabaseSettings settings)
|
||||
{
|
||||
var database = client.GetDatabase(settings.DatabaseName);
|
||||
_collection = database.GetCollection<Feedback>(settings.FeedbackCollectionName);
|
||||
}
|
||||
|
||||
public async Task AddFeedbackAsync(Feedback feedback, FeedbackReceiver receiver)
|
||||
{
|
||||
// TODO: Unit test.
|
||||
Guard.Against.Null(feedback, nameof(feedback));
|
||||
Guard.Against.Null(receiver, nameof(receiver));
|
||||
|
||||
feedback.FeedbackReceiverId = receiver.Id;
|
||||
await _collection.InsertOneAsync(feedback);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Ardalis.GuardClauses;
|
||||
using MongoDB.Driver;
|
||||
using Retroactiune.Core.Entities;
|
||||
using Retroactiune.Core.Interfaces;
|
||||
|
@ -21,10 +22,7 @@ namespace Retroactiune.Core.Services
|
|||
public async Task GenerateTokensAsync(int numberOfTokens, string feedbackReceiverGuid,
|
||||
DateTime? expiryTime = null)
|
||||
{
|
||||
if (numberOfTokens <= 0)
|
||||
{
|
||||
throw new ArgumentException("numberOfTokens must be positive");
|
||||
}
|
||||
Guard.Against.Negative(numberOfTokens, nameof(numberOfTokens));
|
||||
|
||||
var token = new List<Token>();
|
||||
for (var i = 0; i < numberOfTokens; i++)
|
||||
|
@ -41,7 +39,7 @@ namespace Retroactiune.Core.Services
|
|||
await _collection.InsertManyAsync(token);
|
||||
}
|
||||
|
||||
public async Task DeleteTokens(IEnumerable<string> tokenIds)
|
||||
public async Task DeleteTokensAsync(IEnumerable<string> tokenIds)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -54,7 +52,7 @@ namespace Retroactiune.Core.Services
|
|||
}
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<Token>> ListTokens(TokenListFilters filters)
|
||||
public async Task<IEnumerable<Token>> FindAsync(TokenListFilters filters)
|
||||
{
|
||||
var filterBuilder = new FilterDefinitionBuilder<Token>();
|
||||
var activeFilters = new List<FilterDefinition<Token>>();
|
||||
|
@ -119,5 +117,14 @@ namespace Retroactiune.Core.Services
|
|||
throw new GenericServiceException($"Operation failed: {e.Message} {e.StackTrace}");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task MarkTokenAsUsedAsync(Token token)
|
||||
{
|
||||
// TODO: Unit test.
|
||||
var filterBuilder = new FilterDefinitionBuilder<Token>();
|
||||
var updateBuilder = new UpdateDefinitionBuilder<Token>();
|
||||
await _collection.UpdateOneAsync(filterBuilder.Eq(i => i.Id, token.Id),
|
||||
updateBuilder.Set(i => i.TimeUsed, DateTime.UtcNow));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -68,16 +68,8 @@ namespace Retroactiune.Tests.Retroactiune.Core.Services
|
|||
await service.GenerateTokensAsync(3, "Hello", expiryTime);
|
||||
|
||||
// Assert
|
||||
var item = new Token
|
||||
{
|
||||
Id = null,
|
||||
ExpiryTime = expiryTime,
|
||||
TimeUsed = null,
|
||||
FeedbackReceiverId = "Hello",
|
||||
CreatedAt = expiryTime
|
||||
};
|
||||
mongoCollectionMock.Verify(
|
||||
i => i.InsertManyAsync(new[] {item, item, item},
|
||||
i => i.InsertManyAsync(It.IsAny<IEnumerable<Token>>(),
|
||||
It.IsAny<InsertManyOptions>(),
|
||||
It.IsAny<CancellationToken>()), Times.Once);
|
||||
}
|
||||
|
@ -106,7 +98,7 @@ namespace Retroactiune.Tests.Retroactiune.Core.Services
|
|||
|
||||
// Test
|
||||
var service = new TokensService(mongoClientMock.Object, mongoSettingsMock.Object);
|
||||
await service.DeleteTokens(new[] {"test_id"});
|
||||
await service.DeleteTokensAsync(new[] {"test_id"});
|
||||
|
||||
// Assert
|
||||
mongoCollectionMock.Verify(
|
||||
|
@ -145,7 +137,7 @@ namespace Retroactiune.Tests.Retroactiune.Core.Services
|
|||
|
||||
// Test
|
||||
var service = new TokensService(mongoClientMock.Object, mongoSettingsMock.Object);
|
||||
var result = await service.ListTokens(new TokenListFilters());
|
||||
var result = await service.FindAsync(new TokenListFilters());
|
||||
|
||||
// Assert
|
||||
Assert.IsType<List<Token>>(result);
|
||||
|
@ -185,7 +177,7 @@ namespace Retroactiune.Tests.Retroactiune.Core.Services
|
|||
|
||||
// Test
|
||||
var service = new TokensService(mongoClientMock.Object, mongoSettingsMock.Object);
|
||||
var result = await service.ListTokens(new TokenListFilters
|
||||
var result = await service.FindAsync(new TokenListFilters
|
||||
{
|
||||
Ids = new[] {"a", "b"},
|
||||
FeedbackReceiverId = "abc",
|
||||
|
|
|
@ -23,10 +23,12 @@ namespace Retroactiune.Tests.Retroactiune.WebAPI.Controllers
|
|||
var mapper = TestUtils.GetMapper();
|
||||
var mockService = new Mock<IFeedbackReceiversService>();
|
||||
var tokensService = new Mock<ITokensService>();
|
||||
var feedbacksService = new Mock<IFeedbacksService>();
|
||||
var logger = new Mock<ILogger<FeedbackReceiversController>>();
|
||||
|
||||
// Test
|
||||
var controller = new FeedbackReceiversController(mockService.Object, tokensService.Object, mapper, null,
|
||||
var controller = new FeedbackReceiversController(mockService.Object, tokensService.Object,
|
||||
feedbacksService.Object, mapper, null,
|
||||
logger.Object);
|
||||
var result = await controller.Post(new List<FeedbackReceiverInDto>());
|
||||
|
||||
|
@ -42,10 +44,12 @@ namespace Retroactiune.Tests.Retroactiune.WebAPI.Controllers
|
|||
var mapper = TestUtils.GetMapper();
|
||||
var mockService = new Mock<IFeedbackReceiversService>();
|
||||
var tokensService = new Mock<ITokensService>();
|
||||
var feedbacksService = new Mock<IFeedbacksService>();
|
||||
var logger = new Mock<ILogger<FeedbackReceiversController>>();
|
||||
|
||||
// Test
|
||||
var controller = new FeedbackReceiversController(mockService.Object, tokensService.Object, mapper, null,
|
||||
var controller = new FeedbackReceiversController(mockService.Object, tokensService.Object,
|
||||
feedbacksService.Object, mapper, null,
|
||||
logger.Object);
|
||||
var result = await controller.Post(items);
|
||||
|
||||
|
@ -61,10 +65,12 @@ namespace Retroactiune.Tests.Retroactiune.WebAPI.Controllers
|
|||
var mapper = TestUtils.GetMapper();
|
||||
var mockService = new Mock<IFeedbackReceiversService>();
|
||||
var tokensService = new Mock<ITokensService>();
|
||||
var feedbacksService = new Mock<IFeedbacksService>();
|
||||
var logger = new Mock<ILogger<FeedbackReceiversController>>();
|
||||
|
||||
// Test
|
||||
var controller = new FeedbackReceiversController(mockService.Object, tokensService.Object, mapper, null,
|
||||
var controller = new FeedbackReceiversController(mockService.Object, tokensService.Object,
|
||||
feedbacksService.Object, mapper, null,
|
||||
logger.Object);
|
||||
var result = await controller.Delete("bad_guid_but_unit_test_works_cause_validation_doesnt");
|
||||
|
||||
|
@ -84,10 +90,12 @@ namespace Retroactiune.Tests.Retroactiune.WebAPI.Controllers
|
|||
var mapper = TestUtils.GetMapper();
|
||||
var mockService = new Mock<IFeedbackReceiversService>();
|
||||
var tokensService = new Mock<ITokensService>();
|
||||
var feedbacksService = new Mock<IFeedbacksService>();
|
||||
var logger = new Mock<ILogger<FeedbackReceiversController>>();
|
||||
|
||||
// Test
|
||||
var controller = new FeedbackReceiversController(mockService.Object, tokensService.Object, mapper, null,
|
||||
var controller = new FeedbackReceiversController(mockService.Object, tokensService.Object,
|
||||
feedbacksService.Object, mapper, null,
|
||||
logger.Object);
|
||||
var items = new[] {"bad_guid_but_unit_test_works_cause_validation_doesnt", "2", "3"};
|
||||
var result = await controller.DeleteMany(items);
|
||||
|
@ -106,12 +114,14 @@ namespace Retroactiune.Tests.Retroactiune.WebAPI.Controllers
|
|||
var mapper = TestUtils.GetMapper();
|
||||
var mockService = new Mock<IFeedbackReceiversService>();
|
||||
var tokensService = new Mock<ITokensService>();
|
||||
var feedbacksService = new Mock<IFeedbacksService>();
|
||||
var logger = new Mock<ILogger<FeedbackReceiversController>>();
|
||||
mockService.Setup(i => i.DeleteManyAsync(It.IsAny<IEnumerable<string>>()))
|
||||
.ThrowsAsync(new GenericServiceException("op failed"));
|
||||
|
||||
// Test
|
||||
var controller = new FeedbackReceiversController(mockService.Object, tokensService.Object, mapper, null,
|
||||
var controller = new FeedbackReceiversController(mockService.Object, tokensService.Object,
|
||||
feedbacksService.Object, mapper, null,
|
||||
logger.Object);
|
||||
var items = new[] {"bad_guid_but_unit_test_works_cause_validation_doesnt", "2", "3"};
|
||||
var result = await controller.DeleteMany(items);
|
||||
|
@ -129,12 +139,14 @@ namespace Retroactiune.Tests.Retroactiune.WebAPI.Controllers
|
|||
var mapper = TestUtils.GetMapper();
|
||||
var mockService = new Mock<IFeedbackReceiversService>();
|
||||
var tokensService = new Mock<ITokensService>();
|
||||
var feedbacksService = new Mock<IFeedbacksService>();
|
||||
var logger = new Mock<ILogger<FeedbackReceiversController>>();
|
||||
mockService.Setup(i => i.FindAsync(It.IsAny<IEnumerable<string>>(), null, null))
|
||||
.ReturnsAsync(new[] {new FeedbackReceiver()});
|
||||
|
||||
// Test
|
||||
var controller = new FeedbackReceiversController(mockService.Object, tokensService.Object, mapper, null,
|
||||
var controller = new FeedbackReceiversController(mockService.Object, tokensService.Object,
|
||||
feedbacksService.Object, mapper, null,
|
||||
logger.Object);
|
||||
var result = await controller.Get("bad_guid_but_unit_test_works_cause_validation_doesnt");
|
||||
|
||||
|
@ -152,10 +164,12 @@ namespace Retroactiune.Tests.Retroactiune.WebAPI.Controllers
|
|||
var mapper = TestUtils.GetMapper();
|
||||
var mockService = new Mock<IFeedbackReceiversService>();
|
||||
var tokensService = new Mock<ITokensService>();
|
||||
var feedbacksService = new Mock<IFeedbacksService>();
|
||||
var logger = new Mock<ILogger<FeedbackReceiversController>>();
|
||||
|
||||
// Test
|
||||
var controller = new FeedbackReceiversController(mockService.Object, tokensService.Object, mapper, null,
|
||||
var controller = new FeedbackReceiversController(mockService.Object, tokensService.Object,
|
||||
feedbacksService.Object, mapper, null,
|
||||
logger.Object);
|
||||
var result = await controller.Get("bad_guid_but_unit_test_works_cause_validation_doesnt");
|
||||
|
||||
|
@ -173,11 +187,13 @@ namespace Retroactiune.Tests.Retroactiune.WebAPI.Controllers
|
|||
var mapper = TestUtils.GetMapper();
|
||||
var mockService = new Mock<IFeedbackReceiversService>();
|
||||
var tokensService = new Mock<ITokensService>();
|
||||
var feedbacksService = new Mock<IFeedbacksService>();
|
||||
var logger = new Mock<ILogger<FeedbackReceiversController>>();
|
||||
var filterArr = filter as string[] ?? filter.ToArray();
|
||||
|
||||
// Test
|
||||
var controller = new FeedbackReceiversController(mockService.Object, tokensService.Object, mapper, null,
|
||||
var controller = new FeedbackReceiversController(mockService.Object, tokensService.Object,
|
||||
feedbacksService.Object, mapper, null,
|
||||
logger.Object);
|
||||
var result = await controller.List(filterArr, offset, limit);
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@ namespace Retroactiune.Tests.Retroactiune.WebAPI.Controllers
|
|||
|
||||
// Assert
|
||||
Assert.IsType<NoContentResult>(result);
|
||||
tokens.Verify(i => i.DeleteTokens(new[] {"my_guid"}), Times.Once);
|
||||
tokens.Verify(i => i.DeleteTokensAsync(new[] {"my_guid"}), Times.Once);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -85,7 +85,7 @@ namespace Retroactiune.Tests.Retroactiune.WebAPI.Controllers
|
|||
var feedbackService = new Mock<IFeedbackReceiversService>();
|
||||
var tokens = new Mock<ITokensService>();
|
||||
var logger = new Mock<ILogger<TokensController>>();
|
||||
tokens.Setup(i => i.DeleteTokens(It.IsAny<IEnumerable<string>>()))
|
||||
tokens.Setup(i => i.DeleteTokensAsync(It.IsAny<IEnumerable<string>>()))
|
||||
.Throws(new GenericServiceException("op fail"));
|
||||
|
||||
// Test
|
||||
|
@ -94,7 +94,7 @@ namespace Retroactiune.Tests.Retroactiune.WebAPI.Controllers
|
|||
|
||||
// Assert
|
||||
Assert.IsType<BadRequestObjectResult>(result);
|
||||
tokens.Verify(i => i.DeleteTokens(new[] {"my_guid"}), Times.Once);
|
||||
tokens.Verify(i => i.DeleteTokensAsync(new[] {"my_guid"}), Times.Once);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -112,7 +112,7 @@ namespace Retroactiune.Tests.Retroactiune.WebAPI.Controllers
|
|||
|
||||
// Assert
|
||||
Assert.IsType<NoContentResult>(result);
|
||||
tokens.Verify(i => i.DeleteTokens(new[] {"my_guid", "b"}), Times.Once);
|
||||
tokens.Verify(i => i.DeleteTokensAsync(new[] {"my_guid", "b"}), Times.Once);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -123,7 +123,7 @@ namespace Retroactiune.Tests.Retroactiune.WebAPI.Controllers
|
|||
var feedbackService = new Mock<IFeedbackReceiversService>();
|
||||
var tokens = new Mock<ITokensService>();
|
||||
var logger = new Mock<ILogger<TokensController>>();
|
||||
tokens.Setup(i => i.DeleteTokens(It.IsAny<IEnumerable<string>>()))
|
||||
tokens.Setup(i => i.DeleteTokensAsync(It.IsAny<IEnumerable<string>>()))
|
||||
.Throws(new GenericServiceException("op fail"));
|
||||
|
||||
// Test
|
||||
|
@ -132,7 +132,7 @@ namespace Retroactiune.Tests.Retroactiune.WebAPI.Controllers
|
|||
|
||||
// Assert
|
||||
Assert.IsType<BadRequestObjectResult>(result);
|
||||
tokens.Verify(i => i.DeleteTokens(new[] {"my_guid", "b"}), Times.Once);
|
||||
tokens.Verify(i => i.DeleteTokensAsync(new[] {"my_guid", "b"}), Times.Once);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -150,7 +150,7 @@ namespace Retroactiune.Tests.Retroactiune.WebAPI.Controllers
|
|||
|
||||
// Assert
|
||||
Assert.IsType<OkObjectResult>(result);
|
||||
tokens.Verify(i => i.ListTokens(It.IsAny<TokenListFilters>()), Times.Once);
|
||||
tokens.Verify(i => i.FindAsync(It.IsAny<TokenListFilters>()), Times.Once);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -161,7 +161,7 @@ namespace Retroactiune.Tests.Retroactiune.WebAPI.Controllers
|
|||
var feedbackService = new Mock<IFeedbackReceiversService>();
|
||||
var tokens = new Mock<ITokensService>();
|
||||
var logger = new Mock<ILogger<TokensController>>();
|
||||
tokens.Setup(i => i.ListTokens(It.IsAny<TokenListFilters>()))
|
||||
tokens.Setup(i => i.FindAsync(It.IsAny<TokenListFilters>()))
|
||||
.Throws(new GenericServiceException("op fail"));
|
||||
|
||||
// Test
|
||||
|
@ -170,7 +170,7 @@ namespace Retroactiune.Tests.Retroactiune.WebAPI.Controllers
|
|||
|
||||
// Assert
|
||||
Assert.IsType<BadRequestObjectResult>(result);
|
||||
tokens.Verify(i => i.ListTokens(It.IsAny<TokenListFilters>()), Times.Once);
|
||||
tokens.Verify(i => i.FindAsync(It.IsAny<TokenListFilters>()), Times.Once);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Retroactiune.Controllers
|
||||
{
|
||||
public class FeedbackController : ControllerBase
|
||||
{
|
||||
// TODO Add feedback, list feedback, delete feedback, ged feedback.
|
||||
}
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
@ -24,15 +23,17 @@ namespace Retroactiune.Controllers
|
|||
// Note: Probably refactor this to use an Aggregate object, need to learn more about aggregates..
|
||||
private readonly IFeedbackReceiversService _feedbackReceiversService;
|
||||
private readonly ITokensService _tokensService;
|
||||
private readonly IFeedbacksService _feedbacksService;
|
||||
private readonly IMapper _mapper;
|
||||
private readonly ILogger _logger;
|
||||
|
||||
public FeedbackReceiversController(IFeedbackReceiversService feedbackReceiversService,
|
||||
ITokensService tokensService, IMapper mapper,
|
||||
ITokensService tokensService, IFeedbacksService feedbacksService, IMapper mapper,
|
||||
IOptions<ApiBehaviorOptions> apiBehaviorOptions, ILogger<FeedbackReceiversController> logger)
|
||||
{
|
||||
_feedbackReceiversService = feedbackReceiversService;
|
||||
_tokensService = tokensService;
|
||||
_feedbacksService = feedbacksService;
|
||||
_mapper = mapper;
|
||||
_apiBehaviorOptions = apiBehaviorOptions;
|
||||
_logger = logger;
|
||||
|
@ -59,12 +60,7 @@ namespace Retroactiune.Controllers
|
|||
return _apiBehaviorOptions?.Value.InvalidModelStateResponseFactory(ControllerContext);
|
||||
}
|
||||
|
||||
var mappedItems = feedbackReceiversDto.Select(i =>
|
||||
{
|
||||
var result = _mapper.Map<FeedbackReceiver>(i);
|
||||
result.CreatedAt = DateTime.UtcNow;
|
||||
return result;
|
||||
});
|
||||
var mappedItems = feedbackReceiversDto.Select(i => _mapper.Map<FeedbackReceiver>(i));
|
||||
|
||||
await _feedbackReceiversService.CreateManyAsync(mappedItems);
|
||||
|
||||
|
@ -171,5 +167,57 @@ namespace Retroactiune.Controllers
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add Feedback to a FeedbackReceiver.
|
||||
/// </summary>
|
||||
/// <param name="guid">The guid of the FeedbackReceiver to add feedback.</param>
|
||||
/// <param name="feedbackInDto">The feedback dto.</param>
|
||||
/// <response code="200">The feedback has been added.</response>
|
||||
/// <response code="404">The request is invalid.</response>
|
||||
/// <returns></returns>
|
||||
[HttpPost("{guid}/feedbacks")]
|
||||
[ProducesResponseType(typeof(NoContentResult), StatusCodes.Status204NoContent)]
|
||||
[ProducesResponseType(typeof(BasicResponse), StatusCodes.Status400BadRequest)]
|
||||
public async Task<IActionResult> AddFeedback(string guid, [FromBody] FeedbackInDto feedbackInDto)
|
||||
{
|
||||
// TODO: Unit & integration test.
|
||||
var receivers = await _feedbackReceiversService.FindAsync(new[] {guid}, limit: 1);
|
||||
var tokenEnum = await _tokensService.FindAsync(new TokenListFilters
|
||||
{
|
||||
Ids = new[] {feedbackInDto.TokenId}
|
||||
});
|
||||
var feedbackReceivers = receivers as FeedbackReceiver[] ?? receivers.ToArray();
|
||||
var tokens = (tokenEnum as Token[] ?? tokenEnum.ToArray());
|
||||
if (!feedbackReceivers.Any())
|
||||
{
|
||||
return BadRequest(new BasicResponse
|
||||
{
|
||||
Message = $"FeedbackReceiver with id {guid} not found."
|
||||
});
|
||||
}
|
||||
|
||||
if (tokens.Length == 0)
|
||||
{
|
||||
return BadRequest(new BasicResponse
|
||||
{
|
||||
Message = "Token not found."
|
||||
});
|
||||
}
|
||||
|
||||
var token = tokens[0];
|
||||
if (!token.IsValid(feedbackReceivers[0]))
|
||||
{
|
||||
return BadRequest(new BasicResponse
|
||||
{
|
||||
Message = "Token is invalid."
|
||||
});
|
||||
}
|
||||
|
||||
var feedback = _mapper.Map<Feedback>(feedbackInDto);
|
||||
await Task.WhenAll(_tokensService.MarkTokenAsUsedAsync(token),
|
||||
_feedbacksService.AddFeedbackAsync(feedback, feedbackReceivers[0]));
|
||||
return Ok();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -45,7 +45,7 @@ namespace Retroactiune.Controllers
|
|||
try
|
||||
{
|
||||
var tokenFilters = _mapper.Map<TokenListFilters>(filtersDto);
|
||||
var response = await _tokensService.ListTokens(tokenFilters);
|
||||
var response = await _tokensService.FindAsync(tokenFilters);
|
||||
return Ok(response);
|
||||
}
|
||||
catch (GenericServiceException e)
|
||||
|
@ -104,7 +104,7 @@ namespace Retroactiune.Controllers
|
|||
{
|
||||
try
|
||||
{
|
||||
await _tokensService.DeleteTokens(tokenIds);
|
||||
await _tokensService.DeleteTokensAsync(tokenIds);
|
||||
return NoContent();
|
||||
}
|
||||
catch (GenericServiceException e)
|
||||
|
@ -133,7 +133,7 @@ namespace Retroactiune.Controllers
|
|||
{
|
||||
try
|
||||
{
|
||||
await _tokensService.DeleteTokens(new[] {guid});
|
||||
await _tokensService.DeleteTokensAsync(new[] {guid});
|
||||
return NoContent();
|
||||
}
|
||||
catch (GenericServiceException e)
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Retroactiune.DataTransferObjects
|
||||
{
|
||||
|
@ -8,27 +7,12 @@ namespace Retroactiune.DataTransferObjects
|
|||
/// </summary>
|
||||
public class FeedbackInDto
|
||||
{
|
||||
private uint _rating;
|
||||
|
||||
[Required, StringLength(24, ErrorMessage = "invalid guid, must be 24 characters", MinimumLength = 24)]
|
||||
public string FeedbackReceiverId { get; set; }
|
||||
public string TokenId { get; set; }
|
||||
|
||||
[Required]
|
||||
public uint Rating
|
||||
{
|
||||
get => _rating;
|
||||
set
|
||||
{
|
||||
if (value <= 5)
|
||||
{
|
||||
_rating = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ArgumentException();
|
||||
}
|
||||
}
|
||||
}
|
||||
[Required, Range(0, 5, ErrorMessage = "The rating is out of range. [0-5]")]
|
||||
public uint Rating { get; set; }
|
||||
|
||||
[Required] public string Description { get; set; }
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ namespace Retroactiune
|
|||
CreateMap<ListTokensFiltersDto, TokenListFilters>();
|
||||
CreateMap<FeedbackReceiver, FeedbackReceiverInDto>().ReverseMap();
|
||||
CreateMap<FeedbackReceiver, FeedbackReceiverOutDto>();
|
||||
CreateMap<FeedbackInDto, Feedback>();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -40,6 +40,7 @@ namespace Retroactiune
|
|||
// Services
|
||||
services.AddSingleton<IFeedbackReceiversService, FeedbackReceiversService>();
|
||||
services.AddSingleton<ITokensService, TokensService>();
|
||||
services.AddSingleton<IFeedbacksService, FeedbacksService>();
|
||||
services.AddSingleton<IMongoClient, MongoClient>(i =>
|
||||
{
|
||||
var settings = i.GetService<IOptions<DatabaseSettings>>();
|
||||
|
|
|
@ -36,6 +36,7 @@ namespace Retroactiune
|
|||
// Services
|
||||
services.AddSingleton<IFeedbackReceiversService, FeedbackReceiversService>();
|
||||
services.AddSingleton<ITokensService, TokensService>();
|
||||
services.AddSingleton<IFeedbacksService, FeedbacksService>();
|
||||
services.AddSingleton<IMongoClient, MongoClient>(i =>
|
||||
{
|
||||
var settings = i.GetService<IOptions<DatabaseSettings>>();
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
{
|
||||
"DatabaseSettings": {
|
||||
"FeedbackCollectionName": "feedback",
|
||||
"FeedbackCollectionName": "feedbacks",
|
||||
"TokensCollectionName": "tokens",
|
||||
"FeedbackReceiverCollectionName": "feedback_receiver",
|
||||
"FeedbackReceiverCollectionName": "feedback_receivers",
|
||||
"ConnectionString": "mongodb://localhost:27017",
|
||||
"DatabaseName": "RetroactiuneTesting"
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
{
|
||||
"DatabaseSettings": {
|
||||
"FeedbackCollectionName": "feedback",
|
||||
"FeedbackCollectionName": "feedbacks",
|
||||
"TokensCollectionName": "tokens",
|
||||
"FeedbackReceiverCollectionName": "feedback_receiver",
|
||||
"FeedbackReceiverCollectionName": "feedback_receivers",
|
||||
"ConnectionString": "mongodb://localhost:27017",
|
||||
"DatabaseName": "Retroactiune"
|
||||
},
|
||||
|
|
Loading…
Reference in a new issue