Skip to content

Commit

Permalink
MultiModelEditor; fixes #733; fixes #734
Browse files Browse the repository at this point in the history
* [Add] MultiModelEditor
* Bugfixes, make copy two-way and show pills
* Review Comments
* [FIX] - Copy problem for two-way drag-drop source <=> target
* Review comments and fix unit tests
* Add SonarLint settings
* SonarQube fixes
* More SQ comments
* Final SQ Comments
* SQ
* SQ
* Add coverage
* Add Creator tests
* SQ
* Coverage exclusion
* Add ElementBaseTreeRowViewModel tests
* Add xxTreeRowViewModel tests
* Add ElementDefinitionTree unit tests
* Refcatoring and first version ElementDefinitionTree tests
* [FIX] sizing issues
* [FIX] Alignment
* [FIX] Unit tests
* [Add] Search in Treeview
* Implement Copy Settings
* Remove Multi prefix and remove old ModelEditor
* Fix unit tests
* Small sizing issue
  • Loading branch information
lxatstariongroup authored Jan 15, 2025
1 parent 1da23b6 commit 2d72828
Show file tree
Hide file tree
Showing 61 changed files with 3,896 additions and 1,327 deletions.
4 changes: 4 additions & 0 deletions .sonarlint/COMETwebapp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"SonarCloudOrganization": "stariongroup",
"ProjectKey": "STARIONGROUP_COMET-WEB-Community-Edition"
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ public class CardViewTestFixture
private TestClass testClass2 = new ();
private TestClass testClass3 = new ();
private TestClass[] testClasses;
private string[] searchFields = new[] { "Id", "Name" };
private string[] sortFields = new[] { string.Empty, "Id", "Name" };
private readonly string[] searchFields = ["Id", "Name"];
private readonly string[] sortFields = [string.Empty, "Id", "Name"];

private static RenderFragment<TestClass> NormalTemplate()
{
Expand Down Expand Up @@ -110,7 +110,8 @@ public void VerifyComponent()
parameters
.Add(p => p.Items, this.testClasses)
.Add(p => p.ItemSize, 150)
.Add(p => p.ItemTemplate, NormalTemplate());
.Add(p => p.ItemTemplate, NormalTemplate())
.Add(p => p.ScrollableAreaCssClass, "scrollable-area");
});

var cardView = component;
Expand All @@ -122,6 +123,7 @@ public void VerifyComponent()
Assert.That(cardView.Instance.ItemSize, Is.EqualTo(150));
Assert.That(cardView.Instance.SearchFields, Is.EquivalentTo(this.searchFields));
Assert.That(cardView.Instance.SortFields, Is.EquivalentTo(this.sortFields));
Assert.That(cardView.Instance.ScrollableAreaCssClass, Is.EqualTo("scrollable-area"));
});

var textBoxParentComponent = component.Find("#search-textbox");
Expand All @@ -140,6 +142,10 @@ public void VerifyComponent()
Assert.That(comboBoxParentComponent.Attributes.Single(x => x.Name == "style").Value.Contains("visibility:block"), Is.True);
});

var scrollableAreaComponent = component.Find(".scrollable-area");

Assert.That(scrollableAreaComponent, Is.Not.Null);

var cardFields = component.FindComponents<CardField<TestClass>>();

Assert.Multiple(() =>
Expand Down Expand Up @@ -430,7 +436,6 @@ public async Task VerifySortComponent()

cardFields = component.FindComponents<CardField<TestClass>>();

//var sortedTestClasses = this.testClasses.OrderBy(x => x.Id.ToString()).Select(x => x.Name).ToList();
var sortedTestClasses = this.testClasses.OrderBy(x => x.Id).Select(x => x.Name).ToList();
var sortedCarFields = cardFields.Where(x => x.Markup.StartsWith("Name-")).Select(x => x.Markup).ToList();

Expand Down
92 changes: 65 additions & 27 deletions COMET.Web.Common.Tests/Components/OpenModelTestFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,33 +59,13 @@ public class OpenModelTestFixture
private Mock<ISessionService> sessionService;
private Mock<IConfigurationService> configurationService;
private Mock<ICacheService> cacheService;
private List<EngineeringModelSetup> engineeringModels;

[SetUp]
public void Setup()
{
this.context = new TestContext();
this.sessionService = new Mock<ISessionService>();
this.configurationService = new Mock<IConfigurationService>();
this.cacheService = new Mock<ICacheService>();
this.viewModel = new OpenModelViewModel(this.sessionService.Object, this.configurationService.Object, this.cacheService.Object);
this.context.ConfigureDevExpressBlazor();
this.context.Services.AddSingleton<IOpenModelViewModel>(this.viewModel);

var stringTableService = new Mock<IStringTableService>();
this.context.Services.AddSingleton(stringTableService.Object);
}

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

[Test]
public async Task VerifyOpenModel()
{
var engineeringModels = new List<EngineeringModelSetup>
{
this.engineeringModels =
[
new()
{
Iid = Guid.NewGuid(),
Expand All @@ -99,6 +79,7 @@ public async Task VerifyOpenModel()
}
}
},

new()
{
Iid = Guid.NewGuid(),
Expand All @@ -109,7 +90,7 @@ public async Task VerifyOpenModel()
{
Iid = Guid.NewGuid(),
IterationNumber = 1,
FrozenOn = DateTime.Now - TimeSpan.FromDays(1)
FrozenOn = DateTimeOffset.Now.AddDays(-1).DateTime
},
new IterationSetup
{
Expand All @@ -118,10 +99,31 @@ public async Task VerifyOpenModel()
}
}
}
};
];

this.context = new TestContext();
this.sessionService = new Mock<ISessionService>();
this.configurationService = new Mock<IConfigurationService>();
this.cacheService = new Mock<ICacheService>();
this.viewModel = new OpenModelViewModel(this.sessionService.Object, this.configurationService.Object, this.cacheService.Object);
this.context.ConfigureDevExpressBlazor();
this.context.Services.AddSingleton<IOpenModelViewModel>(this.viewModel);

var stringTableService = new Mock<IStringTableService>();
this.context.Services.AddSingleton(stringTableService.Object);
}

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

[Test]
public async Task VerifyOpenModel()
{
this.sessionService.Setup(x => x.OpenIterations).Returns(new SourceList<Iteration>());
this.sessionService.Setup(x => x.GetParticipantModels()).Returns(engineeringModels);
this.sessionService.Setup(x => x.GetParticipantModels()).Returns(this.engineeringModels);
var renderer = this.context.RenderComponent<OpenModel>();
var layoutItems = renderer.FindComponents<DxFormLayoutItem>();

Expand Down Expand Up @@ -158,13 +160,49 @@ public async Task VerifyOpenModel()

this.viewModel.SelectedEngineeringModel = null;

var result = await this.viewModel.OpenSession();

Assert.Multiple(() =>
{
Assert.That(this.viewModel.SelectedDomainOfExpertise, Is.Null);
Assert.That(this.viewModel.SelectedIterationSetup, Is.Null);
Assert.That(this.viewModel.AvailableIterationSetups, Is.Empty);
Assert.That(this.viewModel.AvailablesDomainOfExpertises, Is.Empty);
Assert.That(async () => await this.viewModel.OpenSession(), Throws.Nothing);
Assert.That(result.IsFailed, Is.True);
Assert.That(result.Errors[0].Message, Is.EqualTo("The selected iteration and the domain of expertise should not be null"));
});
}

[Test]
public async Task VerifyOpenModelFails()
{
this.sessionService.Setup(x => x.OpenIterations).Returns(new SourceList<Iteration>());
this.sessionService.Setup(x => x.GetParticipantModels()).Returns(this.engineeringModels);
this.context.RenderComponent<OpenModel>();

this.sessionService.Setup(x => x.GetModelDomains(It.IsAny<EngineeringModelSetup>()))
.Returns(new List<DomainOfExpertise> { new() { Name = "Thermodynamic" } });

this.viewModel.SelectedEngineeringModel = this.viewModel.AvailableEngineeringModelSetups.First();
this.viewModel.SelectedDomainOfExpertise = this.viewModel.AvailablesDomainOfExpertises.First();
this.viewModel.SelectedIterationSetup = this.viewModel.AvailableIterationSetups.First();

var iteration = new Iteration(Guid.NewGuid(), null, null)
{
IterationSetup = this.engineeringModels.SelectMany(x => x.IterationSetup).Single(x => x.Iid == this.viewModel.SelectedIterationSetup.IterationSetupId)
};

var openIterations = new SourceList<Iteration>();
openIterations.Add(iteration);

this.sessionService.Setup(x => x.OpenIterations).Returns(openIterations);

var result = await this.viewModel.OpenSession();

Assert.Multiple(() =>
{
Assert.That(result.IsFailed, Is.True);
Assert.That(result.Errors[0].Message, Is.EqualTo("The selected iteration is already openened"));
});
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,14 @@ public class CompoundComponentSelectedEventTestFixture
[SetUp]
public void SetUp()
{
var parameterType = new CompoundParameterType()
var parameterType = new CompoundParameterType
{
Iid = Guid.NewGuid(),
};

var compoundValues = new List<string> { "1", "0", "3" };

var parameterValueSet = new ParameterValueSet()
var parameterValueSet = new ParameterValueSet
{
Iid = Guid.NewGuid(),
ValueSwitch = ParameterSwitchKind.MANUAL,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="CopyElementDefinitionCreatorTestFixture.cs" company="Starion Group S.A.">
// Copyright (c) 2015-2024 Starion Group S.A.
//
// Authors: Sam Gerené, Alex Vorobiev, Alexander van Delft, Jaime Bernar, Théate Antoine, Nabil Abbar
//
// This file is part of CDP4-COMET WEB Community Edition
// The CDP4-COMET WEB Community Edition is the Starion 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.Utilities
{
using System;
using System.Collections.Concurrent;
using System.Linq;

using CDP4Common.CommonData;
using CDP4Common.EngineeringModelData;
using CDP4Common.Types;

using CDP4Dal;
using CDP4Dal.Operations;

using COMET.Web.Common.Utilities;

using Moq;

using NUnit.Framework;

/// <summary>
/// Suite of tests for the <see cref="CopyElementDefinitionCreator"/> class
/// </summary>
[TestFixture]
public class CopyElementDefinitionCreatorTestFixture
{
private readonly Uri uri = new("http://test.com");
private Mock<ISession> session;
private Assembler asembler;
private ConcurrentDictionary<CacheKey, Lazy<Thing>> cache;
private CDPMessageBus messageBus;

private EngineeringModel model;
private Iteration iteration;
private ElementDefinition elementDef1;
private ElementDefinition elementDef2;
private Parameter parameter1;
private ParameterValueSet valueSet1;
private Parameter parameter2;
private ParameterValueSet valueSet2;
private ParameterOverride parameterOverride;
private ParameterOverrideValueSet overrideValueset;
private ElementUsage usage;

private ParameterSubscription sub1;
private ParameterSubscriptionValueSet subValueset1;
private ParameterSubscription sub2;
private ParameterSubscriptionValueSet subValueset2;

[SetUp]
public void SetUp()
{
this.messageBus = new CDPMessageBus();
this.session = new Mock<ISession>();
this.asembler = new Assembler(this.uri, this.messageBus);
this.cache = this.asembler.Cache;

this.session.Setup(x => x.Assembler).Returns(this.asembler);
this.session.Setup(x => x.CDPMessageBus).Returns(this.messageBus);

this.model = new EngineeringModel(Guid.NewGuid(), this.cache, this.uri);
this.iteration = new Iteration(Guid.NewGuid(), this.cache, this.uri);

this.elementDef1 = new ElementDefinition(Guid.NewGuid(), this.cache, this.uri);
this.elementDef2 = new ElementDefinition(Guid.NewGuid(), this.cache, this.uri);

this.parameter1 = new Parameter(Guid.NewGuid(), this.cache, this.uri);
this.valueSet1 = new ParameterValueSet(Guid.NewGuid(), this.cache, this.uri);
this.parameter2 = new Parameter(Guid.NewGuid(), this.cache, this.uri);
this.valueSet2 = new ParameterValueSet(Guid.NewGuid(), this.cache, this.uri);
this.usage = new ElementUsage(Guid.NewGuid(), this.cache, this.uri);

this.parameterOverride = new ParameterOverride(Guid.NewGuid(), this.cache, this.uri)
{ Parameter = this.parameter2 };

this.overrideValueset = new ParameterOverrideValueSet(Guid.NewGuid(), this.cache, this.uri)
{ ParameterValueSet = this.valueSet2 };

this.model.Iteration.Add(this.iteration);
this.iteration.Element.Add(this.elementDef1);
this.iteration.Element.Add(this.elementDef2);

this.elementDef1.Parameter.Add(this.parameter1);
this.parameter1.ValueSet.Add(this.valueSet1);

this.usage.ElementDefinition = this.elementDef2;
this.usage.ParameterOverride.Add(this.parameterOverride);
this.parameterOverride.ValueSet.Add(this.overrideValueset);

this.elementDef1.ContainedElement.Add(this.usage);

this.sub1 = new ParameterSubscription(Guid.NewGuid(), this.cache, this.uri);
this.sub2 = new ParameterSubscription(Guid.NewGuid(), this.cache, this.uri);

this.subValueset1 = new ParameterSubscriptionValueSet(Guid.NewGuid(), this.cache, this.uri)
{
SubscribedValueSet = this.valueSet1
};

this.subValueset2 = new ParameterSubscriptionValueSet(Guid.NewGuid(), this.cache, this.uri)
{
SubscribedValueSet = this.overrideValueset
};

this.sub1.ValueSet.Add(this.subValueset1);
this.sub2.ValueSet.Add(this.subValueset2);

this.parameter1.ParameterSubscription.Add(this.sub1);
this.parameterOverride.ParameterSubscription.Add(this.sub2);

this.cache.TryAdd(new CacheKey(this.model.Iid, null), new Lazy<Thing>(() => this.model));
this.cache.TryAdd(new CacheKey(this.iteration.Iid, null), new Lazy<Thing>(() => this.iteration));
this.cache.TryAdd(new CacheKey(this.elementDef1.Iid, this.iteration.Iid), new Lazy<Thing>(() => this.elementDef1));
this.cache.TryAdd(new CacheKey(this.elementDef2.Iid, this.iteration.Iid), new Lazy<Thing>(() => this.elementDef2));
this.cache.TryAdd(new CacheKey(this.usage.Iid, this.iteration.Iid), new Lazy<Thing>(() => this.usage));
this.cache.TryAdd(new CacheKey(this.parameter1.Iid, this.iteration.Iid), new Lazy<Thing>(() => this.parameter1));
this.cache.TryAdd(new CacheKey(this.parameter2.Iid, this.iteration.Iid), new Lazy<Thing>(() => this.parameter2));
this.cache.TryAdd(new CacheKey(this.valueSet1.Iid, this.iteration.Iid), new Lazy<Thing>(() => this.valueSet1));
this.cache.TryAdd(new CacheKey(this.valueSet2.Iid, this.iteration.Iid), new Lazy<Thing>(() => this.valueSet2));
this.cache.TryAdd(new CacheKey(this.parameterOverride.Iid, this.iteration.Iid), new Lazy<Thing>(() => this.parameterOverride));
this.cache.TryAdd(new CacheKey(this.overrideValueset.Iid, this.iteration.Iid), new Lazy<Thing>(() => this.overrideValueset));
this.cache.TryAdd(new CacheKey(this.sub1.Iid, this.iteration.Iid), new Lazy<Thing>(() => this.sub1));
this.cache.TryAdd(new CacheKey(this.sub2.Iid, this.iteration.Iid), new Lazy<Thing>(() => this.sub2));
this.cache.TryAdd(new CacheKey(this.subValueset1.Iid, this.iteration.Iid), new Lazy<Thing>(() => this.subValueset1));
this.cache.TryAdd(new CacheKey(this.subValueset2.Iid, this.iteration.Iid), new Lazy<Thing>(() => this.subValueset2));
}

[Test]
public async Task VerifyThatCopyWithUsageWorks()
{
var copy = new CopyElementDefinitionCreator(this.session.Object);
await copy.CopyAsync(this.elementDef1, true);
this.session.Verify(x => x.Write(It.Is<OperationContainer>(c => c.Operations.Count(op => op.OperationKind == OperationKind.Create) == 10)));
}

[Test]
public async Task VerifyThatCopyWithoutUsageWorks()
{
var copy = new CopyElementDefinitionCreator(this.session.Object);
await copy.CopyAsync(this.elementDef1, false);
this.session.Verify(x => x.Write(It.Is<OperationContainer>(c => c.Operations.Count(op => op.OperationKind == OperationKind.Create) == 5)));
}
}
}
Loading

0 comments on commit 2d72828

Please sign in to comment.