diff --git a/Retroactiune.Core/Entities/Feedback.cs b/Retroactiune.Core/Entities/Feedback.cs
index 1e1c181..3475e58 100644
--- a/Retroactiune.Core/Entities/Feedback.cs
+++ b/Retroactiune.Core/Entities/Feedback.cs
@@ -10,28 +10,23 @@ namespace Retroactiune.Core.Entities
///
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; }
diff --git a/Retroactiune.Core/Entities/FeedbackReceiver.cs b/Retroactiune.Core/Entities/FeedbackReceiver.cs
index 6980ea3..9245bcd 100644
--- a/Retroactiune.Core/Entities/FeedbackReceiver.cs
+++ b/Retroactiune.Core/Entities/FeedbackReceiver.cs
@@ -11,6 +11,12 @@ namespace Retroactiune.Core.Entities
///
public class FeedbackReceiver
{
+ public FeedbackReceiver()
+ {
+ Id = ObjectId.GenerateNewId().ToString();
+ CreatedAt = DateTime.UtcNow;
+ }
+
[BsonId, JsonPropertyName("id")]
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; }
diff --git a/Retroactiune.Core/Entities/Token.cs b/Retroactiune.Core/Entities/Token.cs
index 90f75ae..702d182 100644
--- a/Retroactiune.Core/Entities/Token.cs
+++ b/Retroactiune.Core/Entities/Token.cs
@@ -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
///
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);
+ }
}
}
\ No newline at end of file
diff --git a/Retroactiune.Core/Interfaces/IFeedbacksService.cs b/Retroactiune.Core/Interfaces/IFeedbacksService.cs
new file mode 100644
index 0000000..fc124d1
--- /dev/null
+++ b/Retroactiune.Core/Interfaces/IFeedbacksService.cs
@@ -0,0 +1,17 @@
+using System.Threading.Tasks;
+using Retroactiune.Core.Entities;
+
+namespace Retroactiune.Core.Interfaces
+{
+ public interface IFeedbacksService
+ {
+
+ ///
+ /// Adds Feedback to a FeedbackReceiver.
+ ///
+ /// The feedback.
+ /// The feedback receiver.
+ ///
+ public Task AddFeedbackAsync(Feedback feedback, FeedbackReceiver receiver);
+ }
+}
\ No newline at end of file
diff --git a/Retroactiune.Core/Interfaces/ITokensService.cs b/Retroactiune.Core/Interfaces/ITokensService.cs
index f57d37f..5518d0b 100644
--- a/Retroactiune.Core/Interfaces/ITokensService.cs
+++ b/Retroactiune.Core/Interfaces/ITokensService.cs
@@ -23,14 +23,14 @@ namespace Retroactiune.Core.Interfaces
///
/// A list of tokens to delete.
/// The result of the delete operation.
- public Task DeleteTokens(IEnumerable tokenIds);
+ public Task DeleteTokensAsync(IEnumerable tokenIds);
///
- /// List and filters tokens.
+ /// Finds and filters tokens.
///
/// Filters object for filtering results.
/// A list of tokens matching the filters.
- public Task> ListTokens(TokenListFilters filters);
+ public Task> FindAsync(TokenListFilters filters);
///
/// Deletes tokens, by their associated FeedbackReceiverId.
@@ -38,5 +38,11 @@ namespace Retroactiune.Core.Interfaces
/// A list of FeedbackReceiverIDs.
/// The result of the delete operation.
public Task DeleteManyByFeedbackReceiverIdAsync(IEnumerable feedbackReceiverIds);
+
+ ///
+ /// Marks the token as being used.
+ ///
+ /// The token.
+ public Task MarkTokenAsUsedAsync(Token token);
}
}
\ No newline at end of file
diff --git a/Retroactiune.Core/Retroactiune.Core.csproj b/Retroactiune.Core/Retroactiune.Core.csproj
index 02f0260..792b4db 100644
--- a/Retroactiune.Core/Retroactiune.Core.csproj
+++ b/Retroactiune.Core/Retroactiune.Core.csproj
@@ -5,6 +5,7 @@
+
diff --git a/Retroactiune.Core/Services/FeedbacksService.cs b/Retroactiune.Core/Services/FeedbacksService.cs
new file mode 100644
index 0000000..6020956
--- /dev/null
+++ b/Retroactiune.Core/Services/FeedbacksService.cs
@@ -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 _collection;
+
+ public FeedbacksService(IMongoClient client, IDatabaseSettings settings)
+ {
+ var database = client.GetDatabase(settings.DatabaseName);
+ _collection = database.GetCollection(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);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Retroactiune.Core/Services/TokensService.cs b/Retroactiune.Core/Services/TokensService.cs
index 5257e78..6ad22c4 100644
--- a/Retroactiune.Core/Services/TokensService.cs
+++ b/Retroactiune.Core/Services/TokensService.cs
@@ -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();
for (var i = 0; i < numberOfTokens; i++)
@@ -41,7 +39,7 @@ namespace Retroactiune.Core.Services
await _collection.InsertManyAsync(token);
}
- public async Task DeleteTokens(IEnumerable tokenIds)
+ public async Task DeleteTokensAsync(IEnumerable tokenIds)
{
try
{
@@ -54,7 +52,7 @@ namespace Retroactiune.Core.Services
}
}
- public async Task> ListTokens(TokenListFilters filters)
+ public async Task> FindAsync(TokenListFilters filters)
{
var filterBuilder = new FilterDefinitionBuilder();
var activeFilters = new List>();
@@ -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();
+ var updateBuilder = new UpdateDefinitionBuilder();
+ await _collection.UpdateOneAsync(filterBuilder.Eq(i => i.Id, token.Id),
+ updateBuilder.Set(i => i.TimeUsed, DateTime.UtcNow));
+ }
}
}
\ No newline at end of file
diff --git a/Retroactiune.UnitTests/Retroactiune.Core/Services/TestTokensService.cs b/Retroactiune.UnitTests/Retroactiune.Core/Services/TestTokensService.cs
index 001fec4..a69e1ea 100644
--- a/Retroactiune.UnitTests/Retroactiune.Core/Services/TestTokensService.cs
+++ b/Retroactiune.UnitTests/Retroactiune.Core/Services/TestTokensService.cs
@@ -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>(),
It.IsAny(),
It.IsAny()), 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>(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",
diff --git a/Retroactiune.UnitTests/Retroactiune.WebAPI/Controllers/TestFeedbackReceiverController.cs b/Retroactiune.UnitTests/Retroactiune.WebAPI/Controllers/TestFeedbackReceiverController.cs
index d159e05..624bac0 100644
--- a/Retroactiune.UnitTests/Retroactiune.WebAPI/Controllers/TestFeedbackReceiverController.cs
+++ b/Retroactiune.UnitTests/Retroactiune.WebAPI/Controllers/TestFeedbackReceiverController.cs
@@ -23,10 +23,12 @@ namespace Retroactiune.Tests.Retroactiune.WebAPI.Controllers
var mapper = TestUtils.GetMapper();
var mockService = new Mock();
var tokensService = new Mock();
+ var feedbacksService = new Mock();
var logger = new Mock>();
// 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());
@@ -42,10 +44,12 @@ namespace Retroactiune.Tests.Retroactiune.WebAPI.Controllers
var mapper = TestUtils.GetMapper();
var mockService = new Mock();
var tokensService = new Mock();
+ var feedbacksService = new Mock();
var logger = new Mock>();
// 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();
var tokensService = new Mock();
+ var feedbacksService = new Mock();
var logger = new Mock>();
// 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();
var tokensService = new Mock();
+ var feedbacksService = new Mock();
var logger = new Mock>();
// 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();
var tokensService = new Mock();
+ var feedbacksService = new Mock();
var logger = new Mock>();
mockService.Setup(i => i.DeleteManyAsync(It.IsAny>()))
.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();
var tokensService = new Mock();
+ var feedbacksService = new Mock();
var logger = new Mock>();
mockService.Setup(i => i.FindAsync(It.IsAny>(), 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();
var tokensService = new Mock();
+ var feedbacksService = new Mock();
var logger = new Mock>();
// 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();
var tokensService = new Mock();
+ var feedbacksService = new Mock();
var logger = new Mock>();
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);
diff --git a/Retroactiune.UnitTests/Retroactiune.WebAPI/Controllers/TestTokensController.cs b/Retroactiune.UnitTests/Retroactiune.WebAPI/Controllers/TestTokensController.cs
index 5d29719..0722866 100644
--- a/Retroactiune.UnitTests/Retroactiune.WebAPI/Controllers/TestTokensController.cs
+++ b/Retroactiune.UnitTests/Retroactiune.WebAPI/Controllers/TestTokensController.cs
@@ -74,7 +74,7 @@ namespace Retroactiune.Tests.Retroactiune.WebAPI.Controllers
// Assert
Assert.IsType(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();
var tokens = new Mock();
var logger = new Mock>();
- tokens.Setup(i => i.DeleteTokens(It.IsAny>()))
+ tokens.Setup(i => i.DeleteTokensAsync(It.IsAny>()))
.Throws(new GenericServiceException("op fail"));
// Test
@@ -94,7 +94,7 @@ namespace Retroactiune.Tests.Retroactiune.WebAPI.Controllers
// Assert
Assert.IsType(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(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();
var tokens = new Mock();
var logger = new Mock>();
- tokens.Setup(i => i.DeleteTokens(It.IsAny>()))
+ tokens.Setup(i => i.DeleteTokensAsync(It.IsAny>()))
.Throws(new GenericServiceException("op fail"));
// Test
@@ -132,7 +132,7 @@ namespace Retroactiune.Tests.Retroactiune.WebAPI.Controllers
// Assert
Assert.IsType(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(result);
- tokens.Verify(i => i.ListTokens(It.IsAny()), Times.Once);
+ tokens.Verify(i => i.FindAsync(It.IsAny()), Times.Once);
}
[Fact]
@@ -161,7 +161,7 @@ namespace Retroactiune.Tests.Retroactiune.WebAPI.Controllers
var feedbackService = new Mock();
var tokens = new Mock();
var logger = new Mock>();
- tokens.Setup(i => i.ListTokens(It.IsAny()))
+ tokens.Setup(i => i.FindAsync(It.IsAny()))
.Throws(new GenericServiceException("op fail"));
// Test
@@ -170,7 +170,7 @@ namespace Retroactiune.Tests.Retroactiune.WebAPI.Controllers
// Assert
Assert.IsType(result);
- tokens.Verify(i => i.ListTokens(It.IsAny()), Times.Once);
+ tokens.Verify(i => i.FindAsync(It.IsAny()), Times.Once);
}
}
}
\ No newline at end of file
diff --git a/Retroactiune.WebAPI/Controllers/FeedbackController.cs b/Retroactiune.WebAPI/Controllers/FeedbackController.cs
deleted file mode 100644
index 1d7e1f1..0000000
--- a/Retroactiune.WebAPI/Controllers/FeedbackController.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-using Microsoft.AspNetCore.Mvc;
-
-namespace Retroactiune.Controllers
-{
- public class FeedbackController : ControllerBase
- {
- // TODO Add feedback, list feedback, delete feedback, ged feedback.
- }
-}
\ No newline at end of file
diff --git a/Retroactiune.WebAPI/Controllers/FeedbackReceiversController.cs b/Retroactiune.WebAPI/Controllers/FeedbackReceiversController.cs
index 340c3d4..0b519d3 100644
--- a/Retroactiune.WebAPI/Controllers/FeedbackReceiversController.cs
+++ b/Retroactiune.WebAPI/Controllers/FeedbackReceiversController.cs
@@ -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, ILogger 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(i);
- result.CreatedAt = DateTime.UtcNow;
- return result;
- });
+ var mappedItems = feedbackReceiversDto.Select(i => _mapper.Map(i));
await _feedbackReceiversService.CreateManyAsync(mappedItems);
@@ -171,5 +167,57 @@ namespace Retroactiune.Controllers
});
}
}
+
+ ///
+ /// Add Feedback to a FeedbackReceiver.
+ ///
+ /// The guid of the FeedbackReceiver to add feedback.
+ /// The feedback dto.
+ /// The feedback has been added.
+ /// The request is invalid.
+ ///
+ [HttpPost("{guid}/feedbacks")]
+ [ProducesResponseType(typeof(NoContentResult), StatusCodes.Status204NoContent)]
+ [ProducesResponseType(typeof(BasicResponse), StatusCodes.Status400BadRequest)]
+ public async Task 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(feedbackInDto);
+ await Task.WhenAll(_tokensService.MarkTokenAsUsedAsync(token),
+ _feedbacksService.AddFeedbackAsync(feedback, feedbackReceivers[0]));
+ return Ok();
+ }
}
}
\ No newline at end of file
diff --git a/Retroactiune.WebAPI/Controllers/TokensController.cs b/Retroactiune.WebAPI/Controllers/TokensController.cs
index d12a116..a50a5e7 100644
--- a/Retroactiune.WebAPI/Controllers/TokensController.cs
+++ b/Retroactiune.WebAPI/Controllers/TokensController.cs
@@ -45,7 +45,7 @@ namespace Retroactiune.Controllers
try
{
var tokenFilters = _mapper.Map(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)
diff --git a/Retroactiune.WebAPI/DataTransferObjects/FeedbackInDto.cs b/Retroactiune.WebAPI/DataTransferObjects/FeedbackInDto.cs
index 63c7ca0..5e53702 100644
--- a/Retroactiune.WebAPI/DataTransferObjects/FeedbackInDto.cs
+++ b/Retroactiune.WebAPI/DataTransferObjects/FeedbackInDto.cs
@@ -1,5 +1,4 @@
-using System;
-using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations;
namespace Retroactiune.DataTransferObjects
{
@@ -8,27 +7,12 @@ namespace Retroactiune.DataTransferObjects
///
public class FeedbackInDto
{
- private uint _rating;
-
- [Required, StringLength(24, ErrorMessage = "invalid guid, must be 24 characters", MinimumLength = 24)]
- public string FeedbackReceiverId { get; set; }
-
- [Required]
- public uint Rating
- {
- get => _rating;
- set
- {
- if (value <= 5)
- {
- _rating = value;
- }
- else
- {
- throw new ArgumentException();
- }
- }
- }
+
+ [Required, StringLength(24, ErrorMessage = "invalid guid, must be 24 characters", MinimumLength = 24)]
+ public string TokenId { get; set; }
+
+ [Required, Range(0, 5, ErrorMessage = "The rating is out of range. [0-5]")]
+ public uint Rating { get; set; }
[Required] public string Description { get; set; }
}
diff --git a/Retroactiune.WebAPI/MappingProfile.cs b/Retroactiune.WebAPI/MappingProfile.cs
index c3e5a07..0f9a54a 100644
--- a/Retroactiune.WebAPI/MappingProfile.cs
+++ b/Retroactiune.WebAPI/MappingProfile.cs
@@ -12,6 +12,7 @@ namespace Retroactiune
CreateMap();
CreateMap().ReverseMap();
CreateMap();
+ CreateMap();
}
}
}
\ No newline at end of file
diff --git a/Retroactiune.WebAPI/Startup.cs b/Retroactiune.WebAPI/Startup.cs
index 61a5e6a..c877a75 100644
--- a/Retroactiune.WebAPI/Startup.cs
+++ b/Retroactiune.WebAPI/Startup.cs
@@ -40,6 +40,7 @@ namespace Retroactiune
// Services
services.AddSingleton();
services.AddSingleton();
+ services.AddSingleton();
services.AddSingleton(i =>
{
var settings = i.GetService>();
diff --git a/Retroactiune.WebAPI/TestingStartup.cs b/Retroactiune.WebAPI/TestingStartup.cs
index 0a3b32d..b33feaf 100644
--- a/Retroactiune.WebAPI/TestingStartup.cs
+++ b/Retroactiune.WebAPI/TestingStartup.cs
@@ -36,6 +36,7 @@ namespace Retroactiune
// Services
services.AddSingleton();
services.AddSingleton();
+ services.AddSingleton();
services.AddSingleton(i =>
{
var settings = i.GetService>();
diff --git a/Retroactiune.WebAPI/appsettings.Testing.json b/Retroactiune.WebAPI/appsettings.Testing.json
index ddce3c1..a9d7170 100644
--- a/Retroactiune.WebAPI/appsettings.Testing.json
+++ b/Retroactiune.WebAPI/appsettings.Testing.json
@@ -1,8 +1,8 @@
{
"DatabaseSettings": {
- "FeedbackCollectionName": "feedback",
+ "FeedbackCollectionName": "feedbacks",
"TokensCollectionName": "tokens",
- "FeedbackReceiverCollectionName": "feedback_receiver",
+ "FeedbackReceiverCollectionName": "feedback_receivers",
"ConnectionString": "mongodb://localhost:27017",
"DatabaseName": "RetroactiuneTesting"
}
diff --git a/Retroactiune.WebAPI/appsettings.json b/Retroactiune.WebAPI/appsettings.json
index 115992e..7415215 100644
--- a/Retroactiune.WebAPI/appsettings.json
+++ b/Retroactiune.WebAPI/appsettings.json
@@ -1,8 +1,8 @@
{
"DatabaseSettings": {
- "FeedbackCollectionName": "feedback",
+ "FeedbackCollectionName": "feedbacks",
"TokensCollectionName": "tokens",
- "FeedbackReceiverCollectionName": "feedback_receiver",
+ "FeedbackReceiverCollectionName": "feedback_receivers",
"ConnectionString": "mongodb://localhost:27017",
"DatabaseName": "Retroactiune"
},