Skip to content

Commit

Permalink
Refactor the NamingConventionService so that it works for both Server…
Browse files Browse the repository at this point in the history
… and WASM modes. Add new test fixtures for WASM mode. Add two loading types (file loading and via http request).
  • Loading branch information
Robbware committed Oct 18, 2023
1 parent 78ea60d commit 4c84a11
Show file tree
Hide file tree
Showing 7 changed files with 385 additions and 115 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

namespace COMET.Web.Common.Tests.Services.NamingConventionService
{
using COMET.Web.Common.Server.Services.NamingConventionService;
using COMET.Web.Common.Services.NamingConventionService;

using Microsoft.Extensions.Logging;
Expand Down Expand Up @@ -53,13 +54,13 @@ public async Task VerifyInitializationAndGetNamingConvention()
await this.service.InitializeService();
var enumValues = Enum.GetValues<NamingConventionKindTestEnum>();

foreach (var namingConventionKind in enumValues)
Assert.Multiple(() =>
{
Assert.Multiple(() =>
foreach (var namingConventionKind in enumValues)
{
Assert.That(this.service.GetNamingConventionValue(namingConventionKind), Is.Not.Empty);
});
}
}
});
}

/// To be used for testing purposes only
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="NamingConventionServiceTestFixture.cs" company="RHEA System S.A.">
// 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.
//
// 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.WebAssembly.Services.NamingConventionService;

using System.Net;

using COMET.Web.Common.Services.NamingConventionService;
using COMET.Web.Common.Test.Helpers;
using COMET.Web.Common.WebAssembly.Services.NamingConventionService;

using Microsoft.Extensions.Logging;

using Moq;

using NUnit.Framework;

using RichardSzalay.MockHttp;

[TestFixture]
public class NamingConventionServiceTestFixture
{
private NamingConventionService<NamingConventionKindTestEnum> service;
private MockHttpMessageHandler mockHttpMessageHandler;
private Mock<ILogger<INamingConventionService<NamingConventionKindTestEnum>>> logger;

[SetUp]
public void Setup()
{
this.mockHttpMessageHandler = new MockHttpMessageHandler();
var httpClient = this.mockHttpMessageHandler.ToHttpClient();
httpClient.BaseAddress = new Uri("http://localhost/");
this.logger = new Mock<ILogger<INamingConventionService<NamingConventionKindTestEnum>>>();
this.service = new NamingConventionService<NamingConventionKindTestEnum>(this.logger.Object, httpClient);
}

[Test]
public async Task VerifyService()
{
this.mockHttpMessageHandler.When(HttpMethod.Get, "/_content/CDP4.WEB.Common/naming_convention.json")
.Throw(new Exception());

await this.service.InitializeService();
this.logger.Verify(LogLevel.Critical, o => o!.ToString()!.Contains("Exception has been raised"), Times.Once());

this.mockHttpMessageHandler.ResetBackendDefinitions();

var httpResponse = new HttpResponseMessage()
{
StatusCode = HttpStatusCode.InternalServerError
};

this.mockHttpMessageHandler.When(HttpMethod.Get, "/_content/CDP4.WEB.Common/naming_convention.json")
.Respond(_ => httpResponse);

await this.service.InitializeService();
this.logger.Verify(LogLevel.Error, o => o!.ToString()!.Contains("Error fetching naming conventions. Status code:"), Times.Once());

httpResponse.StatusCode = HttpStatusCode.NotFound;

await this.service.InitializeService();
this.logger.Verify(LogLevel.Error, o => o!.ToString()!.Contains("Naming conventions file not found at "), Times.Once());

httpResponse.StatusCode = HttpStatusCode.OK;

var json = """
{
"TestValue1": "TestValue1",
"TestValue2": "TestValue2"
}
""";

httpResponse.Content = new StringContent(json);
await this.service.InitializeService();

var enumValues = Enum.GetValues<NamingConventionKindTestEnum>();

Assert.Multiple(() =>
{
foreach (var namingConventionKind in enumValues)
{
Assert.That(this.service.GetNamingConventionValue(namingConventionKind), Is.Not.Empty);
}
});
}

/// To be used for testing purposes only
public enum NamingConventionKindTestEnum
{
TestValue1,
TestValue2
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="NamingConventionService.cs" company="RHEA System S.A.">
// 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.
//
// 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.Server.Services.NamingConventionService
{
using System.Text.Json;

using COMET.Web.Common.Services.NamingConventionService;

using Microsoft.Extensions.Logging;

/// <summary>
/// The <see cref="NamingConventionService" /> provides static information based on defined naming convention, like for names of
/// <see cref="Category" /> to use for example
/// </summary>
public class NamingConventionService<TEnum> : BaseNamingConventionService<TEnum> where TEnum : Enum
{
/// <summary>
/// The <see cref="ILogger{TCategoryName}" />
/// </summary>
private readonly ILogger<INamingConventionService<TEnum>> logger;

public NamingConventionService(ILogger<INamingConventionService<TEnum>> logger) : base(logger)
{
this.logger = logger;
}

/// <summary>
/// Gets the naming convention configuration
/// </summary>
/// <returns>A <see cref="IReadOnlyDictionary{TKey,TValue}"/> of the naming convention configuration</returns>
public override async Task<IReadOnlyDictionary<string, string>> GetNamingConventionConfiguration()
{
try
{
var namingConvention = JsonSerializer.Deserialize<Dictionary<string, string>>(await File.ReadAllTextAsync(Path.Combine("Resources", "configuration", "naming_convention.json")))!;
return new Dictionary<string, string>(namingConvention, StringComparer.OrdinalIgnoreCase);
}
catch (Exception e)
{
this.logger.LogError(e, "Error while getting the naming convention configuration file.");
throw;
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="BaseNamingConventionService.cs" company="RHEA System S.A.">
// 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.
//
// 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.Services.NamingConventionService;

using Microsoft.Extensions.Logging;

public class BaseNamingConventionService<TEnum> : INamingConventionService<TEnum> where TEnum : Enum
{
/// <summary>
/// <see cref="Dictionary{TKey,TValue}" /> that holds the defined naming convention
/// </summary>
private readonly Dictionary<string, string> definedNaming = new(StringComparer.OrdinalIgnoreCase);

/// <summary>
/// The <see cref="ILogger{TCategoryName}" />
/// </summary>
private readonly ILogger<INamingConventionService<TEnum>> logger;

/// <summary>
/// Initializes a new instance of the <see cref="NamingConventionService" /> class.
/// </summary>
/// <param name="logger">The <see cref="ILogger{TCategoryName}" /></param>
protected BaseNamingConventionService(ILogger<INamingConventionService<TEnum>> logger)
{
this.logger = logger;
}

/// <summary>
/// Initializes this service
/// </summary>
/// <returns>A <see cref="Task" /></returns>
public async Task InitializeService()
{
var namingConvention = await this.GetNamingConventionConfiguration();

foreach (var namingConventionKind in Enum.GetValues(typeof(TEnum)))
{
if (namingConvention.TryGetValue(namingConventionKind.ToString(), out var namingConventionValue))
{
this.definedNaming[namingConventionKind.ToString()] = namingConventionValue;
}
else
{
this.logger.LogWarning("{namingConventionKind} is missing from the Naming Convention configuration file", namingConventionKind.ToString());
}
}
}

/// <summary>
/// Gets the value for naming convention
/// </summary>
/// <param name="namingConventionKey">The naming convention key</param>
/// <returns>The defined naming convention, if exists</returns>
public string GetNamingConventionValue(string namingConventionKey)
{
return this.definedNaming.TryGetValue(namingConventionKey, out var namingConventionValue) ? namingConventionValue : string.Empty;
}

/// <summary>
/// Gets the value for naming convention
/// </summary>
/// <param name="namingConventionKind">The <see cref="NamingConventionKind" /></param>
/// <returns>The defined naming convention, if exists</returns>
public string GetNamingConventionValue(TEnum namingConventionKind)
{
return this.GetNamingConventionValue(namingConventionKind.ToString());
}

/// <summary>
/// Gets the naming convention configuration
/// </summary>
/// <returns>A <see cref="IReadOnlyDictionary{TKey,TValue}"/> of the naming convention configuration</returns>
/// <exception cref="NotImplementedException"></exception>
public virtual Task<IReadOnlyDictionary<string, string>> GetNamingConventionConfiguration()
{
throw new NotImplementedException();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ namespace COMET.Web.Common.Services.NamingConventionService
/// <summary>
/// The <see cref="INamingConventionService"/> provides static information based on defined naming convention, like for names of <see cref="Category"/> to use for example
/// </summary>
public interface INamingConventionService<TEnum> where TEnum : Enum
public interface INamingConventionService<in TEnum> where TEnum : Enum
{
/// <summary>
/// Initializes this service
Expand All @@ -49,5 +49,7 @@ public interface INamingConventionService<TEnum> where TEnum : Enum
/// <param name="namingConventionKind">The <see cref="NamingConventionKind" /></param>
/// <returns>The defined naming convention, if exists</returns>
string GetNamingConventionValue(TEnum namingConventionKind);

Task<IReadOnlyDictionary<string, string>> GetNamingConventionConfiguration();
}
}
Loading

0 comments on commit 4c84a11

Please sign in to comment.