Skip to content

Commit

Permalink
Fix #387 - Add portal name setting (#449)
Browse files Browse the repository at this point in the history
  • Loading branch information
kbeaugrand authored Mar 11, 2022
1 parent 6f03b07 commit fd9a56b
Show file tree
Hide file tree
Showing 11 changed files with 103 additions and 102 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ namespace AzureIoTHub.Portal.Server.Tests.Unit.Controllers.V10
using System;
using AzureIoTHub.Portal.Server.Controllers.V10;
using AzureIoTHub.Portal.Server.Identity;
using AzureIoTHub.Portal.Shared.Models.V10;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Moq;
Expand Down Expand Up @@ -79,10 +80,14 @@ public void GetLoRaActivationSettingShouldReturnTrueToString()
.SetupGet(c => c.IsLoRaEnabled)
.Returns(loraFeatureStatus);

_ = this.mockConfigHandler
.SetupGet(c => c.PortalName)
.Returns(string.Empty);

var controller = this.CreateController();

// Act
var response = controller.GetLoRaActivationSetting();
var response = controller.GetPortalSetting();

// Assert
Assert.IsNotNull(response);
Expand All @@ -91,7 +96,10 @@ public void GetLoRaActivationSettingShouldReturnTrueToString()

Assert.AreEqual(200, okObjectResult.StatusCode);
Assert.IsNotNull(okObjectResult.Value);
Assert.AreEqual(loraFeatureStatus, okObjectResult.Value);
Assert.IsAssignableFrom<PortalSettings>(okObjectResult.Value);
var okSettings = okObjectResult.Value as PortalSettings;

Assert.AreEqual(loraFeatureStatus, okSettings.IsLoRaSupported);

this.mockRepository.VerifyAll();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ namespace AzureIoTHub.Portal.Server.Tests.Unit.Pages
using System.Threading.Tasks;
using AzureIoTHub.Portal.Client.Pages.Devices;
using AzureIoTHub.Portal.Server.Tests.Unit.Helpers;
using AzureIoTHub.Portal.Shared.Models.V10;
using AzureIoTHub.Portal.Shared.Models.V10.Device;
using Bunit;
using Bunit.TestDoubles;
Expand All @@ -29,11 +30,9 @@ public class DevicesListPageTests : IDisposable

private MockRepository mockRepository;
private Mock<IDialogService> mockDialogService;
private FakeNavigationManager mockNavigationManager;
private MockHttpMessageHandler mockHttpClient;

private readonly string apiBaseUrl = "/api/Devices";
private readonly string apiSettingsBaseUrl = "/api/settings/lora";
private readonly string apiTagsBaseUrl = "/api/settings/device-tags";

[SetUp]
Expand All @@ -47,14 +46,11 @@ public void SetUp()
this.mockHttpClient = testContext.Services.AddMockHttpClient();

_ = testContext.Services.AddSingleton(this.mockDialogService.Object);

_ = testContext.Services.AddMudServices();

_ = testContext.JSInterop.SetupVoid("mudKeyInterceptor.connect", _ => true);
_ = testContext.JSInterop.SetupVoid("mudPopover.connect", _ => true);
_ = testContext.JSInterop.Setup<BoundingClientRect>("mudElementRef.getBoundingClientRect", _ => true);

mockNavigationManager = testContext.Services.GetRequiredService<FakeNavigationManager>();
}

private IRenderedComponent<TComponent> RenderComponent<TComponent>(params ComponentParameter[] parameters)
Expand All @@ -73,9 +69,7 @@ public void DeviceListPageRendersCorrectly()
.When(HttpMethod.Get, apiBaseUrl)
.RespondJson(Array.Empty<object>());

_ = this.mockHttpClient
.When(HttpMethod.Get, apiSettingsBaseUrl)
.RespondJson(true);
_ = testContext.Services.AddSingleton(new PortalSettings { IsLoRaSupported = true });

// Act
var cut = RenderComponent<DeviceListPage>();
Expand Down Expand Up @@ -107,9 +101,7 @@ public void WhenDevicesNotLoadedDeviceListPageShouldRenderProgressBar()
.When(HttpMethod.Get, apiBaseUrl)
.RespondJsonAsync(task);

_ = this.mockHttpClient
.When(HttpMethod.Get, apiSettingsBaseUrl)
.RespondJson(true);
_ = testContext.Services.AddSingleton(new PortalSettings { IsLoRaSupported = true });

// Act
var cut = RenderComponent<DeviceListPage>();
Expand All @@ -129,9 +121,7 @@ public async Task WhenResetFilterButtonClickShouldClearFilters()
.When(HttpMethod.Get, apiBaseUrl)
.RespondJson(Array.Empty<object>());

_ = this.mockHttpClient
.When(HttpMethod.Get, apiSettingsBaseUrl)
.RespondJson(true);
_ = testContext.Services.AddSingleton(new PortalSettings { IsLoRaSupported = true });

_ = this.mockHttpClient
.When(HttpMethod.Get, apiTagsBaseUrl)
Expand Down Expand Up @@ -166,9 +156,7 @@ public async Task WhenAddNewDeviceClickShouldNavigateToNewDevicePage(string butt
.When(HttpMethod.Get, apiBaseUrl)
.RespondJson(Array.Empty<object>());

_ = this.mockHttpClient
.When(HttpMethod.Get, apiSettingsBaseUrl)
.RespondJson(true);
_ = testContext.Services.AddSingleton(new PortalSettings { IsLoRaSupported = true });

_ = this.mockHttpClient
.When(HttpMethod.Get, apiTagsBaseUrl)
Expand All @@ -183,7 +171,8 @@ public async Task WhenAddNewDeviceClickShouldNavigateToNewDevicePage(string butt
await Task.Delay(100);

// Assert
Assert.AreEqual("http://localhost/devices/new", this.mockNavigationManager.Uri);
var mockNavigationManager = testContext.Services.GetRequiredService<FakeNavigationManager>();
Assert.AreEqual("http://localhost/devices/new", mockNavigationManager.Uri);
this.mockRepository.VerifyAll();
}

Expand All @@ -195,9 +184,7 @@ public async Task WhenRefreshClickShouldReloadFromApi()
.When(HttpMethod.Get, apiBaseUrl)
.RespondJson(Array.Empty<object>());

_ = this.mockHttpClient
.When(HttpMethod.Get, apiSettingsBaseUrl)
.RespondJson(true);
_ = testContext.Services.AddSingleton(new PortalSettings { IsLoRaSupported = true });

_ = this.mockHttpClient
.When(HttpMethod.Get, apiTagsBaseUrl)
Expand Down Expand Up @@ -230,9 +217,7 @@ public void WhenLoraFeatureDisableDeviceDetailLinkShouldNotContainLora()
.When(HttpMethod.Get, apiBaseUrl)
.RespondJson(new DeviceListItem[] { new DeviceListItem { DeviceID = deviceId } });

_ = this.mockHttpClient
.When(HttpMethod.Get, apiSettingsBaseUrl)
.RespondJson(false);
_ = testContext.Services.AddSingleton(new PortalSettings { IsLoRaSupported = false });

_ = this.mockHttpClient
.When(HttpMethod.Get, apiTagsBaseUrl)
Expand Down Expand Up @@ -262,9 +247,7 @@ public void WhenLoraFeatureEnableDeviceDetailLinkShouldContainLora()
.When(HttpMethod.Get, apiBaseUrl)
.RespondJson(new DeviceListItem[] { new DeviceListItem { DeviceID = deviceId, SupportLoRaFeatures = true } });

_ = this.mockHttpClient
.When(HttpMethod.Get, apiSettingsBaseUrl)
.RespondJson(true);
_ = testContext.Services.AddSingleton(new PortalSettings { IsLoRaSupported = true });

_ = this.mockHttpClient
.When(HttpMethod.Get, apiTagsBaseUrl)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,8 @@ public class CreateDeviceModelPageTests : IDisposable

private MockRepository mockRepository;
private Mock<IDialogService> mockDialogService;
private FakeNavigationManager mockNavigationManager;
private MockHttpMessageHandler mockHttpClient;

private static readonly string ApiSettingsLora = "/api/settings/lora";
private static string apiBaseUrl => $"/api/models";

[SetUp]
Expand All @@ -58,8 +56,6 @@ public void SetUp()
_ = testContext.JSInterop.Setup<BoundingClientRect>("mudElementRef.getBoundingClientRect", _ => true);
_ = testContext.JSInterop.Setup<IEnumerable<BoundingClientRect>>("mudResizeObserver.connect", _ => true);

mockNavigationManager = testContext.Services.GetRequiredService<FakeNavigationManager>();

this.mockHttpClient.AutoFlush = true;
}

Expand All @@ -85,8 +81,7 @@ public void ClickOnSaveShouldPostDeviceModelData()
PropertyType = DevicePropertyType.Double
}).ToArray();

_ = this.mockHttpClient.When(ApiSettingsLora)
.RespondJson(false);
_ = testContext.Services.AddSingleton(new PortalSettings { IsLoRaSupported = false });

_ = this.mockHttpClient.When(HttpMethod.Post, $"{apiBaseUrl}")
.With(m =>
Expand Down Expand Up @@ -139,7 +134,7 @@ public void ClickOnSaveShouldPostDeviceModelData()
cut.Find($"#{nameof(DeviceModel.Description)}").Change(description);

saveButton.Click();
cut.WaitForState(() => this.mockNavigationManager.Uri.EndsWith("/device-models", StringComparison.OrdinalIgnoreCase));
cut.WaitForState(() => testContext.Services.GetRequiredService<FakeNavigationManager>().Uri.EndsWith("/device-models", StringComparison.OrdinalIgnoreCase));

// Assert
this.mockHttpClient.VerifyNoOutstandingExpectation();
Expand All @@ -155,8 +150,7 @@ public void ClickOnAddPropertyShouldAddNewProperty()
_ = this.mockHttpClient.When(HttpMethod.Post, $"{ apiBaseUrl}")
.RespondText(string.Empty);

_ = this.mockHttpClient.When(ApiSettingsLora)
.RespondJson(false);
_ = testContext.Services.AddSingleton(new PortalSettings { IsLoRaSupported = false });

_ = this.mockHttpClient.When(HttpMethod.Post, $"{ apiBaseUrl}/properties")
.With(m =>
Expand Down Expand Up @@ -200,7 +194,7 @@ public void ClickOnAddPropertyShouldAddNewProperty()
cut.Find($"{propertyCssSelector} #{nameof(DeviceProperty.IsWritable)}").Change(true);

saveButton.Click();
cut.WaitForState(() => this.mockNavigationManager.Uri.EndsWith("/device-models", StringComparison.OrdinalIgnoreCase));
cut.WaitForState(() => testContext.Services.GetRequiredService<FakeNavigationManager>().Uri.EndsWith("/device-models", StringComparison.OrdinalIgnoreCase));

// Assert
this.mockHttpClient.VerifyNoOutstandingExpectation();
Expand All @@ -213,8 +207,7 @@ public void ClickOnRemovePropertyShouldRemoveTheProperty()
var propertyName = Guid.NewGuid().ToString();
var displayName = Guid.NewGuid().ToString();

_ = this.mockHttpClient.When(ApiSettingsLora)
.RespondJson(false);
_ = testContext.Services.AddSingleton(new PortalSettings { IsLoRaSupported = false });

_ = this.mockHttpClient.When(HttpMethod.Post, $"{ apiBaseUrl}")
.RespondText(string.Empty);
Expand Down Expand Up @@ -250,7 +243,7 @@ public void ClickOnRemovePropertyShouldRemoveTheProperty()
removePropertyButton.Click();

saveButton.Click();
cut.WaitForState(() => this.mockNavigationManager.Uri.EndsWith("/device-models", StringComparison.OrdinalIgnoreCase));
cut.WaitForState(() => testContext.Services.GetRequiredService<FakeNavigationManager>().Uri.EndsWith("/device-models", StringComparison.OrdinalIgnoreCase));

// Assert
this.mockHttpClient.VerifyNoOutstandingExpectation();
Expand All @@ -260,8 +253,7 @@ public void ClickOnRemovePropertyShouldRemoveTheProperty()
public void WhenLoraFeatureIsDisabledModelDetailsShouldNotDisplayLoRaWANSwitch()
{
// Arrange
_ = this.mockHttpClient.When(ApiSettingsLora)
.RespondJson(false);
_ = testContext.Services.AddSingleton(new PortalSettings { IsLoRaSupported = false });

// Act
var cut = RenderComponent<CreateDeviceModelPage>();
Expand All @@ -277,8 +269,7 @@ public void WhenLoraFeatureIsDisabledModelDetailsShouldNotDisplayLoRaWANSwitch()
public void WhenLoraFeatureIsEnabledModelDetailsShouldDisplayLoRaWANSwitch()
{
// Arrange
_ = this.mockHttpClient.When(ApiSettingsLora)
.RespondJson(true);
_ = testContext.Services.AddSingleton(new PortalSettings { IsLoRaSupported = true });

// Act
var cut = RenderComponent<CreateDeviceModelPage>();
Expand All @@ -293,8 +284,7 @@ public void WhenLoraFeatureIsEnabledModelDetailsShouldDisplayLoRaWANSwitch()
public void WhenLoraFeatureIsEnabledModelDetailsShouldDisplayLoRaWANTab()
{
// Arrange
_ = this.mockHttpClient.When(ApiSettingsLora)
.RespondJson(true);
_ = testContext.Services.AddSingleton(new PortalSettings { IsLoRaSupported = true });

var cut = RenderComponent<CreateDeviceModelPage>();
_ = cut.WaitForElement("#form");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
@attribute [Authorize]
@inject HttpClient httpClient
@inject NavigationManager NavigationManager
@inject PortalSettings Portal
@inject ISnackbar Snackbar
@inject IDialogService DialogService

Expand Down Expand Up @@ -62,7 +63,7 @@
<MudItem xs="12" md="6">
<MudTextField id="@nameof(Model.Description)" @bind-Value="@Model.Description" For="@(() => Model.Description)" Label="Description" Variant="Variant.Outlined" Lines="5" />
</MudItem>
@if (activateLoRaFeature)
@if (Portal.IsLoRaSupported)
{
<MudItem xs="12">
<MudText>
Expand Down Expand Up @@ -182,13 +183,6 @@
}
}

private bool activateLoRaFeature;

protected override async Task OnInitializedAsync()
{
this.activateLoRaFeature = await httpClient.GetFromJsonAsync<bool>("api/settings/lora");
}

private void SetLoRaDeviceModel()
{
Model = new LoRaDeviceModel(Model);
Expand Down Expand Up @@ -330,4 +324,4 @@
// Go back to the list of devices
NavigationManager.NavigateTo("device-models");
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
@page "/devices"
@using AzureIoTHub.Portal.Shared.Models.V10
@using AzureIoTHub.Portal.Shared.Models.V10.Device
@using AzureIoTHub.Portal.Shared.Models.V10.DeviceModel
@using Microsoft.AspNetCore.Authorization
Expand All @@ -8,6 +9,7 @@
@inject HttpClient Http
@inject IDialogService DialogService
@inject NavigationManager navigationManager
@inject PortalSettings Portal

<MudText Typo="Typo.h5" Color="Color.Primary" Class="mb-4">Device List</MudText>

Expand Down Expand Up @@ -113,7 +115,7 @@
<img height="25" src="@context.ImageUrl" />
</MudTd>
<MudTd DataLabel="Device" Style="word-break: break-all;">
<a class="detail-link" href="@($"devices/{@context.DeviceID}{((@context.SupportLoRaFeatures && isLoraEnable) ? "?isLora=true": "")}")">
<a class="detail-link" href="@($"devices/{@context.DeviceID}{((@context.SupportLoRaFeatures && Portal.IsLoRaSupported) ? "?isLora=true": "")}")">
@(string.IsNullOrEmpty(context.DeviceName) ? context.DeviceID : context.DeviceName)
</a>
</MudTd>
Expand Down Expand Up @@ -141,7 +143,7 @@
</MudTd>
<MudTd DataLabel="LSU" Style="text-align: center">@context.StatusUpdatedTime</MudTd>
<MudTd DataLabel="Details" Style="text-align: center">
<a class="detail-link" href="@($"devices/{@context.DeviceID}{((@context.SupportLoRaFeatures && isLoraEnable) ? "?isLora=true": "")}")">
<a class="detail-link" href="@($"devices/{@context.DeviceID}{((@context.SupportLoRaFeatures && Portal.IsLoRaSupported) ? "?isLora=true": "")}")">
<MudIconButton Icon="@Icons.Filled.Visibility" Color="Color.Default" />
</a>
</MudTd>
Expand Down Expand Up @@ -169,15 +171,12 @@
private string searchState = "";
private Dictionary<string, string> searchTags = new();

private bool isLoraEnable;

private IEnumerable<DeviceTag> TagList { get; set; } = new List<DeviceTag>();

private int[] pageSizeOptions = new int[] { 2, 5, 10 };

protected override async Task OnInitializedAsync()
{
isLoraEnable = await this.Http.GetFromJsonAsync<bool>("api/settings/lora");
await LoadDevices();

// Gets the custom tags that can be searched via the panel
Expand Down
11 changes: 10 additions & 1 deletion src/AzureIoTHub.Portal/Client/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ namespace AzureIoTHub.Portal.Client
using System.Net.Http;
using System.Net.Http.Json;
using System.Threading.Tasks;
using System.Text.Json;
using AzureIoTHub.Portal.Client.Services;
using AzureIoTHub.Portal.Shared.Settings;
using Blazored.Modal;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using Microsoft.Extensions.DependencyInjection;
using MudBlazor.Services;
using Tewr.Blazor.FileReader;
using AzureIoTHub.Portal.Shared.Models.V10;

public class Program
{
Expand All @@ -40,6 +40,7 @@ public static async Task Main(string[] args)
_ = builder.Services.AddScoped<ClipboardService>();

await ConfigureOidc(builder);
await ConfigurePortalSettings(builder);

await builder.Build().RunAsync();
}
Expand All @@ -61,5 +62,13 @@ private static async Task ConfigureOidc(WebAssemblyHostBuilder builder)
options.ProviderOptions.ResponseType = "id_token";
});
}

private static async Task ConfigurePortalSettings(WebAssemblyHostBuilder builder)
{
using var httpClient = new HttpClient() { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) };
var settings = await httpClient.GetFromJsonAsync<PortalSettings>("api/settings/portal");

_ = builder.Services.AddSingleton(settings);
}
}
}
Loading

0 comments on commit fd9a56b

Please sign in to comment.