Skip to content
This repository was archived by the owner on Nov 13, 2019. It is now read-only.

Commit ca06c52

Browse files
committed
Unit tests which demonstrate bugs with recursion:
- SameObjectTest demonstrates that two different relationships which share the same relationship url should result in the same object being set for each relationship - ContinueTest demonstrates that when two identical relationship urls are proccessed, the resolution algorithm should continue to process the remaining relationships, rather than breaking out
1 parent 12738c2 commit ca06c52

7 files changed

Lines changed: 382 additions & 0 deletions

File tree

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*
2+
* Copyright 2016 Johns Hopkins University
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.github.jasminb.jsonapi.models.recursion;
17+
18+
import com.github.jasminb.jsonapi.ResolutionStrategy;
19+
import com.github.jasminb.jsonapi.annotations.Id;
20+
import com.github.jasminb.jsonapi.annotations.Relationship;
21+
import com.github.jasminb.jsonapi.annotations.Type;
22+
23+
/**
24+
* Created by esm on 10/1/16.
25+
*/
26+
@Type("bizrelnode")
27+
public class BizRelNode {
28+
29+
@Id
30+
private String id;
31+
32+
@Relationship(value = "bizrel", resolve = true, strategy = ResolutionStrategy.REF)
33+
private String bizrel;
34+
35+
@Relationship(value = "parent", resolve = true)
36+
private Node parent;
37+
38+
@Relationship(value = "node", resolve = true)
39+
private Node node;
40+
41+
private String name;
42+
43+
public String getId() {
44+
return id;
45+
}
46+
47+
public void setId(String id) {
48+
this.id = id;
49+
}
50+
51+
public String getName() {
52+
return name;
53+
}
54+
55+
public void setName(String name) {
56+
this.name = name;
57+
}
58+
59+
public Node getParent() {
60+
return parent;
61+
}
62+
63+
public void setParent(Node parent) {
64+
this.parent = parent;
65+
}
66+
67+
public Node getNode() {
68+
return node;
69+
}
70+
71+
public void setNode(Node node) {
72+
this.node = node;
73+
}
74+
75+
public String getBizrel() {
76+
return bizrel;
77+
}
78+
79+
public void setBizrel(String bizrel) {
80+
this.bizrel = bizrel;
81+
}
82+
83+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/*
2+
* Copyright 2016 Johns Hopkins University
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.github.jasminb.jsonapi.models.recursion;
17+
18+
import com.fasterxml.jackson.databind.ObjectMapper;
19+
import com.github.jasminb.jsonapi.ProbeResolver;
20+
import com.github.jasminb.jsonapi.ResourceConverter;
21+
import com.github.jasminb.jsonapi.annotations.Type;
22+
import org.junit.Test;
23+
24+
import java.nio.charset.Charset;
25+
import java.util.HashMap;
26+
27+
import static org.junit.Assert.assertEquals;
28+
import static org.junit.Assert.assertNotNull;
29+
import static org.junit.Assert.assertSame;
30+
31+
/**
32+
* Insures that all relationships get resolved when there are multiple relationships in a single JSON object point to
33+
* the same thing.
34+
* <p>
35+
* There was a bug in the code that prevented recursive loops: when it found a relationship URL that had been resolved,
36+
* it simply returned. The proper behavior, however, is to 1) set the object for the relationship, even if the
37+
* relationship has already been seen, and 2) <em>continue</em> the loop (rather than breaking) to process additional
38+
* relationships.
39+
* </p>
40+
* <p>
41+
* This test insures that relationships continue to be resolved; in this test, the relationship is the "bizrel"
42+
* relationship.
43+
* </p>
44+
*/
45+
@Type("node")
46+
public class Continue {
47+
48+
@Test
49+
public void testContinue() throws Exception {
50+
ObjectMapper mapper = new ObjectMapper();
51+
52+
Class<BizRelNode> typeUnderTest = BizRelNode.class;
53+
54+
ProbeResolver resolver = new ProbeResolver(new HashMap<String, String>() {
55+
{
56+
put("http://example.com/node/1",
57+
org.apache.commons.io.IOUtils.toString(
58+
this.getClass().getResourceAsStream("node-1.json"), Charset.forName("UTF-8")));
59+
}
60+
});
61+
62+
ResourceConverter underTest = new ResourceConverter(mapper, typeUnderTest, Node.class);
63+
underTest.setGlobalResolver(resolver);
64+
65+
BizRelNode node = underTest.readObject(
66+
org.apache.commons.io.IOUtils.toByteArray(
67+
this.getClass().getResource("continue.json")), typeUnderTest);
68+
69+
// Sanity
70+
71+
assertNotNull(node);
72+
assertEquals("3", node.getId());
73+
assertEquals("bar", node.getName());
74+
assertNotNull(node.getNode());
75+
assertNotNull(node.getParent());
76+
assertSame(node.getNode(), node.getParent());
77+
78+
// The bizrel relationship should be set.
79+
80+
assertEquals("http://www.google.com", node.getBizrel());
81+
}
82+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/*
2+
* Copyright 2016 Johns Hopkins University
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.github.jasminb.jsonapi.models.recursion;
17+
18+
import com.github.jasminb.jsonapi.annotations.Id;
19+
import com.github.jasminb.jsonapi.annotations.Relationship;
20+
import com.github.jasminb.jsonapi.annotations.Type;
21+
22+
/**
23+
* Created by esm on 10/1/16.
24+
*/
25+
@Type("node")
26+
public class Node {
27+
28+
@Id
29+
private String id;
30+
31+
private String name;
32+
33+
@Relationship(value = "parent", resolve = true)
34+
private Node parent;
35+
36+
@Relationship(value = "node", resolve = true)
37+
private Node node;
38+
39+
public String getId() {
40+
return id;
41+
}
42+
43+
public void setId(String id) {
44+
this.id = id;
45+
}
46+
47+
public String getName() {
48+
return name;
49+
}
50+
51+
public void setName(String name) {
52+
this.name = name;
53+
}
54+
55+
public Node getParent() {
56+
return parent;
57+
}
58+
59+
public void setParent(Node parent) {
60+
this.parent = parent;
61+
}
62+
63+
public Node getNode() {
64+
return node;
65+
}
66+
67+
public void setNode(Node node) {
68+
this.node = node;
69+
}
70+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/*
2+
* Copyright 2016 Johns Hopkins University
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.github.jasminb.jsonapi.models.recursion;
17+
18+
import com.fasterxml.jackson.databind.ObjectMapper;
19+
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
20+
import com.github.jasminb.jsonapi.ProbeResolver;
21+
import com.github.jasminb.jsonapi.ResourceConverter;
22+
import org.junit.Assert;
23+
import org.junit.Test;
24+
25+
import java.nio.charset.Charset;
26+
import java.util.HashMap;
27+
28+
import static org.junit.Assert.assertSame;
29+
30+
/**
31+
* Insures that all relationships get resolved when multiple relationships in a single JSON object point to the same
32+
* thing.
33+
* <p>
34+
* There was a bug in the code that prevented recursive loops: when it found a relationship URL that had been resolved,
35+
* it simply returned. The proper behavior, however, is to 1) set the object for the relationship, even if the
36+
* relationship has already been seen, and 2) <em>continue</em> the loop (rather than breaking) to process additional
37+
* relationships.
38+
* </p>
39+
* <p>
40+
* This test insures that the objects for a relationship that are seen twice are properly set. In this test, the
41+
* relationship url for the "parent" and "node" relationships is the same. The deserialized java object should have
42+
* the same object for both fields.
43+
* </p>
44+
*/
45+
public class SameObjectTest {
46+
47+
@Test
48+
public void testSameObject() throws Exception {
49+
ObjectMapper mapper = new ObjectMapper();
50+
mapper.setPropertyNamingStrategy(PropertyNamingStrategy.KEBAB_CASE);
51+
52+
Class<Node> typeUnderTest = Node.class;
53+
54+
ProbeResolver resolver = new ProbeResolver(new HashMap<String, String>() {
55+
{
56+
put("http://example.com/node/1",
57+
org.apache.commons.io.IOUtils.toString(
58+
this.getClass().getResourceAsStream("node-1.json"), Charset.forName("UTF-8")));
59+
}
60+
});
61+
62+
ResourceConverter underTest = new ResourceConverter(mapper, typeUnderTest);
63+
underTest.setGlobalResolver(resolver);
64+
65+
Node node = underTest.readObject(
66+
org.apache.commons.io.IOUtils.toByteArray(
67+
this.getClass().getResource("same-object.json")), typeUnderTest);
68+
69+
// Sanity
70+
71+
Assert.assertNotNull(node);
72+
Assert.assertEquals("2", node.getId());
73+
Assert.assertEquals("foo", node.getName());
74+
75+
// The Node object returned from getNode() and getParent() should be the same
76+
77+
assertSame(node.getParent(), node.getNode());
78+
}
79+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"data":
3+
{
4+
"relationships": {
5+
"parent": {
6+
"links": {
7+
"self": {
8+
"href": "http://example.com/node/1"
9+
}
10+
}
11+
},
12+
"node": {
13+
"links": {
14+
"self": {
15+
"href": "http://example.com/node/1"
16+
}
17+
}
18+
},
19+
"bizrel": {
20+
"links": {
21+
"self": {
22+
"href": "http://www.google.com"
23+
}
24+
}
25+
}
26+
},
27+
"attributes": {
28+
"name": "bar"
29+
},
30+
"type": "bizrelnode",
31+
"id": "3"
32+
}
33+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"data": {
3+
"attributes": {
4+
"name": "bar"
5+
},
6+
"type": "node",
7+
"id": "1"
8+
}
9+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"data":
3+
{
4+
"relationships": {
5+
"parent": {
6+
"links": {
7+
"self": {
8+
"href": "http://example.com/node/1"
9+
}
10+
}
11+
},
12+
"node": {
13+
"links": {
14+
"self": {
15+
"href": "http://example.com/node/1"
16+
}
17+
}
18+
}
19+
},
20+
"attributes": {
21+
"name": "foo"
22+
},
23+
"type": "node",
24+
"id": "2"
25+
}
26+
}

0 commit comments

Comments
 (0)