Skip to content

Commit 0bfa659

Browse files
feature(#20): this commit introduces end-to-end tests for POST /clients/{id}/audiences
1 parent 93831fc commit 0bfa659

1 file changed

Lines changed: 162 additions & 0 deletions

File tree

Applications/Backend/Tests/Integration/Endpoints/ClientEndpointTests.cs

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -760,4 +760,166 @@ public async Task WhenDeleteClientPermissionWithPermissionNotAssigned_ShouldRetu
760760
Assert.Equal(HttpStatusCode.Conflict, response.StatusCode);
761761
Assert.Equal(ClientErrors.PermissionNotAssigned, error);
762762
}
763+
764+
[Fact(DisplayName = "[e2e] - when POST /clients/{id}/audiences with valid audience should assign audience successfully")]
765+
public async Task WhenPostClientAudiencesWithValidAudience_ShouldAssignAudienceSuccessfully()
766+
{
767+
/* arrange: resolve required dependencies */
768+
var clientCollection = factory.Services.GetRequiredService<IClientCollection>();
769+
770+
/* arrange: authenticate user and get access token */
771+
var httpClient = factory.HttpClient.WithRealmHeader("master");
772+
var credentials = new AuthenticationCredentials
773+
{
774+
Username = "federation.testing.user",
775+
Password = "federation.testing.password"
776+
};
777+
778+
var authenticationResponse = await httpClient.PostAsJsonAsync("api/v1/identity/authenticate", credentials);
779+
var authenticationResult = await authenticationResponse.Content.ReadFromJsonAsync<AuthenticationResult>();
780+
781+
Assert.NotNull(authenticationResult);
782+
Assert.NotEmpty(authenticationResult.AccessToken);
783+
784+
httpClient.WithAuthorization(authenticationResult.AccessToken);
785+
786+
/* arrange: create a new client */
787+
var clientPayload = _fixture.Build<ClientCreationScheme>()
788+
.With(client => client.Name, $"test-client-{Guid.NewGuid()}")
789+
.With(client => client.Flows, [Grant.ClientCredentials])
790+
.With(client => client.RedirectUris, [])
791+
.Create();
792+
793+
var clientResponse = await httpClient.PostAsJsonAsync("api/v1/clients", clientPayload);
794+
795+
Assert.Equal(HttpStatusCode.Created, clientResponse.StatusCode);
796+
797+
var clientFilters = ClientFilters.WithSpecifications()
798+
.WithName(clientPayload.Name)
799+
.Build();
800+
801+
var clients = await clientCollection.GetClientsAsync(clientFilters, CancellationToken.None);
802+
var client = clients.FirstOrDefault();
803+
804+
Assert.NotEmpty(clients);
805+
Assert.NotNull(client);
806+
807+
/* arrange: prepare request to assign audience to client */
808+
var payload = new AssignClientAudienceScheme
809+
{
810+
Value = "https://api.example.com"
811+
};
812+
813+
/* act: send POST request to assign audience to client */
814+
var response = await httpClient.PostAsJsonAsync($"api/v1/clients/{client.Id}/audiences", payload);
815+
var audiences = await response.Content.ReadFromJsonAsync<IReadOnlyCollection<string>>();
816+
817+
/* assert: response should be 200 OK and audiences list should be returned */
818+
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
819+
Assert.NotNull(audiences);
820+
821+
/* assert: the assigned audience should be in the returned list */
822+
Assert.Contains(audiences, current => current == payload.Value);
823+
}
824+
825+
[Fact(DisplayName = "[e2e] - when POST /clients/{id}/audiences with duplicate audience should return 409 #ERROR-F4E2A")]
826+
public async Task WhenPostClientAudiencesWithDuplicateAudience_ShouldReturnConflict()
827+
{
828+
/* arrange: resolve required dependencies */
829+
var clientCollection = factory.Services.GetRequiredService<IClientCollection>();
830+
831+
/* arrange: authenticate user and get access token */
832+
var httpClient = factory.HttpClient.WithRealmHeader("master");
833+
var credentials = new AuthenticationCredentials
834+
{
835+
Username = "federation.testing.user",
836+
Password = "federation.testing.password"
837+
};
838+
839+
var authenticationResponse = await httpClient.PostAsJsonAsync("api/v1/identity/authenticate", credentials);
840+
var authenticationResult = await authenticationResponse.Content.ReadFromJsonAsync<AuthenticationResult>();
841+
842+
Assert.NotNull(authenticationResult);
843+
Assert.NotEmpty(authenticationResult.AccessToken);
844+
845+
httpClient.WithAuthorization(authenticationResult.AccessToken);
846+
847+
/* arrange: create a new client */
848+
var payload = _fixture.Build<ClientCreationScheme>()
849+
.With(client => client.Name, $"test-client-{Guid.NewGuid()}")
850+
.With(client => client.Flows, [Grant.ClientCredentials])
851+
.With(client => client.RedirectUris, [])
852+
.Create();
853+
854+
var clientResponse = await httpClient.PostAsJsonAsync("api/v1/clients", payload);
855+
856+
Assert.Equal(HttpStatusCode.Created, clientResponse.StatusCode);
857+
858+
var clientFilters = ClientFilters.WithSpecifications()
859+
.WithName(payload.Name)
860+
.Build();
861+
862+
var clients = await clientCollection.GetClientsAsync(clientFilters, CancellationToken.None);
863+
var client = clients.FirstOrDefault();
864+
865+
Assert.NotEmpty(clients);
866+
Assert.NotNull(client);
867+
868+
/* arrange: assign audience to client first time */
869+
var content = new AssignClientAudienceScheme
870+
{
871+
Value = "https://api.example.com"
872+
};
873+
874+
var firstResponse = await httpClient.PostAsJsonAsync($"api/v1/clients/{client.Id}/audiences", content);
875+
876+
Assert.Equal(HttpStatusCode.OK, firstResponse.StatusCode);
877+
878+
/* act: attempt to assign the same audience again */
879+
var secondResponse = await httpClient.PostAsJsonAsync($"api/v1/clients/{client.Id}/audiences", content);
880+
var error = await secondResponse.Content.ReadFromJsonAsync<Error>();
881+
882+
/* assert: response should be 409 Conflict */
883+
Assert.NotNull(error);
884+
885+
Assert.Equal(HttpStatusCode.Conflict, secondResponse.StatusCode);
886+
Assert.Equal(ClientErrors.ClientAlreadyHasAudience, error);
887+
}
888+
889+
[Fact(DisplayName = "[e2e] - when POST /clients/{id}/audiences with non-existent client should return 404 #ERROR-2D943")]
890+
public async Task WhenPostClientAudiencesWithNonExistentClient_ShouldReturnNotFound()
891+
{
892+
/* arrange: authenticate user and get access token */
893+
var httpClient = factory.HttpClient.WithRealmHeader("master");
894+
var credentials = new AuthenticationCredentials
895+
{
896+
Username = "federation.testing.user",
897+
Password = "federation.testing.password"
898+
};
899+
900+
var authenticationResponse = await httpClient.PostAsJsonAsync("api/v1/identity/authenticate", credentials);
901+
var authenticationResult = await authenticationResponse.Content.ReadFromJsonAsync<AuthenticationResult>();
902+
903+
Assert.NotNull(authenticationResult);
904+
Assert.NotEmpty(authenticationResult.AccessToken);
905+
906+
httpClient.WithAuthorization(authenticationResult.AccessToken);
907+
908+
/* arrange: prepare request with a non-existent client ID */
909+
var nonExistentClientId = Guid.NewGuid().ToString();
910+
var payload = new AssignClientAudienceScheme
911+
{
912+
Value = "https://api.example.com"
913+
};
914+
915+
/* act: send POST request for non-existent client */
916+
var response = await httpClient.PostAsJsonAsync($"api/v1/clients/{nonExistentClientId}/audiences", payload);
917+
var error = await response.Content.ReadFromJsonAsync<Error>();
918+
919+
/* assert: response should be 404 Not Found */
920+
Assert.NotNull(error);
921+
922+
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
923+
Assert.Equal(ClientErrors.ClientDoesNotExist, error);
924+
}
763925
}

0 commit comments

Comments
 (0)