Browse Source

Introduce new unit tests for the core/server/validation builders and extensions

pull/649/head
Kévin Chalet 8 years ago
parent
commit
b5c9798e17
  1. 14
      OpenIddict.sln
  2. 2
      src/OpenIddict.Core/OpenIddict.Core.csproj
  3. 1
      src/OpenIddict.Core/OpenIddictCoreExtensions.cs
  4. 2
      src/OpenIddict.Core/Resolvers/OpenIddictTokenStoreResolver.cs
  5. 49
      src/OpenIddict.EntityFramework/OpenIddictEntityFrameworkBuilder.cs
  6. 2
      src/OpenIddict.EntityFramework/Resolvers/OpenIddictScopeStoreResolver.cs
  7. 57
      src/OpenIddict.EntityFrameworkCore/OpenIddictEntityFrameworkCoreBuilder.cs
  8. 2
      src/OpenIddict.EntityFrameworkCore/Resolvers/OpenIddictScopeStoreResolver.cs
  9. 32
      src/OpenIddict.MongoDb/OpenIddictMongoDbBuilder.cs
  10. 5
      src/OpenIddict.Mvc/OpenIddictMvcExtensions.cs
  11. 3
      src/OpenIddict.Server/OpenIddict.Server.csproj
  12. 1
      src/OpenIddict.Server/OpenIddictServerExtensions.cs
  13. 1
      src/OpenIddict.Validation/OpenIddict.Validation.csproj
  14. 1
      src/OpenIddict.Validation/OpenIddictValidationExtensions.cs
  15. 26
      test/OpenIddict.Abstractions.Tests/OpenIddict.Abstractions.Tests.csproj
  16. 27
      test/OpenIddict.Abstractions.Tests/OpenIddictBuilderTests.cs
  17. 39
      test/OpenIddict.Abstractions.Tests/OpenIddictExtensionsTests.cs
  18. 12
      test/OpenIddict.Core.Tests/OpenIddictCoreBuilderTests.cs
  19. 321
      test/OpenIddict.Core.Tests/OpenIddictCoreExtensionsTests.cs
  20. 54
      test/OpenIddict.Core.Tests/Resolvers/OpenIddictApplicationStoreResolverTests.cs
  21. 54
      test/OpenIddict.Core.Tests/Resolvers/OpenIddictAuthorizationStoreResolverTests.cs
  22. 54
      test/OpenIddict.Core.Tests/Resolvers/OpenIddictScopeStoreResolverTests.cs
  23. 54
      test/OpenIddict.Core.Tests/Resolvers/OpenIddictTokenStoreResolverTests.cs
  24. 141
      test/OpenIddict.EntityFramework.Tests/OpenIddictEntityFrameworkBuilderTests.cs
  25. 78
      test/OpenIddict.EntityFramework.Tests/OpenIddictEntityFrameworkExtensionsTests.cs
  26. 117
      test/OpenIddict.EntityFramework.Tests/Resolvers/OpenIddictApplicationStoreResolverTests.cs
  27. 117
      test/OpenIddict.EntityFramework.Tests/Resolvers/OpenIddictAuthorizationStoreResolverTests.cs
  28. 117
      test/OpenIddict.EntityFramework.Tests/Resolvers/OpenIddictScopeStoreResolverTests.cs
  29. 117
      test/OpenIddict.EntityFramework.Tests/Resolvers/OpenIddictTokenStoreResolverTests.cs
  30. 145
      test/OpenIddict.EntityFrameworkCore.Tests/OpenIddictEntityFrameworkCoreBuilderTests.cs
  31. 78
      test/OpenIddict.EntityFrameworkCore.Tests/OpenIddictEntityFrameworkCoreExtensionsTests.cs
  32. 117
      test/OpenIddict.EntityFrameworkCore.Tests/Resolvers/OpenIddictApplicationStoreResolverTests.cs
  33. 117
      test/OpenIddict.EntityFrameworkCore.Tests/Resolvers/OpenIddictAuthorizationStoreResolverTests.cs
  34. 117
      test/OpenIddict.EntityFrameworkCore.Tests/Resolvers/OpenIddictScopeStoreResolverTests.cs
  35. 117
      test/OpenIddict.EntityFrameworkCore.Tests/Resolvers/OpenIddictTokenStoreResolverTests.cs
  36. 26
      test/OpenIddict.MongoDb.Tests/OpenIddict.MongoDb.Tests.csproj
  37. 282
      test/OpenIddict.MongoDb.Tests/OpenIddictMongoDbBuilderTests.cs
  38. 132
      test/OpenIddict.MongoDb.Tests/OpenIddictMongoDbExtensionsTests.cs
  39. 13
      test/OpenIddict.Mvc.Tests/OpenIddictMvcBuilderTests.cs
  40. 26
      test/OpenIddict.Mvc.Tests/OpenIddictMvcExtensionsTests.cs
  41. 12
      test/OpenIddict.Server.Tests/OpenIddictServerBuilderTests.cs
  42. 208
      test/OpenIddict.Server.Tests/OpenIddictServerExtensionsTests.cs
  43. 12
      test/OpenIddict.Validation.Tests/OpenIddictValidationBuilderTests.cs
  44. 169
      test/OpenIddict.Validation.Tests/OpenIddictValidationExtensionsTests.cs

14
OpenIddict.sln

@ -59,6 +59,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenIddict.MongoDb", "src\O
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenIddict.MongoDb.Models", "src\OpenIddict.MongoDb.Models\OpenIddict.MongoDb.Models.csproj", "{14C55FB6-9626-4BDE-8961-3BE91DDD6418}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenIddict.MongoDb.Models", "src\OpenIddict.MongoDb.Models\OpenIddict.MongoDb.Models.csproj", "{14C55FB6-9626-4BDE-8961-3BE91DDD6418}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenIddict.Abstractions.Tests", "test\OpenIddict.Abstractions.Tests\OpenIddict.Abstractions.Tests.csproj", "{8FACE85E-EF8F-4AB1-85DD-4010D5E2165D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenIddict.MongoDb.Tests", "test\OpenIddict.MongoDb.Tests\OpenIddict.MongoDb.Tests.csproj", "{27F603EF-D335-445B-9443-6B5A6CA3C110}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@ -145,6 +149,14 @@ Global
{14C55FB6-9626-4BDE-8961-3BE91DDD6418}.Debug|Any CPU.Build.0 = Debug|Any CPU {14C55FB6-9626-4BDE-8961-3BE91DDD6418}.Debug|Any CPU.Build.0 = Debug|Any CPU
{14C55FB6-9626-4BDE-8961-3BE91DDD6418}.Release|Any CPU.ActiveCfg = Release|Any CPU {14C55FB6-9626-4BDE-8961-3BE91DDD6418}.Release|Any CPU.ActiveCfg = Release|Any CPU
{14C55FB6-9626-4BDE-8961-3BE91DDD6418}.Release|Any CPU.Build.0 = Release|Any CPU {14C55FB6-9626-4BDE-8961-3BE91DDD6418}.Release|Any CPU.Build.0 = Release|Any CPU
{8FACE85E-EF8F-4AB1-85DD-4010D5E2165D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8FACE85E-EF8F-4AB1-85DD-4010D5E2165D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8FACE85E-EF8F-4AB1-85DD-4010D5E2165D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8FACE85E-EF8F-4AB1-85DD-4010D5E2165D}.Release|Any CPU.Build.0 = Release|Any CPU
{27F603EF-D335-445B-9443-6B5A6CA3C110}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{27F603EF-D335-445B-9443-6B5A6CA3C110}.Debug|Any CPU.Build.0 = Debug|Any CPU
{27F603EF-D335-445B-9443-6B5A6CA3C110}.Release|Any CPU.ActiveCfg = Release|Any CPU
{27F603EF-D335-445B-9443-6B5A6CA3C110}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
@ -170,6 +182,8 @@ Global
{B5371534-4C33-41FA-B3D3-7D70D632DB15} = {D544447C-D701-46BB-9A5B-C76C612A596B} {B5371534-4C33-41FA-B3D3-7D70D632DB15} = {D544447C-D701-46BB-9A5B-C76C612A596B}
{BACF1DD4-8390-48D4-BD9B-DA1EC00C1F98} = {D544447C-D701-46BB-9A5B-C76C612A596B} {BACF1DD4-8390-48D4-BD9B-DA1EC00C1F98} = {D544447C-D701-46BB-9A5B-C76C612A596B}
{14C55FB6-9626-4BDE-8961-3BE91DDD6418} = {D544447C-D701-46BB-9A5B-C76C612A596B} {14C55FB6-9626-4BDE-8961-3BE91DDD6418} = {D544447C-D701-46BB-9A5B-C76C612A596B}
{8FACE85E-EF8F-4AB1-85DD-4010D5E2165D} = {5FC71D6A-A994-4F62-977F-88A7D25379D7}
{27F603EF-D335-445B-9443-6B5A6CA3C110} = {5FC71D6A-A994-4F62-977F-88A7D25379D7}
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {A710059F-0466-4D48-9B3A-0EF4F840B616} SolutionGuid = {A710059F-0466-4D48-9B3A-0EF4F840B616}

2
src/OpenIddict.Core/OpenIddict.Core.csproj

@ -19,7 +19,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="CryptoHelper" Version="$(CryptoHelperVersion)" /> <PackageReference Include="CryptoHelper" Version="$(CryptoHelperVersion)" />
<PackageReference Include="JetBrains.Annotations" Version="$(JetBrainsVersion)" PrivateAssets="All" /> <PackageReference Include="JetBrains.Annotations" Version="$(JetBrainsVersion)" PrivateAssets="All" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="$(AspNetCoreVersion)" /> <PackageReference Include="Microsoft.Extensions.Logging" Version="$(AspNetCoreVersion)" />
<PackageReference Include="Microsoft.Extensions.Options" Version="$(AspNetCoreVersion)" /> <PackageReference Include="Microsoft.Extensions.Options" Version="$(AspNetCoreVersion)" />
</ItemGroup> </ItemGroup>

1
src/OpenIddict.Core/OpenIddictCoreExtensions.cs

@ -29,6 +29,7 @@ namespace Microsoft.Extensions.DependencyInjection
throw new ArgumentNullException(nameof(builder)); throw new ArgumentNullException(nameof(builder));
} }
builder.Services.AddLogging();
builder.Services.AddOptions(); builder.Services.AddOptions();
builder.Services.TryAddScoped(typeof(OpenIddictApplicationManager<>)); builder.Services.TryAddScoped(typeof(OpenIddictApplicationManager<>));

2
src/OpenIddict.Core/Resolvers/OpenIddictTokenStoreResolver.cs

@ -30,7 +30,7 @@ namespace OpenIddict.Core
if (store == null) if (store == null)
{ {
throw new InvalidOperationException(new StringBuilder() throw new InvalidOperationException(new StringBuilder()
.AppendLine("No token store factory has been registered in the dependency injection container.") .AppendLine("No token store has been registered in the dependency injection container.")
.Append("To register the Entity Framework Core stores, reference the 'OpenIddict.EntityFrameworkCore' ") .Append("To register the Entity Framework Core stores, reference the 'OpenIddict.EntityFrameworkCore' ")
.AppendLine("package and call 'services.AddOpenIddict().AddCore().UseEntityFrameworkCore()'.") .AppendLine("package and call 'services.AddOpenIddict().AddCore().UseEntityFrameworkCore()'.")
.Append("To register a custom store, create an implementation of 'IOpenIddictTokenStore' and ") .Append("To register a custom store, create an implementation of 'IOpenIddictTokenStore' and ")

49
src/OpenIddict.EntityFramework/OpenIddictEntityFrameworkBuilder.cs

@ -58,13 +58,37 @@ namespace Microsoft.Extensions.DependencyInjection
return this; return this;
} }
/// <summary>
/// Configures OpenIddict to use the specified entities, derived
/// from the default OpenIddict Entity Framework 6.x entities.
/// </summary>
/// <returns>The <see cref="OpenIddictEntityFrameworkBuilder"/>.</returns>
public OpenIddictEntityFrameworkBuilder ReplaceDefaultEntities<TApplication, TAuthorization, TScope, TToken, TKey>()
where TApplication : OpenIddictApplication<TKey, TAuthorization, TToken>
where TAuthorization : OpenIddictAuthorization<TKey, TApplication, TToken>
where TScope : OpenIddictScope<TKey>
where TToken : OpenIddictToken<TKey, TApplication, TAuthorization>
where TKey : IEquatable<TKey>
{
Services.Configure<OpenIddictCoreOptions>(options =>
{
options.DefaultApplicationType = typeof(TApplication);
options.DefaultAuthorizationType = typeof(TAuthorization);
options.DefaultScopeType = typeof(TScope);
options.DefaultTokenType = typeof(TToken);
});
return this;
}
/// <summary> /// <summary>
/// Configures the OpenIddict Entity Framework 6.x stores to use the specified database context type. /// Configures the OpenIddict Entity Framework 6.x stores to use the specified database context type.
/// </summary> /// </summary>
/// <typeparam name="TContext">The type of the <see cref="DbContext"/> used by OpenIddict.</typeparam> /// <typeparam name="TContext">The type of the <see cref="DbContext"/> used by OpenIddict.</typeparam>
/// <returns>The <see cref="OpenIddictEntityFrameworkBuilder"/>.</returns> /// <returns>The <see cref="OpenIddictEntityFrameworkBuilder"/>.</returns>
public OpenIddictEntityFrameworkBuilder UseDbContext<TContext>() public OpenIddictEntityFrameworkBuilder UseDbContext<TContext>()
where TContext : DbContext => UseDbContext(typeof(TContext)); where TContext : DbContext
=> UseDbContext(typeof(TContext));
/// <summary> /// <summary>
/// Configures the OpenIddict Entity Framework 6.x stores to use the specified database context type. /// Configures the OpenIddict Entity Framework 6.x stores to use the specified database context type.
@ -87,28 +111,5 @@ namespace Microsoft.Extensions.DependencyInjection
return Configure(options => options.DbContextType = type); return Configure(options => options.DbContextType = type);
} }
/// <summary>
/// Configures OpenIddict to use the specified entities, derived
/// from the default OpenIddict Entity Framework 6.x entities.
/// </summary>
/// <returns>The <see cref="OpenIddictEntityFrameworkBuilder"/>.</returns>
public OpenIddictEntityFrameworkBuilder ReplaceDefaultEntities<TApplication, TAuthorization, TScope, TToken, TKey>()
where TApplication : OpenIddictApplication<TKey, TAuthorization, TToken>
where TAuthorization : OpenIddictAuthorization<TKey, TApplication, TToken>
where TScope : OpenIddictScope<TKey>
where TToken : OpenIddictToken<TKey, TApplication, TAuthorization>
where TKey : IEquatable<TKey>
{
Services.Configure<OpenIddictCoreOptions>(options =>
{
options.DefaultApplicationType = typeof(TApplication);
options.DefaultAuthorizationType = typeof(TAuthorization);
options.DefaultScopeType = typeof(TScope);
options.DefaultTokenType = typeof(TToken);
});
return this;
}
} }
} }

2
src/OpenIddict.EntityFramework/Resolvers/OpenIddictScopeStoreResolver.cs

@ -55,7 +55,7 @@ namespace OpenIddict.EntityFramework
throw new InvalidOperationException(new StringBuilder() throw new InvalidOperationException(new StringBuilder()
.AppendLine("The specified scope type is not compatible with the Entity Framework 6.x stores.") .AppendLine("The specified scope type is not compatible with the Entity Framework 6.x stores.")
.Append("When enabling the Entity Framework 6.x stores, make sure you use the built-in ") .Append("When enabling the Entity Framework 6.x stores, make sure you use the built-in ")
.Append("'OpenIdScope' entity (from the 'OpenIddict.EntityFramework.Models' package) ") .Append("'OpenIddictScope' entity (from the 'OpenIddict.EntityFramework.Models' package) ")
.Append("or a custom entity that inherits from the generic 'OpenIddictScope' entity.") .Append("or a custom entity that inherits from the generic 'OpenIddictScope' entity.")
.ToString()); .ToString());
} }

57
src/OpenIddict.EntityFrameworkCore/OpenIddictEntityFrameworkCoreBuilder.cs

@ -57,34 +57,6 @@ namespace Microsoft.Extensions.DependencyInjection
return this; return this;
} }
/// <summary>
/// Configures the OpenIddict Entity Framework Core stores to use the specified database context type.
/// </summary>
/// <typeparam name="TContext">The type of the <see cref="DbContext"/> used by OpenIddict.</typeparam>
/// <returns>The <see cref="OpenIddictEntityFrameworkCoreBuilder"/>.</returns>
public OpenIddictEntityFrameworkCoreBuilder UseDbContext<TContext>()
where TContext : DbContext => UseDbContext(typeof(TContext));
/// <summary>
/// Configures the OpenIddict Entity Framework Core stores to use the specified database context type.
/// </summary>
/// <param name="type">The type of the <see cref="DbContext"/> used by OpenIddict.</param>
/// <returns>The <see cref="OpenIddictEntityFrameworkCoreBuilder"/>.</returns>
public OpenIddictEntityFrameworkCoreBuilder UseDbContext([NotNull] Type type)
{
if (type == null)
{
throw new ArgumentNullException(nameof(type));
}
if (!typeof(DbContext).IsAssignableFrom(type))
{
throw new ArgumentException("The specified type is invalid.", nameof(type));
}
return Configure(options => options.DbContextType = type);
}
/// <summary> /// <summary>
/// Configures OpenIddict to use the default OpenIddict /// Configures OpenIddict to use the default OpenIddict
/// Entity Framework Core entities, with the specified key type. /// Entity Framework Core entities, with the specified key type.
@ -119,5 +91,34 @@ namespace Microsoft.Extensions.DependencyInjection
return this; return this;
} }
/// <summary>
/// Configures the OpenIddict Entity Framework Core stores to use the specified database context type.
/// </summary>
/// <typeparam name="TContext">The type of the <see cref="DbContext"/> used by OpenIddict.</typeparam>
/// <returns>The <see cref="OpenIddictEntityFrameworkCoreBuilder"/>.</returns>
public OpenIddictEntityFrameworkCoreBuilder UseDbContext<TContext>()
where TContext : DbContext
=> UseDbContext(typeof(TContext));
/// <summary>
/// Configures the OpenIddict Entity Framework Core stores to use the specified database context type.
/// </summary>
/// <param name="type">The type of the <see cref="DbContext"/> used by OpenIddict.</param>
/// <returns>The <see cref="OpenIddictEntityFrameworkCoreBuilder"/>.</returns>
public OpenIddictEntityFrameworkCoreBuilder UseDbContext([NotNull] Type type)
{
if (type == null)
{
throw new ArgumentNullException(nameof(type));
}
if (!typeof(DbContext).IsAssignableFrom(type))
{
throw new ArgumentException("The specified type is invalid.", nameof(type));
}
return Configure(options => options.DbContextType = type);
}
} }
} }

2
src/OpenIddict.EntityFrameworkCore/Resolvers/OpenIddictScopeStoreResolver.cs

@ -55,7 +55,7 @@ namespace OpenIddict.EntityFrameworkCore
throw new InvalidOperationException(new StringBuilder() throw new InvalidOperationException(new StringBuilder()
.AppendLine("The specified scope type is not compatible with the Entity Framework Core stores.") .AppendLine("The specified scope type is not compatible with the Entity Framework Core stores.")
.Append("When enabling the Entity Framework Core stores, make sure you use the built-in ") .Append("When enabling the Entity Framework Core stores, make sure you use the built-in ")
.Append("'OpenIdScope' entity (from the 'OpenIddict.EntityFrameworkCore.Models' package) ") .Append("'OpenIddictScope' entity (from the 'OpenIddict.EntityFrameworkCore.Models' package) ")
.Append("or a custom entity that inherits from the generic 'OpenIddictScope' entity.") .Append("or a custom entity that inherits from the generic 'OpenIddictScope' entity.")
.ToString()); .ToString());
} }

32
src/OpenIddict.MongoDb/OpenIddictMongoDbBuilder.cs

@ -57,22 +57,6 @@ namespace Microsoft.Extensions.DependencyInjection
return this; return this;
} }
/// <summary>
/// Configures the MongoDB stores to use the specified database
/// instead of retrieving it from the dependency injection container.
/// </summary>
/// <param name="database">The <see cref="IMongoDatabase"/>.</param>
/// <returns>The <see cref="OpenIddictMongoDbBuilder"/>.</returns>
public OpenIddictMongoDbBuilder UseDatabase([NotNull] IMongoDatabase database)
{
if (database == null)
{
throw new ArgumentNullException(nameof(database));
}
return Configure(options => options.Database = database);
}
/// <summary> /// <summary>
/// Configures OpenIddict to use the specified entity as the default application entity. /// Configures OpenIddict to use the specified entity as the default application entity.
/// </summary> /// </summary>
@ -180,5 +164,21 @@ namespace Microsoft.Extensions.DependencyInjection
return Configure(options => options.TokensCollectionName = name); return Configure(options => options.TokensCollectionName = name);
} }
/// <summary>
/// Configures the MongoDB stores to use the specified database
/// instead of retrieving it from the dependency injection container.
/// </summary>
/// <param name="database">The <see cref="IMongoDatabase"/>.</param>
/// <returns>The <see cref="OpenIddictMongoDbBuilder"/>.</returns>
public OpenIddictMongoDbBuilder UseDatabase([NotNull] IMongoDatabase database)
{
if (database == null)
{
throw new ArgumentNullException(nameof(database));
}
return Configure(options => options.Database = database);
}
} }
} }

5
src/OpenIddict.Mvc/OpenIddictMvcExtensions.cs

@ -60,6 +60,11 @@ namespace Microsoft.Extensions.DependencyInjection
throw new ArgumentNullException(nameof(builder)); throw new ArgumentNullException(nameof(builder));
} }
if (configuration == null)
{
throw new ArgumentNullException(nameof(configuration));
}
configuration(builder.UseMvc()); configuration(builder.UseMvc());
return builder; return builder;

3
src/OpenIddict.Server/OpenIddict.Server.csproj

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\build\packages.props" /> <Import Project="..\..\build\packages.props" />
@ -21,6 +21,7 @@
<PackageReference Include="JetBrains.Annotations" Version="$(JetBrainsVersion)" PrivateAssets="All" /> <PackageReference Include="JetBrains.Annotations" Version="$(JetBrainsVersion)" PrivateAssets="All" />
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.Abstractions" Version="$(AspNetCoreVersion)" /> <PackageReference Include="Microsoft.AspNetCore.Diagnostics.Abstractions" Version="$(AspNetCoreVersion)" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="$(AspNetCoreVersion)" /> <PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="$(AspNetCoreVersion)" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="$(AspNetCoreVersion)" />
<PackageReference Include="Newtonsoft.Json.Bson" Version="$(JsonNetBsonVersion)" /> <PackageReference Include="Newtonsoft.Json.Bson" Version="$(JsonNetBsonVersion)" />
</ItemGroup> </ItemGroup>

1
src/OpenIddict.Server/OpenIddictServerExtensions.cs

@ -34,6 +34,7 @@ namespace Microsoft.Extensions.DependencyInjection
builder.Services.AddAuthentication(); builder.Services.AddAuthentication();
builder.Services.AddDistributedMemoryCache(); builder.Services.AddDistributedMemoryCache();
builder.Services.AddLogging();
builder.Services.AddMemoryCache(); builder.Services.AddMemoryCache();
builder.Services.AddOptions(); builder.Services.AddOptions();

1
src/OpenIddict.Validation/OpenIddict.Validation.csproj

@ -19,6 +19,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="AspNet.Security.OAuth.Validation" Version="$(AspNetContribOpenIdExtensionsVersion)" /> <PackageReference Include="AspNet.Security.OAuth.Validation" Version="$(AspNetContribOpenIdExtensionsVersion)" />
<PackageReference Include="JetBrains.Annotations" Version="$(JetBrainsVersion)" PrivateAssets="All" /> <PackageReference Include="JetBrains.Annotations" Version="$(JetBrainsVersion)" PrivateAssets="All" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="$(AspNetCoreVersion)" />
</ItemGroup> </ItemGroup>
</Project> </Project>

1
src/OpenIddict.Validation/OpenIddictValidationExtensions.cs

@ -33,6 +33,7 @@ namespace Microsoft.Extensions.DependencyInjection
} }
builder.Services.AddAuthentication(); builder.Services.AddAuthentication();
builder.Services.AddLogging();
builder.Services.AddOptions(); builder.Services.AddOptions();
builder.Services.TryAddScoped<IOpenIddictValidationEventService, OpenIddictValidationEventService>(); builder.Services.TryAddScoped<IOpenIddictValidationEventService, OpenIddictValidationEventService>();

26
test/OpenIddict.Abstractions.Tests/OpenIddict.Abstractions.Tests.csproj

@ -0,0 +1,26 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\build\common.props" />
<PropertyGroup>
<TargetFrameworks>netcoreapp2.0;net461</TargetFrameworks>
<TargetFrameworks Condition=" '$(OS)' != 'Windows_NT' ">netcoreapp2.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\OpenIddict.Abstractions\OpenIddict.Abstractions.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="$(AspNetCoreVersion)" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(TestSdkVersion)" />
<PackageReference Include="Moq" Version="$(MoqVersion)" />
<PackageReference Include="xunit" Version="$(XunitVersion)" />
<PackageReference Include="xunit.runner.visualstudio" Version="$(XunitVersion)" />
</ItemGroup>
<ItemGroup>
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
</ItemGroup>
</Project>

27
test/OpenIddict.Abstractions.Tests/OpenIddictBuilderTests.cs

@ -0,0 +1,27 @@
/*
* Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
* See https://github.com/openiddict/openiddict-core for more information concerning
* the license and the contributors participating to this project.
*/
using System;
using Microsoft.Extensions.DependencyInjection;
using Xunit;
namespace OpenIddict.Abstractions.Tests
{
public class OpenIddictBuilderTests
{
[Fact]
public void Constructor_ThrowsAnExceptionForNullServices()
{
// Arrange
var services = (IServiceCollection) null;
// Act and assert
var exception = Assert.Throws<ArgumentNullException>(() => new OpenIddictBuilder(services));
Assert.Equal("services", exception.ParamName);
}
}
}

39
test/OpenIddict.Abstractions.Tests/OpenIddictExtensionsTests.cs

@ -0,0 +1,39 @@
/*
* Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
* See https://github.com/openiddict/openiddict-core for more information concerning
* the license and the contributors participating to this project.
*/
using System;
using Microsoft.Extensions.DependencyInjection;
using Xunit;
namespace OpenIddict.Abstractions.Tests
{
public class OpenIddictExtensionsTests
{
[Fact]
public void AddOpenIddict_ThrowsAnExceptionForNullServices()
{
// Arrange
var services = (IServiceCollection) null;
// Act and assert
var exception = Assert.Throws<ArgumentNullException>(() => services.AddOpenIddict());
Assert.Equal("services", exception.ParamName);
}
[Fact]
public void AddOpenIddict_ThrowsAnExceptionForNullConfigurationDelegate()
{
// Arrange
var services = new ServiceCollection();
// Act and assert
var exception = Assert.Throws<ArgumentNullException>(() => services.AddOpenIddict(configuration: null));
Assert.Equal("configuration", exception.ParamName);
}
}
}

12
test/OpenIddict.Core.Tests/OpenIddictCoreBuilderTests.cs

@ -16,6 +16,18 @@ namespace OpenIddict.Core.Tests
{ {
public class OpenIddictCoreBuilderTests public class OpenIddictCoreBuilderTests
{ {
[Fact]
public void Constructor_ThrowsAnExceptionForNullServices()
{
// Arrange
var services = (IServiceCollection) null;
// Act and assert
var exception = Assert.Throws<ArgumentNullException>(() => new OpenIddictCoreBuilder(services));
Assert.Equal("services", exception.ParamName);
}
[Fact] [Fact]
public void ReplaceApplicationManager_ThrowsAnExceptionForInvalidManager() public void ReplaceApplicationManager_ThrowsAnExceptionForInvalidManager()
{ {

321
test/OpenIddict.Core.Tests/OpenIddictCoreExtensionsTests.cs

@ -0,0 +1,321 @@
/*
* Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
* See https://github.com/openiddict/openiddict-core for more information concerning
* the license and the contributors participating to this project.
*/
using System;
using System.Text;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Moq;
using OpenIddict.Abstractions;
using Xunit;
namespace OpenIddict.Core.Tests
{
public class OpenIddictCoreExtensionsTests
{
[Fact]
public void AddCore_ThrowsAnExceptionForNullBuilder()
{
// Arrange
var builder = (OpenIddictBuilder) null;
// Act and assert
var exception = Assert.Throws<ArgumentNullException>(() => builder.AddCore());
Assert.Equal("builder", exception.ParamName);
}
[Fact]
public void AddCore_ThrowsAnExceptionForNullConfiguration()
{
// Arrange
var services = new ServiceCollection();
var builder = new OpenIddictBuilder(services);
// Act and assert
var exception = Assert.Throws<ArgumentNullException>(() => builder.AddCore(configuration: null));
Assert.Equal("configuration", exception.ParamName);
}
[Fact]
public void AddCore_RegistersLoggingServices()
{
// Arrange
var services = new ServiceCollection();
var builder = new OpenIddictBuilder(services);
// Act
builder.AddCore();
// Assert
Assert.Contains(services, service => service.ServiceType == typeof(ILogger<>));
}
[Fact]
public void AddCore_RegistersOptionsServices()
{
// Arrange
var services = new ServiceCollection();
var builder = new OpenIddictBuilder(services);
// Act
builder.AddCore();
// Assert
Assert.Contains(services, service => service.ServiceType == typeof(IOptions<>));
}
[Theory]
[InlineData(typeof(OpenIddictApplicationManager<>))]
[InlineData(typeof(OpenIddictAuthorizationManager<>))]
[InlineData(typeof(OpenIddictScopeManager<>))]
[InlineData(typeof(OpenIddictTokenManager<>))]
public void AddCore_RegistersDefaultManagers(Type type)
{
// Arrange
var services = new ServiceCollection();
var builder = new OpenIddictBuilder(services);
// Act
builder.AddCore();
// Assert
Assert.Contains(services, service => service.ServiceType == type && service.ImplementationType == type);
}
[Theory]
[InlineData(typeof(IOpenIddictApplicationStoreResolver), typeof(OpenIddictApplicationStoreResolver))]
[InlineData(typeof(IOpenIddictAuthorizationStoreResolver), typeof(OpenIddictAuthorizationStoreResolver))]
[InlineData(typeof(IOpenIddictScopeStoreResolver), typeof(OpenIddictScopeStoreResolver))]
[InlineData(typeof(IOpenIddictTokenStoreResolver), typeof(OpenIddictTokenStoreResolver))]
public void AddCore_RegistersDefaultResolvers(Type serviceType, Type implementationType)
{
// Arrange
var services = new ServiceCollection();
var builder = new OpenIddictBuilder(services);
// Act
builder.AddCore();
// Assert
Assert.Contains(services, service => service.ServiceType == serviceType &&
service.ImplementationType == implementationType);
}
[Theory]
[InlineData(typeof(IOpenIddictApplicationManager))]
[InlineData(typeof(IOpenIddictAuthorizationManager))]
[InlineData(typeof(IOpenIddictScopeManager))]
[InlineData(typeof(IOpenIddictTokenManager))]
public void AddCore_RegistersUntypedProxies(Type type)
{
// Arrange
var services = new ServiceCollection();
var builder = new OpenIddictBuilder(services);
// Act
builder.AddCore();
// Assert
Assert.Contains(services, service => service.ServiceType == type && service.ImplementationFactory != null);
}
[Fact]
public void AddCore_ResolvingUntypedApplicationManagerThrowsAnExceptionWhenDefaultEntityIsNotSet()
{
// Arrange
var services = new ServiceCollection();
var builder = new OpenIddictBuilder(services);
// Act
builder.AddCore();
// Assert
var provider = services.BuildServiceProvider();
var exception = Assert.Throws<InvalidOperationException>(delegate
{
return provider.GetRequiredService<IOpenIddictApplicationManager>();
});
Assert.Equal(new StringBuilder()
.Append("No default application entity type was configured in the OpenIddict core options, ")
.AppendLine("which generally indicates that no application store was registered in the DI container.")
.Append("To register the Entity Framework Core stores, reference the 'OpenIddict.EntityFrameworkCore' ")
.Append("package and call 'services.AddOpenIddict().AddCore().UseEntityFrameworkCore()'.")
.ToString(), exception.Message);
}
[Fact]
public void AddCore_ResolvingUntypedAuthorizationManagerThrowsAnExceptionWhenDefaultEntityIsNotSet()
{
// Arrange
var services = new ServiceCollection();
var builder = new OpenIddictBuilder(services);
// Act
builder.AddCore();
// Assert
var provider = services.BuildServiceProvider();
var exception = Assert.Throws<InvalidOperationException>(delegate
{
return provider.GetRequiredService<IOpenIddictAuthorizationManager>();
});
Assert.Equal(new StringBuilder()
.Append("No default authorization entity type was configured in the OpenIddict core options, ")
.AppendLine("which generally indicates that no authorization store was registered in the DI container.")
.Append("To register the Entity Framework Core stores, reference the 'OpenIddict.EntityFrameworkCore' ")
.Append("package and call 'services.AddOpenIddict().AddCore().UseEntityFrameworkCore()'.")
.ToString(), exception.Message);
}
[Fact]
public void AddCore_ResolvingUntypedScopeManagerThrowsAnExceptionWhenDefaultEntityIsNotSet()
{
// Arrange
var services = new ServiceCollection();
var builder = new OpenIddictBuilder(services);
// Act
builder.AddCore();
// Assert
var provider = services.BuildServiceProvider();
var exception = Assert.Throws<InvalidOperationException>(delegate
{
return provider.GetRequiredService<IOpenIddictScopeManager>();
});
Assert.Equal(new StringBuilder()
.Append("No default scope entity type was configured in the OpenIddict core options, ")
.AppendLine("which generally indicates that no scope store was registered in the DI container.")
.Append("To register the Entity Framework Core stores, reference the 'OpenIddict.EntityFrameworkCore' ")
.Append("package and call 'services.AddOpenIddict().AddCore().UseEntityFrameworkCore()'.")
.ToString(), exception.Message);
}
[Fact]
public void AddCore_ResolvingUntypedTokenManagerThrowsAnExceptionWhenDefaultEntityIsNotSet()
{
// Arrange
var services = new ServiceCollection();
var builder = new OpenIddictBuilder(services);
// Act
builder.AddCore();
// Assert
var provider = services.BuildServiceProvider();
var exception = Assert.Throws<InvalidOperationException>(delegate
{
return provider.GetRequiredService<IOpenIddictTokenManager>();
});
Assert.Equal(new StringBuilder()
.Append("No default token entity type was configured in the OpenIddict core options, ")
.AppendLine("which generally indicates that no token store was registered in the DI container.")
.Append("To register the Entity Framework Core stores, reference the 'OpenIddict.EntityFrameworkCore' ")
.Append("package and call 'services.AddOpenIddict().AddCore().UseEntityFrameworkCore()'.")
.ToString(), exception.Message);
}
[Fact]
public void AddCore_ResolvingUntypedApplicationManagerReturnsGenericManager()
{
// Arrange
var services = new ServiceCollection();
var builder = new OpenIddictBuilder(services);
// Act
builder.AddCore(options =>
{
options.SetDefaultApplicationEntity<OpenIddictApplication>();
options.Services.AddSingleton(Mock.Of<IOpenIddictApplicationStore<OpenIddictApplication>>());
});
var provider = services.BuildServiceProvider();
var manager = provider.GetRequiredService<IOpenIddictApplicationManager>();
// Assert
Assert.IsType<OpenIddictApplicationManager<OpenIddictApplication>>(manager);
}
[Fact]
public void AddCore_ResolvingUntypedAuthorizationManagerReturnsGenericManager()
{
// Arrange
var services = new ServiceCollection();
var builder = new OpenIddictBuilder(services);
// Act
builder.AddCore(options =>
{
options.SetDefaultAuthorizationEntity<OpenIddictAuthorization>();
options.Services.AddSingleton(Mock.Of<IOpenIddictAuthorizationStore<OpenIddictAuthorization>>());
});
var provider = services.BuildServiceProvider();
var manager = provider.GetRequiredService<IOpenIddictAuthorizationManager>();
// Assert
Assert.IsType<OpenIddictAuthorizationManager<OpenIddictAuthorization>>(manager);
}
[Fact]
public void AddCore_ResolvingUntypedScopeManagerReturnsGenericManager()
{
// Arrange
var services = new ServiceCollection();
var builder = new OpenIddictBuilder(services);
// Act
builder.AddCore(options =>
{
options.SetDefaultScopeEntity<OpenIddictScope>();
options.Services.AddSingleton(Mock.Of<IOpenIddictScopeStore<OpenIddictScope>>());
});
var provider = services.BuildServiceProvider();
var manager = provider.GetRequiredService<IOpenIddictScopeManager>();
// Assert
Assert.IsType<OpenIddictScopeManager<OpenIddictScope>>(manager);
}
[Fact]
public void AddCore_ResolvingUntypedTokenManagerReturnsGenericManager()
{
// Arrange
var services = new ServiceCollection();
var builder = new OpenIddictBuilder(services);
// Act
builder.AddCore(options =>
{
options.SetDefaultTokenEntity<OpenIddictToken>();
options.Services.AddSingleton(Mock.Of<IOpenIddictTokenStore<OpenIddictToken>>());
});
var provider = services.BuildServiceProvider();
var manager = provider.GetRequiredService<IOpenIddictTokenManager>();
// Assert
Assert.IsType<OpenIddictTokenManager<OpenIddictToken>>(manager);
}
public class OpenIddictApplication { }
public class OpenIddictAuthorization { }
public class OpenIddictScope { }
public class OpenIddictToken { }
}
}

54
test/OpenIddict.Core.Tests/Resolvers/OpenIddictApplicationStoreResolverTests.cs

@ -0,0 +1,54 @@
/*
* Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
* See https://github.com/openiddict/openiddict-core for more information concerning
* the license and the contributors participating to this project.
*/
using System;
using System.Text;
using Microsoft.Extensions.DependencyInjection;
using Moq;
using OpenIddict.Abstractions;
using Xunit;
namespace OpenIddict.Core.Tests
{
public class OpenIddictApplicationStoreResolverTests
{
[Fact]
public void Get_ThrowsAnExceptionWhenStoreCannotBeFound()
{
// Arrange
var services = new ServiceCollection();
var provider = services.BuildServiceProvider();
var resolver = new OpenIddictApplicationStoreResolver(provider);
// Act and assert
var exception = Assert.Throws<InvalidOperationException>(() => resolver.Get<OpenIddictApplication>());
Assert.Equal(new StringBuilder()
.AppendLine("No application store has been registered in the dependency injection container.")
.Append("To register the Entity Framework Core stores, reference the 'OpenIddict.EntityFrameworkCore' ")
.AppendLine("package and call 'services.AddOpenIddict().AddCore().UseEntityFrameworkCore()'.")
.Append("To register a custom store, create an implementation of 'IOpenIddictApplicationStore' and ")
.Append("use 'services.AddOpenIddict().AddCore().AddApplicationStore()' to add it to the DI container.")
.ToString(), exception.Message);
}
[Fact]
public void Get_ReturnsCustomStoreCorrespondingToTheSpecifiedType()
{
// Arrange
var services = new ServiceCollection();
services.AddSingleton(Mock.Of<IOpenIddictApplicationStore<OpenIddictApplication>>());
var provider = services.BuildServiceProvider();
var resolver = new OpenIddictApplicationStoreResolver(provider);
// Act and assert
Assert.NotNull(resolver.Get<OpenIddictApplication>());
}
public class OpenIddictApplication { }
}
}

54
test/OpenIddict.Core.Tests/Resolvers/OpenIddictAuthorizationStoreResolverTests.cs

@ -0,0 +1,54 @@
/*
* Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
* See https://github.com/openiddict/openiddict-core for more information concerning
* the license and the contributors participating to this project.
*/
using System;
using System.Text;
using Microsoft.Extensions.DependencyInjection;
using Moq;
using OpenIddict.Abstractions;
using Xunit;
namespace OpenIddict.Core.Tests
{
public class OpenIddictAuthorizationStoreResolverTests
{
[Fact]
public void Get_ThrowsAnExceptionWhenStoreCannotBeFound()
{
// Arrange
var services = new ServiceCollection();
var provider = services.BuildServiceProvider();
var resolver = new OpenIddictAuthorizationStoreResolver(provider);
// Act and assert
var exception = Assert.Throws<InvalidOperationException>(() => resolver.Get<OpenIddictAuthorization>());
Assert.Equal(new StringBuilder()
.AppendLine("No authorization store has been registered in the dependency injection container.")
.Append("To register the Entity Framework Core stores, reference the 'OpenIddict.EntityFrameworkCore' ")
.AppendLine("package and call 'services.AddOpenIddict().AddCore().UseEntityFrameworkCore()'.")
.Append("To register a custom store, create an implementation of 'IOpenIddictAuthorizationStore' and ")
.Append("use 'services.AddOpenIddict().AddCore().AddAuthorizationStore()' to add it to the DI container.")
.ToString(), exception.Message);
}
[Fact]
public void Get_ReturnsCustomStoreCorrespondingToTheSpecifiedType()
{
// Arrange
var services = new ServiceCollection();
services.AddSingleton(Mock.Of<IOpenIddictAuthorizationStore<OpenIddictAuthorization>>());
var provider = services.BuildServiceProvider();
var resolver = new OpenIddictAuthorizationStoreResolver(provider);
// Act and assert
Assert.NotNull(resolver.Get<OpenIddictAuthorization>());
}
public class OpenIddictAuthorization { }
}
}

54
test/OpenIddict.Core.Tests/Resolvers/OpenIddictScopeStoreResolverTests.cs

@ -0,0 +1,54 @@
/*
* Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
* See https://github.com/openiddict/openiddict-core for more information concerning
* the license and the contributors participating to this project.
*/
using System;
using System.Text;
using Microsoft.Extensions.DependencyInjection;
using Moq;
using OpenIddict.Abstractions;
using Xunit;
namespace OpenIddict.Core.Tests
{
public class OpenIddictScopeStoreResolverTests
{
[Fact]
public void Get_ThrowsAnExceptionWhenStoreCannotBeFound()
{
// Arrange
var services = new ServiceCollection();
var provider = services.BuildServiceProvider();
var resolver = new OpenIddictScopeStoreResolver(provider);
// Act and assert
var exception = Assert.Throws<InvalidOperationException>(() => resolver.Get<OpenIddictScope>());
Assert.Equal(new StringBuilder()
.AppendLine("No scope store has been registered in the dependency injection container.")
.Append("To register the Entity Framework Core stores, reference the 'OpenIddict.EntityFrameworkCore' ")
.AppendLine("package and call 'services.AddOpenIddict().AddCore().UseEntityFrameworkCore()'.")
.Append("To register a custom store, create an implementation of 'IOpenIddictScopeStore' and ")
.Append("use 'services.AddOpenIddict().AddCore().AddScopeStore()' to add it to the DI container.")
.ToString(), exception.Message);
}
[Fact]
public void Get_ReturnsCustomStoreCorrespondingToTheSpecifiedType()
{
// Arrange
var services = new ServiceCollection();
services.AddSingleton(Mock.Of<IOpenIddictScopeStore<OpenIddictScope>>());
var provider = services.BuildServiceProvider();
var resolver = new OpenIddictScopeStoreResolver(provider);
// Act and assert
Assert.NotNull(resolver.Get<OpenIddictScope>());
}
public class OpenIddictScope { }
}
}

54
test/OpenIddict.Core.Tests/Resolvers/OpenIddictTokenStoreResolverTests.cs

@ -0,0 +1,54 @@
/*
* Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
* See https://github.com/openiddict/openiddict-core for more information concerning
* the license and the contributors participating to this project.
*/
using System;
using System.Text;
using Microsoft.Extensions.DependencyInjection;
using Moq;
using OpenIddict.Abstractions;
using Xunit;
namespace OpenIddict.Core.Tests
{
public class OpenIddictTokenStoreResolverTests
{
[Fact]
public void Get_ThrowsAnExceptionWhenStoreCannotBeFound()
{
// Arrange
var services = new ServiceCollection();
var provider = services.BuildServiceProvider();
var resolver = new OpenIddictTokenStoreResolver(provider);
// Act and assert
var exception = Assert.Throws<InvalidOperationException>(() => resolver.Get<OpenIddictToken>());
Assert.Equal(new StringBuilder()
.AppendLine("No token store has been registered in the dependency injection container.")
.Append("To register the Entity Framework Core stores, reference the 'OpenIddict.EntityFrameworkCore' ")
.AppendLine("package and call 'services.AddOpenIddict().AddCore().UseEntityFrameworkCore()'.")
.Append("To register a custom store, create an implementation of 'IOpenIddictTokenStore' and ")
.Append("use 'services.AddOpenIddict().AddCore().AddTokenStore()' to add it to the DI container.")
.ToString(), exception.Message);
}
[Fact]
public void Get_ReturnsCustomStoreCorrespondingToTheSpecifiedType()
{
// Arrange
var services = new ServiceCollection();
services.AddSingleton(Mock.Of<IOpenIddictTokenStore<OpenIddictToken>>());
var provider = services.BuildServiceProvider();
var resolver = new OpenIddictTokenStoreResolver(provider);
// Act and assert
Assert.NotNull(resolver.Get<OpenIddictToken>());
}
public class OpenIddictToken { }
}
}

141
test/OpenIddict.EntityFramework.Tests/OpenIddictEntityFrameworkBuilderTests.cs

@ -0,0 +1,141 @@
/*
* Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
* See https://github.com/openiddict/openiddict-core for more information concerning
* the license and the contributors participating to this project.
*/
using System;
using System.Data.Entity;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using OpenIddict.Core;
using OpenIddict.EntityFramework.Models;
using Xunit;
namespace OpenIddict.EntityFramework.Tests
{
public class OpenIddictEntityFrameworkBuilderTests
{
[Fact]
public void Constructor_ThrowsAnExceptionForNullServices()
{
// Arrange
var services = (IServiceCollection) null;
// Act and assert
var exception = Assert.Throws<ArgumentNullException>(() => new OpenIddictEntityFrameworkBuilder(services));
Assert.Equal("services", exception.ParamName);
}
[Fact]
public void ReplaceDefaultEntities_EntitiesAreCorrectlyReplaced()
{
// Arrange
var services = CreateServices();
var builder = CreateBuilder(services);
// Act
builder.ReplaceDefaultEntities<CustomApplication, CustomAuthorization, CustomScope, CustomToken, long>();
// Assert
var provider = services.BuildServiceProvider();
var options = provider.GetRequiredService<IOptionsMonitor<OpenIddictCoreOptions>>().CurrentValue;
Assert.Equal(typeof(CustomApplication), options.DefaultApplicationType);
Assert.Equal(typeof(CustomAuthorization), options.DefaultAuthorizationType);
Assert.Equal(typeof(CustomScope), options.DefaultScopeType);
Assert.Equal(typeof(CustomToken), options.DefaultTokenType);
}
[Fact]
public void UseDbContext_ThrowsAnExceptionForNullType()
{
// Arrange
var services = CreateServices();
var builder = CreateBuilder(services);
// Act and assert
var exception = Assert.Throws<ArgumentNullException>(delegate
{
return builder.UseDbContext(type: null);
});
Assert.Equal("type", exception.ParamName);
}
[Fact]
public void UseDbContext_ThrowsAnExceptionForInvalidType()
{
// Arrange
var services = CreateServices();
var builder = CreateBuilder(services);
// Act and assert
var exception = Assert.Throws<ArgumentException>(delegate
{
return builder.UseDbContext(typeof(object));
});
Assert.Equal("type", exception.ParamName);
Assert.StartsWith("The specified type is invalid.", exception.Message);
}
[Fact]
public void UseDbContext_RegistersDbContextAsScopedService()
{
// Arrange
var services = CreateServices();
var builder = CreateBuilder(services);
// Act
builder.UseDbContext<CustomDbContext>();
// Assert
Assert.Contains(services, service => service.Lifetime == ServiceLifetime.Scoped &&
service.ServiceType == typeof(CustomDbContext) &&
service.ImplementationType == typeof(CustomDbContext));
}
[Fact]
public void UseDbContext_SetsDbContextTypeInOptions()
{
// Arrange
var services = CreateServices();
var builder = CreateBuilder(services);
// Act
builder.UseDbContext<CustomDbContext>();
// Assert
var provider = services.BuildServiceProvider();
var options = provider.GetRequiredService<IOptionsMonitor<OpenIddictEntityFrameworkOptions>>().CurrentValue;
Assert.Equal(typeof(CustomDbContext), options.DbContextType);
}
private static OpenIddictEntityFrameworkBuilder CreateBuilder(IServiceCollection services)
=> services.AddOpenIddict().AddCore().UseEntityFramework();
private static IServiceCollection CreateServices()
{
var services = new ServiceCollection();
services.AddOptions();
return services;
}
public class CustomApplication : OpenIddictApplication<long, CustomAuthorization, CustomToken> { }
public class CustomAuthorization : OpenIddictAuthorization<long, CustomApplication, CustomToken> { }
public class CustomScope : OpenIddictScope<long> { }
public class CustomToken : OpenIddictToken<long, CustomApplication, CustomAuthorization> { }
public class CustomDbContext : DbContext
{
public CustomDbContext(string nameOrConnectionString)
: base(nameOrConnectionString)
{
}
}
}
}

78
test/OpenIddict.EntityFramework.Tests/OpenIddictEntityFrameworkExtensionsTests.cs

@ -5,8 +5,10 @@
*/ */
using System; using System;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using OpenIddict.Abstractions;
using OpenIddict.Core; using OpenIddict.Core;
using OpenIddict.EntityFramework.Models; using OpenIddict.EntityFramework.Models;
using Xunit; using Xunit;
@ -15,26 +17,47 @@ namespace OpenIddict.EntityFramework.Tests
{ {
public class OpenIddictEntityFrameworkExtensionsTests public class OpenIddictEntityFrameworkExtensionsTests
{ {
[Theory] [Fact]
[InlineData(typeof(OpenIddictApplicationStoreResolver))] public void UseEntityFramework_ThrowsAnExceptionForNullBuilder()
[InlineData(typeof(OpenIddictAuthorizationStoreResolver))]
[InlineData(typeof(OpenIddictScopeStoreResolver))]
[InlineData(typeof(OpenIddictTokenStoreResolver))]
public void AddEntityFrameworkStores_RegistersEntityFrameworkStoreFactories(Type type)
{ {
// Arrange // Arrange
var services = new ServiceCollection().AddOptions(); var builder = (OpenIddictCoreBuilder) null;
// Act and assert
var exception = Assert.Throws<ArgumentNullException>(() => builder.UseEntityFramework());
Assert.Equal("builder", exception.ParamName);
}
[Fact]
public void UseEntityFramework_ThrowsAnExceptionForNullConfiguration()
{
// Arrange
var services = new ServiceCollection();
var builder = new OpenIddictCoreBuilder(services);
// Act and assert
var exception = Assert.Throws<ArgumentNullException>(() => builder.UseEntityFramework(configuration: null));
Assert.Equal("configuration", exception.ParamName);
}
[Fact]
public void UseEntityFramework_RegistersCachingServices()
{
// Arrange
var services = new ServiceCollection();
var builder = new OpenIddictCoreBuilder(services); var builder = new OpenIddictCoreBuilder(services);
// Act // Act
builder.UseEntityFramework(); builder.UseEntityFramework();
// Assert // Assert
Assert.Contains(services, service => service.ImplementationType == type); Assert.Contains(services, service => service.ServiceType == typeof(IMemoryCache));
} }
[Fact] [Fact]
public void UseEntityFrameworkModels_KeyTypeDefaultsToString() public void UseEntityFramework_RegistersDefaultEntities()
{ {
// Arrange // Arrange
var services = new ServiceCollection().AddOptions(); var services = new ServiceCollection().AddOptions();
@ -52,5 +75,42 @@ namespace OpenIddict.EntityFramework.Tests
Assert.Equal(typeof(OpenIddictScope), options.DefaultScopeType); Assert.Equal(typeof(OpenIddictScope), options.DefaultScopeType);
Assert.Equal(typeof(OpenIddictToken), options.DefaultTokenType); Assert.Equal(typeof(OpenIddictToken), options.DefaultTokenType);
} }
[Theory]
[InlineData(typeof(IOpenIddictApplicationStoreResolver), typeof(OpenIddictApplicationStoreResolver))]
[InlineData(typeof(IOpenIddictAuthorizationStoreResolver), typeof(OpenIddictAuthorizationStoreResolver))]
[InlineData(typeof(IOpenIddictScopeStoreResolver), typeof(OpenIddictScopeStoreResolver))]
[InlineData(typeof(IOpenIddictTokenStoreResolver), typeof(OpenIddictTokenStoreResolver))]
public void UseEntityFramework_RegistersEntityFrameworkStoreResolvers(Type serviceType, Type implementationType)
{
// Arrange
var services = new ServiceCollection();
var builder = new OpenIddictCoreBuilder(services);
// Act
builder.UseEntityFramework();
// Assert
Assert.Contains(services, service => service.ServiceType == serviceType &&
service.ImplementationType == implementationType);
}
[Theory]
[InlineData(typeof(OpenIddictApplicationStore<,,,,>))]
[InlineData(typeof(OpenIddictAuthorizationStore<,,,,>))]
[InlineData(typeof(OpenIddictScopeStore<,,>))]
[InlineData(typeof(OpenIddictTokenStore<,,,,>))]
public void UseEntityFramework_RegistersEntityFrameworkStore(Type type)
{
// Arrange
var services = new ServiceCollection();
var builder = new OpenIddictCoreBuilder(services);
// Act
builder.UseEntityFramework();
// Assert
Assert.Contains(services, service => service.ServiceType == type && service.ImplementationType == type);
}
} }
} }

117
test/OpenIddict.EntityFramework.Tests/Resolvers/OpenIddictApplicationStoreResolverTests.cs

@ -0,0 +1,117 @@
/*
* Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
* See https://github.com/openiddict/openiddict-core for more information concerning
* the license and the contributors participating to this project.
*/
using System;
using System.Data.Entity;
using System.Text;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Moq;
using OpenIddict.Abstractions;
using OpenIddict.EntityFramework.Models;
using Xunit;
namespace OpenIddict.EntityFramework.Tests
{
public class OpenIddictApplicationStoreResolverTests
{
[Fact]
public void Get_ReturnsCustomStoreCorrespondingToTheSpecifiedTypeWhenAvailable()
{
// Arrange
var services = new ServiceCollection();
services.AddSingleton(Mock.Of<IOpenIddictApplicationStore<CustomApplication>>());
var monitor = Mock.Of<IOptionsMonitor<OpenIddictEntityFrameworkOptions>>();
var provider = services.BuildServiceProvider();
var resolver = new OpenIddictApplicationStoreResolver(monitor, provider);
// Act and assert
Assert.NotNull(resolver.Get<CustomApplication>());
}
[Fact]
public void Get_ThrowsAnExceptionForInvalidEntityType()
{
// Arrange
var services = new ServiceCollection();
var monitor = Mock.Of<IOptionsMonitor<OpenIddictEntityFrameworkOptions>>();
var provider = services.BuildServiceProvider();
var resolver = new OpenIddictApplicationStoreResolver(monitor, provider);
// Act and assert
var exception = Assert.Throws<InvalidOperationException>(() => resolver.Get<CustomApplication>());
Assert.Equal(new StringBuilder()
.AppendLine("The specified application type is not compatible with the Entity Framework 6.x stores.")
.Append("When enabling the Entity Framework 6.x stores, make sure you use the built-in ")
.Append("'OpenIddictApplication' entity (from the 'OpenIddict.EntityFramework.Models' package) ")
.Append("or a custom entity that inherits from the generic 'OpenIddictApplication' entity.")
.ToString(), exception.Message);
}
[Fact]
public void Get_ThrowsAnExceptionWhenDbContextTypeIsNotAvailable()
{
// Arrange
var services = new ServiceCollection();
var monitor = Mock.Of<IOptionsMonitor<OpenIddictEntityFrameworkOptions>>(
mock => mock.CurrentValue == new OpenIddictEntityFrameworkOptions
{
DbContextType = null
});
var provider = services.BuildServiceProvider();
var resolver = new OpenIddictApplicationStoreResolver(monitor, provider);
// Act and assert
var exception = Assert.Throws<InvalidOperationException>(() => resolver.Get<OpenIddictApplication>());
Assert.Equal(new StringBuilder()
.AppendLine("No Entity Framework 6.x context was specified in the OpenIddict options.")
.Append("To configure the OpenIddict Entity Framework 6.x stores to use a specific 'DbContext', ")
.Append("use 'options.UseEntityFramework().UseDbContext<TContext>()'.")
.ToString(), exception.Message);
}
[Fact]
public void Get_ReturnsDefaultStoreCorrespondingToTheSpecifiedTypeWhenAvailable()
{
// Arrange
var services = new ServiceCollection();
services.AddSingleton(Mock.Of<IOpenIddictApplicationStore<CustomApplication>>());
services.AddSingleton(CreateStore());
var monitor = Mock.Of<IOptionsMonitor<OpenIddictEntityFrameworkOptions>>(
mock => mock.CurrentValue == new OpenIddictEntityFrameworkOptions
{
DbContextType = typeof(DbContext)
});
var provider = services.BuildServiceProvider();
var resolver = new OpenIddictApplicationStoreResolver(monitor, provider);
// Act and assert
Assert.NotNull(resolver.Get<MyApplication>());
}
private static OpenIddictApplicationStore<MyApplication, MyAuthorization, MyToken, DbContext, long> CreateStore()
=> new Mock<OpenIddictApplicationStore<MyApplication, MyAuthorization, MyToken, DbContext, long>>(
Mock.Of<IMemoryCache>(),
Mock.Of<DbContext>(),
Mock.Of<IOptionsMonitor<OpenIddictEntityFrameworkOptions>>()).Object;
public class CustomApplication { }
public class MyApplication : OpenIddictApplication<long, MyAuthorization, MyToken> { }
public class MyAuthorization : OpenIddictAuthorization<long, MyApplication, MyToken> { }
public class MyScope : OpenIddictScope<long> { }
public class MyToken : OpenIddictToken<long, MyApplication, MyAuthorization> { }
}
}

117
test/OpenIddict.EntityFramework.Tests/Resolvers/OpenIddictAuthorizationStoreResolverTests.cs

@ -0,0 +1,117 @@
/*
* Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
* See https://github.com/openiddict/openiddict-core for more information concerning
* the license and the contributors participating to this project.
*/
using System;
using System.Data.Entity;
using System.Text;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Moq;
using OpenIddict.Abstractions;
using OpenIddict.EntityFramework.Models;
using Xunit;
namespace OpenIddict.EntityFramework.Tests
{
public class OpenIddictAuthorizationStoreResolverTests
{
[Fact]
public void Get_ReturnsCustomStoreCorrespondingToTheSpecifiedTypeWhenAvailable()
{
// Arrange
var services = new ServiceCollection();
services.AddSingleton(Mock.Of<IOpenIddictAuthorizationStore<CustomAuthorization>>());
var monitor = Mock.Of<IOptionsMonitor<OpenIddictEntityFrameworkOptions>>();
var provider = services.BuildServiceProvider();
var resolver = new OpenIddictAuthorizationStoreResolver(monitor, provider);
// Act and assert
Assert.NotNull(resolver.Get<CustomAuthorization>());
}
[Fact]
public void Get_ThrowsAnExceptionForInvalidEntityType()
{
// Arrange
var services = new ServiceCollection();
var monitor = Mock.Of<IOptionsMonitor<OpenIddictEntityFrameworkOptions>>();
var provider = services.BuildServiceProvider();
var resolver = new OpenIddictAuthorizationStoreResolver(monitor, provider);
// Act and assert
var exception = Assert.Throws<InvalidOperationException>(() => resolver.Get<CustomAuthorization>());
Assert.Equal(new StringBuilder()
.AppendLine("The specified authorization type is not compatible with the Entity Framework 6.x stores.")
.Append("When enabling the Entity Framework 6.x stores, make sure you use the built-in ")
.Append("'OpenIddictAuthorization' entity (from the 'OpenIddict.EntityFramework.Models' package) ")
.Append("or a custom entity that inherits from the generic 'OpenIddictAuthorization' entity.")
.ToString(), exception.Message);
}
[Fact]
public void Get_ThrowsAnExceptionWhenDbContextTypeIsNotAvailable()
{
// Arrange
var services = new ServiceCollection();
var monitor = Mock.Of<IOptionsMonitor<OpenIddictEntityFrameworkOptions>>(
mock => mock.CurrentValue == new OpenIddictEntityFrameworkOptions
{
DbContextType = null
});
var provider = services.BuildServiceProvider();
var resolver = new OpenIddictAuthorizationStoreResolver(monitor, provider);
// Act and assert
var exception = Assert.Throws<InvalidOperationException>(() => resolver.Get<OpenIddictAuthorization>());
Assert.Equal(new StringBuilder()
.AppendLine("No Entity Framework 6.x context was specified in the OpenIddict options.")
.Append("To configure the OpenIddict Entity Framework 6.x stores to use a specific 'DbContext', ")
.Append("use 'options.UseEntityFramework().UseDbContext<TContext>()'.")
.ToString(), exception.Message);
}
[Fact]
public void Get_ReturnsDefaultStoreCorrespondingToTheSpecifiedTypeWhenAvailable()
{
// Arrange
var services = new ServiceCollection();
services.AddSingleton(Mock.Of<IOpenIddictAuthorizationStore<CustomAuthorization>>());
services.AddSingleton(CreateStore());
var monitor = Mock.Of<IOptionsMonitor<OpenIddictEntityFrameworkOptions>>(
mock => mock.CurrentValue == new OpenIddictEntityFrameworkOptions
{
DbContextType = typeof(DbContext)
});
var provider = services.BuildServiceProvider();
var resolver = new OpenIddictAuthorizationStoreResolver(monitor, provider);
// Act and assert
Assert.NotNull(resolver.Get<MyAuthorization>());
}
private static OpenIddictAuthorizationStore<MyAuthorization, MyApplication, MyToken, DbContext, long> CreateStore()
=> new Mock<OpenIddictAuthorizationStore<MyAuthorization, MyApplication, MyToken, DbContext, long>>(
Mock.Of<IMemoryCache>(),
Mock.Of<DbContext>(),
Mock.Of<IOptionsMonitor<OpenIddictEntityFrameworkOptions>>()).Object;
public class CustomAuthorization { }
public class MyApplication : OpenIddictApplication<long, MyAuthorization, MyToken> { }
public class MyAuthorization : OpenIddictAuthorization<long, MyApplication, MyToken> { }
public class MyScope : OpenIddictScope<long> { }
public class MyToken : OpenIddictToken<long, MyApplication, MyAuthorization> { }
}
}

117
test/OpenIddict.EntityFramework.Tests/Resolvers/OpenIddictScopeStoreResolverTests.cs

@ -0,0 +1,117 @@
/*
* Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
* See https://github.com/openiddict/openiddict-core for more information concerning
* the license and the contributors participating to this project.
*/
using System;
using System.Data.Entity;
using System.Text;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Moq;
using OpenIddict.Abstractions;
using OpenIddict.EntityFramework.Models;
using Xunit;
namespace OpenIddict.EntityFramework.Tests
{
public class OpenIddictScopeStoreResolverTests
{
[Fact]
public void Get_ReturnsCustomStoreCorrespondingToTheSpecifiedTypeWhenAvailable()
{
// Arrange
var services = new ServiceCollection();
services.AddSingleton(Mock.Of<IOpenIddictScopeStore<CustomScope>>());
var monitor = Mock.Of<IOptionsMonitor<OpenIddictEntityFrameworkOptions>>();
var provider = services.BuildServiceProvider();
var resolver = new OpenIddictScopeStoreResolver(monitor, provider);
// Act and assert
Assert.NotNull(resolver.Get<CustomScope>());
}
[Fact]
public void Get_ThrowsAnExceptionForInvalidEntityType()
{
// Arrange
var services = new ServiceCollection();
var monitor = Mock.Of<IOptionsMonitor<OpenIddictEntityFrameworkOptions>>();
var provider = services.BuildServiceProvider();
var resolver = new OpenIddictScopeStoreResolver(monitor, provider);
// Act and assert
var exception = Assert.Throws<InvalidOperationException>(() => resolver.Get<CustomScope>());
Assert.Equal(new StringBuilder()
.AppendLine("The specified scope type is not compatible with the Entity Framework 6.x stores.")
.Append("When enabling the Entity Framework 6.x stores, make sure you use the built-in ")
.Append("'OpenIddictScope' entity (from the 'OpenIddict.EntityFramework.Models' package) ")
.Append("or a custom entity that inherits from the generic 'OpenIddictScope' entity.")
.ToString(), exception.Message);
}
[Fact]
public void Get_ThrowsAnExceptionWhenDbContextTypeIsNotAvailable()
{
// Arrange
var services = new ServiceCollection();
var monitor = Mock.Of<IOptionsMonitor<OpenIddictEntityFrameworkOptions>>(
mock => mock.CurrentValue == new OpenIddictEntityFrameworkOptions
{
DbContextType = null
});
var provider = services.BuildServiceProvider();
var resolver = new OpenIddictScopeStoreResolver(monitor, provider);
// Act and assert
var exception = Assert.Throws<InvalidOperationException>(() => resolver.Get<OpenIddictScope>());
Assert.Equal(new StringBuilder()
.AppendLine("No Entity Framework 6.x context was specified in the OpenIddict options.")
.Append("To configure the OpenIddict Entity Framework 6.x stores to use a specific 'DbContext', ")
.Append("use 'options.UseEntityFramework().UseDbContext<TContext>()'.")
.ToString(), exception.Message);
}
[Fact]
public void Get_ReturnsDefaultStoreCorrespondingToTheSpecifiedTypeWhenAvailable()
{
// Arrange
var services = new ServiceCollection();
services.AddSingleton(Mock.Of<IOpenIddictScopeStore<CustomScope>>());
services.AddSingleton(CreateStore());
var monitor = Mock.Of<IOptionsMonitor<OpenIddictEntityFrameworkOptions>>(
mock => mock.CurrentValue == new OpenIddictEntityFrameworkOptions
{
DbContextType = typeof(DbContext)
});
var provider = services.BuildServiceProvider();
var resolver = new OpenIddictScopeStoreResolver(monitor, provider);
// Act and assert
Assert.NotNull(resolver.Get<MyScope>());
}
private static OpenIddictScopeStore<MyScope, DbContext, long> CreateStore()
=> new Mock<OpenIddictScopeStore<MyScope, DbContext, long>>(
Mock.Of<IMemoryCache>(),
Mock.Of<DbContext>(),
Mock.Of<IOptionsMonitor<OpenIddictEntityFrameworkOptions>>()).Object;
public class CustomScope { }
public class MyApplication : OpenIddictApplication<long, MyAuthorization, MyToken> { }
public class MyAuthorization : OpenIddictAuthorization<long, MyApplication, MyToken> { }
public class MyScope : OpenIddictScope<long> { }
public class MyToken : OpenIddictToken<long, MyApplication, MyAuthorization> { }
}
}

117
test/OpenIddict.EntityFramework.Tests/Resolvers/OpenIddictTokenStoreResolverTests.cs

@ -0,0 +1,117 @@
/*
* Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
* See https://github.com/openiddict/openiddict-core for more information concerning
* the license and the contributors participating to this project.
*/
using System;
using System.Data.Entity;
using System.Text;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Moq;
using OpenIddict.Abstractions;
using OpenIddict.EntityFramework.Models;
using Xunit;
namespace OpenIddict.EntityFramework.Tests
{
public class OpenIddictTokenStoreResolverTests
{
[Fact]
public void Get_ReturnsCustomStoreCorrespondingToTheSpecifiedTypeWhenAvailable()
{
// Arrange
var services = new ServiceCollection();
services.AddSingleton(Mock.Of<IOpenIddictTokenStore<CustomToken>>());
var monitor = Mock.Of<IOptionsMonitor<OpenIddictEntityFrameworkOptions>>();
var provider = services.BuildServiceProvider();
var resolver = new OpenIddictTokenStoreResolver(monitor, provider);
// Act and assert
Assert.NotNull(resolver.Get<CustomToken>());
}
[Fact]
public void Get_ThrowsAnExceptionForInvalidEntityType()
{
// Arrange
var services = new ServiceCollection();
var monitor = Mock.Of<IOptionsMonitor<OpenIddictEntityFrameworkOptions>>();
var provider = services.BuildServiceProvider();
var resolver = new OpenIddictTokenStoreResolver(monitor, provider);
// Act and assert
var exception = Assert.Throws<InvalidOperationException>(() => resolver.Get<CustomToken>());
Assert.Equal(new StringBuilder()
.AppendLine("The specified token type is not compatible with the Entity Framework 6.x stores.")
.Append("When enabling the Entity Framework 6.x stores, make sure you use the built-in ")
.Append("'OpenIddictToken' entity (from the 'OpenIddict.EntityFramework.Models' package) ")
.Append("or a custom entity that inherits from the generic 'OpenIddictToken' entity.")
.ToString(), exception.Message);
}
[Fact]
public void Get_ThrowsAnExceptionWhenDbContextTypeIsNotAvailable()
{
// Arrange
var services = new ServiceCollection();
var monitor = Mock.Of<IOptionsMonitor<OpenIddictEntityFrameworkOptions>>(
mock => mock.CurrentValue == new OpenIddictEntityFrameworkOptions
{
DbContextType = null
});
var provider = services.BuildServiceProvider();
var resolver = new OpenIddictTokenStoreResolver(monitor, provider);
// Act and assert
var exception = Assert.Throws<InvalidOperationException>(() => resolver.Get<OpenIddictToken>());
Assert.Equal(new StringBuilder()
.AppendLine("No Entity Framework 6.x context was specified in the OpenIddict options.")
.Append("To configure the OpenIddict Entity Framework 6.x stores to use a specific 'DbContext', ")
.Append("use 'options.UseEntityFramework().UseDbContext<TContext>()'.")
.ToString(), exception.Message);
}
[Fact]
public void Get_ReturnsDefaultStoreCorrespondingToTheSpecifiedTypeWhenAvailable()
{
// Arrange
var services = new ServiceCollection();
services.AddSingleton(Mock.Of<IOpenIddictTokenStore<CustomToken>>());
services.AddSingleton(CreateStore());
var monitor = Mock.Of<IOptionsMonitor<OpenIddictEntityFrameworkOptions>>(
mock => mock.CurrentValue == new OpenIddictEntityFrameworkOptions
{
DbContextType = typeof(DbContext)
});
var provider = services.BuildServiceProvider();
var resolver = new OpenIddictTokenStoreResolver(monitor, provider);
// Act and assert
Assert.NotNull(resolver.Get<MyToken>());
}
private static OpenIddictTokenStore<MyToken, MyApplication, MyAuthorization, DbContext, long> CreateStore()
=> new Mock<OpenIddictTokenStore<MyToken, MyApplication, MyAuthorization, DbContext, long>>(
Mock.Of<IMemoryCache>(),
Mock.Of<DbContext>(),
Mock.Of<IOptionsMonitor<OpenIddictEntityFrameworkOptions>>()).Object;
public class CustomToken { }
public class MyApplication : OpenIddictApplication<long, MyAuthorization, MyToken> { }
public class MyAuthorization : OpenIddictAuthorization<long, MyApplication, MyToken> { }
public class MyScope : OpenIddictScope<long> { }
public class MyToken : OpenIddictToken<long, MyApplication, MyAuthorization> { }
}
}

145
test/OpenIddict.EntityFrameworkCore.Tests/OpenIddictEntityFrameworkCoreBuilderTests.cs

@ -0,0 +1,145 @@
/*
* Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
* See https://github.com/openiddict/openiddict-core for more information concerning
* the license and the contributors participating to this project.
*/
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using OpenIddict.Core;
using OpenIddict.EntityFrameworkCore.Models;
using Xunit;
namespace OpenIddict.EntityFrameworkCore.Tests
{
public class OpenIddictEntityFrameworkCoreBuilderTests
{
[Fact]
public void Constructor_ThrowsAnExceptionForNullServices()
{
// Arrange
var services = (IServiceCollection) null;
// Act and assert
var exception = Assert.Throws<ArgumentNullException>(() => new OpenIddictEntityFrameworkCoreBuilder(services));
Assert.Equal("services", exception.ParamName);
}
[Fact]
public void ReplaceDefaultEntities_EntitiesAreCorrectlyReplaced()
{
// Arrange
var services = CreateServices();
var builder = CreateBuilder(services);
// Act
builder.ReplaceDefaultEntities<CustomApplication, CustomAuthorization, CustomScope, CustomToken, long>();
// Assert
var provider = services.BuildServiceProvider();
var options = provider.GetRequiredService<IOptionsMonitor<OpenIddictCoreOptions>>().CurrentValue;
Assert.Equal(typeof(CustomApplication), options.DefaultApplicationType);
Assert.Equal(typeof(CustomAuthorization), options.DefaultAuthorizationType);
Assert.Equal(typeof(CustomScope), options.DefaultScopeType);
Assert.Equal(typeof(CustomToken), options.DefaultTokenType);
}
[Fact]
public void ReplaceDefaultEntities_AllowsSpecifyingCustomKeyType()
{
// Arrange
var services = CreateServices();
var builder = CreateBuilder(services);
// Act
builder.ReplaceDefaultEntities<long>();
// Assert
var provider = services.BuildServiceProvider();
var options = provider.GetRequiredService<IOptionsMonitor<OpenIddictCoreOptions>>().CurrentValue;
Assert.Equal(typeof(OpenIddictApplication<long>), options.DefaultApplicationType);
Assert.Equal(typeof(OpenIddictAuthorization<long>), options.DefaultAuthorizationType);
Assert.Equal(typeof(OpenIddictScope<long>), options.DefaultScopeType);
Assert.Equal(typeof(OpenIddictToken<long>), options.DefaultTokenType);
}
[Fact]
public void UseDbContext_ThrowsAnExceptionForNullType()
{
// Arrange
var services = CreateServices();
var builder = CreateBuilder(services);
// Act and assert
var exception = Assert.Throws<ArgumentNullException>(delegate
{
return builder.UseDbContext(type: null);
});
Assert.Equal("type", exception.ParamName);
}
[Fact]
public void UseDbContext_ThrowsAnExceptionForInvalidType()
{
// Arrange
var services = CreateServices();
var builder = CreateBuilder(services);
// Act and assert
var exception = Assert.Throws<ArgumentException>(delegate
{
return builder.UseDbContext(typeof(object));
});
Assert.Equal("type", exception.ParamName);
Assert.StartsWith("The specified type is invalid.", exception.Message);
}
[Fact]
public void UseDbContext_SetsDbContextTypeInOptions()
{
// Arrange
var services = CreateServices();
var builder = CreateBuilder(services);
// Act
builder.UseDbContext<CustomDbContext>();
// Assert
var provider = services.BuildServiceProvider();
var options = provider.GetRequiredService<IOptionsMonitor<OpenIddictEntityFrameworkCoreOptions>>().CurrentValue;
Assert.Equal(typeof(CustomDbContext), options.DbContextType);
}
private static OpenIddictEntityFrameworkCoreBuilder CreateBuilder(IServiceCollection services)
=> services.AddOpenIddict().AddCore().UseEntityFrameworkCore();
private static IServiceCollection CreateServices()
{
var services = new ServiceCollection();
services.AddOptions();
return services;
}
public class CustomApplication : OpenIddictApplication<long, CustomAuthorization, CustomToken> { }
public class CustomAuthorization : OpenIddictAuthorization<long, CustomApplication, CustomToken> { }
public class CustomScope : OpenIddictScope<long> { }
public class CustomToken : OpenIddictToken<long, CustomApplication, CustomAuthorization> { }
public class CustomDbContext : DbContext
{
public CustomDbContext(DbContextOptions options)
: base(options)
{
}
}
}
}

78
test/OpenIddict.EntityFrameworkCore.Tests/OpenIddictEntityFrameworkCoreExtensionsTests.cs

@ -5,8 +5,10 @@
*/ */
using System; using System;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using OpenIddict.Abstractions;
using OpenIddict.Core; using OpenIddict.Core;
using OpenIddict.EntityFrameworkCore.Models; using OpenIddict.EntityFrameworkCore.Models;
using Xunit; using Xunit;
@ -15,26 +17,47 @@ namespace OpenIddict.EntityFrameworkCore.Tests
{ {
public class OpenIddictEntityFrameworkCoreExtensionsTests public class OpenIddictEntityFrameworkCoreExtensionsTests
{ {
[Theory] [Fact]
[InlineData(typeof(OpenIddictApplicationStoreResolver))] public void UseEntityFrameworkCore_ThrowsAnExceptionForNullBuilder()
[InlineData(typeof(OpenIddictAuthorizationStoreResolver))]
[InlineData(typeof(OpenIddictScopeStoreResolver))]
[InlineData(typeof(OpenIddictTokenStoreResolver))]
public void UseEntityFrameworkCore_RegistersEntityFrameworkCoreStoreFactories(Type type)
{ {
// Arrange // Arrange
var services = new ServiceCollection().AddOptions(); var builder = (OpenIddictCoreBuilder) null;
// Act and assert
var exception = Assert.Throws<ArgumentNullException>(() => builder.UseEntityFrameworkCore());
Assert.Equal("builder", exception.ParamName);
}
[Fact]
public void UseEntityFrameworkCore_ThrowsAnExceptionForNullConfiguration()
{
// Arrange
var services = new ServiceCollection();
var builder = new OpenIddictCoreBuilder(services);
// Act and assert
var exception = Assert.Throws<ArgumentNullException>(() => builder.UseEntityFrameworkCore(configuration: null));
Assert.Equal("configuration", exception.ParamName);
}
[Fact]
public void UseEntityFrameworkCore_RegistersCachingServices()
{
// Arrange
var services = new ServiceCollection();
var builder = new OpenIddictCoreBuilder(services); var builder = new OpenIddictCoreBuilder(services);
// Act // Act
builder.UseEntityFrameworkCore(); builder.UseEntityFrameworkCore();
// Assert // Assert
Assert.Contains(services, service => service.ImplementationType == type); Assert.Contains(services, service => service.ServiceType == typeof(IMemoryCache));
} }
[Fact] [Fact]
public void UseEntityFrameworkCore_KeyTypeDefaultsToString() public void UseEntityFrameworkCore_RegistersDefaultEntities()
{ {
// Arrange // Arrange
var services = new ServiceCollection().AddOptions(); var services = new ServiceCollection().AddOptions();
@ -53,24 +76,41 @@ namespace OpenIddict.EntityFrameworkCore.Tests
Assert.Equal(typeof(OpenIddictToken), options.DefaultTokenType); Assert.Equal(typeof(OpenIddictToken), options.DefaultTokenType);
} }
[Fact] [Theory]
public void UseEntityFrameworkCore_KeyTypeCanBeOverriden() [InlineData(typeof(IOpenIddictApplicationStoreResolver), typeof(OpenIddictApplicationStoreResolver))]
[InlineData(typeof(IOpenIddictAuthorizationStoreResolver), typeof(OpenIddictAuthorizationStoreResolver))]
[InlineData(typeof(IOpenIddictScopeStoreResolver), typeof(OpenIddictScopeStoreResolver))]
[InlineData(typeof(IOpenIddictTokenStoreResolver), typeof(OpenIddictTokenStoreResolver))]
public void UseEntityFrameworkCore_RegistersEntityFrameworkCoreStoreResolvers(Type serviceType, Type implementationType)
{ {
// Arrange // Arrange
var services = new ServiceCollection().AddOptions(); var services = new ServiceCollection();
var builder = new OpenIddictCoreBuilder(services); var builder = new OpenIddictCoreBuilder(services);
// Act // Act
builder.UseEntityFrameworkCore().ReplaceDefaultEntities<Guid>(); builder.UseEntityFrameworkCore();
// Assert // Assert
var provider = services.BuildServiceProvider(); Assert.Contains(services, service => service.ServiceType == serviceType &&
var options = provider.GetRequiredService<IOptionsMonitor<OpenIddictCoreOptions>>().CurrentValue; service.ImplementationType == implementationType);
}
Assert.Equal(typeof(OpenIddictApplication<Guid>), options.DefaultApplicationType); [Theory]
Assert.Equal(typeof(OpenIddictAuthorization<Guid>), options.DefaultAuthorizationType); [InlineData(typeof(OpenIddictApplicationStore<,,,,>))]
Assert.Equal(typeof(OpenIddictScope<Guid>), options.DefaultScopeType); [InlineData(typeof(OpenIddictAuthorizationStore<,,,,>))]
Assert.Equal(typeof(OpenIddictToken<Guid>), options.DefaultTokenType); [InlineData(typeof(OpenIddictScopeStore<,,>))]
[InlineData(typeof(OpenIddictTokenStore<,,,,>))]
public void UseEntityFrameworkCore_RegistersEntityFrameworkCoreStore(Type type)
{
// Arrange
var services = new ServiceCollection();
var builder = new OpenIddictCoreBuilder(services);
// Act
builder.UseEntityFrameworkCore();
// Assert
Assert.Contains(services, service => service.ServiceType == type && service.ImplementationType == type);
} }
} }
} }

117
test/OpenIddict.EntityFrameworkCore.Tests/Resolvers/OpenIddictApplicationStoreResolverTests.cs

@ -0,0 +1,117 @@
/*
* Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
* See https://github.com/openiddict/openiddict-core for more information concerning
* the license and the contributors participating to this project.
*/
using System;
using System.Text;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Moq;
using OpenIddict.Abstractions;
using OpenIddict.EntityFrameworkCore.Models;
using Xunit;
namespace OpenIddict.EntityFrameworkCore.Tests
{
public class OpenIddictApplicationStoreResolverTests
{
[Fact]
public void Get_ReturnsCustomStoreCorrespondingToTheSpecifiedTypeWhenAvailable()
{
// Arrange
var services = new ServiceCollection();
services.AddSingleton(Mock.Of<IOpenIddictApplicationStore<CustomApplication>>());
var monitor = Mock.Of<IOptionsMonitor<OpenIddictEntityFrameworkCoreOptions>>();
var provider = services.BuildServiceProvider();
var resolver = new OpenIddictApplicationStoreResolver(monitor, provider);
// Act and assert
Assert.NotNull(resolver.Get<CustomApplication>());
}
[Fact]
public void Get_ThrowsAnExceptionForInvalidEntityType()
{
// Arrange
var services = new ServiceCollection();
var monitor = Mock.Of<IOptionsMonitor<OpenIddictEntityFrameworkCoreOptions>>();
var provider = services.BuildServiceProvider();
var resolver = new OpenIddictApplicationStoreResolver(monitor, provider);
// Act and assert
var exception = Assert.Throws<InvalidOperationException>(() => resolver.Get<CustomApplication>());
Assert.Equal(new StringBuilder()
.AppendLine("The specified application type is not compatible with the Entity Framework Core stores.")
.Append("When enabling the Entity Framework Core stores, make sure you use the built-in ")
.Append("'OpenIddictApplication' entity (from the 'OpenIddict.EntityFrameworkCore.Models' package) ")
.Append("or a custom entity that inherits from the generic 'OpenIddictApplication' entity.")
.ToString(), exception.Message);
}
[Fact]
public void Get_ThrowsAnExceptionWhenDbContextTypeIsNotAvailable()
{
// Arrange
var services = new ServiceCollection();
var monitor = Mock.Of<IOptionsMonitor<OpenIddictEntityFrameworkCoreOptions>>(
mock => mock.CurrentValue == new OpenIddictEntityFrameworkCoreOptions
{
DbContextType = null
});
var provider = services.BuildServiceProvider();
var resolver = new OpenIddictApplicationStoreResolver(monitor, provider);
// Act and assert
var exception = Assert.Throws<InvalidOperationException>(() => resolver.Get<OpenIddictApplication>());
Assert.Equal(new StringBuilder()
.AppendLine("No Entity Framework Core context was specified in the OpenIddict options.")
.Append("To configure the OpenIddict Entity Framework Core stores to use a specific 'DbContext', ")
.Append("use 'options.UseEntityFrameworkCore().UseDbContext<TContext>()'.")
.ToString(), exception.Message);
}
[Fact]
public void Get_ReturnsDefaultStoreCorrespondingToTheSpecifiedTypeWhenAvailable()
{
// Arrange
var services = new ServiceCollection();
services.AddSingleton(Mock.Of<IOpenIddictApplicationStore<CustomApplication>>());
services.AddSingleton(CreateStore());
var monitor = Mock.Of<IOptionsMonitor<OpenIddictEntityFrameworkCoreOptions>>(
mock => mock.CurrentValue == new OpenIddictEntityFrameworkCoreOptions
{
DbContextType = typeof(DbContext)
});
var provider = services.BuildServiceProvider();
var resolver = new OpenIddictApplicationStoreResolver(monitor, provider);
// Act and assert
Assert.NotNull(resolver.Get<MyApplication>());
}
private static OpenIddictApplicationStore<MyApplication, MyAuthorization, MyToken, DbContext, long> CreateStore()
=> new Mock<OpenIddictApplicationStore<MyApplication, MyAuthorization, MyToken, DbContext, long>>(
Mock.Of<IMemoryCache>(),
Mock.Of<DbContext>(),
Mock.Of<IOptionsMonitor<OpenIddictEntityFrameworkCoreOptions>>()).Object;
public class CustomApplication { }
public class MyApplication : OpenIddictApplication<long, MyAuthorization, MyToken> { }
public class MyAuthorization : OpenIddictAuthorization<long, MyApplication, MyToken> { }
public class MyScope : OpenIddictScope<long> { }
public class MyToken : OpenIddictToken<long, MyApplication, MyAuthorization> { }
}
}

117
test/OpenIddict.EntityFrameworkCore.Tests/Resolvers/OpenIddictAuthorizationStoreResolverTests.cs

@ -0,0 +1,117 @@
/*
* Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
* See https://github.com/openiddict/openiddict-core for more information concerning
* the license and the contributors participating to this project.
*/
using System;
using System.Text;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Moq;
using OpenIddict.Abstractions;
using OpenIddict.EntityFrameworkCore.Models;
using Xunit;
namespace OpenIddict.EntityFrameworkCore.Tests
{
public class OpenIddictAuthorizationStoreResolverTests
{
[Fact]
public void Get_ReturnsCustomStoreCorrespondingToTheSpecifiedTypeWhenAvailable()
{
// Arrange
var services = new ServiceCollection();
services.AddSingleton(Mock.Of<IOpenIddictAuthorizationStore<CustomAuthorization>>());
var monitor = Mock.Of<IOptionsMonitor<OpenIddictEntityFrameworkCoreOptions>>();
var provider = services.BuildServiceProvider();
var resolver = new OpenIddictAuthorizationStoreResolver(monitor, provider);
// Act and assert
Assert.NotNull(resolver.Get<CustomAuthorization>());
}
[Fact]
public void Get_ThrowsAnExceptionForInvalidEntityType()
{
// Arrange
var services = new ServiceCollection();
var monitor = Mock.Of<IOptionsMonitor<OpenIddictEntityFrameworkCoreOptions>>();
var provider = services.BuildServiceProvider();
var resolver = new OpenIddictAuthorizationStoreResolver(monitor, provider);
// Act and assert
var exception = Assert.Throws<InvalidOperationException>(() => resolver.Get<CustomAuthorization>());
Assert.Equal(new StringBuilder()
.AppendLine("The specified authorization type is not compatible with the Entity Framework Core stores.")
.Append("When enabling the Entity Framework Core stores, make sure you use the built-in ")
.Append("'OpenIddictAuthorization' entity (from the 'OpenIddict.EntityFrameworkCore.Models' package) ")
.Append("or a custom entity that inherits from the generic 'OpenIddictAuthorization' entity.")
.ToString(), exception.Message);
}
[Fact]
public void Get_ThrowsAnExceptionWhenDbContextTypeIsNotAvailable()
{
// Arrange
var services = new ServiceCollection();
var monitor = Mock.Of<IOptionsMonitor<OpenIddictEntityFrameworkCoreOptions>>(
mock => mock.CurrentValue == new OpenIddictEntityFrameworkCoreOptions
{
DbContextType = null
});
var provider = services.BuildServiceProvider();
var resolver = new OpenIddictAuthorizationStoreResolver(monitor, provider);
// Act and assert
var exception = Assert.Throws<InvalidOperationException>(() => resolver.Get<OpenIddictAuthorization>());
Assert.Equal(new StringBuilder()
.AppendLine("No Entity Framework Core context was specified in the OpenIddict options.")
.Append("To configure the OpenIddict Entity Framework Core stores to use a specific 'DbContext', ")
.Append("use 'options.UseEntityFrameworkCore().UseDbContext<TContext>()'.")
.ToString(), exception.Message);
}
[Fact]
public void Get_ReturnsDefaultStoreCorrespondingToTheSpecifiedTypeWhenAvailable()
{
// Arrange
var services = new ServiceCollection();
services.AddSingleton(Mock.Of<IOpenIddictAuthorizationStore<CustomAuthorization>>());
services.AddSingleton(CreateStore());
var monitor = Mock.Of<IOptionsMonitor<OpenIddictEntityFrameworkCoreOptions>>(
mock => mock.CurrentValue == new OpenIddictEntityFrameworkCoreOptions
{
DbContextType = typeof(DbContext)
});
var provider = services.BuildServiceProvider();
var resolver = new OpenIddictAuthorizationStoreResolver(monitor, provider);
// Act and assert
Assert.NotNull(resolver.Get<MyAuthorization>());
}
private static OpenIddictAuthorizationStore<MyAuthorization, MyApplication, MyToken, DbContext, long> CreateStore()
=> new Mock<OpenIddictAuthorizationStore<MyAuthorization, MyApplication, MyToken, DbContext, long>>(
Mock.Of<IMemoryCache>(),
Mock.Of<DbContext>(),
Mock.Of<IOptionsMonitor<OpenIddictEntityFrameworkCoreOptions>>()).Object;
public class CustomAuthorization { }
public class MyApplication : OpenIddictApplication<long, MyAuthorization, MyToken> { }
public class MyAuthorization : OpenIddictAuthorization<long, MyApplication, MyToken> { }
public class MyScope : OpenIddictScope<long> { }
public class MyToken : OpenIddictToken<long, MyApplication, MyAuthorization> { }
}
}

117
test/OpenIddict.EntityFrameworkCore.Tests/Resolvers/OpenIddictScopeStoreResolverTests.cs

@ -0,0 +1,117 @@
/*
* Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
* See https://github.com/openiddict/openiddict-core for more information concerning
* the license and the contributors participating to this project.
*/
using System;
using System.Text;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Moq;
using OpenIddict.Abstractions;
using OpenIddict.EntityFrameworkCore.Models;
using Xunit;
namespace OpenIddict.EntityFrameworkCore.Tests
{
public class OpenIddictScopeStoreResolverTests
{
[Fact]
public void Get_ReturnsCustomStoreCorrespondingToTheSpecifiedTypeWhenAvailable()
{
// Arrange
var services = new ServiceCollection();
services.AddSingleton(Mock.Of<IOpenIddictScopeStore<CustomScope>>());
var monitor = Mock.Of<IOptionsMonitor<OpenIddictEntityFrameworkCoreOptions>>();
var provider = services.BuildServiceProvider();
var resolver = new OpenIddictScopeStoreResolver(monitor, provider);
// Act and assert
Assert.NotNull(resolver.Get<CustomScope>());
}
[Fact]
public void Get_ThrowsAnExceptionForInvalidEntityType()
{
// Arrange
var services = new ServiceCollection();
var monitor = Mock.Of<IOptionsMonitor<OpenIddictEntityFrameworkCoreOptions>>();
var provider = services.BuildServiceProvider();
var resolver = new OpenIddictScopeStoreResolver(monitor, provider);
// Act and assert
var exception = Assert.Throws<InvalidOperationException>(() => resolver.Get<CustomScope>());
Assert.Equal(new StringBuilder()
.AppendLine("The specified scope type is not compatible with the Entity Framework Core stores.")
.Append("When enabling the Entity Framework Core stores, make sure you use the built-in ")
.Append("'OpenIddictScope' entity (from the 'OpenIddict.EntityFrameworkCore.Models' package) ")
.Append("or a custom entity that inherits from the generic 'OpenIddictScope' entity.")
.ToString(), exception.Message);
}
[Fact]
public void Get_ThrowsAnExceptionWhenDbContextTypeIsNotAvailable()
{
// Arrange
var services = new ServiceCollection();
var monitor = Mock.Of<IOptionsMonitor<OpenIddictEntityFrameworkCoreOptions>>(
mock => mock.CurrentValue == new OpenIddictEntityFrameworkCoreOptions
{
DbContextType = null
});
var provider = services.BuildServiceProvider();
var resolver = new OpenIddictScopeStoreResolver(monitor, provider);
// Act and assert
var exception = Assert.Throws<InvalidOperationException>(() => resolver.Get<OpenIddictScope>());
Assert.Equal(new StringBuilder()
.AppendLine("No Entity Framework Core context was specified in the OpenIddict options.")
.Append("To configure the OpenIddict Entity Framework Core stores to use a specific 'DbContext', ")
.Append("use 'options.UseEntityFrameworkCore().UseDbContext<TContext>()'.")
.ToString(), exception.Message);
}
[Fact]
public void Get_ReturnsDefaultStoreCorrespondingToTheSpecifiedTypeWhenAvailable()
{
// Arrange
var services = new ServiceCollection();
services.AddSingleton(Mock.Of<IOpenIddictScopeStore<CustomScope>>());
services.AddSingleton(CreateStore());
var monitor = Mock.Of<IOptionsMonitor<OpenIddictEntityFrameworkCoreOptions>>(
mock => mock.CurrentValue == new OpenIddictEntityFrameworkCoreOptions
{
DbContextType = typeof(DbContext)
});
var provider = services.BuildServiceProvider();
var resolver = new OpenIddictScopeStoreResolver(monitor, provider);
// Act and assert
Assert.NotNull(resolver.Get<MyScope>());
}
private static OpenIddictScopeStore<MyScope, DbContext, long> CreateStore()
=> new Mock<OpenIddictScopeStore<MyScope, DbContext, long>>(
Mock.Of<IMemoryCache>(),
Mock.Of<DbContext>(),
Mock.Of<IOptionsMonitor<OpenIddictEntityFrameworkCoreOptions>>()).Object;
public class CustomScope { }
public class MyApplication : OpenIddictApplication<long, MyAuthorization, MyToken> { }
public class MyAuthorization : OpenIddictAuthorization<long, MyApplication, MyToken> { }
public class MyScope : OpenIddictScope<long> { }
public class MyToken : OpenIddictToken<long, MyApplication, MyAuthorization> { }
}
}

117
test/OpenIddict.EntityFrameworkCore.Tests/Resolvers/OpenIddictTokenStoreResolverTests.cs

@ -0,0 +1,117 @@
/*
* Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
* See https://github.com/openiddict/openiddict-core for more information concerning
* the license and the contributors participating to this project.
*/
using System;
using System.Text;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Moq;
using OpenIddict.Abstractions;
using OpenIddict.EntityFrameworkCore.Models;
using Xunit;
namespace OpenIddict.EntityFrameworkCore.Tests
{
public class OpenIddictTokenStoreResolverTests
{
[Fact]
public void Get_ReturnsCustomStoreCorrespondingToTheSpecifiedTypeWhenAvailable()
{
// Arrange
var services = new ServiceCollection();
services.AddSingleton(Mock.Of<IOpenIddictTokenStore<CustomToken>>());
var monitor = Mock.Of<IOptionsMonitor<OpenIddictEntityFrameworkCoreOptions>>();
var provider = services.BuildServiceProvider();
var resolver = new OpenIddictTokenStoreResolver(monitor, provider);
// Act and assert
Assert.NotNull(resolver.Get<CustomToken>());
}
[Fact]
public void Get_ThrowsAnExceptionForInvalidEntityType()
{
// Arrange
var services = new ServiceCollection();
var monitor = Mock.Of<IOptionsMonitor<OpenIddictEntityFrameworkCoreOptions>>();
var provider = services.BuildServiceProvider();
var resolver = new OpenIddictTokenStoreResolver(monitor, provider);
// Act and assert
var exception = Assert.Throws<InvalidOperationException>(() => resolver.Get<CustomToken>());
Assert.Equal(new StringBuilder()
.AppendLine("The specified token type is not compatible with the Entity Framework Core stores.")
.Append("When enabling the Entity Framework Core stores, make sure you use the built-in ")
.Append("'OpenIddictToken' entity (from the 'OpenIddict.EntityFrameworkCore.Models' package) ")
.Append("or a custom entity that inherits from the generic 'OpenIddictToken' entity.")
.ToString(), exception.Message);
}
[Fact]
public void Get_ThrowsAnExceptionWhenDbContextTypeIsNotAvailable()
{
// Arrange
var services = new ServiceCollection();
var monitor = Mock.Of<IOptionsMonitor<OpenIddictEntityFrameworkCoreOptions>>(
mock => mock.CurrentValue == new OpenIddictEntityFrameworkCoreOptions
{
DbContextType = null
});
var provider = services.BuildServiceProvider();
var resolver = new OpenIddictTokenStoreResolver(monitor, provider);
// Act and assert
var exception = Assert.Throws<InvalidOperationException>(() => resolver.Get<OpenIddictToken>());
Assert.Equal(new StringBuilder()
.AppendLine("No Entity Framework Core context was specified in the OpenIddict options.")
.Append("To configure the OpenIddict Entity Framework Core stores to use a specific 'DbContext', ")
.Append("use 'options.UseEntityFrameworkCore().UseDbContext<TContext>()'.")
.ToString(), exception.Message);
}
[Fact]
public void Get_ReturnsDefaultStoreCorrespondingToTheSpecifiedTypeWhenAvailable()
{
// Arrange
var services = new ServiceCollection();
services.AddSingleton(Mock.Of<IOpenIddictTokenStore<CustomToken>>());
services.AddSingleton(CreateStore());
var monitor = Mock.Of<IOptionsMonitor<OpenIddictEntityFrameworkCoreOptions>>(
mock => mock.CurrentValue == new OpenIddictEntityFrameworkCoreOptions
{
DbContextType = typeof(DbContext)
});
var provider = services.BuildServiceProvider();
var resolver = new OpenIddictTokenStoreResolver(monitor, provider);
// Act and assert
Assert.NotNull(resolver.Get<MyToken>());
}
private static OpenIddictTokenStore<MyToken, MyApplication, MyAuthorization, DbContext, long> CreateStore()
=> new Mock<OpenIddictTokenStore<MyToken, MyApplication, MyAuthorization, DbContext, long>>(
Mock.Of<IMemoryCache>(),
Mock.Of<DbContext>(),
Mock.Of<IOptionsMonitor<OpenIddictEntityFrameworkCoreOptions>>()).Object;
public class CustomToken { }
public class MyApplication : OpenIddictApplication<long, MyAuthorization, MyToken> { }
public class MyAuthorization : OpenIddictAuthorization<long, MyApplication, MyToken> { }
public class MyScope : OpenIddictScope<long> { }
public class MyToken : OpenIddictToken<long, MyApplication, MyAuthorization> { }
}
}

26
test/OpenIddict.MongoDb.Tests/OpenIddict.MongoDb.Tests.csproj

@ -0,0 +1,26 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\build\common.props" />
<PropertyGroup>
<TargetFrameworks>netcoreapp2.0;net461</TargetFrameworks>
<TargetFrameworks Condition=" '$(OS)' != 'Windows_NT' ">netcoreapp2.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\OpenIddict.MongoDb\OpenIddict.MongoDb.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="$(AspNetCoreVersion)" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(TestSdkVersion)" />
<PackageReference Include="Moq" Version="$(MoqVersion)" />
<PackageReference Include="xunit" Version="$(XunitVersion)" />
<PackageReference Include="xunit.runner.visualstudio" Version="$(XunitVersion)" />
</ItemGroup>
<ItemGroup>
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
</ItemGroup>
</Project>

282
test/OpenIddict.MongoDb.Tests/OpenIddictMongoDbBuilderTests.cs

@ -0,0 +1,282 @@
/*
* Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
* See https://github.com/openiddict/openiddict-core for more information concerning
* the license and the contributors participating to this project.
*/
using System;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using MongoDB.Driver;
using Moq;
using OpenIddict.Core;
using OpenIddict.MongoDb.Models;
using Xunit;
namespace OpenIddict.MongoDb.Tests
{
public class OpenIddictMongoDbBuilderTests
{
[Fact]
public void Constructor_ThrowsAnExceptionForNullServices()
{
// Arrange
var services = (IServiceCollection) null;
// Act and assert
var exception = Assert.Throws<ArgumentNullException>(() => new OpenIddictMongoDbBuilder(services));
Assert.Equal("services", exception.ParamName);
}
[Fact]
public void ReplaceDefaultApplicationEntity_EntityIsCorrectlySet()
{
// Arrange
var services = CreateServices();
var builder = CreateBuilder(services);
// Act
builder.ReplaceDefaultApplicationEntity<CustomApplication>();
// Assert
var provider = services.BuildServiceProvider();
var options = provider.GetRequiredService<IOptionsMonitor<OpenIddictCoreOptions>>().CurrentValue;
Assert.Equal(typeof(CustomApplication), options.DefaultApplicationType);
}
[Fact]
public void ReplaceDefaultAuthorizationEntity_EntityIsCorrectlySet()
{
// Arrange
var services = CreateServices();
var builder = CreateBuilder(services);
// Act
builder.ReplaceDefaultAuthorizationEntity<CustomAuthorization>();
// Assert
var provider = services.BuildServiceProvider();
var options = provider.GetRequiredService<IOptionsMonitor<OpenIddictCoreOptions>>().CurrentValue;
Assert.Equal(typeof(CustomAuthorization), options.DefaultAuthorizationType);
}
[Fact]
public void ReplaceDefaultScopeEntity_EntityIsCorrectlySet()
{
// Arrange
var services = CreateServices();
var builder = CreateBuilder(services);
// Act
builder.ReplaceDefaultScopeEntity<CustomScope>();
// Assert
var provider = services.BuildServiceProvider();
var options = provider.GetRequiredService<IOptionsMonitor<OpenIddictCoreOptions>>().CurrentValue;
Assert.Equal(typeof(CustomScope), options.DefaultScopeType);
}
[Fact]
public void ReplaceDefaultTokenEntity_EntityIsCorrectlySet()
{
// Arrange
var services = CreateServices();
var builder = CreateBuilder(services);
// Act
builder.ReplaceDefaultTokenEntity<CustomToken>();
// Assert
var provider = services.BuildServiceProvider();
var options = provider.GetRequiredService<IOptionsMonitor<OpenIddictCoreOptions>>().CurrentValue;
Assert.Equal(typeof(CustomToken), options.DefaultTokenType);
}
[Theory]
[InlineData(null)]
[InlineData("")]
public void SetApplicationsCollectionName_ThrowsAnExceptionForNullOrEmptyCollectionName(string name)
{
// Arrange
var services = CreateServices();
var builder = CreateBuilder(services);
// Act and assert
var exception = Assert.Throws<ArgumentException>(() => builder.SetApplicationsCollectionName(name));
Assert.Equal("name", exception.ParamName);
Assert.StartsWith("The collection name cannot be null or empty.", exception.Message);
}
[Fact]
public void SetApplicationsCollectionName_CollectionNameIsCorrectlySet()
{
// Arrange
var services = CreateServices();
var builder = CreateBuilder(services);
// Act
builder.SetApplicationsCollectionName("custom_collection");
// Assert
var provider = services.BuildServiceProvider();
var options = provider.GetRequiredService<IOptionsMonitor<OpenIddictMongoDbOptions>>().CurrentValue;
Assert.Equal("custom_collection", options.ApplicationsCollectionName);
}
[Theory]
[InlineData(null)]
[InlineData("")]
public void SetAuthorizationsCollectionName_ThrowsAnExceptionForNullOrEmptyCollectionName(string name)
{
// Arrange
var services = CreateServices();
var builder = CreateBuilder(services);
// Act and assert
var exception = Assert.Throws<ArgumentException>(() => builder.SetAuthorizationsCollectionName(name));
Assert.Equal("name", exception.ParamName);
Assert.StartsWith("The collection name cannot be null or empty.", exception.Message);
}
[Fact]
public void SetAuthorizationsCollectionName_CollectionNameIsCorrectlySet()
{
// Arrange
var services = CreateServices();
var builder = CreateBuilder(services);
// Act
builder.SetAuthorizationsCollectionName("custom_collection");
// Assert
var provider = services.BuildServiceProvider();
var options = provider.GetRequiredService<IOptionsMonitor<OpenIddictMongoDbOptions>>().CurrentValue;
Assert.Equal("custom_collection", options.AuthorizationsCollectionName);
}
[Theory]
[InlineData(null)]
[InlineData("")]
public void SetScopesCollectionName_ThrowsAnExceptionForNullOrEmptyCollectionName(string name)
{
// Arrange
var services = CreateServices();
var builder = CreateBuilder(services);
// Act and assert
var exception = Assert.Throws<ArgumentException>(() => builder.SetScopesCollectionName(name));
Assert.Equal("name", exception.ParamName);
Assert.StartsWith("The collection name cannot be null or empty.", exception.Message);
}
[Fact]
public void SetScopesCollectionName_CollectionNameIsCorrectlySet()
{
// Arrange
var services = CreateServices();
var builder = CreateBuilder(services);
// Act
builder.SetScopesCollectionName("custom_collection");
// Assert
var provider = services.BuildServiceProvider();
var options = provider.GetRequiredService<IOptionsMonitor<OpenIddictMongoDbOptions>>().CurrentValue;
Assert.Equal("custom_collection", options.ScopesCollectionName);
}
[Theory]
[InlineData(null)]
[InlineData("")]
public void SetTokensCollectionName_ThrowsAnExceptionForNullOrEmptyCollectionName(string name)
{
// Arrange
var services = CreateServices();
var builder = CreateBuilder(services);
// Act and assert
var exception = Assert.Throws<ArgumentException>(() => builder.SetTokensCollectionName(name));
Assert.Equal("name", exception.ParamName);
Assert.StartsWith("The collection name cannot be null or empty.", exception.Message);
}
[Fact]
public void SetTokensCollectionName_CollectionNameIsCorrectlySet()
{
// Arrange
var services = CreateServices();
var builder = CreateBuilder(services);
// Act
builder.SetTokensCollectionName("custom_collection");
// Assert
var provider = services.BuildServiceProvider();
var options = provider.GetRequiredService<IOptionsMonitor<OpenIddictMongoDbOptions>>().CurrentValue;
Assert.Equal("custom_collection", options.TokensCollectionName);
}
[Fact]
public void UseDatabase_ThrowsAnExceptionForNullDatabase()
{
// Arrange
var services = CreateServices();
var builder = CreateBuilder(services);
// Act and assert
var exception = Assert.Throws<ArgumentNullException>(delegate
{
return builder.UseDatabase(database: null);
});
Assert.Equal("database", exception.ParamName);
}
[Fact]
public void UseDatabase_SetsDatabaseInOptions()
{
// Arrange
var services = CreateServices();
var builder = CreateBuilder(services);
var database = Mock.Of<IMongoDatabase>();
// Act
builder.UseDatabase(database);
// Assert
var provider = services.BuildServiceProvider();
var options = provider.GetRequiredService<IOptionsMonitor<OpenIddictMongoDbOptions>>().CurrentValue;
Assert.Equal(database, options.Database);
}
private static OpenIddictMongoDbBuilder CreateBuilder(IServiceCollection services)
=> services.AddOpenIddict().AddCore().UseMongoDb();
private static IServiceCollection CreateServices()
{
var services = new ServiceCollection();
services.AddOptions();
return services;
}
public class CustomApplication : OpenIddictApplication { }
public class CustomAuthorization : OpenIddictAuthorization { }
public class CustomScope : OpenIddictScope { }
public class CustomToken : OpenIddictToken { }
}
}

132
test/OpenIddict.MongoDb.Tests/OpenIddictMongoDbExtensionsTests.cs

@ -0,0 +1,132 @@
/*
* Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
* See https://github.com/openiddict/openiddict-core for more information concerning
* the license and the contributors participating to this project.
*/
using System;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using OpenIddict.Abstractions;
using OpenIddict.Core;
using OpenIddict.MongoDb.Models;
using Xunit;
namespace OpenIddict.MongoDb.Tests
{
public class OpenIddictMongoDbExtensionsTests
{
[Fact]
public void UseMongoDb_ThrowsAnExceptionForNullBuilder()
{
// Arrange
var builder = (OpenIddictCoreBuilder) null;
// Act and assert
var exception = Assert.Throws<ArgumentNullException>(() => builder.UseMongoDb());
Assert.Equal("builder", exception.ParamName);
}
[Fact]
public void UseMongoDb_ThrowsAnExceptionForNullConfiguration()
{
// Arrange
var services = new ServiceCollection();
var builder = new OpenIddictCoreBuilder(services);
// Act and assert
var exception = Assert.Throws<ArgumentNullException>(() => builder.UseMongoDb(configuration: null));
Assert.Equal("configuration", exception.ParamName);
}
[Fact]
public void UseMongoDb_RegistersCachingServices()
{
// Arrange
var services = new ServiceCollection();
var builder = new OpenIddictCoreBuilder(services);
// Act
builder.UseMongoDb();
// Assert
Assert.Contains(services, service => service.ServiceType == typeof(IMemoryCache));
}
[Fact]
public void UseMongoDb_RegistersDefaultEntities()
{
// Arrange
var services = new ServiceCollection().AddOptions();
var builder = new OpenIddictCoreBuilder(services);
// Act
builder.UseMongoDb();
// Assert
var provider = services.BuildServiceProvider();
var options = provider.GetRequiredService<IOptionsMonitor<OpenIddictCoreOptions>>().CurrentValue;
Assert.Equal(typeof(OpenIddictApplication), options.DefaultApplicationType);
Assert.Equal(typeof(OpenIddictAuthorization), options.DefaultAuthorizationType);
Assert.Equal(typeof(OpenIddictScope), options.DefaultScopeType);
Assert.Equal(typeof(OpenIddictToken), options.DefaultTokenType);
}
[Theory]
[InlineData(typeof(IOpenIddictApplicationStoreResolver), typeof(OpenIddictApplicationStoreResolver))]
[InlineData(typeof(IOpenIddictAuthorizationStoreResolver), typeof(OpenIddictAuthorizationStoreResolver))]
[InlineData(typeof(IOpenIddictScopeStoreResolver), typeof(OpenIddictScopeStoreResolver))]
[InlineData(typeof(IOpenIddictTokenStoreResolver), typeof(OpenIddictTokenStoreResolver))]
public void UseMongoDb_RegistersMongoDbStoreResolvers(Type serviceType, Type implementationType)
{
// Arrange
var services = new ServiceCollection();
var builder = new OpenIddictCoreBuilder(services);
// Act
builder.UseMongoDb();
// Assert
Assert.Contains(services, service => service.ServiceType == serviceType &&
service.ImplementationType == implementationType);
}
[Theory]
[InlineData(typeof(OpenIddictApplicationStore<>))]
[InlineData(typeof(OpenIddictAuthorizationStore<>))]
[InlineData(typeof(OpenIddictScopeStore<>))]
[InlineData(typeof(OpenIddictTokenStore<>))]
public void UseMongoDb_RegistersMongoDbStore(Type type)
{
// Arrange
var services = new ServiceCollection();
var builder = new OpenIddictCoreBuilder(services);
// Act
builder.UseMongoDb();
// Assert
Assert.Contains(services, service => service.ServiceType == type && service.ImplementationType == type);
}
[Fact]
public void UseMongoDb_RegistersMongoDbContext()
{
// Arrange
var services = new ServiceCollection();
var builder = new OpenIddictCoreBuilder(services);
// Act
builder.UseMongoDb();
// Assert
Assert.Contains(services, service => service.Lifetime == ServiceLifetime.Singleton &&
service.ServiceType == typeof(IOpenIddictMongoDbContext) &&
service.ImplementationType == typeof(OpenIddictMongoDbContext));
}
}
}

13
test/OpenIddict.Mvc.Tests/OpenIddictMvcBuilderTests.cs

@ -4,6 +4,7 @@
* the license and the contributors participating to this project. * the license and the contributors participating to this project.
*/ */
using System;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Xunit; using Xunit;
@ -12,6 +13,18 @@ namespace OpenIddict.Mvc.Tests
{ {
public class OpenIddictMvcBuilderTests public class OpenIddictMvcBuilderTests
{ {
[Fact]
public void Constructor_ThrowsAnExceptionForNullServices()
{
// Arrange
var services = (IServiceCollection) null;
// Act and assert
var exception = Assert.Throws<ArgumentNullException>(() => new OpenIddictMvcBuilder(services));
Assert.Equal("services", exception.ParamName);
}
[Fact] [Fact]
public void Configure_OptionsAreCorrectlyAmended() public void Configure_OptionsAreCorrectlyAmended()
{ {

26
test/OpenIddict.Mvc.Tests/OpenIddictMvcExtensionsTests.cs

@ -4,6 +4,7 @@
* the license and the contributors participating to this project. * the license and the contributors participating to this project.
*/ */
using System;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
@ -13,6 +14,31 @@ namespace OpenIddict.Mvc.Tests
{ {
public class OpenIddictMvcExtensionsTests public class OpenIddictMvcExtensionsTests
{ {
[Fact]
public void UseMvc_ThrowsAnExceptionForNullBuilder()
{
// Arrange
var builder = (OpenIddictServerBuilder) null;
// Act and assert
var exception = Assert.Throws<ArgumentNullException>(() => builder.UseMvc());
Assert.Equal("builder", exception.ParamName);
}
[Fact]
public void UseMvc_ThrowsAnExceptionForNullConfiguration()
{
// Arrange
var services = new ServiceCollection();
var builder = new OpenIddictServerBuilder(services);
// Act and assert
var exception = Assert.Throws<ArgumentNullException>(() => builder.UseMvc(configuration: null));
Assert.Equal("configuration", exception.ParamName);
}
[Fact] [Fact]
public void UseMvc_RegistersModelBinderProvider() public void UseMvc_RegistersModelBinderProvider()
{ {

12
test/OpenIddict.Server.Tests/OpenIddictServerBuilderTests.cs

@ -23,6 +23,18 @@ namespace OpenIddict.Server.Tests
{ {
public class OpenIddictServerBuilderTests public class OpenIddictServerBuilderTests
{ {
[Fact]
public void Constructor_ThrowsAnExceptionForNullServices()
{
// Arrange
var services = (IServiceCollection) null;
// Act and assert
var exception = Assert.Throws<ArgumentNullException>(() => new OpenIddictServerBuilder(services));
Assert.Equal("services", exception.ParamName);
}
[Fact] [Fact]
public void AddEventHandler_HandlerIsAttached() public void AddEventHandler_HandlerIsAttached()
{ {

208
test/OpenIddict.Server.Tests/OpenIddictServerExtensionsTests.cs

@ -0,0 +1,208 @@
/*
* Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
* See https://github.com/openiddict/openiddict-core for more information concerning
* the license and the contributors participating to this project.
*/
using System;
using System.Text;
using AspNet.Security.OpenIdConnect.Server;
using Microsoft.AspNetCore.Authentication;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Xunit;
namespace OpenIddict.Server.Tests
{
public class OpenIddictServerExtensionsTests
{
[Fact]
public void AddServer_ThrowsAnExceptionForNullBuilder()
{
// Arrange
var builder = (OpenIddictBuilder) null;
// Act and assert
var exception = Assert.Throws<ArgumentNullException>(() => builder.AddServer());
Assert.Equal("builder", exception.ParamName);
}
[Fact]
public void AddServer_ThrowsAnExceptionForNullConfiguration()
{
// Arrange
var services = new ServiceCollection();
var builder = new OpenIddictBuilder(services);
// Act and assert
var exception = Assert.Throws<ArgumentNullException>(() => builder.AddServer(configuration: null));
Assert.Equal("configuration", exception.ParamName);
}
[Fact]
public void AddServer_RegistersAuthenticationServices()
{
// Arrange
var services = new ServiceCollection();
var builder = new OpenIddictBuilder(services);
// Act
builder.AddServer();
// Assert
Assert.Contains(services, service => service.ServiceType == typeof(IAuthenticationService));
}
[Fact]
public void AddServer_RegistersCachingServices()
{
// Arrange
var services = new ServiceCollection();
var builder = new OpenIddictBuilder(services);
// Act
builder.AddServer();
// Assert
Assert.Contains(services, service => service.ServiceType == typeof(IDistributedCache));
Assert.Contains(services, service => service.ServiceType == typeof(IMemoryCache));
}
[Fact]
public void AddServer_RegistersLoggingServices()
{
// Arrange
var services = new ServiceCollection();
var builder = new OpenIddictBuilder(services);
// Act
builder.AddServer();
// Assert
Assert.Contains(services, service => service.ServiceType == typeof(ILogger<>));
}
[Fact]
public void AddServer_RegistersOptionsServices()
{
// Arrange
var services = new ServiceCollection();
var builder = new OpenIddictBuilder(services);
// Act
builder.AddServer();
// Assert
Assert.Contains(services, service => service.ServiceType == typeof(IOptions<>));
}
[Fact]
public void AddServer_RegistersEventService()
{
// Arrange
var services = new ServiceCollection();
var builder = new OpenIddictBuilder(services);
// Act
builder.AddServer();
// Assert
Assert.Contains(services, service => service.Lifetime == ServiceLifetime.Scoped &&
service.ServiceType == typeof(IOpenIddictServerEventService) &&
service.ImplementationType == typeof(OpenIddictServerEventService));
}
[Fact]
public void AddServer_RegistersHandler()
{
// Arrange
var services = new ServiceCollection();
var builder = new OpenIddictBuilder(services);
// Act
builder.AddServer();
// Assert
Assert.Contains(services, service => service.Lifetime == ServiceLifetime.Scoped &&
service.ServiceType == typeof(OpenIddictServerHandler) &&
service.ImplementationType == typeof(OpenIddictServerHandler));
}
[Fact]
public void AddServer_RegistersProvider()
{
// Arrange
var services = new ServiceCollection();
var builder = new OpenIddictBuilder(services);
// Act
builder.AddServer();
// Assert
Assert.Contains(services, service => service.Lifetime == ServiceLifetime.Scoped &&
service.ServiceType == typeof(OpenIddictServerProvider) &&
service.ImplementationFactory != null);
}
[Fact]
public void AddServer_ResolvingProviderThrowsAnExceptionWhenCoreServicesAreNotRegistered()
{
// Arrange
var services = new ServiceCollection();
var builder = new OpenIddictBuilder(services);
// Act
builder.AddServer();
// Assert
var provider = services.BuildServiceProvider();
var exception = Assert.Throws<InvalidOperationException>(() => provider.GetRequiredService<OpenIddictServerProvider>());
Assert.Equal(new StringBuilder()
.AppendLine("The core services must be registered when enabling the server handler.")
.Append("To register the OpenIddict core services, use 'services.AddOpenIddict().AddCore()'.")
.ToString(), exception.Message);
}
[Theory]
[InlineData(typeof(IPostConfigureOptions<OpenIddictServerOptions>), typeof(OpenIddictServerInitializer))]
[InlineData(typeof(IPostConfigureOptions<OpenIddictServerOptions>), typeof(OpenIdConnectServerInitializer))]
public void AddServer_RegistersInitializers(Type serviceType, Type implementationType)
{
// Arrange
var services = new ServiceCollection();
var builder = new OpenIddictBuilder(services);
// Act
builder.AddServer();
// Assert
Assert.Contains(services, service => service.ServiceType == serviceType &&
service.ImplementationType == implementationType);
}
[Fact]
public void AddServer_RegistersAuthenticationScheme()
{
// Arrange
var services = new ServiceCollection();
var builder = new OpenIddictBuilder(services);
// Act
builder.AddServer();
// Assert
var provider = services.BuildServiceProvider();
var options = provider.GetRequiredService<IOptions<AuthenticationOptions>>().Value;
Assert.Contains(options.Schemes, scheme => scheme.Name == OpenIddictServerDefaults.AuthenticationScheme &&
scheme.HandlerType == typeof(OpenIddictServerHandler));
}
}
}

12
test/OpenIddict.Validation.Tests/OpenIddictValidationBuilderTests.cs

@ -17,6 +17,18 @@ namespace OpenIddict.Validation.Tests
{ {
public class OpenIddictValidationBuilderTests public class OpenIddictValidationBuilderTests
{ {
[Fact]
public void Constructor_ThrowsAnExceptionForNullServices()
{
// Arrange
var services = (IServiceCollection) null;
// Act and assert
var exception = Assert.Throws<ArgumentNullException>(() => new OpenIddictValidationBuilder(services));
Assert.Equal("services", exception.ParamName);
}
[Fact] [Fact]
public void AddEventHandler_HandlerIsAttached() public void AddEventHandler_HandlerIsAttached()
{ {

169
test/OpenIddict.Validation.Tests/OpenIddictValidationExtensionsTests.cs

@ -0,0 +1,169 @@
/*
* Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
* See https://github.com/openiddict/openiddict-core for more information concerning
* the license and the contributors participating to this project.
*/
using System;
using AspNet.Security.OAuth.Validation;
using Microsoft.AspNetCore.Authentication;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Xunit;
namespace OpenIddict.Validation.Tests
{
public class OpenIddictValidationExtensionsTests
{
[Fact]
public void AddValidation_ThrowsAnExceptionForNullBuilder()
{
// Arrange
var builder = (OpenIddictBuilder) null;
// Act and assert
var exception = Assert.Throws<ArgumentNullException>(() => builder.AddValidation());
Assert.Equal("builder", exception.ParamName);
}
[Fact]
public void AddValidation_ThrowsAnExceptionForNullConfiguration()
{
// Arrange
var services = new ServiceCollection();
var builder = new OpenIddictBuilder(services);
// Act and assert
var exception = Assert.Throws<ArgumentNullException>(() => builder.AddValidation(configuration: null));
Assert.Equal("configuration", exception.ParamName);
}
[Fact]
public void AddValidation_RegistersAuthenticationServices()
{
// Arrange
var services = new ServiceCollection();
var builder = new OpenIddictBuilder(services);
// Act
builder.AddValidation();
// Assert
Assert.Contains(services, service => service.ServiceType == typeof(IAuthenticationService));
}
[Fact]
public void AddValidation_RegistersLoggingServices()
{
// Arrange
var services = new ServiceCollection();
var builder = new OpenIddictBuilder(services);
// Act
builder.AddValidation();
// Assert
Assert.Contains(services, service => service.ServiceType == typeof(ILogger<>));
}
[Fact]
public void AddValidation_RegistersOptionsServices()
{
// Arrange
var services = new ServiceCollection();
var builder = new OpenIddictBuilder(services);
// Act
builder.AddValidation();
// Assert
Assert.Contains(services, service => service.ServiceType == typeof(IOptions<>));
}
[Fact]
public void AddValidation_RegistersEventService()
{
// Arrange
var services = new ServiceCollection();
var builder = new OpenIddictBuilder(services);
// Act
builder.AddValidation();
// Assert
Assert.Contains(services, service => service.Lifetime == ServiceLifetime.Scoped &&
service.ServiceType == typeof(IOpenIddictValidationEventService) &&
service.ImplementationType == typeof(OpenIddictValidationEventService));
}
[Fact]
public void AddValidation_RegistersHandler()
{
// Arrange
var services = new ServiceCollection();
var builder = new OpenIddictBuilder(services);
// Act
builder.AddValidation();
// Assert
Assert.Contains(services, service => service.Lifetime == ServiceLifetime.Scoped &&
service.ServiceType == typeof(OpenIddictValidationHandler) &&
service.ImplementationType == typeof(OpenIddictValidationHandler));
}
[Fact]
public void AddValidation_RegistersProvider()
{
// Arrange
var services = new ServiceCollection();
var builder = new OpenIddictBuilder(services);
// Act
builder.AddValidation();
// Assert
Assert.Contains(services, service => service.Lifetime == ServiceLifetime.Scoped &&
service.ServiceType == typeof(OpenIddictValidationProvider) &&
service.ImplementationType == typeof(OpenIddictValidationProvider));
}
[Theory]
[InlineData(typeof(IPostConfigureOptions<OpenIddictValidationOptions>), typeof(OpenIddictValidationInitializer))]
[InlineData(typeof(IPostConfigureOptions<OpenIddictValidationOptions>), typeof(OAuthValidationInitializer))]
public void AddValidation_RegistersInitializers(Type serviceType, Type implementationType)
{
// Arrange
var services = new ServiceCollection();
var builder = new OpenIddictBuilder(services);
// Act
builder.AddValidation();
// Assert
Assert.Contains(services, service => service.ServiceType == serviceType &&
service.ImplementationType == implementationType);
}
[Fact]
public void AddValidation_RegistersAuthenticationScheme()
{
// Arrange
var services = new ServiceCollection();
var builder = new OpenIddictBuilder(services);
// Act
builder.AddValidation();
// Assert
var provider = services.BuildServiceProvider();
var options = provider.GetRequiredService<IOptions<AuthenticationOptions>>().Value;
Assert.Contains(options.Schemes, scheme => scheme.Name == OpenIddictValidationDefaults.AuthenticationScheme &&
scheme.HandlerType == typeof(OpenIddictValidationHandler));
}
}
}
Loading…
Cancel
Save