Skip to content

Commit

Permalink
Fix #475: Added EngineeringModelId inside Template and improvement (#492
Browse files Browse the repository at this point in the history
)
  • Loading branch information
antoineatstariongroup authored Jan 8, 2024
1 parent e89974f commit 1611f87
Show file tree
Hide file tree
Showing 13 changed files with 303 additions and 25 deletions.
3 changes: 2 additions & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@
**/docker-compose*
**/Dockerfile*
**/obj
!nginx.conf
!nginx.conf
switcher.json
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -352,3 +352,5 @@ MigrationBackup/

# Jetbrains folders
.idea/

switcher.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="SingleEngineeringModelApplicationTemplateTestFixture.cs" company="RHEA System S.A.">
// Copyright (c) 2024 RHEA System S.A.
//
// Authors: Sam Gerené, Alex Vorobiev, Alexander van Delft, Jaime Bernar, Théate Antoine
//
// This file is part of COMET WEB Community Edition
// The COMET WEB Community Edition is the RHEA Web Application implementation of ECSS-E-TM-10-25
// Annex A and Annex C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// </copyright>
// --------------------------------------------------------------------------------------------------------------------

namespace COMET.Web.Common.Tests.Components.Applications
{
using Bunit;

using CDP4Common.EngineeringModelData;
using CDP4Common.Extensions;

using CDP4Dal;

using COMET.Web.Common.Components;
using COMET.Web.Common.Components.Applications;
using COMET.Web.Common.Components.Selectors;
using COMET.Web.Common.Model.Configuration;
using COMET.Web.Common.Services.ConfigurationService;
using COMET.Web.Common.Services.SessionManagement;
using COMET.Web.Common.Services.StringTableService;
using COMET.Web.Common.Test.Helpers;
using COMET.Web.Common.ViewModels.Components;
using COMET.Web.Common.ViewModels.Components.Applications;
using COMET.Web.Common.ViewModels.Components.Selectors;

using DynamicData;

using Microsoft.AspNetCore.Components;
using Microsoft.Extensions.DependencyInjection;

using Moq;

using NUnit.Framework;

using TestContext = Bunit.TestContext;

[TestFixture]
public class SingleEngineeringModelApplicationTemplateTestFixture
{
private Mock<ISingleEngineeringModelApplicationTemplateViewModel> viewModel;
private List<EngineeringModel> openEngineeringModels;
private TestContext context;

[SetUp]
public void Setup()
{
this.context = new TestContext();
this.viewModel = new Mock<ISingleEngineeringModelApplicationTemplateViewModel>();

this.openEngineeringModels = [];
var sessionService = new Mock<ISessionService>();
sessionService.Setup(x => x.OpenEngineeringModels).Returns(this.openEngineeringModels);
sessionService.Setup(x => x.OpenIterations).Returns(new SourceList<Iteration>());
var session = new Mock<ISession>();
session.Setup(x => x.DataSourceUri).Returns("http://localhost:5000");
sessionService.Setup(x => x.Session).Returns(session.Object);
this.viewModel.Setup(x => x.SessionService).Returns(sessionService.Object);
var mockConfigurationService = new Mock<IConfigurationService>();
mockConfigurationService.Setup(x => x.ServerConfiguration).Returns(new ServerConfiguration());
this.context.Services.AddSingleton(this.viewModel.Object);
this.context.Services.AddSingleton<IOpenModelViewModel, OpenModelViewModel>();
this.context.Services.AddSingleton(mockConfigurationService.Object);
this.context.Services.AddSingleton(new Mock<IStringTableService>().Object);
this.context.Services.AddSingleton(sessionService.Object);
this.context.ConfigureDevExpressBlazor();
}

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

[Test]
public void VerifyWithEngineeringModelIdParameter()
{
this.openEngineeringModels.Add(new EngineeringModel
{
Iid = Guid.NewGuid()
});

this.viewModel.Setup(x => x.OnThingSelect(It.IsAny<EngineeringModel>())).Callback((EngineeringModel engineeringModel) => this.viewModel.Setup(x => x.SelectedThing).Returns(engineeringModel));
var renderer = this.context.RenderComponent<SingleEngineeringModelApplicationTemplate>(parameters => { parameters.Add(p => p.EngineeringModelId, Guid.NewGuid()); });

Assert.Multiple(() =>
{
Assert.That(renderer.Instance.EngineeringModelId, Is.EqualTo(this.openEngineeringModels[0].Iid));
this.viewModel.Verify(x => x.OnThingSelect(this.openEngineeringModels[0]), Times.Once);
});

this.viewModel.Setup(x => x.SelectedThing).Returns((EngineeringModel)null);
_ = this.context.RenderComponent<SingleEngineeringModelApplicationTemplate>(parameters => { parameters.Add(p => p.EngineeringModelId, this.openEngineeringModels[0].Iid); });

this.viewModel.Verify(x => x.OnThingSelect(this.openEngineeringModels[0]), Times.Exactly(2));

this.viewModel.Setup(x => x.SelectedThing).Returns(new EngineeringModel
{
Iid = Guid.NewGuid()
});

renderer = this.context.RenderComponent<SingleEngineeringModelApplicationTemplate>(parameters => { parameters.Add(p => p.EngineeringModelId, this.openEngineeringModels[0].Iid); });

Assert.Multiple(() =>
{
Assert.That(renderer.Instance.EngineeringModelId, Is.EqualTo(this.viewModel.Object.SelectedThing.Iid));
this.viewModel.Verify(x => x.OnThingSelect(this.openEngineeringModels[0]), Times.Exactly(2));
});
}

[Test]
public void VerifyWithoutEngineeringModelIdParameter()
{
this.openEngineeringModels.Add(new EngineeringModel()
{
Iid = Guid.NewGuid()
});

var renderer = this.context.RenderComponent<SingleEngineeringModelApplicationTemplate>(parameters =>
{
parameters.Add(p => p.Body, builder =>
{
builder.OpenElement(0, "p");
builder.AddContent(1, "body");
builder.CloseComponent();
});
});

var navigationManager = this.context.Services.GetService<NavigationManager>();

Assert.Multiple(() =>
{
Assert.That(navigationManager.Uri, Is.EqualTo("http://localhost/"));
this.viewModel.Verify(x => x.OnThingSelect(this.openEngineeringModels[0]), Times.Exactly(2));
});

this.viewModel.Setup(x => x.SelectedThing).Returns(this.openEngineeringModels[0]);
renderer.Instance.SetCorrectUrl();
var engineeringModel = this.viewModel.Object.SelectedThing;

Assert.Multiple(() =>
{
Assert.That(navigationManager.Uri, Does.Contain("localhost%3A5000"));
Assert.That(navigationManager.Uri, Does.Contain(engineeringModel.Iid.ToShortGuid()));
});

renderer.Render();

var pElement = renderer.Find("p");
Assert.That(pElement.TextContent, Is.EqualTo("body"));

this.openEngineeringModels.Add(new EngineeringModel());

renderer = this.context.RenderComponent<SingleEngineeringModelApplicationTemplate>(parameters =>
{
parameters.Add(p => p.Body, builder =>
{
builder.OpenElement(0, "p");
builder.AddContent(1, "body");
builder.CloseComponent();
});
});

Assert.That(() => renderer.FindComponent<EngineeringModelSelector>(), Throws.Exception);
this.viewModel.Verify(x => x.AskToSelectThing(), Times.Once);
this.viewModel.Setup(x => x.IsOnSelectionMode).Returns(true);
this.viewModel.Setup(x => x.EngineeringModelSelectorViewModel).Returns(new EngineeringModelSelectorViewModel());
renderer.Render();
Assert.That(() => renderer.FindComponent<EngineeringModelSelector>(), Throws.Nothing);
this.openEngineeringModels.Clear();
this.viewModel.Setup(x => x.SelectedThing).Returns((EngineeringModel)null);
renderer.Instance.SetCorrectUrl();

renderer.Render();

Assert.Multiple(() =>
{
Assert.That(navigationManager.Uri, Is.EqualTo("http://localhost/"));
Assert.That(() => renderer.FindComponent<OpenModel>(), Throws.Nothing);
});
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -108,13 +108,19 @@ public void VerifyWithIterationIdParameter()
}
});

this.viewModel.Setup(x => x.OnThingSelect(It.IsAny<Iteration>())).Callback((Iteration iteration) => this.viewModel.Setup(x => x.SelectedThing).Returns(iteration));
var renderer = this.context.RenderComponent<SingleIterationApplicationTemplate>(parameters => { parameters.Add(p => p.IterationId, Guid.NewGuid()); });

Assert.That(renderer.Instance.IterationId, Is.EqualTo(Guid.Empty));
Assert.Multiple(() =>
{
Assert.That(renderer.Instance.IterationId, Is.EqualTo(this.openIterations.Items.First().Iid));
this.viewModel.Verify(x => x.OnThingSelect(this.openIterations.Items.First()), Times.Once);
});

this.viewModel.Setup(x => x.SelectedThing).Returns((Iteration)null);
_ = this.context.RenderComponent<SingleIterationApplicationTemplate>(parameters => { parameters.Add(p => p.IterationId, this.openIterations.Items.First().Iid); });

this.viewModel.Verify(x => x.OnThingSelect(this.openIterations.Items.First()), Times.Once);
this.viewModel.Verify(x => x.OnThingSelect(this.openIterations.Items.First()), Times.Exactly(2));

this.viewModel.Setup(x => x.SelectedThing).Returns(new Iteration
{
Expand All @@ -132,8 +138,8 @@ public void VerifyWithIterationIdParameter()

Assert.Multiple(() =>
{
Assert.That(renderer.Instance.IterationId, Is.EqualTo(this.openIterations.Items.First().Iid));
this.viewModel.Verify(x => x.OnThingSelect(this.openIterations.Items.First()), Times.Once);
Assert.That(renderer.Instance.IterationId, Is.EqualTo(this.viewModel.Object.SelectedThing.Iid));
this.viewModel.Verify(x => x.OnThingSelect(this.openIterations.Items.First()), Times.Exactly(2));
});
}

Expand Down Expand Up @@ -167,7 +173,7 @@ public void VerifyWithoutIterationIdParameter()
Assert.Multiple(() =>
{
Assert.That(navigationManager.Uri, Is.EqualTo("http://localhost/"));
this.viewModel.Verify(x => x.OnThingSelect(this.openIterations.Items.First()), Times.Once);
this.viewModel.Verify(x => x.OnThingSelect(this.openIterations.Items.First()), Times.Exactly(2));
});

this.viewModel.Setup(x => x.SelectedThing).Returns(this.openIterations.Items.First());
Expand Down
2 changes: 1 addition & 1 deletion COMET.Web.Common/COMET.Web.Common.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
</PackageReleaseNotes>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="CDP4ServicesDal-CE" Version="24.2.0" />
<PackageReference Include="CDP4ServicesDal-CE" Version="24.4.0" />
<PackageReference Include="DevExpress.Blazor" Version="23.1.4" />
<PackageReference Include="FluentResults" Version="3.15.2" />
<PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="7.0.4" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
<EngineeringModelSelector ViewModel="@this.ViewModel.EngineeringModelSelectorViewModel"/>
</DxPopup>

@if (this.ViewModel.SessionService.OpenIterations.Count == 0)
@if (this.ViewModel.SessionService.OpenEngineeringModels.Count == 0)
{
<DxPopup Visible="true" HeaderText="Open a Model" ShowFooter="false" CloseOnEscape="false" CloseOnOutsideClick="false"
ShowCloseButton="false">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,76 @@ namespace COMET.Web.Common.Components.Applications
{
using CDP4Common.EngineeringModelData;

using COMET.Web.Common.ViewModels.Components.Applications;
using COMET.Web.Common.Extensions;
using COMET.Web.Common.Utilities;

using Microsoft.AspNetCore.Components;

/// <summary>
/// Shared component that will englobe all applications where only one <see cref="EngineeringModel" /> needs to be selected
/// </summary>
public partial class SingleEngineeringModelApplicationTemplate
{
/// <summary>
/// The <see cref="Guid" /> of selected <see cref="EngineeringModel" />
/// </summary>
[Parameter]
public Guid EngineeringModelId { get; set; }

/// <summary>
/// Method invoked when the component is ready to start, having received its
/// initial parameters from its parent in the render tree.
/// </summary>
protected override void OnInitialized()
{
this.UpdateProperties();
base.OnInitialized();
}

/// <summary>
/// Method invoked when the component has received parameters from its parent in
/// the render tree, and the incoming values have been assigned to properties.
/// </summary>
protected override void OnParametersSet()
{
base.OnParametersSet();
this.UpdateProperties();
}

/// <summary>
/// Update properties of the viewmodel based on provided parameters
/// </summary>
private void UpdateProperties()
{
if (this.EngineeringModelId == Guid.Empty)
{
switch (this.ViewModel.SessionService.OpenEngineeringModels.Count)
{
case 1:
this.ViewModel.OnThingSelect(this.ViewModel.SessionService.OpenEngineeringModels.First());
break;
case > 1:
this.ViewModel.AskToSelectThing();
break;
}
}
else if (this.EngineeringModelId != Guid.Empty && this.ViewModel.SelectedThing == null)
{
this.ViewModel.OnThingSelect(this.ViewModel.SessionService.OpenEngineeringModels.FirstOrDefault(x => x.Iid == this.EngineeringModelId));
}

this.EngineeringModelId = this.ViewModel.SelectedThing?.Iid ?? Guid.Empty;
}

/// <summary>
/// Set URL parameters based on the current context
/// </summary>
/// <param name="currentOptions">A <see cref="Dictionary{TKey,TValue}" /> of URL parameters</param>
protected override void SetUrlParameters(Dictionary<string, string> currentOptions)
{
base.SetUrlParameters(currentOptions);

currentOptions[QueryKeys.ModelKey] = this.ViewModel.SelectedThing.Iid.ToShortGuid();
}
}
}
Loading

0 comments on commit 1611f87

Please sign in to comment.