package com.nightscout.core.upload; import com.nightscout.core.drivers.AbstractUploaderDevice; import com.nightscout.core.preferences.TestPreferences; import net.tribe7.common.collect.Lists; import net.tribe7.common.io.CharStreams; import org.apache.http.Header; 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.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 org.mockito.Mockito; import java.io.IOException; import java.io.InputStreamReader; import java.net.URI; import static com.nightscout.core.test.MockFactory.mockCalRecord; import static com.nightscout.core.test.MockFactory.mockDeviceStatus; import static com.nightscout.core.test.MockFactory.mockGlucoseDataSet; import static com.nightscout.core.test.MockFactory.mockMeterRecord; 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.when; public class RestV1UploaderTest { private RestV1Uploader restUploader; private HttpClient mockHttpClient; private ArgumentCaptor<HttpUriRequest> captor; private TestPreferences preferences; public static void verifyGlucoseDataSet(JSONObject jsonObject, boolean enableCloudSensorData) throws JSONException { assertThat(jsonObject.getString("device"), is("UNKNOWN")); assertThat(jsonObject.get("date"), is(not(nullValue()))); assertThat(jsonObject.get("dateString"), is(not(nullValue()))); assertThat(jsonObject.get("sgv"), is(not(nullValue()))); assertThat(jsonObject.get("direction"), is(not(nullValue()))); assertThat(jsonObject.get("type"), is(not(nullValue()))); if (enableCloudSensorData) { assertThat(jsonObject.get("filtered"), is(not(nullValue()))); assertThat(jsonObject.get("unfiltered"), is(not(nullValue()))); assertThat(jsonObject.get("rssi"), is(not(nullValue()))); assertThat(jsonObject.get("noise"), is(not(nullValue()))); } else { assertThat(jsonObject.has("filtered"), is(false)); assertThat(jsonObject.has("unfiltered"), is(false)); assertThat(jsonObject.has("rssi"), is(false)); assertThat(jsonObject.has("noise"), is(false)); } } public static void verifyMeterRecord(JSONObject jsonObject) throws JSONException { assertThat(jsonObject.getString("device"), is("UNKNOWN")); assertThat(jsonObject.getString("type"), is("mbg")); assertThat(jsonObject.get("date"), is(not(nullValue()))); assertThat(jsonObject.get("dateString"), is(not(nullValue()))); assertThat(jsonObject.get("mbg"), is(not(nullValue()))); } public static void verifyCalRecord(JSONObject jsonObject) throws JSONException { assertThat(jsonObject.getString("device"), is("UNKNOWN")); assertThat(jsonObject.getString("type"), is("cal")); assertThat(jsonObject.get("date"), is(not(nullValue()))); assertThat(jsonObject.get("dateString"), is(not(nullValue()))); assertThat(jsonObject.get("slope"), is(not(nullValue()))); assertThat(jsonObject.get("intercept"), is(not(nullValue()))); assertThat(jsonObject.get("scale"), is(not(nullValue()))); } public static void verifyDeviceStatus(JSONObject jsonObject, AbstractUploaderDevice deviceStatus) throws JSONException { assertThat(jsonObject.getInt("uploaderBattery"), is(deviceStatus.getBatteryLevel())); } @Before public void setUp() throws Exception { preferences = new TestPreferences(); restUploader = new RestV1Uploader(preferences, URI.create("http://testingtesting@test.com/v1")); mockHttpClient = Mockito.mock(HttpClient.class); restUploader.setClient(mockHttpClient); setUpExecuteCaptor(); } public void setUpExecuteCaptor() throws IOException { setUpExecuteCaptor(200); } public void setUpExecuteCaptor(int status) throws IOException { captor = ArgumentCaptor.forClass(HttpUriRequest.class); 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 testInitialize_StripUserInfo() { RestV1Uploader uploader = new RestV1Uploader(preferences, URI.create("http://testingtesting@test.com/v1")); assertThat(uploader.getUri().toString(), is("http://test.com/v1")); } @Test public void testInitialize_GenerateToken() { RestV1Uploader uploader = new RestV1Uploader(preferences, URI.create("http://testingtesting@test.com/v1")); assertThat(uploader.getSecret(), is(not(nullValue()))); assertThat(uploader.getSecret(), is("b0212be2cc6081fba3e0b6f3dc6e0109d6f7b4cb")); } @Test public void testInitalize_NoToken() { try { new RestV1Uploader(preferences, URI.create("http://test.com")); fail("Should not be a valid uploader."); } catch (IllegalArgumentException e) { assertThat(e.getMessage(), containsString("token")); } } @Test public void testGlucoseDataSet_Endpoint() throws Exception { restUploader.uploadGlucoseDataSets(Lists.newArrayList(mockGlucoseDataSet())); assertThat(captor.getValue().getURI().toString(), containsString("entries")); } @Test public void testAPISecret() throws Exception { restUploader.uploadGlucoseDataSets(Lists.newArrayList(mockGlucoseDataSet())); HttpPost post = (HttpPost) captor.getValue(); Header[] headers = post.getHeaders("api-secret"); assertThat(headers.length, is(1)); assertThat(headers[0].getValue(), is("b0212be2cc6081fba3e0b6f3dc6e0109d6f7b4cb")); } @Test public void testGlucoseDataSet_Entity() throws Exception { restUploader.uploadGlucoseDataSets(Lists.newArrayList(mockGlucoseDataSet())); HttpPost post = (HttpPost) captor.getValue(); String entity = CharStreams.toString(new InputStreamReader(post.getEntity().getContent())); verifyGlucoseDataSet(new JSONObject(entity), false); } @Test public void testGlucoseDataSet_EntitySensorUploadEnabled() throws Exception { preferences.setRawEnabled(true); restUploader.uploadGlucoseDataSets(Lists.newArrayList(mockGlucoseDataSet())); HttpPost post = (HttpPost) captor.getValue(); String entity = CharStreams.toString(new InputStreamReader(post.getEntity().getContent())); verifyGlucoseDataSet(new JSONObject(entity), true); } @Test public void testMeterRecord_Endpoint() throws Exception { restUploader.uploadMeterRecords(Lists.newArrayList(mockMeterRecord())); assertThat(captor.getValue().getURI().toString(), containsString("entries")); } @Test public void testMeterRecord_Entity() throws Exception { restUploader.uploadMeterRecords(Lists.newArrayList(mockMeterRecord())); HttpPost post = (HttpPost) captor.getValue(); String entity = CharStreams.toString(new InputStreamReader(post.getEntity().getContent())); verifyMeterRecord(new JSONObject(entity)); } @Test public void testCalRecord_Endpoint() throws Exception { preferences.setRawEnabled(true); restUploader.uploadCalRecords(Lists.newArrayList(mockCalRecord())); assertThat(captor.getValue().getURI().toString(), containsString("entries")); } @Test public void testCalRecord_Entity() throws Exception { preferences.setRawEnabled(true); restUploader.uploadCalRecords(Lists.newArrayList(mockCalRecord())); HttpPost post = (HttpPost) captor.getValue(); String entity = CharStreams.toString(new InputStreamReader(post.getEntity().getContent())); verifyCalRecord(new JSONObject(entity)); } @Test public void testDeviceStatus_Endpoint() throws Exception { restUploader.uploadDeviceStatus(mockDeviceStatus(), 100); assertThat(captor.getValue().getURI().toString(), containsString("devicestatus")); } @Test public void testDeviceStatus_Entity() throws Exception { AbstractUploaderDevice deviceStatus = mockDeviceStatus(); restUploader.uploadDeviceStatus(deviceStatus, 100); HttpPost post = (HttpPost) captor.getValue(); String entity = CharStreams.toString(new InputStreamReader(post.getEntity().getContent())); verifyDeviceStatus(new JSONObject(entity), deviceStatus); } // TODO add test for mismatched EGV/Sensor records to verify upload }