Skip to content

Commit b4b95e8

Browse files
committed
Add Java SSO unit + integration tests and run them in CI
The client module's generated tests are empty stubs; add hand-written SSOTest (token/hash generation) and SSOIntegrationTest (live create+fetch via secure SSO) in the core module, and point CI at core. Also fix a Gradle 9 plugin-ordering error in the hand-written core/pubsub build.gradle (java plugin applied before its DSL is used).
1 parent d16adfc commit b4b95e8

5 files changed

Lines changed: 146 additions & 1 deletion

File tree

.github/workflows/ci.yml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,13 @@ jobs:
2323
with:
2424
distribution: temurin
2525
java-version: '17'
26+
# Run the core module's tests: this compiles the generated client (a dependency)
27+
# and runs the hand-written SSO unit + integration tests, which are the real coverage.
2628
- name: Run tests
27-
working-directory: client
29+
working-directory: core
2830
run: |
2931
chmod +x gradlew
3032
./gradlew test --no-daemon
33+
env:
34+
FASTCOMMENTS_API_KEY: ${{ secrets.FASTCOMMENTS_API_KEY }}
35+
FASTCOMMENTS_TENANT_ID: ${{ secrets.FASTCOMMENTS_TENANT_ID }}

core/build.gradle

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
apply plugin: 'java'
12
apply plugin: 'idea'
23
apply plugin: 'eclipse'
34
apply plugin: 'com.diffplug.spotless'
@@ -66,6 +67,8 @@ dependencies {
6667
implementation project(':client')
6768
implementation 'com.google.code.gson:gson:2.12.1'
6869
implementation 'commons-codec:commons-codec:1.16.0'
70+
testImplementation 'org.junit.jupiter:junit-jupiter:5.10.3'
71+
testRuntimeOnly 'org.junit.platform:junit-platform-launcher:1.10.3'
6972
}
7073

7174
javadoc {
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package com.fastcomments;
2+
3+
import com.fastcomments.api.PublicApi;
4+
import com.fastcomments.core.sso.FastCommentsSSO;
5+
import com.fastcomments.core.sso.SecureSSOUserData;
6+
import com.fastcomments.invoker.ApiClient;
7+
import com.fastcomments.invoker.ApiException;
8+
import com.fastcomments.model.APIStatus;
9+
import com.fastcomments.model.CommentData;
10+
import com.fastcomments.model.GetCommentsResponseWithPresencePublicComment;
11+
import com.fastcomments.model.SaveCommentsResponseWithPresence;
12+
import org.junit.jupiter.api.Test;
13+
14+
import java.security.GeneralSecurityException;
15+
16+
import static org.junit.jupiter.api.Assertions.*;
17+
import static org.junit.jupiter.api.Assumptions.assumeTrue;
18+
19+
/**
20+
* Integration tests that hit the live FastComments API. Requires FASTCOMMENTS_API_KEY and
21+
* FASTCOMMENTS_TENANT_ID; skipped when they are not set.
22+
*/
23+
public class SSOIntegrationTest {
24+
25+
private static final String API_KEY = System.getenv("FASTCOMMENTS_API_KEY");
26+
private static final String TENANT_ID = System.getenv("FASTCOMMENTS_TENANT_ID");
27+
private static final String BASE_URL =
28+
System.getenv().getOrDefault("FASTCOMMENTS_BASE_URL", "https://fastcomments.com");
29+
30+
private PublicApi publicApi() {
31+
ApiClient apiClient = new ApiClient();
32+
apiClient.setBasePath(BASE_URL);
33+
return new PublicApi(apiClient);
34+
}
35+
36+
@Test
37+
public void testCreateAndFetchCommentWithSecureSSO() throws GeneralSecurityException, ApiException {
38+
assumeTrue(API_KEY != null && !API_KEY.isEmpty(), "FASTCOMMENTS_API_KEY is required");
39+
assumeTrue(TENANT_ID != null && !TENANT_ID.isEmpty(), "FASTCOMMENTS_TENANT_ID is required");
40+
41+
long timestamp = System.currentTimeMillis();
42+
String urlId = "sdk-test-java-" + timestamp;
43+
String commentText = "Test from Java SDK at " + timestamp;
44+
45+
SecureSSOUserData user = new SecureSSOUserData(
46+
"java-user-" + timestamp,
47+
"java-" + timestamp + "@example.com",
48+
"javatester" + timestamp,
49+
"https://example.com/avatar.jpg");
50+
FastCommentsSSO sso = FastCommentsSSO.createSecure(API_KEY, user);
51+
String token = sso.prepareToSend();
52+
53+
CommentData commentData = new CommentData()
54+
.commenterName(user.username)
55+
.comment(commentText)
56+
.url("https://example.com/java-test")
57+
.urlId(urlId);
58+
59+
SaveCommentsResponseWithPresence createResponse = publicApi()
60+
.createCommentPublic(TENANT_ID, urlId, "java-test-" + timestamp, commentData)
61+
.sso(token)
62+
.execute();
63+
64+
assertEquals(APIStatus.SUCCESS, createResponse.getStatus(), "Create comment should succeed");
65+
assertNotNull(createResponse.getComment(), "Response should include the created comment");
66+
assertEquals(user.username, createResponse.getComment().getCommenterName());
67+
assertTrue(createResponse.getComment().getCommentHTML().contains(commentText));
68+
69+
GetCommentsResponseWithPresencePublicComment getResponse = publicApi()
70+
.getCommentsPublic(TENANT_ID, urlId)
71+
.sso(token)
72+
.execute();
73+
74+
assertEquals("success", getResponse.getStatus(), "Get comments should succeed");
75+
assertNotNull(getResponse.getComments());
76+
assertTrue(getResponse.getComments().size() >= 1, "Should have at least one comment");
77+
assertEquals(user.username, getResponse.getComments().get(0).getCommenterName());
78+
}
79+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package com.fastcomments.core.sso;
2+
3+
import org.junit.jupiter.api.Test;
4+
5+
import java.security.GeneralSecurityException;
6+
7+
import static org.junit.jupiter.api.Assertions.*;
8+
9+
/**
10+
* Unit tests for SSO token / verification hash generation. No network or credentials required.
11+
*/
12+
public class SSOTest {
13+
14+
private static final String API_KEY = "test-api-key-12345";
15+
16+
@Test
17+
public void testCreateSecureSSOProducesToken() throws GeneralSecurityException {
18+
SecureSSOUserData user = new SecureSSOUserData(
19+
"user-1", "user@example.com", "tester", "https://example.com/avatar.jpg");
20+
FastCommentsSSO sso = FastCommentsSSO.createSecure(API_KEY, user);
21+
22+
String token = sso.prepareToSend();
23+
assertNotNull(token);
24+
assertFalse(token.isEmpty());
25+
26+
SecureSSOPayload payload = sso.getSecureSSOPayload();
27+
assertNotNull(payload);
28+
assertNotNull(payload.userDataJSONBase64);
29+
assertNotNull(payload.verificationHash);
30+
assertTrue(payload.timestamp != null && payload.timestamp > 0);
31+
}
32+
33+
@Test
34+
public void testCreateSimpleSSOProducesToken() {
35+
SimpleSSOUserData user = new SimpleSSOUserData(
36+
"tester", "user@example.com", "https://example.com/avatar.jpg");
37+
FastCommentsSSO sso = new FastCommentsSSO(user);
38+
39+
String token = sso.prepareToSend();
40+
assertNotNull(token);
41+
assertFalse(token.isEmpty());
42+
}
43+
44+
@Test
45+
public void testVerificationHashIsDeterministic() throws GeneralSecurityException {
46+
long timestamp = 1700000000000L;
47+
String userData = "dGVzdA=="; // base64("test")
48+
49+
String hashA = SecureSSOPayload.createVerificationHash(API_KEY, timestamp, userData);
50+
String hashB = SecureSSOPayload.createVerificationHash(API_KEY, timestamp, userData);
51+
52+
assertNotNull(hashA);
53+
assertFalse(hashA.isEmpty());
54+
assertEquals(hashA, hashB);
55+
assertNotEquals(hashA, SecureSSOPayload.createVerificationHash(API_KEY, timestamp + 1, userData));
56+
}
57+
}

pubsub/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
apply plugin: 'java'
12
apply plugin: 'idea'
23
apply plugin: 'eclipse'
34
apply plugin: 'com.diffplug.spotless'

0 commit comments

Comments
 (0)