Skip to content

Commit

Permalink
Added pagination to Achievements (#884)
Browse files Browse the repository at this point in the history
* Added pagination to Achievements

* Fixed formatting

* Fixed code smells

* Fixed another code smell
  • Loading branch information
andrii52 authored Nov 7, 2022
1 parent 936b244 commit 9f7961e
Show file tree
Hide file tree
Showing 6 changed files with 374 additions and 32 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Moq;
using NUnit.Framework;
using OutOfSchool.WebApi.Controllers.V1;
using OutOfSchool.WebApi.Models;
using OutOfSchool.WebApi.Models.Achievement;
using OutOfSchool.WebApi.Services;

namespace OutOfSchool.WebApi.Tests.Controllers;

[TestFixture]
internal class AchievementControllerTest
{
private AchievementController controller;
private Mock<IAchievementService> achievementService;
private Mock<IProviderService> providerService;
private Mock<IProviderAdminService> providerAdminService;
private Mock<IWorkshopService> workshopService;

[SetUp]
public void Setup()
{
achievementService = new Mock<IAchievementService>();
providerService = new Mock<IProviderService>();
providerAdminService = new Mock<IProviderAdminService>();
workshopService = new Mock<IWorkshopService>();

controller = new AchievementController(achievementService.Object, providerService.Object, providerAdminService.Object, workshopService.Object);
}

[Test]
public async Task GetByWorkshopId_Valid_ReturnsOkObject()
{
// Arrange
achievementService.Setup(a => a.GetByFilter(It.IsAny<AchievementsFilter>())).ReturnsAsync(SearchResult());

// Act
var result = await controller.GetByWorkshopId(It.IsAny<AchievementsFilter>()).ConfigureAwait(false) as OkObjectResult;
var resultValue = result.Value as SearchResult<AchievementDto>;

// Assert
Assert.That(result, Is.Not.Null);
Assert.AreEqual(200, result.StatusCode);
Assert.AreEqual(10, resultValue.TotalAmount);
Assert.AreEqual(6, resultValue.Entities.Count);
}

[Test]
public async Task GetByWorkshopId_NotValid_RetunsNoCententResult()
{
// Arrange
achievementService.Setup(a => a.GetByFilter(It.IsAny<AchievementsFilter>())).ReturnsAsync(new SearchResult<AchievementDto>());

var result = await controller.GetByWorkshopId(It.IsAny<AchievementsFilter>()).ConfigureAwait(false) as NoContentResult;

Assert.That(result, Is.Not.Null);
Assert.AreEqual(204, result.StatusCode);
}

private static SearchResult<AchievementDto> SearchResult()
{
return new SearchResult<AchievementDto>
{
TotalAmount = 10,
Entities = new List<AchievementDto>()
{
new AchievementDto(),
new AchievementDto(),
new AchievementDto(),
new AchievementDto(),
new AchievementDto(),
new AchievementDto(),
},
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,242 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using AutoMapper;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging;
using Moq;
using NUnit.Framework;
using OutOfSchool.Services;
using OutOfSchool.Services.Enums;
using OutOfSchool.Services.Models;
using OutOfSchool.Services.Repository;
using OutOfSchool.Tests.Common;
using OutOfSchool.WebApi.Models;
using OutOfSchool.WebApi.Models.Achievement;
using OutOfSchool.WebApi.Services;

namespace OutOfSchool.WebApi.Tests.Services;

[TestFixture]
public class AchievementServiceTest
{
private readonly Guid validWorkshopGuid = new Guid("08da8474-a754-4d37-879e-4932d389b27a");
private readonly Guid notValidWorkshopGuid = new Guid("05da8774-d754-1d37-979e-4135d389c27a");
private DbContextOptions<OutOfSchoolDbContext> options;
private OutOfSchoolDbContext context;
private AchievementService service;
private IAchievementRepository achievementRepository;
private Mock<ILogger<AchievementService>> logger;
private Mock<IStringLocalizer<SharedResource>> localizer;
private IMapper mapper;

[SetUp]
public void SetUp()
{
var builder =
new DbContextOptionsBuilder<OutOfSchoolDbContext>().UseInMemoryDatabase(
databaseName: "OutOfSchoolTestDB");

options = builder.Options;
context = new OutOfSchoolDbContext(options);

achievementRepository = new AchievementRepository(context);
logger = new Mock<ILogger<AchievementService>>();
localizer = new Mock<IStringLocalizer<SharedResource>>();
mapper = TestHelper.CreateMapperInstanceOfProfileType<Util.MappingProfile>();
service = new AchievementService(achievementRepository, logger.Object, localizer.Object, mapper);

SeedDatabase();
}

[Test]
public async Task GetByFilter_Valid_ReturnsSearchResult()
{
// Arrange
var expected = Achievements();
var filter = new AchievementsFilter() { WorkshopId = validWorkshopGuid };

// Act
var result = await service.GetByFilter(filter);

// Assert
Assert.IsNotNull(result.Entities);
Assert.AreEqual(expected.First().Id, result.Entities.First().Id);
Assert.AreEqual(expected.Count, result.TotalAmount);
Assert.IsInstanceOf<IReadOnlyCollection<AchievementDto>>(result.Entities);
}

[Test]
public async Task GetByFilter_NotValidWorkshopId_ReturnsEmpty()
{
// Arrange
var expexted = new List<Achievement>();
var filter = new AchievementsFilter() { WorkshopId = notValidWorkshopGuid };

// Act
var result = await service.GetByFilter(filter);

// Assert
Assert.That(result.Entities, Is.Empty);
Assert.AreEqual(result.TotalAmount, expexted.Count);
}

private void SeedDatabase()
{
using var ctx = new OutOfSchoolDbContext(options);
{
ctx.Database.EnsureDeleted();
ctx.Database.EnsureCreated();

ctx.Achievements.AddRange(Achievements());

ctx.SaveChanges();
}
}

private List<Achievement> Achievements()
{
return new List<Achievement>()
{
new Achievement()
{
AchievementDate = DateTime.Now,
AchievementTypeId = 1,
Id = validWorkshopGuid,
WorkshopId = new Guid("08da8474-a754-4d37-879e-4932d389b27a"),
Title = "Назва1",
Children = new List<Child>()
{
new Child
{
DateOfBirth = DateTime.Now,
FirstName = "Арієль",
Gender = Gender.Female,
Id = new Guid("0d3a847c-2f7a-482f-89f2-417b98c6d02a"),
IsParent = true,
LastName = "Русалонька",
MiddleName = "Моряка",
Parent = new Parent
{
User = new User
{
Email = "[email protected]",
FirstName = "Арієль",
Id = "08da847c-2f6d-4327-8184-b1a11c8f7008",
LastName = "Русалонька",
MiddleName = "Моряка",
PhoneNumber = "498344943",
},
Gender = Gender.Female,
DateOfBirth = DateTime.Now,
UserId = "06da847c-2f6d-4327-8184-b1a11c8f7008",
Id = new Guid("05da847c-2f6d-4327-8184-b1a11c8f7008"),
},
ParentId = new Guid("05da847c-2f6d-4327-8184-b1a11c8f7008"),
PlaceOfStudy = null,
SocialGroups = new List<SocialGroup>(),
},
new Child()
{
DateOfBirth = DateTime.Now,
FirstName = "Валентина",
Gender = Gender.Female,
Id = new Guid("08da8b0f-fccd-496a-8288-b02729234229"),
IsParent = true,
LastName = "Русалонька",
MiddleName = "Моряка",
Parent = new Parent
{
User = new User
{
Email = "[email protected]",
FirstName = "Арієль",
Id = "09da847c-2f6d-5327-8184-b1a11c8f7808",
LastName = "Русалонька",
MiddleName = "Моряка",
PhoneNumber = "498344943",
},
Gender = Gender.Female,
DateOfBirth = DateTime.Now,
UserId = "09da847c-2f6d-5327-8184-b1a11c8f7808",
Id = new Guid("09da847c-2f6d-5327-8184-b1a11c8f7808"),
},
ParentId = new Guid("09da847c-2f6d-5327-8184-b1a11c8f7808"),
PlaceOfStudy = null,
SocialGroups = new List<SocialGroup>(),
},
},
},
new Achievement()
{
AchievementDate = DateTime.Now,
AchievementTypeId = 1,
WorkshopId = validWorkshopGuid,
Id = new Guid("08da8b47-f4c8-46f7-8376-3aa4d947a1e1"),
Title = "Назва2",
Children = new List<Child>()
{
new Child
{
DateOfBirth = DateTime.Now,
FirstName = "Арієль",
Gender = Gender.Female,
Id = new Guid("08da847c-2f7a-482f-89f2-417b98c6d02a"),
IsParent = true,
LastName = "Русалонька",
MiddleName = "Моряка",
Parent = new Parent
{
User = new User
{
Email = "[email protected]",
FirstName = "Арієль",
Id = "06da847c-2f6d-4327-8184-b1a11c8f7008",
LastName = "Русалонька",
MiddleName = "Моряка",
PhoneNumber = "498344943",
},
Gender = Gender.Female,
DateOfBirth = DateTime.Now,
UserId = "06da847c-2f6d-4327-8184-b1a11c8f7008",
Id = new Guid("02da847c-2f6d-4327-8184-b1a11c8f7008"),
},
ParentId = new Guid("02da847c-2f6d-4327-8184-b1a11c8f7008"),
PlaceOfStudy = null,
SocialGroups = new List<SocialGroup>(),
},
new Child()
{
DateOfBirth = DateTime.Now,
FirstName = "Валентина",
Gender = Gender.Female,
Id = new Guid("08da8b0f-fccd-436a-8288-b02829234229"),
IsParent = true,
LastName = "Русалонька",
MiddleName = "Моряка",
Parent = new Parent
{
User = new User
{
Email = "[email protected]",
FirstName = "Арієль",
Id = "03da847c-2f6d-4327-8184-b1a11c8f7008",
LastName = "Русалонька",
MiddleName = "Моряка",
PhoneNumber = "498344943",
},
DateOfBirth = DateTime.Now,
Gender = Gender.Female,
UserId = "578b8827-9985-4839-a3ab-258abef30a54",
},
ParentId = new Guid("03da847c-2f6d-4327-8184-b1a11c8f7008"),
PlaceOfStudy = null,
SocialGroups = new List<SocialGroup>(),
},
},
},
};
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System.Net.Mime;
using Microsoft.AspNetCore.Mvc;
using OutOfSchool.Services.Enums;
using OutOfSchool.Services.Models;
using OutOfSchool.WebApi.Common;
using OutOfSchool.WebApi.Models;
using OutOfSchool.WebApi.Models.Achievement;
Expand Down Expand Up @@ -60,19 +59,20 @@ public async Task<IActionResult> GetById(Guid id)
/// <summary>
/// To recieve the Achievement list by Workshop id.
/// </summary>
/// <param name="workshopId">Key of the Workshop in the table.</param>
/// <returns>List of achievements.</returns>
/// <param name="filter">Entity that represents searching parameters.</param>
/// <returns><see cref="SearchResult{AchievementDto}"/>.</returns>
/// <response code="200">The entity was found by given Id.</response>
/// <response code="500">If any server error occures. For example: Id was wrong.</response>
[AllowAnonymous]
[HttpGet("{workshopId}")]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(IEnumerable<AchievementDto>))]
[HttpGet]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(SearchResult<AchievementDto>))]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> GetByWorkshopId(Guid workshopId)
public async Task<IActionResult> GetByWorkshopId([FromQuery] AchievementsFilter filter)
{
var achievements = await achievementService.GetByWorkshopId(workshopId).ConfigureAwait(false);
var achievements = await achievementService.GetByFilter(filter).ConfigureAwait(false);

if (!achievements.Any())
if (achievements.TotalAmount < 1)
{
return NoContent();
}
Expand Down Expand Up @@ -106,7 +106,7 @@ public async Task<IActionResult> Create(AchievementCreateDTO achievementDto)
}

var userHasRights = await this.IsUserProvidersOwnerOrAdmin(achievementDto.WorkshopId).ConfigureAwait(false);

if (!userHasRights)
{
return StatusCode(403, "Forbidden to create achievement for another providers.");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace OutOfSchool.WebApi.Models.Achievement;

public class AchievementsFilter : SearchStringFilter
{
public Guid WorkshopId { get; set; } = Guid.Empty;
}
Loading

0 comments on commit 9f7961e

Please sign in to comment.