From 311d9ca5a47f24c7a28e4d5e34f720d177aaa9b8 Mon Sep 17 00:00:00 2001 From: IgorHrabrov <18480638+IgorHrabrov@users.noreply.github.com> Date: Tue, 3 Dec 2019 22:27:52 +0200 Subject: [PATCH] Port the AspNet.Security.OpenIdConnect.Extensions tests --- .../Primitives/OpenIddictExtensions.cs | 8 +- .../Primitives/OpenIddictExtensionsTests.cs | 1460 +++++++++++++++++ 2 files changed, 1461 insertions(+), 7 deletions(-) diff --git a/src/OpenIddict.Abstractions/Primitives/OpenIddictExtensions.cs b/src/OpenIddict.Abstractions/Primitives/OpenIddictExtensions.cs index 3f751541..e53595fb 100644 --- a/src/OpenIddict.Abstractions/Primitives/OpenIddictExtensions.cs +++ b/src/OpenIddict.Abstractions/Primitives/OpenIddictExtensions.cs @@ -1123,7 +1123,6 @@ namespace OpenIddict.Abstractions /// /// The claims principal. /// The access token lifetime or null if the claim cannot be found. - public static TimeSpan? GetAccessTokenLifetime([NotNull] this ClaimsPrincipal principal) { if (principal == null) @@ -1150,7 +1149,6 @@ namespace OpenIddict.Abstractions /// /// The claims principal. /// The authorization code lifetime or null if the claim cannot be found. - public static TimeSpan? GetAuthorizationCodeLifetime([NotNull] this ClaimsPrincipal principal) { if (principal == null) @@ -1177,7 +1175,6 @@ namespace OpenIddict.Abstractions /// /// The claims principal. /// The device code lifetime or null if the claim cannot be found. - public static TimeSpan? GetDeviceCodeLifetime([NotNull] this ClaimsPrincipal principal) { if (principal == null) @@ -1204,7 +1201,6 @@ namespace OpenIddict.Abstractions /// /// The claims principal. /// The identity token lifetime or null if the claim cannot be found. - public static TimeSpan? GetIdentityTokenLifetime([NotNull] this ClaimsPrincipal principal) { if (principal == null) @@ -1231,7 +1227,6 @@ namespace OpenIddict.Abstractions /// /// The claims principal. /// The refresh token lifetime or null if the claim cannot be found. - public static TimeSpan? GetRefreshTokenLifetime([NotNull] this ClaimsPrincipal principal) { if (principal == null) @@ -1258,7 +1253,6 @@ namespace OpenIddict.Abstractions /// /// The claims principal. /// The user code lifetime or null if the claim cannot be found. - public static TimeSpan? GetUserCodeLifetime([NotNull] this ClaimsPrincipal principal) { if (principal == null) @@ -1669,7 +1663,7 @@ namespace OpenIddict.Abstractions /// The claims principal. public static ClaimsPrincipal SetResources( [NotNull] this ClaimsPrincipal principal, [CanBeNull] ImmutableArray resources) - => principal.SetClaims(Claims.Private.Resources, resources); + => principal.SetClaims(Claims.Private.Resources, resources); /// /// Sets the resources list in the claims principal. diff --git a/test/OpenIddict.Abstractions.Tests/Primitives/OpenIddictExtensionsTests.cs b/test/OpenIddict.Abstractions.Tests/Primitives/OpenIddictExtensionsTests.cs index eaf52914..14974a03 100644 --- a/test/OpenIddict.Abstractions.Tests/Primitives/OpenIddictExtensionsTests.cs +++ b/test/OpenIddict.Abstractions.Tests/Primitives/OpenIddictExtensionsTests.cs @@ -5,6 +5,10 @@ */ using System; +using System.Collections.Immutable; +using System.Globalization; +using System.Linq; +using System.Security.Claims; using Xunit; namespace OpenIddict.Abstractions.Tests.Primitives @@ -890,5 +894,1461 @@ namespace OpenIddict.Abstractions.Tests.Primitives // Act and assert Assert.Equal(result, request.IsRefreshTokenGrantType()); } + + [Fact] + public void GetDestinations_ThrowsAnExceptionForNullClaim() + { + // Arrange + var claim = (Claim) null; + + // Act and assert + var exception = Assert.Throws(() => claim.GetDestinations()); + + Assert.Equal("claim", exception.ParamName); + } + + [Theory] + [InlineData(null, new string[0])] + [InlineData("", new string[0])] + [InlineData("[]", new string[0])] + [InlineData(@"[""id_token""]", new[] { "id_token" })] + [InlineData(@"[""access_token"",""id_token""]", new[] { "access_token", "id_token" })] + [InlineData(@"[""access_token"",""access_token"",""id_token""]", new[] { "access_token", "id_token" })] + [InlineData(@"[""access_token"",""ACCESS_TOKEN"",""id_token""]", new[] { "access_token", "id_token" })] + public void GetDestinations_ReturnsExpectedDestinations(string destination, string[] destinations) + { + // Arrange + var claim = new Claim(OpenIddictConstants.Claims.Name, "Bob le Bricoleur"); + claim.Properties[OpenIddictConstants.Properties.Destinations] = destination; + + // Act and assert + Assert.Equal(destinations, claim.GetDestinations()); + } + + [Fact] + public void SetDestinations_ThrowsAnExceptionForNullClaim() + { + // Arrange + var claim = (Claim) null; + + // Act and assert + var exception = Assert.Throws(() => claim.SetDestinations()); + + Assert.Equal("claim", exception.ParamName); + } + + [Theory] + [InlineData(null)] + [InlineData(new object[] { new string[0] })] + public void SetDestinations_RemovesPropertyForEmptyArray(string[] destinations) + { + // Arrange + var claim = new Claim(OpenIddictConstants.Claims.Name, "Bob le Bricoleur"); + + // Act + claim.SetDestinations(destinations); + + // Assert + Assert.Equal(0, claim.Properties.Count); + } + + [Theory] + [InlineData(null)] + [InlineData("")] + public void SetDestinations_ThrowsAnExceptionForNullOrEmptyDestinations(string destination) + { + // Arrange + var claim = new Claim(OpenIddictConstants.Claims.Name, "Bob le Bricoleur"); + + // Act and assert + var exception = Assert.Throws(() => claim.SetDestinations(destination)); + + Assert.Equal("destinations", exception.ParamName); + Assert.StartsWith("Destinations cannot be null or empty.", exception.Message); + } + + [Theory] + [InlineData(new[] { "access_token" }, @"[""access_token""]")] + [InlineData(new[] { "access_token", "id_token" }, @"[""access_token"",""id_token""]")] + [InlineData(new[] { "access_token", "access_token", "id_token" }, @"[""access_token"",""id_token""]")] + [InlineData(new[] { "access_token", "ACCESS_TOKEN", "id_token" }, @"[""access_token"",""id_token""]")] + public void SetDestinations_SetsAppropriateDestinations(string[] destinations, string destination) + { + // Arrange + var claim = new Claim(OpenIddictConstants.Claims.Name, "Bob le Bricoleur"); + + // Act + claim.SetDestinations(destinations); + + // Assert + Assert.Equal(destination, claim.Properties[OpenIddictConstants.Properties.Destinations]); + } + + [Fact] + public void ClaimsIdentity_Clone_ReturnsDifferentInstanceWithFilteredClaims() + { + // Arrange + var identity = new ClaimsIdentity(); + identity.AddClaim(new Claim(OpenIddictConstants.Claims.Name, "Bob le Bricoleur")); + identity.AddClaim(new Claim(OpenIddictConstants.Claims.ClientId, "B56BF6CE-8D8C-4290-A0E7-A4F8EE0A9FC4")); + + // Act + var clone = identity.Clone(claim => claim.Type == OpenIddictConstants.Claims.Name); + clone.AddClaim(new Claim("clone_claim", "value")); + + // Assert + Assert.NotSame(identity, clone); + Assert.Null(identity.FindFirst("clone_claim")); + Assert.NotNull(clone.FindFirst(OpenIddictConstants.Claims.Name)); + Assert.Null(clone.FindFirst(OpenIddictConstants.Claims.ClientId)); + } + + [Fact] + public void ClaimsIdentity_Clone_ExcludesUnwantedClaims() + { + // Arrange + var identity = new ClaimsIdentity(); + identity.AddClaim(new Claim(OpenIddictConstants.Claims.Name, "Bob le Bricoleur")); + identity.AddClaim(new Claim(OpenIddictConstants.Claims.Subject, "D8F1A010-BD46-4F8F-AD4E-05582307F8F4")); + + // Act + var clone = identity.Clone(claim => claim.Type == OpenIddictConstants.Claims.Name); + + // Assert + Assert.Single(clone.Claims); + Assert.Null(clone.FindFirst(OpenIddictConstants.Claims.Subject)); + Assert.Equal("Bob le Bricoleur", clone.FindFirst(OpenIddictConstants.Claims.Name).Value); + } + + [Fact] + public void ClaimsIdentity_Clone_ExcludesUnwantedClaimsFromActor() + { + // Arrange + var identity = new ClaimsIdentity + { + Actor = new ClaimsIdentity() + }; + identity.Actor.AddClaim(new Claim(OpenIddictConstants.Claims.Name, "Bob le Bricoleur")); + identity.Actor.AddClaim(new Claim(OpenIddictConstants.Claims.Subject, "D8F1A010-BD46-4F8F-AD4E-05582307F8F4")); + + // Act + var clone = identity.Clone(claim => claim.Type == OpenIddictConstants.Claims.Name); + + // Assert + Assert.Single(clone.Actor.Claims); + Assert.Null(clone.Actor.FindFirst(OpenIddictConstants.Claims.Subject)); + Assert.Equal("Bob le Bricoleur", clone.Actor.FindFirst(OpenIddictConstants.Claims.Name).Value); + } + + [Fact] + public void ClaimsPrincipal_Clone_ExcludesUnwantedClaimsFromIdentities() + { + // Arrange + var identity = new ClaimsIdentity(); + identity.AddClaim(new Claim(OpenIddictConstants.Claims.Name, "Bob le Bricoleur")); + identity.AddClaim(new Claim(OpenIddictConstants.Claims.Subject, "D8F1A010-BD46-4F8F-AD4E-05582307F8F4")); + + var principal = new ClaimsPrincipal(identity); + + // Act + var clone = principal.Clone(claim => claim.Type == OpenIddictConstants.Claims.Name); + + // Assert + Assert.Single(clone.Claims); + Assert.Null(clone.FindFirst(OpenIddictConstants.Claims.Subject)); + Assert.Equal("Bob le Bricoleur", clone.FindFirst(OpenIddictConstants.Claims.Name).Value); + } + + [Fact] + public void AddClaim_ThrowsAnExceptionForNullIdentity() + { + // Arrange + var identity = (ClaimsIdentity) null; + + // Act and assert + var exception = Assert.Throws(() => + { + identity.AddClaim(OpenIddictConstants.Claims.Name, "Bob le Bricoleur"); + }); + + Assert.Equal("identity", exception.ParamName); + } + + [Fact] + public void AddClaim_SetsAppropriateClaim() + { + // Arrange + var identity = new ClaimsIdentity(); + + // Act + identity.AddClaim(OpenIddictConstants.Claims.Name, "Bob le Bricoleur"); + + // Assert + Assert.Equal("Bob le Bricoleur", identity.FindFirst(OpenIddictConstants.Claims.Name).Value); + } + + [Theory] + [InlineData(new[] { "access_token" }, @"[""access_token""]")] + [InlineData(new[] { "access_token", "id_token" }, @"[""access_token"",""id_token""]")] + [InlineData(new[] { "access_token", "access_token", "id_token" }, @"[""access_token"",""id_token""]")] + [InlineData(new[] { "access_token", "ACCESS_TOKEN", "id_token" }, @"[""access_token"",""id_token""]")] + public void AddClaim_SetsAppropriateDestinations(string[] destinations, string destination) + { + // Arrange + var identity = new ClaimsIdentity(); + + // Act + identity.AddClaim(OpenIddictConstants.Claims.Name, "Bob le Bricoleur", destinations); + + var claim = identity.FindFirst(OpenIddictConstants.Claims.Name); + + // Assert + Assert.Equal("Bob le Bricoleur", claim.Value); + Assert.Equal(destination, claim.Properties[OpenIddictConstants.Properties.Destinations]); + } + + [Fact] + public void GetClaim_ThrowsAnExceptionForNullIdentity() + { + // Arrange + var identity = (ClaimsIdentity) null; + + // Act and assert + var exception = Assert.Throws(() => + { + identity.GetClaim(OpenIddictConstants.Claims.Name); + }); + + Assert.Equal("identity", exception.ParamName); + } + + [Fact] + public void GetClaim_ReturnsNullForMissingClaims() + { + // Arrange + var identity = new ClaimsIdentity(); + var principal = new ClaimsPrincipal(); + + // Act and assert + Assert.Null(identity.GetClaim(OpenIddictConstants.Claims.Name)); + Assert.Null(principal.GetClaim(OpenIddictConstants.Claims.Name)); + } + + [Fact] + public void GetClaim_ReturnsAppropriateResult() + { + // Arrange + var identity = new ClaimsIdentity(); + var principal = new ClaimsPrincipal(identity); + + identity.AddClaim(OpenIddictConstants.Claims.Name, "Bob le Bricoleur"); + + // Act and assert + Assert.Equal("Bob le Bricoleur", identity.GetClaim(OpenIddictConstants.Claims.Name)); + Assert.Equal("Bob le Bricoleur", principal.GetClaim(OpenIddictConstants.Claims.Name)); + } + + [Fact] + public void ClaimsIdentity_Clone_ThrowsAnExceptionForNullIdentity() + { + // Arrange + var identity = (ClaimsIdentity) null; + + // Act and assert + var exception = Assert.Throws(() => identity.Clone(c => true)); + + Assert.Equal("identity", exception.ParamName); + } + + [Fact] + public void ClaimsIdentity_Clone_ReturnsIdenticalIdentity() + { + // Arrange + var identity = new ClaimsIdentity(); + identity.AddClaim("type", "value"); + + // Act + var copy = identity.Clone(c => true); + + // Assert + Assert.Equal("value", copy.GetClaim("type")); + Assert.Equal(identity.Claims.Count(), copy.Claims.Count()); + } + + [Fact] + public void ClaimsPrincipal_Clone_ThrowsAnExceptionForNullPrincipal() + { + // Arrange + var principal = (ClaimsPrincipal) null; + + // Act and assert + var exception = Assert.Throws(() => principal.Clone(c => true)); + + Assert.Equal("principal", exception.ParamName); + } + + [Fact] + public void ClaimsPrincipal_Clone_ReturnsIdenticalPrincipal() + { + // Arrange + var identity = new ClaimsIdentity(); + identity.AddClaim(new Claim(OpenIddictConstants.Claims.Name, "Bob le Bricoleur")); + + var principal = new ClaimsPrincipal(identity); + + // Act + var copy = principal.Clone(c => true); + + // Assert + Assert.Equal("Bob le Bricoleur", copy.GetClaim(OpenIddictConstants.Claims.Name)); + Assert.Equal(principal.Claims.Count(), copy.Claims.Count()); + } + + [Fact] + public void ClaimsIdentity_Clone_ReturnsDifferentIdentityInstance() + { + // Arrange + var identity = new ClaimsIdentity(); + identity.AddClaim("type", "value"); + + // Act + var copy = identity.Clone(c => true); + copy.AddClaim("clone_type", "value"); + + // Assert + Assert.NotSame(identity, copy); + Assert.Null(identity.FindFirst("clone_type")); + } + + [Fact] + public void ClaimsPrincipal_Clone_ReturnsDifferentPrincipalInstance() + { + // Arrange + var identity = new ClaimsIdentity(); + identity.AddClaim(new Claim(OpenIddictConstants.Claims.Name, "Bob le Bricoleur")); + + var principal = new ClaimsPrincipal(identity); + + // Act + var copy = principal.Clone(c => true); + copy.SetClaim("clone_claim", "value"); + + // Assert + Assert.NotSame(principal, copy); + Assert.Null(principal.FindFirst("clone_claim")); + } + + [Fact] + public void GetClaim_ThrowsAnExceptionForNullPrincipal() + { + // Arrange + var principal = (ClaimsPrincipal) null; + + // Act and assert + var exception = Assert.Throws(() => principal.GetClaim("type")); + + Assert.Equal("principal", exception.ParamName); + } + + [Fact] + public void GetClaim_ReturnsNullForMissingClaim() + { + // Arrange + var principal = new ClaimsPrincipal(); + + // Act and assert + Assert.Null(principal.GetClaim("type")); + } + + [Fact] + public void GetClaim_IsCaseInsensitive() + { + // Arrange + var identity = new ClaimsIdentity(); + var principal = new ClaimsPrincipal(identity); + principal.SetClaim("type", "value"); + + // Act and assert + Assert.Equal("value", principal.GetClaim("TYPE")); + } + + [Fact] + public void GetAudiences_ThrowsAnExceptionForNullPrincipal() + { + // Arrange + var principal = (ClaimsPrincipal) null; + + // Act and assert + var exception = Assert.Throws(() => principal.GetAudiences()); + + Assert.Equal("principal", exception.ParamName); + } + + [Theory] + [InlineData(new string[0], new string[0])] + [InlineData(new[] { "fabrikam" }, new[] { "fabrikam" })] + [InlineData(new[] { "fabrikam", "contoso" }, new[] { "fabrikam", "contoso" })] + [InlineData(new[] { "fabrikam", "fabrikam", "contoso" }, new[] { "fabrikam", "contoso" })] + [InlineData(new[] { "fabrikam", "FABRIKAM", "contoso" }, new[] { "fabrikam", "FABRIKAM", "contoso" })] + public void GetAudiences_ReturnsExpectedAudiences(string[] audience, string[] audiences) + { + // Arrange + var identity = new ClaimsIdentity(); + var principal = new ClaimsPrincipal(identity); + + principal.SetClaims(OpenIddictConstants.Claims.Audience, audience.ToImmutableArray()); + + // Act and assert + Assert.Equal(audiences, principal.GetAudiences()); + } + + [Fact] + public void GetPresenters_ThrowsAnExceptionForNullPrincipal() + { + // Arrange + var principal = (ClaimsPrincipal) null; + + // Act and assert + var exception = Assert.Throws(() => principal.GetPresenters()); + + Assert.Equal("principal", exception.ParamName); + } + + [Theory] + [InlineData(new string[0], new string[0])] + [InlineData(new[] { "fabrikam" }, new[] { "fabrikam" })] + [InlineData(new[] { "fabrikam", "contoso" }, new[] { "fabrikam", "contoso" })] + [InlineData(new[] { "fabrikam", "fabrikam", "contoso" }, new[] { "fabrikam", "contoso" })] + [InlineData(new[] { "fabrikam", "FABRIKAM", "contoso" }, new[] { "fabrikam", "FABRIKAM", "contoso" })] + public void GetPresenters_ReturnsExpectedPresenters(string[] presenter, string[] presenters) + { + // Arrange + var identity = new ClaimsIdentity(); + var principal = new ClaimsPrincipal(identity); + + principal.SetClaims(OpenIddictConstants.Claims.Private.Presenters, presenter.ToImmutableArray()); + + // Act and assert + Assert.Equal(presenters, principal.GetPresenters()); + } + + [Fact] + public void GetResources_ThrowsAnExceptionForNullPrincipal() + { + // Arrange + var principal = (ClaimsPrincipal) null; + + // Act and assert + var exception = Assert.Throws(() => principal.GetResources()); + + Assert.Equal("principal", exception.ParamName); + } + + [Theory] + [InlineData(new string[0], new string[0])] + [InlineData(new[] { "fabrikam" }, new[] { "fabrikam" })] + [InlineData(new[] { "fabrikam", "contoso" }, new[] { "fabrikam", "contoso" })] + [InlineData(new[] { "fabrikam", "fabrikam", "contoso" }, new[] { "fabrikam", "contoso" })] + [InlineData(new[] { "fabrikam", "FABRIKAM", "contoso" }, new[] { "fabrikam", "FABRIKAM", "contoso" })] + public void GetResources_ReturnsExpectedResources(string[] resource, string[] resources) + { + // Arrange + var identity = new ClaimsIdentity(); + var principal = new ClaimsPrincipal(identity); + + principal.SetClaims(OpenIddictConstants.Claims.Private.Resources, resource.ToImmutableArray()); + + // Act and assert + Assert.Equal(resources, principal.GetResources()); + } + + [Fact] + public void GetScopes_ThrowsAnExceptionForNullPrincipal() + { + // Arrange + var principal = (ClaimsPrincipal) null; + + // Act and assert + var exception = Assert.Throws(() => principal.GetScopes()); + + Assert.Equal("principal", exception.ParamName); + } + + [Theory] + [InlineData(new string[0], new string[0])] + [InlineData(new[] { "openid" }, new[] { "openid" })] + [InlineData(new[] { "openid", "profile" }, new[] { "openid", "profile" })] + [InlineData(new[] { "openid", "openid", "profile" }, new[] { "openid", "profile" })] + [InlineData(new[] { "openid", "OPENID", "profile" }, new[] { "openid", "OPENID", "profile" })] + public void ClaimsPrincipal_GetScopes_ReturnsExpectedScopes(string[] scope, string[] scopes) + { + // Arrange + var identity = new ClaimsIdentity(); + var principal = new ClaimsPrincipal(identity); + + principal.SetClaims(OpenIddictConstants.Claims.Private.Scopes, scope.ToImmutableArray()); + + // Act and assert + Assert.Equal(scopes, principal.GetScopes()); + } + + [Fact] + public void GetAccessTokenLifetime_ThrowsAnExceptionForNullPrincipal() + { + // Arrange + var principal = (ClaimsPrincipal) null; + + // Act and assert + var exception = Assert.Throws(() => principal.GetAccessTokenLifetime()); + + Assert.Equal("principal", exception.ParamName); + } + + [Theory] + [InlineData(null)] + [InlineData("62")] + public void GetAccessTokenLifetime_ReturnsExpectedResult(string lifetime) + { + // Arrange + var identity = new ClaimsIdentity(); + var principal = new ClaimsPrincipal(identity); + + principal.SetClaim(OpenIddictConstants.Claims.Private.AccessTokenLifetime, lifetime); + + // Act and assert + Assert.Equal(ParseLifeTime(lifetime), principal.GetAccessTokenLifetime()); + } + + [Fact] + public void GetAuthorizationCodeLifetime_ThrowsAnExceptionForNullPrincipal() + { + // Arrange + var principal = (ClaimsPrincipal) null; + + // Act and assert + var exception = Assert.Throws(() => principal.GetAuthorizationCodeLifetime()); + + Assert.Equal("principal", exception.ParamName); + } + + [Theory] + [InlineData(null)] + [InlineData("62")] + public void GetAuthorizationCodeLifetime_ReturnsExpectedResult(string lifetime) + { + // Arrange + var identity = new ClaimsIdentity(); + var principal = new ClaimsPrincipal(identity); + + principal.SetClaim(OpenIddictConstants.Claims.Private.AuthorizationCodeLifetime, lifetime); + + // Act and assert + Assert.Equal(ParseLifeTime(lifetime), principal.GetAuthorizationCodeLifetime()); + } + + [Fact] + public void GetIdentityTokenLifetime_ThrowsAnExceptionForNullPrincipal() + { + // Arrange + var principal = (ClaimsPrincipal) null; + + // Act and assert + var exception = Assert.Throws(() => principal.GetIdentityTokenLifetime()); + + Assert.Equal("principal", exception.ParamName); + } + + [Theory] + [InlineData(null)] + [InlineData("62")] + public void GetIdentityTokenLifetime_ReturnsExpectedResult(string lifetime) + { + // Arrange + var identity = new ClaimsIdentity(); + var principal = new ClaimsPrincipal(identity); + + principal.SetClaim(OpenIddictConstants.Claims.Private.IdentityTokenLifetime, lifetime); + + // Act and assert + Assert.Equal(ParseLifeTime(lifetime), principal.GetIdentityTokenLifetime()); + } + + [Fact] + public void GetRefreshTokenLifetime_ThrowsAnExceptionForNullPrincipal() + { + // Arrange + var principal = (ClaimsPrincipal) null; + + // Act and assert + var exception = Assert.Throws(() => principal.GetRefreshTokenLifetime()); + + Assert.Equal("principal", exception.ParamName); + } + + [Theory] + [InlineData(null)] + [InlineData("62")] + public void GetRefreshTokenLifetime_ReturnsExpectedResult(string lifetime) + { + // Arrange + var identity = new ClaimsIdentity(); + var principal = new ClaimsPrincipal(identity); + + principal.SetClaim(OpenIddictConstants.Claims.Private.RefreshTokenLifetime, lifetime); + + // Act and assert + Assert.Equal(ParseLifeTime(lifetime), principal.GetRefreshTokenLifetime()); + } + + [Fact] + public void GetInternalTokenId_ThrowsAnExceptionForNullPrincipal() + { + // Arrange + var principal = (ClaimsPrincipal) null; + + // Act and assert + var exception = Assert.Throws(() => principal.GetInternalTokenId()); + + Assert.Equal("principal", exception.ParamName); + } + + [Theory] + [InlineData(null)] + [InlineData("identifier")] + public void GetInternalTokenId_ReturnsExpectedResult(string identifier) + { + // Arrange + var identity = new ClaimsIdentity(); + var principal = new ClaimsPrincipal(identity); + + principal.SetClaim(OpenIddictConstants.Claims.Private.TokenId, identifier); + + // Act and assert + Assert.Equal(identifier, principal.GetInternalTokenId()); + } + + [Fact] + public void GetTokenUsage_ThrowsAnExceptionForNullPrincipal() + { + // Arrange + var principal = (ClaimsPrincipal) null; + + // Act and assert + var exception = Assert.Throws(() => principal.GetTokenUsage()); + + Assert.Equal("principal", exception.ParamName); + } + + [Theory] + [InlineData(null)] + [InlineData("access_token")] + public void GetTokenUsage_ReturnsExpectedResult(string usage) + { + // Arrange + var identity = new ClaimsIdentity(); + var principal = new ClaimsPrincipal(identity); + + principal.SetClaim(OpenIddictConstants.Claims.Private.TokenUsage, usage); + + // Act and assert + Assert.Equal(usage, principal.GetTokenUsage()); + } + + [Fact] + public void HasAudience_ThrowsAnExceptionForNullPrincipal() + { + // Arrange + var principal = (ClaimsPrincipal) null; + + // Act and assert + var exception = Assert.Throws(() => principal.HasAudience("Fabrikam")); + + Assert.Equal("principal", exception.ParamName); + } + + [Theory] + [InlineData(null)] + [InlineData("")] + public void HasAudience_ThrowsAnExceptionForNullOrEmptyAudience(string audience) + { + // Arrange + var principal = new ClaimsPrincipal(); + + // Act and assert + var exception = Assert.Throws(() => principal.HasAudience(audience)); + + Assert.Equal("audience", exception.ParamName); + Assert.StartsWith("The audience cannot be null or empty.", exception.Message); + } + + [Theory] + [InlineData(new string[0], false)] + [InlineData(new[] { "fabrikam" }, true)] + public void HasAudience_ReturnsExpectedResult(string[] audience, bool result) + { + // Arrange + var identity = new ClaimsIdentity(); + var principal = new ClaimsPrincipal(identity); + + principal.SetClaims(OpenIddictConstants.Claims.Audience, audience.ToImmutableArray()); + + // Act and assert + Assert.Equal(result, principal.HasAudience()); + } + + [Theory] + [InlineData(new string[0], false)] + [InlineData(new[] { "contoso" }, false)] + [InlineData(new[] { "contoso", "fabrikam" }, true)] + [InlineData(new[] { "fabrikam" }, true)] + [InlineData(new[] { "fabrikam", "contoso" }, true)] + [InlineData(new[] { "CONTOSO" }, false)] + [InlineData(new[] { "CONTOSO", "FABRIKAM" }, false)] + [InlineData(new[] { "FABRIKAM" }, false)] + [InlineData(new[] { "FABRIKAM", "CONTOSO" }, false)] + public void HasAudience_ReturnsAppropriateResult(string[] audience, bool result) + { + // Arrange + var identity = new ClaimsIdentity(); + var principal = new ClaimsPrincipal(identity); + + principal.SetClaims(OpenIddictConstants.Claims.Audience, audience.ToImmutableArray()); + + // Act and assert + Assert.Equal(result, principal.HasAudience("fabrikam")); + } + + [Fact] + public void HasPresenter_ThrowsAnExceptionForNullPrincipal() + { + // Arrange + var principal = (ClaimsPrincipal) null; + + // Act and assert + var exception = Assert.Throws(() => principal.HasPresenter("Fabrikam")); + + Assert.Equal("principal", exception.ParamName); + } + + [Theory] + [InlineData(null)] + [InlineData("")] + public void HasPresenter_ThrowsAnExceptionForNullOrEmptyPresenter(string presenter) + { + // Arrange + var principal = new ClaimsPrincipal(); + + // Act and assert + var exception = Assert.Throws(() => principal.HasPresenter(presenter)); + + Assert.Equal("presenter", exception.ParamName); + Assert.StartsWith("The presenter cannot be null or empty.", exception.Message); + } + + [Theory] + [InlineData(new string[0], false)] + [InlineData(new[] { "fabrikam" }, true)] + public void HasPresenter_ReturnsExpectedResult(string[] presenter, bool result) + { + // Arrange + var identity = new ClaimsIdentity(); + var principal = new ClaimsPrincipal(identity); + + principal.SetClaims(OpenIddictConstants.Claims.Private.Presenters, presenter.ToImmutableArray()); + + // Act and assert + Assert.Equal(result, principal.HasPresenter()); + } + + [Theory] + [InlineData(new string[0], false)] + [InlineData(new[] { "contoso" }, false)] + [InlineData(new []{ "contoso", "fabrikam" }, true)] + [InlineData(new []{ "fabrikam" }, true)] + [InlineData(new []{ "fabrikam", "contoso" }, true)] + [InlineData(new []{ "CONTOSO" }, false)] + [InlineData(new []{ "CONTOSO", "FABRIKAM" }, false)] + [InlineData(new []{ "FABRIKAM" }, false)] + [InlineData(new []{ "FABRIKAM", "CONTOSO" }, false)] + public void HasPresenter_ReturnsAppropriateResult(string[] presenter, bool result) + { + // Arrange + var identity = new ClaimsIdentity(); + var principal = new ClaimsPrincipal(identity); + + principal.SetClaims(OpenIddictConstants.Claims.Private.Presenters, presenter.ToImmutableArray()); + + // Act and assert + Assert.Equal(result, principal.HasPresenter("fabrikam")); + } + + [Fact] + public void HasResource_ThrowsAnExceptionForNullPrincipal() + { + // Arrange + var principal = (ClaimsPrincipal) null; + + // Act and assert + var exception = Assert.Throws(() => principal.HasResource("Fabrikam")); + + Assert.Equal("principal", exception.ParamName); + } + + [Theory] + [InlineData(null)] + [InlineData("")] + public void HasResource_ThrowsAnExceptionForNullOrEmptyResource(string resource) + { + // Arrange + var principal = new ClaimsPrincipal(); + + // Act and assert + var exception = Assert.Throws(() => principal.HasResource(resource)); + + Assert.Equal("resource", exception.ParamName); + Assert.StartsWith("The resource cannot be null or empty.", exception.Message); + } + + [Theory] + [InlineData(new string[0], false)] + [InlineData(new[] { "fabrikam" }, true)] + public void HasResource_ReturnsExpectedResult(string[] resource, bool result) + { + // Arrange + var identity = new ClaimsIdentity(); + var principal = new ClaimsPrincipal(identity); + + principal.SetClaims(OpenIddictConstants.Claims.Private.Resources, resource.ToImmutableArray()); + + // Act and assert + Assert.Equal(result, principal.HasResource()); + } + + [Theory] + [InlineData(new string[0], false)] + [InlineData(new []{ "contoso" }, false)] + [InlineData(new []{ "contoso", "fabrikam" }, true)] + [InlineData(new []{ "fabrikam" }, true)] + [InlineData(new []{ "fabrikam", "contoso" }, true)] + [InlineData(new []{ "CONTOSO" }, false)] + [InlineData(new []{ "CONTOSO", "FABRIKAM" }, false)] + [InlineData(new []{ "FABRIKAM" }, false)] + [InlineData(new[] { "FABRIKAM" , "CONTOSO" }, false)] + public void HasResource_ReturnsAppropriateResult(string[] resource, bool result) + { + // Arrange + var identity = new ClaimsIdentity(); + var principal = new ClaimsPrincipal(identity); + + principal.SetClaims(OpenIddictConstants.Claims.Private.Resources, resource.ToImmutableArray()); + + // Act and assert + Assert.Equal(result, principal.HasResource("fabrikam")); + } + + [Fact] + public void HasScope_ThrowsAnExceptionForNullPrincipal() + { + // Arrange + var principal = (ClaimsPrincipal) null; + + // Act and assert + var exception = Assert.Throws(() => principal.HasScope(OpenIddictConstants.Scopes.OpenId)); + + Assert.Equal("principal", exception.ParamName); + } + + [Theory] + [InlineData(null)] + [InlineData("")] + public void ClaimsPrincipal_HasScope_ThrowsAnExceptionForNullOrEmptyScope(string scope) + { + // Arrange + var principal = new ClaimsPrincipal(); + + // Act and assert + var exception = Assert.Throws(() => principal.HasScope(scope)); + + Assert.Equal("scope", exception.ParamName); + Assert.StartsWith("The scope cannot be null or empty.", exception.Message); + } + + [Theory] + [InlineData(new string[0], false)] + [InlineData(new[] { "openid" }, true)] + public void ClaimsPrincipal_HasScope_ReturnsExpectedResult(string[] scope, bool result) + { + // Arrange + var identity = new ClaimsIdentity(); + var principal = new ClaimsPrincipal(identity); + + principal.SetClaims(OpenIddictConstants.Claims.Private.Scopes, scope.ToImmutableArray()); + + // Act and assert + Assert.Equal(result, principal.HasScope()); + } + + [Theory] + [InlineData(new string[0], false)] + [InlineData(new[] { "profile" }, false)] + [InlineData(new []{ "profile", "openid" }, true)] + [InlineData(new []{ "openid" }, true)] + [InlineData(new []{ "openid" , "profile" }, true)] + [InlineData(new []{ "PROFILE" }, false)] + [InlineData(new []{ "PROFILE", "OPENID" }, false)] + [InlineData(new []{ "OPENID" }, false)] + [InlineData(new []{ "OPENID", "PROFILE" }, false)] + public void HasScope_ReturnsAppropriateResult(string[] scope, bool result) + { + // Arrange + var identity = new ClaimsIdentity(); + var principal = new ClaimsPrincipal(identity); + + principal.SetClaims(OpenIddictConstants.Claims.Private.Scopes, scope.ToImmutableArray()); + + // Act and assert + Assert.Equal(result, principal.HasScope(OpenIddictConstants.Scopes.OpenId)); + } + + [Fact] + public void IsAccessToken_ThrowsAnExceptionForNullPrincipal() + { + // Arrange + var principal = (ClaimsPrincipal) null; + + // Act and assert + var exception = Assert.Throws(() => principal.IsAccessToken()); + + Assert.Equal("principal", exception.ParamName); + } + + [Theory] + [InlineData(null, false)] + [InlineData("unknown", false)] + [InlineData(OpenIddictConstants.TokenUsages.AccessToken, true)] + [InlineData(OpenIddictConstants.TokenUsages.AuthorizationCode, false)] + [InlineData(OpenIddictConstants.TokenUsages.IdToken, false)] + [InlineData(OpenIddictConstants.TokenUsages.RefreshToken, false)] + public void IsAccessToken_ReturnsExpectedResult(string usage, bool result) + { + // Arrange + var identity = new ClaimsIdentity(); + var principal = new ClaimsPrincipal(identity); + + principal.SetClaim(OpenIddictConstants.Claims.Private.TokenUsage, usage); + + // Act and assert + Assert.Equal(result, principal.IsAccessToken()); + } + + [Fact] + public void IsAuthorizationCode_ThrowsAnExceptionForNullPrincipal() + { + // Arrange + var principal = (ClaimsPrincipal) null; + + // Act and assert + var exception = Assert.Throws(() => principal.IsAuthorizationCode()); + + Assert.Equal("principal", exception.ParamName); + } + + [Theory] + [InlineData(null, false)] + [InlineData("unknown", false)] + [InlineData(OpenIddictConstants.TokenUsages.AccessToken, false)] + [InlineData(OpenIddictConstants.TokenUsages.AuthorizationCode, true)] + [InlineData(OpenIddictConstants.TokenUsages.IdToken, false)] + [InlineData(OpenIddictConstants.TokenUsages.RefreshToken, false)] + public void IsAuthorizationCode_ReturnsExpectedResult(string usage, bool result) + { + // Arrange + var identity = new ClaimsIdentity(); + var principal = new ClaimsPrincipal(identity); + + principal.SetClaim(OpenIddictConstants.Claims.Private.TokenUsage, usage); + + // Act and assert + Assert.Equal(result, principal.IsAuthorizationCode()); + } + + [Fact] + public void IsIdentityToken_ThrowsAnExceptionForNullPrincipal() + { + // Arrange + var principal = (ClaimsPrincipal) null; + + // Act and assert + var exception = Assert.Throws(() => principal.IsIdentityToken()); + + Assert.Equal("principal", exception.ParamName); + } + + [Theory] + [InlineData(null, false)] + [InlineData("unknown", false)] + [InlineData(OpenIddictConstants.TokenUsages.AccessToken, false)] + [InlineData(OpenIddictConstants.TokenUsages.AuthorizationCode, false)] + [InlineData(OpenIddictConstants.TokenUsages.IdToken, true)] + [InlineData(OpenIddictConstants.TokenUsages.RefreshToken, false)] + public void IsIdentityToken_ReturnsExpectedResult(string usage, bool result) + { + // Arrange + var identity = new ClaimsIdentity(); + var principal = new ClaimsPrincipal(identity); + + principal.SetClaim(OpenIddictConstants.Claims.Private.TokenUsage, usage); + + // Act and assert + Assert.Equal(result, principal.IsIdentityToken()); + } + + [Fact] + public void IsRefreshToken_ThrowsAnExceptionForNullPrincipal() + { + // Arrange + var principal = (ClaimsPrincipal) null; + + // Act and assert + var exception = Assert.Throws(() => principal.IsRefreshToken()); + + Assert.Equal("principal", exception.ParamName); + } + + [Theory] + [InlineData(null, false)] + [InlineData("unknown", false)] + [InlineData(OpenIddictConstants.TokenUsages.AccessToken, false)] + [InlineData(OpenIddictConstants.TokenUsages.AuthorizationCode, false)] + [InlineData(OpenIddictConstants.TokenUsages.IdToken, false)] + [InlineData(OpenIddictConstants.TokenUsages.RefreshToken, true)] + public void IsRefreshToken_ReturnsExpectedResult(string usage, bool result) + { + // Arrange + var identity = new ClaimsIdentity(); + var principal = new ClaimsPrincipal(identity); + + principal.SetClaim(OpenIddictConstants.Claims.Private.TokenUsage, usage); + + // Act and assert + Assert.Equal(result, principal.IsRefreshToken()); + } + + [Theory] + [InlineData(null)] + [InlineData("")] + public void AddClaim_ThrowsAnExceptionForNullOrEmptyType(string type) + { + // Arrange + var identity = new ClaimsIdentity(); + + // Act and assert + var exception = Assert.Throws(() => identity.AddClaim(type, "value")); + + Assert.Equal("type", exception.ParamName); + Assert.StartsWith("The claim type cannot be null or empty.", exception.Message); + } + + [Fact] + public void AddClaim_AddsExpectedClaim() + { + // Arrange + var identity = new ClaimsIdentity(); + + // Act + identity.AddClaim("type", "value"); + + // Assert + Assert.Equal("value", identity.GetClaim("type")); + } + + [Fact] + public void RemoveClaims_ThrowsAnExceptionForNullPrincipal() + { + // Arrange + var principal = (ClaimsPrincipal) null; + + // Act and assert + var exception = Assert.Throws(() => principal.RemoveClaims("type")); + + Assert.Equal("principal", exception.ParamName); + } + + [Theory] + [InlineData(null)] + [InlineData("")] + public void RemoveClaims_ThrowsAnExceptionForNullOrEmptyClaimType(string type) + { + // Arrange + var principal = new ClaimsPrincipal(); + + // Act and assert + var exception = Assert.Throws(() => principal.RemoveClaims(type)); + + Assert.Equal("type", exception.ParamName); + Assert.StartsWith("The claim type cannot be null or empty.", exception.Message); + } + + [Fact] + public void RemoveClaims_RemoveClaims() + { + // Arrange + var identity = new ClaimsIdentity(); + var principal = new ClaimsPrincipal(identity); + + principal.SetClaim("type", "value"); + + // Act + principal.RemoveClaims("type"); + + // Assert + Assert.Null(principal.GetClaim("type")); + } + + [Fact] + public void SetClaim_ThrowsAnExceptionForNullPrincipal() + { + // Arrange + var principal = (ClaimsPrincipal) null; + + // Act and assert + var exception = Assert.Throws(() => principal.SetClaim("type", "value")); + + Assert.Equal("principal", exception.ParamName); + } + + [Theory] + [InlineData(null)] + [InlineData("")] + public void SetClaim_ThrowsAnExceptionForNullOrEmptyProperty(string type) + { + // Arrange + var principal = new ClaimsPrincipal(); + + // Act and assert + var exception = Assert.Throws(() => principal.SetClaim(type, "value")); + + Assert.Equal("type", exception.ParamName); + Assert.StartsWith("The claim type cannot be null or empty.", exception.Message); + } + + [Fact] + public void SetClaim_AddsExpectedClaim() + { + // Arrange + var identity = new ClaimsIdentity(); + var principal = new ClaimsPrincipal(identity); + + // Act + principal.SetClaim("type", "value"); + + // Assert + Assert.Equal("value", principal.GetClaim("type")); + } + + [Fact] + public void SetClaim_IsCaseInsensitive() + { + // Arrange + var identity = new ClaimsIdentity(); + var principal = new ClaimsPrincipal(identity); + + // Act + principal.SetClaim("TYPE", "value"); + + // Assert + Assert.Equal("value", principal.GetClaim("type")); + } + + [Fact] + public void SetClaim_RemovesEmptyClaim() + { + // Arrange + var identity = new ClaimsIdentity(); + var principal = new ClaimsPrincipal(identity); + + // Act + principal.SetClaim("type", string.Empty); + + // Assert + Assert.Null(principal.GetClaim("type")); + } + + [Fact] + public void SetAudiences_ThrowsAnExceptionForNullPrincipal() + { + // Arrange + var principal = (ClaimsPrincipal) null; + + // Act and assert + var exception = Assert.Throws(() => principal.SetAudiences()); + + Assert.Equal("principal", exception.ParamName); + } + + [Theory] + [InlineData(null, new string[0])] + [InlineData(new string[0], new string[0])] + [InlineData(new[] { "fabrikam" }, new[] { "fabrikam" })] + [InlineData(new[] { "fabrikam", "contoso" }, new[] { "fabrikam", "contoso" })] + [InlineData(new[] { "fabrikam", "fabrikam", "contoso" }, new[] { "fabrikam", "contoso" })] + [InlineData(new[] { "fabrikam", "FABRIKAM", "contoso" }, new[] { "fabrikam", "FABRIKAM", "contoso" })] + public void SetAudiences_AddsAudiences(string[] audiences, string[] audience) + { + // Arrange + var identity = new ClaimsIdentity(); + var principal = new ClaimsPrincipal(identity); + + // Act + principal.SetAudiences(audiences); + + // Assert + Assert.Equal(audience, principal.GetClaims(OpenIddictConstants.Claims.Audience)); + } + + [Fact] + public void SetPresenters_ThrowsAnExceptionForNullPrincipal() + { + // Arrange + var principal = (ClaimsPrincipal) null; + + // Act and assert + var exception = Assert.Throws(() => principal.SetPresenters()); + + Assert.Equal("principal", exception.ParamName); + } + + [Theory] + [InlineData(null, new string[0])] + [InlineData(new string[0], new string[0])] + [InlineData(new[] { "fabrikam" }, new[] { "fabrikam" })] + [InlineData(new[] { "fabrikam", "contoso" }, new[] { "fabrikam", "contoso" })] + [InlineData(new[] { "fabrikam", "fabrikam", "contoso" }, new[] { "fabrikam", "contoso" })] + [InlineData(new[] { "fabrikam", "FABRIKAM", "contoso" }, new[] { "fabrikam", "FABRIKAM", "contoso" })] + public void SetPresenters_AddsPresenters(string[] presenters, string[] presenter) + { + // Arrange + var identity = new ClaimsIdentity(); + var principal = new ClaimsPrincipal(identity); + + // Act + principal.SetPresenters(presenters); + + // Assert + Assert.Equal(presenter, principal.GetClaims(OpenIddictConstants.Claims.Private.Presenters)); + } + + [Fact] + public void SetResources_ThrowsAnExceptionForNullPrincipal() + { + // Arrange + var principal = (ClaimsPrincipal) null; + + // Act and assert + var exception = Assert.Throws(() => principal.SetResources()); + + Assert.Equal("principal", exception.ParamName); + } + + [Theory] + [InlineData(null, new string[0])] + [InlineData(new string[0], new string[0])] + [InlineData(new[] { "fabrikam" }, new[] { "fabrikam" })] + [InlineData(new[] { "fabrikam", "contoso" }, new[] { "fabrikam", "contoso" })] + [InlineData(new[] { "fabrikam", "fabrikam", "contoso" }, new[] { "fabrikam", "contoso" })] + [InlineData(new[] { "fabrikam", "FABRIKAM", "contoso" }, new[] { "fabrikam", "FABRIKAM", "contoso" })] + public void SetResources_AddsResources(string[] resources, string[] resource) + { + // Arrange + var identity = new ClaimsIdentity(); + var principal = new ClaimsPrincipal(identity); + + // Act + principal.SetResources(resources); + + // Assert + Assert.Equal(resource, principal.GetClaims(OpenIddictConstants.Claims.Private.Resources)); + } + + [Fact] + public void SetScopes_ThrowsAnExceptionForNullPrincipal() + { + // Arrange + var principal = (ClaimsPrincipal) null; + + // Act and assert + var exception = Assert.Throws(() => principal.SetScopes()); + + Assert.Equal("principal", exception.ParamName); + } + + [Theory] + [InlineData(null, new string[0])] + [InlineData(new string[0], new string[0])] + [InlineData(new[] { "openid" }, new[] { "openid" })] + [InlineData(new[] { "openid", "profile" }, new[] { "openid", "profile" })] + [InlineData(new[] { "openid", "openid", "profile" }, new[] { "openid", "profile" })] + [InlineData(new[] { "openid", "OPENID", "profile" }, new[] { "openid", "OPENID", "profile" })] + public void SetScopes_AddsScopes(string[] scopes, string[] scope) + { + // Arrange + var identity = new ClaimsIdentity(); + var principal = new ClaimsPrincipal(identity); + + // Act + principal.SetScopes(scopes); + + // Assert + Assert.Equal(scope, principal.GetClaims(OpenIddictConstants.Claims.Private.Scopes)); + } + + [Fact] + public void SetAccessTokenLifetime_ThrowsAnExceptionForNullPrincipal() + { + // Arrange + var principal = (ClaimsPrincipal) null; + + // Act and assert + var exception = Assert.Throws(() => principal.SetAccessTokenLifetime(null)); + + Assert.Equal("principal", exception.ParamName); + } + + [Theory] + [InlineData(null)] + [InlineData("62")] + public void SetAccessTokenLifetime_AddsLifetime(string lifetime) + { + // Arrange + var identity = new ClaimsIdentity(); + var principal = new ClaimsPrincipal(identity); + + // Act + principal.SetAccessTokenLifetime(ParseLifeTime(lifetime)); + + // Assert + Assert.Equal(lifetime, principal.GetClaim(OpenIddictConstants.Claims.Private.AccessTokenLifetime)); + } + + [Fact] + public void SetAuthorizationCodeLifetime_ThrowsAnExceptionForNullPrincipal() + { + // Arrange + var principal = (ClaimsPrincipal) null; + + // Act and assert + var exception = Assert.Throws(() => principal.SetAuthorizationCodeLifetime(null)); + + Assert.Equal("principal", exception.ParamName); + } + + [Theory] + [InlineData(null)] + [InlineData("62")] + public void SetAuthorizationCodeLifetime_AddsLifetime(string lifetime) + { + // Arrange + var identity = new ClaimsIdentity(); + var principal = new ClaimsPrincipal(identity); + + // Act + principal.SetAuthorizationCodeLifetime(ParseLifeTime(lifetime)); + + // Assert + Assert.Equal(lifetime, principal.GetClaim(OpenIddictConstants.Claims.Private.AuthorizationCodeLifetime)); + } + + [Fact] + public void SetIdentityTokenLifetime_ThrowsAnExceptionForNullPrincipal() + { + // Arrange + var principal = (ClaimsPrincipal) null; + + // Act and assert + var exception = Assert.Throws(() => principal.SetIdentityTokenLifetime(null)); + + Assert.Equal("principal", exception.ParamName); + } + + [Theory] + [InlineData(null)] + [InlineData("62")] + public void SetIdentityTokenLifetime_AddsLifetime(string lifetime) + { + // Arrange + var identity = new ClaimsIdentity(); + var principal = new ClaimsPrincipal(identity); + + // Act + principal.SetIdentityTokenLifetime(ParseLifeTime(lifetime)); + + // Assert + Assert.Equal(lifetime, principal.GetClaim(OpenIddictConstants.Claims.Private.IdentityTokenLifetime)); + } + + [Fact] + public void SetRefreshTokenLifetime_ThrowsAnExceptionForNullPrincipal() + { + // Arrange + var principal = (ClaimsPrincipal) null; + + // Act and assert + var exception = Assert.Throws(() => principal.SetRefreshTokenLifetime(null)); + + Assert.Equal("principal", exception.ParamName); + } + + [Theory] + [InlineData(null)] + [InlineData("62")] + public void SetRefreshTokenLifetime_AddsLifetime(string lifetime) + { + // Arrange + var identity = new ClaimsIdentity(); + var principal = new ClaimsPrincipal(identity); + + // Act + principal.SetRefreshTokenLifetime(ParseLifeTime(lifetime)); + + // Assert + Assert.Equal(lifetime, principal.GetClaim(OpenIddictConstants.Claims.Private.RefreshTokenLifetime)); + } + + [Fact] + public void SetInternalTokenId_ThrowsAnExceptionForNullPrincipal() + { + // Arrange + var principal = (ClaimsPrincipal) null; + + // Act and assert + var exception = Assert.Throws(() => principal.SetInternalTokenId(null)); + + Assert.Equal("principal", exception.ParamName); + } + + [Theory] + [InlineData(null)] + [InlineData("identifier")] + public void SetInternalTokenId_AddsScopes(string identifier) + { + // Arrange + var identity = new ClaimsIdentity(); + var principal = new ClaimsPrincipal(identity); + + // Act + principal.SetInternalTokenId(identifier); + + // Assert + Assert.Equal(identifier, principal.GetClaim(OpenIddictConstants.Claims.Private.TokenId)); + } + + private TimeSpan? ParseLifeTime(string lifetime) + { + var lifeT = lifetime != null + ? (TimeSpan?)TimeSpan.FromSeconds(double.Parse(lifetime, NumberStyles.Number, CultureInfo.InvariantCulture)) + : null; + + return lifeT; + } } }