public void AdjustOptionsNameOnGetOrAdd(string name)
    {
        var tc    = new TenantContext("test-id-123", null, null, null, null, null);
        var tca   = new TestTenantContextAccessor(tc);
        var cache = new MultiTenantOptionsCache <CookieAuthenticationOptions>(tca, (o, context) =>
        {
            o.Cookie.Name = context.Id;
        });

        var options = new CookieAuthenticationOptions();

        options.Cookie.Name = "a_name";
        var options2 = new CookieAuthenticationOptions();

        options2.Cookie.Name = "diff_name";

        // Add new options.
        var result = cache.GetOrAdd(name, () => options);

        Assert.Equal(options.Cookie.Name, result.Cookie.Name);

        // Get the existing object.
        result = cache.GetOrAdd(name, () => options2);
        Assert.NotEqual(options2.Cookie.Name, result.Cookie.Name);

        // Confirm different tenant on same object is an add.
        tc.GetType().GetProperty("Id").SetValue(tc, "diff_id");
        result = cache.GetOrAdd(name, () => options2);
        Assert.Equal(options2.Cookie.Name, result.Cookie.Name);
    }
    public void AdjustedOptionsNameOnAdd(string name)
    {
        var tc    = new TenantContext("test-id-123", null, null, null, null, null);
        var tca   = new TestTenantContextAccessor(tc);
        var cache = new MultiTenantOptionsCache <CookieAuthenticationOptions>(tca, (o, context) =>
        {
            o.Cookie.Name = context.Id;
        });

        var options = new CookieAuthenticationOptions();

        // Add new options.
        var result = cache.TryAdd(name, options);

        Assert.True(result);

        // Fail adding options under same name.
        result = cache.TryAdd(name, options);
        Assert.False(result);

        // Change the TC id and confirm options can be added again.
        tc.GetType().GetProperty("Id").SetValue(tc, "diff_id");
        result = cache.TryAdd(name, options);
        Assert.True(result);
    }
    public void RemoveOptionsForAllTenants(string name)
    {
        var tc    = new TenantContext("test-id-123", null, null, null, null, null);
        var tca   = new TestTenantContextAccessor(tc);
        var cache = new MultiTenantOptionsCache <CookieAuthenticationOptions>(tca, (o, context) =>
        {
            o.Cookie.Name = context.Id;
        });

        var options = new CookieAuthenticationOptions();

        // Add new options.
        var result = cache.TryAdd(name, options);

        Assert.True(result);

        tc.GetType().GetProperty("Id").SetValue(tc, "diff_id");
        result = cache.TryAdd(name, options);
        Assert.True(result);

        // Remove all options.
        result = cache.TryRemove(name);
        Assert.True(result);
        Assert.Empty((IEnumerable)cache.GetType().BaseType.
                     GetField("_cache", BindingFlags.NonPublic | BindingFlags.Instance).
                     GetValue(cache));
    }
    public void ThrowIfContructorParamIsNull()
    {
        var tc  = new TenantContext("test-id-123", null, null, null, null, null);
        var tca = new TestTenantContextAccessor(tc);

        Assert.Throws <ArgumentNullException>(() => new MultiTenantOptionsCache <CookieAuthenticationOptions>(tca, null));

        Assert.Throws <ArgumentNullException>(() => new MultiTenantOptionsCache <CookieAuthenticationOptions>(null, (o, context) => o.Cookie.Name = ""));
    }
    public void ThrowsIfGetOtAddFactoryIsNull()
    {
        var tc    = new TenantContext("test-id-123", null, null, null, null, null);
        var tca   = new TestTenantContextAccessor(tc);
        var cache = new MultiTenantOptionsCache <CookieAuthenticationOptions>(tca, (o, context) =>
        {
            o.Cookie.Name = context.Id;
        });

        Assert.Throws <ArgumentNullException>(() => cache.GetOrAdd("", null));
    }
    public void IgnoreNullTenantContext()
    {
        var tca = new TestTenantContextAccessor(null);

        var services = new ServiceCollection();

        services.AddTransient <ITenantContextAccessor>(_sp => tca);
        services.Configure <CookieAuthenticationOptions>(o => o.Cookie.Name      = "begin");
        services.PostConfigure <CookieAuthenticationOptions>(o => o.Cookie.Name += "end");
        var sp = services.BuildServiceProvider();

        Action <CookieAuthenticationOptions, TenantContext> tenantConfig = (o, _tc) => o.Cookie.Name += $"_{_tc.Id}_";

        var factory = ActivatorUtilities.
                      CreateInstance <MultiTenantOptionsFactory <CookieAuthenticationOptions> >(sp, new [] { tenantConfig });

        var options = factory.Create("");

        Assert.Equal($"beginend", options.Cookie.Name);
    }
    public void CreateOptionsWithTenantAction(string name)
    {
        var tc  = new TenantContext("test-id-123", null, null, null, null, null);
        var tca = new TestTenantContextAccessor(tc);

        var services = new ServiceCollection();

        services.AddTransient <ITenantContextAccessor>(_sp => tca);
        services.Configure <CookieAuthenticationOptions>(name, o => o.Cookie.Name      = $"{name}_begin");
        services.PostConfigure <CookieAuthenticationOptions>(name, o => o.Cookie.Name += "end");
        var sp = services.BuildServiceProvider();

        Action <CookieAuthenticationOptions, TenantContext> tenantConfig = (o, _tc) => o.Cookie.Name += $"_{_tc.Id}_";

        var factory = ActivatorUtilities.
                      CreateInstance <MultiTenantOptionsFactory <CookieAuthenticationOptions> >(sp, new [] { tenantConfig });

        var options = factory.Create(name);

        Assert.Equal($"{name}_begin_{tc.Id}_end", options.Cookie.Name);
    }