diff --git a/reqifviewer.Tests/Pages/Index/IndexPageTestFixture.cs b/reqifviewer.Tests/Pages/Index/IndexPageTestFixture.cs index 28cbf48..4319fb6 100644 --- a/reqifviewer.Tests/Pages/Index/IndexPageTestFixture.cs +++ b/reqifviewer.Tests/Pages/Index/IndexPageTestFixture.cs @@ -20,6 +20,8 @@ namespace ReqifViewer.Tests.Pages.Index { + using System.Collections.Generic; + using System.Globalization; using System.IO; using System.Threading; using System.Threading.Tasks; @@ -27,6 +29,7 @@ namespace ReqifViewer.Tests.Pages.Index using Bunit; using Microsoft.AspNetCore.Components.Forms; + using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Moq; @@ -39,7 +42,7 @@ namespace ReqifViewer.Tests.Pages.Index using ReqIFSharp.Extensions.Services; using reqifviewer.Pages.Index; - + using reqifviewer.Utilities; using TestContext = Bunit.TestContext; /// @@ -50,7 +53,8 @@ public class IndexPageTestFixture { private Mock reqIfLoaderService; private TestContext context; - private const long MaxFileSize = 5 * 1024 * 1024; + private IConfiguration configuration; + private const double MaxFileSizeInMb = 5; [SetUp] public void SetUp() @@ -58,7 +62,12 @@ public void SetUp() this.context = new TestContext(); this.reqIfLoaderService = new Mock(); + this.configuration = new ConfigurationBuilder() + .AddInMemoryCollection([new KeyValuePair(Constants.MaxUploadFileSizeInMbConfigurationKey, MaxFileSizeInMb.ToString(CultureInfo.InvariantCulture))]) + .Build(); + this.context.Services.AddSingleton(this.reqIfLoaderService.Object); + this.context.Services.AddSingleton(this.configuration); } [TearDown] @@ -72,16 +81,17 @@ public async Task VerifyComponent() { var renderer = this.context.RenderComponent(); var uploadComponent = renderer.FindComponent(); + var maxFileSizeInBytes = (long)(MaxFileSizeInMb * 1024 * 1024); var file = new Mock(); - file.Setup(x => x.Size).Returns(MaxFileSize + 1); + file.Setup(x => x.Size).Returns(maxFileSizeInBytes + 1); file.Setup(x => x.Name).Returns("file.reqif"); file.Setup(x => x.OpenReadStream(It.IsAny(), It.IsAny())).Returns(new MemoryStream()); await renderer.InvokeAsync(() => uploadComponent.Instance.OnChange.InvokeAsync(new InputFileChangeEventArgs([file.Object]))); file.Verify(x => x.OpenReadStream(It.IsAny(), It.IsAny()), Times.Never); - file.Setup(x => x.Size).Returns(MaxFileSize - 1); + file.Setup(x => x.Size).Returns(maxFileSizeInBytes - 1); await renderer.InvokeAsync(() => uploadComponent.Instance.OnChange.InvokeAsync(new InputFileChangeEventArgs([file.Object]))); file.Verify(x => x.OpenReadStream(It.IsAny(), It.IsAny()), Times.Once); diff --git a/reqifviewer/Pages/Index/AboutComponent.razor b/reqifviewer/Pages/Index/AboutComponent.razor index 8cdd3ad..d417512 100644 --- a/reqifviewer/Pages/Index/AboutComponent.razor +++ b/reqifviewer/Pages/Index/AboutComponent.razor @@ -47,7 +47,7 @@ limitations under the License.
- +
diff --git a/reqifviewer/Pages/Index/IndexPage.razor.cs b/reqifviewer/Pages/Index/IndexPage.razor.cs index 355770c..7cbaf81 100644 --- a/reqifviewer/Pages/Index/IndexPage.razor.cs +++ b/reqifviewer/Pages/Index/IndexPage.razor.cs @@ -22,6 +22,7 @@ namespace reqifviewer.Pages.Index { using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Forms; + using Microsoft.Extensions.Configuration; using ReqIFSharp; using ReqIFSharp.Extensions.Services; @@ -35,6 +36,9 @@ namespace reqifviewer.Pages.Index using System.Threading.Tasks; using System.Threading; using System; + using System.Globalization; + + using Utilities; /// /// The code behind for the component @@ -47,6 +51,12 @@ public partial class IndexPage : ComponentBase, IDisposable [Inject] public IReqIFLoaderService ReqIfLoaderService { get; set; } + /// + /// Gets or sets the + /// + [Inject] + public IConfiguration Configuration { get; set; } + /// /// Gets or sets the error message that is displayed in the component /// @@ -68,9 +78,9 @@ public partial class IndexPage : ComponentBase, IDisposable private const string UploadsDirectory = "wwwroot/uploads/"; /// - /// The directory where uploaded files are stored + /// The maximum file size to upload in megabytes /// - private const long MaxFileSizeInBytes = 5 * 1024 * 1024; + private double MaxUploadFileSizeInMb => double.Parse(this.Configuration.GetSection(Constants.MaxUploadFileSizeInMbConfigurationKey).Value!, CultureInfo.InvariantCulture); /// /// Gets or sets the file path @@ -131,9 +141,11 @@ protected override void OnInitialized() /// private async Task HandleSelection(InputFileChangeEventArgs e) { - if (e.File.Size > MaxFileSizeInBytes) + var maxUploadFileSizeInBytes = (long)(this.MaxUploadFileSizeInMb * 1024 * 1024); + + if (e.File.Size > maxUploadFileSizeInBytes) { - this.ErrorMessage = $"The max file size is {MaxFileSizeInBytes/(1024*1024)} MB"; + this.ErrorMessage = $"The max file size is {this.MaxUploadFileSizeInMb} MB"; return; } @@ -152,7 +164,7 @@ private async Task HandleSelection(InputFileChangeEventArgs e) await using (var fileStream = new FileStream(this.ReqIfFilePath, FileMode.Create)) { - await e.File.OpenReadStream(MaxFileSizeInBytes).CopyToAsync(fileStream); + await e.File.OpenReadStream(maxUploadFileSizeInBytes).CopyToAsync(fileStream); } this.reqifisAvailable = true; @@ -212,7 +224,6 @@ private async Task OnCancel() if (this.cancellationTokenSource != null) { await this.cancellationTokenSource.CancelAsync(); - TryDeleteFile(this.ReqIfFilePath); this.IsLoading = false; await this.InvokeAsync(this.StateHasChanged); } diff --git a/reqifviewer/Program.cs b/reqifviewer/Program.cs index c7b6862..b5f7d2f 100644 --- a/reqifviewer/Program.cs +++ b/reqifviewer/Program.cs @@ -74,6 +74,7 @@ public static async Task Main(string[] args) builder.Services.AddScoped(); builder.Services.AddGoogleAnalytics("295704041"); builder.Services.AddBlazorStrap(); + builder.Services.AddHttpClient(); var app = builder.Build(); diff --git a/reqifviewer/Utilities/Constants.cs b/reqifviewer/Utilities/Constants.cs new file mode 100644 index 0000000..a6543ac --- /dev/null +++ b/reqifviewer/Utilities/Constants.cs @@ -0,0 +1,33 @@ +// ------------------------------------------------------------------------------------------------- +// +// +// Copyright 2023-2024 RHEA System S.A. +// +// 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. +// +// +// ------------------------------------------------------------------------------------------------- + +namespace reqifviewer.Utilities +{ + /// + /// Contains constant values that can be shared across the application + /// + public static class Constants + { + /// + /// The name of the configuration key used to retrieve the max upload file size, in megabytes + /// + public const string MaxUploadFileSizeInMbConfigurationKey = "MaxUploadFileSizeInMb"; + } +} diff --git a/reqifviewer/appsettings.Development.json b/reqifviewer/appsettings.Development.json new file mode 100644 index 0000000..b909150 --- /dev/null +++ b/reqifviewer/appsettings.Development.json @@ -0,0 +1,3 @@ +{ + "DetailedErrors": true +} diff --git a/reqifviewer/appsettings.json b/reqifviewer/appsettings.json index bcd33de..7264720 100644 --- a/reqifviewer/appsettings.json +++ b/reqifviewer/appsettings.json @@ -1,4 +1,5 @@ { + "MaxUploadFileSizeInMb": 500, "AllowedHosts": "*", "Serilog": { "Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File" ],