From 43f8a13981869fc2beb061d1f5c612ddc3da1c95 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jo=C3=A3o=20Rua?=
<140734849+joao4all@users.noreply.github.com>
Date: Thu, 23 May 2024 09:47:49 +0100
Subject: [PATCH] Feat #634 [Implement] The use of a toast/message notitication
to indicate success or failure to a user on Reference Data, Server
Administration and Engineering Model pages (#638)
---
.../NotificationServiceTestFixture.cs | 77 ++++++++----
.../SessionServiceTestFixture.cs | 12 +-
COMET.Web.Common/App.razor | 2 -
.../INotificationService.cs | 9 ++
.../NotificationService.cs | 38 +++---
.../SessionManagement/ISessionService.cs | 20 +++
.../SessionManagement/SessionService.cs | 39 +++++-
.../CategoriesTableTestFixture.cs | 8 +-
.../UserManagementTableTestFixture.cs | 6 +-
.../NotificationComponentTestFixture.cs | 119 ++++++++++++++++++
...ommonFileStoreTableViewModelTestFixture.cs | 4 +-
.../OptionsTableViewModelTestFixture.cs | 4 +-
.../PublicationsTableViewModelTestFixture.cs | 6 +-
...surementScalesTableViewModelTestFixture.cs | 28 ++++-
...asurementUnitsTableViewModelTestFixture.cs | 2 +-
...ParameterTypesTableViewModelTestFixture.cs | 23 +++-
...insOfExpertiseTableViewModelTestFixture.cs | 4 +-
.../ActiveDomainsTableViewModelTestFixture.cs | 6 +-
...ineeringModelsTableViewModelTestFixture.cs | 2 +-
.../ParticipantsTableViewModelTestFixture.cs | 6 +-
.../OrganizationsTableViewModelTestFixture.cs | 4 +-
...rticipantRolesTableViewModelTestFixture.cs | 2 +-
.../PersonRolesTableViewModelTestFixture.cs | 2 +-
.../SelectedDeprecatableDataItemBase.razor.cs | 8 +-
COMETwebapp/Extensions/ResultExtensions.cs | 76 +++++++++++
.../Extensions/ServiceCollectionExtensions.cs | 1 -
.../ReferenceData/ReferenceDataPage.razor | 1 +
COMETwebapp/Pages/_Host.cshtml | 1 +
COMETwebapp/Program.cs | 3 +-
.../Shared/TopMenuEntry/AboutMenu.razor | 10 +-
.../Shared/TopMenuEntry/AboutMenu.razor.cs | 16 +--
.../TopMenuEntry/NotificationComponent.razor | 26 ++++
.../NotificationComponent.razor.cs | 111 ++++++++++++++++
.../BaseDataItemTableViewModel.cs | 29 +++--
.../DeletableDataItemTableViewModel.cs | 7 +-
.../DeprecatableDataItemTableViewModel.cs | 5 +-
.../CommonFileStoreTableViewModel.cs | 2 +-
.../Options/OptionsTableViewModel.cs | 2 +-
.../PublicationsTableViewModel.cs | 2 +-
.../Categories/CategoriesTableViewModel.cs | 2 +-
.../MeasurementScalesTableViewModel.cs | 73 ++++++-----
.../MeasurementUnitsTableViewModel.cs | 2 +-
.../ParameterTypeTableViewModel.cs | 82 ++++++------
.../DomainsOfExpertiseTableViewModel.cs | 2 +-
.../ActiveDomainsTableViewModel.cs | 2 +-
.../EngineeringModelsTableViewModel.cs | 2 +-
.../ParticipantsTableViewModel.cs | 2 +-
.../OrganizationsTableViewModel.cs | 2 +-
.../Roles/ParticipantRolesTableViewModel.cs | 2 +-
.../Roles/PersonRolesTableViewModel.cs | 2 +-
.../UserManagementTableViewModel.cs | 2 +-
.../wwwroot/Scripts/bootstrap.bundle.min.js | 7 ++
52 files changed, 715 insertions(+), 190 deletions(-)
create mode 100644 COMETwebapp.Tests/Shared/TopMenuEntry/NotificationComponentTestFixture.cs
create mode 100644 COMETwebapp/Extensions/ResultExtensions.cs
create mode 100644 COMETwebapp/Shared/TopMenuEntry/NotificationComponent.razor
create mode 100644 COMETwebapp/Shared/TopMenuEntry/NotificationComponent.razor.cs
create mode 100644 COMETwebapp/wwwroot/Scripts/bootstrap.bundle.min.js
diff --git a/COMET.Web.Common.Tests/Services/NotificationService/NotificationServiceTestFixture.cs b/COMET.Web.Common.Tests/Services/NotificationService/NotificationServiceTestFixture.cs
index 068325af..d178b731 100644
--- a/COMET.Web.Common.Tests/Services/NotificationService/NotificationServiceTestFixture.cs
+++ b/COMET.Web.Common.Tests/Services/NotificationService/NotificationServiceTestFixture.cs
@@ -1,25 +1,24 @@
// --------------------------------------------------------------------------------------------------------------------
//
-// Copyright (c) 2023-2024 Starion Group S.A.
+// Copyright (c) 2024 Starion Group S.A.
//
-// Authors: Sam Gerené, Alex Vorobiev, Alexander van Delft, Jaime Bernar, Théate Antoine, Nabil Abbar
+// Authors: Sam Gerené, Alex Vorobiev, Alexander van Delft, Jaime Bernar, Théate Antoine, João Rua
//
-// 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.
+// 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.
//
-// 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
+// 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.
//
-// 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.
+// 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 .
//
// --------------------------------------------------------------------------------------------------------------------
@@ -27,31 +26,55 @@ namespace COMET.Web.Common.Tests.Services.NotificationService
{
using COMET.Web.Common.Services.NotificationService;
+ using DynamicData;
+
+ using FluentResults;
+
using NUnit.Framework;
[TestFixture]
public class NotificationServiceTestFixture
{
+ private NotificationService notificationService;
+
+ [SetUp]
+ public void Setup()
+ {
+ this.notificationService = new NotificationService();
+ }
+
[Test]
public void VerifyNotificationService()
{
- var notificationService = new NotificationService();
- Assert.That(notificationService.NotificationCount, Is.EqualTo(0));
+ Assert.That(this.notificationService.NotificationCount, Is.EqualTo(0));
+
+ this.notificationService.AddNotifications(-2);
+ Assert.That(this.notificationService.NotificationCount, Is.EqualTo(0));
+
+ this.notificationService.AddNotifications(4);
+ Assert.That(this.notificationService.NotificationCount, Is.EqualTo(4));
- notificationService.AddNotifications(-2);
- Assert.That(notificationService.NotificationCount, Is.EqualTo(0));
+ this.notificationService.RemoveNotifications(1);
+ Assert.That(this.notificationService.NotificationCount, Is.EqualTo(3));
- notificationService.AddNotifications(4);
- Assert.That(notificationService.NotificationCount, Is.EqualTo(4));
+ this.notificationService.RemoveNotifications(-1);
+ Assert.That(this.notificationService.NotificationCount, Is.EqualTo(3));
- notificationService.RemoveNotifications(1);
- Assert.That(notificationService.NotificationCount, Is.EqualTo(3));
+ this.notificationService.RemoveNotifications(5);
+ Assert.That(this.notificationService.NotificationCount, Is.EqualTo(0));
+ }
- notificationService.RemoveNotifications(-1);
- Assert.That(notificationService.NotificationCount, Is.EqualTo(3));
+ [Test]
+ public void VerifyResultsList()
+ {
+ Assert.Multiple(() =>
+ {
+ Assert.That(this.notificationService.Results, Is.Not.Null);
+ Assert.That(this.notificationService.Results, Has.Count.EqualTo(0));
+ });
- notificationService.RemoveNotifications(5);
- Assert.That(notificationService.NotificationCount, Is.EqualTo(0));
+ this.notificationService.Results.Add(new Result());
+ Assert.That(this.notificationService.Results, Has.Count.EqualTo(1));
}
}
}
diff --git a/COMET.Web.Common.Tests/Services/SessionManagement/SessionServiceTestFixture.cs b/COMET.Web.Common.Tests/Services/SessionManagement/SessionServiceTestFixture.cs
index 6c69950c..ac438c7b 100644
--- a/COMET.Web.Common.Tests/Services/SessionManagement/SessionServiceTestFixture.cs
+++ b/COMET.Web.Common.Tests/Services/SessionManagement/SessionServiceTestFixture.cs
@@ -30,6 +30,7 @@ namespace COMET.Web.Common.Tests.Services.SessionManagement
using CDP4Dal;
+ using COMET.Web.Common.Services.NotificationService;
using COMET.Web.Common.Services.SessionManagement;
using DynamicData;
@@ -46,13 +47,15 @@ public class SessionServiceTestFixture
private SessionService sessionService;
private readonly Uri uri = new("http://test.com/");
private CDPMessageBus messageBus;
+ private Mock notificationService;
[SetUp]
public void Setup()
{
var logger = new Mock>();
this.messageBus = new CDPMessageBus();
- this.sessionService = new SessionService(logger.Object, this.messageBus);
+ this.notificationService = new Mock();
+ this.sessionService = new SessionService(logger.Object, this.messageBus, this.notificationService.Object);
var engineeringModel = new EngineeringModel();
this.sessionService.OpenIterations.Add(new Iteration(){ Container = engineeringModel});
@@ -78,7 +81,12 @@ public void VerifyCreateOrUpdateThings()
var domain = new DomainOfExpertise();
siteDirectory.Domain.Add(domain);
- Assert.That(async () => await this.sessionService.CreateOrUpdateThings(siteDirectory, [domain], ["file A"]), Throws.InvalidOperationException);
+ Assert.Multiple(() =>
+ {
+ Assert.That(async () => await this.sessionService.CreateOrUpdateThings(siteDirectory, [domain], ["file A"]), Throws.InvalidOperationException);
+ Assert.That(async () => await this.sessionService.CreateOrUpdateThingsWithNotification(siteDirectory, [domain], ["file A"]), Throws.InvalidOperationException);
+ Assert.That(async () => await this.sessionService.CreateOrUpdateThingsWithNotification(siteDirectory, [domain]), Throws.InvalidOperationException);
+ });
}
[Test]
diff --git a/COMET.Web.Common/App.razor b/COMET.Web.Common/App.razor
index 9ce1f6d6..caa4c882 100644
--- a/COMET.Web.Common/App.razor
+++ b/COMET.Web.Common/App.razor
@@ -44,5 +44,3 @@
-
-
\ No newline at end of file
diff --git a/COMET.Web.Common/Services/NotificationService/INotificationService.cs b/COMET.Web.Common/Services/NotificationService/INotificationService.cs
index 413b898e..7c196c37 100644
--- a/COMET.Web.Common/Services/NotificationService/INotificationService.cs
+++ b/COMET.Web.Common/Services/NotificationService/INotificationService.cs
@@ -25,6 +25,10 @@
namespace COMET.Web.Common.Services.NotificationService
{
+ using DynamicData;
+
+ using FluentResults;
+
///
/// The provides notification information
///
@@ -35,6 +39,11 @@ public interface INotificationService
///
int NotificationCount { get; }
+ ///
+ /// A sourcelist with s
+ ///
+ SourceList Results { get; }
+
///
/// Increases the
///
diff --git a/COMET.Web.Common/Services/NotificationService/NotificationService.cs b/COMET.Web.Common/Services/NotificationService/NotificationService.cs
index 9d557a4a..d3e5bd89 100644
--- a/COMET.Web.Common/Services/NotificationService/NotificationService.cs
+++ b/COMET.Web.Common/Services/NotificationService/NotificationService.cs
@@ -1,30 +1,33 @@
// --------------------------------------------------------------------------------------------------------------------
//
-// Copyright (c) 2023-2024 Starion Group S.A.
+// Copyright (c) 2024 Starion Group S.A.
//
-// Authors: Sam Gerené, Alex Vorobiev, Alexander van Delft, Jaime Bernar, Théate Antoine, Nabil Abbar
+// Authors: Sam Gerené, Alex Vorobiev, Alexander van Delft, Jaime Bernar, Théate Antoine, João Rua
//
-// 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.
+// 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.
//
-// 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
+// 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.
//
-// 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.
+// 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 .
//
// --------------------------------------------------------------------------------------------------------------------
namespace COMET.Web.Common.Services.NotificationService
{
+ using DynamicData;
+
+ using FluentResults;
+
using ReactiveUI;
///
@@ -37,6 +40,11 @@ public class NotificationService : ReactiveObject, INotificationService
///
private int notificationCount;
+ ///
+ /// A sourcelist with s
+ ///
+ public SourceList Results { get; } = new();
+
///
/// Gets the number of notification(s)
///
diff --git a/COMET.Web.Common/Services/SessionManagement/ISessionService.cs b/COMET.Web.Common/Services/SessionManagement/ISessionService.cs
index a1648788..7d017e7d 100644
--- a/COMET.Web.Common/Services/SessionManagement/ISessionService.cs
+++ b/COMET.Web.Common/Services/SessionManagement/ISessionService.cs
@@ -32,6 +32,8 @@ namespace COMET.Web.Common.Services.SessionManagement
using CDP4Dal;
using CDP4Dal.Operations;
+ using COMET.Web.Common.Services.NotificationService;
+
using DynamicData;
using FluentResults;
@@ -117,5 +119,23 @@ public interface ISessionService : CDP4Web.Services.SessionService.ISessionServi
/// A of the file paths as to create or update
/// A with the of the operation
Task WriteTransaction(OperationContainer operationContainer, IReadOnlyCollection files);
+
+ ///
+ /// Creates or updates things, add new notifications to the
+ ///
+ /// The top container to use for the transaction
+ /// A of to create or update
+ /// A with the of the operation
+ Task CreateOrUpdateThingsWithNotification(Thing topContainer, IReadOnlyCollection toUpdateOrCreate);
+
+ ///
+ /// Creates or updates things, add new notifications to the
+ ///
+ /// The top container to use for the transaction
+ /// A of to create or update
+ /// A of the file paths as to create or update
+ /// A with the of the operation
+ /// The have to be a cloned
+ Task CreateOrUpdateThingsWithNotification(Thing topContainer, IReadOnlyCollection toUpdateOrCreate, IReadOnlyCollection files);
}
}
diff --git a/COMET.Web.Common/Services/SessionManagement/SessionService.cs b/COMET.Web.Common/Services/SessionManagement/SessionService.cs
index 71a8dd42..19786cec 100644
--- a/COMET.Web.Common/Services/SessionManagement/SessionService.cs
+++ b/COMET.Web.Common/Services/SessionManagement/SessionService.cs
@@ -40,6 +40,8 @@ namespace COMET.Web.Common.Services.SessionManagement
using CDP4Web.Enumerations;
using CDP4Web.Extensions;
+ using COMET.Web.Common.Services.NotificationService;
+
using DynamicData;
using FluentResults;
@@ -59,14 +61,21 @@ public class SessionService : CDP4Web.Services.SessionService.SessionService, IS
///
private readonly ILogger logger;
+ ///
+ /// The
+ ///
+ private readonly INotificationService notificationService;
+
///
/// Creates a new instance of type
///
/// the
/// The
- public SessionService(ILogger logger, ICDPMessageBus messageBus) : base(logger, messageBus)
+ /// The
+ public SessionService(ILogger logger, ICDPMessageBus messageBus, INotificationService notificationService) : base(logger, messageBus)
{
this.logger = logger;
+ this.notificationService = notificationService;
}
///
@@ -154,6 +163,34 @@ public Task CreateOrUpdateThings(Thing topContainer, IReadOnlyCollection
return this.WriteTransaction(operationContainer, files);
}
+ ///
+ /// Creates or updates things, add new notifications to the
+ ///
+ /// The top container to use for the transaction
+ /// A of to create or update
+ /// A with the of the operation
+ public async Task CreateOrUpdateThingsWithNotification(Thing topContainer, IReadOnlyCollection toUpdateOrCreate)
+ {
+ var result = await this.CreateOrUpdateThings(topContainer, toUpdateOrCreate);
+ this.notificationService.Results.Add(result);
+ return result;
+ }
+
+ ///
+ /// Creates or updates things, add new notifications to the
+ ///
+ /// The top container to use for the transaction
+ /// A of to create or update
+ /// A of the file paths as to create or update
+ /// A with the of the operation
+ /// The have to be a cloned
+ public async Task CreateOrUpdateThingsWithNotification(Thing topContainer, IReadOnlyCollection toUpdateOrCreate, IReadOnlyCollection files)
+ {
+ var result = await this.CreateOrUpdateThings(topContainer, toUpdateOrCreate, files);
+ this.notificationService.Results.Add(result);
+ return result;
+ }
+
///
/// Reads the instances from the data-source
///
diff --git a/COMETwebapp.Tests/Components/ReferenceData/CategoriesTableTestFixture.cs b/COMETwebapp.Tests/Components/ReferenceData/CategoriesTableTestFixture.cs
index 139e1233..25b54e11 100644
--- a/COMETwebapp.Tests/Components/ReferenceData/CategoriesTableTestFixture.cs
+++ b/COMETwebapp.Tests/Components/ReferenceData/CategoriesTableTestFixture.cs
@@ -345,15 +345,15 @@ public async Task VerifyAddOrEditCategory()
Assert.Multiple(() =>
{
Assert.That(this.viewModel.Rows.Count, Is.EqualTo(2));
- this.sessionService.Verify(x => x.CreateOrUpdateThings(It.IsAny(), It.IsAny>()), Times.Exactly(2));
+ this.sessionService.Verify(x => x.CreateOrUpdateThingsWithNotification(It.IsAny(), It.IsAny>()), Times.Exactly(2));
});
- this.sessionService.Setup(x => x.CreateOrUpdateThings(It.IsAny(), It.IsAny>())).Throws(new Exception());
+ this.sessionService.Setup(x => x.CreateOrUpdateThingsWithNotification(It.IsAny(), It.IsAny>())).Throws(new Exception());
await this.viewModel.CreateCategory(false);
Assert.Multiple(() =>
{
- this.sessionService.Verify(x => x.CreateOrUpdateThings(It.IsAny(), It.IsAny>()), Times.Exactly(3));
+ this.sessionService.Verify(x => x.CreateOrUpdateThingsWithNotification(It.IsAny(), It.IsAny>()), Times.Exactly(3));
this.logger.Verify(LogLevel.Error, x => !string.IsNullOrWhiteSpace(x.ToString()), Times.Once());
});
@@ -422,7 +422,7 @@ public async Task VerifyGridActions()
var editForm = renderer.FindComponent();
await renderer.InvokeAsync(editForm.Instance.OnValidSubmit.InvokeAsync);
- this.sessionService.Verify(x => x.CreateOrUpdateThings(It.IsAny(), It.IsAny>()), Times.Once);
+ this.sessionService.Verify(x => x.CreateOrUpdateThingsWithNotification(It.IsAny(), It.IsAny>()), Times.Once);
}
}
}
diff --git a/COMETwebapp.Tests/Components/SiteDirectory/UserManagementTableTestFixture.cs b/COMETwebapp.Tests/Components/SiteDirectory/UserManagementTableTestFixture.cs
index 4c20d5a0..24a81c3f 100644
--- a/COMETwebapp.Tests/Components/SiteDirectory/UserManagementTableTestFixture.cs
+++ b/COMETwebapp.Tests/Components/SiteDirectory/UserManagementTableTestFixture.cs
@@ -323,7 +323,7 @@ public async Task VerifyAddingOrEditingPerson()
Assert.Multiple(() =>
{
- this.sessionService.Verify(x => x.CreateOrUpdateThings(It.IsAny(), It.Is>(c => c.Count == 4)), Times.Once);
+ this.sessionService.Verify(x => x.CreateOrUpdateThingsWithNotification(It.IsAny(), It.Is>(c => c.Count == 4)), Times.Once);
Assert.Multiple(() => { Assert.That(this.viewModel.Rows.Count, Is.EqualTo(2)); });
});
}
@@ -352,13 +352,13 @@ public async Task VerifyAddingOrEditingPersonInteractions()
Assert.Multiple(() =>
{
- this.sessionService.Verify(x => x.CreateOrUpdateThings(It.IsAny(), It.IsAny>()), Times.Once);
+ this.sessionService.Verify(x => x.CreateOrUpdateThingsWithNotification(It.IsAny(), It.IsAny>()), Times.Once);
Assert.That(this.viewModel.Thing, Is.InstanceOf(typeof(Person)));
});
var form = renderer.FindComponent();
await renderer.InvokeAsync(form.Instance.EditModelSaving.InvokeAsync);
- this.sessionService.Verify(x => x.CreateOrUpdateThings(It.IsAny(), It.IsAny>()), Times.Once);
+ this.sessionService.Verify(x => x.CreateOrUpdateThingsWithNotification(It.IsAny(), It.IsAny>()), Times.Once);
}
[Test]
diff --git a/COMETwebapp.Tests/Shared/TopMenuEntry/NotificationComponentTestFixture.cs b/COMETwebapp.Tests/Shared/TopMenuEntry/NotificationComponentTestFixture.cs
new file mode 100644
index 00000000..309e50b2
--- /dev/null
+++ b/COMETwebapp.Tests/Shared/TopMenuEntry/NotificationComponentTestFixture.cs
@@ -0,0 +1,119 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// 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 .
+//
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace COMETwebapp.Tests.Shared.TopMenuEntry
+{
+ using AntDesign;
+
+ using Bunit;
+
+ using COMET.Web.Common.Services.VersionService;
+ using COMET.Web.Common.Test.Helpers;
+
+ using COMETwebapp.Shared.TopMenuEntry;
+
+ using DevExpress.Blazor;
+
+ using DynamicData;
+
+ using FluentResults;
+
+ using Microsoft.Extensions.DependencyInjection;
+
+ using Moq;
+
+ using NUnit.Framework;
+
+ using TestContext = Bunit.TestContext;
+ using IAntDesignNotificationService = AntDesign.INotificationService;
+ using INotificationService = COMET.Web.Common.Services.NotificationService.INotificationService;
+ using Result = FluentResults.Result;
+
+ [TestFixture]
+ public class NotificationComponentTestFixture
+ {
+ private TestContext context;
+ private Mock versionService;
+ private Mock notificationService;
+ private Mock antDesignNotificationService;
+
+ [SetUp]
+ public void Setup()
+ {
+ this.context = new TestContext();
+ this.antDesignNotificationService = new Mock();
+ this.notificationService = new Mock();
+ this.notificationService.Setup(x => x.Results).Returns(new SourceList());
+ this.versionService = new Mock();
+ this.versionService.Setup(x => x.GetVersion()).Returns("1.1.2");
+ this.context.Services.AddSingleton(this.versionService.Object);
+ this.context.Services.AddSingleton(this.notificationService.Object);
+ this.context.Services.AddSingleton(this.antDesignNotificationService.Object);
+ this.context.Services.AddSingleton(new NotificationService());
+ this.context.Services.AddSingleton(new MessageService());
+ this.context.Services.AddSingleton(new MessageService());
+ this.context.Services.AddSingleton(new ConfirmService());
+ this.context.Services.AddSingleton(new ModalService());
+ this.context.Services.AddSingleton(new DrawerService());
+ this.context.Services.AddSingleton(new ImageService());
+ this.context.Services.AddSingleton(new Mock().Object);
+ this.context.Services.AddSingleton(new Mock().Object);
+ this.context.ConfigureDevExpressBlazor();
+ }
+
+ [TearDown]
+ public void Teardown()
+ {
+ this.context.CleanContext();
+ }
+
+ [Test]
+ public void VerifyAboutEntry()
+ {
+ var renderer = this.context.RenderComponent(parameters =>
+ {
+ parameters.Add(p => p.Items, builder =>
+ {
+ builder.OpenComponent(0, typeof(NotificationComponent));
+ builder.CloseComponent();
+ });
+ });
+
+ var notificationComponent = renderer.FindComponent();
+
+ Assert.Multiple(() =>
+ {
+ Assert.That(notificationComponent.Instance, Is.Not.Null);
+ Assert.That(notificationComponent.Instance.AntNotificationService, Is.Not.Null);
+ Assert.That(notificationComponent.Instance.NotificationService, Is.Not.Null);
+ });
+
+ this.notificationService.Object.Results.Add(new Result());
+ this.antDesignNotificationService.Verify(x => x.Open(It.IsAny()), Times.Once);
+
+ this.notificationService.Object.Results.Add(new Result { Reasons = { new Error("err"), new ExceptionalError(new Exception("exception")) } });
+ this.antDesignNotificationService.Verify(x => x.Open(It.IsAny()), Times.Exactly(2));
+ }
+ }
+}
diff --git a/COMETwebapp.Tests/ViewModels/Components/EngineeringModel/CommonFileStoreTableViewModelTestFixture.cs b/COMETwebapp.Tests/ViewModels/Components/EngineeringModel/CommonFileStoreTableViewModelTestFixture.cs
index 43a28793..86307553 100644
--- a/COMETwebapp.Tests/ViewModels/Components/EngineeringModel/CommonFileStoreTableViewModelTestFixture.cs
+++ b/COMETwebapp.Tests/ViewModels/Components/EngineeringModel/CommonFileStoreTableViewModelTestFixture.cs
@@ -137,9 +137,9 @@ public async Task VerifyCommonFileStoreCreateOrEdit()
this.viewModel.Thing = this.commonFileStore;
await this.viewModel.CreateOrEditCommonFileStore(true);
- this.sessionService.Verify(x => x.CreateOrUpdateThings(It.IsAny(), It.IsAny>()), Times.Once);
+ this.sessionService.Verify(x => x.CreateOrUpdateThingsWithNotification(It.IsAny(), It.IsAny>()), Times.Once);
- this.sessionService.Setup(x => x.CreateOrUpdateThings(It.IsAny(), It.IsAny>())).Throws(new Exception());
+ this.sessionService.Setup(x => x.CreateOrUpdateThingsWithNotification(It.IsAny(), It.IsAny>())).Throws(new Exception());
this.viewModel.Thing = new CommonFileStore();
await this.viewModel.CreateOrEditCommonFileStore(false);
this.loggerMock.Verify(LogLevel.Error, x => !string.IsNullOrWhiteSpace(x.ToString()), Times.Once());
diff --git a/COMETwebapp.Tests/ViewModels/Components/EngineeringModel/OptionsTableViewModelTestFixture.cs b/COMETwebapp.Tests/ViewModels/Components/EngineeringModel/OptionsTableViewModelTestFixture.cs
index 12fadd84..9353ad64 100644
--- a/COMETwebapp.Tests/ViewModels/Components/EngineeringModel/OptionsTableViewModelTestFixture.cs
+++ b/COMETwebapp.Tests/ViewModels/Components/EngineeringModel/OptionsTableViewModelTestFixture.cs
@@ -152,9 +152,9 @@ public async Task VerifyOptionCreateOrEdit()
Assert.That(this.viewModel.Thing.Original, Is.Not.Null);
await this.viewModel.CreateOrEditOption(true);
- this.sessionService.Verify(x => x.CreateOrUpdateThings(It.IsAny(), It.IsAny>()), Times.Once);
+ this.sessionService.Verify(x => x.CreateOrUpdateThingsWithNotification(It.IsAny(), It.IsAny>()), Times.Once);
- this.sessionService.Setup(x => x.CreateOrUpdateThings(It.IsAny(), It.IsAny>())).Throws(new Exception());
+ this.sessionService.Setup(x => x.CreateOrUpdateThingsWithNotification(It.IsAny(), It.IsAny>())).Throws(new Exception());
this.viewModel.SetCurrentOption(new Option());
this.viewModel.SelectedIsDefaultValue = true;
diff --git a/COMETwebapp.Tests/ViewModels/Components/EngineeringModel/PublicationsTableViewModelTestFixture.cs b/COMETwebapp.Tests/ViewModels/Components/EngineeringModel/PublicationsTableViewModelTestFixture.cs
index 642538ff..c726cbc3 100644
--- a/COMETwebapp.Tests/ViewModels/Components/EngineeringModel/PublicationsTableViewModelTestFixture.cs
+++ b/COMETwebapp.Tests/ViewModels/Components/EngineeringModel/PublicationsTableViewModelTestFixture.cs
@@ -153,18 +153,18 @@ public async Task VerifyPublicationCreation()
this.viewModel.InitializeViewModel();
this.viewModel.SetCurrentIteration(this.iteration);
await this.viewModel.CreatePublication();
- this.sessionService.Verify(x => x.CreateOrUpdateThings(It.IsAny(), It.IsAny>()), Times.Never);
+ this.sessionService.Verify(x => x.CreateOrUpdateThingsWithNotification(It.IsAny(), It.IsAny>()), Times.Never);
this.viewModel.SelectedParameterRowsToPublish = listOfSelectedRowsToPublish;
await this.viewModel.CreatePublication();
Assert.Multiple(() =>
{
- this.sessionService.Verify(x => x.CreateOrUpdateThings(It.IsAny(), It.IsAny>()), Times.Once);
+ this.sessionService.Verify(x => x.CreateOrUpdateThingsWithNotification(It.IsAny(), It.IsAny>()), Times.Once);
Assert.That(this.viewModel.SelectedParameterRowsToPublish, Is.Empty);
});
- this.sessionService.Setup(x => x.CreateOrUpdateThings(It.IsAny(), It.IsAny>())).Throws(new Exception());
+ this.sessionService.Setup(x => x.CreateOrUpdateThingsWithNotification(It.IsAny(), It.IsAny>())).Throws(new Exception());
this.viewModel.SelectedParameterRowsToPublish = listOfSelectedRowsToPublish;
await this.viewModel.CreatePublication();
this.loggerMock.Verify(LogLevel.Error, x => !string.IsNullOrWhiteSpace(x.ToString()), Times.Once());
diff --git a/COMETwebapp.Tests/ViewModels/Components/ReferenceData/MeasurementScalesTableViewModelTestFixture.cs b/COMETwebapp.Tests/ViewModels/Components/ReferenceData/MeasurementScalesTableViewModelTestFixture.cs
index bc138597..ff4065f0 100644
--- a/COMETwebapp.Tests/ViewModels/Components/ReferenceData/MeasurementScalesTableViewModelTestFixture.cs
+++ b/COMETwebapp.Tests/ViewModels/Components/ReferenceData/MeasurementScalesTableViewModelTestFixture.cs
@@ -24,6 +24,8 @@
namespace COMETwebapp.Tests.ViewModels.Components.ReferenceData
{
+ using AntDesign;
+
using CDP4Common.CommonData;
using CDP4Common.SiteDirectoryData;
using CDP4Common.Types;
@@ -35,17 +37,22 @@ namespace COMETwebapp.Tests.ViewModels.Components.ReferenceData
using CDP4Web.Enumerations;
using COMET.Web.Common.Services.SessionManagement;
+ using COMET.Web.Common.Test.Helpers;
using COMETwebapp.Services.ShowHideDeprecatedThingsService;
using COMETwebapp.ViewModels.Components.ReferenceData.MeasurementScales;
using COMETwebapp.Wrappers;
+ using FluentResults;
+
using Microsoft.Extensions.Logging;
using Moq;
using NUnit.Framework;
+ using Result = FluentResults.Result;
+
[TestFixture]
public class MeasurementScalesTableViewModelTestFixture
{
@@ -56,6 +63,7 @@ public class MeasurementScalesTableViewModelTestFixture
private Mock> loggerMock;
private CDPMessageBus messageBus;
private Mock showHideService;
+ private Mock notificationService;
private MeasurementScale measurementScale;
private SiteDirectory siteDirectory;
@@ -65,6 +73,7 @@ public void Setup()
this.sessionService = new Mock();
this.permissionService = new Mock();
this.showHideService = new Mock();
+ this.notificationService = new Mock();
this.messageBus = new CDPMessageBus();
this.loggerMock = new Mock>();
@@ -109,8 +118,9 @@ public void Setup()
session.Setup(x => x.RetrieveSiteDirectory()).Returns(this.siteDirectory);
this.sessionService.Setup(x => x.Session).Returns(session.Object);
this.sessionService.Setup(x => x.GetSiteDirectory()).Returns(this.siteDirectory);
+ this.sessionService.Setup(x => x.CreateOrUpdateThings(It.IsAny(), It.IsAny>())).Returns(Task.FromResult(new Result()));
- this.viewModel = new MeasurementScalesTableViewModel(this.sessionService.Object, this.showHideService.Object, this.messageBus, this.loggerMock.Object);
+ this.viewModel = new MeasurementScalesTableViewModel(this.sessionService.Object, this.showHideService.Object, this.messageBus, this.loggerMock.Object, this.notificationService.Object);
}
[TearDown]
@@ -168,16 +178,22 @@ public async Task VerifyMeasurementScaleAddOrEdit()
Assert.Multiple(() =>
{
- this.sessionService.Verify(x => x.CreateOrUpdateThings(It.IsAny(), It.IsAny>()), Times.Once);
+ this.sessionService.Verify(x => x.CreateOrUpdateThingsWithNotification(It.IsAny(), It.IsAny>()), Times.Once);
Assert.That(((LogarithmicScale)this.viewModel.Thing).ReferenceQuantityValue, Has.Count.EqualTo(1));
});
+ var exceptionalError = new ExceptionalError(new InvalidDataException("Invalid data"));
+ var regularError = new Error("Failure");
this.viewModel.SelectedReferenceQuantityValue.Value = string.Empty;
+
+ this.sessionService.Setup(x => x.CreateOrUpdateThingsWithNotification(It.IsAny(), It.IsAny>()))
+ .Returns(Task.FromResult(new Result { Reasons = { regularError, exceptionalError } }));
+
await this.viewModel.CreateOrEditMeasurementScale(true);
Assert.Multiple(() =>
{
- this.sessionService.Verify(x => x.CreateOrUpdateThings(It.IsAny(), It.IsAny>()), Times.Exactly(2));
+ this.sessionService.Verify(x => x.CreateOrUpdateThingsWithNotification(It.IsAny(), It.IsAny>()), Times.Exactly(2));
Assert.That(((LogarithmicScale)this.viewModel.Thing).ReferenceQuantityValue, Has.Count.EqualTo(0));
});
@@ -188,9 +204,13 @@ public async Task VerifyMeasurementScaleAddOrEdit()
Assert.Multiple(() =>
{
- this.sessionService.Verify(x => x.CreateOrUpdateThings(It.IsAny(), It.IsAny>()), Times.Exactly(3));
+ this.sessionService.Verify(x => x.CreateOrUpdateThingsWithNotification(It.IsAny(), It.IsAny>()), Times.Exactly(3));
Assert.That(((LogarithmicScale)this.viewModel.Thing).ReferenceQuantityValue, Has.Count.EqualTo(1));
});
+
+ this.sessionService.Setup(x => x.CreateOrUpdateThingsWithNotification(It.IsAny(), It.IsAny>())).Throws(new Exception());
+ await this.viewModel.CreateOrEditMeasurementScale(false);
+ this.loggerMock.Verify(LogLevel.Error, x => !string.IsNullOrWhiteSpace(x.ToString()), Times.Once());
}
[Test]
diff --git a/COMETwebapp.Tests/ViewModels/Components/ReferenceData/MeasurementUnitsTableViewModelTestFixture.cs b/COMETwebapp.Tests/ViewModels/Components/ReferenceData/MeasurementUnitsTableViewModelTestFixture.cs
index 5cd0faf9..313760f3 100644
--- a/COMETwebapp.Tests/ViewModels/Components/ReferenceData/MeasurementUnitsTableViewModelTestFixture.cs
+++ b/COMETwebapp.Tests/ViewModels/Components/ReferenceData/MeasurementUnitsTableViewModelTestFixture.cs
@@ -211,7 +211,7 @@ public async Task VerifyMeasurementAddOrEdit()
((DerivedUnit)this.viewModel.Thing).UnitFactor.Add(unitFactor);
await this.viewModel.CreateOrEditMeasurementUnit(true);
- this.sessionService.Verify(x => x.CreateOrUpdateThings(
+ this.sessionService.Verify(x => x.CreateOrUpdateThingsWithNotification(
It.IsAny(),
It.Is>(c => c.Count == 3)),
Times.Once);
diff --git a/COMETwebapp.Tests/ViewModels/Components/ReferenceData/ParameterTypesTableViewModelTestFixture.cs b/COMETwebapp.Tests/ViewModels/Components/ReferenceData/ParameterTypesTableViewModelTestFixture.cs
index 2dbb5419..3f559d7c 100644
--- a/COMETwebapp.Tests/ViewModels/Components/ReferenceData/ParameterTypesTableViewModelTestFixture.cs
+++ b/COMETwebapp.Tests/ViewModels/Components/ReferenceData/ParameterTypesTableViewModelTestFixture.cs
@@ -24,6 +24,8 @@
namespace COMETwebapp.Tests.ViewModels.Components.ReferenceData
{
+ using AntDesign;
+
using CDP4Common.CommonData;
using CDP4Common.SiteDirectoryData;
using CDP4Common.Types;
@@ -32,6 +34,7 @@ namespace COMETwebapp.Tests.ViewModels.Components.ReferenceData
using CDP4Dal.Permission;
using COMET.Web.Common.Services.SessionManagement;
+ using COMET.Web.Common.Test.Helpers;
using COMETwebapp.Services.ShowHideDeprecatedThingsService;
using COMETwebapp.ViewModels.Components.ReferenceData.ParameterTypes;
@@ -43,6 +46,8 @@ namespace COMETwebapp.Tests.ViewModels.Components.ReferenceData
using NUnit.Framework;
+ using Result = FluentResults.Result;
+
[TestFixture]
public class ParameterTypesTableViewModelTestFixture
{
@@ -53,6 +58,7 @@ public class ParameterTypesTableViewModelTestFixture
private Mock> loggerMock;
private CDPMessageBus messageBus;
private Mock showHideService;
+ private Mock notificationService;
private ParameterType parameterType;
private SiteDirectory siteDirectory;
@@ -62,6 +68,7 @@ public void Setup()
this.sessionService = new Mock();
this.permissionService = new Mock();
this.showHideService = new Mock();
+ this.notificationService = new Mock();
this.messageBus = new CDPMessageBus();
this.loggerMock = new Mock>();
@@ -104,8 +111,9 @@ public void Setup()
session.Setup(x => x.RetrieveSiteDirectory()).Returns(this.siteDirectory);
this.sessionService.Setup(x => x.Session).Returns(session.Object);
this.sessionService.Setup(x => x.GetSiteDirectory()).Returns(this.siteDirectory);
+ this.sessionService.Setup(x => x.CreateOrUpdateThings(It.IsAny(), It.IsAny>())).Returns(Task.FromResult(new Result()));
- this.viewModel = new ParameterTypeTableViewModel(this.sessionService.Object, this.showHideService.Object, this.messageBus, this.loggerMock.Object);
+ this.viewModel = new ParameterTypeTableViewModel(this.sessionService.Object, this.showHideService.Object, this.messageBus, this.loggerMock.Object, this.notificationService.Object);
}
[TearDown]
@@ -144,20 +152,25 @@ public async Task VerifyMeasurementScaleAddOrEdit()
this.viewModel.SelectedParameterType = new ClassKindWrapper(ClassKind.SampledFunctionParameterType);
await this.viewModel.CreateOrEditParameterType(true);
- this.sessionService.Verify(x => x.CreateOrUpdateThings(It.IsAny(), It.IsAny>()), Times.Once);
+ this.sessionService.Verify(x => x.CreateOrUpdateThingsWithNotification(It.IsAny(), It.IsAny>()), Times.Once);
this.viewModel.SelectedParameterType = new ClassKindWrapper(ClassKind.EnumerationParameterType);
await this.viewModel.CreateOrEditParameterType(true);
- this.sessionService.Verify(x => x.CreateOrUpdateThings(It.IsAny(), It.IsAny>()), Times.Exactly(2));
+ this.sessionService.Verify(x => x.CreateOrUpdateThingsWithNotification(It.IsAny(), It.IsAny>()), Times.Exactly(2));
this.viewModel.SelectedParameterType = new ClassKindWrapper(ClassKind.CompoundParameterType);
+ this.viewModel.Thing = this.viewModel.Thing.Clone(false);
await this.viewModel.CreateOrEditParameterType(true);
- this.sessionService.Verify(x => x.CreateOrUpdateThings(It.IsAny(), It.IsAny>()), Times.Exactly(3));
+ this.sessionService.Verify(x => x.CreateOrUpdateThingsWithNotification(It.IsAny(), It.IsAny>()), Times.Exactly(3));
this.viewModel.SelectedParameterType = new ClassKindWrapper(ClassKind.DerivedQuantityKind);
this.viewModel.Thing = this.viewModel.Thing.Clone(true);
await this.viewModel.CreateOrEditParameterType(false);
- this.sessionService.Verify(x => x.CreateOrUpdateThings(It.IsAny(), It.IsAny>()), Times.Exactly(4));
+ this.sessionService.Verify(x => x.CreateOrUpdateThingsWithNotification(It.IsAny(), It.IsAny>()), Times.Exactly(4));
+
+ this.sessionService.Setup(x => x.CreateOrUpdateThingsWithNotification(It.IsAny(), It.IsAny>())).Throws(new Exception("Error"));
+ await this.viewModel.CreateOrEditParameterType(false);
+ this.loggerMock.Verify(LogLevel.Error, x => !string.IsNullOrWhiteSpace(x.ToString()), Times.Once());
}
[Test]
diff --git a/COMETwebapp.Tests/ViewModels/Components/SiteDirectory/DomainsOfExpertiseTableViewModelTestFixture.cs b/COMETwebapp.Tests/ViewModels/Components/SiteDirectory/DomainsOfExpertiseTableViewModelTestFixture.cs
index ae3ff1e6..6ee2b3f2 100644
--- a/COMETwebapp.Tests/ViewModels/Components/SiteDirectory/DomainsOfExpertiseTableViewModelTestFixture.cs
+++ b/COMETwebapp.Tests/ViewModels/Components/SiteDirectory/DomainsOfExpertiseTableViewModelTestFixture.cs
@@ -177,10 +177,10 @@ public async Task VerifyDomainCreateOrEdit()
this.viewModel.InitializeViewModel();
await this.viewModel.CreateOrEditDomainOfExpertise(false);
- this.sessionService.Verify(x => x.CreateOrUpdateThings(It.IsAny(), It.Is>(c => c.Count == 1)), Times.Once);
+ this.sessionService.Verify(x => x.CreateOrUpdateThingsWithNotification(It.IsAny(), It.Is>(c => c.Count == 1)), Times.Once);
await this.viewModel.CreateOrEditDomainOfExpertise(true);
- this.sessionService.Verify(x => x.CreateOrUpdateThings(It.IsAny(), It.Is>(c => c.Count == 2)), Times.Once);
+ this.sessionService.Verify(x => x.CreateOrUpdateThingsWithNotification(It.IsAny(), It.Is>(c => c.Count == 2)), Times.Once);
}
}
}
diff --git a/COMETwebapp.Tests/ViewModels/Components/SiteDirectory/EngineeringModels/ActiveDomainsTableViewModelTestFixture.cs b/COMETwebapp.Tests/ViewModels/Components/SiteDirectory/EngineeringModels/ActiveDomainsTableViewModelTestFixture.cs
index 750f3ed3..21b45c82 100644
--- a/COMETwebapp.Tests/ViewModels/Components/SiteDirectory/EngineeringModels/ActiveDomainsTableViewModelTestFixture.cs
+++ b/COMETwebapp.Tests/ViewModels/Components/SiteDirectory/EngineeringModels/ActiveDomainsTableViewModelTestFixture.cs
@@ -188,17 +188,17 @@ public async Task VerifyActiveDomainsEdit()
this.viewModel.SetEngineeringModel(this.model);
await this.viewModel.EditActiveDomains();
- this.sessionService.Verify(x => x.CreateOrUpdateThings(It.IsAny(), It.IsAny>()), Times.Never);
+ this.sessionService.Verify(x => x.CreateOrUpdateThingsWithNotification(It.IsAny(), It.IsAny>()), Times.Never);
this.viewModel.SelectedDomainsOfExpertise = [this.domain, this.domain.Clone(true)];
await this.viewModel.EditActiveDomains();
Assert.Multiple(() =>
{
- this.sessionService.Verify(x => x.CreateOrUpdateThings(It.IsAny(), It.IsAny>()), Times.Once);
+ this.sessionService.Verify(x => x.CreateOrUpdateThingsWithNotification(It.IsAny(), It.IsAny>()), Times.Once);
});
- this.sessionService.Setup(x => x.CreateOrUpdateThings(It.IsAny(), It.IsAny>())).Throws(new Exception());
+ this.sessionService.Setup(x => x.CreateOrUpdateThingsWithNotification(It.IsAny(), It.IsAny>())).Throws(new Exception());
await this.viewModel.EditActiveDomains();
this.loggerMock.Verify(LogLevel.Error, x => !string.IsNullOrWhiteSpace(x.ToString()), Times.Once());
}
diff --git a/COMETwebapp.Tests/ViewModels/Components/SiteDirectory/EngineeringModels/EngineeringModelsTableViewModelTestFixture.cs b/COMETwebapp.Tests/ViewModels/Components/SiteDirectory/EngineeringModels/EngineeringModelsTableViewModelTestFixture.cs
index 722dca9f..148a7764 100644
--- a/COMETwebapp.Tests/ViewModels/Components/SiteDirectory/EngineeringModels/EngineeringModelsTableViewModelTestFixture.cs
+++ b/COMETwebapp.Tests/ViewModels/Components/SiteDirectory/EngineeringModels/EngineeringModelsTableViewModelTestFixture.cs
@@ -219,7 +219,7 @@ public async Task VerifyModelCreation()
this.viewModel.SetupEngineeringModelWithSelectedValues();
await this.viewModel.CreateEngineeringModel();
- this.sessionService.Verify(x => x.CreateOrUpdateThings(It.IsAny(), It.Is>(c => c.Count == 4)), Times.Once);
+ this.sessionService.Verify(x => x.CreateOrUpdateThingsWithNotification(It.IsAny(), It.Is>(c => c.Count == 4)), Times.Once);
this.viewModel.ResetSelectedValues();
diff --git a/COMETwebapp.Tests/ViewModels/Components/SiteDirectory/EngineeringModels/ParticipantsTableViewModelTestFixture.cs b/COMETwebapp.Tests/ViewModels/Components/SiteDirectory/EngineeringModels/ParticipantsTableViewModelTestFixture.cs
index 1d8aba41..8ffc06ec 100644
--- a/COMETwebapp.Tests/ViewModels/Components/SiteDirectory/EngineeringModels/ParticipantsTableViewModelTestFixture.cs
+++ b/COMETwebapp.Tests/ViewModels/Components/SiteDirectory/EngineeringModels/ParticipantsTableViewModelTestFixture.cs
@@ -233,14 +233,14 @@ public async Task VerifyParticipantsActions()
this.viewModel.SetEngineeringModel(this.model);
await this.viewModel.CreateOrEditParticipant(false);
- this.sessionService.Verify(x => x.CreateOrUpdateThings(It.IsAny(), It.IsAny>()), Times.Never);
+ this.sessionService.Verify(x => x.CreateOrUpdateThingsWithNotification(It.IsAny(), It.IsAny>()), Times.Never);
this.viewModel.SelectedDomains = [this.participant.Domain.First(), this.participant.Domain.First().Clone(true)];
await this.viewModel.CreateOrEditParticipant(false);
- this.sessionService.Verify(x => x.CreateOrUpdateThings(It.IsAny(), It.Is>(c => c.Count() == 1)), Times.Once);
+ this.sessionService.Verify(x => x.CreateOrUpdateThingsWithNotification(It.IsAny(), It.Is>(c => c.Count() == 1)), Times.Once);
await this.viewModel.CreateOrEditParticipant(true);
- this.sessionService.Verify(x => x.CreateOrUpdateThings(It.IsAny(), It.Is>(c => c.Count() == 2)), Times.Once);
+ this.sessionService.Verify(x => x.CreateOrUpdateThingsWithNotification(It.IsAny(), It.Is>(c => c.Count() == 2)), Times.Once);
}
}
}
diff --git a/COMETwebapp.Tests/ViewModels/Components/SiteDirectory/OrganizationsTableViewModelTestFixture.cs b/COMETwebapp.Tests/ViewModels/Components/SiteDirectory/OrganizationsTableViewModelTestFixture.cs
index c5d398d5..0b030618 100644
--- a/COMETwebapp.Tests/ViewModels/Components/SiteDirectory/OrganizationsTableViewModelTestFixture.cs
+++ b/COMETwebapp.Tests/ViewModels/Components/SiteDirectory/OrganizationsTableViewModelTestFixture.cs
@@ -176,10 +176,10 @@ public async Task VerifyCreateOrEditOrganization()
this.viewModel.InitializeViewModel();
await this.viewModel.CreateOrEditOrganization(false);
- this.sessionService.Verify(x => x.CreateOrUpdateThings(It.IsAny(), It.Is>(c => c.Count == 1)), Times.Once);
+ this.sessionService.Verify(x => x.CreateOrUpdateThingsWithNotification(It.IsAny(), It.Is>(c => c.Count == 1)), Times.Once);
await this.viewModel.CreateOrEditOrganization(true);
- this.sessionService.Verify(x => x.CreateOrUpdateThings(It.IsAny(), It.Is>(c => c.Count == 2)), Times.Once);
+ this.sessionService.Verify(x => x.CreateOrUpdateThingsWithNotification(It.IsAny(), It.Is>(c => c.Count == 2)), Times.Once);
}
}
}
diff --git a/COMETwebapp.Tests/ViewModels/Components/SiteDirectory/Roles/ParticipantRolesTableViewModelTestFixture.cs b/COMETwebapp.Tests/ViewModels/Components/SiteDirectory/Roles/ParticipantRolesTableViewModelTestFixture.cs
index a712944c..fdd8cc19 100644
--- a/COMETwebapp.Tests/ViewModels/Components/SiteDirectory/Roles/ParticipantRolesTableViewModelTestFixture.cs
+++ b/COMETwebapp.Tests/ViewModels/Components/SiteDirectory/Roles/ParticipantRolesTableViewModelTestFixture.cs
@@ -177,7 +177,7 @@ public async Task VerifyParticipantRoleCreation()
this.viewModel.InitializeViewModel();
await this.viewModel.CreateOrEditParticipantRole(true);
- this.sessionService.Verify(x => x.CreateOrUpdateThings(It.IsAny(), It.IsAny>()), Times.Once);
+ this.sessionService.Verify(x => x.CreateOrUpdateThingsWithNotification(It.IsAny(), It.IsAny>()), Times.Once);
}
}
}
diff --git a/COMETwebapp.Tests/ViewModels/Components/SiteDirectory/Roles/PersonRolesTableViewModelTestFixture.cs b/COMETwebapp.Tests/ViewModels/Components/SiteDirectory/Roles/PersonRolesTableViewModelTestFixture.cs
index cee9c2aa..b4ec1e90 100644
--- a/COMETwebapp.Tests/ViewModels/Components/SiteDirectory/Roles/PersonRolesTableViewModelTestFixture.cs
+++ b/COMETwebapp.Tests/ViewModels/Components/SiteDirectory/Roles/PersonRolesTableViewModelTestFixture.cs
@@ -177,7 +177,7 @@ public async Task VerifyParticipantRoleCreation()
this.viewModel.InitializeViewModel();
await this.viewModel.CreateOrEditPersonRole(true);
- this.sessionService.Verify(x => x.CreateOrUpdateThings(It.IsAny(), It.IsAny>()), Times.Once);
+ this.sessionService.Verify(x => x.CreateOrUpdateThingsWithNotification(It.IsAny(), It.IsAny>()), Times.Once);
}
}
}
diff --git a/COMETwebapp/Components/Common/SelectedDeprecatableDataItemBase.razor.cs b/COMETwebapp/Components/Common/SelectedDeprecatableDataItemBase.razor.cs
index 59727ced..f02351c8 100644
--- a/COMETwebapp/Components/Common/SelectedDeprecatableDataItemBase.razor.cs
+++ b/COMETwebapp/Components/Common/SelectedDeprecatableDataItemBase.razor.cs
@@ -119,7 +119,13 @@ protected void OnSaved()
}
this.ShouldCreateThing = false;
- var createdRow = this.ViewModel.Rows.Items.First(x => x.Thing.Iid == this.ViewModel.Thing.Iid);
+ var createdRow = this.ViewModel.Rows.Items.FirstOrDefault(x => x.Thing.Iid == this.ViewModel.Thing.Iid);
+
+ if (createdRow is null)
+ {
+ return;
+ }
+
this.OnSelectedDataItemChanged(createdRow);
}
}
diff --git a/COMETwebapp/Extensions/ResultExtensions.cs b/COMETwebapp/Extensions/ResultExtensions.cs
new file mode 100644
index 00000000..eaebd34c
--- /dev/null
+++ b/COMETwebapp/Extensions/ResultExtensions.cs
@@ -0,0 +1,76 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// 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 .
+//
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace COMETwebapp.Extensions
+{
+ using System.Text.RegularExpressions;
+
+ using AntDesign;
+
+ using FluentResults;
+
+ ///
+ /// Extension class for Result
+ ///
+ public static class ResultExtensions
+ {
+ ///
+ /// Gets the toast description, from
+ ///
+ /// The validation result base
+ /// A html string containing the description to be displayed
+ public static string GetHtmlErrorsDescription(this IResultBase result)
+ {
+ return $"""
+ {string.Join(" ", result.Errors.Select(GetErrorString))}
+ If the error persists, check our issues page
+ """;
+ }
+
+ ///
+ /// Gets the error string for display in the description of the toast
+ ///
+ /// The error to be displayed
+ /// A html string containing the error
+ private static string GetErrorString(this IReason error)
+ {
+ string errorLine;
+ var errorId = Guid.NewGuid();
+
+ if (error is IExceptionalError exceptionalError)
+ {
+ errorLine = $"""
+ {exceptionalError.Message}
+