Skip to content

Commit

Permalink
- naming changes in UnplacedElementsDropZone.razor
Browse files Browse the repository at this point in the history
- add missing localization
- some basic tests
  • Loading branch information
andreasweishaupt committed Feb 29, 2024
1 parent f6bbb76 commit b55ae1c
Show file tree
Hide file tree
Showing 4 changed files with 207 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -57,16 +57,16 @@
</ActivatorContent>
<ChildContent>
<MudMenuItem
Class="px-2 text-xs" IconColor="@(_typeFilter.Count == 0 ? Color.Default : Color.Transparent)" Icon="@Icons.Material.Filled.Check"
OnClick="() => ResetTypeFilter()" AutoClose="false">
Class="px-2 text-xs" IconColor="@(_contentTypeFilter.Count == 0 ? Color.Default : Color.Transparent)" Icon="@Icons.Material.Filled.Check"
OnClick="() => ResetContentTypeFilter()" AutoClose="false">
@Localizer["UnplacedElementsDropZone.Filter.All"]
</MudMenuItem>
<MudDivider Class="p-0"></MudDivider>
@foreach (ContentTypeEnum type in Enum.GetValues(typeof(ContentTypeEnum)))
{
<MudMenuItem
Class="px-2 text-xs" IconColor="@(_typeFilter.Contains(type) ? Color.Default : Color.Transparent)" Icon="@Icons.Material.Filled.Check"
OnClick="() => ToggleTypeFilter(type)" AutoClose="false">
Class="px-2 text-xs" IconColor="@(_contentTypeFilter.Contains(type) ? Color.Default : Color.Transparent)" Icon="@Icons.Material.Filled.Check"
OnClick="() => ToggleContentTypeFilter(type)" AutoClose="false">
@Localizer[$"UnplacedElementsDropZone.Type.{type}"]
</MudMenuItem>
}
Expand Down Expand Up @@ -99,7 +99,7 @@
</div>

<div class="grid justify-items-end px-2">
<MudTextField @bind-Value="SearchString" Immediate="true" Style="font-size: 14px;" Placeholder="Suche" Adornment="Adornment.Start"
<MudTextField @bind-Value="SearchString" Immediate="true" Style="font-size: 14px;" Placeholder="@Localizer["UnplacedElementsDropZone.SearchBar.PlaceHolder"]" Adornment="Adornment.Start"
IconSize="Size.Small" AdornmentIcon="@Icons.Material.Outlined.Search" Clearable="true"/>
</div>
</div>
Expand Down Expand Up @@ -136,7 +136,7 @@

internal string? SearchString { get; set; }
private List<LearningElementDifficultyEnum> _difficultyFilter = new();
private List<ContentTypeEnum> _typeFilter = new();
private List<ContentTypeEnum> _contentTypeFilter = new();
private List<Type> _elementTypeFilter = new();

protected override void OnParametersSet()
Expand Down Expand Up @@ -186,10 +186,10 @@

if (!ShowAfterDifficultyFilter(element)) return false;

if (!ShowAfterContentTypeFilter(element)) return false;

if (!ShowAfterElementTypeFilter(element)) return false;

if (!ShowAfterContentTypeFilter(element)) return false;

return true;
}

Expand All @@ -213,7 +213,7 @@
return true;
}

private bool ShowAfterContentTypeFilter(ILearningElementViewModel element)
private bool ShowAfterElementTypeFilter(ILearningElementViewModel element)
{
if (_elementTypeFilter.Count != 0 && !_elementTypeFilter.Contains(element.LearningContent.GetType()))
{
Expand All @@ -223,34 +223,34 @@
return true;
}

private bool ShowAfterElementTypeFilter(ILearningElementViewModel element)
private bool ShowAfterContentTypeFilter(ILearningElementViewModel element)
{
if (_typeFilter.Count == 0) return true;
if (_contentTypeFilter.Count == 0) return true;

if (element.LearningContent.GetType() == typeof(FileContentViewModel))
{
if (!_typeFilter.Contains(ContentTypeHelper.GetContentType(((FileContentViewModel)element.LearningContent).Type)))
if (!_contentTypeFilter.Contains(ContentTypeHelper.GetContentType(((FileContentViewModel)element.LearningContent).Type)))
{
return false;
}
}
else if (element.LearningContent.GetType() == typeof(LinkContentViewModel))
{
if (!_typeFilter.Contains(ContentTypeEnum.Video))
if (!_contentTypeFilter.Contains(ContentTypeEnum.Video))
{
return false;
}
}
else if (element.LearningContent.GetType() == typeof(AdaptivityContentViewModel))
{
if (!_typeFilter.Contains(ContentTypeEnum.Adaptivity))
if (!_contentTypeFilter.Contains(ContentTypeEnum.Adaptivity))
{
return false;
}
}
else if (element.LearningContent.GetType() == typeof(StoryContentViewModel))
{
if (!_typeFilter.Contains(ContentTypeEnum.Story))
if (!_contentTypeFilter.Contains(ContentTypeEnum.Story))
{
return false;
}
Expand Down Expand Up @@ -293,20 +293,20 @@
}
}

private void ResetTypeFilter()
private void ResetContentTypeFilter()
{
_typeFilter.Clear();
_contentTypeFilter.Clear();
}

private void ToggleTypeFilter(ContentTypeEnum type)
private void ToggleContentTypeFilter(ContentTypeEnum type)
{
if (_typeFilter.Contains(type))
if (_contentTypeFilter.Contains(type))
{
_typeFilter.Remove(type);
_contentTypeFilter.Remove(type);
}
else
{
_typeFilter.Add(type);
_contentTypeFilter.Add(type);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,7 @@
<data name="UnplacedElementsDropZone.Filter.StoryElement" xml:space="preserve">
<value>Storyelement</value>
</data>
<data name="UnplacedElementsDropZone.SearchBar.PlaceHolder" xml:space="preserve">
<value>Suche</value>
</data>
</root>
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,7 @@
<data name="UnplacedElementsDropZone.Filter.StoryElement" xml:space="preserve">
<value>Story element</value>
</data>
<data name="UnplacedElementsDropZone.SearchBar.PlaceHolder" xml:space="preserve">
<value>Search</value>
</data>
</root>
Original file line number Diff line number Diff line change
@@ -1,12 +1,26 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Bunit;
using Bunit.TestDoubles;
using BusinessLogic.Commands;
using Microsoft.AspNetCore.Components;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Localization;
using MudBlazor;
using NSubstitute;
using NUnit.Framework;
using Presentation.Components.Forms.Element;
using Presentation.PresentationLogic.LearningContent;
using Presentation.PresentationLogic.LearningContent.AdaptivityContent;
using Presentation.PresentationLogic.LearningContent.FileContent;
using Presentation.PresentationLogic.LearningContent.LinkContent;
using Presentation.PresentationLogic.LearningContent.Story;
using Presentation.PresentationLogic.LearningElement;
using Presentation.PresentationLogic.LearningWorld;
using Presentation.PresentationLogic.SelectedViewModels;
using Presentation.View.LearningElement;
using Shared;
using TestContext = Bunit.TestContext;

namespace PresentationTest.Components.Forms.Element;
Expand All @@ -28,12 +42,25 @@ public void Setup()
_selectedViewModelsProvider = Substitute.For<ISelectedViewModelsProvider>();
_undoRedoSource = Substitute.For<IOnUndoRedo>();

var localizerForLearningElementDifficultyHelper =
Substitute.For<IStringLocalizer<LearningElementDifficultyEnum>>();
localizerForLearningElementDifficultyHelper[Arg.Any<string>()]
.Returns(ci => new LocalizedString(ci.Arg<string>(), ci.Arg<string>()));
localizerForLearningElementDifficultyHelper[Arg.Any<string>(), Arg.Any<object[]>()].Returns(ci =>
new LocalizedString(ci.Arg<string>() + string.Concat(ci.Arg<object[]>()),
ci.Arg<string>() + string.Concat(ci.Arg<object[]>())));
LearningElementDifficultyHelper.Initialize(localizerForLearningElementDifficultyHelper);

_testContext.Services.AddSingleton(_worldPresenter);
_testContext.Services.AddSingleton(_localizer);
_testContext.Services.AddSingleton(_selectedViewModelsProvider);
_testContext.Services.AddSingleton(_undoRedoSource);

_testContext.AddMudBlazorTestServices();

_testContext.ComponentFactories.AddStub<MudMenu>();
_testContext.ComponentFactories.AddStub<MudMenuItem>();
_testContext.ComponentFactories.AddStub<DragDropLearningElement>();
}

[TearDown]
Expand All @@ -48,6 +75,8 @@ public void TearDown()
private ISelectedViewModelsProvider _selectedViewModelsProvider;
private IOnUndoRedo _undoRedoSource;

private List<ILearningElementViewModel> _itemList;

Check warning on line 78 in PresentationTest/Components/Forms/Element/UnplacedElementsDropZoneUt.cs

View workflow job for this annotation

GitHub Actions / build (IntegrationTest)

Non-nullable field '_itemList' must contain a non-null value when exiting constructor. Consider declaring the field as nullable.

Check warning on line 78 in PresentationTest/Components/Forms/Element/UnplacedElementsDropZoneUt.cs

View workflow job for this annotation

GitHub Actions / build (PresentationTest)

Non-nullable field '_itemList' must contain a non-null value when exiting constructor. Consider declaring the field as nullable.

[Test]
public void Constructor_InjectsDependencies()
{
Expand All @@ -62,9 +91,159 @@ public void Constructor_InjectsDependencies()
});
}

[Test]
public void Render_RendersUnplacedItems()
{
var expectedItem1 = Substitute.For<ILearningElementViewModel>();
expectedItem1.Name = "item1";
expectedItem1.LearningContent = Substitute.For<IAdaptivityContentViewModel>();
var expectedItem2 = Substitute.For<ILearningElementViewModel>();
expectedItem2.Name = "item2";
expectedItem2.LearningContent = Substitute.For<IAdaptivityContentViewModel>();
var items = new List<ILearningElementViewModel>() { expectedItem1, expectedItem2 };
var systemUnderTest = GetRenderedComponent(items);

var mudDropZone = systemUnderTest.FindComponentOrFail<MudDropZone<ILearningElementViewModel>>();

var dragDropLearningElements = mudDropZone.FindComponentsOrFail<Stub<DragDropLearningElement>>().ToList();

private IRenderedComponent<UnplacedElementsDropZone> GetRenderedComponent()
Assert.That(dragDropLearningElements, Has.Count.EqualTo(2));
var element1 = dragDropLearningElements.First();
var element2 = dragDropLearningElements.Last();
Assert.That(element1.Instance.Parameters["LearningElement"], Is.EqualTo(expectedItem1));
Assert.That(element2.Instance.Parameters["LearningElement"], Is.EqualTo(expectedItem2));
}

[Test]
public void Render_RendersFilters()
{
var systemUnderTest = GetRenderedComponent();

var mudMenus = systemUnderTest.FindComponentsOrFail<Stub<MudMenu>>().ToList();
var searchBar = systemUnderTest.FindComponentOrFail<MudTextField<string>>();

Assert.That(mudMenus, Has.Count.EqualTo(3));

// Element Type Filter
var elementTypeFilterHeader =
_testContext.Render((RenderFragment)mudMenus[0].Instance.Parameters["ActivatorContent"]);
var elementTypeFilterChildContent =
_testContext.Render((RenderFragment)mudMenus[0].Instance.Parameters["ChildContent"]);
var elementTypeFilterEntries = elementTypeFilterChildContent.FindComponentsOrFail<Stub<MudMenuItem>>().ToList();
Assert.Multiple(() =>
{
Assert.That(elementTypeFilterHeader.Markup, Contains.Substring("UnplacedElementsDropZone.Filter.Element"));
Assert.That(elementTypeFilterEntries, Has.Count.EqualTo(4));
Assert.That(
_testContext.Render((RenderFragment)elementTypeFilterEntries[0].Instance.Parameters["ChildContent"])
.Markup, Is.EqualTo("UnplacedElementsDropZone.Filter.All"));
Assert.That(
_testContext.Render((RenderFragment)elementTypeFilterEntries[1].Instance.Parameters["ChildContent"])
.Markup, Is.EqualTo("UnplacedElementsDropZone.Filter.LearningElement"));
Assert.That(
_testContext.Render((RenderFragment)elementTypeFilterEntries[2].Instance.Parameters["ChildContent"])
.Markup, Is.EqualTo("UnplacedElementsDropZone.Filter.AdaptivityElement"));
Assert.That(
_testContext.Render((RenderFragment)elementTypeFilterEntries[3].Instance.Parameters["ChildContent"])
.Markup, Is.EqualTo("UnplacedElementsDropZone.Filter.StoryElement"));
});

// Content Type Filter
var contentTypeFilterHeader =
_testContext.Render((RenderFragment)mudMenus[1].Instance.Parameters["ActivatorContent"]);
var contentTypeFilterChildContent =
_testContext.Render((RenderFragment)mudMenus[1].Instance.Parameters["ChildContent"]);
var contentTypeFilterEntries = contentTypeFilterChildContent.FindComponentsOrFail<Stub<MudMenuItem>>().ToList();
Assert.Multiple(() =>
{
Assert.That(contentTypeFilterHeader.Markup, Contains.Substring("UnplacedElementsDropZone.Filter.Type"));
Assert.That(contentTypeFilterEntries, Has.Count.EqualTo(Enum.GetNames(typeof(ContentTypeEnum)).Length + 1));
Assert.That(
_testContext.Render((RenderFragment)contentTypeFilterEntries[0].Instance.Parameters["ChildContent"])
.Markup, Is.EqualTo("UnplacedElementsDropZone.Filter.All"));
});
foreach (var contentTypeFilterEntry in contentTypeFilterEntries.Skip(1))
{
var entryMarkup = _testContext
.Render((RenderFragment)contentTypeFilterEntry.Instance.Parameters["ChildContent"]).Markup;
Assert.That(entryMarkup, Does.StartWith("UnplacedElementsDropZone.Type."));
entryMarkup = entryMarkup.Remove(0, "UnplacedElementsDropZone.Type.".Length);
Assert.That(Enum.GetNames(typeof(ContentTypeEnum)), Contains.Item(entryMarkup));
}

// Difficulty Filter
var difficultyFilterHeader =
_testContext.Render((RenderFragment)mudMenus[2].Instance.Parameters["ActivatorContent"]);
var difficultyFilterChildContent =
_testContext.Render((RenderFragment)mudMenus[2].Instance.Parameters["ChildContent"]);
var difficultyFilterEntries = difficultyFilterChildContent.FindComponentsOrFail<Stub<MudMenuItem>>().ToList();
Assert.Multiple(() =>
{
Assert.That(difficultyFilterHeader.Markup,
Contains.Substring("UnplacedElementsDropZone.Filter.Difficulty"));
Assert.That(difficultyFilterEntries, Has.Count.EqualTo(5));
Assert.That(
_testContext.Render((RenderFragment)difficultyFilterEntries[0].Instance.Parameters["ChildContent"])
.Markup, Is.EqualTo("UnplacedElementsDropZone.Filter.All"));
Assert.That(
_testContext.Render((RenderFragment)difficultyFilterEntries[1].Instance.Parameters["ChildContent"])
.Markup, Is.EqualTo("Enum.LearningElementDifficultyEnum.None"));
Assert.That(
_testContext.Render((RenderFragment)difficultyFilterEntries[2].Instance.Parameters["ChildContent"])
.Markup, Is.EqualTo("Enum.LearningElementDifficultyEnum.Easy"));
Assert.That(
_testContext.Render((RenderFragment)difficultyFilterEntries[3].Instance.Parameters["ChildContent"])
.Markup, Is.EqualTo("Enum.LearningElementDifficultyEnum.Medium"));
Assert.That(
_testContext.Render((RenderFragment)difficultyFilterEntries[4].Instance.Parameters["ChildContent"])
.Markup, Is.EqualTo("Enum.LearningElementDifficultyEnum.Hard"));
});

// Search Bar
Assert.That(searchBar.Instance.Placeholder, Is.EqualTo("UnplacedElementsDropZone.SearchBar.PlaceHolder"));
}


private static ILearningElementViewModel CreateSubstituteForLearningElement(string name,
ILearningContentViewModel learningContent, string? fileType = null)
{
var item = Substitute.For<ILearningElementViewModel>();
item.Name.Returns(name);
item.LearningContent = learningContent;
item.Difficulty = LearningElementDifficultyEnum.None;

if (fileType != null && learningContent is IFileContentViewModel fileContent)
{
fileContent.Type.Returns(fileType);
}

return item;
}

private static List<ILearningElementViewModel> GetTestItems()
{
return new List<ILearningElementViewModel>
{
CreateSubstituteForLearningElement("storyItem1", Substitute.For<IStoryContentViewModel>()),
CreateSubstituteForLearningElement("storyItem2", Substitute.For<IStoryContentViewModel>()),
CreateSubstituteForLearningElement("adaptivityItem1", Substitute.For<IAdaptivityContentViewModel>()),
CreateSubstituteForLearningElement("adaptivityItem2", Substitute.For<IAdaptivityContentViewModel>()),
CreateSubstituteForLearningElement("linkItem1", Substitute.For<ILinkContentViewModel>()),
CreateSubstituteForLearningElement("linkItem2", Substitute.For<ILinkContentViewModel>()),
CreateSubstituteForLearningElement("item4", Substitute.For<IFileContentViewModel>(), "txt"),
CreateSubstituteForLearningElement("item5", Substitute.For<IFileContentViewModel>(), "pdf")
};
}

private IRenderedComponent<UnplacedElementsDropZone> GetRenderedComponent(
List<ILearningElementViewModel>? items = null)
{
_itemList = items ?? GetTestItems();
_testContext.RenderTree.Add<MudDropContainer<ILearningElementViewModel>>(parameterBuilder: builder =>
{
builder.Add(p => p.Items, _itemList);
builder.Add(p => p.ItemsSelector, (model, s) => true);
});
return _testContext.RenderComponent<UnplacedElementsDropZone>();
}
}

0 comments on commit b55ae1c

Please sign in to comment.