Skip to content

Commit

Permalink
Refcatoring and first version ElementDefinitionTree tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Alexander van Delft committed Jan 8, 2025
1 parent 9fcdadc commit ee5cfb3
Show file tree
Hide file tree
Showing 9 changed files with 383 additions and 59 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,255 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="ElementDefinitionTreeTestFixture.cs" company="Starion Group S.A.">
// Copyright (c) 2024 Starion Group S.A.
//
// Authors: Sam Gerené, Alex Vorobiev, Alexander van Delft, Jaime Bernar, Théate Antoine, João Rua
//
// This file is part of COMET WEB Community Edition
// The COMET WEB Community Edition is the Starion Group Web Application implementation of ECSS-E-TM-10-25 Annex A and Annex C.
//
// The COMET WEB Community Edition is free software; you can redistribute it and/or
// modify it under the terms of the GNU Affero General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// The COMET WEB Community Edition is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------

namespace COMETwebapp.Tests.Components.MultiModelEditor
{
using Bunit;
using Bunit.Rendering;

using CDP4Common.EngineeringModelData;
using CDP4Common.SiteDirectoryData;

using COMET.Web.Common.Model;
using COMET.Web.Common.Model.Configuration;
using COMET.Web.Common.Services.ConfigurationService;
using COMET.Web.Common.Services.SessionManagement;
using COMET.Web.Common.Test.Helpers;

using COMETwebapp.Components.MultiModelEditor;
using COMETwebapp.ViewModels.Components.MultiModelEditor;
using COMETwebapp.ViewModels.Components.MultiModelEditor.Rows;

using DevExpress.Blazor;

using Microsoft.Extensions.DependencyInjection;

using Moq;

using NUnit.Framework;

using TestContext = Bunit.TestContext;

[TestFixture]
public class ElementDefinitionTreeTestFixture
{
private TestContext context;
private IRenderedComponent<ElementDefinitionTree> renderedComponent;
private ElementDefinitionTree tree;
private Mock<IElementDefinitionTreeViewModel> elementDefinitionTreeViewModel;

[SetUp]
public void SetUp()
{
this.context = new TestContext();
this.context.ConfigureDevExpressBlazor();

var configuration = new Mock<IConfigurationService>();
configuration.Setup(x => x.ServerConfiguration).Returns(new ServerConfiguration());
var elementDefinition = new ElementDefinition();

var row = new ElementDefinitionTreeRowViewModel
{
ElementName = "Test1",
ElementBase = elementDefinition,
OwnerShortName = "Owner",
IsTopElement = true
};

this.elementDefinitionTreeViewModel = new Mock<IElementDefinitionTreeViewModel>();
this.elementDefinitionTreeViewModel.Setup(x => x.Rows).Returns([row]);

this.context.Services.AddSingleton(configuration.Object);
this.context.Services.AddSingleton(this.elementDefinitionTreeViewModel.Object);
this.context.Services.AddSingleton<ISessionService, SessionService>();

this.renderedComponent = this.context.RenderComponent<ElementDefinitionTree>();
this.tree = this.renderedComponent.Instance;
}

[TearDown]
public void TearDown()
{
this.context.CleanContext();
}

[Test]
public void VerifyComponent()
{
Assert.Multiple(() =>
{
Assert.That(this.renderedComponent, Is.Not.Null);
Assert.That(this.tree, Is.Not.Null);
Assert.That(this.tree.ViewModel, Is.Not.Null);
});
}

[Test]
public void VerifyElementSelection()
{
ElementBaseTreeRowViewModel selectedModel = null;

this.renderedComponent = this.context.RenderComponent<ElementDefinitionTree>(parameters =>
{
parameters
.Add(p => p.SelectionChanged, model => selectedModel = model);
});

var treeView = this.renderedComponent.FindComponent<DxTreeView>();

Assert.Multiple(() =>
{
Assert.That(treeView.Instance.GetSelectedNodeInfo(), Is.Null);
Assert.That(selectedModel, Is.Null);
});

var firstSourceRow = treeView.Find(".dxbl-treeview-item-container");
firstSourceRow.Click();

Assert.Multiple(() =>
{
Assert.That(treeView.Instance.GetSelectedNodeInfo(), Is.Not.Null);
Assert.That(selectedModel, Is.Not.Null);
});
}

[Test]
public void VerifyIsModelSelectionEnabled()
{
Assert.That(() => this.renderedComponent.FindComponent<DxComboBox<IterationData, IterationData>>(), Throws.TypeOf<ComponentNotFoundException>());

this.renderedComponent = this.context.RenderComponent<ElementDefinitionTree>(parameters =>
{
parameters
.Add(p => p.IsModelSelectionEnabled, true);
});

Assert.That(this.renderedComponent.FindComponent<DxComboBox<IterationData, IterationData>>(), Is.Not.Null);
}

[Test]
public void VerifyInitialIteration()
{
var iteration = new Iteration
{
Iid = Guid.NewGuid(),
IterationSetup = new IterationSetup
{
IterationNumber = 1,
Container = new EngineeringModelSetup
{
Iid = Guid.NewGuid(),
Name = "ModelName",
ShortName = "ModelShortName"
}
}
};

this.elementDefinitionTreeViewModel.VerifySet(x => x.Iteration = iteration, Times.Never);

this.renderedComponent = this.context.RenderComponent<ElementDefinitionTree>(parameters =>
{
parameters
.Add(p => p.InitialIteration, iteration);
});

this.elementDefinitionTreeViewModel.VerifySet(x => x.Iteration = iteration, Times.Once);
}

[Test]
public void VerifyInitialIterationChangeFromViewModel()
{
var iteration1 = new Iteration
{
Iid = Guid.NewGuid(),
IterationSetup = new IterationSetup
{
IterationNumber = 1,
Container = new EngineeringModelSetup
{
Iid = Guid.NewGuid(),
Name = "ModelName",
ShortName = "ModelShortName"
}
}
};

var iteration2 = new Iteration
{
Iid = Guid.NewGuid(),
IterationSetup = new IterationSetup
{
IterationNumber = 2,
Container = iteration1.IterationSetup.Container
}
};

this.elementDefinitionTreeViewModel.VerifySet(x => x.Iteration = iteration1, Times.Never);

this.renderedComponent = this.context.RenderComponent<ElementDefinitionTree>(parameters =>
{
parameters
.Add(p => p.InitialIteration, iteration1);
});

this.elementDefinitionTreeViewModel.VerifySet(x => x.Iteration = iteration1, Times.Once);
this.elementDefinitionTreeViewModel.Setup(x => x.Iteration).Returns(iteration2);

this.renderedComponent.Render();

Assert.That(this.renderedComponent.Instance.InitialIteration, Is.EqualTo(iteration2));
}

[Test]
public void VerifyDragIsNotAllowed()
{
var firstItem = this.renderedComponent.Find(".dxbl-text").FirstElementChild;

Assert.Multiple(() =>
{
Assert.That(firstItem, Is.Not.Null);
Assert.That(firstItem.InnerHtml, Contains.Substring("Test1"));
Assert.That(firstItem.Attributes.Length, Is.EqualTo(1));
});
}

[Test]
public void VerifyDragIsAllowed()
{
this.renderedComponent = this.context.RenderComponent<ElementDefinitionTree>(parameters =>
{
parameters
.Add(p => p.AllowDrag, true);
});

var firstItem = this.renderedComponent.Find(".dxbl-text").FirstElementChild;

Assert.Multiple(() =>
{
Assert.That(firstItem, Is.Not.Null);
Assert.That(firstItem.InnerHtml, Contains.Substring("Test1"));
Assert.That(firstItem.Attributes.Length, Is.EqualTo(9));
});
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,6 @@ public void VerifySelectIteration()
Assert.That(this.viewModel.Description, Is.EqualTo("Please select a model"));
Assert.That(this.viewModel.Iteration, Is.Null);
Assert.That(this.viewModel.Iterations.Count, Is.EqualTo(2));
Assert.That(this.viewModel.SelectedElementDefinition, Is.Null);
Assert.That(this.viewModel.SelectedIterationData, Is.Null);
Assert.That(this.viewModel.Rows.Count, Is.EqualTo(0));
});
Expand All @@ -153,7 +152,6 @@ public void VerifySelectIteration()
Assert.That(this.viewModel.Description, Is.EqualTo(expectedIterationData.IterationName));
Assert.That(this.viewModel.Iteration, Is.EqualTo(this.iteration));
Assert.That(this.viewModel.Iterations.Count, Is.EqualTo(2));
Assert.That(this.viewModel.SelectedElementDefinition, Is.Null);
Assert.That(this.viewModel.SelectedIterationData, Is.EqualTo(expectedIterationData));
Assert.That(this.viewModel.Rows.Count, Is.EqualTo(2));
});
Expand All @@ -170,7 +168,6 @@ public void VerifyUpdatedElement()
Assert.That(this.viewModel.Description, Is.EqualTo(expectedIterationData.IterationName));
Assert.That(this.viewModel.Iteration, Is.EqualTo(this.iteration));
Assert.That(this.viewModel.Iterations.Count, Is.EqualTo(2));
Assert.That(this.viewModel.SelectedElementDefinition, Is.Null);
Assert.That(this.viewModel.SelectedIterationData, Is.EqualTo(expectedIterationData));
Assert.That(this.viewModel.Rows.Count, Is.EqualTo(2));
});
Expand Down Expand Up @@ -198,7 +195,6 @@ public void VerifyRemoveAndAddElement()
Assert.That(this.viewModel.Description, Is.EqualTo(expectedIterationData.IterationName));
Assert.That(this.viewModel.Iteration, Is.EqualTo(this.iteration));
Assert.That(this.viewModel.Iterations.Count, Is.EqualTo(2));
Assert.That(this.viewModel.SelectedElementDefinition, Is.Null);
Assert.That(this.viewModel.SelectedIterationData, Is.EqualTo(expectedIterationData));
Assert.That(this.viewModel.Rows.Count, Is.EqualTo(2));
});
Expand Down
49 changes: 16 additions & 33 deletions COMETwebapp/Components/MultiModelEditor/ElementDefinitionTree.razor
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
------------------------------------------------------------------------------->
@using COMET.Web.Common.Model
@using COMETwebapp.ViewModels.Components.MultiModelEditor.Rows
@using CDP4JsonSerializer.JsonConverter
@inject IJSRuntime JSRuntime

<div style = "height:50px">
Expand Down Expand Up @@ -52,7 +51,7 @@ else
</div>
<DxTreeView @ref="this.TreeView" Data="@this.ViewModel.Rows"
CssClass="sticky-scrollable-column"
SelectionChanged="args => { this.SelectionChanged.InvokeAsync(args.NodeInfo?.DataItem as ElementBaseTreeRowViewModel); }"
SelectionChanged="args => {this.SelectionChanged.InvokeAsync(args.NodeInfo?.DataItem as ElementBaseTreeRowViewModel); }"
AllowSelectNodes="true"
SizeMode="SizeMode.Small"
AnimationType="LayoutAnimationType.None">
Expand All @@ -61,45 +60,29 @@ else
var dataItem = (ElementBaseTreeRowViewModel)context.DataItem;
var draggable = this.AllowDrag && this.AllowNodeDrag.Invoke(this, dataItem);
var isTopElement = dataItem is ElementDefinitionTreeRowViewModel { IsTopElement: true };
var style = isTopElement ? "font-weight-bold" : string.Empty;
var cssClass = isTopElement ? "font-weight-bold" : string.Empty;
}

@if (draggable)
{
<div class="@style @(this.AllowDrop && this.dragOverNode == dataItem && this.AllowNodeDrop ? "treeview-item-drag-over" : "")"
draggable="@(this.AllowDrag ? "true" : "false")"
dropzone="@(this.AllowDrop && this.dragOverNode == dataItem && this.AllowNodeDrop ? "move" : "")"
@ondragstart="@(async () => await this.DragStartAsync(dataItem))"
@ondragend="@(async () => await this.DragEndAsync(dataItem))"
ondragover="@(this.AllowDrop && this.dragOverNode == dataItem && this.AllowNodeDrop ? "event.preventDefault();" : "")"
@ondragenter="@(async () => await this.DragEnterAsync(dataItem))"
@ondragleave="@(async () => await this.DragLeaveAsync(dataItem))"
@ondrop="@(async () => await this.DropAsync(dataItem))">
@dataItem.ElementName <span>
<button class="starion-pill" title="Owning Domain Of Expertise: @dataItem.OwnerShortName">@dataItem.OwnerShortName</button>
</span>
@foreach (var categoryShortName in dataItem.ElementBase.GetAllCategories().Select(x => x.ShortName))
{
<span>
<button class="starion-pill" style="background-color:aliceblue !important;" title="Category: @categoryShortName">@categoryShortName</button>
</span>
}
</div>
<ElementDefinitionTreeItem
CssClass="@($"{cssClass} {(this.AllowDrop && this.dragOverNode == dataItem && this.AllowNodeDrop ? "treeview-item-drag-over" : "")}")"
ElementBaseTreeRowViewModel="@dataItem"
draggable="@(this.AllowDrag ? "true" : "false")"
dropzone="@(this.AllowDrop && this.dragOverNode == dataItem && this.AllowNodeDrop ? "move" : "")"
@ondragstart="@(async () => await this.DragStartAsync(dataItem))"
@ondragend="@(async () => await this.DragEndAsync(dataItem))"
ondragover="@(this.AllowDrop && this.dragOverNode == dataItem && this.AllowNodeDrop ? "event.preventDefault();" : "")"
@ondragenter="@(async () => await this.DragEnterAsync(dataItem))"
@ondragleave="@(async () => await this.DragLeaveAsync(dataItem))"
@ondrop="@(async () => await this.DropAsync(dataItem))"
/>
}
else
{
<div>
@dataItem.ElementName <span>
<button class="starion-pill" title="Owning Domain Of Expertise: @dataItem.OwnerShortName">@dataItem.OwnerShortName</button>
</span>
@foreach (var categoryShortName in dataItem.ElementBase.GetAllCategories().Select(x => x.ShortName))
{
<span>
<button class="starion-pill" style="background-color:aliceblue !important;" title="Category: @categoryShortName">@categoryShortName</button>
</span>
}
</div>
<ElementDefinitionTreeItem CssClass="@cssClass" ElementBaseTreeRowViewModel="@dataItem" />
}

</NodeTextTemplate>
<DataMappings>
<DxTreeViewDataMapping Children="Rows" Text="ElementName"/>
Expand Down
Loading

0 comments on commit ee5cfb3

Please sign in to comment.