From 52d79776712d0170654b3a018e37a2ddbf6703da Mon Sep 17 00:00:00 2001 From: jaimeatrhea Date: Thu, 21 Sep 2023 09:49:01 +0200 Subject: [PATCH] Add webapp tests --- .../BookEditor/BookEditorBodyTestFixture.cs | 117 +++++++++ .../BookEditor/BookEditorColumnTestFixture.cs | 150 +++++++++++ .../BookEditorBodyViewModelTestFixture.cs | 243 ++++++++++++++++++ .../BookEditor/BookEditorBody.razor | 16 +- .../BookEditor/BookEditorColumn.razor | 4 +- .../BookEditor/BookEditorColumn.razor.css | 4 +- .../BookEditor/BookEditorBodyViewModel.cs | 3 +- 7 files changed, 524 insertions(+), 13 deletions(-) create mode 100644 COMETwebapp.Tests/Components/BookEditor/BookEditorBodyTestFixture.cs create mode 100644 COMETwebapp.Tests/Components/BookEditor/BookEditorColumnTestFixture.cs create mode 100644 COMETwebapp.Tests/ViewModels/Components/BookEditor/BookEditorBodyViewModelTestFixture.cs diff --git a/COMETwebapp.Tests/Components/BookEditor/BookEditorBodyTestFixture.cs b/COMETwebapp.Tests/Components/BookEditor/BookEditorBodyTestFixture.cs new file mode 100644 index 00000000..d992312c --- /dev/null +++ b/COMETwebapp.Tests/Components/BookEditor/BookEditorBodyTestFixture.cs @@ -0,0 +1,117 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// Copyright (c) 2023 RHEA System S.A. +// +// Authors: Sam Gerené, Alex Vorobiev, Alexander van Delft, Jaime Bernar, Théate Antoine, Nabil Abbar +// +// 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. +// +// 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.Components.BookEditor +{ + using Bunit; + + using CDP4Common.EngineeringModelData; + using CDP4Common.ReportingData; + using CDP4Common.SiteDirectoryData; + + using COMET.Web.Common.Services.SessionManagement; + using COMET.Web.Common.Test.Helpers; + using COMET.Web.Common.ViewModels.Components; + using COMET.Web.Common.ViewModels.Components.BookEditor; + + using COMETwebapp.Components.BookEditor; + using COMETwebapp.Services.Interoperability; + using COMETwebapp.ViewModels.Components.BookEditor; + + using DynamicData; + + using Microsoft.Extensions.DependencyInjection; + + using Moq; + + using NUnit.Framework; + + using TestContext = Bunit.TestContext; + + [TestFixture] + public class BookEditorBodyTestFixture + { + private TestContext context; + private IRenderedComponent component; + private Mock viewModel; + private Mock sessionService; + + [SetUp] + public void Setup() + { + this.context = new TestContext(); + this.context.ConfigureDevExpressBlazor(); + this.sessionService = new Mock(); + + this.viewModel = new Mock(); + this.viewModel.Setup(x => x.CurrentIteration).Returns(new Iteration()); + this.viewModel.Setup(x => x.CurrentDomain).Returns(new DomainOfExpertise()); + this.viewModel.Setup(x => x.AvailableBooks).Returns(new SourceList()); + + var editorPopupViewModel = new Mock(); + editorPopupViewModel.Setup(x => x.ValidationErrors).Returns(new SourceList()); + editorPopupViewModel.Setup(x => x.Item).Returns(new Book()); + editorPopupViewModel.Setup(x => x.ActiveDomains).Returns(new List()); + editorPopupViewModel.Setup(x => x.AvailableCategories).Returns(new List()); + + this.viewModel.Setup(x => x.EditorPopupViewModel).Returns(editorPopupViewModel.Object); + + var confirmCancelPopupViewModel = new Mock(); + + this.viewModel.Setup(x => x.ConfirmCancelPopupViewModel).Returns(confirmCancelPopupViewModel.Object); + + var domDataService = new Mock(); + + this.context.Services.AddSingleton(this.viewModel.Object); + this.context.Services.AddSingleton(this.sessionService.Object); + this.context.Services.AddSingleton(domDataService.Object); + + this.component = this.context.RenderComponent(); + } + + [TearDown] + public void Teardown() + { + this.context.CleanContext(); + } + + [Test] + public void VerifyComponent() + { + var bookEditorColumn = this.component.FindComponent>(); + var sectionEditorColumn = this.component.FindComponent>(); + var pageEditorColumn = this.component.FindComponent>(); + var noteEditorColumn = this.component.FindComponent>(); + + Assert.Multiple(() => + { + Assert.That(bookEditorColumn.Instance, Is.Not.Null); + Assert.That(sectionEditorColumn.Instance, Is.Not.Null); + Assert.That(pageEditorColumn.Instance, Is.Not.Null); + Assert.That(noteEditorColumn.Instance, Is.Not.Null); + }); + } + } +} + diff --git a/COMETwebapp.Tests/Components/BookEditor/BookEditorColumnTestFixture.cs b/COMETwebapp.Tests/Components/BookEditor/BookEditorColumnTestFixture.cs new file mode 100644 index 00000000..21d4ec93 --- /dev/null +++ b/COMETwebapp.Tests/Components/BookEditor/BookEditorColumnTestFixture.cs @@ -0,0 +1,150 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// Copyright (c) 2023 RHEA System S.A. +// +// Authors: Sam Gerené, Alex Vorobiev, Alexander van Delft, Jaime Bernar, Théate Antoine, Nabil Abbar +// +// 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. +// +// 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.Components.BookEditor +{ + using Bunit; + + using CDP4Common.ReportingData; + using CDP4Common.SiteDirectoryData; + + using COMET.Web.Common.Test.Helpers; + + using COMETwebapp.Components.BookEditor; + using COMETwebapp.Services.Interoperability; + + using Microsoft.AspNetCore.Components; + using Microsoft.Extensions.DependencyInjection; + + using Moq; + + using NUnit.Framework; + + using TestContext = Bunit.TestContext; + + [TestFixture] + public class BookEditorColumnTestFixture + { + private TestContext context; + private IRenderedComponent> component; + private Mock domDataService; + private bool editIsClicked; + private bool deleteIsClicked; + private bool isCollapsed; + private bool addNewItemIsClicked; + private Book selectedBook; + + [SetUp] + public void Setup() + { + this.context = new TestContext(); + this.context.ConfigureDevExpressBlazor(); + + this.domDataService = new Mock(); + + this.context.Services.AddSingleton(this.domDataService.Object); + + var book = new Book() + { + Name = "Book Example", + ShortName = "BookExample", + Owner = new DomainOfExpertise + { + Name = "Sys", + ShortName = "sys" + } + }; + + var onEditClicked = new EventCallbackFactory().Create(this, () => { this.editIsClicked = true;}); + var onDeleteClicked = new EventCallbackFactory().Create(this, () => { this.deleteIsClicked = true; }); + var onSelectedValueClicked = new EventCallbackFactory().Create(this, (b) => { this.selectedBook = b; }); + var onCollapseClicked = new EventCallbackFactory().Create(this, () => this.isCollapsed = true); + var onAddNewItemClicked = new EventCallbackFactory().Create(this, () => this.addNewItemIsClicked = true); + + this.component = this.context.RenderComponent>(parameters => + { + parameters.Add(p => p.CollapseButtonIconClass, "icon-class"); + parameters.Add(p => p.HeaderTitle, "TestColumn"); + parameters.Add(p => p.HeaderHexColor, "#CCC"); + parameters.Add(p => p.Items, new List() { book }); + parameters.Add(p => p.OnEditClicked, onEditClicked); + parameters.Add(p => p.OnDeleteClicked, onDeleteClicked); + parameters.Add(p => p.SelectedValueChanged, onSelectedValueClicked); + parameters.Add(p => p.CssClass, "node"); + parameters.Add(p => p.OnCollapseClicked, onCollapseClicked); + parameters.Add(p => p.OnCreateNewItemClick, onAddNewItemClicked); + }); + } + + [TearDown] + public void Teardown() + { + this.context.CleanContext(); + } + + [Test] + public void VerifyComponent() + { + var collapseButton = this.component.Find(".collapse-button"); + collapseButton.Click(); + + Assert.That(this.isCollapsed, Is.True); + + var addItemButton = this.component.Find(".add-item-button"); + addItemButton.Click(); + + Assert.That(this.addNewItemIsClicked, Is.True); + + var header = this.component.Find(".header-text"); + + Assert.Multiple(() => + { + Assert.That(header.Attributes["class"].Value, Is.EqualTo("header-text")); + Assert.That(header.HasAttribute("style"), Is.True); + }); + + var nodeButton = this.component.Find(".node-button"); + nodeButton.Click(); + + Assert.Multiple(() => + { + Assert.That(this.selectedBook, Is.Not.Null); + Assert.That(this.component.Instance.SelectedValue, Is.Not.Null); + }); + + var editButton = this.component.Find(".icon-edit"); + var deleteButton = this.component.Find(".icon-trash"); + + editButton.Click(); + deleteButton.Click(); + + Assert.Multiple(() => + { + Assert.That(this.editIsClicked, Is.True); + Assert.That(this.deleteIsClicked, Is.True); + }); + } + } +} + diff --git a/COMETwebapp.Tests/ViewModels/Components/BookEditor/BookEditorBodyViewModelTestFixture.cs b/COMETwebapp.Tests/ViewModels/Components/BookEditor/BookEditorBodyViewModelTestFixture.cs new file mode 100644 index 00000000..94a331d5 --- /dev/null +++ b/COMETwebapp.Tests/ViewModels/Components/BookEditor/BookEditorBodyViewModelTestFixture.cs @@ -0,0 +1,243 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// Copyright (c) 2023 RHEA System S.A. +// +// Authors: Sam Gerené, Alex Vorobiev, Alexander van Delft, Jaime Bernar, Théate Antoine, Nabil Abbar +// +// 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. +// +// 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.ViewModels.Components.BookEditor +{ + using CDP4Common.CommonData; + using CDP4Common.EngineeringModelData; + using CDP4Common.ReportingData; + + using COMET.Web.Common.Services.SessionManagement; + + using COMETwebapp.ViewModels.Components.BookEditor; + + using Moq; + + using NUnit.Framework; + + [TestFixture] + public class BookEditorBodyViewModelTestFixture + { + private IBookEditorBodyViewModel viewModel; + private Mock sessionService; + + [SetUp] + public void SetUp() + { + this.sessionService = new Mock(); + + this.viewModel = new BookEditorBodyViewModel(this.sessionService.Object); + } + + [Test] + public void VerifyProperties() + { + Assert.Multiple(() => + { + Assert.That(this.viewModel.SelectedBook, Is.Null); + Assert.That(this.viewModel.SelectedSection, Is.Null); + Assert.That(this.viewModel.SelectedPage, Is.Null); + Assert.That(this.viewModel.SelectedNote, Is.Null); + Assert.That(this.viewModel.AvailableBooks, Is.Not.Null); + Assert.That(this.viewModel.AvailableBooks, Is.Empty); + Assert.That(this.viewModel.AvailableCategories, Is.Not.Null); + Assert.That(this.viewModel.AvailableCategories, Is.Empty); + Assert.That(this.viewModel.ActiveDomains, Is.Not.Null); + Assert.That(this.viewModel.ActiveDomains, Is.Empty); + Assert.That(this.viewModel.ThingToCreate, Is.Null); + Assert.That(this.viewModel.ThingToDelete, Is.Null); + Assert.That(this.viewModel.ThingToEdit, Is.Null); + Assert.That(this.viewModel.EditorPopupViewModel, Is.Not.Null); + Assert.That(this.viewModel.ConfirmCancelPopupViewModel, Is.Not.Null); + }); + } + + private void FillSelectedItems() + { + var book = new Book(); + var section = new Section(); + var page = new Page(); + var note = new TextualNote(); + + this.viewModel.SelectedBook = book; + this.viewModel.SelectedSection = section; + this.viewModel.SelectedPage = page; + this.viewModel.SelectedNote = note; + } + + [Test] + public void VerifySelectedItemsAreReset() + { + this.FillSelectedItems(); + this.viewModel.SelectedBook = new Book(); + + Assert.Multiple(() => + { + Assert.That(this.viewModel.SelectedSection, Is.Null); + Assert.That(this.viewModel.SelectedPage, Is.Null); + Assert.That(this.viewModel.SelectedNote, Is.Null); + }); + + this.FillSelectedItems(); + this.viewModel.SelectedSection = new Section(); + + Assert.Multiple(() => + { + Assert.That(this.viewModel.SelectedBook, Is.Not.Null); + Assert.That(this.viewModel.SelectedPage, Is.Null); + Assert.That(this.viewModel.SelectedNote, Is.Null); + }); + + this.FillSelectedItems(); + this.viewModel.SelectedPage = new Page(); + + Assert.Multiple(() => + { + Assert.That(this.viewModel.SelectedBook, Is.Not.Null); + Assert.That(this.viewModel.SelectedSection, Is.Not.Null); + Assert.That(this.viewModel.SelectedNote, Is.Null); + }); + } + + [Test] + public void VerifySetThingToCreate() + { + //Try to set a thing that is not a book, section, page or note + Assert.That(() => this.viewModel.SetThingToCreate(new Iteration()), Throws.ArgumentException); + + var book = new Book(); + this.viewModel.SetThingToCreate(book); + + Assert.Multiple(() => + { + Assert.That(this.viewModel.ThingToCreate, Is.Not.Null); + Assert.That(this.viewModel.ThingToCreate, Is.EqualTo(book)); + Assert.That(this.viewModel.EditorPopupViewModel.HeaderText, Is.EqualTo("Create a new Book")); + Assert.That(this.viewModel.EditorPopupViewModel.OnConfirmClick, Is.Not.Null); + Assert.That(this.viewModel.EditorPopupViewModel.OnCancelClick, Is.Not.Null); + Assert.That(this.viewModel.EditorPopupViewModel.IsVisible = true); + }); + } + + [Test] + public void VerifyOnCreateThing() + { + //Try to create a thing when the thing to create has not been set + Assert.That(() => this.viewModel.OnCreateThing(), Throws.InvalidOperationException); + + var section = new Section(); + this.viewModel.SelectedBook = new Book(); + this.viewModel.SetThingToCreate(section); + + Assert.That(() => this.viewModel.OnCreateThing(), Throws.Nothing); + + this.sessionService.Verify(x => x.CreateThing(It.IsAny(), It.IsAny()), Times.Once); + + Assert.Multiple(() => + { + Assert.That(this.viewModel.ThingToCreate, Is.Null); + Assert.That(this.viewModel.EditorPopupViewModel.IsVisible, Is.False); + }); + } + + [Test] + public void VerifySetThingToEdit() + { + //Try to set a thing that is not a book, section, page or note + Assert.That(() => this.viewModel.SetThingToEdit(new Iteration()), Throws.ArgumentException); + + var book = new Book(); + this.viewModel.SetThingToEdit(book); + + Assert.Multiple(() => + { + Assert.That(this.viewModel.ThingToEdit, Is.Not.Null); + Assert.That(this.viewModel.ThingToEdit, Is.EqualTo(book)); + Assert.That(this.viewModel.EditorPopupViewModel.HeaderText, Is.EqualTo("Edit the Book")); + Assert.That(this.viewModel.EditorPopupViewModel.OnConfirmClick, Is.Not.Null); + Assert.That(this.viewModel.EditorPopupViewModel.OnCancelClick, Is.Not.Null); + Assert.That(this.viewModel.EditorPopupViewModel.IsVisible = true); + }); + } + + [Test] + public void VerifyOnEditThing() + { + //Try to edit a thing when the thing to edit has not been set + Assert.That(() => this.viewModel.OnEditThing(), Throws.InvalidOperationException); + + var section = new Section(); + section.Container = new Book(); + this.viewModel.SetThingToEdit(section); + + Assert.That(() => this.viewModel.OnEditThing(), Throws.Nothing); + + this.sessionService.Verify(x => x.UpdateThing(It.IsAny(), It.IsAny()), Times.Once); + + Assert.Multiple(() => + { + Assert.That(this.viewModel.ThingToEdit, Is.Null); + Assert.That(this.viewModel.EditorPopupViewModel.IsVisible, Is.False); + }); + } + + [Test] + public void VerifySetThingToDelete() + { + //Try to set a thing that is not a book, section, page or note + Assert.That(() => this.viewModel.SetThingToDelete(new Iteration()), Throws.ArgumentException); + + var book = new Book(); + this.viewModel.SetThingToDelete(book); + + Assert.Multiple(() => + { + Assert.That(this.viewModel.ThingToDelete, Is.Not.Null); + Assert.That(this.viewModel.ThingToDelete, Is.EqualTo(book)); + Assert.That(this.viewModel.ConfirmCancelPopupViewModel.IsVisible, Is.True); + }); + } + + [Test] + public void VerifyOnDeleteThing() + { + //Try to delete a thing when the thing to delete has not been set + Assert.That(() => this.viewModel.OnDeleteThing(), Throws.InvalidOperationException); + + var section = new Section(); + section.Container = new Book(); + this.viewModel.SetThingToDelete(section); + + Assert.That(() => this.viewModel.OnDeleteThing(), Throws.Nothing); + + this.sessionService.Verify(x => x.DeleteThing(It.IsAny(), It.IsAny()), Times.Once); + + Assert.Multiple(() => + { + Assert.That(this.viewModel.ThingToDelete, Is.Null); + Assert.That(this.viewModel.EditorPopupViewModel.IsVisible, Is.False); + }); + } + } +} diff --git a/COMETwebapp/Components/BookEditor/BookEditorBody.razor b/COMETwebapp/Components/BookEditor/BookEditorBody.razor index 189c6028..fe8404a3 100644 --- a/COMETwebapp/Components/BookEditor/BookEditorBody.razor +++ b/COMETwebapp/Components/BookEditor/BookEditorBody.razor @@ -27,11 +27,11 @@ - - - -
+ + + + @@ -54,7 +54,7 @@ IsCollapsed="@this.IsSectionColumnCollapsed" OnCollapseClicked="@(() => this.IsBooksColumnCollapsed = !this.IsBooksColumnCollapsed)" CollapseButtonIconClass="@(this.IsBooksColumnCollapsed ? "icon-arrow-right" : "icon-arrow-left")" - CssClass="section-nodes" + CssClass="section-node" OnCreateNewItemClick="@(() => this.ViewModel.SetThingToCreate(new Section()))" OnEditClicked="@((s) => this.ViewModel.SetThingToEdit(s))" OnDeleteClicked="@((s) => this.ViewModel.SetThingToDelete(s))" @@ -70,7 +70,7 @@ IsCollapsed="@this.IsPageColumnCollapsed" OnCollapseClicked="@(() => this.IsSectionColumnCollapsed = !this.IsSectionColumnCollapsed)" CollapseButtonIconClass="@(this.IsSectionColumnCollapsed ? "icon-arrow-right" : "icon-arrow-left")" - CssClass="page-nodes" + CssClass="page-node" OnCreateNewItemClick="@(() => this.ViewModel.SetThingToCreate(new Page()))" OnEditClicked="@((p) => this.ViewModel.SetThingToEdit(p))" OnDeleteClicked="@((p) => this.ViewModel.SetThingToDelete(p))" @@ -85,7 +85,7 @@ @bind-SelectedValue="@this.ViewModel.SelectedNote" OnCollapseClicked="@(() => this.IsPageColumnCollapsed = !this.IsPageColumnCollapsed)" CollapseButtonIconClass="@(this.IsPageColumnCollapsed ? "icon-arrow-right" : "icon-arrow-left")" - CssClass="note-nodes" + CssClass="note-node" OnCreateNewItemClick="@(() => this.ViewModel.SetThingToCreate(new TextualNote(){ LanguageCode = "es" }))" OnEditClicked="@((n) => this.ViewModel.SetThingToEdit(n))" OnDeleteClicked="@((n) => this.ViewModel.SetThingToDelete(n))" diff --git a/COMETwebapp/Components/BookEditor/BookEditorColumn.razor b/COMETwebapp/Components/BookEditor/BookEditorColumn.razor index b9203249..8ea5d3a3 100644 --- a/COMETwebapp/Components/BookEditor/BookEditorColumn.razor +++ b/COMETwebapp/Components/BookEditor/BookEditorColumn.razor @@ -31,7 +31,7 @@
-
@this.HeaderTitle
+
@this.HeaderTitle
@@ -56,7 +56,7 @@ } -