Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
75b457d
HEEDLS-585 Move delegate item checkbox into partial
ibrahimmunir14 Sep 8, 2021
5683c3c
HEEDLS-585 Implement no-JS filtering on EmailDelegates page
ibrahimmunir14 Sep 8, 2021
55c0ba4
HEEDLS-585 Write tests for EmailDelegates Controller, VM and Filters
ibrahimmunir14 Sep 8, 2021
6b0c3ea
HEEDLS-585 Add search/sort/paginationEnabled parameters to searchSort…
ibrahimmunir14 Sep 8, 2021
0d800a1
HEEDLS-585 Implement JS filtering on EmailDelegates page
ibrahimmunir14 Sep 8, 2021
f52e506
HEEDLS-585 Keep track of selected delegates (JS) when submitting form
ibrahimmunir14 Sep 10, 2021
c9d190b
HEEDLS-585 Keep track of selected filters (JS) when submitting form
ibrahimmunir14 Sep 10, 2021
4f5a07b
HEEDLS-585 Add separate action for confirmation
ibrahimmunir14 Sep 10, 2021
93fa314
HEEDLS-585 TS Lint
ibrahimmunir14 Sep 10, 2021
91b504c
HEEDLS-585 Add Select/Deselect buttons with JS functionality
ibrahimmunir14 Sep 10, 2021
1c4a437
HEEDLS-585 Implement Select/Deselect All with no-JS functionality
ibrahimmunir14 Sep 14, 2021
d330349
HEEDLS-585 Hide select/deselect buttons if no delegates found
ibrahimmunir14 Sep 14, 2021
a0a217e
Revert "HEEDLS-585 Add separate action for confirmation"
ibrahimmunir14 Sep 10, 2021
fb9b3d0
HEEDLS-585 Extract GetFilterBy function; use in Email/AllDelegates; w…
ibrahimmunir14 Sep 15, 2021
0bef066
HEEDLS-585 Make search/sort/filter/paginateEnabled parameters required
ibrahimmunir14 Sep 15, 2021
d9be401
HEEDLS-585 Remove sortEnabled parameter and always do sorting
ibrahimmunir14 Sep 15, 2021
ae31d34
HEEDLS-585 Run linter and change function declaration style
ibrahimmunir14 Sep 15, 2021
757e9ac
HEEDLS-585 Create new VM on POST error and set form data, instead of …
ibrahimmunir14 Sep 15, 2021
f78b3a0
Merge branch 'master' into HEEDLS-585-welcome-emails-filter
ibrahimmunir14 Sep 16, 2021
585871a
HEEDLS-585 Review markups - renaming
ibrahimmunir14 Sep 21, 2021
42eb95f
HEEDLS-585 Pull out common DelegatesVMFilterOptions helper functions
ibrahimmunir14 Sep 21, 2021
e73006a
HEEDLS-585 Pull out common GetCustomPromptOptions helper function
ibrahimmunir14 Sep 21, 2021
be1fdf1
HEEDLS-585 Review markups - early exit and renaming
ibrahimmunir14 Sep 21, 2021
e9a0c0d
Merge branch 'master' into HEEDLS-585-welcome-emails-filter
ibrahimmunir14 Sep 21, 2021
c585514
HEEDLS-585 Use new SearchSortFilter changes
ibrahimmunir14 Sep 21, 2021
c312653
HEEDLS-585 Rename PreChecked to IsDelegateSelected
ibrahimmunir14 Sep 21, 2021
676ca04
HEEDLS-585 JS formatting
ibrahimmunir14 Sep 21, 2021
7a0a17c
HEEDLS-585 Specify index for each element in selectedIds query param
ibrahimmunir14 Sep 22, 2021
94f174f
Merge branch 'master' into HEEDLS-585-welcome-emails-filter
ibrahimmunir14 Sep 22, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
namespace DigitalLearningSolutions.Web.Tests.Controllers.TrackingSystem.Delegates
{
using DigitalLearningSolutions.Data.DataServices;
using DigitalLearningSolutions.Data.Services;
using DigitalLearningSolutions.Web.Controllers.TrackingSystem.Delegates;
using DigitalLearningSolutions.Web.Helpers;
using DigitalLearningSolutions.Web.Tests.ControllerHelpers;
using DigitalLearningSolutions.Web.ViewModels.TrackingSystem.Delegates.EmailDelegates;
using FakeItEasy;
using FluentAssertions;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using NUnit.Framework;

public class EmailDelegatesControllerTests
{
private CentreCustomPromptHelper centreCustomPromptsHelper = null!;
private EmailDelegatesController emailDelegatesController = null!;

private HttpRequest httpRequest = null!;
private HttpResponse httpResponse = null!;
private IJobGroupsDataService jobGroupsDataService = null!;
private IPasswordResetService passwordResetService = null!;
private IUserService userService = null!;

[SetUp]
public void Setup()
{
var centreCustomPromptsService = A.Fake<ICentreCustomPromptsService>();
centreCustomPromptsHelper = new CentreCustomPromptHelper(centreCustomPromptsService);
userService = A.Fake<IUserService>();
jobGroupsDataService = A.Fake<IJobGroupsDataService>();
passwordResetService = A.Fake<IPasswordResetService>();

httpRequest = A.Fake<HttpRequest>();
httpResponse = A.Fake<HttpResponse>();
const string cookieName = "EmailDelegateFilter";
const string cookieValue = "JobGroupId|JobGroupId|1";

emailDelegatesController = new EmailDelegatesController(
centreCustomPromptsHelper,
jobGroupsDataService,
passwordResetService,
userService
)
.WithMockHttpContext(httpRequest, cookieName, cookieValue, httpResponse)
.WithMockUser(true)
.WithMockServices()
.WithMockTempData();
}

[Test]
public void Index_with_no_query_parameters_uses_cookie_value_for_filterBy()
{
// When
var result = emailDelegatesController.Index();

// Then
result.As<ViewResult>().Model.As<EmailDelegatesViewModel>().FilterBy.Should()
.Be("JobGroupId|JobGroupId|1");
}

[Test]
public void Index_with_query_parameters_uses_query_parameter_value_for_filterBy()
{
// Given
const string filterBy = "JobGroupId|JobGroupId|2";
A.CallTo(() => httpRequest.Query.ContainsKey("filterBy")).Returns(true);

// When
var result = emailDelegatesController.Index(filterBy);

// Then
result.As<ViewResult>().Model.As<EmailDelegatesViewModel>().FilterBy.Should()
.Be(filterBy);
}

[Test]
public void Index_with_CLEAR_filterBy_query_parameter_removes_cookie()
{
// Given
const string filterBy = "CLEAR";

// When
var result = emailDelegatesController.Index(filterBy);

// Then
A.CallTo(() => httpResponse.Cookies.Delete("EmailDelegateFilter")).MustHaveHappened();
result.As<ViewResult>().Model.As<EmailDelegatesViewModel>().FilterBy.Should()
.BeNull();
}

[Test]
public void Index_with_null_filterBy_and_new_filter_query_parameter_adds_new_cookie_value()
{
// Given
const string? filterBy = null;
const string newFilterValue = "JobGroupId|JobGroupId|2";

// When
var result = emailDelegatesController.Index(filterBy, newFilterValue);

// Then
A.CallTo(() => httpResponse.Cookies.Append("EmailDelegateFilter", newFilterValue, A<CookieOptions>._))
.MustHaveHappened();
result.As<ViewResult>().Model.As<EmailDelegatesViewModel>().FilterBy.Should()
.Be(newFilterValue);
}

[Test]
public void Index_with_CLEAR_filterBy_and_new_filter_query_parameter_sets_new_cookie_value()
{
// Given
const string filterBy = "CLEAR";
const string newFilterValue = "JobGroupId|JobGroupId|2";

// When
var result = emailDelegatesController.Index(filterBy, newFilterValue);

// Then
A.CallTo(() => httpResponse.Cookies.Append("EmailDelegateFilter", newFilterValue, A<CookieOptions>._))
.MustHaveHappened();
result.As<ViewResult>().Model.As<EmailDelegatesViewModel>().FilterBy.Should()
.Be(newFilterValue);
}
}
}
65 changes: 65 additions & 0 deletions DigitalLearningSolutions.Web.Tests/Helpers/FilteringHelperTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,26 @@
using System.Linq;
using DigitalLearningSolutions.Web.Helpers;
using DigitalLearningSolutions.Web.Tests.TestHelpers;
using FakeItEasy;
using FluentAssertions;
using Microsoft.AspNetCore.Http;
using NUnit.Framework;

public class FilteringHelperTests
{
private const string FilterByAlphaBravoCharlie = "Group|Name|Alpha╡Group|Name|Bravo╡Group|Name|Charlie";
private const string CookieName = "TestFilterCookie";
private static readonly SortableItem ItemA1 = new SortableItem("a", 1);
private static readonly SortableItem ItemA3 = new SortableItem("a", 3);
private static readonly SortableItem ItemB2 = new SortableItem("b", 2);
private static readonly IQueryable<SortableItem> InputItems = new[] { ItemA1, ItemA3, ItemB2 }.AsQueryable();
private HttpRequest httpRequest = null!;

[SetUp]
public void Setup()
{
httpRequest = A.Fake<HttpRequest>();
}

[Test]
public void FilterItems_returns_expected_items_with_single_filter()
Expand Down Expand Up @@ -139,5 +149,60 @@ public void AddNewFilterToFilterBy_appends_new_filter_even_if_substring(string f
// Then
result.Should().Be($"{filterBy}╡{newFilterValue}");
}

[Test]
public void GetFilterBy_with_no_parameters_returns_cookie_value()
{
// Given
const string CookieValue = "Cookie Value";
A.CallTo(() => httpRequest.Cookies.ContainsKey(CookieName)).Returns(true);
A.CallTo(() => httpRequest.Cookies[CookieName]).Returns(CookieValue);

// When
var result = FilteringHelper.GetFilterBy(null, null, httpRequest, CookieName);

// Then
result.Should().Be(CookieValue);
}

[Test]
public void GetFilterBy_with_no_parameters_and_no_cookies_returns_defaultFilterValue()
{
// When
var result = FilteringHelper.GetFilterBy(null, null, httpRequest, CookieName, "default-filter");

// Then
result.Should().Be("default-filter");
}

[Test]
public void GetFilterBy_with_CLEAR_filterBy_and_no_filterValue_returns_null()
{
// When
var result = FilteringHelper.GetFilterBy("CLEAR", null, httpRequest, CookieName);

// Then
result.Should().BeNull();
}

[Test]
public void GetFilterBy_with_CLEAR_filterBy_and_set_filterValue_returns_filterValue()
{
// When
var result = FilteringHelper.GetFilterBy("CLEAR", "filter-value", httpRequest, CookieName);

// Then
result.Should().Be("filter-value");
}

[Test]
public void GetFilterBy_with_filterBy_and_filterValue_returns_combined_filter_by()
{
// When
var result = FilteringHelper.GetFilterBy("filter-by", "filter-value", httpRequest, CookieName);

// Then
result.Should().Be("filter-by╡filter-value");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
namespace DigitalLearningSolutions.Web.Tests.ViewModels.TrackingSystem.Delegates.EmailDelegates
{
using System.Collections.Generic;
using DigitalLearningSolutions.Data.Models.CustomPrompts;
using DigitalLearningSolutions.Data.Tests.TestHelpers;
using DigitalLearningSolutions.Web.Helpers;
using DigitalLearningSolutions.Web.Models.Enums;
using DigitalLearningSolutions.Web.ViewModels.Common.SearchablePage;
using DigitalLearningSolutions.Web.ViewModels.TrackingSystem.Delegates.EmailDelegates;
using FluentAssertions;
using NUnit.Framework;

public class EmailDelegatesViewModelFilterOptionsTests
{
[Test]
public void GetEmailDelegatesFilterViewModels_should_return_correct_job_group_filter()
{
// Given
var (jobGroups, expectedFilter) = GetSampleJobGroupsAndFilter();

// When
var result =
EmailDelegatesViewModelFilterOptions.GetEmailDelegatesFilterViewModels(jobGroups, new List<CustomPrompt>());

// Then
result.Should().ContainEquivalentOf(expectedFilter);
}

[Test]
public void GetEmailDelegatesFilterViewModels_should_return_correct_custom_prompt_filters()
{
// Given
var (customPrompts, expectedFilters) = GetSampleCustomPromptsAndFilters();

// When
var result = EmailDelegatesViewModelFilterOptions.GetEmailDelegatesFilterViewModels(
new List<(int, string)>(),
customPrompts
);

// Then
expectedFilters.ForEach(expectedFilter => result.Should().ContainEquivalentOf(expectedFilter));
}

private (IEnumerable<(int id, string name)> jobGroups, FilterViewModel filter) GetSampleJobGroupsAndFilter()
{
var jobGroups = new List<(int id, string name)> { (1, "J 1"), (2, "J 2") };

var jobGroupOptions = new[]
{
new FilterOptionViewModel(
"J 1",
"JobGroupId" + FilteringHelper.Separator +
"JobGroupId" + FilteringHelper.Separator + 1,
FilterStatus.Default
),
new FilterOptionViewModel(
"J 2",
"JobGroupId" + FilteringHelper.Separator +
"JobGroupId" + FilteringHelper.Separator + 2,
FilterStatus.Default
)
};
var jobGroupFilter = new FilterViewModel("JobGroupId", "Job Group", jobGroupOptions);

return (jobGroups, jobGroupFilter);
}

private (List<CustomPrompt> customPrompts, List<FilterViewModel> filters) GetSampleCustomPromptsAndFilters()
{
var customPrompt1 = CustomPromptsTestHelper.GetDefaultCustomPrompt(
1,
"First prompt",
"Clinical\r\nNon-Clinical"
);
var customPrompt3 = CustomPromptsTestHelper.GetDefaultCustomPrompt(3);
var customPrompt4 = CustomPromptsTestHelper.GetDefaultCustomPrompt(4, "Fourth prompt", "C 1\r\nC 2\r\nC 3");
var customPrompts = new List<CustomPrompt> { customPrompt1, customPrompt3, customPrompt4 };

var customPrompt1Options = new[]
{
new FilterOptionViewModel(
"Clinical",
"Answer1" + FilteringHelper.Separator +
"Answer1" + FilteringHelper.Separator + "Clinical",
FilterStatus.Default
),
new FilterOptionViewModel(
"Non-Clinical",
"Answer1" + FilteringHelper.Separator +
"Answer1" + FilteringHelper.Separator + "Non-Clinical",
FilterStatus.Default
),
new FilterOptionViewModel(
"No option selected",
"Answer1" + FilteringHelper.Separator +
"Answer1" + FilteringHelper.Separator + FilteringHelper.EmptyValue,
FilterStatus.Default
)
};
var customPrompt4Options = new[]
{
new FilterOptionViewModel(
"C 1",
"Answer4" + FilteringHelper.Separator +
"Answer4" + FilteringHelper.Separator + "C 1",
FilterStatus.Default
),
new FilterOptionViewModel(
"C 2",
"Answer4" + FilteringHelper.Separator +
"Answer4" + FilteringHelper.Separator + "C 2",
FilterStatus.Default
),
new FilterOptionViewModel(
"C 3",
"Answer4" + FilteringHelper.Separator +
"Answer4" + FilteringHelper.Separator + "C 3",
FilterStatus.Default
),
new FilterOptionViewModel(
"No option selected",
"Answer4" + FilteringHelper.Separator +
"Answer4" + FilteringHelper.Separator + FilteringHelper.EmptyValue,
FilterStatus.Default
)
};
var customPromptFilters = new List<FilterViewModel>
{
new FilterViewModel("CustomPrompt1", "First prompt", customPrompt1Options),
new FilterViewModel("CustomPrompt4", "Fourth prompt", customPrompt4Options)
};

return (customPrompts, customPromptFilters);
}
}
}
Loading