Skip to content

Commit facc125

Browse files
committed
Updated AccountAccessResponse deserialization
1 parent 261f819 commit facc125

File tree

8 files changed

+226
-136
lines changed

8 files changed

+226
-136
lines changed

src/main/java/io/mailtrap/Mapper.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@
77
import com.fasterxml.jackson.databind.json.JsonMapper;
88
import com.fasterxml.jackson.databind.module.SimpleModule;
99
import io.mailtrap.model.response.ErrorResponse;
10-
import io.mailtrap.model.response.account_accesses.Specifier;
11-
import io.mailtrap.serialization.SpecifierDeserializer;
1210
import io.mailtrap.serialization.ErrorResponseDeserializer;
1311

1412
/**
@@ -21,7 +19,6 @@ public class Mapper {
2119
.serializationInclusion(JsonInclude.Include.NON_NULL)
2220
.serializationInclusion(JsonInclude.Include.NON_EMPTY)
2321
.addModule(new SimpleModule().addDeserializer(ErrorResponse.class, new ErrorResponseDeserializer()))
24-
.addModule(new SimpleModule().addDeserializer(Specifier.class, new SpecifierDeserializer()))
2522
.build();
2623

2724
public static ObjectMapper get() {
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package io.mailtrap.model.response.account_accesses;
2+
3+
import com.fasterxml.jackson.annotation.JsonCreator;
4+
import com.fasterxml.jackson.annotation.JsonValue;
5+
6+
public enum AccessLevel {
7+
8+
OWNER(1000),
9+
ADMIN(100),
10+
VIEWER(10),
11+
INDETERMINATE(1);
12+
13+
private final int value;
14+
15+
AccessLevel(int value) {
16+
this.value = value;
17+
}
18+
19+
@JsonValue
20+
public int getValue() {
21+
return value;
22+
}
23+
24+
@JsonCreator
25+
public static AccessLevel fromValue(int value) {
26+
for (AccessLevel level : AccessLevel.values()) {
27+
if (level.value == value) {
28+
return level;
29+
}
30+
}
31+
throw new IllegalArgumentException("Unknown access_level: " + value);
32+
}
33+
}

src/main/java/io/mailtrap/model/response/account_accesses/AccountAccessResponse.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
package io.mailtrap.model.response.account_accesses;
22

33
import com.fasterxml.jackson.annotation.JsonProperty;
4+
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
45
import io.mailtrap.model.response.Permissions;
6+
import io.mailtrap.serialization.AccountAccessResponseDeserializer;
57
import lombok.Data;
68

79
import java.util.List;
810

911
@Data
12+
@JsonDeserialize(using = AccountAccessResponseDeserializer.class)
1013
public class AccountAccessResponse {
1114

1215
private long id;

src/main/java/io/mailtrap/model/response/account_accesses/Resource.java

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,7 @@ public class Resource {
1212
@JsonProperty("resource_type")
1313
private ResourceType resourceType;
1414

15-
/**
16-
* Possible values are <p>
17-
* 1000 - owner <p>
18-
* 100 - admin <p>
19-
* 10 - viewer <p>
20-
* 1 - fallback
21-
*/
2215
@JsonProperty("access_level")
23-
private int accessLevel;
16+
private AccessLevel accessLevel;
2417

2518
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package io.mailtrap.serialization;
2+
3+
import com.fasterxml.jackson.core.JsonParser;
4+
import com.fasterxml.jackson.core.type.TypeReference;
5+
import com.fasterxml.jackson.databind.DeserializationContext;
6+
import com.fasterxml.jackson.databind.JsonDeserializer;
7+
import com.fasterxml.jackson.databind.JsonNode;
8+
import com.fasterxml.jackson.databind.ObjectMapper;
9+
import io.mailtrap.model.response.Permissions;
10+
import io.mailtrap.model.response.account_accesses.*;
11+
12+
import java.io.IOException;
13+
import java.util.List;
14+
15+
public class AccountAccessResponseDeserializer extends JsonDeserializer<AccountAccessResponse> {
16+
17+
@Override
18+
public AccountAccessResponse deserialize(JsonParser p, DeserializationContext ctxt)
19+
throws IOException {
20+
21+
ObjectMapper mapper = (ObjectMapper) p.getCodec();
22+
JsonNode rootNode = mapper.readTree(p);
23+
24+
// Extract the simple fields
25+
long id = rootNode.get("id").asLong();
26+
JsonNode resourcesNode = rootNode.get("resources");
27+
JsonNode permissionsNode = rootNode.get("permissions");
28+
29+
// Deserialize the simple fields
30+
var resources = mapper.convertValue(resourcesNode, new TypeReference<List<Resource>>() {
31+
});
32+
var permissions = mapper.treeToValue(permissionsNode, Permissions.class);
33+
34+
// Extract and handle the specifier_type and specifier fields
35+
String specifierTypeStr = rootNode.get("specifier_type").asText();
36+
37+
SpecifierType specifierType = SpecifierType.fromValue(specifierTypeStr);
38+
39+
JsonNode specifierNode = rootNode.get("specifier");
40+
41+
Specifier specifier = switch (specifierType) {
42+
case USER -> mapper.treeToValue(specifierNode, UserSpecifier.class);
43+
case INVITE -> mapper.treeToValue(specifierNode, InviteSpecifier.class);
44+
case API_TOKEN -> mapper.treeToValue(specifierNode, ApiTokenSpecifier.class);
45+
};
46+
47+
// Construct the AccountAccessResponse object
48+
var response = new AccountAccessResponse();
49+
50+
response.setId(id);
51+
response.setSpecifier(specifier);
52+
response.setSpecifierType(specifierType);
53+
response.setResources(resources);
54+
response.setPermissions(permissions);
55+
56+
return response;
57+
}
58+
}

src/main/java/io/mailtrap/serialization/SpecifierDeserializer.java

Lines changed: 0 additions & 35 deletions
This file was deleted.
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
package io.mailtrap.serialization;
2+
3+
import com.fasterxml.jackson.databind.ObjectMapper;
4+
import io.mailtrap.Mapper;
5+
import io.mailtrap.model.response.account_accesses.AccountAccessResponse;
6+
import io.mailtrap.model.response.account_accesses.ApiTokenSpecifier;
7+
import io.mailtrap.model.response.account_accesses.InviteSpecifier;
8+
import io.mailtrap.model.response.account_accesses.UserSpecifier;
9+
import org.junit.jupiter.api.Test;
10+
11+
import static org.junit.jupiter.api.Assertions.*;
12+
13+
class AccountAccessResponseDeserializerTest {
14+
15+
private final ObjectMapper mapper = Mapper.get();
16+
17+
@Test
18+
void testApiTokenSpecifierDeserialization() throws Exception {
19+
String json = """
20+
{
21+
"id": 1,
22+
"specifier_type": "ApiToken",
23+
"specifier": {
24+
"id": 1,
25+
"name": "Token",
26+
"token": "xyz",
27+
"expires_at": "2025-01-01T00:00:00"
28+
},
29+
"resources": [],
30+
"permissions": {
31+
"can_read": true,
32+
"can_update": true,
33+
"can_destroy": true,
34+
"can_leave": true
35+
}
36+
}
37+
""";
38+
39+
AccountAccessResponse response = mapper.readValue(json, AccountAccessResponse.class);
40+
41+
assertInstanceOf(ApiTokenSpecifier.class, response.getSpecifier());
42+
ApiTokenSpecifier apiTokenSpecifier = (ApiTokenSpecifier) response.getSpecifier();
43+
assertEquals(1, apiTokenSpecifier.getId());
44+
assertEquals("Token", apiTokenSpecifier.getName());
45+
assertEquals("xyz", apiTokenSpecifier.getToken());
46+
assertEquals("2025-01-01T00:00:00", apiTokenSpecifier.getExpiresAt());
47+
}
48+
49+
@Test
50+
void testInviteSpecifierDeserialization() throws Exception {
51+
String json = """
52+
{
53+
"id": 1,
54+
"specifier_type": "Invite",
55+
"specifier": {
56+
"id": 2,
57+
"email": "[email protected]"
58+
},
59+
"resources": [],
60+
"permissions": {
61+
"can_read": true,
62+
"can_update": true,
63+
"can_destroy": true,
64+
"can_leave": true
65+
}
66+
}
67+
""";
68+
69+
AccountAccessResponse response = mapper.readValue(json, AccountAccessResponse.class);
70+
71+
assertInstanceOf(InviteSpecifier.class, response.getSpecifier());
72+
InviteSpecifier inviteSpecifier = (InviteSpecifier) response.getSpecifier();
73+
assertEquals(2, inviteSpecifier.getId());
74+
assertEquals("[email protected]", inviteSpecifier.getEmail());
75+
}
76+
77+
@Test
78+
void testUserSpecifierDeserialization() throws Exception {
79+
String json = """
80+
{
81+
"id": 3,
82+
"specifier_type": "User",
83+
"specifier": {
84+
"id": 3,
85+
"email": "[email protected]",
86+
"name": "John Doe"
87+
},
88+
"resources": [],
89+
"permissions": {
90+
"can_read": true,
91+
"can_update": true,
92+
"can_destroy": true,
93+
"can_leave": true
94+
}
95+
}
96+
""";
97+
98+
AccountAccessResponse response = mapper.readValue(json, AccountAccessResponse.class);
99+
100+
assertInstanceOf(UserSpecifier.class, response.getSpecifier());
101+
UserSpecifier userSpecifier = (UserSpecifier) response.getSpecifier();
102+
assertEquals(3, userSpecifier.getId());
103+
assertEquals("[email protected]", userSpecifier.getEmail());
104+
assertEquals("John Doe", userSpecifier.getName());
105+
}
106+
107+
@Test
108+
void testMissingFields() {
109+
String json = """
110+
{
111+
"id": 3,
112+
"specifier_type": "Unknown",
113+
"specifier": {
114+
"id": 3,
115+
"name": "John Doe, The unknown specifier"
116+
},
117+
"resources": [],
118+
"permissions": {
119+
"can_read": true,
120+
"can_update": true,
121+
"can_destroy": true,
122+
"can_leave": true
123+
}
124+
}
125+
""";
126+
127+
IllegalArgumentException exception = assertThrows(IllegalArgumentException.class,
128+
() -> mapper.readValue(json, AccountAccessResponse.class));
129+
assertTrue(exception.getMessage().contains("Invalid specifier_type provided"));
130+
}
131+
}

0 commit comments

Comments
 (0)