<NME> TokenControllerTests.cs
<BEF> using Exceptionless.Core.Authorization;
using Exceptionless.Tests.Extensions;
using Exceptionless.Core.Repositories;
using Exceptionless.Core.Utility;
using Exceptionless.Web.Models;
using FluentRest;
using Xunit;
using Xunit.Abstractions;

namespace Exceptionless.Tests.Controllers;

public sealed class TokenControllerTests : IntegrationTestsBase {
    public TokenControllerTests(ITestOutputHelper output, AppWebHostFactory factory) : base(output, factory) {
    }

    protected override async Task ResetDataAsync() {
        await base.ResetDataAsync();
        var service = GetService<SampleDataService>();
        await service.CreateDataAsync();
    }

    [Fact]
    public async Task CanDisableApiKey() {
        var token = await SendRequestAsAsync<ViewToken>(r => r
           .Post()
           .AsGlobalAdminUser()
           .AppendPath("tokens")
           .Content(new NewToken {
               OrganizationId = SampleDataService.TEST_ORG_ID,
               ProjectId = SampleDataService.TEST_PROJECT_ID,
               Scopes = new HashSet<string> { AuthorizationRoles.Client, AuthorizationRoles.User }
           })
           .StatusCodeShouldBeCreated()
        );

        Assert.NotNull(token.Id);
        Assert.False(token.IsDisabled);
        Assert.Equal(2, token.Scopes.Count);

        var updateToken = new UpdateToken {
            IsDisabled = true,
            Notes = "Disabling until next release"
        };

        var updatedToken = await SendRequestAsAsync<ViewToken>(r => r
           .Patch()
           .BearerToken(token.Id)
           .AppendPath($"tokens/{token.Id}")
           .Content(updateToken)
           .StatusCodeShouldBeOk()
        );

        Assert.True(updatedToken.IsDisabled);
        Assert.Equal(updateToken.Notes, updatedToken.Notes);

        await SendRequestAsync(r => r
           .BearerToken(token.Id)
           .AppendPath($"tokens/{token.Id}")
           .StatusCodeShouldBeUnauthorized()
        );

        var repository = GetService<ITokenRepository>();
        var actualToken = await repository.GetByIdAsync(token.Id);
        Assert.NotNull(actualToken);
        actualToken.IsDisabled = false;
        await repository.SaveAsync(actualToken);

        token = await SendRequestAsAsync<ViewToken>(r => r
           .BearerToken(token.Id)
           .AppendPath($"tokens/{token.Id}")
           .StatusCodeShouldBeOk()
        );

        Assert.False(token.IsDisabled);
    }
}
        );
        
        var actualToken = await repository.GetByIdAsync(token.Id, o => o.Cache());
        Assert.NotNull(actualToken);
        Assert.True(actualToken.IsSuspended);

        await SendRequestAsync(r => r
           .Delete()
           .AsGlobalAdminUser()
           .AppendPath($"organizations", SampleDataService.TEST_ORG_ID, "suspend")
           .StatusCodeShouldBeOk()
        );

        actualToken = await repository.GetByIdAsync(token.Id, o => o.Cache());
        Assert.NotNull(actualToken);
        Assert.False(actualToken.IsSuspended);
    }
}

<MSG> Mark tokens suspended when org is suspended


<DFF> @@ -6,12 +6,13 @@
 using FluentRest;
 using Xunit;
 using Xunit.Abstractions;
+using Exceptionless.Core.Models;
+using Foundatio.Repositories;
 
 namespace Exceptionless.Tests.Controllers;
 
 public sealed class TokenControllerTests : IntegrationTestsBase {
-    public TokenControllerTests(ITestOutputHelper output, AppWebHostFactory factory) : base(output, factory) {
-    }
+    public TokenControllerTests(ITestOutputHelper output, AppWebHostFactory factory) : base(output, factory) {}
 
     protected override async Task ResetDataAsync() {
         await base.ResetDataAsync();
@@ -73,4 +74,36 @@ public sealed class TokenControllerTests : IntegrationTestsBase {
 
         Assert.False(token.IsDisabled);
     }
+
+    [Fact]
+    public async Task SuspendingOrganizationWillDisableApiKey() {
+        var token = await SendRequestAsAsync<ViewToken>(r => r
+           .Post()
+           .AsGlobalAdminUser()
+           .AppendPath("tokens")
+           .Content(new NewToken {
+               OrganizationId = SampleDataService.TEST_ORG_ID,
+               ProjectId = SampleDataService.TEST_PROJECT_ID,
+               Scopes = new HashSet<string> { AuthorizationRoles.Client }
+           })
+           .StatusCodeShouldBeCreated()
+        );
+
+        Assert.NotNull(token.Id);
+        Assert.False(token.IsDisabled);
+        Assert.Single(token.Scopes);
+
+        await SendRequestAsync(r => r
+           .Post()
+           .AsGlobalAdminUser()
+           .AppendPath($"organizations", SampleDataService.TEST_ORG_ID, "suspend")
+           .QueryString("code", SuspensionCode.Billing)
+           .StatusCodeShouldBeOk()
+        );
+        
+        var repository = GetService<ITokenRepository>();
+        var actualToken = await repository.GetByIdAsync(token.Id, o => o.Cache(false));
+        Assert.NotNull(actualToken);
+        Assert.True(actualToken.IsSuspended);
+    }
 }

{'addition_count': 35, 'commit_subject': 'Mark tokens suspended when org is suspended', 'deletion_count': 2, 'file_extension': '.cs', 'lang': 'Tests/Controllers/TokenControllerTests', 'license': 'apache-2.0', 'repo_name': 'exceptionless/Exceptionless'}