/**
* Copyright (c) 2016 Couchbase, Inc. All rights reserved.
* <p/>
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of the License at
* <p/>
* http://www.apache.org/licenses/LICENSE-2.0
* <p/>
* Unless required by applicable law or agreed to in writing, software distributed under the
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific language governing permissions
* and limitations under the License.
*/
package com.couchbase.lite.mockserver;
import com.couchbase.lite.Manager;
import java.io.IOException;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.RecordedRequest;
import okio.Buffer;
/*
Mock checkpoint response for a 201 PUT request to update the checkpoint
{
"id":"_local/7d3186e30a82a3312fc2c54098a25ce568cd7dfb",
"ok":true,
"rev":"0-1"
}
*/
public class MockCheckpointPut implements SmartMockResponse {
private String id;
private String rev;
private boolean isSticky;
private long delayMs;
private String getId() {
return id;
}
private void setId(String id) {
this.id = id;
}
private Map<String, Object> generateMap() {
Map<String, Object> docMap = new HashMap<String, Object>();
docMap.put("id", getId());
docMap.put("ok", true); // ditto
docMap.put("rev", generateNextRev());
return docMap;
}
private String generateBody() {
Map documentMap = generateMap();
try {
return Manager.getObjectMapper().writeValueAsString(documentMap);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* If the rev is empty, then generate rev "0-1"
* If the rev is "0-1", then generate rev "0-2"
* etc..
*
* @return the next rev to use, with respect to this.rev
*/
private String generateNextRev() {
if (getRev() == null) {
return "0-0001";
} else {
StringTokenizer st = new StringTokenizer(getRev(), "-");
String beforeDash = st.nextToken();
String afterDash = st.nextToken();
int afterDashInt = Integer.parseInt(afterDash);
afterDashInt += 1;
afterDash = String.format("%s", afterDashInt);
return String.format("%s-%s", beforeDash, afterDash);
}
}
@Override
public MockResponse generateMockResponse(RecordedRequest request) {
MockResponse mockResponse = new MockResponse();
if (request.getMethod().equals("PUT")) {
// extract id from request
// /db/_local/e11a8567a2ecaf27c52d02899fa82258a343d720 -> _local/e11a8567a2ecaf27c52d02899fa82258a343d720
String path = request.getPath();
String localDocId = "";
Pattern pattern = Pattern.compile("/db/_local/(.*)");
Matcher matcher = pattern.matcher(path);
if (matcher.find()) {
localDocId = matcher.group(1);
} else {
throw new RuntimeException(String.format(Locale.ENGLISH, "Could not extract local doc id from: %s", path));
}
// call setId
setId(String.format(Locale.ENGLISH, "_local/%s", localDocId));
// extract the _rev field from the request
try {
// Request.getUtf8Body() consumes Buffer. So need to clone.
Buffer clone = request.getBody().clone();
Map<String, Object> jsonMap = Manager.getObjectMapper().readValue(clone.readByteArray(), Map.class);
if (jsonMap.containsKey("_rev")) {
setRev((String) jsonMap.get("_rev"));
}
} catch (IOException e) {
throw new RuntimeException(e);
}
mockResponse.setBody(generateBody());
MockHelper.set201OKJson(mockResponse);
return mockResponse;
} else if (request.getMethod().equals("GET")) {
MockHelper.set404NotFoundJson(mockResponse);
} else {
throw new RuntimeException(String.format(Locale.ENGLISH, "Unexpected method: %s", request.getMethod()));
}
return mockResponse;
}
@Override
public boolean isSticky() {
return this.isSticky;
}
@Override
public long delayMs() {
return delayMs;
}
public void setSticky(boolean isSticky) {
this.isSticky = isSticky;
}
public String getRev() {
return rev;
}
public void setRev(String rev) {
this.rev = rev;
}
public long getDelayMs() {
return delayMs;
}
public void setDelayMs(long delayMs) {
this.delayMs = delayMs;
}
}