Skip to content

Commit 8e419ef

Browse files
committed
Added addition tests to improve the coverage
1 parent 7051e94 commit 8e419ef

File tree

8 files changed

+340
-17
lines changed

8 files changed

+340
-17
lines changed

codecov.yml

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
codecov:
2+
notify:
3+
require_ci_to_pass: yes
4+
5+
coverage:
6+
precision: 2
7+
round: down
8+
range: "70...95"
9+
10+
status:
11+
project: yes
12+
patch: yes
13+
changes: no
14+
15+
notify:
16+
gitter:
17+
default:
18+
url: "https://webhooks.gitter.im/e/49ad46bbe08a7cda7e7f"
19+
threshold: 1%
20+
only_pulls: false
21+
branches: null
22+
flags: null
23+
paths: null
24+
25+
parsers:
26+
gcov:
27+
branch_detection:
28+
conditional: yes
29+
loop: yes
30+
method: no
31+
macro: no
32+
33+
comment:
34+
layout: "header, diff"
35+
behavior: default
36+
require_changes: no
37+
38+
ignore:
39+
- "/springfox-grails/src/main/java/springfox/documentation/grails/SynthesizedAnnotations.java"
40+
- "/springfox-grails/src/main/java/springfox/documentation/grails/ActionSpecificationFactory.java"

springfox-grails-contract-tests/src/integration-test/resources/expected-service-description.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
"url": "http://www.apache.org/licenses/LICENSE-2.0"
1414
}
1515
},
16-
"host": "localhost:8080",
16+
"host": "localhost:__PORT__",
1717
"basePath": "/",
1818
"tags": [
1919
{

springfox-grails/src/main/java/springfox/documentation/grails/Actions.java

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -72,16 +72,6 @@ static Set<RequestMethod> methodOverrides(GrailsActionContext context) {
7272
return methodOverrides(context, newHashSet());
7373
}
7474

75-
private static void setFinalStatic(Field field, Object newValue) throws Exception {
76-
field.setAccessible(true);
77-
78-
Field modifiersField = Field.class.getDeclaredField("modifiers");
79-
modifiersField.setAccessible(true);
80-
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
81-
82-
field.set(null, newValue);
83-
}
84-
8575
static Set<MediaType> producesOverrides(GrailsActionContext context) {
8676
Set<MediaType> produces = newHashSet(MediaType.APPLICATION_JSON);
8777
List<String> responseFormats;

springfox-grails/src/main/java/springfox/documentation/grails/DefaultGrailsPropertyTransformer.java

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,25 @@
44

55
public class DefaultGrailsPropertyTransformer implements GrailsPropertyTransformer {
66
@Override
7-
public AlternateTypePropertyBuilder apply(GrailsDomainClassProperty each) {
8-
Class type = each.getReferencedPropertyType();
9-
if (!each.isPersistent() && each.getName().endsWith("Id")) {
10-
GrailsDomainClassProperty property = each.getDomainClass().getPropertyByName(each.getName().replace("Id", ""));
11-
type = property.getDomainClass().getIdentifier().getType();
7+
public AlternateTypePropertyBuilder apply(GrailsDomainClassProperty property) {
8+
Class type = property.getReferencedPropertyType();
9+
if (!property.isPersistent() && property.getName().endsWith("Id")) {
10+
type = relatedDomainIdentifierType(relatedDomainProperty(property));
1211
}
12+
1313
return new AlternateTypePropertyBuilder()
14-
.withName(each.getName())
14+
.withName(property.getName())
1515
.withType(type)
1616
.withCanRead(true)
1717
.withCanWrite(true);
1818
}
19+
20+
private Class relatedDomainIdentifierType(GrailsDomainClassProperty property) {
21+
return property.getDomainClass().getIdentifier().getType();
22+
}
23+
24+
private GrailsDomainClassProperty relatedDomainProperty(GrailsDomainClassProperty property) {
25+
String entityPropertyName = property.getName().replace("Id", "");
26+
return property.getDomainClass().getPropertyByName(entityPropertyName);
27+
}
1928
}

springfox-grails/src/test/groovy/springfox/documentation/grails/ActionsSpec.groovy

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
package springfox.documentation.grails
22

3+
import grails.core.GrailsControllerClass
4+
import grails.core.GrailsDomainClass
5+
import grails.web.mapping.LinkGenerator
6+
import grails.web.mapping.UrlMappings
7+
import org.springframework.web.bind.annotation.RequestMethod
38
import spock.lang.Specification
9+
import spock.lang.Unroll
410

511

612
class ActionsSpec extends Specification implements GrailsControllerSupport {
@@ -28,4 +34,64 @@ class ActionsSpec extends Specification implements GrailsControllerSupport {
2834
handlerMethods.containsKey("delete")
2935
handlerMethods.containsKey("other")
3036
}
37+
38+
@Unroll
39+
def "Detects grails method overrides for #action"() {
40+
given:
41+
def grailsController = grailsController(controller)
42+
def context = context(grailsController, action)
43+
when:
44+
def methods = Actions.methodOverrides(context)
45+
then:
46+
methods == expected
47+
where:
48+
controller | action | expected
49+
OverridenController | "withOverrides" | [RequestMethod.POST] as Set
50+
OverridenController | "noOverrides" | [] as Set
51+
}
52+
53+
@Unroll
54+
def "Detects grails method overrides with defaults for #action"() {
55+
given:
56+
def grailsController = grailsController(controller)
57+
def context = context(grailsController, action)
58+
when:
59+
def methods = Actions.methodOverrides(context, [RequestMethod.GET] as Set)
60+
then:
61+
methods == expected
62+
where:
63+
controller | action | expected
64+
OverridenController | "withOverrides" | [RequestMethod.POST] as Set
65+
OverridenController | "noOverrides" | [RequestMethod.GET] as Set
66+
}
67+
68+
def grailsController(Class controller) {
69+
def grails = Mock(GrailsControllerClass)
70+
grails.clazz >> controller
71+
grails
72+
}
73+
74+
GrailsActionContext context(controller, action) {
75+
new GrailsActionContext(
76+
controller,
77+
Mock(GrailsDomainClass),
78+
actionAttributes(),
79+
action)
80+
}
81+
82+
def actionAttributes() {
83+
new GrailsActionAttributes(
84+
Mock(LinkGenerator),
85+
Mock(UrlMappings))
86+
}
87+
88+
class OverridenController {
89+
static allowedMethods = [withOverrides: "POST", update: "PUT", delete: "DELETE"]
90+
91+
def withOverrides() {
92+
}
93+
94+
def show() {
95+
}
96+
}
3197
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package springfox.documentation.grails
2+
3+
import grails.core.GrailsDomainClass
4+
import grails.core.GrailsDomainClassProperty
5+
import spock.lang.Specification
6+
import spock.lang.Unroll
7+
8+
9+
class DefaultGrailsPropertySelectorSpec extends Specification {
10+
@Unroll
11+
def "selects scalar properties except version" () {
12+
given:
13+
def sut = new DefaultGrailsPropertySelector()
14+
expect:
15+
sut.apply(property) == expected
16+
where:
17+
property | expected
18+
version() | false
19+
scalar() | true
20+
entity() | false
21+
versionEntity() | false
22+
}
23+
24+
GrailsDomainClassProperty version() {
25+
property("version", null)
26+
}
27+
28+
GrailsDomainClassProperty scalar() {
29+
property("name", null)
30+
}
31+
32+
GrailsDomainClassProperty entity() {
33+
property("name", Mock(GrailsDomainClass))
34+
}
35+
36+
GrailsDomainClassProperty versionEntity() {
37+
property("version", Mock(GrailsDomainClass))
38+
}
39+
40+
def property(name, domain) {
41+
def property = Mock(GrailsDomainClassProperty)
42+
property.name >> name
43+
property.referencedDomainClass >> domain
44+
property
45+
}
46+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package springfox.documentation.grails
2+
3+
import grails.core.GrailsDomainClass
4+
import grails.core.GrailsDomainClassProperty
5+
import spock.lang.Specification
6+
import spock.lang.Unroll
7+
8+
9+
class DefaultGrailsPropertyTransformerSpec extends Specification {
10+
@Unroll
11+
def "Infers types correctly for grails property #name" (){
12+
given:
13+
def sut = new DefaultGrailsPropertyTransformer()
14+
when:
15+
def transformed = sut.apply(property)
16+
then:
17+
transformed.name == name
18+
transformed.clazz == type
19+
where:
20+
property | name | type
21+
id() | "id" | Long
22+
relatedEntityProperty() | "relatedEntity" | RelatedEntity
23+
relatedEntityIdProperty() | "relatedEntityId" | Long
24+
scalarProperty("test", String) | "test" | String
25+
}
26+
27+
def id() {
28+
scalarProperty("id", Long)
29+
}
30+
31+
def scalarProperty(propertyName, propertyType) {
32+
def property = Mock(GrailsDomainClassProperty)
33+
property.referencedPropertyType >> propertyType
34+
property.type >> propertyType
35+
property.persistent >> true
36+
property.name >> propertyName
37+
property
38+
}
39+
40+
def relatedEntityProperty() {
41+
def property = Mock(GrailsDomainClassProperty)
42+
property.referencedPropertyType >> RelatedEntity
43+
property.persistent >> true
44+
property.name >> "relatedEntity"
45+
property.domainClass >> relatedEntityDomain()
46+
property
47+
}
48+
49+
def relatedEntityIdProperty() {
50+
def property = Mock(GrailsDomainClassProperty)
51+
property.referencedPropertyType >> Long
52+
property.persistent >> false
53+
property.name >> "relatedEntityId"
54+
property.domainClass >> domainClass()
55+
property
56+
}
57+
58+
GrailsDomainClass domainClass() {
59+
def domain = Mock(GrailsDomainClass)
60+
domain.getPropertyByName("relatedEntity") >> relatedEntityProperty()
61+
domain
62+
}
63+
64+
GrailsDomainClass relatedEntityDomain() {
65+
def domain = Mock(GrailsDomainClass)
66+
domain.getIdentifier() >> id()
67+
domain
68+
}
69+
70+
class RelatedEntity {
71+
}
72+
}
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
package springfox.documentation.grails
2+
3+
import grails.core.GrailsControllerClass
4+
import grails.core.GrailsDomainClass
5+
import grails.web.mapping.LinkGenerator
6+
import grails.web.mapping.UrlMapping
7+
import grails.web.mapping.UrlMappings
8+
import org.springframework.web.bind.annotation.RequestMethod
9+
import spock.lang.Specification
10+
11+
12+
class GrailsActionAttributesSpec extends Specification {
13+
14+
def "Gets the http methods for operations correctly" () {
15+
given:
16+
def sut = actionAttributes(linkGenerator(), urlMappings())
17+
when:
18+
def actual = sut.httpMethod(context)
19+
then:
20+
actual == methods
21+
where:
22+
context | methods
23+
noOverrides() | [RequestMethod.GET] as Set
24+
withOverrides() | [RequestMethod.POST] as Set
25+
}
26+
27+
GrailsActionContext noOverrides() {
28+
context(noOverridesController(), "noOverride")
29+
}
30+
31+
GrailsActionContext withOverrides() {
32+
context(withOverridesController(), "withOverrides")
33+
}
34+
35+
GrailsActionContext context(controller, action) {
36+
new GrailsActionContext(
37+
controller,
38+
Mock(GrailsDomainClass),
39+
actionAttributes(linkGenerator(), urlMappings()),
40+
action)
41+
}
42+
43+
def noOverridesController() {
44+
controller(AController, "A")
45+
}
46+
47+
def withOverridesController() {
48+
controller(OverridenController, "Overriden")
49+
}
50+
51+
def controller(controllerClazz, name) {
52+
def controller = Mock(GrailsControllerClass)
53+
controller.clazz >> controllerClazz
54+
controller.name >> name
55+
controller
56+
}
57+
58+
def actionAttributes(linkGenerator, urlMappings) {
59+
new GrailsActionAttributes(
60+
linkGenerator,
61+
urlMappings)
62+
}
63+
64+
UrlMappings urlMappings() {
65+
def mappings = Mock(UrlMappings)
66+
mappings.urlMappings >> [noOverrideMapping(), withOverrideMapping()]
67+
mappings
68+
}
69+
70+
def noOverrideMapping() {
71+
def noOverride = Mock(UrlMapping)
72+
noOverride.actionName >> "noOverride"
73+
noOverride.httpMethod >> "GET"
74+
noOverride.controllerName >> "A"
75+
noOverride
76+
}
77+
78+
79+
def withOverrideMapping() {
80+
def noOverride = Mock(UrlMapping)
81+
noOverride.actionName >> "withOverride"
82+
noOverride.httpMethod >> "POST"
83+
noOverride.controllerName >> "Override"
84+
noOverride
85+
}
86+
87+
LinkGenerator linkGenerator() {
88+
def links = Mock(LinkGenerator)
89+
links.link(_) >> "/test"
90+
links.serverBaseURL >> "http://localhost:8080"
91+
links
92+
}
93+
94+
class OverridenController {
95+
static allowedMethods = [withOverrides: "POST", update: "PUT", delete: "DELETE"]
96+
97+
def withOverrides() {
98+
}
99+
}
100+
}

0 commit comments

Comments
 (0)