Skip to content

Commit cd1d14d

Browse files
author
Ronald Holshausen
committedNov 24, 2019
fix: JSON reporter was generated incorrect failure JSON #980
1 parent 4b2c3f6 commit cd1d14d

File tree

3 files changed

+111
-5
lines changed

3 files changed

+111
-5
lines changed
 

‎provider/pact-jvm-provider/src/main/kotlin/au/com/dius/pact/provider/ResponseComparison.kt

+7-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import au.com.dius.pact.core.model.Response
1818
import au.com.dius.pact.core.model.isNullOrEmpty
1919
import au.com.dius.pact.core.model.messaging.Message
2020
import au.com.dius.pact.core.support.Json
21+
import com.github.salomonbrys.kotson.jsonObject
2122
import com.google.gson.JsonParser
2223
import mu.KLogging
2324
import org.apache.http.entity.ContentType
@@ -26,7 +27,12 @@ import java.nio.charset.Charset
2627
data class BodyComparisonResult(
2728
val mismatches: Map<String, List<BodyMismatch>> = emptyMap(),
2829
val diff: List<String> = emptyList()
29-
)
30+
) {
31+
fun toJson() = jsonObject(
32+
"mismatches" to Json.toJson(mismatches.mapValues { entry -> entry.value.map { it.description() } }),
33+
"diff" to diff.joinToString("\n")
34+
)
35+
}
3036

3137
data class ComparisonResult(
3238
val statusMismatch: StatusMismatch? = null,

‎provider/pact-jvm-provider/src/main/kotlin/au/com/dius/pact/provider/reporters/JsonReporter.kt

+20-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package au.com.dius.pact.provider.reporters
22

3+
import arrow.core.Either
4+
import au.com.dius.pact.core.matchers.BodyTypeMismatch
5+
import au.com.dius.pact.core.matchers.HeaderMismatch
36
import au.com.dius.pact.core.model.BasePact
47
import au.com.dius.pact.core.model.FileSource
58
import au.com.dius.pact.core.model.Interaction
@@ -10,6 +13,7 @@ import au.com.dius.pact.core.model.UrlPactSource
1013
import au.com.dius.pact.core.support.Json
1114
import au.com.dius.pact.core.support.hasProperty
1215
import au.com.dius.pact.core.support.property
16+
import au.com.dius.pact.provider.BodyComparisonResult
1317
import au.com.dius.pact.provider.IConsumerInfo
1418
import au.com.dius.pact.provider.IProviderInfo
1519
import com.github.salomonbrys.kotson.array
@@ -19,6 +23,7 @@ import com.github.salomonbrys.kotson.jsonObject
1923
import com.github.salomonbrys.kotson.obj
2024
import com.github.salomonbrys.kotson.set
2125
import com.github.salomonbrys.kotson.string
26+
import com.github.salomonbrys.kotson.toJson
2227
import com.google.gson.JsonObject
2328
import com.google.gson.JsonParser
2429
import org.apache.commons.lang3.exception.ExceptionUtils
@@ -191,15 +196,27 @@ class JsonReporter(
191196
if (!verification.has("header")) {
192197
verification["header"] = jsonObject()
193198
}
194-
verification["header"].obj[key] = Json.toJson(comparison)
199+
verification["header"].obj[key] = when (comparison) {
200+
is List<*> -> Json.toJson(comparison.map {
201+
when (it) {
202+
is HeaderMismatch -> it.mismatch.toJson()
203+
else -> Json.toJson(it)
204+
}
205+
})
206+
else -> Json.toJson(comparison)
207+
}
195208
}
196209

197210
override fun bodyComparisonOk() { }
198211

199212
override fun bodyComparisonFailed(comparison: Any) {
200213
val verification = jsonData["execution"].array.last()["interactions"].array.last()["verification"].obj
201214
verification["result"] = FAILED
202-
verification["body"] = Json.toJson(comparison)
215+
verification["body"] = when (comparison) {
216+
is Either.Left<*> -> Json.toJson((comparison as Either.Left<BodyTypeMismatch>).a.description())
217+
is Either.Right<*> -> (comparison as Either.Right<BodyComparisonResult>).b.toJson()
218+
else -> Json.toJson(comparison)
219+
}
203220
}
204221

205222
override fun errorHasNoAnnotatedMethodsFoundForInteraction(interaction: Interaction) {
@@ -239,7 +256,7 @@ class JsonReporter(
239256
override fun metadataComparisonOk() { }
240257

241258
companion object {
242-
const val REPORT_FORMAT = "0.0.0"
259+
const val REPORT_FORMAT = "0.1.0"
243260
const val FAILED = "failed"
244261
}
245262
}

‎provider/pact-jvm-provider/src/test/groovy/au/com/dius/pact/provider/reporters/JsonReporterSpec.groovy

+84-1
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,20 @@
11
package au.com.dius.pact.provider.reporters
22

3+
import arrow.core.Either
4+
import au.com.dius.pact.core.matchers.BodyMismatch
5+
import au.com.dius.pact.core.matchers.HeaderMismatch
36
import au.com.dius.pact.core.model.Request
47
import au.com.dius.pact.core.model.RequestResponseInteraction
58
import au.com.dius.pact.core.model.Response
9+
import au.com.dius.pact.provider.BodyComparisonResult
610
import au.com.dius.pact.provider.ConsumerInfo
711
import au.com.dius.pact.provider.ProviderInfo
12+
import com.google.gson.JsonParser
813
import groovy.json.JsonOutput
914
import groovy.json.JsonSlurper
1015
import spock.lang.Specification
1116

12-
@SuppressWarnings('UnnecessaryObjectReferences')
17+
@SuppressWarnings(['UnnecessaryObjectReferences', 'LineLength'])
1318
class JsonReporterSpec extends Specification {
1419

1520
private File reportDir
@@ -105,4 +110,82 @@ class JsonReporterSpec extends Specification {
105110
reportJson.execution.first().interactions.first().interaction.description == 'Interaction 1'
106111
}
107112

113+
def 'generates the correct JSON for validation failures'() {
114+
given:
115+
def reporter = new JsonReporter('test', reportDir)
116+
def provider1 = new ProviderInfo(name: 'provider1')
117+
def consumer = new ConsumerInfo(name: 'Consumer')
118+
def interaction1 = new RequestResponseInteraction('Interaction 1', [], new Request(), new Response())
119+
120+
when:
121+
reporter.initialise(provider1)
122+
reporter.reportVerificationForConsumer(consumer, provider1, null)
123+
reporter.interactionDescription(interaction1)
124+
reporter.statusComparisonFailed(200, 'expected status of 201 but was 200')
125+
reporter.headerComparisonFailed('HEADER-X', [''], [
126+
new HeaderMismatch('HEADER-X', 'Y', '', "Expected a header 'HEADER-X' but was missing")
127+
])
128+
reporter.bodyComparisonFailed(
129+
new Either.Right(new BodyComparisonResult([
130+
'$.0': [
131+
new BodyMismatch(
132+
JsonParser.parseString('{"doesNotExist":"Test","documentId":0}'),
133+
JsonParser.parseString('{"documentId":0,"documentCategoryId":5,"documentCategoryCode":null,"contentLength":0,"tags":null}'),
134+
'Expected doesNotExist="Test" but was missing', '$.0', '''{
135+
- "doesNotExist": "Test",
136+
- "documentId": 0
137+
+ "documentId": 0,
138+
+ "documentCategoryId": 5,
139+
+ "documentCategoryCode": null,
140+
+ "contentLength": 0,
141+
+ "tags": null
142+
}''')],
143+
'$.1': [
144+
new BodyMismatch(JsonParser.parseString('{"doesNotExist":"Test","documentId":0}'),
145+
JsonParser.parseString('{"documentId":1,"documentCategoryId":5,"documentCategoryCode":null,"contentLength":0,"tags":null}'),
146+
'Expected doesNotExist="Test" but was missing', '$.1', '''{
147+
- "doesNotExist": "Test",
148+
- "documentId": 0
149+
+ "documentId": 1,
150+
+ "documentCategoryId": 5,
151+
+ "documentCategoryCode": null,
152+
+ "contentLength": 0,
153+
+ "tags": null
154+
}''')]
155+
], [
156+
' {',
157+
'- " doesNotExist ": " Test ",',
158+
'- " documentId ": 0',
159+
'+ " documentId ": 0,',
160+
'+ " documentCategoryId ": 5,',
161+
'+ " documentCategoryCode ": null,',
162+
'+ " contentLength ": 0,',
163+
'+ " tags ": null',
164+
'+ },',
165+
'+ {',
166+
'+ " documentId ": 1,',
167+
'+ " documentCategoryId ": 5,',
168+
'+ " documentCategoryCode ": null,',
169+
'+ " contentLength ": 0,',
170+
'+ " tags ": null',
171+
' }'
172+
]))
173+
)
174+
reporter.finaliseReport()
175+
176+
def reportJson = new JsonSlurper().parse(new File(reportDir, 'provider1.json'))
177+
178+
then:
179+
reportJson.provider.name == 'provider1'
180+
reportJson.execution.size == 1
181+
reportJson.execution[0].interactions.size == 1
182+
reportJson.execution[0].interactions[0].verification.result == 'failed'
183+
reportJson.execution[0].interactions[0].verification.status == ['expected status of 201 but was 200']
184+
reportJson.execution[0].interactions[0].verification.header == ['HEADER-X': ["Expected a header 'HEADER-X' but was missing"]]
185+
reportJson.execution[0].interactions[0].verification.body.mismatches == [
186+
'$.0': ['Expected doesNotExist="Test" but was missing'],
187+
'$.1': ['Expected doesNotExist="Test" but was missing']
188+
]
189+
}
190+
108191
}

0 commit comments

Comments
 (0)
Please sign in to comment.