// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; using System.Globalization; using System.Linq; using System.Net.Http; using System.Runtime.InteropServices; using System.Threading.Tasks; using System.Web; using BasicTestApp.AuthTest; using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Authorization; using Microsoft.AspNetCore.Components.WebAssembly.Hosting; using Microsoft.AspNetCore.Components.WebAssembly.Http; using Microsoft.AspNetCore.Components.WebAssembly.Services; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; namespace BasicTestApp { public class Program { public static async Task Main(string[] args) { await SimulateErrorsIfNeededForTest(); var builder = WebAssemblyHostBuilder.CreateDefault(args); if (RuntimeInformation.IsOSPlatform(OSPlatform.Create("WEBASSEMBLY"))) { // Needed because the test server runs on a different port than the client app, // and we want to test sending/receiving cookies under this config WebAssemblyHttpMessageHandlerOptions.DefaultCredentials = FetchCredentialsOption.Include; } builder.RootComponents.Add("root"); builder.Services.AddSingleton(new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); builder.Services.AddSingleton(); builder.Services.AddAuthorizationCore(options => { options.AddPolicy("NameMustStartWithB", policy => policy.RequireAssertion(ctx => ctx.User.Identity.Name?.StartsWith("B") ?? false)); }); // Replace the default logger with a custom one that wraps it var originalLoggerDescriptor = builder.Services.Single(d => d.ServiceType == typeof(ILoggerFactory)); builder.Services.AddSingleton(services => { var originalLogger = (ILoggerFactory)Activator.CreateInstance( originalLoggerDescriptor.ImplementationType, new object[] { services }); return new PrependMessageLoggerFactory("Custom logger", originalLogger); }); var host = builder.Build(); ConfigureCulture(host); await host.RunAsync(); } private static void ConfigureCulture(WebAssemblyHost host) { // In the absence of a specified value, we want the culture to be en-US so that the tests for bind can work consistently. var culture = new CultureInfo("en-US"); Uri uri = null; try { uri = new Uri(host.Services.GetService().Uri); } catch (ArgumentException) { // Some of our tests set this application up incorrectly so that querying NavigationManager.Uri throws. } if (uri != null && HttpUtility.ParseQueryString(uri.Query)["culture"] is string cultureName) { culture = new CultureInfo(cultureName); } // CultureInfo.CurrentCulture is async-scoped and will not affect the culture in sibling scopes. // Use CultureInfo.DefaultThreadCurrentCulture instead to modify the application's default scope. CultureInfo.DefaultThreadCurrentCulture = culture; CultureInfo.DefaultThreadCurrentUICulture = culture; } // Supports E2E tests in StartupErrorNotificationTest private static async Task SimulateErrorsIfNeededForTest() { var currentUrl = DefaultWebAssemblyJSRuntime.Instance.Invoke("getCurrentUrl"); if (currentUrl.Contains("error=sync")) { throw new InvalidTimeZoneException("This is a synchronous startup exception"); } await Task.Yield(); if (currentUrl.Contains("error=async")) { throw new InvalidTimeZoneException("This is an asynchronous startup exception"); } } } }