diff --git a/src/spec/java/com/zitadel/SDKTestUsingClientCredentialsAuthenticationSpec.java b/src/spec/java/com/zitadel/SDKTestUsingClientCredentialsAuthenticationSpec.java deleted file mode 100644 index 892a7dba..00000000 --- a/src/spec/java/com/zitadel/SDKTestUsingClientCredentialsAuthenticationSpec.java +++ /dev/null @@ -1,96 +0,0 @@ -package com.zitadel; - -import com.zitadel.model.*; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import java.util.UUID; - -import static org.junit.jupiter.api.Assertions.fail; - -@SuppressWarnings("NewClassNamingConvention") -public class SDKTestUsingClientCredentialsAuthenticationSpec extends BaseTest { - - private final String clientId = System.getProperty("CLIENT_ID"); - private final String clientSecret = System.getProperty("CLIENT_SECRET"); - private final String baseUrl = System.getProperty("BASE_URL"); - private String userId; - - /** - * Sets up the test environment before each test by creating a user. - */ - @BeforeEach - void setUp() { - userId = createUser(); - } - - /** - * Creates a new user in Zitadel using a valid Personal Access Token. - * - * @return the user ID of the newly created user - */ - private String createUser() { - Zitadel zitadel = Zitadel.withClientCredentials(baseUrl, clientId, clientSecret); - - try { - UserServiceAddHumanUserResponse response = zitadel.users.userServiceAddHumanUser(new UserServiceAddHumanUserRequest() - .username(UUID.randomUUID().toString()) - .profile(new UserServiceSetHumanProfile() - .givenName("John") - .familyName("Doe")) - .email(new UserServiceSetHumanEmail() - .email("johndoe" + UUID.randomUUID() + "@caos.ag"))); - System.out.println("User created: " + response); - return response.getUserId(); - } catch (ApiException e) { - throw new RuntimeException("Exception while creating user: " + e.getMessage()); - } - } - - /** - * Tests deactivating and reactivating a user with a valid Personal Access Token. - *

- * It expects the user to be deactivated and then reactivated successfully. - */ - @Test - void shouldDeactivateAndReactivateUserWithValidToken() { - Zitadel zitadel = Zitadel.withClientCredentials(baseUrl, clientId, clientSecret); - - try { - UserServiceDeactivateUserResponse deactivateResponse = zitadel.users.userServiceDeactivateUser(userId); - System.out.println("User deactivated: " + deactivateResponse); - - UserServiceReactivateUserResponse reactivateResponse = zitadel.users.userServiceReactivateUser(userId); - System.out.println("User reactivated: " + reactivateResponse); - // assertEquals("success", reactivateResponse.getStatus()); - } catch (ApiException e) { - fail("Exception when calling deactivateUser or reactivateUser with valid token: " + e.getMessage()); - } - } - - /** - * Tests deactivating and reactivating a user with an invalid Personal Access Token. - *

- * It expects an exception to be thrown for both deactivate and reactivate operations. - */ - @Test - void shouldNotDeactivateOrReactivateUserWithInvalidToken() { - Zitadel zitadel = Zitadel.withClientCredentials(baseUrl, "clientId", "clientSecret"); - - try { - zitadel.users.userServiceDeactivateUser(userId); - fail("Expected exception when deactivating user with invalid token, but got response."); - } catch (Exception e) { - // assertTrue(e.getMessage().contains("Unauthorized")); - System.out.println("Caught expected ApiException: " + e.getMessage()); - } - - try { - zitadel.users.userServiceReactivateUser(userId); - fail("Expected exception when reactivating user with invalid token, but got response."); - } catch (Exception e) { - // assertTrue(e.getMessage().contains("Unauthorized")); - System.out.println("Caught expected ApiException: " + e.getMessage()); - } - } -} diff --git a/src/spec/java/com/zitadel/SDKTestUsingPersonalAccessTokenAuthenticationSpec.java b/src/spec/java/com/zitadel/SDKTestUsingPersonalAccessTokenAuthenticationSpec.java deleted file mode 100644 index 4890e255..00000000 --- a/src/spec/java/com/zitadel/SDKTestUsingPersonalAccessTokenAuthenticationSpec.java +++ /dev/null @@ -1,99 +0,0 @@ -package com.zitadel; - -import com.zitadel.model.*; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import java.util.UUID; - -import static org.junit.jupiter.api.Assertions.fail; - -/** - * This spec tests the SDK behavior using Personal Access Token (PAT) authentication. - * It includes test cases for valid and invalid token scenarios related to user deactivation and reactivation. - */ -@SuppressWarnings("NewClassNamingConvention") -class SDKTestUsingPersonalAccessTokenAuthenticationSpec extends BaseTest { - - private final String validToken = System.getProperty("AUTH_TOKEN"); - private final String baseUrl = System.getProperty("BASE_URL"); - private String userId; - - /** - * Sets up the test environment before each test by creating a user. - */ - @BeforeEach - void setUp() { - userId = createUser(); - } - - /** - * Creates a new user in Zitadel using a valid Personal Access Token. - * - * @return the user ID of the newly created user - */ - private String createUser() { - Zitadel zitadel = Zitadel.withAccessToken(baseUrl, validToken); - - try { - UserServiceAddHumanUserResponse response = zitadel.users.userServiceAddHumanUser(new UserServiceAddHumanUserRequest() - .username(UUID.randomUUID().toString()) - .profile(new UserServiceSetHumanProfile() - .givenName("John") - .familyName("Doe")) - .email(new UserServiceSetHumanEmail() - .email("johndoe" + UUID.randomUUID() + "@caos.ag"))); - System.out.println("User created: " + response); - return response.getUserId(); - } catch (ApiException e) { - throw new RuntimeException("Exception while creating user: " + e.getMessage()); - } - } - - /** - * Tests deactivating and reactivating a user with a valid Personal Access Token. - *

- * It expects the user to be deactivated and then reactivated successfully. - */ - @Test - void shouldDeactivateAndReactivateUserWithValidToken() { - Zitadel zitadel = Zitadel.withAccessToken(baseUrl, validToken); - - try { - UserServiceDeactivateUserResponse deactivateResponse = zitadel.users.userServiceDeactivateUser(userId); - System.out.println("User deactivated: " + deactivateResponse); - - UserServiceReactivateUserResponse reactivateResponse = zitadel.users.userServiceReactivateUser(userId); - System.out.println("User reactivated: " + reactivateResponse); - // assertEquals("success", reactivateResponse.getStatus()); - } catch (ApiException e) { - fail("Exception when calling deactivateUser or reactivateUser with valid token: " + e.getMessage()); - } - } - - /** - * Tests deactivating and reactivating a user with an invalid Personal Access Token. - *

- * It expects an exception to be thrown for both deactivate and reactivate operations. - */ - @Test - void shouldNotDeactivateOrReactivateUserWithInvalidToken() { - Zitadel zitadel = Zitadel.withAccessToken(baseUrl, "whoops"); - - try { - zitadel.users.userServiceDeactivateUser(userId); - fail("Expected exception when deactivating user with invalid token, but got response."); - } catch (ApiException e) { - // assertTrue(e.getMessage().contains("Unauthorized")); - System.out.println("Caught expected ApiException: " + e.getMessage()); - } - - try { - zitadel.users.userServiceReactivateUser(userId); - fail("Expected exception when reactivating user with invalid token, but got response."); - } catch (ApiException e) { - // assertTrue(e.getMessage().contains("Unauthorized")); - System.out.println("Caught expected ApiException: " + e.getMessage()); - } - } -} diff --git a/src/spec/java/com/zitadel/SessionServiceSanityCheckSpec.java b/src/spec/java/com/zitadel/SessionServiceSanityCheckSpec.java new file mode 100644 index 00000000..3968b961 --- /dev/null +++ b/src/spec/java/com/zitadel/SessionServiceSanityCheckSpec.java @@ -0,0 +1,122 @@ +package com.zitadel; + +import com.zitadel.model.*; +import org.junit.jupiter.api.*; + +import java.util.List; +import java.util.UUID; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * SessionService Integration Tests + *

+ * This suite verifies the Zitadel SessionService API's basic operations using a + * personal access token: + *

+ * 1. Create a session with specified checks and lifetime + * 2. Retrieve the session by ID + * 3. List sessions and ensure the created session appears + * 4. Update the session's lifetime and confirm a new token is returned + * 5. Error when retrieving a non-existent session + *

+ * Each test runs in isolation: a new session is created in @BeforeEach and deleted in + * {@code @AfterEach} to ensure a clean state. + */ +@SuppressWarnings("NewClassNamingConvention") +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +class SessionServiceSanityCheckSpec extends BaseTest { + + private final Supplier validToken = () -> System.getProperty("AUTH_TOKEN"); + private final Supplier baseUrl = () -> System.getProperty("BASE_URL"); + private Zitadel client; + private SessionServiceCreateSessionResponse session; + + @BeforeAll + void initClient() { + client = Zitadel.withAccessToken(baseUrl.get(), validToken.get()); + } + + @BeforeEach + void setUp() throws ApiException { + SessionServiceCreateSessionRequest request = new SessionServiceCreateSessionRequest() + .checks(new SessionServiceChecks() + .user(new SessionServiceCheckUser().loginName("johndoe"))) + .lifetime("18000s"); + + session = client.sessions.sessionServiceCreateSession(request); + } + + @AfterEach + void tearDown() { + try { + client.sessions.sessionServiceDeleteSession( + session.getSessionId(), + new SessionServiceDeleteSessionBody() + ); + } catch (ApiException ignored) { + // cleanup errors are ignored + } + } + + /** + * Retrieves the session details by ID. + */ + @Test + void testRetrievesSessionDetailsById() throws ApiException { + SessionServiceGetSessionResponse response = + client.sessions.sessionServiceGetSession( + session.getSessionId(), + session.getSessionToken() + ); + assertNotNull(response.getSession()); + assertEquals(session.getSessionId(), response.getSession().getId()); + } + + /** + * Includes the created session when listing all sessions. + */ + @Test + void testIncludesCreatedSessionWhenListing() throws ApiException { + SessionServiceListSessionsRequest request = new SessionServiceListSessionsRequest() + .query(new SessionServiceListQuery()); + + SessionServiceListSessionsResponse response = + client.sessions.sessionServiceListSessions(request); + assertNotNull(response.getSessions()); + List ids = response.getSessions().stream() + .map(SessionServiceSession::getId) + .collect(Collectors.toList()); + assertTrue(ids.contains(session.getSessionId())); + } + + /** + * Updates the session lifetime and returns a new token. + */ + @Test + void testUpdatesSessionLifetimeAndReturnsNewToken() throws ApiException { + SessionServiceSetSessionRequest request = new SessionServiceSetSessionRequest() + .lifetime("36000s"); + + SessionServiceSetSessionResponse response = + client.sessions.sessionServiceSetSession( + session.getSessionId(), request + ); + assertNotNull(response.getSessionToken()); + } + + /** + * Raises an ApiException when retrieving a non-existent session. + */ + @Test + void testRaisesApiExceptionForNonexistentSession() { + assertThrows(ApiException.class, () -> + client.sessions.sessionServiceGetSession( + UUID.randomUUID().toString(), + session.getSessionToken() + ) + ); + } +} diff --git a/src/spec/java/com/zitadel/UserServiceSanityCheckSpec.java b/src/spec/java/com/zitadel/UserServiceSanityCheckSpec.java new file mode 100644 index 00000000..5452ee6b --- /dev/null +++ b/src/spec/java/com/zitadel/UserServiceSanityCheckSpec.java @@ -0,0 +1,127 @@ +package com.zitadel; + +import com.zitadel.model.*; +import org.junit.jupiter.api.*; + +import java.util.List; +import java.util.UUID; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * UserService Integration Tests + *

+ * This suite verifies the Zitadel UserService API's basic operations using a + * personal access token: + *

+ * 1. Create a human user + * 2. Retrieve the user by ID + * 3. List users and ensure the created user appears + * 4. Update the user's email and confirm the change + * 5. Error when retrieving a non-existent user + *

+ * Each test runs in isolation: a new session is created in @BeforeEach and deleted in + * {@code @AfterEach} to ensure a clean state. + */ +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@SuppressWarnings("NewClassNamingConvention") +class UserServiceSanityCheckSpec extends BaseTest { + + private final Supplier validToken = () -> System.getProperty("AUTH_TOKEN"); + private final Supplier baseUrl = () -> System.getProperty("BASE_URL"); + private Zitadel client; + private UserServiceAddHumanUserResponse user; + + @BeforeAll + void initClient() { + client = Zitadel.withAccessToken(baseUrl.get(), validToken.get()); + } + + /** + * Create a new human user before each test. + */ + @BeforeEach + void setUp() throws ApiException { + UserServiceAddHumanUserRequest request = new UserServiceAddHumanUserRequest() + .username(UUID.randomUUID().toString()) + .profile(new UserServiceSetHumanProfile() + .givenName("John") + .familyName("Doe")) + .email(new UserServiceSetHumanEmail() + .email("johndoe" + UUID.randomUUID() + "@example.com")); + + user = client.users.userServiceAddHumanUser(request); + } + + /** + * Delete the created human user after each test. + */ + @AfterEach + void tearDown() { + try { + client.users.userServiceDeleteUser(user.getUserId()); + } catch (ApiException ignored) { + // cleanup errors are ignored + } + } + + /** + * Retrieves the user details by ID. + */ + @Test + void testRetrievesUserDetailsById() throws ApiException { + UserServiceGetUserByIDResponse response = client.users.userServiceGetUserByID( + user.getUserId() + ); + assertNotNull(response.getUser()); + assertEquals(user.getUserId(), response.getUser().getUserId()); + } + + /** + * Includes the created user when listing all users. + */ + @Test + void testIncludesCreatedUserWhenListing() throws ApiException { + UserServiceListUsersRequest request = new UserServiceListUsersRequest() + .query(new UserServiceListQuery()); + + UserServiceListUsersResponse response = client.users.userServiceListUsers(request); + assertNotNull(response.getResult()); + List ids = response.getResult().stream() + .map(UserServiceUser::getUserId) + .collect(Collectors.toList()); + assertTrue(ids.contains(user.getUserId())); + } + + /** + * Updates the user's email and returns a new email reflecting the change. + */ + @SuppressWarnings("DataFlowIssue") + @Test + void testUpdatesUserEmailAndReflectsInGet() throws ApiException { + client.users.userServiceUpdateHumanUser( + user.getUserId(), + new UserServiceUpdateHumanUserRequest() + .email(new UserServiceSetHumanEmail() + .email("updated" + UUID.randomUUID() + "@example.com")) + ); + + UserServiceGetUserByIDResponse response = client.users.userServiceGetUserByID( + user.getUserId() + ); + assertNotNull(response.getUser().getHuman().getEmail()); + assertTrue(response.getUser().getHuman().getEmail().getEmail().contains("updated")); + } + + /** + * Raises an ApiException when retrieving a non-existent user. + */ + @Test + void testRaisesApiExceptionForNonexistentUser() { + assertThrows(ApiException.class, () -> + client.users.userServiceGetUserByID(UUID.randomUUID().toString()) + ); + } +} diff --git a/src/spec/java/com/zitadel/auth/UseAccessTokenSpec.java b/src/spec/java/com/zitadel/auth/UseAccessTokenSpec.java new file mode 100644 index 00000000..eb049659 --- /dev/null +++ b/src/spec/java/com/zitadel/auth/UseAccessTokenSpec.java @@ -0,0 +1,54 @@ +package com.zitadel.auth; + +import com.zitadel.ApiException; +import com.zitadel.BaseTest; +import com.zitadel.Zitadel; +import com.zitadel.model.SettingsServiceGetGeneralSettingsResponse; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; + +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; + +/** + * SettingsService Integration Tests using Personal Access Token + *

+ * Verifies the general settings endpoint with: + * 1. Valid personal access token + * 2. Invalid personal access token + */ +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@SuppressWarnings("NewClassNamingConvention") +class UseAccessTokenSpec extends BaseTest { + + /** + * Retrieves general settings successfully with a valid access token. + * + * @throws ApiException on API error + */ + @Test + void testRetrievesGeneralSettingsWithValidAuth() throws ApiException { + Zitadel client = Zitadel.withAccessToken( + System.getProperty("BASE_URL"), + System.getProperty("AUTH_TOKEN") + ); + + SettingsServiceGetGeneralSettingsResponse response = + client.settings.settingsServiceGetGeneralSettings(); + assertNotNull(response); + } + + /** + * Raises ApiException when using an invalid access token. + */ + @Test + void testRaisesApiExceptionWithInvalidAuth() { + Zitadel invalid = Zitadel.withAccessToken( + System.getProperty("BASE_URL"), + "invalid" + ); + + assertThrows(ApiException.class, invalid.settings::settingsServiceGetGeneralSettings + ); + } +} diff --git a/src/spec/java/com/zitadel/auth/UseClientCredentialsSpec.java b/src/spec/java/com/zitadel/auth/UseClientCredentialsSpec.java new file mode 100644 index 00000000..a8629dc0 --- /dev/null +++ b/src/spec/java/com/zitadel/auth/UseClientCredentialsSpec.java @@ -0,0 +1,56 @@ +package com.zitadel.auth; + +import com.zitadel.ApiException; +import com.zitadel.BaseTest; +import com.zitadel.Zitadel; +import com.zitadel.model.SettingsServiceGetGeneralSettingsResponse; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; + +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; + +/** + * SettingsService Integration Tests using Client Credentials + *

+ * Verifies the general settings endpoint with: + * 1. Valid client credentials + * 2. Invalid client credentials + */ +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@SuppressWarnings("NewClassNamingConvention") +class UseClientCredentialsSpec extends BaseTest { + + /** + * Retrieves general settings successfully with valid client credentials. + * + * @throws ApiException on API error + */ + @Test + void testRetrievesGeneralSettingsWithValidAuth() throws ApiException { + Zitadel client = Zitadel.withClientCredentials( + System.getProperty("BASE_URL"), + System.getProperty("CLIENT_ID"), + System.getProperty("CLIENT_SECRET") + ); + + SettingsServiceGetGeneralSettingsResponse response = + client.settings.settingsServiceGetGeneralSettings(); + assertNotNull(response); + } + + /** + * Raises ApiException when using invalid client credentials. + */ + @Test + void testRaisesApiExceptionWithInvalidAuth() { + Zitadel invalid = Zitadel.withClientCredentials( + System.getProperty("BASE_URL"), + "invalid", + "invalid" + ); + + assertThrows(RuntimeException.class, invalid.settings::settingsServiceGetGeneralSettings + ); + } +} diff --git a/src/spec/java/com/zitadel/auth/UsePrivateKeySpec.java b/src/spec/java/com/zitadel/auth/UsePrivateKeySpec.java new file mode 100644 index 00000000..3d1401d8 --- /dev/null +++ b/src/spec/java/com/zitadel/auth/UsePrivateKeySpec.java @@ -0,0 +1,73 @@ +package com.zitadel.auth; + +import com.zitadel.ApiException; +import com.zitadel.BaseTest; +import com.zitadel.Zitadel; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; + +import static org.junit.jupiter.api.Assertions.assertThrows; + +/** + * SettingsService Integration Tests using Private Key Assertion + *

+ * Verifies the general settings endpoint with: + * 1. Valid private key assertion + * 2. Invalid private key assertion + */ +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@SuppressWarnings("NewClassNamingConvention") +class UsePrivateKeySpec extends BaseTest { + + private String keyFile; + + /** + * Prepare a temporary JWT key file before each test. + * Reads the raw key from the JWT_KEY system property and writes it to a temp file. + * Exits if the key is missing. + * + * @throws IOException on file I/O errors + */ + @BeforeAll + void setUp() throws IOException { + String k = System.getProperty("JWT_KEY"); + if (k == null) System.exit(1); + File f = File.createTempFile("jwt_", null); + Files.write(f.toPath(), k.getBytes(StandardCharsets.UTF_8)); + keyFile = f.getAbsolutePath(); + } + + /** + * Retrieves general settings successfully with a valid private key. + * + * @throws ApiException on API error + */ + @Test + void testRetrievesGeneralSettingsWithValidAuth() throws ApiException { + Zitadel client = Zitadel.withPrivateKey( + System.getProperty("BASE_URL"), + keyFile + ); + + client.settings.settingsServiceGetGeneralSettings(); + } + + /** + * Raises ApiException when using an invalid private key. + */ + @Test + void testRaisesApiExceptionWithInvalidAuth() { + Zitadel invalid = Zitadel.withPrivateKey( + "https://zitadel.cloud", + keyFile + ); + + assertThrows(ApiException.class, invalid.settings::settingsServiceGetGeneralSettings); + } +}