/** AirCasting - Share your Air! Copyright (C) 2011-2012 HabitatMap, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. You can contact the authors by email at <info@habitatmap.org> */ package pl.llp.aircasting.view.presenter; import pl.llp.aircasting.InjectedTestRunner; import pl.llp.aircasting.activity.ApplicationState; import pl.llp.aircasting.activity.events.SessionChangeEvent; import pl.llp.aircasting.event.ui.ViewStreamEvent; import pl.llp.aircasting.helper.SettingsHelper; import pl.llp.aircasting.model.Measurement; import pl.llp.aircasting.model.MeasurementStream; import pl.llp.aircasting.model.Sensor; import pl.llp.aircasting.model.SensorManager; import pl.llp.aircasting.model.Session; import pl.llp.aircasting.model.SessionManager; import pl.llp.aircasting.model.events.MeasurementEvent; import com.google.inject.Inject; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import java.util.ArrayList; import java.util.Date; import java.util.List; import static org.fest.assertions.Assertions.assertThat; import static org.mockito.Mockito.*; @RunWith(InjectedTestRunner.class) public class MeasurementPresenterTest { @Inject MeasurementPresenter presenter; List<Measurement> measurements; private Measurement measurement1 = new Measurement(4, 4, 4, new Date(0, 0, 0, 0, 1, 8)); private Measurement measurement2 = new Measurement(5, 6, 5, new Date(0, 0, 0, 0, 1, 10)); private MeasurementPresenter.Listener listener; private MeasurementStream stream; private Session session; private Sensor sensor; private SessionChangeEvent EVENT; @Inject ApplicationState state; @Before public void setup() { measurements = new ArrayList<Measurement>(); for (int i = 0; i < 4; i++) { measurements.add(new Measurement(i, i, i, new Date(0, 0, 0, 0, 1, 2 * i))); } sensor = mock(Sensor.class); when(sensor.getSensorName()).thenReturn("LHC"); presenter.sensorManager = mock(SensorManager.class); when(presenter.sensorManager.getVisibleSensor()).thenReturn(sensor); presenter.onEvent(new ViewStreamEvent(sensor)); stream = mock(MeasurementStream.class); when(stream.getMeasurements()).thenReturn(measurements); session = mock(Session.class); presenter.sessionManager = mockSessionManager(); when(presenter.sessionManager.getMeasurementStream("LHC")).thenReturn(stream); when(presenter.sessionManager.isSessionStarted()).thenReturn(true); when(presenter.sessionManager.getSession()).thenReturn(session); listener = mock(MeasurementPresenter.Listener.class); presenter.registerListener(listener); presenter.settingsHelper = mock(SettingsHelper.class); when(presenter.settingsHelper.getAveragingTime()).thenReturn(1); EVENT = new SessionChangeEvent(new Session()); } private SessionManager mockSessionManager() { SessionManager result = mock(SessionManager.class); when(result.isSessionStarted()).thenReturn(true); return result; } private void triggerMeasurement(Measurement measurement) { presenter.onEvent(new MeasurementEvent(measurement, sensor)); } @Test public void shouldShowLastNMillis() { state.recording().startRecording(); presenter.setZoom(100); List<Measurement> result = presenter.getTimelineView(); assertThat(result).contains(measurements.get(3)); assertThat(result).excludes(measurements.get(2)); } @Test public void shouldNotCluster() { state.recording().startRecording(); presenter.setZoom(4000); assertThat(presenter.getTimelineView()).contains(measurements.get(3), measurements.get(2)); } @Test public void shouldHandleEmptyList() { when(stream.getMeasurements()).thenReturn(new ArrayList<Measurement>()); assertThat(presenter.getTimelineView()).isEmpty(); } @Test public void shouldAppendWithoutRecalculating() { state.recording().startRecording(); presenter.setZoom(4000); presenter.getTimelineView(); presenter.sessionManager = mockSessionManager(); triggerMeasurement(measurement1); List<Measurement> result = presenter.getTimelineView(); assertThat(result).contains(measurement1, measurements.get(3)).excludes(measurements.get(2)); } @Test public void shouldNotifyListeners_when_recording() { // given state.recording().startRecording(); // when triggerMeasurement(measurement1); // then verify(listener).onViewUpdated(); } @Test public void shouldUnregisterListeners() { presenter.unregisterListener(listener); triggerMeasurement(measurement1); verifyZeroInteractions(listener); } @Test public void shouldAllowToZoomOut() { state.recording().startRecording(); presenter.setZoom(2000); assertThat(presenter.canZoomOut()).isTrue(); } @Test public void shouldNotAllowToZoomOutTooMuch() { presenter.setZoom(100000000); assertThat(presenter.canZoomOut()).isFalse(); } @Test public void shouldAllowToZoomOutAfterMoreDataArrives() { state.recording().startRecording(); presenter.setZoom(8000); presenter.getTimelineView(); triggerMeasurement(measurement1); assertThat(presenter.canZoomOut()).isTrue(); } @Test public void shouldUpdateTheFullView() { state.recording().startRecording(); presenter.getFullView(); presenter.sessionManager = mockSessionManager(); triggerMeasurement(measurement1); List<Measurement> result = presenter.getFullView(); assertThat(result).contains(measurement1); } @Test public void shouldNotUpdateWhenViewingASession() { presenter.getFullView(); presenter.sessionManager = mockSessionManager(); when(presenter.sessionManager.isSessionStarted()).thenReturn(false); when(presenter.sessionManager.isSessionSaved()).thenReturn(true); presenter.onEvent(EVENT); triggerMeasurement(measurement1); assertThat(presenter.getFullView()).isEmpty(); } @Test public void shouldOnlyUpdateFromVisibleSensorEvents() { presenter.getFullView(); presenter.sessionManager = mockSessionManager(); when(presenter.sessionManager.isSessionStarted()).thenReturn(false); when(presenter.sessionManager.isSessionSaved()).thenReturn(true); presenter.onEvent(EVENT); triggerMeasurement(measurement1); assertThat(presenter.getFullView()).isEmpty(); } @Test public void fullViewShouldBeEmptyWithoutASession() { when(presenter.sessionManager.isSessionSaved()).thenReturn(false); when(presenter.sessionManager.isSessionStarted()).thenReturn(false); triggerMeasurement(measurement1); assertThat(presenter.getFullView()).isEmpty(); } @Test public void timelineViewShouldBeEmptyWithoutASession() { when(presenter.sessionManager.isSessionSaved()).thenReturn(false); when(presenter.sessionManager.isSessionStarted()).thenReturn(false); assertThat(presenter.getTimelineView()).isEmpty(); } // // @Test // public void shouldScrollLeft() // { // presenter.setZoom(4000); // // presenter.scroll(-0.5); // // assertThat(presenter.getTimelineView(), hasItem(equalTo(measurements.get(2)))); // assertThat(presenter.getTimelineView(), hasItem(equalTo(measurements.get(1)))); // } // // @Test // public void shouldScrollRight() // { // presenter.setZoom(4000); // // presenter.scroll(-1); // presenter.scroll(0.5); // // assertThat(presenter.getTimelineView(), hasItem(equalTo(measurements.get(2)))); // assertThat(presenter.getTimelineView(), hasItem(equalTo(measurements.get(1)))); // } // // @Test // public void shouldNotScrollTooMuchRight() // { // presenter.setZoom(4000); // // presenter.scroll(2); // // assertThat(presenter.getTimelineView(), hasItem(equalTo(measurements.get(3)))); // assertThat(presenter.getTimelineView(), hasItem(equalTo(measurements.get(2)))); // } // // @Test // public void shouldNotScrollTooMuchLeft() // { // presenter.setZoom(4000); // // presenter.scroll(-10); // // assertThat(presenter.getTimelineView(), hasItem(equalTo(measurements.get(1)))); // assertThat(presenter.getTimelineView(), hasItem(equalTo(measurements.get(0)))); // } // // @Test // public void shouldNotifyListenersOnScroll() // { // presenter.scroll(-10); // // verify(listener).onViewUpdated(); // } // // @Test // public void shouldNotUpdateTheTimelineIfScrolled() // { // presenter.setZoom(4000); // presenter.scroll(-0.5); // // presenter.getTimelineView(); // triggerMeasurement(measurement1); // // assertThat(presenter.getTimelineView(), not(hasItem(equalTo(measurement1)))); // } // // @Test // public void shouldAverage() // { // when(presenter.settingsHelper.getAveragingTime()).thenReturn(4); // Measurement expected = new Measurement(1.5, 1.5, 1.5, new Date(0, 0, 0, 0, 1, 3)); // // presenter.onEvent(EVENT); // // assertThat(presenter.getFullView(), hasItem(equalTo(expected))); // } // @Test public void shouldAverageOnTheFly() { state.recording().startRecording(); when(presenter.settingsHelper.getAveragingTime()).thenReturn(4); Measurement expected = new Measurement(3.5, 3.5, 3.5, new Date(0, 0, 0, 0, 1, 5)); presenter.onEvent(EVENT); triggerMeasurement(measurement1); triggerMeasurement(measurement2); assertThat(presenter.getFullView()).contains(expected, measurement2); } @Test public void shouldAverageTimelineOnTheFly() { state.recording().startRecording(); when(presenter.settingsHelper.getAveragingTime()).thenReturn(4); Measurement expected = new Measurement(3.5, 3.5, 3.5, new Date(0, 0, 0, 0, 1, 5)); presenter.onEvent(EVENT); presenter.getTimelineView(); triggerMeasurement(measurement1); triggerMeasurement(measurement2); assertThat(presenter.getTimelineView()).contains(expected, measurement2); } @Test public void shouldNotifyListenersAboutNewAveragedMeasurements() { state.recording().startRecording(); when(presenter.settingsHelper.getAveragingTime()).thenReturn(4); Measurement expected = new Measurement(3.5, 3.5, 3.5, new Date(0, 0, 0, 0, 1, 5)); presenter.registerListener(listener); triggerMeasurement(measurement1); triggerMeasurement(measurement2); triggerMeasurement(new Measurement(0, 0, 0, new Date(0, 0, 0, 0, 1, 10))); verify(listener, atLeastOnce()).onAveragedMeasurement(expected); } }