JasperFx / alba

Easy integration testing for ASP.NET Core applications
https://jasperfx.github.io/alba
Apache License 2.0
406 stars 39 forks source link

[feat] Allow removing claim value in test? #160

Closed sommmen closed 6 months ago

sommmen commented 7 months ago

Hi,

I have role based authorization, my claims would look like this;

{
    "role": [
        "Employee",
        "Admin",
         ...
    ]
}

In a test i'd like to remove this role so i can test that asp.net correctly returns Forbidden, but i can't seem to get that to work becuase i can only remove a claim by key;

await Host.Scenario(c =>
{
    c.RemoveClaim("Role"); // Would remove all roles, not a specific role.
    c.Get.Url(url);
    c.StatusCodeShouldBe(HttpStatusCode.Forbidden);
});

Could Alba support configuring the claim values on a per test basis? In my case i'd like to only remove the 'Employee' role.

For the sake of completeness, the Host is setup in a base class, using MsTest :


public abstract class IntegrationTestBase
{
    protected static IAlbaHost Host { get; set; } = null!;

    [ClassInitialize(InheritanceBehavior.BeforeEachDerivedClass)]
    public static async Task ClassInitialize(TestContext context)
    {

        var jwtSecurityStub = new JwtSecurityStub()
            .With(JwtRegisteredClaimNames.Email, "runner@webapi.tests");

        var claimsByRole = RoleManagerExtensions.GetRoleClaims();

        foreach (var (role, claims) in claimsByRole)
        {
            jwtSecurityStub = jwtSecurityStub.With("role", role);

            foreach (var claim in claims)
            {
                jwtSecurityStub = jwtSecurityStub.With(claim);
            }
        }

        Host = await AlbaHost.For<Program>(x =>
        {
            x.ConfigureServices((_, services) =>
            {
                for (var i = services.Count - 1; i >= 0; i--)
                {
                    var service = services[i];

                    Type[] implementationTypesToRemove =
                    [
                        // Hosted services that do stuff on startup
                        typeof(VersionHostedService),
                        typeof(DbContextWarmUpHostedService),
                        typeof(YarpConfiguratorHostedService),

                        // Remove auth so the stub can pick this up
                        typeof(ConfigureJwtBearerOptions)
                    ];

                    if (implementationTypesToRemove.Contains(service.ImplementationType))
                    {
                        services.RemoveAt(i);
                    }
                }

                services.ConfigureOptions<ConfigureJwtBearerOptionsMock>();
            });
        }, jwtSecurityStub);
    }

    [ClassCleanup]
    public void ClassCleanup()
    {
        Host.Dispose();
    }
}

I may be able to push out a PR, if you'd like me to do that, please provide me some steps on how you want this to work.

Hawxy commented 6 months ago

Sorry, I missed this issue when you first posted it. This is unsupportable, claims don't have a type once created, they're just strings. I'd recommend writing an extension that removes the claim and adds the change you want (claims can be removed & added as part of the same scenario).