Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: Improved test coverage in #31

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions .github/workflows/maven.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,11 @@ jobs:
distribution: 'temurin'
cache: maven
- name: Build with Maven
run: mvn -B package --file pom.xml

- name: Run tests and verify
run: mvn verify -Dgpg.skip=true
run: mvn -B clean install --file pom.xml -Dgpg.skip=true

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
with:
files: '**/target/site/jacoco/jacoco.xml'
files: '**/target/site/jacoco-aggregate/jacoco.xml'
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
8 changes: 1 addition & 7 deletions kinde-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -125,19 +125,13 @@
</execution>
<execution>
<id>post-unit-test</id>
<phase>test</phase>
<phase>verify</phase>
<goals>
<goal>report</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/jacoco</outputDirectory>
<dataFile>${project.build.directory}/jacoco/jacoco.exec</dataFile>
<reportFormats>
<format>HTML</format>
<format>XML</format>
</reportFormats>
<append>true</append>
<skip>false</skip>
<includes>
<include>com/kinde/**</include>
</includes>
Expand Down
46 changes: 27 additions & 19 deletions kinde-management/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,21 @@
<groupId>com.kinde</groupId>
<artifactId>kinde-core</artifactId>
</dependency>
<!-- Mockito (if you are using it for mocking) -->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>5.4.0</version>
<scope>test</scope>
</dependency>

<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>

</dependencies>

<build>
Expand Down Expand Up @@ -165,7 +180,17 @@
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.10</version> <!-- Replace with the latest version -->
<version>0.8.12</version> <!-- Replace with the latest version -->
<configuration>
<excludes>
<exclude>com/google/inject/**/*.class</exclude>
<exclude>javax/inject/**/*.class</exclude>
<exclude>org/springframework/**/*.class</exclude>
<exclude>**/generated/**</exclude>
<exclude>**/thirdparty/**</exclude>
<exclude>org/openapitools/**</exclude>
</excludes>
</configuration>
<executions>
<execution>
<goals>
Expand All @@ -181,30 +206,13 @@
</execution>
<execution>
<id>post-unit-test</id>
<phase>test</phase>
<phase>verify</phase>
<goals>
<goal>report</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/jacoco</outputDirectory>
<dataFile>${project.build.directory}/jacoco/jacoco.exec</dataFile>
<reportFormats>
<format>HTML</format>
<format>XML</format>
</reportFormats>
<append>true</append>
<skip>false</skip>
<includes>
<include>com/kinde/**</include>
</includes>
<excludes>
<exclude>com/google/inject/**/*.class</exclude>
<exclude>javax/inject/**/*.class</exclude>
<exclude>org/springframework/**/*.class</exclude>
<exclude>**/generated/**</exclude>
<exclude>**/thirdparty/**</exclude>
<!-- Add more excludes if necessary -->
</excludes>
</configuration>
</execution>
</executions>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@
@Override
public ApiClient initClient() {
if (kindeClient == null) {
return new ApiClient();
Map<String, Authentication> authMap = new HashMap<>();
authMap.put("ManagementAPI",new OAuth(

Check warning on line 29 in kinde-management/src/main/java/com/kinde/admin/KindeAdminSessionImpl.java

View check run for this annotation

Codecov / codecov/patch

kinde-management/src/main/java/com/kinde/admin/KindeAdminSessionImpl.java#L28-L29

Added lines #L28 - L29 were not covered by tests
"https://kinde.com","http://kinde.com/oauth2/token"));
return new ApiClient(authMap);

Check warning on line 31 in kinde-management/src/main/java/com/kinde/admin/KindeAdminSessionImpl.java

View check run for this annotation

Codecov / codecov/patch

kinde-management/src/main/java/com/kinde/admin/KindeAdminSessionImpl.java#L31

Added line #L31 was not covered by tests
Comment on lines +28 to +31
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

⚠️ Potential issue

Hardcoded URLs Identified in Multiple Locations

The review has uncovered that hardcoded URLs "https://kinde.com" and "http://kinde.com/oauth2/token" are present in several Java files, including both main and test directories. This widespread use of hardcoded authentication endpoints poses the following concerns:

  1. Maintainability: Updating the URLs requires changes in multiple files, increasing the risk of inconsistencies and errors.
  2. Flexibility: Different environments (development, staging, production) may require different URLs, which is not feasible with hardcoded values.
  3. Security: Hardcoded URLs can be a vector for security vulnerabilities if they need to be updated or if unauthorized changes occur.

Recommendations:

  • Centralize Configuration: Refactor the code to use configuration files or environment variables for authentication URLs.

    String domain = config.getKindeDomain();
    String tokenEndpoint = config.getKindeTokenEndpoint();
    authMap.put("ManagementAPI", new OAuth(domain, tokenEndpoint));
  • Implement Validation and Error Handling: Ensure that configurations are loaded correctly and handle scenarios where configurations might be missing or incorrect.

    if (kindeClient == null) {
        logger.warn("KindeClient is null. Using default authentication.");
        try {
            Map<String, Authentication> authMap = new HashMap<>();
            authMap.put("ManagementAPI", new OAuth(domain, tokenEndpoint));
            return new ApiClient(authMap);
        } catch (Exception e) {
            logger.error("Failed to initialize default ApiClient", e);
            throw new IllegalStateException("Unable to initialize ApiClient", e);
        }
    }
  • Review All Instances: Conduct a comprehensive review of all occurrences of these hardcoded URLs and apply the refactoring consistently across the codebase.

🔗 Analysis chain

Avoid using hardcoded URLs and improve error handling

While the addition of a default authentication mechanism when kindeClient is null is a good idea, there are several concerns with the current implementation:

  1. Hardcoded URLs: The URLs "https://kinde.com" and "http://kinde.com/oauth2/token" are hardcoded. This reduces flexibility and may cause issues if these URLs change or differ across environments.

  2. Lack of error handling: There's no error handling or logging for this new code path, which could make debugging difficult if issues arise.

  3. Security implications: Using hardcoded authentication endpoints could pose a security risk if these URLs change or if different environments require different URLs.

  4. Maintainability: Hardcoded values reduce maintainability and make it harder to update the code for different environments or configurations.

To address these concerns, consider the following improvements:

  1. Use configuration values instead of hardcoded URLs:
String domain = config.getKindeDomain();
String tokenEndpoint = config.getKindeTokenEndpoint();
authMap.put("ManagementAPI", new OAuth(domain, tokenEndpoint));
  1. Add error handling and logging:
if (kindeClient == null) {
    logger.warn("KindeClient is null. Using default authentication.");
    try {
        Map<String, Authentication> authMap = new HashMap<>();
        authMap.put("ManagementAPI", new OAuth(domain, tokenEndpoint));
        return new ApiClient(authMap);
    } catch (Exception e) {
        logger.error("Failed to initialize default ApiClient", e);
        throw new IllegalStateException("Unable to initialize ApiClient", e);
    }
}
  1. Consider adding a comment explaining why this default authentication is necessary when kindeClient is null.

To ensure these URLs are not used elsewhere in the codebase, you can run the following command:

This will help identify if these hardcoded URLs are used in other parts of the codebase, which might also need to be updated.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

rg --type java "https://kinde.com" "http://kinde.com/oauth2/token"

Length of output: 134


Script:

#!/bin/bash
# Corrected command to search for hardcoded URLs in Java files
rg --type java -e "https://kinde.com" -e "http://kinde.com/oauth2/token"

Length of output: 3628

}
KindeTokens kindeTokens = kindeClient.clientSession().retrieveTokens();
if (kindeTokens.getAccessToken() == null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.kinde.admin;

import com.kinde.KindeClient;
import com.kinde.KindeClientSession;
import com.kinde.client.OidcMetaData;
import com.kinde.config.KindeConfig;
import com.kinde.token.AccessToken;
import com.kinde.token.IDToken;
import com.kinde.token.KindeTokens;
import com.kinde.token.RefreshToken;
import com.kinde.token.jwt.JwtGenerator;
import com.nimbusds.oauth2.sdk.id.Issuer;
import com.nimbusds.openid.connect.sdk.SubjectType;
import com.nimbusds.openid.connect.sdk.op.OIDCProviderMetadata;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import org.openapitools.client.ApiClient;

import java.net.URI;
import java.util.Arrays;

import static org.mockito.Mockito.when;

public class KindeAdminSessionImplTest {

@Test
public void testInitClient() throws Exception {
KindeAdminSessionImpl kindeAdminSession1 = new KindeAdminSessionImpl(null);
ApiClient apiClient = kindeAdminSession1.initClient();

KindeClient kindeClient = Mockito.mock(KindeClient.class);
KindeClientSession kindeClientSession = Mockito.mock(KindeClientSession.class);
when(kindeClient.clientSession()).thenReturn(kindeClientSession);
KindeConfig kindeConfig = Mockito.mock(KindeConfig.class);
when(kindeClient.kindeConfig()).thenReturn(kindeConfig);
OidcMetaData oidcMetaData = Mockito.mock(OidcMetaData.class);
when(kindeClient.oidcMetaData()).thenReturn(oidcMetaData);
OIDCProviderMetadata oidcProviderMetadata = new OIDCProviderMetadata(new Issuer("https://kinde.com"),
Arrays.asList(SubjectType.PUBLIC), new URI("https://kinde.com"));
oidcProviderMetadata.setTokenEndpointURI(new URI("https://kinde.com"));
when(oidcMetaData.getOpMetadata()).thenReturn(oidcProviderMetadata);
IDToken idToken = IDToken.init(JwtGenerator.generateIDToken(),true);
AccessToken accessToken = AccessToken.init(JwtGenerator.generateAccessToken(),true);
RefreshToken refreshToken = RefreshToken.init(JwtGenerator.refreshToken(),true);
KindeTokens kindeTokens = new KindeTokens(Arrays.asList(),idToken,accessToken,refreshToken);
when(kindeClientSession.retrieveTokens()).thenReturn(kindeTokens);
KindeAdminSessionImpl kindeAdminSession2 = new KindeAdminSessionImpl(kindeClient);
kindeAdminSession2.initClient();
}
Comment on lines +47 to +49
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Enhance test assertions and scenario verification.

The test creates two KindeAdminSessionImpl instances (one with null and one with a mocked KindeClient) but doesn't verify the behavior difference or assert the results. Consider the following improvements:

  1. Add assertions to verify the behavior of initClient() with the mocked KindeClient.
  2. Compare the results of both initClient() calls to ensure they behave differently as expected.
  3. Verify that the mocked methods were called as expected.

Example improvements:

ApiClient apiClient1 = kindeAdminSession1.initClient();
assertNotNull(apiClient1, "ApiClient should not be null for null KindeClient");

KindeAdminSessionImpl kindeAdminSession2 = new KindeAdminSessionImpl(kindeClient);
ApiClient apiClient2 = kindeAdminSession2.initClient();
assertNotNull(apiClient2, "ApiClient should not be null for mocked KindeClient");

// Verify that the mocked methods were called
Mockito.verify(kindeClient).clientSession();
Mockito.verify(kindeClient).kindeConfig();
Mockito.verify(kindeClient).oidcMetaData();
Mockito.verify(kindeClientSession).retrieveTokens();

// Compare the two ApiClient instances if they should be different
assertNotEquals(apiClient1, apiClient2, "ApiClient instances should be different for null and mocked KindeClient");

}
Comment on lines +24 to +50
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Good start, but expand test coverage and add assertions.

The test class provides a good foundation for testing the KindeAdminSessionImpl.initClient() method. However, to improve the overall test coverage and reliability, consider the following suggestions:

  1. Add assertions to verify the expected behavior in both scenarios (null and mocked KindeClient).
  2. Include error scenarios and edge cases, such as:
    • KindeClient throwing exceptions
    • Invalid or expired tokens
    • Network errors during client initialization
  3. Test different configuration scenarios (e.g., different OIDC provider metadata).
  4. Consider using parameterized tests for testing multiple scenarios efficiently.

Example additional test case:

@Test
public void testInitClientWithException() {
    KindeClient mockClient = Mockito.mock(KindeClient.class);
    when(mockClient.clientSession()).thenThrow(new RuntimeException("Session error"));

    KindeAdminSessionImpl kindeAdminSession = new KindeAdminSessionImpl(mockClient);
    
    assertThrows(RuntimeException.class, () -> kindeAdminSession.initClient(),
                 "initClient should throw RuntimeException when client session fails");
}

117 changes: 117 additions & 0 deletions kinde-management/src/test/java/com/kinde/token/jwt/JwtGenerator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package com.kinde.token.jwt;

import com.nimbusds.jose.JWSAlgorithm;
import com.nimbusds.jose.JWSHeader;
import com.nimbusds.jose.JWSSigner;
import com.nimbusds.jose.crypto.RSASSASigner;
import com.nimbusds.jose.jwk.RSAKey;
import com.nimbusds.jose.jwk.gen.RSAKeyGenerator;
import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.SignedJWT;
import lombok.SneakyThrows;

import java.util.*;

public class JwtGenerator {
@SneakyThrows
public static String generateAccessToken() {

// generate a new signed token
RSAKey rsaJWK = new RSAKeyGenerator(2048)
.keyID("123")
.generate();
Comment on lines +20 to +22
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Reuse RSA key instead of generating a new one in each method

Currently, each method generates a new RSA key pair every time it's called. This can be inefficient and unnecessary for testing purposes. Consider generating the RSA key once and reusing it across all methods to improve efficiency.

For example, you can declare the RSA key as a static variable:

private static final RSAKey RSA_JWK = new RSAKeyGenerator(2048)
        .keyID("123")
        .generate();

private static final JWSSigner SIGNER = new RSASSASigner(RSA_JWK);

Then, use SIGNER in your methods without generating new keys each time.

Also applies to: 51-53, 90-92

RSAKey rsaPublicJWK = rsaJWK.toPublicJWK();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Remove unused variable rsaPublicJWK

The variable rsaPublicJWK declared in methods generateAccessToken (line 23), generateIDToken (line 54), and refreshToken (line 93) is never used in the code. Removing this unused variable will clean up the code and eliminate any potential confusion.

Apply this diff to remove the unused variable:

-            RSAKey rsaPublicJWK = rsaJWK.toPublicJWK();

Also applies to: 54-54, 93-93


JWSSigner signer = new RSASSASigner(rsaJWK);

Date now = new Date();

JWTClaimsSet jwtClaims = new JWTClaimsSet.Builder()
.issuer("https://openid.net")
.subject("test")
.audience(Arrays.asList("https://kinde.com"))
.expirationTime(new Date(now.getTime() + 1000*60*10)) // expires in 10 minutes
.notBeforeTime(now)
.issueTime(now)
.claim("permissions",Arrays.asList("test1","test1"))
.jwtID(UUID.randomUUID().toString())
.build();

SignedJWT signedJWT = new SignedJWT(
new JWSHeader.Builder(JWSAlgorithm.RS256).keyID(rsaJWK.getKeyID()).build(),
jwtClaims);

signedJWT.sign(signer);
return signedJWT.serialize();
}
Comment on lines +17 to +46
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Refactor common code to reduce duplication

The methods generateAccessToken, generateIDToken, and refreshToken share significant portions of code, such as RSA key generation, signer initialization, and claim setup. Consider refactoring the common code into private helper methods or a constructor to enhance maintainability and reduce duplication.

For example, you can create a private method to generate the RSA key and signer:

@SneakyThrows
private static RSASSASigner getSigner() {
    RSAKey rsaJWK = new RSAKeyGenerator(2048)
            .keyID("123")
            .generate();
    return new RSASSASigner(rsaJWK);
}

And another private method to build the common JWT claims:

private static JWTClaimsSet.Builder getCommonClaims(Date now) {
    return new JWTClaimsSet.Builder()
            .issuer("https://openid.net")
            .subject("test")
            .audience(Collections.singletonList("https://kinde.com"))
            .expirationTime(new Date(now.getTime() + 1000 * 60 * 10)) // expires in 10 minutes
            .notBeforeTime(now)
            .issueTime(now)
            .claim("permissions", Arrays.asList("test1", "test1"))
            .jwtID(UUID.randomUUID().toString());
}

This refactoring will make your test code cleaner and more manageable.

Also applies to: 49-85, 88-116


@SneakyThrows
public static String generateIDToken() {
// generate a new signed token
RSAKey rsaJWK = new RSAKeyGenerator(2048)
.keyID("123")
.generate();
RSAKey rsaPublicJWK = rsaJWK.toPublicJWK();

JWSSigner signer = new RSASSASigner(rsaJWK);

Date now = new Date();

Map<String,Object> featureFlags = new HashMap<>();

featureFlags.put("test_str","test_str");
featureFlags.put("test_integer",Integer.valueOf(1));
featureFlags.put("test_boolean",Boolean.valueOf(false));

JWTClaimsSet jwtClaims = new JWTClaimsSet.Builder()
.issuer("https://openid.net")
.subject("test")
.audience(Arrays.asList("https://kinde.com"))
.expirationTime(new Date(now.getTime() + 1000*60*10)) // expires in 10 minutes
.notBeforeTime(now)
.issueTime(now)
.claim("permissions",Arrays.asList("test1","test1"))
.claim("org_codes",Arrays.asList("test1","test1"))
.claim("feature_flags",featureFlags)
.jwtID(UUID.randomUUID().toString())
.build();

SignedJWT signedJWT = new SignedJWT(
new JWSHeader.Builder(JWSAlgorithm.RS256).keyID(rsaJWK.getKeyID()).build(),
jwtClaims);

signedJWT.sign(signer);
return signedJWT.serialize();
}

@SneakyThrows
public static String refreshToken() {
// generate a new signed token
RSAKey rsaJWK = new RSAKeyGenerator(2048)
.keyID("123")
.generate();
RSAKey rsaPublicJWK = rsaJWK.toPublicJWK();

JWSSigner signer = new RSASSASigner(rsaJWK);

Date now = new Date();

JWTClaimsSet jwtClaims = new JWTClaimsSet.Builder()
.issuer("https://openid.net")
.subject("test")
.audience(Arrays.asList("https://kinde.com"))
.expirationTime(new Date(now.getTime() + 1000*60*10)) // expires in 10 minutes
.notBeforeTime(now)
.issueTime(now)
.claim("permissions",Arrays.asList("test1","test1"))
.jwtID(UUID.randomUUID().toString())
.build();

SignedJWT signedJWT = new SignedJWT(
new JWSHeader.Builder(JWSAlgorithm.RS256).keyID(rsaJWK.getKeyID()).build(),
jwtClaims);

signedJWT.sign(signer);
return signedJWT.serialize();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.kinde.spring.config;

import org.junit.Assert;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientProperties;

public class KindeOAuth2PropertiesTest {

@Test
public void testKindeOAuth2Properties() {
OAuth2ClientProperties clientProperties = Mockito.mock(OAuth2ClientProperties.class);
KindeOAuth2Properties kindeOAuth2Properties = new KindeOAuth2Properties(clientProperties);

Assert.assertNull(kindeOAuth2Properties.getRedirectUri());
Assert.assertNull(kindeOAuth2Properties.getClientId());
Assert.assertNull(kindeOAuth2Properties.getClientSecret());
Assert.assertNull(kindeOAuth2Properties.getAuthorizationGrantType());
Assert.assertNull(kindeOAuth2Properties.getDomain());
Assert.assertEquals("api://default",kindeOAuth2Properties.getAudience());
Assert.assertNull(kindeOAuth2Properties.getPostLogoutRedirectUri());
Assert.assertNull(kindeOAuth2Properties.getProxy());
Assert.assertNull(kindeOAuth2Properties.getScopes());

Assert.assertNotNull(kindeOAuth2Properties.getPermissionsClaim());

kindeOAuth2Properties.setRedirectUri("https://kinde.com");
Assert.assertEquals("https://kinde.com",kindeOAuth2Properties.getRedirectUri());

kindeOAuth2Properties.setClientId("client-id");
Assert.assertEquals("client-id",kindeOAuth2Properties.getClientId());

kindeOAuth2Properties.setClientSecret("client-secret");
Assert.assertEquals("client-secret",kindeOAuth2Properties.getClientSecret());

kindeOAuth2Properties.setDomain("https://kinde.com");
Assert.assertEquals("https://kinde.com",kindeOAuth2Properties.getDomain());

kindeOAuth2Properties.setAudience("https://kinde.com/api");
Assert.assertEquals("https://kinde.com/api",kindeOAuth2Properties.getAudience());
}


}
Comment on lines +1 to +44
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Good start on testing, but room for improvement in coverage and structure.

The test provides a solid foundation for verifying the basic functionality of KindeOAuth2Properties. However, there are several areas where the test can be enhanced:

  1. Comprehensive coverage: Add tests for all setter methods and properties, including those currently not covered (e.g., setScopes(), setProxy()).

  2. Edge case testing: Include tests for potential error cases and invalid inputs to ensure robust behavior.

  3. Test organization: Consider breaking down the single large test method into multiple smaller, focused test methods. This improves readability and makes it easier to identify which specific functionality has failed when a test doesn't pass.

  4. Use of test fixtures: Implement @BeforeEach to set up common test objects, reducing code duplication.

  5. Parameterized tests: For properties that accept various inputs, consider using JUnit's parameterized tests to cover multiple scenarios efficiently.

Here's an example of how you might restructure the tests:

public class KindeOAuth2PropertiesTest {
    private OAuth2ClientProperties clientProperties;
    private KindeOAuth2Properties kindeOAuth2Properties;

    @BeforeEach
    void setUp() {
        clientProperties = Mockito.mock(OAuth2ClientProperties.class);
        kindeOAuth2Properties = new KindeOAuth2Properties(clientProperties);
    }

    @Test
    void testDefaultValues() {
        // Test all properties for their default values
    }

    @Test
    void testSetterMethods() {
        // Test all setter methods
    }

    @ParameterizedTest
    @ValueSource(strings = {"https://kinde.com", "", "invalid-uri"})
    void testSetRedirectUri(String uri) {
        kindeOAuth2Properties.setRedirectUri(uri);
        assertEquals(uri, kindeOAuth2Properties.getRedirectUri());
    }

    // Additional test methods for other properties and edge cases
}

This structure would provide more comprehensive and organized testing for the KindeOAuth2Properties class.

14 changes: 14 additions & 0 deletions kinde-springboot/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,20 @@
<groupId>org.sonatype.plugins</groupId>
<artifactId>nexus-staging-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.12</version>
<executions>
<execution>
<id>report-aggregate</id>
<phase>verify</phase>
<goals>
<goal>report-aggregate</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Loading