Created
January 13, 2016 21:05
-
-
Save leoluz/5e7ad32910911d0b0c4a to your computer and use it in GitHub Desktop.
A Wiremock listener implementation that records stubs with scenarios allowing you to playback your tests even in complex scenarios that depends on state transitions awareness.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import com.github.tomakehurst.wiremock.common.FileSource | |
import com.github.tomakehurst.wiremock.common.IdGenerator | |
import com.github.tomakehurst.wiremock.common.UniqueFilenameGenerator | |
import com.github.tomakehurst.wiremock.common.VeryShortIdGenerator | |
import com.github.tomakehurst.wiremock.http.* | |
import com.github.tomakehurst.wiremock.matching.RequestPattern | |
import com.github.tomakehurst.wiremock.matching.ValuePattern | |
import com.github.tomakehurst.wiremock.stubbing.Scenario | |
import com.github.tomakehurst.wiremock.stubbing.StubMapping | |
import static com.github.tomakehurst.wiremock.common.Json.write | |
import static java.util.Arrays.asList | |
import static org.skyscreamer.jsonassert.JSONCompareMode.LENIENT | |
class StubMappingWithScenarioJsonRecorder implements RequestListener { | |
private final FileSource mappingsFileSource | |
private final FileSource filesFileSource | |
private final List<CaseInsensitiveKey> headersToMatch | |
private IdGenerator idGenerator | |
private def scenariosMap | |
public StubMappingWithScenarioJsonRecorder(FileSource mappingsFileSource, FileSource filesFileSource, List<CaseInsensitiveKey> headersToMatch) | |
{ | |
this.mappingsFileSource = mappingsFileSource | |
this.filesFileSource = filesFileSource | |
this.headersToMatch = headersToMatch | |
this.scenariosMap = [:] | |
idGenerator = new VeryShortIdGenerator() | |
} | |
@Override | |
public void requestReceived(Request request, Response response) { | |
RequestPattern requestPattern = buildRequestPatternFrom(request) | |
if (response.isFromProxy()) { | |
writeToMappingAndBodyFile(request, response, requestPattern) | |
} | |
} | |
private RequestPattern buildRequestPatternFrom(Request request) { | |
RequestPattern requestPattern = new RequestPattern(request.getMethod(), request.getUrl()) | |
if (!headersToMatch.isEmpty()) { | |
for (HttpHeader header: request.getHeaders().all()) { | |
if (headersToMatch.contains(header.caseInsensitiveKey())) { | |
requestPattern.addHeader(header.key(), ValuePattern.equalTo(header.firstValue())) | |
} | |
} | |
} | |
String body = request.getBodyAsString() | |
if (!body.isEmpty()) { | |
ValuePattern bodyPattern = valuePatternForContentType(request) | |
requestPattern.setBodyPatterns(asList(bodyPattern)) | |
} | |
return requestPattern | |
} | |
private ValuePattern valuePatternForContentType(Request request) { | |
String contentType = request.getHeader("Content-Type") | |
if (contentType != null) { | |
if (contentType.contains("json")) { | |
return ValuePattern.equalToJson(request.getBodyAsString(), LENIENT) | |
} else if (contentType.contains("xml")) { | |
return ValuePattern.equalToXml(request.getBodyAsString()) | |
} | |
} | |
return ValuePattern.equalTo(request.getBodyAsString()) | |
} | |
private void writeToMappingAndBodyFile(Request request, Response response, RequestPattern requestPattern) { | |
String fileId = idGenerator.generate() | |
String mappingFileName = UniqueFilenameGenerator.generate(request, "mapping", fileId) | |
String bodyFileName = UniqueFilenameGenerator.generate(request, "body", fileId) | |
ResponseDefinition responseToWrite = new ResponseDefinition() | |
responseToWrite.setStatus(response.getStatus()) | |
responseToWrite.setBodyFileName(bodyFileName) | |
if (response.getHeaders().size() > 0) { | |
responseToWrite.setHeaders(response.getHeaders()) | |
} | |
StubMapping mapping = new StubMapping(requestPattern, responseToWrite) | |
String scenarioName = getScenarioName(requestPattern) | |
def currentScenarioState = getScenarioCurrentState(scenarioName) | |
mapping.setScenarioName(scenarioName); | |
mapping.setRequiredScenarioState(currentScenarioState) | |
if (isNewScenarioState(scenarioName)) { | |
mapping.setNewScenarioState(getNewScenarioState(scenarioName)) | |
} | |
filesFileSource.writeBinaryFile(bodyFileName, response.getBody()) | |
mappingsFileSource.writeTextFile(mappingFileName, write(mapping)) | |
} | |
String getScenarioName(requestPattern) { | |
def baseUrl = requestPattern.url.split(/[?#]/)[0] | |
"${requestPattern.method}_${baseUrl}" | |
} | |
String getScenarioCurrentState(String scenarioName) { | |
def currentState | |
if (!this.scenariosMap[scenarioName]) { | |
this.scenariosMap << [(scenarioName): Scenario.STARTED] | |
currentState = Scenario.STARTED | |
} else { | |
currentState = this.scenariosMap[scenarioName] | |
} | |
currentState | |
} | |
private boolean isNewScenarioState(scenarioName) { | |
this.scenariosMap.containsKey(scenarioName) | |
} | |
String getNewScenarioState(String scenarioName) { | |
def newScenarioState | |
if (!this.scenariosMap[scenarioName]) { | |
this.scenariosMap << [(scenarioName): Scenario.STARTED] | |
newScenarioState = Scenario.STARTED | |
} else { | |
def currentState = this.scenariosMap[scenarioName] | |
newScenarioState = currentState == Scenario.STARTED ? 1 : currentState + 1 | |
this.scenariosMap[scenarioName] = newScenarioState | |
} | |
newScenarioState.toString() | |
} | |
public void setIdGenerator(IdGenerator idGenerator) { | |
this.idGenerator = idGenerator | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment