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

SAK-50696 - LTI Fix Non-Deterministic Unit Tests #13014

Merged
merged 2 commits into from
Nov 19, 2024
Merged
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
8 changes: 7 additions & 1 deletion lti/tsugi-util/src/java/org/tsugi/jackson/JacksonUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@

import lombok.extern.slf4j.Slf4j;

import java.util.Map;

/**
* Some Tsugi Utility code for to make using Jackson easier to use.
*/
Expand All @@ -35,7 +37,7 @@ public static String prettyPrint(Object obj)
throws com.fasterxml.jackson.core.JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();

// ***IMPORTANT!!!*** for Jackson 2.x use the line below instead of the one above:
// ***IMPORTANT!!!*** for Jackson 2.x use the line below instead of the one above:
// ObjectWriter writer = mapper.writer().withDefaultPrettyPrinter();
// return mapper.writeValueAsString(obj);
ObjectWriter writer = mapper.writerWithDefaultPrettyPrinter();
Expand Down Expand Up @@ -73,4 +75,8 @@ public static ObjectMapper getLaxObjectMapper()
return mapper;
}

public static Map<String, Object> getHashMapFromJSONString(String keySetJSON) throws JsonProcessingException {
return new ObjectMapper().readValue(keySetJSON, Map.class);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import java.util.Map;
import java.util.TreeMap;

import org.tsugi.jackson.JacksonUtil;
import org.tsugi.lti13.objects.GroupService;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.core.JsonProcessingException;
Expand All @@ -38,7 +39,7 @@ public void testConstructor() throws com.fasterxml.jackson.core.JsonProcessingEx
ObjectMapper mapper = new ObjectMapper();
String jsonString = mapper.writeValueAsString(gs);
String jsonTest = "{\"scope\":[\"https://purl.imsglobal.org/spec/lti-gs/scope/contextgroup.readonly\"],\"context_groups_url\":\"https://www.myuniv.example.com/2344/groups\",\"context_group_sets_url\":\"https://www.myuniv.example.com/2344/groups/sets\",\"service_versions\":[\"1.0\"]}";
assertEquals(jsonString, jsonTest);
assertEquals(JacksonUtil.getHashMapFromJSONString(jsonString), JacksonUtil.getHashMapFromJSONString(jsonTest));
}

@Test
Expand Down
19 changes: 15 additions & 4 deletions lti/tsugi-util/src/test/org/tsugi/lti13/LTI13KeySetTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
import java.util.TreeMap;
import static org.junit.Assert.*;

import com.fasterxml.jackson.core.JsonProcessingException;
import org.junit.Test;
import org.tsugi.jackson.JacksonUtil;

/**
*
Expand All @@ -24,7 +26,7 @@ public class LTI13KeySetTest {

@Test
public void testKeySets() throws
NoSuchAlgorithmException, NoSuchProviderException, java.security.spec.InvalidKeySpecException {
NoSuchAlgorithmException, NoSuchProviderException, java.security.spec.InvalidKeySpecException, JsonProcessingException {

String serialized = "-----BEGIN PUBLIC KEY-----\n"
+ "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApgviDRUN1Z6hIOBg5uj1k\n"
Expand All @@ -41,7 +43,7 @@ public void testKeySets() throws
RSAPublicKey rsaPublic = (RSAPublicKey) publicKey;

String keySetJSON = LTI13KeySetUtil.getKeySetJSON(rsaPublic);
boolean good = keySetJSON.contains("{\"keys\":[{\"kty\":\"RSA\",\"e\":\"AQAB\",");
boolean good = checkKeySetJSONGoodness(keySetJSON);
if (!good) {
System.out.println("keyset JSON is bad\n");
System.out.println(keySetJSON);
Expand All @@ -57,14 +59,23 @@ public void testKeySets() throws
keys.put(kid, rsaPublic);

String keySetJSON2 = LTI13KeySetUtil.getKeySetJSON(keys);
good = keySetJSON2.contains("{\"keys\":[{\"kty\":\"RSA\",\"e\":\"AQAB\",");
good = checkKeySetJSONGoodness(keySetJSON2);
if (!good) {
System.out.println("keyset JSON is bad\n");
System.out.println(keySetJSON);
}
assertTrue(good);

assertEquals(keySetJSON, keySetJSON2);
assertEquals(JacksonUtil.getHashMapFromJSONString(keySetJSON), JacksonUtil.getHashMapFromJSONString(keySetJSON2));
}

private boolean checkKeySetJSONGoodness(String keySetJSON){
boolean good = keySetJSON.contains("{\"keys\":");
if (!good) {
return false;
}
good = keySetJSON.contains("\"kty\":\"RSA\"") && keySetJSON.contains("\"e\":\"AQAB\"") ;
return good;
}

@Test
Expand Down
13 changes: 11 additions & 2 deletions lti/tsugi-util/src/test/org/tsugi/lti13/LTI13NimbusTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public void testRSAPaulGray() throws
/*
{"kty":"RSA","e":"AQAB","n":"rTbpgFsy-cho8KY7j9AtbAdQcVU6d1lYGobsOYs_gdgObf-_2uSEiPfHcs9Lz_v41XP2XToCbna1ejHj0xRds2LY3MpOHxy3UV3bk5GQp4c8eg1ydHEF4DpcIdzP2P3QDFeSppJjO3bakA0Atp20iubNZNmO0x42fbrRgYQmkPrpE-ShbNIWhq0FaRDPDg_o2R0rB9IliAfilZgwiGpzvWmOnmaB1maE4WpnWAo4gul8nMBQL0YDbIdCHi3qUx1cnXFgZwufMR27ZZ6xgvt_AY94_KBuuAC1XrQpqEpO5i7t3_tT2_OfAnh6GjXluAa06Iv3JNGfBox81a0h6qxfsw"}
*/
boolean good = keyStr.contains("{\"kty\":\"RSA\",\"e\":\"AQAB\",\"n\":");
boolean good = checkKeySetJSONGoodness(keyStr, false);
if (!good) {
System.out.println("rsaKey\n" + keyStr);
}
Expand Down Expand Up @@ -84,14 +84,23 @@ public void testRSAFromString() throws
/*
{"keys":[{"kty":"RSA","e":"AQAB","n":"pgviDRUN1Z6hIOBg5uj1kKSJjfJjayEJeJR7A06sm5K4QjYKYMve55LaD8CMqf98l_gnZ0vIaCuf4G9mkphc_yV0cgFY65wQmecPxv3IZ77wbJ-g5lL5vuCVTbh55nD--cj_hSBznXecQTXQNV9d51rCa65-PQ-YL1oRnrpUuLNPbdnc8kT_ZUq5Ic0WJM-NprN1tbbn2LafBY-igqbRQVoxIt75B8cd-35iQAUm8B4sw8zGs1bFpBy3A8rhCYcBAOdK2iSSudK2WEfW1E7RWnnNvw3ykMoVh1pq7zwL4P0IHXevvPnja-PmAT9zTwgU8WhiiIKl7YtJzkR9pEWtTw"}]}
*/
boolean good = keysetJSON.contains("{\"keys\":[{\"kty\":\"RSA\",\"e\":\"AQAB\",");
boolean good = checkKeySetJSONGoodness(keysetJSON, true);
if (!good) {
System.out.println("keyset JSON is bad\n");
System.out.println(keysetJSON);
}
assertTrue(good);
}

private boolean checkKeySetJSONGoodness(String keySetJSON, boolean withKeysAsParent){
boolean good = keySetJSON.contains("{\"keys\":");
if (!good && withKeysAsParent) {
return false;
}
good = keySetJSON.contains("\"kty\":\"RSA\"") && keySetJSON.contains("\"e\":\"AQAB\"") ;
return good;
}

@Test
public void testBrokenDeserialization() {
String bad_serialized = "-----BEGIN PUBLIC KEY-----\n"
Expand Down
17 changes: 9 additions & 8 deletions lti/tsugi-util/src/test/org/tsugi/lti13/LTI13ObjectTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import static org.junit.Assert.*;

import com.fasterxml.jackson.core.JsonProcessingException;
import org.junit.Test;

import org.tsugi.lti13.objects.LaunchJWT;
Expand Down Expand Up @@ -150,7 +151,7 @@ public void testOne() throws com.fasterxml.jackson.core.JsonProcessingException
}

@Test
public void testTwo() {
public void testTwo() throws JsonProcessingException {
LTIPlatformConfiguration lpc = new LTIPlatformConfiguration();
LTILaunchMessage mp = new LTILaunchMessage();
mp.type = LaunchJWT.MESSAGE_TYPE_LAUNCH;
Expand All @@ -169,10 +170,10 @@ public void testTwo() {
String expected =
"{\"token_endpoint_auth_methods_supported\":[\"private_key_jwt\"],\"token_endpoint_auth_signing_alg_values_supported\":[\"RS256\"],\"scopes_supported\":[\"openid\"],\"response_types_supported\":[\"id_token\"],\"subject_types_supported\":[\"public\",\"pairwise\"],\"id_token_signing_alg_values_supported\":[\"RS256\"],\"claims_supported\":[\"iss\",\"aud\"],\"https://purl.imsglobal.org/spec/lti-platform-configuration\":{\"messages_supported\":[{\"type\":\"LtiResourceLinkRequest\",\"placements\":[]},{\"type\":\"LtiDeepLinkingRequest\",\"placements\":[]}],\"variables\":[\"User.id\",\"Person.email.primary\"]}}";

if ( ! expected.equals(pcs) ) {
if ( !JacksonUtil.getHashMapFromJSONString(expected).equals(JacksonUtil.getHashMapFromJSONString(pcs)) ) {
System.out.println(pcs);
}
assertEquals(pcs, expected);
assertEquals(JacksonUtil.getHashMapFromJSONString(expected), JacksonUtil.getHashMapFromJSONString(pcs));
}

@Test
Expand All @@ -189,15 +190,15 @@ public void testThree() throws com.fasterxml.jackson.core.JsonProcessingExceptio
String expected =
"{\"https://purl.imsglobal.org/spec/lti/claim/message_type\":\"LtiResourceLinkRequest\",\"https://purl.imsglobal.org/spec/lti/claim/version\":\"1.3.0\",\"https://purl.imsglobal.org/spec/lti/claim/roles\":[],\"https://purl.imsglobal.org/spec/lti/claim/role_scope_mentor\":[],\"https://purl.imsglobal.org/spec/lti/claim/launch_presentation\":{\"document_target\":\"iframe\"}}";
String ljs = JacksonUtil.toString(lj);
assertEquals(expected,ljs);
assertEquals(JacksonUtil.getHashMapFromJSONString(expected),JacksonUtil.getHashMapFromJSONString(ljs));

lj = new LaunchJWT(LaunchJWT.MESSAGE_TYPE_LAUNCH);
lj.nonce = null; // Since we can't match random stuff
lj.expires = null; // Since we can't match random stuff
lj.issued = null; // Since we can't match random stuff
lj.jti = null; // Since we can't match random stuff
ljs = JacksonUtil.toString(lj);
assertEquals(expected,ljs);
assertEquals(JacksonUtil.getHashMapFromJSONString(expected), JacksonUtil.getHashMapFromJSONString(ljs));

lj = new LaunchJWT(LaunchJWT.MESSAGE_TYPE_DEEP_LINK);
lj.nonce = null; // Since we can't match random stuff
Expand All @@ -206,7 +207,7 @@ public void testThree() throws com.fasterxml.jackson.core.JsonProcessingExceptio
lj.jti = null; // Since we can't match random stuff
ljs = JacksonUtil.toString(lj);
String expected2 = expected.replaceAll("LtiResourceLinkRequest", "LtiDeepLinkingRequest");
assertEquals(expected2,ljs);
assertEquals(JacksonUtil.getHashMapFromJSONString(expected2), JacksonUtil.getHashMapFromJSONString(ljs));

lj = new LaunchJWT(LaunchJWT.MESSAGE_TYPE_LTI_DATA_PRIVACY_LAUNCH_REQUEST);
lj.nonce = null; // Since we can't match random stuff
Expand All @@ -215,7 +216,7 @@ public void testThree() throws com.fasterxml.jackson.core.JsonProcessingExceptio
lj.jti = null; // Since we can't match random stuff
ljs = JacksonUtil.toString(lj);
expected2 = expected.replaceAll("LtiResourceLinkRequest", "LtiDataPrivacyLaunchRequest");
assertEquals(expected2,ljs);
assertEquals(JacksonUtil.getHashMapFromJSONString(expected2), JacksonUtil.getHashMapFromJSONString(ljs));

lj = new LaunchJWT(LaunchJWT.MESSAGE_TYPE_LTI_SUBMISSION_REVIEW_REQUEST);
lj.nonce = null; // Since we can't match random stuff
Expand All @@ -224,7 +225,7 @@ public void testThree() throws com.fasterxml.jackson.core.JsonProcessingExceptio
lj.jti = null; // Since we can't match random stuff
ljs = JacksonUtil.toString(lj);
expected2 = expected.replaceAll("LtiResourceLinkRequest", "LtiSubmissionReviewRequest");
assertEquals(expected2,ljs);
assertEquals(JacksonUtil.getHashMapFromJSONString(expected2), JacksonUtil.getHashMapFromJSONString(ljs));
}

@Test
Expand Down
Loading