package org.openmhealth.shim.fitbit.mapper; import com.fasterxml.jackson.databind.JsonNode; import org.openmhealth.schema.domain.omh.*; import org.openmhealth.shim.common.mapper.DataPointMapperUnitTests; import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; import java.io.IOException; import java.time.LocalDate; import java.time.LocalTime; import java.time.OffsetDateTime; import java.util.List; import static java.time.ZoneOffset.UTC; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.equalTo; import static org.openmhealth.schema.domain.omh.DurationUnit.*; import static org.openmhealth.schema.domain.omh.DurationUnit.DAY; import static org.openmhealth.schema.domain.omh.KcalUnit.*; import static org.openmhealth.schema.domain.omh.LengthUnit.KILOMETER; /** * @author Chris Schaefbauer * @author Emerson Farrugia */ public class FitbitPhysicalActivityDataPointMapperUnitTests extends DataPointMapperUnitTests { private final FitbitPhysicalActivityDataPointMapper mapper = new FitbitPhysicalActivityDataPointMapper(); private JsonNode singleActivityResponseNode; private JsonNode multipleActivityResponseNode; @BeforeTest public void initializeResponseNodes() throws IOException { singleActivityResponseNode = asJsonNode("org/openmhealth/shim/fitbit/mapper/fitbit-activities-date-single-in-activities-list.json"); multipleActivityResponseNode = asJsonNode( "org/openmhealth/shim/fitbit/mapper/fitbit-activities-date-multiple-in-activities-list.json"); } @Test public void asDataPointsShouldReturnEmptyListWhenResponseIsEmpty() throws IOException { JsonNode emptyNode = asJsonNode("org/openmhealth/shim/fitbit/mapper/fitbit-activities-date-empty-activities-list.json"); assertThat(mapper.asDataPoints(emptyNode), is(empty())); } @Test public void asDataPointsShouldReturnCorrectNumberOfDataPoints() { assertThat(mapper.asDataPoints(singleActivityResponseNode).size(), equalTo(1)); assertThat(mapper.asDataPoints(multipleActivityResponseNode).size(), equalTo(3)); } @Test public void asDataPointsShouldReturnCorrectDataPointForSingleActivity() { List<DataPoint<PhysicalActivity>> dataPoints = mapper.asDataPoints(singleActivityResponseNode); assertThatDataPointMatches(dataPoints.get(0), "Walk", "2014-06-19", "09:00", 3.36, 3600000L, 79441095L, 128.0); } @Test public void asDataPointsShouldReturnCorrectDataPointsForMultipleActivities() { List<DataPoint<PhysicalActivity>> dataPoints = mapper.asDataPoints(multipleActivityResponseNode); assertThatDataPointMatches(dataPoints.get(0), "Run", "2015-06-23", "11:55", 6.43738, 1440000L, 253202765L, 150.0); assertThatDataPointMatches(dataPoints.get(1), "Swimming", "2015-06-23", "10:00", null, null, 253246706L, null); assertThatDataPointMatches(dataPoints.get(2), "Walk", "2015-06-23", 6.43738, 253202766L, 200.0); } public void assertThatDataPointMatches(DataPoint<PhysicalActivity> dataPoint, String expectedActivityName, String expectedEffectiveDate, Double expectedDistance, Long expectedExternalId, Double expectedCaloriesBurned) { OffsetDateTime expectedEffectiveStartDateTime = OffsetDateTime.of(LocalDate.parse(expectedEffectiveDate).atStartOfDay(), UTC); TimeFrame expectedTimeFrame = new TimeFrame( TimeInterval.ofStartDateTimeAndDuration(expectedEffectiveStartDateTime, new DurationUnitValue(DAY, 1))); assertThatDataPointMatches(dataPoint, expectedActivityName, expectedTimeFrame, expectedDistance, expectedExternalId, expectedCaloriesBurned); } public void assertThatDataPointMatches(DataPoint<PhysicalActivity> dataPoint, String expectedActivityName, TimeFrame expectedTimeFrame, Double expectedDistance, Long expectedExternalId, Double expectedCaloriesBurned) { PhysicalActivity.Builder expectedMeasureBuilder = new PhysicalActivity.Builder(expectedActivityName); expectedMeasureBuilder.setEffectiveTimeFrame(expectedTimeFrame); if (expectedDistance != null) { expectedMeasureBuilder.setDistance(new LengthUnitValue(KILOMETER, expectedDistance)); } if (expectedCaloriesBurned != null) { expectedMeasureBuilder.setCaloriesBurned(new KcalUnitValue(KILOCALORIE, expectedCaloriesBurned)); } PhysicalActivity expectedPhysicalActivity = expectedMeasureBuilder.build(); assertThat(dataPoint.getBody(), equalTo(expectedPhysicalActivity)); assertThat(dataPoint.getHeader().getBodySchemaId(), equalTo(PhysicalActivity.SCHEMA_ID)); assertThat(dataPoint.getHeader().getAcquisitionProvenance().getAdditionalProperties().get("external_id"), equalTo(expectedExternalId)); assertThat(dataPoint.getHeader().getAcquisitionProvenance().getSourceName(), equalTo(FitbitDataPointMapper.RESOURCE_API_SOURCE_NAME)); } public void assertThatDataPointMatches(DataPoint<PhysicalActivity> dataPoint, String expectedActivityName, String expectedEffectiveDate, String expectedEffectiveStartTime, Double expectedDistance, Long expectedDurationInMs, Long expectedExternalId, Double expectedCaloriesBurned) { OffsetDateTime expectedEffectiveStartDateTime = OffsetDateTime .of(LocalDate.parse(expectedEffectiveDate), LocalTime.parse(expectedEffectiveStartTime), UTC); TimeFrame expectedTimeFrame; if (expectedDurationInMs != null) { DurationUnitValue expectedDuration = new DurationUnitValue(MILLISECOND, expectedDurationInMs); expectedTimeFrame = new TimeFrame( TimeInterval.ofStartDateTimeAndDuration(expectedEffectiveStartDateTime, expectedDuration)); } else { expectedTimeFrame = new TimeFrame(expectedEffectiveStartDateTime); } assertThatDataPointMatches(dataPoint, expectedActivityName, expectedTimeFrame, expectedDistance, expectedExternalId, expectedCaloriesBurned); } }