diff --git a/Directory.Packages.props b/Directory.Packages.props index bec7da953..87aaee4ed 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -30,27 +30,27 @@ - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + diff --git a/src/AspNetCore.Testing/LaunchPadExtension.cs b/src/AspNetCore.Testing/LaunchPadExtension.cs index 71d7a7623..32e944f32 100644 --- a/src/AspNetCore.Testing/LaunchPadExtension.cs +++ b/src/AspNetCore.Testing/LaunchPadExtension.cs @@ -89,7 +89,11 @@ public virtual IHostBuilder Configure(IHostBuilder builder) builder.ConfigureRocketSurgery(z => z.ForTesting(_testAssemblyReference, _loggerFactory)); builder.ConfigureLogging((_, loggingBuilder) => loggingBuilder.Services.AddSingleton(_loggerFactory)); builder.ConfigureServices(s => s.AddSingleton(z => (TestServer)z.GetRequiredService())); - builder.ConfigureServices(s => s.AddHttpLogging(options => options.LoggingFields = HttpLoggingFields.All)); + builder.ConfigureServices(s => s.AddHttpLogging( + options => + { + options.LoggingFields = HttpLoggingFields.All; + })); return builder; } diff --git a/src/AspNetCore.Testing/LaunchPadWebAppFixture.cs b/src/AspNetCore.Testing/LaunchPadWebAppFixture.cs index 8a984caed..b32085446 100644 --- a/src/AspNetCore.Testing/LaunchPadWebAppFixture.cs +++ b/src/AspNetCore.Testing/LaunchPadWebAppFixture.cs @@ -114,10 +114,15 @@ protected virtual void Dispose(bool disposing) class AppFixtureLoggerFactory : ILoggerFactory { private ILoggerFactory? _innerLoggerFactory; + private List _deferredLoggers = new(); public void SetLoggerFactory(ILoggerFactory loggerFactory) { _innerLoggerFactory = loggerFactory; + foreach (var logger in _deferredLoggers) + { + logger.SetLogger(loggerFactory.CreateLogger(logger.CategoryName)); + } } public void Dispose() @@ -132,7 +137,60 @@ public void AddProvider(ILoggerProvider provider) public ILogger CreateLogger(string categoryName) { - return _innerLoggerFactory?.CreateLogger(categoryName) ?? NullLogger.Instance; + return _innerLoggerFactory?.CreateLogger(categoryName) ?? AddDeferredLogger(categoryName); + } + + private DeferredLogger AddDeferredLogger(string categoryName) + { + var logger = new DeferredLogger(categoryName); + _deferredLoggers.Add(logger); + return logger; + } + } + + class DeferredLogger : ILogger + { + public string CategoryName { get; } + private List<(LogLevel logLevel, EventId eventId, string text)> _deferredLogs = new(); + private ILogger? _logger; + + public DeferredLogger(string categoryName) + { + CategoryName = categoryName; + } + + public void Log(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func formatter) + { + if (_logger is null) + { + _deferredLogs.Add((logLevel, eventId, formatter(state, exception))); + return; + } + _logger.Log(logLevel, eventId, state, exception, formatter); + } + + public bool IsEnabled(LogLevel logLevel) + { + return _logger?.IsEnabled(logLevel) ?? true; + } + + public IDisposable? BeginScope(TState state) where TState : notnull + { + return _logger?.BeginScope(state); + } + + public void SetLogger(ILogger logger) + { + _logger = logger; + foreach (var log in _deferredLogs) + { +#pragma warning disable CA1848 +#pragma warning disable CA2254 + // ReSharper disable once TemplateIsNotCompileTimeConstantProblem + _logger.Log(log.logLevel, log.eventId, log.text); +#pragma warning restore CA2254 +#pragma warning restore CA1848 + } } } diff --git a/test/Sample.Graphql.Tests/Helpers/GraphQlExtension.cs b/test/Sample.Graphql.Tests/Helpers/GraphQlExtension.cs index f197df64d..618d38762 100644 --- a/test/Sample.Graphql.Tests/Helpers/GraphQlExtension.cs +++ b/test/Sample.Graphql.Tests/Helpers/GraphQlExtension.cs @@ -29,7 +29,6 @@ public Task Start(IAlbaHost host) public IHostBuilder Configure(IHostBuilder builder) { - new TemporaryGraphQlExtension().Configure(builder); builder.ConfigureServices( z => z .AddW3CLogging(_ => { }) diff --git a/test/Sample.Graphql.Tests/Helpers/TemporaryGraphQlExtension.cs b/test/Sample.Graphql.Tests/Helpers/TemporaryGraphQlExtension.cs deleted file mode 100644 index 9d5472e30..000000000 --- a/test/Sample.Graphql.Tests/Helpers/TemporaryGraphQlExtension.cs +++ /dev/null @@ -1,48 +0,0 @@ -using System.Net; -using Alba; -using HotChocolate.AspNetCore.Serialization; -using HotChocolate.Execution; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; - -namespace Sample.Graphql.Tests.Helpers; - -[Obsolete("Remove once https://github.com/ChilliCream/hotchocolate/issues/5684 is fixed!")] -internal class TemporaryGraphQlExtension : IAlbaExtension -{ - public void Dispose() - { - } - - public ValueTask DisposeAsync() - { - return ValueTask.CompletedTask; - } - - public Task Start(IAlbaHost host) - { - return Task.CompletedTask; - } - - public IHostBuilder Configure(IHostBuilder builder) - { - builder.ConfigureServices(z => z.AddHttpResponseFormatter()); - return builder; - } - - [Obsolete("Remove once https://github.com/ChilliCream/hotchocolate/issues/5684 is fixed!")] - internal class MyHttpResponseFormatter() : DefaultHttpResponseFormatter(true) - { - protected override HttpStatusCode OnDetermineStatusCode(IResponseStream responseStream, FormatInfo format, HttpStatusCode? proposedStatusCode) - { - var code = base.OnDetermineStatusCode(responseStream, format, proposedStatusCode); - return code == HttpStatusCode.InternalServerError ? HttpStatusCode.OK : code; - } - - protected override HttpStatusCode OnDetermineStatusCode(IQueryResult result, FormatInfo format, HttpStatusCode? proposedStatusCode) - { - var code = base.OnDetermineStatusCode(result, format, proposedStatusCode); - return code == HttpStatusCode.InternalServerError ? HttpStatusCode.OK : code; - } - } -} diff --git a/test/Sample.Graphql.Tests/snapshots/FoundationTests.GraphqlSchema.verified.graphql b/test/Sample.Graphql.Tests/snapshots/FoundationTests.GraphqlSchema.verified.graphql index 76f3943d3..d2c5a9b67 100644 --- a/test/Sample.Graphql.Tests/snapshots/FoundationTests.GraphqlSchema.verified.graphql +++ b/test/Sample.Graphql.Tests/snapshots/FoundationTests.GraphqlSchema.verified.graphql @@ -530,6 +530,9 @@ enum SortEnumType { "The `@specifiedBy` directive is used within the type system definition language to provide a URL for specifying the behavior of custom scalar definitions." directive @specifiedBy("The specifiedBy URL points to a human-readable specification. This field will only read a result for scalar types." url: String!) on SCALAR +"The @tag directive is used to applies arbitrary string\nmetadata to a schema location. Custom tooling can use\nthis metadata during any step of the schema delivery flow,\nincluding composition, static analysis, and documentation.\n \n\ninterface Book {\n id: ID! @tag(name: \"your-value\")\n title: String!\n author: String!\n}" +directive @tag("The name of the tag." name: String!) repeatable on SCHEMA | SCALAR | OBJECT | FIELD_DEFINITION | ARGUMENT_DEFINITION | INTERFACE | UNION | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION + "A coordinate is an array of positions." scalar Coordinates