Skip to content

Commit bd0f2fb

Browse files
committed
add test coverage to capture existing Gson behavior on polymorphic types
1 parent 7b313c3 commit bd0f2fb

7 files changed

Lines changed: 285 additions & 0 deletions
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
package com.adyen.model.nexo;
2+
3+
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
5+
import static org.junit.jupiter.api.Assertions.assertNotNull;
6+
import static org.junit.jupiter.api.Assertions.assertNull;
7+
8+
import com.adyen.terminal.serialization.TerminalAPIGsonBuilder;
9+
import com.google.gson.Gson;
10+
import com.google.gson.JsonObject;
11+
import com.google.gson.JsonParser;
12+
import java.io.IOException;
13+
import org.junit.jupiter.api.Test;
14+
15+
public class AuthenticatedDataTest {
16+
17+
@Test
18+
public void testShouldSerializeAndDeserializeKeyTransportFromMockFile() throws IOException {
19+
String mockJson =
20+
NexoTestUtils.readResource("mocks/terminal-api/authenticated-data-key-transport.json");
21+
Gson terminalApiGson = TerminalAPIGsonBuilder.create();
22+
23+
AuthenticatedData deserializedAuthenticatedData =
24+
terminalApiGson.fromJson(mockJson, AuthenticatedData.class);
25+
assertEquals(1, deserializedAuthenticatedData.getKeyTransportOrKEK().size());
26+
assertInstanceOf(
27+
Object.class,
28+
deserializedAuthenticatedData.getKeyTransportOrKEK().get(0),
29+
"Gson deserializes to a 'generic' type instead of KeyTransport");
30+
31+
String serializedJson = terminalApiGson.toJson(deserializedAuthenticatedData);
32+
JsonObject expectedJsonObject = JsonParser.parseString(mockJson).getAsJsonObject();
33+
JsonObject serializedJsonObject = JsonParser.parseString(serializedJson).getAsJsonObject();
34+
assertEquals(expectedJsonObject, serializedJsonObject);
35+
JsonObject keyTransportOrKEKItem =
36+
serializedJsonObject.getAsJsonArray("keyTransportOrKEK").get(0).getAsJsonObject();
37+
assertNotNull(keyTransportOrKEKItem.get("RecipientIdentifier"));
38+
assertEquals(
39+
"rsaEncryption",
40+
keyTransportOrKEKItem
41+
.getAsJsonObject("KeyEncryptionAlgorithm")
42+
.get("Algorithm")
43+
.getAsString());
44+
}
45+
46+
@Test
47+
public void testShouldSerializeAndDeserializeKekFromMockFile() throws IOException {
48+
String mockJson = NexoTestUtils.readResource("mocks/terminal-api/authenticated-data-kek.json");
49+
Gson terminalApiGson = TerminalAPIGsonBuilder.create();
50+
51+
AuthenticatedData deserializedAuthenticatedData =
52+
terminalApiGson.fromJson(mockJson, AuthenticatedData.class);
53+
assertEquals(1, deserializedAuthenticatedData.getKeyTransportOrKEK().size());
54+
assertInstanceOf(
55+
Object.class,
56+
deserializedAuthenticatedData.getKeyTransportOrKEK().get(0),
57+
"Gson deserializes as a 'generic' type instead of Kek.class");
58+
59+
String serializedJson = terminalApiGson.toJson(deserializedAuthenticatedData);
60+
JsonObject expectedJsonObject = JsonParser.parseString(mockJson).getAsJsonObject();
61+
JsonObject serializedJsonObject = JsonParser.parseString(serializedJson).getAsJsonObject();
62+
assertEquals(expectedJsonObject, serializedJsonObject);
63+
JsonObject keyTransportOrKEKItem =
64+
serializedJsonObject.getAsJsonArray("keyTransportOrKEK").get(0).getAsJsonObject();
65+
assertNotNull(keyTransportOrKEKItem.get("KEKIdentifier"));
66+
assertEquals(
67+
"kid-1",
68+
keyTransportOrKEKItem.getAsJsonObject("KEKIdentifier").get("KeyIdentifier").getAsString());
69+
assertEquals(
70+
"des-ede3-cbc",
71+
keyTransportOrKEKItem
72+
.getAsJsonObject("KeyEncryptionAlgorithm")
73+
.get("Algorithm")
74+
.getAsString());
75+
}
76+
77+
@Test
78+
public void testDeserializationWithMissingRequiredFields() throws IOException {
79+
Gson terminalApiGson = TerminalAPIGsonBuilder.create();
80+
81+
// JSON missing MACAlgorithm (required field)
82+
String jsonMissingMacAlgorithm =
83+
NexoTestUtils.readResource(
84+
"mocks/terminal-api/authenticated-data-missing-mac-algorithm.json");
85+
AuthenticatedData result1 =
86+
terminalApiGson.fromJson(jsonMissingMacAlgorithm, AuthenticatedData.class);
87+
assertNotNull(result1, "Deserialization should succeed even with missing required field");
88+
assertNull(result1.getMACAlgorithm(), "MACAlgorithm should be null when missing from JSON");
89+
assertNotNull(result1.getEncapsulatedContent(), "EncapsulatedContent should be present");
90+
assertNotNull(result1.getMAC(), "MAC should be present");
91+
92+
// JSON missing EncapsulatedContent (required field)
93+
String jsonMissingEncapsulatedContent =
94+
NexoTestUtils.readResource(
95+
"mocks/terminal-api/authenticated-data-missing-encapsulated-content.json");
96+
AuthenticatedData result2 =
97+
terminalApiGson.fromJson(jsonMissingEncapsulatedContent, AuthenticatedData.class);
98+
assertNotNull(result2, "Deserialization should succeed even with missing required field");
99+
assertNotNull(result2.getMACAlgorithm(), "MACAlgorithm should be present");
100+
assertNull(
101+
result2.getEncapsulatedContent(),
102+
"EncapsulatedContent should be null when missing from JSON");
103+
assertNotNull(result2.getMAC(), "MAC should be present");
104+
105+
// JSON missing MAC (required field)
106+
String jsonMissingMac =
107+
NexoTestUtils.readResource("mocks/terminal-api/authenticated-data-missing-mac.json");
108+
AuthenticatedData result3 = terminalApiGson.fromJson(jsonMissingMac, AuthenticatedData.class);
109+
assertNotNull(result3, "Deserialization should succeed even with missing required field");
110+
assertNotNull(result3.getMACAlgorithm(), "MACAlgorithm should be present");
111+
assertNotNull(result3.getEncapsulatedContent(), "EncapsulatedContent should be present");
112+
assertNull(result3.getMAC(), "MAC should be null when missing from JSON");
113+
}
114+
115+
@Test
116+
public void testSerializationWithNullRequiredFields() {
117+
Gson terminalApiGson = TerminalAPIGsonBuilder.create();
118+
119+
AuthenticatedData authenticatedData = new AuthenticatedData();
120+
authenticatedData.setVersion(VersionType.V_0);
121+
// Not setting MACAlgorithm, EncapsulatedContent, MAC (required fields)
122+
123+
String serialized = terminalApiGson.toJson(authenticatedData);
124+
assertNotNull(serialized, "Serialization should succeed even with null required fields");
125+
126+
AuthenticatedData deserialized = terminalApiGson.fromJson(serialized, AuthenticatedData.class);
127+
assertNotNull(deserialized);
128+
assertNull(deserialized.getMACAlgorithm(), "MACAlgorithm should remain null after round-trip");
129+
assertNull(
130+
deserialized.getEncapsulatedContent(),
131+
"EncapsulatedContent should remain null after round-trip");
132+
assertNull(deserialized.getMAC(), "MAC should remain null after round-trip");
133+
}
134+
135+
@Test
136+
public void testDeserializationWithMissingNonRequiredField() throws IOException {
137+
String mockJson =
138+
NexoTestUtils.readResource("mocks/terminal-api/authenticated-data-missing-version.json");
139+
Gson terminalApiGson = TerminalAPIGsonBuilder.create();
140+
141+
AuthenticatedData deserializedAuthenticatedData =
142+
terminalApiGson.fromJson(mockJson, AuthenticatedData.class);
143+
assertNotNull(deserializedAuthenticatedData);
144+
assertEquals(VersionType.V_0, deserializedAuthenticatedData.getVersion());
145+
assertEquals(1, deserializedAuthenticatedData.getKeyTransportOrKEK().size());
146+
147+
String serializedJson = terminalApiGson.toJson(deserializedAuthenticatedData);
148+
JsonObject expectedJsonObject = JsonParser.parseString(mockJson).getAsJsonObject();
149+
JsonObject serializedJsonObject = JsonParser.parseString(serializedJson).getAsJsonObject();
150+
assertEquals(expectedJsonObject, serializedJsonObject);
151+
}
152+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"keyTransportOrKEK": [
3+
{
4+
"KEKIdentifier": {
5+
"KeyIdentifier": "kid-1",
6+
"KeyVersion": "kv1",
7+
"DerivationIdentifier": "ZGVyaXZhdGlvbg=="
8+
},
9+
"KeyEncryptionAlgorithm": {
10+
"Algorithm": "des-ede3-cbc"
11+
},
12+
"EncryptedKey": "ZW5jcnlwdGVkLWtleQ==",
13+
"Version": "v4"
14+
}
15+
],
16+
"MACAlgorithm": {
17+
"Algorithm": "id-sha256"
18+
},
19+
"EncapsulatedContent": {
20+
"Content": "cGF5bG9hZA==",
21+
"ContentType": "id-data"
22+
},
23+
"Version": "v0",
24+
"MAC": "bWFjLXZhbHVl"
25+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"keyTransportOrKEK": [
3+
{
4+
"RecipientIdentifier": {
5+
"IssuerAndSerialNumber": {
6+
"Issuer": {
7+
"RelativeDistinguishedName": []
8+
},
9+
"SerialNumber": 123
10+
}
11+
},
12+
"KeyEncryptionAlgorithm": {
13+
"Algorithm": "rsaEncryption"
14+
},
15+
"EncryptedKey": "ZW5jcnlwdGVkLWtleQ==",
16+
"Version": "v0"
17+
}
18+
],
19+
"MACAlgorithm": {
20+
"Algorithm": "id-sha256"
21+
},
22+
"EncapsulatedContent": {
23+
"Content": "cGF5bG9hZA==",
24+
"ContentType": "id-data"
25+
},
26+
"Version": "v0",
27+
"MAC": "bWFjLXZhbHVl"
28+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"keyTransportOrKEK": [
3+
{
4+
"KEKIdentifier": {
5+
"KeyIdentifier": "kid-1",
6+
"KeyVersion": "kv1"
7+
},
8+
"KeyEncryptionAlgorithm": {
9+
"Algorithm": "des-ede3-cbc"
10+
},
11+
"EncryptedKey": "ZW5jcnlwdGVkLWtleQ=="
12+
}
13+
],
14+
"MACAlgorithm": {
15+
"Algorithm": "id-sha256"
16+
},
17+
"MAC": "bWFjLXZhbHVl"
18+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"keyTransportOrKEK": [
3+
{
4+
"KEKIdentifier": {
5+
"KeyIdentifier": "kid-1",
6+
"KeyVersion": "kv1"
7+
},
8+
"KeyEncryptionAlgorithm": {
9+
"Algorithm": "des-ede3-cbc"
10+
},
11+
"EncryptedKey": "ZW5jcnlwdGVkLWtleQ=="
12+
}
13+
],
14+
"EncapsulatedContent": {
15+
"Content": "cGF5bG9hZA==",
16+
"ContentType": "id-data"
17+
},
18+
"MAC": "bWFjLXZhbHVl"
19+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"keyTransportOrKEK": [
3+
{
4+
"KEKIdentifier": {
5+
"KeyIdentifier": "kid-1",
6+
"KeyVersion": "kv1"
7+
},
8+
"KeyEncryptionAlgorithm": {
9+
"Algorithm": "des-ede3-cbc"
10+
},
11+
"EncryptedKey": "ZW5jcnlwdGVkLWtleQ=="
12+
}
13+
],
14+
"MACAlgorithm": {
15+
"Algorithm": "id-sha256"
16+
},
17+
"EncapsulatedContent": {
18+
"Content": "cGF5bG9hZA==",
19+
"ContentType": "id-data"
20+
}
21+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"keyTransportOrKEK": [
3+
{
4+
"KEKIdentifier": {
5+
"KeyIdentifier": "kid-1",
6+
"KeyVersion": "kv1"
7+
},
8+
"KeyEncryptionAlgorithm": {
9+
"Algorithm": "des-ede3-cbc"
10+
},
11+
"EncryptedKey": "ZW5jcnlwdGVkLWtleQ=="
12+
}
13+
],
14+
"MACAlgorithm": {
15+
"Algorithm": "id-sha256"
16+
},
17+
"EncapsulatedContent": {
18+
"Content": "cGF5bG9hZA==",
19+
"ContentType": "id-data"
20+
},
21+
"MAC": "bWFjLXZhbHVl"
22+
}

0 commit comments

Comments
 (0)