package com.nightscout.core.upload;
import com.nightscout.core.dexcom.InvalidRecordLengthException;
import com.nightscout.core.dexcom.records.GlucoseDataSet;
import com.nightscout.core.preferences.NightscoutPreferences;
import com.nightscout.core.preferences.TestPreferences;
import net.tribe7.common.io.CharStreams;
import org.apache.http.HttpResponse;
import org.apache.http.ProtocolVersion;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.entity.StringEntity;
import org.apache.http.message.AbstractHttpMessage;
import org.apache.http.message.BasicHttpResponse;
import org.apache.http.message.BasicStatusLine;
import org.json.JSONException;
import org.json.JSONObject;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static com.nightscout.core.test.MockFactory.mockGlucoseDataSet;
import static junit.framework.TestCase.fail;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class AbstractRestUploaderTest {
private NoopRestUploader restUploader;
private HttpClient mockHttpClient;
private ArgumentCaptor<HttpUriRequest> captor;
@Before
public void setUp() throws Exception {
URI uri = URI.create("http://test.com");
restUploader = new NoopRestUploader(new TestPreferences(), uri);
mockHttpClient = mock(HttpClient.class);
restUploader.setClient(mockHttpClient);
captor = ArgumentCaptor.forClass(HttpUriRequest.class);
}
public void setUpExecuteCaptor() throws IOException {
setUpExecuteCaptor(200);
}
public void setUpExecuteCaptor(int status) throws IOException {
HttpResponse response = new BasicHttpResponse(
new BasicStatusLine(new ProtocolVersion("mock", 1, 2), status, ""));
response.setEntity(new StringEntity(""));
when(mockHttpClient.execute(captor.capture())).thenReturn(response);
}
@Test
public void testUploads_isPost() throws Exception {
setUpExecuteCaptor();
List<GlucoseDataSet> dataSets = new ArrayList<>(Arrays.asList(mockGlucoseDataSet()));
restUploader.uploadGlucoseDataSets(dataSets);
assertThat(captor.getValue().getMethod(), is("POST"));
}
@Test
public void testUploads_setsUrl() throws Exception {
setUpExecuteCaptor();
List<GlucoseDataSet> dataSets = new ArrayList<>(Arrays.asList(mockGlucoseDataSet()));
restUploader.uploadGlucoseDataSets(dataSets);
assertThat(captor.getValue().getURI(), is(not(nullValue())));
assertThat(captor.getValue().getURI().toString(), is("http://test.com/endpoint"));
}
@Test
public void testUploads_setsContentType() throws Exception {
setUpExecuteCaptor();
List<GlucoseDataSet> dataSets = new ArrayList<>(Arrays.asList(mockGlucoseDataSet()));
restUploader.uploadGlucoseDataSets(dataSets);
assertThat(captor.getValue().getFirstHeader("Content-Type"), is(not(nullValue())));
assertThat(captor.getValue().getFirstHeader("Content-Type").getValue(),
is("application/json"));
}
@Test
public void testUploads_setsAccept() throws Exception {
setUpExecuteCaptor();
List<GlucoseDataSet> dataSets = new ArrayList<>(Arrays.asList(mockGlucoseDataSet()));
restUploader.uploadGlucoseDataSets(dataSets);
assertThat(captor.getValue().getFirstHeader("Accept"), is(not(nullValue())));
assertThat(captor.getValue().getFirstHeader("Accept").getValue(), is("application/json"));
}
@Test
public void testUploads_setsExtraHeaders() throws Exception {
setUpExecuteCaptor();
List<GlucoseDataSet> dataSets = new ArrayList<>(Arrays.asList(mockGlucoseDataSet()));
restUploader.uploadGlucoseDataSets(dataSets);
assertThat(captor.getValue().getFirstHeader("key").getValue(), is("value"));
}
@Test
public void testUploads_setsEntity() throws IOException, InvalidRecordLengthException {
setUpExecuteCaptor();
List<GlucoseDataSet> dataSets = new ArrayList<>(Arrays.asList(mockGlucoseDataSet()));
restUploader.uploadGlucoseDataSets(dataSets);
HttpPost post = (HttpPost) captor.getValue();
String entity = CharStreams.toString(new InputStreamReader(post.getEntity().getContent()));
assertThat(entity, containsString("jsonKey"));
assertThat(entity, containsString("jsonValue"));
}
@Test
public void testUploads_2XXStatusCodeReturnsTrue() throws IOException, InvalidRecordLengthException {
setUpExecuteCaptor(251);
boolean result = restUploader.uploadGlucoseDataSets(new ArrayList<>(Arrays.asList(mockGlucoseDataSet())));
assertThat(result, is(true));
}
@Test
public void testUploads_Non200StatusCodeReturnsFalse() throws IOException, InvalidRecordLengthException {
setUpExecuteCaptor(400);
boolean result = restUploader.uploadGlucoseDataSets(new ArrayList<>(Arrays.asList(mockGlucoseDataSet())));
assertThat(result, is(false));
}
class NoopRestUploader extends AbstractRestUploader {
public NoopRestUploader(NightscoutPreferences preferences, URI uri) {
super(preferences, uri);
}
@Override
protected void setExtraHeaders(AbstractHttpMessage httpMessage) {
httpMessage.addHeader("key", "value");
}
@Override
protected boolean doUpload(GlucoseDataSet glucoseDataSet) throws IOException {
JSONObject jsonObject = new JSONObject();
try {
jsonObject.put("jsonKey", "jsonValue");
} catch (JSONException e) {
fail("This should never happen.");
}
return doPost("endpoint", jsonObject);
}
}
}