From 946ba2470d6e79c1654d376f4a001cfd7cc1cf79 Mon Sep 17 00:00:00 2001 From: Loic Sharma Date: Sun, 9 Feb 2020 20:22:46 -0800 Subject: [PATCH 1/4] Rename BaGet.Core.Server to BaGet.Hosting; fix namespaces Work --- BaGet.sln | 4 +- global.json | 7 + src/BaGet.Aliyun/AliyunStorageService.cs | 1 - .../Configuration/AliyunStorageOptions.cs | 3 +- .../Extensions/ServiceCollectionExtensions.cs | 4 +- .../Configuration/S3StorageOptions.cs | 2 +- .../Extensions/ServiceCollectionExtensions.cs | 4 +- src/BaGet.Aws/Helpers/AwsIamHelper.cs | 2 +- src/BaGet.Aws/S3StorageService.cs | 1 - ...ns.cs => DependencyInjectionExtensions.cs} | 2 +- .../Extensions/StorageExceptionExtensions.cs | 2 +- src/BaGet.Azure/Storage/BlobStorageService.cs | 1 - src/BaGet.Azure/Table/TablePackageService.cs | 1 - .../Content/DefaultPackageContentService.cs | 2 +- .../Content/IPackageContentService.cs | 2 +- ...ns.cs => DependencyInjectionExtensions.cs} | 2 +- .../GoogleCloudStorageOptions.cs | 2 +- .../Extensions/ServiceCollectionExtensions.cs | 3 +- .../Services/GoogleCloudStorageService.cs | 3 +- .../BaGet.Hosting.csproj} | 0 .../BaGetUrlGenerator.cs | 2 +- .../Configuration/ConfigureCorsOptions.cs | 3 +- .../ConfigureForwardedHeadersOptions.cs | 2 +- .../Controllers/PackageContentController.cs | 4 +- .../Controllers/PackageMetadataController.cs | 2 +- .../Controllers/PackagePublishController.cs | 3 +- .../Controllers/SearchController.cs | 2 +- .../Controllers/ServiceIndexController.cs | 2 +- .../Controllers/SymbolController.cs | 3 +- .../Extensions/HttpRequestExtensions.cs | 2 +- .../IApplicationBuilderExtensions.cs | 2 +- .../IEndpointRouteBuilderExtensions.cs | 2 +- .../Extensions/IHostExtensions.cs | 3 +- .../IServiceCollectionExtensions.cs | 4 +- .../OperationCancelledMiddleware.cs | 2 +- .../Properties/launchSettings.json | 27 ++++ .../Routes.cs | 2 +- src/BaGet/BaGet.csproj | 4 +- .../Extensions/IHostBuilderExtensions.cs | 40 ++---- .../IServiceCollectionExtensions.cs | 28 ++-- src/BaGet/Program.cs | 52 +++----- src/BaGet/Startup.cs | 6 +- tests/BaGet.Tests/ApiIntegrationTests.cs | 39 ++++++ tests/BaGet.Tests/BaGet.Tests.csproj | 17 ++- tests/BaGet.Tests/HostIntegrationTests.cs | 76 +++++++++++ .../BaGet.Tests/NuGetClientIntegrationTest.cs | 96 -------------- .../NuGetClientIntegrationTests.cs | 58 +++++++++ tests/BaGet.Tests/PackageControllerTest.cs | 32 ----- .../ServiceCollectionExtensionsTest.cs | 90 ------------- .../Support/BaGetWebApplicationFactory.cs | 78 +++++++++++ .../HttpSourceResourceProviderTestHost.cs | 13 +- .../BaGet.Tests/Support/HttpSourceTestHost.cs | 43 ------ .../BaGet.Tests/Support/TestableHttpSource.cs | 55 ++++++++ tests/BaGet.Tests/Support/XunitLogger.cs | 40 ++++++ .../Support/XunitLoggerProvider.cs | 22 ++++ tests/BaGet.Tests/TestData.Designer.cs | 72 ++++++++++ tests/BaGet.Tests/TestData.resx | 123 ++++++++++++++++++ tests/BaGet.Tests/TestServerBuilder.cs | 121 ----------------- tests/BaGet.Tests/XunitLogger.cs | 45 ------- tests/BaGet.Tests/XunitLoggerProvider.cs | 23 ---- 60 files changed, 692 insertions(+), 596 deletions(-) create mode 100644 global.json rename src/BaGet.Azure/Extensions/{IServiceCollectionExtensions.cs => DependencyInjectionExtensions.cs} (98%) rename src/BaGet.Core/Extensions/{ServiceCollectionExtensions.cs => DependencyInjectionExtensions.cs} (91%) rename src/{BaGet.Core.Server/BaGet.Core.Server.csproj => BaGet.Hosting/BaGet.Hosting.csproj} (100%) rename src/{BaGet.Core.Server => BaGet.Hosting}/BaGetUrlGenerator.cs (99%) rename src/{BaGet.Core.Server => BaGet.Hosting}/Configuration/ConfigureCorsOptions.cs (84%) rename src/{BaGet.Core.Server => BaGet.Hosting}/Configuration/ConfigureForwardedHeadersOptions.cs (94%) rename src/{BaGet.Core.Server => BaGet.Hosting}/Controllers/PackageContentController.cs (98%) rename src/{BaGet.Core.Server => BaGet.Hosting}/Controllers/PackageMetadataController.cs (98%) rename src/{BaGet.Core.Server => BaGet.Hosting}/Controllers/PackagePublishController.cs (98%) rename src/{BaGet.Core.Server => BaGet.Hosting}/Controllers/SearchController.cs (98%) rename src/{BaGet.Core.Server => BaGet.Hosting}/Controllers/ServiceIndexController.cs (96%) rename src/{BaGet.Core.Server => BaGet.Hosting}/Controllers/SymbolController.cs (98%) rename src/{BaGet.Core.Server => BaGet.Hosting}/Extensions/HttpRequestExtensions.cs (98%) rename src/{BaGet.Core.Server => BaGet.Hosting}/Extensions/IApplicationBuilderExtensions.cs (90%) rename src/{BaGet.Core.Server => BaGet.Hosting}/Extensions/IEndpointRouteBuilderExtensions.cs (99%) rename src/{BaGet.Core.Server => BaGet.Hosting}/Extensions/IHostExtensions.cs (93%) rename src/{BaGet.Core.Server => BaGet.Hosting}/Extensions/IServiceCollectionExtensions.cs (93%) rename src/{BaGet.Core.Server => BaGet.Hosting}/OperationCancelledMiddleware.cs (98%) create mode 100644 src/BaGet.Hosting/Properties/launchSettings.json rename src/{BaGet.Core.Server => BaGet.Hosting}/Routes.cs (98%) create mode 100644 tests/BaGet.Tests/ApiIntegrationTests.cs create mode 100644 tests/BaGet.Tests/HostIntegrationTests.cs delete mode 100644 tests/BaGet.Tests/NuGetClientIntegrationTest.cs create mode 100644 tests/BaGet.Tests/NuGetClientIntegrationTests.cs delete mode 100644 tests/BaGet.Tests/PackageControllerTest.cs delete mode 100644 tests/BaGet.Tests/ServiceCollectionExtensionsTest.cs create mode 100644 tests/BaGet.Tests/Support/BaGetWebApplicationFactory.cs delete mode 100644 tests/BaGet.Tests/Support/HttpSourceTestHost.cs create mode 100644 tests/BaGet.Tests/Support/TestableHttpSource.cs create mode 100644 tests/BaGet.Tests/Support/XunitLogger.cs create mode 100644 tests/BaGet.Tests/Support/XunitLoggerProvider.cs create mode 100644 tests/BaGet.Tests/TestData.Designer.cs create mode 100644 tests/BaGet.Tests/TestData.resx delete mode 100644 tests/BaGet.Tests/TestServerBuilder.cs delete mode 100644 tests/BaGet.Tests/XunitLogger.cs delete mode 100644 tests/BaGet.Tests/XunitLoggerProvider.cs diff --git a/BaGet.sln b/BaGet.sln index 5f63e2668..6f41ed22d 100644 --- a/BaGet.sln +++ b/BaGet.sln @@ -30,7 +30,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution nuget.config = nuget.config EndProjectSection EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BaGet.Core.Server", "src\BaGet.Core.Server\BaGet.Core.Server.csproj", "{D68B56AC-98DD-4DA7-B4F8-1243538A8A5C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BaGet.Hosting", "src\BaGet.Hosting\BaGet.Hosting.csproj", "{D68B56AC-98DD-4DA7-B4F8-1243538A8A5C}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BaGet.Database.Sqlite", "src\BaGet.Database.Sqlite\BaGet.Database.Sqlite.csproj", "{EC5E6B2C-2494-40E8-8682-080BA580DDA7}" EndProject @@ -46,7 +46,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{DDEC EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BaGet.Protocol.Samples.Tests", "samples\BaGet.Protocol.Samples.Tests.csproj", "{16B0D424-BB2F-4C0C-90B0-4F7955326ADF}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BaGet.Aliyun", "src\BaGet.Aliyun\BaGet.Aliyun.csproj", "{9F7C4F38-D598-42D9-A9F8-962490483B18}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BaGet.Aliyun", "src\BaGet.Aliyun\BaGet.Aliyun.csproj", "{9F7C4F38-D598-42D9-A9F8-962490483B18}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/global.json b/global.json new file mode 100644 index 000000000..9cf054ff3 --- /dev/null +++ b/global.json @@ -0,0 +1,7 @@ +{ + "sdk": { + // "version": "2.2.402" + // "version": "3.0.102" + "version": "3.1.101" + } +} diff --git a/src/BaGet.Aliyun/AliyunStorageService.cs b/src/BaGet.Aliyun/AliyunStorageService.cs index 8e2b05f7d..9ea3e6353 100644 --- a/src/BaGet.Aliyun/AliyunStorageService.cs +++ b/src/BaGet.Aliyun/AliyunStorageService.cs @@ -3,7 +3,6 @@ using System.Threading; using System.Threading.Tasks; using Aliyun.OSS; -using BaGet.Aliyun.Configuration; using BaGet.Core; using Microsoft.Extensions.Options; diff --git a/src/BaGet.Aliyun/Configuration/AliyunStorageOptions.cs b/src/BaGet.Aliyun/Configuration/AliyunStorageOptions.cs index 74c4b18ce..2357bdd61 100644 --- a/src/BaGet.Aliyun/Configuration/AliyunStorageOptions.cs +++ b/src/BaGet.Aliyun/Configuration/AliyunStorageOptions.cs @@ -1,7 +1,6 @@ using System.ComponentModel.DataAnnotations; -using BaGet.Core; -namespace BaGet.Aliyun.Configuration +namespace BaGet.Aliyun { public class AliyunStorageOptions { diff --git a/src/BaGet.Aliyun/Extensions/ServiceCollectionExtensions.cs b/src/BaGet.Aliyun/Extensions/ServiceCollectionExtensions.cs index f14de4557..4bee05cd9 100644 --- a/src/BaGet.Aliyun/Extensions/ServiceCollectionExtensions.cs +++ b/src/BaGet.Aliyun/Extensions/ServiceCollectionExtensions.cs @@ -1,10 +1,8 @@ -using System; using Aliyun.OSS; -using BaGet.Aliyun.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; -namespace BaGet.Aliyun.Extensions +namespace BaGet.Aliyun { public static class ServiceCollectionExtensions { diff --git a/src/BaGet.Aws/Configuration/S3StorageOptions.cs b/src/BaGet.Aws/Configuration/S3StorageOptions.cs index fa2eb1b24..025340d20 100644 --- a/src/BaGet.Aws/Configuration/S3StorageOptions.cs +++ b/src/BaGet.Aws/Configuration/S3StorageOptions.cs @@ -1,7 +1,7 @@ using System.ComponentModel.DataAnnotations; using BaGet.Core; -namespace BaGet.Aws.Configuration +namespace BaGet.Aws { public class S3StorageOptions { diff --git a/src/BaGet.Aws/Extensions/ServiceCollectionExtensions.cs b/src/BaGet.Aws/Extensions/ServiceCollectionExtensions.cs index ef619e69b..d447eb681 100644 --- a/src/BaGet.Aws/Extensions/ServiceCollectionExtensions.cs +++ b/src/BaGet.Aws/Extensions/ServiceCollectionExtensions.cs @@ -2,12 +2,10 @@ using Amazon; using Amazon.Runtime; using Amazon.S3; -using BaGet.Aws.Configuration; -using BaGet.Aws.Helpers; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; -namespace BaGet.Aws.Extensions +namespace BaGet.Aws { public static class ServiceCollectionExtensions { diff --git a/src/BaGet.Aws/Helpers/AwsIamHelper.cs b/src/BaGet.Aws/Helpers/AwsIamHelper.cs index 3297deed6..66a08de3b 100644 --- a/src/BaGet.Aws/Helpers/AwsIamHelper.cs +++ b/src/BaGet.Aws/Helpers/AwsIamHelper.cs @@ -2,7 +2,7 @@ using System.Threading.Tasks; using Amazon.Runtime; -namespace BaGet.Aws.Helpers +namespace BaGet.Aws { public static class AwsIamHelper { diff --git a/src/BaGet.Aws/S3StorageService.cs b/src/BaGet.Aws/S3StorageService.cs index c95e1bbbe..bee08c5f0 100644 --- a/src/BaGet.Aws/S3StorageService.cs +++ b/src/BaGet.Aws/S3StorageService.cs @@ -4,7 +4,6 @@ using System.Threading.Tasks; using Amazon.S3; using Amazon.S3.Model; -using BaGet.Aws.Configuration; using BaGet.Core; using Microsoft.Extensions.Options; diff --git a/src/BaGet.Azure/Extensions/IServiceCollectionExtensions.cs b/src/BaGet.Azure/Extensions/DependencyInjectionExtensions.cs similarity index 98% rename from src/BaGet.Azure/Extensions/IServiceCollectionExtensions.cs rename to src/BaGet.Azure/Extensions/DependencyInjectionExtensions.cs index b5c90670a..b4bf153b9 100644 --- a/src/BaGet.Azure/Extensions/IServiceCollectionExtensions.cs +++ b/src/BaGet.Azure/Extensions/DependencyInjectionExtensions.cs @@ -12,7 +12,7 @@ namespace BaGet.Azure using TableStorageAccount = Microsoft.Azure.Cosmos.Table.CloudStorageAccount; - public static class IServiceCollectionExtensions + public static class DependencyInjectionExtensions { public static IServiceCollection AddTableStorageService(this IServiceCollection services) { diff --git a/src/BaGet.Azure/Extensions/StorageExceptionExtensions.cs b/src/BaGet.Azure/Extensions/StorageExceptionExtensions.cs index be637c177..a7f50c131 100644 --- a/src/BaGet.Azure/Extensions/StorageExceptionExtensions.cs +++ b/src/BaGet.Azure/Extensions/StorageExceptionExtensions.cs @@ -1,6 +1,6 @@ using System.Net; -namespace BaGet.Azure.Extensions +namespace BaGet.Azure { using StorageException = Microsoft.WindowsAzure.Storage.StorageException; using TableStorageException = Microsoft.Azure.Cosmos.Table.StorageException; diff --git a/src/BaGet.Azure/Storage/BlobStorageService.cs b/src/BaGet.Azure/Storage/BlobStorageService.cs index deccc5c72..fe07efb38 100644 --- a/src/BaGet.Azure/Storage/BlobStorageService.cs +++ b/src/BaGet.Azure/Storage/BlobStorageService.cs @@ -2,7 +2,6 @@ using System.IO; using System.Threading; using System.Threading.Tasks; -using BaGet.Azure.Extensions; using BaGet.Core; using Microsoft.WindowsAzure.Storage; using Microsoft.WindowsAzure.Storage.Blob; diff --git a/src/BaGet.Azure/Table/TablePackageService.cs b/src/BaGet.Azure/Table/TablePackageService.cs index 9af6bab12..40c68c287 100644 --- a/src/BaGet.Azure/Table/TablePackageService.cs +++ b/src/BaGet.Azure/Table/TablePackageService.cs @@ -3,7 +3,6 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; -using BaGet.Azure.Extensions; using BaGet.Core; using Microsoft.Azure.Cosmos.Table; using Microsoft.Extensions.Logging; diff --git a/src/BaGet.Core/Content/DefaultPackageContentService.cs b/src/BaGet.Core/Content/DefaultPackageContentService.cs index 011714b78..e3c6e9582 100644 --- a/src/BaGet.Core/Content/DefaultPackageContentService.cs +++ b/src/BaGet.Core/Content/DefaultPackageContentService.cs @@ -6,7 +6,7 @@ using BaGet.Protocol.Models; using NuGet.Versioning; -namespace BaGet.Core.Content +namespace BaGet.Core { /// /// Implements the NuGet Package Content resource. Supports read-through caching. diff --git a/src/BaGet.Core/Content/IPackageContentService.cs b/src/BaGet.Core/Content/IPackageContentService.cs index 331c62e51..31abcafdd 100644 --- a/src/BaGet.Core/Content/IPackageContentService.cs +++ b/src/BaGet.Core/Content/IPackageContentService.cs @@ -4,7 +4,7 @@ using BaGet.Protocol.Models; using NuGet.Versioning; -namespace BaGet.Core.Content +namespace BaGet.Core { /// /// The Package Content resource, used to download NuGet packages and to fetch other metadata. diff --git a/src/BaGet.Core/Extensions/ServiceCollectionExtensions.cs b/src/BaGet.Core/Extensions/DependencyInjectionExtensions.cs similarity index 91% rename from src/BaGet.Core/Extensions/ServiceCollectionExtensions.cs rename to src/BaGet.Core/Extensions/DependencyInjectionExtensions.cs index 25a077a97..c5bd7bf1c 100644 --- a/src/BaGet.Core/Extensions/ServiceCollectionExtensions.cs +++ b/src/BaGet.Core/Extensions/DependencyInjectionExtensions.cs @@ -4,7 +4,7 @@ namespace BaGet.Core { - public static class ServiceCollectionExtensions + public static class DependencyInjectionExtensions { public static IServiceCollection ConfigureAndValidate( this IServiceCollection services, diff --git a/src/BaGet.Gcp/Configuration/GoogleCloudStorageOptions.cs b/src/BaGet.Gcp/Configuration/GoogleCloudStorageOptions.cs index 3aa4ab220..6b9a2ff42 100644 --- a/src/BaGet.Gcp/Configuration/GoogleCloudStorageOptions.cs +++ b/src/BaGet.Gcp/Configuration/GoogleCloudStorageOptions.cs @@ -1,7 +1,7 @@ using System.ComponentModel.DataAnnotations; using BaGet.Core; -namespace BaGet.Gcp.Configuration +namespace BaGet.Gcp { public class GoogleCloudStorageOptions : StorageOptions { diff --git a/src/BaGet.Gcp/Extensions/ServiceCollectionExtensions.cs b/src/BaGet.Gcp/Extensions/ServiceCollectionExtensions.cs index 87b972847..3e736af58 100644 --- a/src/BaGet.Gcp/Extensions/ServiceCollectionExtensions.cs +++ b/src/BaGet.Gcp/Extensions/ServiceCollectionExtensions.cs @@ -1,7 +1,6 @@ -using BaGet.Gcp.Services; using Microsoft.Extensions.DependencyInjection; -namespace BaGet.Gcp.Extensions +namespace BaGet.Gcp { public static class ServiceCollectionExtensions { diff --git a/src/BaGet.Gcp/Services/GoogleCloudStorageService.cs b/src/BaGet.Gcp/Services/GoogleCloudStorageService.cs index b0c318508..6a01f4064 100644 --- a/src/BaGet.Gcp/Services/GoogleCloudStorageService.cs +++ b/src/BaGet.Gcp/Services/GoogleCloudStorageService.cs @@ -6,12 +6,11 @@ using System.Threading; using System.Threading.Tasks; using BaGet.Core; -using BaGet.Gcp.Configuration; using Google; using Google.Cloud.Storage.V1; using Microsoft.Extensions.Options; -namespace BaGet.Gcp.Services +namespace BaGet.Gcp { public class GoogleCloudStorageService : IStorageService { diff --git a/src/BaGet.Core.Server/BaGet.Core.Server.csproj b/src/BaGet.Hosting/BaGet.Hosting.csproj similarity index 100% rename from src/BaGet.Core.Server/BaGet.Core.Server.csproj rename to src/BaGet.Hosting/BaGet.Hosting.csproj diff --git a/src/BaGet.Core.Server/BaGetUrlGenerator.cs b/src/BaGet.Hosting/BaGetUrlGenerator.cs similarity index 99% rename from src/BaGet.Core.Server/BaGetUrlGenerator.cs rename to src/BaGet.Hosting/BaGetUrlGenerator.cs index bfcc399ea..3b67663d5 100644 --- a/src/BaGet.Core.Server/BaGetUrlGenerator.cs +++ b/src/BaGet.Hosting/BaGetUrlGenerator.cs @@ -4,7 +4,7 @@ using Microsoft.AspNetCore.Routing; using NuGet.Versioning; -namespace BaGet +namespace BaGet.Hosting { // TODO: This should validate the "Host" header against known valid values public class BaGetUrlGenerator : IUrlGenerator diff --git a/src/BaGet.Core.Server/Configuration/ConfigureCorsOptions.cs b/src/BaGet.Hosting/Configuration/ConfigureCorsOptions.cs similarity index 84% rename from src/BaGet.Core.Server/Configuration/ConfigureCorsOptions.cs rename to src/BaGet.Hosting/Configuration/ConfigureCorsOptions.cs index fb7d57b07..8d515385a 100644 --- a/src/BaGet.Core.Server/Configuration/ConfigureCorsOptions.cs +++ b/src/BaGet.Hosting/Configuration/ConfigureCorsOptions.cs @@ -1,7 +1,7 @@ using Microsoft.AspNetCore.Cors.Infrastructure; using Microsoft.Extensions.Options; -namespace BaGet.Configuration +namespace BaGet.Hosting { public class ConfigureCorsOptions : IConfigureOptions { @@ -9,6 +9,7 @@ public class ConfigureCorsOptions : IConfigureOptions public void Configure(CorsOptions options) { + // TODO: Consider disabling this on production builds. options.AddPolicy( CorsPolicy, builder => builder.AllowAnyOrigin() diff --git a/src/BaGet.Core.Server/Configuration/ConfigureForwardedHeadersOptions.cs b/src/BaGet.Hosting/Configuration/ConfigureForwardedHeadersOptions.cs similarity index 94% rename from src/BaGet.Core.Server/Configuration/ConfigureForwardedHeadersOptions.cs rename to src/BaGet.Hosting/Configuration/ConfigureForwardedHeadersOptions.cs index 8a962fff1..939af8ed6 100644 --- a/src/BaGet.Core.Server/Configuration/ConfigureForwardedHeadersOptions.cs +++ b/src/BaGet.Hosting/Configuration/ConfigureForwardedHeadersOptions.cs @@ -2,7 +2,7 @@ using Microsoft.AspNetCore.HttpOverrides; using Microsoft.Extensions.Options; -namespace BaGet.Configuration +namespace BaGet.Hosting { public class ConfigureForwardedHeadersOptions : IConfigureOptions { diff --git a/src/BaGet.Core.Server/Controllers/PackageContentController.cs b/src/BaGet.Hosting/Controllers/PackageContentController.cs similarity index 98% rename from src/BaGet.Core.Server/Controllers/PackageContentController.cs rename to src/BaGet.Hosting/Controllers/PackageContentController.cs index 5ce4f5c34..749d00450 100644 --- a/src/BaGet.Core.Server/Controllers/PackageContentController.cs +++ b/src/BaGet.Hosting/Controllers/PackageContentController.cs @@ -1,12 +1,12 @@ using System; using System.Threading; using System.Threading.Tasks; -using BaGet.Core.Content; +using BaGet.Core; using BaGet.Protocol.Models; using Microsoft.AspNetCore.Mvc; using NuGet.Versioning; -namespace BaGet.Controllers +namespace BaGet.Hosting { /// /// The Package Content resource, used to download content from packages. diff --git a/src/BaGet.Core.Server/Controllers/PackageMetadataController.cs b/src/BaGet.Hosting/Controllers/PackageMetadataController.cs similarity index 98% rename from src/BaGet.Core.Server/Controllers/PackageMetadataController.cs rename to src/BaGet.Hosting/Controllers/PackageMetadataController.cs index 87c3ac65f..ded05cbef 100644 --- a/src/BaGet.Core.Server/Controllers/PackageMetadataController.cs +++ b/src/BaGet.Hosting/Controllers/PackageMetadataController.cs @@ -6,7 +6,7 @@ using Microsoft.AspNetCore.Mvc; using NuGet.Versioning; -namespace BaGet.Controllers +namespace BaGet.Hosting { /// /// The Package Metadata resource, used to fetch packages' information. diff --git a/src/BaGet.Core.Server/Controllers/PackagePublishController.cs b/src/BaGet.Hosting/Controllers/PackagePublishController.cs similarity index 98% rename from src/BaGet.Core.Server/Controllers/PackagePublishController.cs rename to src/BaGet.Hosting/Controllers/PackagePublishController.cs index be8850ce5..c81ac2490 100644 --- a/src/BaGet.Core.Server/Controllers/PackagePublishController.cs +++ b/src/BaGet.Hosting/Controllers/PackagePublishController.cs @@ -2,13 +2,12 @@ using System.Threading; using System.Threading.Tasks; using BaGet.Core; -using BaGet.Extensions; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using NuGet.Versioning; -namespace BaGet.Controllers +namespace BaGet.Hosting { public class PackagePublishController : Controller { diff --git a/src/BaGet.Core.Server/Controllers/SearchController.cs b/src/BaGet.Hosting/Controllers/SearchController.cs similarity index 98% rename from src/BaGet.Core.Server/Controllers/SearchController.cs rename to src/BaGet.Hosting/Controllers/SearchController.cs index 5b8db0903..0bb6ed8e2 100644 --- a/src/BaGet.Core.Server/Controllers/SearchController.cs +++ b/src/BaGet.Hosting/Controllers/SearchController.cs @@ -5,7 +5,7 @@ using BaGet.Protocol.Models; using Microsoft.AspNetCore.Mvc; -namespace BaGet.Controllers +namespace BaGet.Hosting { public class SearchController : Controller { diff --git a/src/BaGet.Core.Server/Controllers/ServiceIndexController.cs b/src/BaGet.Hosting/Controllers/ServiceIndexController.cs similarity index 96% rename from src/BaGet.Core.Server/Controllers/ServiceIndexController.cs rename to src/BaGet.Hosting/Controllers/ServiceIndexController.cs index 5101e91b2..707af2c6a 100644 --- a/src/BaGet.Core.Server/Controllers/ServiceIndexController.cs +++ b/src/BaGet.Hosting/Controllers/ServiceIndexController.cs @@ -5,7 +5,7 @@ using BaGet.Protocol.Models; using Microsoft.AspNetCore.Mvc; -namespace BaGet.Controllers +namespace BaGet.Hosting { /// /// The NuGet Service Index. This aids NuGet client to discover this server's services. diff --git a/src/BaGet.Core.Server/Controllers/SymbolController.cs b/src/BaGet.Hosting/Controllers/SymbolController.cs similarity index 98% rename from src/BaGet.Core.Server/Controllers/SymbolController.cs rename to src/BaGet.Hosting/Controllers/SymbolController.cs index 6a22b176e..3376e53d9 100644 --- a/src/BaGet.Core.Server/Controllers/SymbolController.cs +++ b/src/BaGet.Hosting/Controllers/SymbolController.cs @@ -2,12 +2,11 @@ using System.Threading; using System.Threading.Tasks; using BaGet.Core; -using BaGet.Extensions; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; -namespace BaGet.Controllers +namespace BaGet.Hosting { public class SymbolController : Controller { diff --git a/src/BaGet.Core.Server/Extensions/HttpRequestExtensions.cs b/src/BaGet.Hosting/Extensions/HttpRequestExtensions.cs similarity index 98% rename from src/BaGet.Core.Server/Extensions/HttpRequestExtensions.cs rename to src/BaGet.Hosting/Extensions/HttpRequestExtensions.cs index efb02d876..79a169b31 100644 --- a/src/BaGet.Core.Server/Extensions/HttpRequestExtensions.cs +++ b/src/BaGet.Hosting/Extensions/HttpRequestExtensions.cs @@ -4,7 +4,7 @@ using BaGet.Core; using Microsoft.AspNetCore.Http; -namespace BaGet.Extensions +namespace BaGet.Hosting { public static class HttpRequestExtensions { diff --git a/src/BaGet.Core.Server/Extensions/IApplicationBuilderExtensions.cs b/src/BaGet.Hosting/Extensions/IApplicationBuilderExtensions.cs similarity index 90% rename from src/BaGet.Core.Server/Extensions/IApplicationBuilderExtensions.cs rename to src/BaGet.Hosting/Extensions/IApplicationBuilderExtensions.cs index b66483780..cf6fc7904 100644 --- a/src/BaGet.Core.Server/Extensions/IApplicationBuilderExtensions.cs +++ b/src/BaGet.Hosting/Extensions/IApplicationBuilderExtensions.cs @@ -1,7 +1,7 @@ using System; using Microsoft.AspNetCore.Builder; -namespace BaGet.Core.Server.Extensions +namespace BaGet.Hosting { public static class IApplicationBuilderExtensions { diff --git a/src/BaGet.Core.Server/Extensions/IEndpointRouteBuilderExtensions.cs b/src/BaGet.Hosting/Extensions/IEndpointRouteBuilderExtensions.cs similarity index 99% rename from src/BaGet.Core.Server/Extensions/IEndpointRouteBuilderExtensions.cs rename to src/BaGet.Hosting/Extensions/IEndpointRouteBuilderExtensions.cs index e8c7dcd7c..e2334d179 100644 --- a/src/BaGet.Core.Server/Extensions/IEndpointRouteBuilderExtensions.cs +++ b/src/BaGet.Hosting/Extensions/IEndpointRouteBuilderExtensions.cs @@ -2,7 +2,7 @@ using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Routing.Constraints; -namespace BaGet.Extensions +namespace BaGet.Hosting { public static class IEndpointRouteBuilderExtensions { diff --git a/src/BaGet.Core.Server/Extensions/IHostExtensions.cs b/src/BaGet.Hosting/Extensions/IHostExtensions.cs similarity index 93% rename from src/BaGet.Core.Server/Extensions/IHostExtensions.cs rename to src/BaGet.Hosting/Extensions/IHostExtensions.cs index 5aed4dfde..ce730c489 100644 --- a/src/BaGet.Core.Server/Extensions/IHostExtensions.cs +++ b/src/BaGet.Hosting/Extensions/IHostExtensions.cs @@ -1,12 +1,11 @@ using System.Threading; using System.Threading.Tasks; using BaGet.Core; -using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Options; -namespace BaGet.Extensions +namespace BaGet.Hosting { public static class IHostExtensions { diff --git a/src/BaGet.Core.Server/Extensions/IServiceCollectionExtensions.cs b/src/BaGet.Hosting/Extensions/IServiceCollectionExtensions.cs similarity index 93% rename from src/BaGet.Core.Server/Extensions/IServiceCollectionExtensions.cs rename to src/BaGet.Hosting/Extensions/IServiceCollectionExtensions.cs index eacef94a0..ab8aeca68 100644 --- a/src/BaGet.Core.Server/Extensions/IServiceCollectionExtensions.cs +++ b/src/BaGet.Hosting/Extensions/IServiceCollectionExtensions.cs @@ -1,5 +1,3 @@ -using BaGet.Configuration; -using BaGet.Controllers; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Cors.Infrastructure; using Microsoft.AspNetCore.Http.Features; @@ -8,7 +6,7 @@ using Microsoft.Extensions.Options; using Newtonsoft.Json; -namespace BaGet.Core.Server.Extensions +namespace BaGet.Hosting { public static class IServiceCollectionExtensions { diff --git a/src/BaGet.Core.Server/OperationCancelledMiddleware.cs b/src/BaGet.Hosting/OperationCancelledMiddleware.cs similarity index 98% rename from src/BaGet.Core.Server/OperationCancelledMiddleware.cs rename to src/BaGet.Hosting/OperationCancelledMiddleware.cs index a2ead6587..8827ad88c 100644 --- a/src/BaGet.Core.Server/OperationCancelledMiddleware.cs +++ b/src/BaGet.Hosting/OperationCancelledMiddleware.cs @@ -4,7 +4,7 @@ using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; -namespace BaGet +namespace BaGet.Hosting { /// /// Captures and converts to HTTP 409 response. diff --git a/src/BaGet.Hosting/Properties/launchSettings.json b/src/BaGet.Hosting/Properties/launchSettings.json new file mode 100644 index 000000000..903a77a8a --- /dev/null +++ b/src/BaGet.Hosting/Properties/launchSettings.json @@ -0,0 +1,27 @@ +{ + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:62088/", + "sslPort": 44302 + } + }, + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "BaGet.Core.Server": { + "commandName": "Project", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "applicationUrl": "https://localhost:5001;http://localhost:5000" + } + } +} \ No newline at end of file diff --git a/src/BaGet.Core.Server/Routes.cs b/src/BaGet.Hosting/Routes.cs similarity index 98% rename from src/BaGet.Core.Server/Routes.cs rename to src/BaGet.Hosting/Routes.cs index 43062898d..1cc58b3ca 100644 --- a/src/BaGet.Core.Server/Routes.cs +++ b/src/BaGet.Hosting/Routes.cs @@ -1,4 +1,4 @@ -namespace BaGet +namespace BaGet.Hosting { public class Routes { diff --git a/src/BaGet/BaGet.csproj b/src/BaGet/BaGet.csproj index c7fee2183..7c2800d69 100644 --- a/src/BaGet/BaGet.csproj +++ b/src/BaGet/BaGet.csproj @@ -1,4 +1,4 @@ - + netcoreapp3.1 @@ -18,12 +18,12 @@ - + diff --git a/src/BaGet/Extensions/IHostBuilderExtensions.cs b/src/BaGet/Extensions/IHostBuilderExtensions.cs index a6dea2f38..28f9a9339 100644 --- a/src/BaGet/Extensions/IHostBuilderExtensions.cs +++ b/src/BaGet/Extensions/IHostBuilderExtensions.cs @@ -1,44 +1,30 @@ using System; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.Logging; -namespace BaGet.Extensions +namespace BaGet { - // See https://github.com/aspnet/MetaPackages/blob/master/src/Microsoft.AspNetCore/WebHost.cs + // TODO: Move this to BaGet.Hosting. public static class IHostBuilderExtensions { - public static IHostBuilder ConfigureBaGetConfiguration(this IHostBuilder builder, string[] args) + public static IHostBuilder UseBaGet(this IHostBuilder host) { - return builder.ConfigureAppConfiguration((context, config) => + host.ConfigureServices((context, services) => { - config - .SetBasePath(Environment.CurrentDirectory) - .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) - .AddEnvironmentVariables(); + services.AddBaGet(context.Configuration); + }); + + host.ConfigureAppConfiguration((context, config) => + { + var root = Environment.GetEnvironmentVariable("BAGET_CONFIG_ROOT"); - if (args != null) + if (!string.IsNullOrEmpty(root)) { - config.AddCommandLine(args); + config.SetBasePath(root); } }); - } - public static IHostBuilder ConfigureBaGetLogging(this IHostBuilder builder) - { - return builder - .ConfigureLogging((context, logging) => - { - logging.AddConfiguration(context.Configuration.GetSection("Logging")); - logging.AddConsole(); - logging.AddDebug(); - }); - } - - public static IHostBuilder ConfigureBaGetServices(this IHostBuilder builder) - { - return builder - .ConfigureServices((context, services) => services.ConfigureBaGet(context.Configuration)); + return host; } } } diff --git a/src/BaGet/Extensions/IServiceCollectionExtensions.cs b/src/BaGet/Extensions/IServiceCollectionExtensions.cs index 3aea409bb..0ef561421 100644 --- a/src/BaGet/Extensions/IServiceCollectionExtensions.cs +++ b/src/BaGet/Extensions/IServiceCollectionExtensions.cs @@ -3,22 +3,15 @@ using System.Net.Http; using System.Reflection; using BaGet.Aliyun; -using BaGet.Aliyun.Configuration; -using BaGet.Aliyun.Extensions; using BaGet.Aws; -using BaGet.Aws.Configuration; -using BaGet.Aws.Extensions; using BaGet.Azure; using BaGet.Core; -using BaGet.Core.Content; -using BaGet.Core.Server.Extensions; using BaGet.Database.MySql; using BaGet.Database.PostgreSql; using BaGet.Database.Sqlite; using BaGet.Database.SqlServer; -using BaGet.Gcp.Configuration; -using BaGet.Gcp.Extensions; -using BaGet.Gcp.Services; +using BaGet.Gcp; +using BaGet.Hosting; using BaGet.Protocol; using Microsoft.AspNetCore.Builder; using Microsoft.EntityFrameworkCore; @@ -26,14 +19,14 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; -namespace BaGet.Extensions +namespace BaGet { + // TODO: Move this to BaGet.Core public static class IServiceCollectionExtensions { - public static IServiceCollection ConfigureBaGet( + public static IServiceCollection AddBaGet( this IServiceCollection services, - IConfiguration configuration, - bool httpServices = false) + IConfiguration configuration) { services.ConfigureAndValidate(configuration); services.ConfigureAndValidate(configuration.GetSection(nameof(BaGetOptions.Search))); @@ -41,6 +34,8 @@ public static IServiceCollection ConfigureBaGet( services.ConfigureAndValidate(configuration.GetSection(nameof(BaGetOptions.Storage))); services.ConfigureAndValidate(configuration.GetSection(nameof(BaGetOptions.Database))); services.ConfigureAndValidate(configuration.GetSection(nameof(BaGetOptions.Storage))); + + // Add options for different providers services.ConfigureAndValidate(configuration.GetSection(nameof(BaGetOptions.Storage))); services.ConfigureAndValidate(configuration.GetSection(nameof(BaGetOptions.Search))); @@ -50,11 +45,6 @@ public static IServiceCollection ConfigureBaGet( services.ConfigureAliyunOSS(configuration); services.ConfigureIis(configuration); - if (httpServices) - { - services.ConfigureHttpServices(); - } - services.AddBaGetContext(); services.AddTransient(); @@ -193,7 +183,7 @@ public static IServiceCollection ConfigureGcp( return services; } - + public static IServiceCollection ConfigureIis( this IServiceCollection services, IConfiguration configuration) diff --git a/src/BaGet/Program.cs b/src/BaGet/Program.cs index e74483abc..1d2f16a80 100644 --- a/src/BaGet/Program.cs +++ b/src/BaGet/Program.cs @@ -1,15 +1,10 @@ -using System; -using System.Threading; using System.Threading.Tasks; using BaGet.Core; -using BaGet.Extensions; +using BaGet.Hosting; using McMaster.Extensions.CommandLineUtils; using Microsoft.AspNetCore.Hosting; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.Options; namespace BaGet { @@ -31,11 +26,10 @@ public static async Task Main(string[] args) { downloads.OnExecuteAsync(async cancellationToken => { - var provider = CreateHostBuilder(args).Build().Services; + var host = CreateHostBuilder(args).Build(); + var importer = host.Services.GetRequiredService(); - await provider - .GetRequiredService() - .ImportAsync(cancellationToken); + await importer.ImportAsync(cancellationToken); }); }); }); @@ -52,35 +46,21 @@ await provider } public static IHostBuilder CreateWebHostBuilder(string[] args) => - Host.CreateDefaultBuilder(args) - .ConfigureWebHostDefaults(webBuilder => - { - webBuilder - .ConfigureKestrel(options => - { - // Remove the upload limit from Kestrel. If needed, an upload limit can - // be enforced by a reverse proxy server, like IIS. - options.Limits.MaxRequestBodySize = null; - }) - .UseStartup(); - }) - .ConfigureAppConfiguration((builderContext, config) => + CreateHostBuilder(args) + .ConfigureWebHostDefaults(web => { - var root = Environment.GetEnvironmentVariable("BAGET_CONFIG_ROOT"); - if (!string.IsNullOrEmpty(root)) + web.ConfigureKestrel(options => { - config.SetBasePath(root); - } + // Remove the upload limit from Kestrel. If needed, an upload limit can + // be enforced by a reverse proxy server, like IIS. + options.Limits.MaxRequestBodySize = null; + }); + + web.UseStartup(); }); - public static IHostBuilder CreateHostBuilder(string[] args) - { - // TODO: Merge 'CreateWebHostBuilder' and 'CreateHostBuilder' - // See: https://docs.microsoft.com/en-us/aspnet/core/migration/22-to-30?view=aspnetcore-3.1&tabs=visual-studio#configuration - return new HostBuilder() - .ConfigureBaGetConfiguration(args) - .ConfigureBaGetServices() - .ConfigureBaGetLogging(); - } + public static IHostBuilder CreateHostBuilder(string[] args) => + Host.CreateDefaultBuilder(args) + .UseBaGet(); } } diff --git a/src/BaGet/Startup.cs b/src/BaGet/Startup.cs index d231991fe..ac219c974 100644 --- a/src/BaGet/Startup.cs +++ b/src/BaGet/Startup.cs @@ -1,8 +1,6 @@ using System; -using BaGet.Configuration; using BaGet.Core; -using BaGet.Core.Server.Extensions; -using BaGet.Extensions; +using BaGet.Hosting; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.SpaServices.ReactDevelopmentServer; @@ -23,7 +21,7 @@ public Startup(IConfiguration configuration) public void ConfigureServices(IServiceCollection services) { - services.ConfigureBaGet(Configuration, httpServices: true); + services.ConfigureHttpServices(); // In production, the UI files will be served from this directory services.AddSpaStaticFiles(configuration => diff --git a/tests/BaGet.Tests/ApiIntegrationTests.cs b/tests/BaGet.Tests/ApiIntegrationTests.cs new file mode 100644 index 000000000..59e915a4b --- /dev/null +++ b/tests/BaGet.Tests/ApiIntegrationTests.cs @@ -0,0 +1,39 @@ +using System.Net; +using System.Net.Http; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc.Testing; +using Xunit; +using Xunit.Abstractions; + +namespace BaGet.Tests +{ + public class ApiTest : IClassFixture + { + private readonly WebApplicationFactory _factory; + private readonly HttpClient _client; + + public ApiTest(BaGetWebApplicationFactory factory, ITestOutputHelper output) + { + _factory = factory.WithOutput(output); + _client = _factory.CreateClient(); + } + + [Fact] + public async Task IndexReturnsOk() + { + var response = await _client.GetAsync("v3/index.json"); + var content = await response.Content.ReadAsStringAsync(); + + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + Assert.Equal(TestData.ServiceIndex, content); + } + + [Fact] + public async Task VersionListReturnsNotFound() + { + var response = await _client.GetAsync("v3/package/PackageDoesNotExist/index.json"); + + Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); + } + } +} diff --git a/tests/BaGet.Tests/BaGet.Tests.csproj b/tests/BaGet.Tests/BaGet.Tests.csproj index 734bd403d..c054b3eb8 100644 --- a/tests/BaGet.Tests/BaGet.Tests.csproj +++ b/tests/BaGet.Tests/BaGet.Tests.csproj @@ -11,11 +11,26 @@ - + + + + TestData.resx + True + True + + + + + + TestData.Designer.cs + ResXFileCodeGenerator + + + diff --git a/tests/BaGet.Tests/HostIntegrationTests.cs b/tests/BaGet.Tests/HostIntegrationTests.cs new file mode 100644 index 000000000..9ee6731ba --- /dev/null +++ b/tests/BaGet.Tests/HostIntegrationTests.cs @@ -0,0 +1,76 @@ +using System; +using System.Collections.Generic; +using BaGet.Core; +using BaGet.Database.Sqlite; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Xunit; + +namespace BaGet.Tests +{ + public class HostIntegrationTests + { + private readonly string DatabaseTypeKey = $"{nameof(BaGetOptions.Database)}:{nameof(DatabaseOptions.Type)}"; + private readonly string ConnectionStringKey = $"{nameof(BaGetOptions.Database)}:{nameof(DatabaseOptions.ConnectionString)}"; + + [Fact] + public void ThrowsIfDatabaseTypeInvalid() + { + var provider = BuildServiceProvider(new Dictionary + { + { DatabaseTypeKey, "InvalidType" } + }); + + Assert.Throws( + () => provider.GetRequiredService()); + } + + [Fact] + public void ReturnsDatabaseContext() + { + var provider = BuildServiceProvider(new Dictionary + { + { DatabaseTypeKey, DatabaseType.Sqlite.ToString() }, + { ConnectionStringKey, "..." } + }); + + Assert.NotNull(provider.GetRequiredService()); + } + + [Fact] + public void ReturnsSqliteContext() + { + var provider = BuildServiceProvider(new Dictionary + { + { DatabaseTypeKey, DatabaseType.Sqlite.ToString() }, + { ConnectionStringKey, "..." } + }); + + Assert.NotNull(provider.GetRequiredService()); + } + + [Fact] + public void DefaultsToSqlite() + { + var provider = BuildServiceProvider(); + + var context = provider.GetRequiredService(); + + Assert.IsType(context); + } + + private IServiceProvider BuildServiceProvider(Dictionary configs = null) + { + var hostBuilder = Host.CreateDefaultBuilder(); + + hostBuilder.UseBaGet(); + hostBuilder.ConfigureAppConfiguration((ctx, config) => + { + config.AddInMemoryCollection(configs ?? new Dictionary()); + }); + + return hostBuilder.Build().Services; + } + } +} diff --git a/tests/BaGet.Tests/NuGetClientIntegrationTest.cs b/tests/BaGet.Tests/NuGetClientIntegrationTest.cs deleted file mode 100644 index a0c89d8e1..000000000 --- a/tests/BaGet.Tests/NuGetClientIntegrationTest.cs +++ /dev/null @@ -1,96 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Net; -using System.Net.Http; -using System.Threading.Tasks; -using BaGet.Tests.Support; -using Microsoft.AspNetCore.TestHost; -using Microsoft.Extensions.Logging; -using NuGet.Configuration; -using NuGet.Protocol; -using NuGet.Protocol.Core.Types; -using Xunit; -using Xunit.Abstractions; - -namespace BaGet.Tests -{ - /// - /// Uses official nuget client packages to talk to test host. - /// - public class NuGetClientIntegrationTest : IDisposable - { - protected readonly ITestOutputHelper Helper; - private readonly TestServer server; - private readonly string IndexUrlString = "v3/index.json"; - private SourceRepository _sourceRepository; - private readonly SourceCacheContext _cacheContext; - private HttpSourceResource _httpSource; - private HttpClient _httpClient; - private readonly string indexUrl; - - public NuGetClientIntegrationTest(ITestOutputHelper helper) - { - Helper = helper ?? throw new ArgumentNullException(nameof(helper)); - server = TestServerBuilder.Create().TraceToTestOutputHelper(Helper, LogLevel.Error).Build(); - var providers = new List>(); - providers.AddRange(Repository.Provider.GetCoreV3()); - providers.Add(new Lazy(() => new PackageMetadataResourceV3Provider())); - _httpClient = server.CreateClient(); - providers.Insert(0, new Lazy(() => new HttpSourceResourceProviderTestHost(_httpClient))); - - indexUrl = new Uri(server.BaseAddress, IndexUrlString).AbsoluteUri; - var packageSource = new PackageSource(indexUrl); - _sourceRepository = new SourceRepository(packageSource, providers); - _cacheContext = new SourceCacheContext() { NoCache = true, MaxAge = new DateTimeOffset(), DirectDownload = true }; - _httpSource = _sourceRepository.GetResource(); - Assert.IsType(_httpSource.HttpSource); - } - public void Dispose() - { - server?.Dispose(); - } - - [Fact] - public async Task GetIndexShouldReturn200() - { - var index = await _httpClient.GetAsync(indexUrl); - Assert.Equal(HttpStatusCode.OK, index.StatusCode); - return; - } - - [Fact] - public async Task IndexResourceHasManyEntries() - { - var indexResource = await _sourceRepository.GetResourceAsync(); - Assert.NotEmpty(indexResource.Entries); - } - - [Fact] - public async Task IndexIncludesAtLeastOneSearchQueryEntry() - { - var indexResource = await _sourceRepository.GetResourceAsync(); - Assert.NotEmpty(indexResource.GetServiceEntries("SearchQueryService")); - } - - [Fact] - public async Task IndexIncludesAtLeastOneRegistrationsBaseEntry() - { - var indexResource = await _sourceRepository.GetResourceAsync(); - Assert.NotEmpty(indexResource.GetServiceEntries("RegistrationsBaseUrl")); - } - - [Fact] - public async Task IndexIncludesAtLeastOnePackageBaseAddressEntry() - { - var indexResource = await _sourceRepository.GetResourceAsync(); - Assert.NotEmpty(indexResource.GetServiceEntries("PackageBaseAddress/3.0.0")); - } - - [Fact] - public async Task IndexIncludesAtLeastOneSearchAutocompleteServiceEntry() - { - var indexResource = await _sourceRepository.GetResourceAsync(); - Assert.NotEmpty(indexResource.GetServiceEntries("SearchAutocompleteService")); - } - } -} diff --git a/tests/BaGet.Tests/NuGetClientIntegrationTests.cs b/tests/BaGet.Tests/NuGetClientIntegrationTests.cs new file mode 100644 index 000000000..165b0f277 --- /dev/null +++ b/tests/BaGet.Tests/NuGetClientIntegrationTests.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; +using System.Net.Http; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc.Testing; +using NuGet.Configuration; +using NuGet.Protocol; +using NuGet.Protocol.Core.Types; +using Xunit; +using Xunit.Abstractions; + +namespace BaGet.Tests +{ + /// + /// Uses official nuget client packages to talk to test host. + /// + public class NuGetClientIntegrationTests : IClassFixture + { + private readonly WebApplicationFactory _factory; + private readonly HttpClient _client; + + private readonly SourceRepository _sourceRepository; + private readonly SourceCacheContext _cacheContext; + + public NuGetClientIntegrationTests( + BaGetWebApplicationFactory factory, + ITestOutputHelper output) + { + _factory = factory.WithOutput(output); + _client = _factory.CreateDefaultClient(); + + var sourceUri = new Uri(_factory.Server.BaseAddress, "v3/index.json"); + var packageSource = new PackageSource(sourceUri.AbsoluteUri); + var providers = new List>(); + + providers.Add(new Lazy(() => new HttpSourceResourceProviderTestHost(_client))); + providers.AddRange(Repository.Provider.GetCoreV3()); + + _sourceRepository = new SourceRepository(packageSource, providers); + _cacheContext = new SourceCacheContext() { NoCache = true, MaxAge = new DateTimeOffset(), DirectDownload = true }; + } + + [Fact] + public async Task ValidIndex() + { + var index = await _sourceRepository.GetResourceAsync(); + + Assert.Equal(12, index.Entries.Count); + + Assert.NotEmpty(index.GetServiceEntries("PackageBaseAddress/3.0.0")); + Assert.NotEmpty(index.GetServiceEntries("PackagePublish/2.0.0")); + Assert.NotEmpty(index.GetServiceEntries("RegistrationsBaseUrl")); + Assert.NotEmpty(index.GetServiceEntries("SearchAutocompleteService")); + Assert.NotEmpty(index.GetServiceEntries("SearchQueryService")); + Assert.NotEmpty(index.GetServiceEntries("SymbolPackagePublish/4.9.0")); + } + } +} diff --git a/tests/BaGet.Tests/PackageControllerTest.cs b/tests/BaGet.Tests/PackageControllerTest.cs deleted file mode 100644 index a991331af..000000000 --- a/tests/BaGet.Tests/PackageControllerTest.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System; -using System.Threading.Tasks; -using Microsoft.Extensions.Logging; -using Xunit; -using Xunit.Abstractions; -namespace BaGet.Tests -{ - - public class PackageControllerTest - { - protected readonly ITestOutputHelper Helper; - private readonly string IndexUrlFormatString = "v3/package/{0}/index.json"; - - public PackageControllerTest(ITestOutputHelper helper) - { - Helper = helper ?? throw new ArgumentNullException(nameof(helper)); - } - - [Theory] - [InlineData("id01")] - [InlineData("id02")] - public async Task AskEmptyServerForNotExistingPackageID(string packageID) - { - using (var server = TestServerBuilder.Create().TraceToTestOutputHelper(Helper, LogLevel.Error).Build()) - { - //Ask Empty Storage for a not existings ID - var response = await server.CreateClient().GetAsync(string.Format(IndexUrlFormatString, packageID)); - Assert.Equal(System.Net.HttpStatusCode.NotFound, response.StatusCode); - } - } - } -} diff --git a/tests/BaGet.Tests/ServiceCollectionExtensionsTest.cs b/tests/BaGet.Tests/ServiceCollectionExtensionsTest.cs deleted file mode 100644 index ba4fdd3b7..000000000 --- a/tests/BaGet.Tests/ServiceCollectionExtensionsTest.cs +++ /dev/null @@ -1,90 +0,0 @@ -using System; -using System.Collections.Generic; -using BaGet.Core; -using BaGet.Database.Sqlite; -using BaGet.Extensions; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Xunit; - -namespace BaGet.Tests -{ - public class ServiceCollectionExtensionsTest - { - private readonly string DatabaseTypeKey = $"{nameof(BaGetOptions.Database)}:{nameof(DatabaseOptions.Type)}"; - private readonly string ConnectionStringKey = $"{nameof(BaGetOptions.Database)}:{nameof(DatabaseOptions.ConnectionString)}"; - - [Fact] - public void AskServiceProviderForNotConfiguredDatabaseOptions() - { - var provider = new ServiceCollection() - .ConfigureBaGet(new ConfigurationBuilder().Build()) // Method Under Test - .BuildServiceProvider(); - - var expected = Assert.Throws( - () => provider.GetRequiredService().Database); - - Assert.Contains(nameof(BaGetOptions.Database), expected.Message); - } - - [Fact] - public void AskServiceProviderForWellConfiguredDatabaseOptions() - { - // Create a IConfiguration with a minimal "Database" object. - var initialData = new Dictionary(); - initialData.Add(DatabaseTypeKey, DatabaseType.Sqlite.ToString()); - initialData.Add(ConnectionStringKey, "blabla"); - - var configuration = new ConfigurationBuilder() - .AddInMemoryCollection(initialData) - .Build(); - - var provider = new ServiceCollection() - .ConfigureBaGet(configuration) // Method Under Test - .BuildServiceProvider(); - - Assert.NotNull(provider.GetRequiredService()); - } - - [Fact] - public void AskServiceProviderForWellConfiguredSqliteContext() - { - // Create a IConfiguration with a minimal "Database" object. - var initialData = new Dictionary(); - initialData.Add(DatabaseTypeKey, DatabaseType.Sqlite.ToString()); - initialData.Add(ConnectionStringKey, "blabla"); - - var configuration = new ConfigurationBuilder() - .AddInMemoryCollection(initialData) - .Build(); - - var provider = new ServiceCollection() - .ConfigureBaGet(configuration) // Method Under Test - .BuildServiceProvider(); - - Assert.NotNull(provider.GetRequiredService()); - } - - [Theory] - [InlineData("")] - [InlineData("")] - [InlineData(" ")] - public void AskServiceProviderForInvalidDatabaseType(string databaseType) - { - // Create a IConfiguration with a minimal "Database" object. - var initialData = new Dictionary(); - initialData.Add(DatabaseTypeKey, databaseType); - - var configuration = new ConfigurationBuilder() - .AddInMemoryCollection(initialData) - .Build(); - - var provider = new ServiceCollection() - .ConfigureBaGet(configuration) // Method Under Test - .BuildServiceProvider(); - - var expected = Assert.Throws( - () => provider.GetRequiredService().Database); - } - } -} diff --git a/tests/BaGet.Tests/Support/BaGetWebApplicationFactory.cs b/tests/BaGet.Tests/Support/BaGetWebApplicationFactory.cs new file mode 100644 index 000000000..8eb93700e --- /dev/null +++ b/tests/BaGet.Tests/Support/BaGetWebApplicationFactory.cs @@ -0,0 +1,78 @@ +using System; +using System.Collections.Generic; +using System.IO; +using BaGet.Core; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Mvc.Testing; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Xunit.Abstractions; + +namespace BaGet.Tests +{ + public class BaGetWebApplicationFactory : WebApplicationFactory + { + private readonly string DatabaseTypeKey = $"{nameof(BaGetOptions.Database)}:{nameof(DatabaseOptions.Type)}"; + private readonly string ConnectionStringKey = $"{nameof(BaGetOptions.Database)}:{nameof(DatabaseOptions.ConnectionString)}"; + private readonly string StorageTypeKey = $"{nameof(BaGetOptions.Storage)}:{nameof(StorageOptions.Type)}"; + private readonly string FileSystemStoragePathKey = $"{nameof(BaGetOptions.Storage)}:{nameof(FileSystemStorageOptions.Path)}"; + private readonly string SearchTypeKey = $"{nameof(BaGetOptions.Search)}:{nameof(SearchOptions.Type)}"; + private readonly string MirrorEnabledKey = $"{nameof(BaGetOptions.Mirror)}:{nameof(MirrorOptions.Enabled)}"; + + public WebApplicationFactory WithOutput(ITestOutputHelper output) + { + return WithWebHostBuilder(builder => + { + builder.ConfigureLogging(logging => + { + logging.AddProvider(new XunitLoggerProvider(output)); + }); + }); + } + + protected override void ConfigureWebHost(IWebHostBuilder builder) + { + // Create temporary storage paths. + var tempPath = Path.Combine( + Path.GetTempPath(), + "BaGetTests", + Guid.NewGuid().ToString("N")); + var sqlitePath = Path.Combine(tempPath, "BaGet.db"); + var storagePath = Path.Combine(tempPath, "Packages"); + + Directory.CreateDirectory(tempPath); + + builder + .UseStartup() + .ConfigureAppConfiguration(config => + { + // Setup the integration test configuration. + config.AddInMemoryCollection(new Dictionary + { + { DatabaseTypeKey, DatabaseType.Sqlite.ToString() }, + { ConnectionStringKey, $"Data Source={sqlitePath}" }, + { StorageTypeKey, StorageType.FileSystem.ToString() }, + { FileSystemStoragePathKey, storagePath }, + { SearchTypeKey, nameof(SearchType.Database) }, + { MirrorEnabledKey, false.ToString() }, + }); + }) + .ConfigureServices((context, services) => + { + // Setup the integration test database. + var provider = services.BuildServiceProvider(); + var scopeFactory = provider.GetRequiredService(); + + using (var scope = scopeFactory.CreateScope()) + { + scope.ServiceProvider + .GetRequiredService() + .Database + .Migrate(); + } + }); + } + } +} diff --git a/tests/BaGet.Tests/Support/HttpSourceResourceProviderTestHost.cs b/tests/BaGet.Tests/Support/HttpSourceResourceProviderTestHost.cs index 0e7a838b3..2420112a1 100644 --- a/tests/BaGet.Tests/Support/HttpSourceResourceProviderTestHost.cs +++ b/tests/BaGet.Tests/Support/HttpSourceResourceProviderTestHost.cs @@ -8,7 +8,7 @@ using NuGet.Protocol; using NuGet.Protocol.Core.Types; -namespace BaGet.Tests.Support +namespace BaGet.Tests { /// /// Similar to official HttpSourceResourceProvider, but uses test host. @@ -20,17 +20,12 @@ private readonly ConcurrentDictionary _cache = new ConcurrentDictionary(); private readonly HttpClient _httpClient; - /// - /// The throttle to apply to all HTTP requests. - /// - public static IThrottle Throttle { get; set; } - - public HttpSourceResourceProviderTestHost(HttpClient client) + public HttpSourceResourceProviderTestHost(HttpClient httpClient) : base(typeof(HttpSourceResource), nameof(HttpSourceResource), NuGetResourceProviderPositions.Last) { - _httpClient = client; + _httpClient = httpClient; } public override Task> TryCreate(SourceRepository source, CancellationToken token) @@ -43,7 +38,7 @@ public override Task> TryCreate(SourceRepository sou { curResource = _cache.GetOrAdd( source.PackageSource, - packageSource => new HttpSourceResource(HttpSourceTestHost.Create(source, _httpClient))); + packageSource => new HttpSourceResource(TestableHttpSource.Create(source, _httpClient))); } return Task.FromResult(new Tuple(curResource != null, curResource)); diff --git a/tests/BaGet.Tests/Support/HttpSourceTestHost.cs b/tests/BaGet.Tests/Support/HttpSourceTestHost.cs deleted file mode 100644 index 85688cd36..000000000 --- a/tests/BaGet.Tests/Support/HttpSourceTestHost.cs +++ /dev/null @@ -1,43 +0,0 @@ -// 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.IO; -using System.Net.Http; -using System.Threading.Tasks; -using NuGet.Configuration; -using NuGet.Protocol; -using NuGet.Protocol.Core.Types; - -namespace BaGet.Tests.Support -{ - public class HttpSourceTestHost : HttpSource - { - public static HttpSourceTestHost Create(SourceRepository source, HttpClient client) - { - Func> factory = () => source.GetResourceAsync(); - - return new HttpSourceTestHost(source.PackageSource, factory, NullThrottle.Instance, client); - } - public HttpSourceTestHost( - PackageSource packageSource, - Func> messageHandlerFactory, - IThrottle throttle, - HttpClient client) - : base(packageSource, messageHandlerFactory, throttle) - { - var prop = typeof(HttpSource).GetField("_httpClient", - System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); - prop.SetValue(this, client); - HttpCacheDirectory = Path.Combine(Path.GetTempPath(), System.Guid.NewGuid().ToString("N")); - var cacheDir = new DirectoryInfo(HttpCacheDirectory); - if (cacheDir.Exists) - { - foreach (var dir in cacheDir.EnumerateDirectories()) - { - dir.Delete(true); - } - } - } - } -} diff --git a/tests/BaGet.Tests/Support/TestableHttpSource.cs b/tests/BaGet.Tests/Support/TestableHttpSource.cs new file mode 100644 index 000000000..a7e022cbc --- /dev/null +++ b/tests/BaGet.Tests/Support/TestableHttpSource.cs @@ -0,0 +1,55 @@ +using System; +using System.IO; +using System.Net.Http; +using System.Reflection; +using System.Threading.Tasks; +using NuGet.Configuration; +using NuGet.Protocol; +using NuGet.Protocol.Core.Types; + +namespace BaGet.Tests +{ + public class TestableHttpSource : HttpSource + { + public static TestableHttpSource Create(SourceRepository source, HttpClient client) + { + Func> factory = () => source.GetResourceAsync(); + + var httpCacheDirectory = Path.Combine( + Path.GetTempPath(), + "BaGetTests", + Guid.NewGuid().ToString("N")); + + return new TestableHttpSource( + source.PackageSource, + factory, + NullThrottle.Instance, + client, + httpCacheDirectory); + } + + private TestableHttpSource( + PackageSource packageSource, + Func> messageHandlerFactory, + IThrottle throttle, + HttpClient httpClient, + string httpCacheDirectory) + : base(packageSource, messageHandlerFactory, throttle) + { + // Set the HTTP client on the parent's private field. + var flags = BindingFlags.NonPublic | BindingFlags.Instance; + var field = typeof(HttpSource).GetField("_httpClient", flags); + + if (field == null) + { + throw new InvalidOperationException( + $"Could not find field '_httpClient' with flags '{flags}' " + + $"on {nameof(HttpSource)}"); + } + + field.SetValue(this, httpClient); + + HttpCacheDirectory = httpCacheDirectory; + } + } +} diff --git a/tests/BaGet.Tests/Support/XunitLogger.cs b/tests/BaGet.Tests/Support/XunitLogger.cs new file mode 100644 index 000000000..1c3d19647 --- /dev/null +++ b/tests/BaGet.Tests/Support/XunitLogger.cs @@ -0,0 +1,40 @@ +using System; +using Microsoft.Extensions.Logging; +using Xunit.Abstractions; + +namespace BaGet.Tests +{ + // Based off: + // https://stackoverflow.com/questions/46169169/net-core-2-0-configurelogging-xunit-test + public class XunitLogger : ILogger + { + private readonly ITestOutputHelper _output; + private readonly string _category; + + public XunitLogger(ITestOutputHelper output, string category) + { + _output = output ?? throw new ArgumentNullException(nameof(output)); + _category = category ?? throw new ArgumentNullException(nameof(category)); + } + + public IDisposable BeginScope(TState state) => NullScope.Instance; + public bool IsEnabled(LogLevel logLevel) => true; + + public void Log(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func formatter) + { + _output.WriteLine($"{_category} [{eventId}] {formatter(state, exception)}"); + + if (exception != null) + { + _output.WriteLine(exception.ToString()); + } + } + + private class NullScope : IDisposable + { + public static readonly NullScope Instance = new NullScope(); + + public void Dispose() { } + } + } +} diff --git a/tests/BaGet.Tests/Support/XunitLoggerProvider.cs b/tests/BaGet.Tests/Support/XunitLoggerProvider.cs new file mode 100644 index 000000000..efc71d7e4 --- /dev/null +++ b/tests/BaGet.Tests/Support/XunitLoggerProvider.cs @@ -0,0 +1,22 @@ +using System; +using Microsoft.Extensions.Logging; +using Xunit.Abstractions; + +namespace BaGet.Tests +{ + // Based off: + // https://stackoverflow.com/questions/46169169/net-core-2-0-configurelogging-xunit-test + public class XunitLoggerProvider : ILoggerProvider + { + private readonly ITestOutputHelper _output; + + public XunitLoggerProvider(ITestOutputHelper output) + { + _output = output ?? throw new ArgumentNullException(nameof(output)); + } + + public ILogger CreateLogger(string category) => new XunitLogger(_output, category); + + public void Dispose() { } + } +} diff --git a/tests/BaGet.Tests/TestData.Designer.cs b/tests/BaGet.Tests/TestData.Designer.cs new file mode 100644 index 000000000..133e5d761 --- /dev/null +++ b/tests/BaGet.Tests/TestData.Designer.cs @@ -0,0 +1,72 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace BaGet.Tests { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class TestData { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal TestData() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("BaGet.Tests.TestData", typeof(TestData).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to {"version":"3.0.0","resources":[{"@id":"http://localhost/api/v2/package","@type":"PackagePublish/2.0.0","comment":null},{"@id":"http://localhost/api/v2/symbol","@type":"SymbolPackagePublish/4.9.0","comment":null},{"@id":"http://localhost/v3/search","@type":"SearchQueryService","comment":null},{"@id":"http://localhost/v3/search","@type":"SearchQueryService/3.0.0-beta","comment":null},{"@id":"http://localhost/v3/search","@type":"SearchQueryService/3.0.0-rc","comment":null},{"@id":"http://localhost/v3/registra [rest of string was truncated]";. + /// + internal static string ServiceIndex { + get { + return ResourceManager.GetString("ServiceIndex", resourceCulture); + } + } + } +} diff --git a/tests/BaGet.Tests/TestData.resx b/tests/BaGet.Tests/TestData.resx new file mode 100644 index 000000000..e2b63e4f3 --- /dev/null +++ b/tests/BaGet.Tests/TestData.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + {"version":"3.0.0","resources":[{"@id":"http://localhost/api/v2/package","@type":"PackagePublish/2.0.0","comment":null},{"@id":"http://localhost/api/v2/symbol","@type":"SymbolPackagePublish/4.9.0","comment":null},{"@id":"http://localhost/v3/search","@type":"SearchQueryService","comment":null},{"@id":"http://localhost/v3/search","@type":"SearchQueryService/3.0.0-beta","comment":null},{"@id":"http://localhost/v3/search","@type":"SearchQueryService/3.0.0-rc","comment":null},{"@id":"http://localhost/v3/registration","@type":"RegistrationsBaseUrl","comment":null},{"@id":"http://localhost/v3/registration","@type":"RegistrationsBaseUrl/3.0.0-rc","comment":null},{"@id":"http://localhost/v3/registration","@type":"RegistrationsBaseUrl/3.0.0-beta","comment":null},{"@id":"http://localhost/v3/package","@type":"PackageBaseAddress/3.0.0","comment":null},{"@id":"http://localhost/v3/autocomplete","@type":"SearchAutocompleteService","comment":null},{"@id":"http://localhost/v3/autocomplete","@type":"SearchAutocompleteService/3.0.0-rc","comment":null},{"@id":"http://localhost/v3/autocomplete","@type":"SearchAutocompleteService/3.0.0-beta","comment":null}]} + + \ No newline at end of file diff --git a/tests/BaGet.Tests/TestServerBuilder.cs b/tests/BaGet.Tests/TestServerBuilder.cs deleted file mode 100644 index c2c315bb6..000000000 --- a/tests/BaGet.Tests/TestServerBuilder.cs +++ /dev/null @@ -1,121 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using BaGet.Core; -using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.TestHost; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; -using Xunit.Abstractions; - -namespace BaGet.Tests -{ - /// - /// fluent builder pattern implementation. - /// private/hidden Constructor, please use one of the static methods for creation. - /// - public class TestServerBuilder - { - private const string DefaultPackagesFolderName = "Packages"; - - private readonly string DatabaseTypeKey = $"{nameof(BaGetOptions.Database)}:{nameof(DatabaseOptions.Type)}"; - private readonly string ConnectionStringKey = $"{nameof(BaGetOptions.Database)}:{nameof(DatabaseOptions.ConnectionString)}"; - private readonly string StorageTypeKey = $"{nameof(BaGetOptions.Storage)}:{nameof(StorageOptions.Type)}"; - private readonly string FileSystemStoragePathKey = $"{nameof(BaGetOptions.Storage)}:{nameof(FileSystemStorageOptions.Path)}"; - private readonly string SearchTypeKey = $"{nameof(BaGetOptions.Search)}:{nameof(SearchOptions.Type)}"; - private readonly string MirrorEnabledKey = $"{nameof(BaGetOptions.Mirror)}:{nameof(MirrorOptions.Enabled)}"; - - private ITestOutputHelper _helper; - private LogLevel _minimumLevel = LogLevel.None; - - /// - /// private/hidden Constructor. - /// Tests should use some of the static methods! - /// - private TestServerBuilder() - { - Configuration = new Dictionary(); - } - - /// - /// In Memory representation of Config Settings - /// - public Dictionary Configuration { get; private set; } - - /// - /// Xunit.ITestOutputHelper is used as Logging-Target (Microsoft.Extensions.Logging) - /// - /// - /// - /// - public TestServerBuilder TraceToTestOutputHelper(ITestOutputHelper helper, LogLevel minimumLevel) - { - _helper = helper ?? throw new ArgumentNullException(nameof(helper)); - _minimumLevel = minimumLevel; - return this; - } - - /// - /// Test Server Builder instance that uses a empty subfolder of System.IO.Path.GetTempPath - /// - /// - public static TestServerBuilder Create() - { - return new TestServerBuilder().UseEmptyTempFolder(); - } - - - /// - /// Creates a subdirectory (Path.GetTempPath() + Guid) and uses this as location for - /// - Sqlite file => .\BaGet.db - /// - FilePackageStorageService => .\Packages\*.* - /// - /// - private TestServerBuilder UseEmptyTempFolder() - { - Configuration.Add(DatabaseTypeKey, DatabaseType.Sqlite.ToString()); - var uniqueTempFolder = Path.Combine(Path.GetTempPath(), System.Guid.NewGuid().ToString("N")); - Directory.CreateDirectory(uniqueTempFolder); - var resolvedSqliteFile = Path.Combine(uniqueTempFolder, "BaGet.db"); - var storageFolderPath = Path.Combine(uniqueTempFolder, DefaultPackagesFolderName); - Configuration.Add(ConnectionStringKey, string.Format("Data Source={0}", resolvedSqliteFile)); - Configuration.Add(StorageTypeKey, StorageType.FileSystem.ToString()); - Configuration.Add(FileSystemStoragePathKey, storageFolderPath); - Configuration.Add(SearchTypeKey, nameof(SearchType.Database)); - Configuration.Add(MirrorEnabledKey, false.ToString()); - return this; - } - - public TestServer Build() - { - var configurationBuilder = new ConfigurationBuilder().AddInMemoryCollection(Configuration); - var hostBuilder = new WebHostBuilder() - .UseConfiguration(configurationBuilder.Build()) - .UseStartup(); - - if (_helper != null) - { - hostBuilder.ConfigureLogging((builder) => - { - builder.AddProvider(new XunitLoggerProvider(_helper)); - builder.SetMinimumLevel(_minimumLevel); - }); - } - - var server = new TestServer(hostBuilder); - - //Ensure that the Database is created, we use the same feature like inside the Startup in case of Env.IsDevelopment (EF-Migrations) - var scopeFactory = server.Host.Services.GetRequiredService(); - using (var scope = scopeFactory.CreateScope()) - { - scope.ServiceProvider - .GetRequiredService() - .Database - .Migrate(); - } - return server; - } - } -} diff --git a/tests/BaGet.Tests/XunitLogger.cs b/tests/BaGet.Tests/XunitLogger.cs deleted file mode 100644 index ec2de7b48..000000000 --- a/tests/BaGet.Tests/XunitLogger.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System; -using Microsoft.Extensions.Logging; -using Xunit.Abstractions; - -namespace BaGet.Tests -{ - // https://stackoverflow.com/questions/46169169/net-core-2-0-configurelogging-xunit-test - public class XunitLogger : ILogger - { - private readonly ITestOutputHelper _testOutputHelper; - private readonly string _categoryName; - - public XunitLogger(ITestOutputHelper testOutputHelper, string categoryName) - { - _testOutputHelper = testOutputHelper ?? throw new ArgumentNullException(nameof(testOutputHelper)); - if (string.IsNullOrWhiteSpace(categoryName)) - { - throw new ArgumentNullException(nameof(categoryName)); - } - _categoryName = categoryName; - } - - public IDisposable BeginScope(TState state) - => NoOpDisposable.Instance; - - public bool IsEnabled(LogLevel logLevel) - => true; - - public void Log(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func formatter) - { - _testOutputHelper.WriteLine($"{_categoryName} [{eventId}] {formatter(state, exception)}"); - if (exception != null) - { - _testOutputHelper.WriteLine(exception.ToString()); - } - } - - private class NoOpDisposable : IDisposable - { - public static NoOpDisposable Instance = new NoOpDisposable(); - public void Dispose() - { } - } - } -} diff --git a/tests/BaGet.Tests/XunitLoggerProvider.cs b/tests/BaGet.Tests/XunitLoggerProvider.cs deleted file mode 100644 index 2f9ac48ec..000000000 --- a/tests/BaGet.Tests/XunitLoggerProvider.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System; -using Microsoft.Extensions.Logging; -using Xunit.Abstractions; - -namespace BaGet.Tests -{ - // https://stackoverflow.com/questions/46169169/net-core-2-0-configurelogging-xunit-test - public class XunitLoggerProvider : ILoggerProvider - { - private readonly ITestOutputHelper _testOutputHelper; - - public XunitLoggerProvider(ITestOutputHelper testOutputHelper) - { - _testOutputHelper = testOutputHelper ?? throw new ArgumentNullException(nameof(testOutputHelper)); - } - - public ILogger CreateLogger(string categoryName) - => new XunitLogger(_testOutputHelper, categoryName); - - public void Dispose() - { } - } -} From f223f654f8154c3414c0bcef4062b3fac3755548 Mon Sep 17 00:00:00 2001 From: Loic Sharma Date: Sun, 3 May 2020 18:33:50 -0700 Subject: [PATCH 2/4] Remove global.json --- global.json | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 global.json diff --git a/global.json b/global.json deleted file mode 100644 index 9cf054ff3..000000000 --- a/global.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "sdk": { - // "version": "2.2.402" - // "version": "3.0.102" - "version": "3.1.101" - } -} From 78c77d75c0ff46bb1cbcb57b2126c2c4f25a3ea0 Mon Sep 17 00:00:00 2001 From: Loic Sharma Date: Sun, 3 May 2020 18:42:35 -0700 Subject: [PATCH 3/4] Clean up --- .../Properties/launchSettings.json | 27 ------------------- 1 file changed, 27 deletions(-) delete mode 100644 src/BaGet.Hosting/Properties/launchSettings.json diff --git a/src/BaGet.Hosting/Properties/launchSettings.json b/src/BaGet.Hosting/Properties/launchSettings.json deleted file mode 100644 index 903a77a8a..000000000 --- a/src/BaGet.Hosting/Properties/launchSettings.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:62088/", - "sslPort": 44302 - } - }, - "profiles": { - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, - "BaGet.Core.Server": { - "commandName": "Project", - "launchBrowser": true, - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - }, - "applicationUrl": "https://localhost:5001;http://localhost:5000" - } - } -} \ No newline at end of file From 9bdcf73b84ccc3848aea4a5ac0a7ba36836626d6 Mon Sep 17 00:00:00 2001 From: Loic Sharma Date: Sun, 3 May 2020 18:45:34 -0700 Subject: [PATCH 4/4] Rename --- tests/BaGet.Tests/ApiIntegrationTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/BaGet.Tests/ApiIntegrationTests.cs b/tests/BaGet.Tests/ApiIntegrationTests.cs index 59e915a4b..88a78b8bd 100644 --- a/tests/BaGet.Tests/ApiIntegrationTests.cs +++ b/tests/BaGet.Tests/ApiIntegrationTests.cs @@ -7,12 +7,12 @@ namespace BaGet.Tests { - public class ApiTest : IClassFixture + public class ApiIntegrationTests : IClassFixture { private readonly WebApplicationFactory _factory; private readonly HttpClient _client; - public ApiTest(BaGetWebApplicationFactory factory, ITestOutputHelper output) + public ApiIntegrationTests(BaGetWebApplicationFactory factory, ITestOutputHelper output) { _factory = factory.WithOutput(output); _client = _factory.CreateClient();