Browse Source

Remove the initialization logic from the MongoDB stores

pull/996/head
Kévin Chalet 6 years ago
parent
commit
6bec7ad0c9
  1. 1
      src/OpenIddict.Abstractions/Managers/IOpenIddictTokenManager.cs
  2. 5
      src/OpenIddict.Core/Managers/OpenIddictApplicationManager.cs
  3. 5
      src/OpenIddict.Core/Managers/OpenIddictAuthorizationManager.cs
  4. 5
      src/OpenIddict.Core/Managers/OpenIddictScopeManager.cs
  5. 5
      src/OpenIddict.Core/Managers/OpenIddictTokenManager.cs
  6. 17
      src/OpenIddict.MongoDb/OpenIddictMongoDbBuilder.cs
  7. 145
      src/OpenIddict.MongoDb/OpenIddictMongoDbContext.cs
  8. 11
      src/OpenIddict.MongoDb/OpenIddictMongoDbOptions.cs
  9. 34
      test/OpenIddict.MongoDb.Tests/OpenIddictMongoDbBuilderTests.cs
  10. 221
      test/OpenIddict.MongoDb.Tests/OpenIddictMongoDbContextTests.cs

1
src/OpenIddict.Abstractions/Managers/IOpenIddictTokenManager.cs

@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading;

5
src/OpenIddict.Core/Managers/OpenIddictApplicationManager.cs

@ -38,6 +38,11 @@ namespace OpenIddict.Core
/// <summary>
/// Provides methods allowing to manage the applications stored in the store.
/// </summary>
/// <remarks>
/// Applications that do not want to depend on a specific entity type can use the non-generic
/// <see cref="IOpenIddictApplicationManager"/> instead, for which the actual entity type
/// is resolved at runtime based on the default entity type registered in the core options.
/// </remarks>
/// <typeparam name="TApplication">The type of the Application entity.</typeparam>
public class OpenIddictApplicationManager<TApplication> : IOpenIddictApplicationManager where TApplication : class
{

5
src/OpenIddict.Core/Managers/OpenIddictAuthorizationManager.cs

@ -26,6 +26,11 @@ namespace OpenIddict.Core
/// <summary>
/// Provides methods allowing to manage the authorizations stored in the store.
/// </summary>
/// <remarks>
/// Applications that do not want to depend on a specific entity type can use the non-generic
/// <see cref="IOpenIddictAuthorizationManager"/> instead, for which the actual entity type
/// is resolved at runtime based on the default entity type registered in the core options.
/// </remarks>
/// <typeparam name="TAuthorization">The type of the Authorization entity.</typeparam>
public class OpenIddictAuthorizationManager<TAuthorization> : IOpenIddictAuthorizationManager where TAuthorization : class
{

5
src/OpenIddict.Core/Managers/OpenIddictScopeManager.cs

@ -24,6 +24,11 @@ namespace OpenIddict.Core
/// <summary>
/// Provides methods allowing to manage the scopes stored in the store.
/// </summary>
/// <remarks>
/// Applications that do not want to depend on a specific entity type can use the non-generic
/// <see cref="IOpenIddictScopeManager"/> instead, for which the actual entity type
/// is resolved at runtime based on the default entity type registered in the core options.
/// </remarks>
/// <typeparam name="TScope">The type of the Scope entity.</typeparam>
public class OpenIddictScopeManager<TScope> : IOpenIddictScopeManager where TScope : class
{

5
src/OpenIddict.Core/Managers/OpenIddictTokenManager.cs

@ -26,6 +26,11 @@ namespace OpenIddict.Core
/// <summary>
/// Provides methods allowing to manage the tokens stored in the store.
/// </summary>
/// <remarks>
/// Applications that do not want to depend on a specific entity type can use the non-generic
/// <see cref="IOpenIddictTokenManager"/> instead, for which the actual entity type
/// is resolved at runtime based on the default entity type registered in the core options.
/// </remarks>
/// <typeparam name="TToken">The type of the Token entity.</typeparam>
public class OpenIddictTokenManager<TToken> : IOpenIddictTokenManager where TToken : class
{

17
src/OpenIddict.MongoDb/OpenIddictMongoDbBuilder.cs

@ -50,14 +50,6 @@ namespace Microsoft.Extensions.DependencyInjection
return this;
}
/// <summary>
/// Disables initialization so that the MongoDB indexes used by OpenIddict
/// are not automatically created the first time the stores are invoked.
/// </summary>
/// <returns>The <see cref="OpenIddictMongoDbBuilder"/>.</returns>
public OpenIddictMongoDbBuilder DisableInitialization()
=> Configure(options => options.DisableInitialization = true);
/// <summary>
/// Configures OpenIddict to use the specified entity as the default application entity.
/// </summary>
@ -136,15 +128,6 @@ namespace Microsoft.Extensions.DependencyInjection
return Configure(options => options.AuthorizationsCollectionName = name);
}
/// <summary>
/// Sets the maximal duration given to the MongoDB client to initialize
/// the database and register the indexes used by the OpenIddict entities.
/// </summary>
/// <param name="timeout">The timeout.</param>
/// <returns>The <see cref="OpenIddictMongoDbBuilder"/>.</returns>
public OpenIddictMongoDbBuilder SetInitializationTimeout(TimeSpan timeout)
=> Configure(options => options.InitializationTimeout = timeout);
/// <summary>
/// Replaces the default scopes collection name (by default, openiddict.scopes).
/// </summary>

145
src/OpenIddict.MongoDb/OpenIddictMongoDbContext.cs

@ -12,19 +12,16 @@ using JetBrains.Annotations;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using MongoDB.Driver;
using OpenIddict.MongoDb.Models;
namespace OpenIddict.MongoDb
{
/// <summary>
/// Exposes the MongoDB database used by the OpenIddict stores.
/// </summary>
public class OpenIddictMongoDbContext : IOpenIddictMongoDbContext, IDisposable
public class OpenIddictMongoDbContext : IOpenIddictMongoDbContext
{
private readonly IOptionsMonitor<OpenIddictMongoDbOptions> _options;
private readonly IServiceProvider _provider;
private readonly SemaphoreSlim _semaphore;
private IMongoDatabase _database;
public OpenIddictMongoDbContext(
[NotNull] IOptionsMonitor<OpenIddictMongoDbOptions> options,
@ -32,14 +29,8 @@ namespace OpenIddict.MongoDb
{
_options = options;
_provider = provider;
_semaphore = new SemaphoreSlim(1);
}
/// <summary>
/// Disposes the semaphore held by this instance.
/// </summary>
public void Dispose() => _semaphore.Dispose();
/// <summary>
/// Gets the <see cref="IMongoDatabase"/>.
/// </summary>
@ -49,135 +40,29 @@ namespace OpenIddict.MongoDb
/// </returns>
public ValueTask<IMongoDatabase> GetDatabaseAsync(CancellationToken cancellationToken)
{
if (_database != null)
{
return new ValueTask<IMongoDatabase>(_database);
}
if (cancellationToken.IsCancellationRequested)
{
return new ValueTask<IMongoDatabase>(Task.FromCanceled<IMongoDatabase>(cancellationToken));
}
async Task<IMongoDatabase> ExecuteAsync()
var database = _options.CurrentValue.Database;
if (database == null)
{
var options = _options.CurrentValue;
if (options == null)
{
throw new InvalidOperationException("The OpenIddict MongoDB options cannot be retrieved.");
}
if (!await _semaphore.WaitAsync(options.InitializationTimeout, cancellationToken))
{
throw new InvalidOperationException(new StringBuilder()
.AppendLine("The MongoDB database couldn't be initialized within a reasonable timeframe.")
.Append("Make sure that the MongoDB server is ready and accepts connections from this machine or use ")
.Append("'services.AddOpenIddict().AddCore().UseMongoDb().SetInitializationTimeout()' to adjust the timeout.")
.ToString());
}
try
{
var database = options.Database;
if (database == null)
{
database = _provider.GetService<IMongoDatabase>();
}
if (database == null)
{
throw new InvalidOperationException(new StringBuilder()
.AppendLine("No suitable MongoDB database service can be found.")
.Append("To configure the OpenIddict MongoDB stores to use a specific database, use ")
.Append("'services.AddOpenIddict().AddCore().UseMongoDb().UseDatabase()' or register an ")
.Append("'IMongoDatabase' in the dependency injection container in 'ConfigureServices()'.")
.ToString());
}
if (!options.DisableInitialization)
{
// Note: the cancellation token passed as a parameter is deliberately not used here to ensure
// the cancellation of a single store operation doesn't prevent the indexes from being created.
var applications = database.GetCollection<OpenIddictMongoDbApplication>(options.ApplicationsCollectionName);
await applications.Indexes.CreateManyAsync(new[]
{
new CreateIndexModel<OpenIddictMongoDbApplication>(
Builders<OpenIddictMongoDbApplication>.IndexKeys.Ascending(application => application.ClientId),
new CreateIndexOptions
{
Unique = true
}),
new CreateIndexModel<OpenIddictMongoDbApplication>(
Builders<OpenIddictMongoDbApplication>.IndexKeys.Ascending(application => application.PostLogoutRedirectUris),
new CreateIndexOptions
{
Background = true
}),
new CreateIndexModel<OpenIddictMongoDbApplication>(
Builders<OpenIddictMongoDbApplication>.IndexKeys.Ascending(application => application.RedirectUris),
new CreateIndexOptions
{
Background = true
})
});
var authorizations = database.GetCollection<OpenIddictMongoDbAuthorization>(options.AuthorizationsCollectionName);
await authorizations.Indexes.CreateOneAsync(new CreateIndexModel<OpenIddictMongoDbAuthorization>(
Builders<OpenIddictMongoDbAuthorization>.IndexKeys
.Ascending(authorization => authorization.ApplicationId)
.Ascending(authorization => authorization.Scopes)
.Ascending(authorization => authorization.Status)
.Ascending(authorization => authorization.Subject)
.Ascending(authorization => authorization.Type),
new CreateIndexOptions
{
Background = true
}));
var scopes = database.GetCollection<OpenIddictMongoDbScope>(options.ScopesCollectionName);
await scopes.Indexes.CreateOneAsync(new CreateIndexModel<OpenIddictMongoDbScope>(
Builders<OpenIddictMongoDbScope>.IndexKeys.Ascending(scope => scope.Name),
new CreateIndexOptions
{
Unique = true
}));
var tokens = database.GetCollection<OpenIddictMongoDbToken>(options.TokensCollectionName);
await tokens.Indexes.CreateManyAsync(new[]
{
new CreateIndexModel<OpenIddictMongoDbToken>(
Builders<OpenIddictMongoDbToken>.IndexKeys.Ascending(token => token.ReferenceId),
new CreateIndexOptions<OpenIddictMongoDbToken>
{
PartialFilterExpression = Builders<OpenIddictMongoDbToken>.Filter.Exists(token => token.ReferenceId),
Unique = true
}),
new CreateIndexModel<OpenIddictMongoDbToken>(
Builders<OpenIddictMongoDbToken>.IndexKeys
.Ascending(token => token.ApplicationId)
.Ascending(token => token.Status)
.Ascending(token => token.Subject)
.Ascending(token => token.Type),
new CreateIndexOptions
{
Background = true
})
});
}
return _database = database;
}
database = _provider.GetService<IMongoDatabase>();
}
finally
{
_semaphore.Release();
}
if (database == null)
{
return new ValueTask<IMongoDatabase>(Task.FromException<IMongoDatabase>(
new InvalidOperationException(new StringBuilder()
.AppendLine("No suitable MongoDB database service can be found.")
.Append("To configure the OpenIddict MongoDB stores to use a specific database, use ")
.Append("'services.AddOpenIddict().AddCore().UseMongoDb().UseDatabase()' or register an ")
.Append("'IMongoDatabase' in the dependency injection container in 'ConfigureServices()'.")
.ToString())));
}
return new ValueTask<IMongoDatabase>(ExecuteAsync());
return new ValueTask<IMongoDatabase>(database);
}
}
}

11
src/OpenIddict.MongoDb/OpenIddictMongoDbOptions.cs

@ -30,17 +30,6 @@ namespace OpenIddict.MongoDb
/// </summary>
public IMongoDatabase Database { get; set; }
/// <summary>
/// Gets or sets a boolean indicating whether automatic initialization should be disabled.
/// </summary>
public bool DisableInitialization { get; set; }
/// <summary>
/// Gets or sets the maximal duration given to the MongoDB client to initialize
/// the database and register the indexes used by the OpenIddict entities.
/// </summary>
public TimeSpan InitializationTimeout { get; set; } = TimeSpan.FromSeconds(30);
/// <summary>
/// Gets or sets the name of the scopes collection (by default, openiddict.scopes).
/// </summary>

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

@ -29,23 +29,6 @@ namespace OpenIddict.MongoDb.Tests
Assert.Equal("services", exception.ParamName);
}
[Fact]
public void DisableInitialization_InitializationIsCorrectlyDisabled()
{
// Arrange
var services = CreateServices();
var builder = CreateBuilder(services);
// Act
builder.DisableInitialization();
// Assert
var provider = services.BuildServiceProvider();
var options = provider.GetRequiredService<IOptionsMonitor<OpenIddictMongoDbOptions>>().CurrentValue;
Assert.True(options.DisableInitialization);
}
[Fact]
public void ReplaceDefaultApplicationEntity_EntityIsCorrectlySet()
{
@ -213,23 +196,6 @@ namespace OpenIddict.MongoDb.Tests
Assert.Equal("custom_collection", options.ScopesCollectionName);
}
[Fact]
public void SetInitializationTimeout_TimeoutIsCorrectlySet()
{
// Arrange
var services = CreateServices();
var builder = CreateBuilder(services);
// Act
builder.SetInitializationTimeout(TimeSpan.FromDays(42));
// Assert
var provider = services.BuildServiceProvider();
var options = provider.GetRequiredService<IOptionsMonitor<OpenIddictMongoDbOptions>>().CurrentValue;
Assert.Equal(TimeSpan.FromDays(42), options.InitializationTimeout);
}
[Theory]
[InlineData(null)]
[InlineData("")]

221
test/OpenIddict.MongoDb.Tests/OpenIddictMongoDbContextTests.cs

@ -5,7 +5,6 @@
*/
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
@ -13,7 +12,6 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using MongoDB.Driver;
using Moq;
using OpenIddict.MongoDb.Models;
using Xunit;
namespace OpenIddict.MongoDb.Tests
@ -30,7 +28,7 @@ namespace OpenIddict.MongoDb.Tests
var options = Mock.Of<IOptionsMonitor<OpenIddictMongoDbOptions>>();
var token = new CancellationToken(canceled: true);
using var context = new OpenIddictMongoDbContext(options, provider);
var context = new OpenIddictMongoDbContext(options, provider);
// Act and assert
var exception = await Assert.ThrowsAsync<TaskCanceledException>(async delegate
@ -41,76 +39,6 @@ namespace OpenIddict.MongoDb.Tests
Assert.Equal(token, exception.CancellationToken);
}
[Fact]
public async Task GetDatabaseAsync_ThrowsAnExceptionForNullOptions()
{
// Arrange
var services = new ServiceCollection();
var provider = services.BuildServiceProvider();
var database = GetDatabase();
var options = Mock.Of<IOptionsMonitor<OpenIddictMongoDbOptions>>();
using var context = new OpenIddictMongoDbContext(options, provider);
// Act and assert
var exception = await Assert.ThrowsAsync<InvalidOperationException>(async delegate
{
await context.GetDatabaseAsync(CancellationToken.None);
});
Assert.Equal("The OpenIddict MongoDB options cannot be retrieved.", exception.Message);
}
[Fact]
public async Task GetDatabaseAsync_ThrowsAnExceptionForConcurrentCallsWhenInitializationTimesOut()
{
// Arrange
var services = new ServiceCollection();
var provider = services.BuildServiceProvider();
var manager = new Mock<IMongoIndexManager<OpenIddictMongoDbApplication>>();
manager.Setup(mock => mock.CreateManyAsync(It.IsAny<IEnumerable<CreateIndexModel<OpenIddictMongoDbApplication>>>(), It.IsAny<CancellationToken>()))
.Returns(async delegate
{
await Task.Delay(TimeSpan.FromMilliseconds(1000));
return new[] { string.Empty };
});
var collection = new Mock<IMongoCollection<OpenIddictMongoDbApplication>>();
collection.SetupGet(mock => mock.Indexes)
.Returns(manager.Object);
var database = GetDatabase();
database.Setup(mock => mock.GetCollection<OpenIddictMongoDbApplication>(It.IsAny<string>(), It.IsAny<MongoCollectionSettings>()))
.Returns(collection.Object);
var options = Mock.Of<IOptionsMonitor<OpenIddictMongoDbOptions>>(
mock => mock.CurrentValue == new OpenIddictMongoDbOptions
{
Database = database.Object,
InitializationTimeout = TimeSpan.FromMilliseconds(50)
});
using var context = new OpenIddictMongoDbContext(options, provider);
// Act and assert
var exception = await Assert.ThrowsAsync<InvalidOperationException>(delegate
{
return Task.WhenAll(
context.GetDatabaseAsync(CancellationToken.None).AsTask(),
context.GetDatabaseAsync(CancellationToken.None).AsTask(),
context.GetDatabaseAsync(CancellationToken.None).AsTask(),
context.GetDatabaseAsync(CancellationToken.None).AsTask());
});
Assert.Equal(new StringBuilder()
.AppendLine("The MongoDB database couldn't be initialized within a reasonable timeframe.")
.Append("Make sure that the MongoDB server is ready and accepts connections from this machine or use ")
.Append("'services.AddOpenIddict().AddCore().UseMongoDb().SetInitializationTimeout()' to adjust the timeout.")
.ToString(), exception.Message);
}
[Fact]
public async Task GetDatabaseAsync_PrefersDatabaseRegisteredInOptionsToDatabaseRegisteredInDependencyInjectionContainer()
{
@ -120,17 +48,17 @@ namespace OpenIddict.MongoDb.Tests
var provider = services.BuildServiceProvider();
var database = GetDatabase();
var database = Mock.Of<IMongoDatabase>();
var options = Mock.Of<IOptionsMonitor<OpenIddictMongoDbOptions>>(
mock => mock.CurrentValue == new OpenIddictMongoDbOptions
{
Database = database.Object
Database = database
});
using var context = new OpenIddictMongoDbContext(options, provider);
var context = new OpenIddictMongoDbContext(options, provider);
// Act and assert
Assert.Same(database.Object, await context.GetDatabaseAsync(CancellationToken.None));
Assert.Same(database, await context.GetDatabaseAsync(CancellationToken.None));
}
[Fact]
@ -140,14 +68,13 @@ namespace OpenIddict.MongoDb.Tests
var services = new ServiceCollection();
var provider = services.BuildServiceProvider();
var database = GetDatabase();
var options = Mock.Of<IOptionsMonitor<OpenIddictMongoDbOptions>>(
mock => mock.CurrentValue == new OpenIddictMongoDbOptions
{
Database = null
});
using var context = new OpenIddictMongoDbContext(options, provider);
var context = new OpenIddictMongoDbContext(options, provider);
// Act and assert
var exception = await Assert.ThrowsAsync<InvalidOperationException>(async delegate
@ -170,8 +97,8 @@ namespace OpenIddict.MongoDb.Tests
var services = new ServiceCollection();
services.AddSingleton(Mock.Of<IMongoDatabase>());
var database = GetDatabase();
services.AddSingleton(database.Object);
var database = Mock.Of<IMongoDatabase>();
services.AddSingleton(database);
var provider = services.BuildServiceProvider();
@ -181,138 +108,10 @@ namespace OpenIddict.MongoDb.Tests
Database = null
});
using var context = new OpenIddictMongoDbContext(options, provider);
var context = new OpenIddictMongoDbContext(options, provider);
// Act and assert
Assert.Same(database.Object, await context.GetDatabaseAsync(CancellationToken.None));
}
[Fact]
public async Task GetDatabaseAsync_SkipsInitializationWhenDisabled()
{
// Arrange
var services = new ServiceCollection();
var provider = services.BuildServiceProvider();
var database = GetDatabase();
var options = Mock.Of<IOptionsMonitor<OpenIddictMongoDbOptions>>(
mock => mock.CurrentValue == new OpenIddictMongoDbOptions
{
Database = database.Object,
DisableInitialization = true
});
using var context = new OpenIddictMongoDbContext(options, provider);
// Act
await context.GetDatabaseAsync(CancellationToken.None);
// Assert
database.Verify(mock => mock.GetCollection<OpenIddictMongoDbApplication>(It.IsAny<string>(), It.IsAny<MongoCollectionSettings>()), Times.Never());
database.Verify(mock => mock.GetCollection<OpenIddictMongoDbAuthorization>(It.IsAny<string>(), It.IsAny<MongoCollectionSettings>()), Times.Never());
database.Verify(mock => mock.GetCollection<OpenIddictMongoDbScope>(It.IsAny<string>(), It.IsAny<MongoCollectionSettings>()), Times.Never());
database.Verify(mock => mock.GetCollection<OpenIddictMongoDbToken>(It.IsAny<string>(), It.IsAny<MongoCollectionSettings>()), Times.Never());
}
[Fact]
public async Task GetDatabaseAsync_ReturnsCachedDatabase()
{
// Arrange
var services = new ServiceCollection();
var provider = services.BuildServiceProvider();
var database = GetDatabase();
var options = Mock.Of<IOptionsMonitor<OpenIddictMongoDbOptions>>(
mock => mock.CurrentValue == new OpenIddictMongoDbOptions
{
Database = database.Object
});
using var context = new OpenIddictMongoDbContext(options, provider);
// Act and assert
Assert.Same(database.Object, await context.GetDatabaseAsync(CancellationToken.None));
Assert.Same(database.Object, await context.GetDatabaseAsync(CancellationToken.None));
database.Verify(mock => mock.GetCollection<OpenIddictMongoDbApplication>(It.IsAny<string>(), It.IsAny<MongoCollectionSettings>()), Times.Once());
database.Verify(mock => mock.GetCollection<OpenIddictMongoDbAuthorization>(It.IsAny<string>(), It.IsAny<MongoCollectionSettings>()), Times.Once());
database.Verify(mock => mock.GetCollection<OpenIddictMongoDbScope>(It.IsAny<string>(), It.IsAny<MongoCollectionSettings>()), Times.Once());
database.Verify(mock => mock.GetCollection<OpenIddictMongoDbToken>(It.IsAny<string>(), It.IsAny<MongoCollectionSettings>()), Times.Once());
}
[Fact]
public async Task GetDatabaseAsync_FailedInvocationDoesNotPreventFutureInvocations()
{
// Arrange
var services = new ServiceCollection();
var provider = services.BuildServiceProvider();
var count = 0;
var collection = new Mock<IMongoCollection<OpenIddictMongoDbApplication>>();
collection.SetupGet(mock => mock.Indexes)
.Returns(Mock.Of<IMongoIndexManager<OpenIddictMongoDbApplication>>());
var database = GetDatabase();
database.Setup(mock => mock.GetCollection<OpenIddictMongoDbApplication>(It.IsAny<string>(), It.IsAny<MongoCollectionSettings>()))
.Callback(() => count++)
.Returns(delegate
{
if (count == 1)
{
throw new Exception();
}
return collection.Object;
});
var options = Mock.Of<IOptionsMonitor<OpenIddictMongoDbOptions>>(
mock => mock.CurrentValue == new OpenIddictMongoDbOptions
{
Database = database.Object
});
using var context = new OpenIddictMongoDbContext(options, provider);
// Act and assert
await Assert.ThrowsAsync<Exception>(async () => await context.GetDatabaseAsync(CancellationToken.None));
Assert.Same(database.Object, await context.GetDatabaseAsync(CancellationToken.None));
database.Verify(mock => mock.GetCollection<OpenIddictMongoDbApplication>(It.IsAny<string>(), It.IsAny<MongoCollectionSettings>()), Times.Exactly(2));
database.Verify(mock => mock.GetCollection<OpenIddictMongoDbAuthorization>(It.IsAny<string>(), It.IsAny<MongoCollectionSettings>()), Times.Once());
database.Verify(mock => mock.GetCollection<OpenIddictMongoDbScope>(It.IsAny<string>(), It.IsAny<MongoCollectionSettings>()), Times.Once());
database.Verify(mock => mock.GetCollection<OpenIddictMongoDbToken>(It.IsAny<string>(), It.IsAny<MongoCollectionSettings>()), Times.Once());
}
private static Mock<IMongoDatabase> GetDatabase()
{
var applications = new Mock<IMongoCollection<OpenIddictMongoDbApplication>>();
applications.SetupGet(mock => mock.Indexes)
.Returns(Mock.Of<IMongoIndexManager<OpenIddictMongoDbApplication>>());
var authorizations = new Mock<IMongoCollection<OpenIddictMongoDbAuthorization>>();
authorizations.SetupGet(mock => mock.Indexes)
.Returns(Mock.Of<IMongoIndexManager<OpenIddictMongoDbAuthorization>>());
var scopes = new Mock<IMongoCollection<OpenIddictMongoDbScope>>();
scopes.SetupGet(mock => mock.Indexes)
.Returns(Mock.Of<IMongoIndexManager<OpenIddictMongoDbScope>>());
var tokens = new Mock<IMongoCollection<OpenIddictMongoDbToken>>();
tokens.SetupGet(mock => mock.Indexes)
.Returns(Mock.Of<IMongoIndexManager<OpenIddictMongoDbToken>>());
var database = new Mock<IMongoDatabase>();
database.Setup(mock => mock.GetCollection<OpenIddictMongoDbApplication>(It.IsAny<string>(), It.IsAny<MongoCollectionSettings>()))
.Returns(applications.Object);
database.Setup(mock => mock.GetCollection<OpenIddictMongoDbAuthorization>(It.IsAny<string>(), It.IsAny<MongoCollectionSettings>()))
.Returns(authorizations.Object);
database.Setup(mock => mock.GetCollection<OpenIddictMongoDbScope>(It.IsAny<string>(), It.IsAny<MongoCollectionSettings>()))
.Returns(scopes.Object);
database.Setup(mock => mock.GetCollection<OpenIddictMongoDbToken>(It.IsAny<string>(), It.IsAny<MongoCollectionSettings>()))
.Returns(tokens.Object);
return database;
Assert.Same(database, await context.GetDatabaseAsync(CancellationToken.None));
}
}
}

Loading…
Cancel
Save