Skip to content

Commit

Permalink
feat: Resources page new filter component
Browse files Browse the repository at this point in the history
Merge pull request #311 from DFE-Digital/resources-new-filter-component
  • Loading branch information
killij authored Oct 31, 2023
2 parents 9fdd463 + a4bfef4 commit fb68caa
Show file tree
Hide file tree
Showing 21 changed files with 1,326 additions and 312 deletions.
134 changes: 10 additions & 124 deletions Childrens-Social-Care-CPD-Tests/Controllers/ResourcesControllerTests.cs
Original file line number Diff line number Diff line change
@@ -1,52 +1,28 @@
using Childrens_Social_Care_CPD.Contentful.Models;
using Childrens_Social_Care_CPD.Controllers;
using Childrens_Social_Care_CPD.DataAccess;
using Childrens_Social_Care_CPD.Controllers;
using Childrens_Social_Care_CPD.Core.Resources;
using Childrens_Social_Care_CPD.Models;
using FluentAssertions;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.Extensions.Logging;
using NSubstitute;
using NUnit.Framework;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Threading;
using System.Threading.Tasks;
using static Childrens_Social_Care_CPD.GraphQL.Queries.SearchResourcesByTags;

namespace Childrens_Social_Care_CPD_Tests.Controllers;

public class ResourcesControllerTests
{
private IResourcesRepository _resourcesRepository;

private IResourcesSearchStrategy _searchStrategy;
private ResourcesController _resourcesController;
private IRequestCookieCollection _cookies;
private HttpContext _httpContext;
private HttpRequest _httpRequest;
private ILogger<ResourcesController> _logger;
private CancellationTokenSource _cancellationTokenSource;

private void SetPageContent(Content content)
{
_resourcesRepository.FetchRootPage(Arg.Any<CancellationToken>()).Returns(content);
}

public void SetSearchResults(ResponseType content)
{
_resourcesRepository
.FindByTags(Arg.Any<IEnumerable<string>>(), Arg.Any<int>(), Arg.Any<int>(), Arg.Any<CancellationToken>())
.Returns(content);
}

[SetUp]
public void SetUp()
{
_cancellationTokenSource = new CancellationTokenSource();
_resourcesRepository = Substitute.For<IResourcesRepository>();

_logger = Substitute.For<ILogger<ResourcesController>>();
_cookies = Substitute.For<IRequestCookieCollection>();
_httpContext = Substitute.For<HttpContext>();
_httpRequest = Substitute.For<HttpRequest>();
Expand All @@ -56,115 +32,25 @@ public void SetUp()
_httpContext.Request.Returns(_httpRequest);
controllerContext.HttpContext = _httpContext;

_resourcesController = new ResourcesController(_logger, _resourcesRepository)
_searchStrategy = Substitute.For<IResourcesSearchStrategy>();
_resourcesController = new ResourcesController(_searchStrategy)
{
ControllerContext = controllerContext,
TempData = Substitute.For<ITempDataDictionary>()
};
}

[Test]
public async Task Search_With_Empty_Query_Returns_View()
{
// act
var actual = await _resourcesController.Search(query: null, _cancellationTokenSource.Token) as ViewResult;

// assert
actual.Should().BeOfType<ViewResult>();
actual.Model.Should().BeOfType<ResourcesListViewModel>();
}

[Test]
public async Task Search_Page_Resource_Is_Passed_To_View()
public async Task Search_Returns_Strategy_Model()
{
// arrange
var content = new Content();
SetPageContent(content);

// act
var actual = (await _resourcesController.Search(query: null, _cancellationTokenSource.Token) as ViewResult)?.Model as ResourcesListViewModel;
var model = new ResourcesListViewModel(null, null, null, null);
_searchStrategy.SearchAsync(Arg.Any<ResourcesQuery>(), Arg.Any<CancellationToken>()).Returns(model);

// assert
actual.Content.Should().Be(content);
}

[Test]
public async Task Search_Sets_The_ViewState_ContextModel()
{
// act
await _resourcesController.Search(null, _cancellationTokenSource.Token);
var actual = _resourcesController.ViewData["ContextModel"] as ContextModel;
var actual = await _resourcesController.Search(query: null) as ViewResult;

// assert
actual.Should().NotBeNull();
actual.Id.Should().Be(string.Empty);
actual.Title.Should().Be("Resources");
actual.Category.Should().Be("Resources");
}

[Test]
public async Task Search_Selected_Tags_Are_Passed_Into_View()
{
// arrange
var query = new ResourcesQuery
{
Page = 1,
Tags = new int[] { 1, 2 }
};

// act
var actual = (await _resourcesController.Search(query, _cancellationTokenSource.Token) as ViewResult)?.Model as ResourcesListViewModel;

// assert
actual.SelectedTags.Should().Equal(query.Tags);
}

[Test]
public async Task Search_Page_Set_To_Be_In_Bounds()
{
// arrange
var results = new ResponseType()
{
ResourceCollection = new ResourceCollection()
{
Total = 3,
Items = new Collection<SearchResult>()
{
new SearchResult(),
new SearchResult(),
new SearchResult(),
}
}
};
SetSearchResults(results);
var query = new ResourcesQuery
{
Page = 2,
Tags = new int[] { 1, 2 }
};

// act
var actual = (await _resourcesController.Search(query, _cancellationTokenSource.Token) as ViewResult)?.Model as ResourcesListViewModel;

// assert
actual.CurrentPage.Should().Be(1);
}

[Test]
public async Task Search_Invalid_Tags_Logs_Warning()
{
// arrange
var tags = new int[] { -1 };
var query = new ResourcesQuery
{
Page = 2,
Tags = tags
};

// act
await _resourcesController.Search(query, _cancellationTokenSource.Token);

//assert
_logger.ReceivedWithAnyArgs(1).LogWarning(default, args: default);
actual.Model.Should().Be(model);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
using Childrens_Social_Care_CPD.Contentful.Models;
using Childrens_Social_Care_CPD.Controllers;
using Childrens_Social_Care_CPD.Core.Resources;
using Childrens_Social_Care_CPD.DataAccess;
using NSubstitute;
using NUnit.Framework;
using static Childrens_Social_Care_CPD.GraphQL.Queries.SearchResourcesByTags;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Threading.Tasks;
using System.Threading;
using FluentAssertions;

namespace Childrens_Social_Care_CPD_Tests.Core.Resources;

public class ResourcesDynamicTagsSearchStategyTests
{
private IResourcesRepository _resourcesRepository;

private IResourcesSearchStrategy _sut;

private void SetTags(IEnumerable<TagInfo> tags)
{
_resourcesRepository.GetSearchTagsAsync().Returns(tags);
}

private void SetPageContent(Content content)
{
_resourcesRepository.FetchRootPageAsync(Arg.Any<CancellationToken>()).Returns(content);
}

private void SetSearchResults(ResponseType content)
{
_resourcesRepository
.FindByTagsAsync(Arg.Any<IEnumerable<string>>(), Arg.Any<int>(), Arg.Any<int>(), Arg.Any<CancellationToken>())
.Returns(content);
}

[SetUp]
public void SetUp()
{
_resourcesRepository = Substitute.For<IResourcesRepository>();
SetTags(new List<TagInfo>
{
new TagInfo("Cat1", "Tag1", "tag1")
});
_sut = new ResourcesDynamicTagsSearchStategy(_resourcesRepository);
}

[Test]
public async Task Search_With_Empty_Query()
{
// act
var actual = await _sut.SearchAsync(query: null);

// assert
actual.TotalPages.Should().Be(0);
actual.TotalResults.Should().Be(0);
actual.CurrentPage.Should().Be(0);
actual.SelectedTags.Should().BeEmpty();
actual.Results.Should().BeNull();
actual.Content.Should().BeNull();
}

[Test]
public async Task Search_Returns_Tags()
{
// act
var actual = await _sut.SearchAsync(query: null);

// assert
actual.TagInfos.Should().HaveCount(1);
}

[Test]
public async Task Search_Returns_CMS_Content()
{
// arrange
var content = new Content();
SetPageContent(content);

// act
var actual = await _sut.SearchAsync(query: null);

// assert
actual.Content.Should().Be(content);
}

[Test]
public async Task Search_Selected_Tags_Are_Passed_Into_View()
{
// arrange
var query = new ResourcesQuery
{
Page = 1,
Tags = new string[] { "tag1", "tag2" }
};

// act
var actual = await _sut.SearchAsync(query);

// assert
actual.SelectedTags.Should().Equal(query.Tags);
}

[Test]
public async Task Search_Page_Set_To_Be_In_Bounds()
{
// arrange
var results = new ResponseType()
{
ResourceCollection = new ResourceCollection()
{
Total = 3,
Items = new Collection<SearchResult>()
{
new SearchResult(),
new SearchResult(),
new SearchResult(),
}
}
};
SetSearchResults(results);
var query = new ResourcesQuery
{
Page = 2,
Tags = new string[] { "tag1", "tag2" }
};

// act
var actual = await _sut.SearchAsync(query);

// assert
actual.CurrentPage.Should().Be(1);
}

[TestCase("")]
[TestCase("-1")]
[TestCase("x")]
public async Task Invalid_Tags_Are_Not_Queried_For(string value)
{
// arrange
IEnumerable<string> passedTags = null;
var tags = new string[] { value, "tag1" };
var query = new ResourcesQuery
{
Page = 2,
Tags = tags
};
await _resourcesRepository.FindByTagsAsync(Arg.Do<IEnumerable<string>>(value => passedTags = value), Arg.Any<int>(), Arg.Any<int>(), Arg.Any<CancellationToken>());

// act
var actual = await _sut.SearchAsync(query);

//assert
passedTags.Should().NotContain(value);
}

[TestCase("")]
[TestCase("x")]
public async Task Invalid_Tags_Are_Sanitised(string value)
{
// arrange
var tags = new string[] { value, "tag1" };
var query = new ResourcesQuery
{
Page = 2,
Tags = tags
};

// act
var actual = await _sut.SearchAsync(query);

//assert
actual.SelectedTags.Should().NotContain(value);
}
}
Loading

0 comments on commit fb68caa

Please sign in to comment.