// Copyright 2015 The Project Buendia Authors
//
// 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: http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distrib-
// uted 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
// specific language governing permissions and limitations under the License.
package org.projectbuendia.client.ui.login;
import android.test.AndroidTestCase;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.projectbuendia.client.diagnostics.Troubleshooter;
import org.projectbuendia.client.diagnostics.TroubleshootingAction;
import org.projectbuendia.client.events.diagnostics.TroubleshootingActionsChangedEvent;
import org.projectbuendia.client.events.user.KnownUsersLoadFailedEvent;
import org.projectbuendia.client.events.user.KnownUsersLoadedEvent;
import org.projectbuendia.client.events.user.UserAddFailedEvent;
import org.projectbuendia.client.events.user.UserAddedEvent;
import org.projectbuendia.client.json.JsonNewUser;
import org.projectbuendia.client.json.JsonUser;
import org.projectbuendia.client.ui.FakeEventBus;
import org.projectbuendia.client.user.UserManager;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
/** Tests for {@link LoginController}. */
public class LoginControllerTest extends AndroidTestCase {
private LoginController mController;
@Mock private UserManager mMockUserManager;
@Mock private LoginController.Ui mMockUi;
@Mock private LoginController.FragmentUi mMockFragmentUi;
@Mock private Troubleshooter mTroubleshooter;
private FakeEventBus mFakeEventBus;
/** Tests that init() attempts to load known users. */
public void testInit_SetsKnownUserLoadGoing() {
// WHEN the controller is inited
mController.init();
// THEN it requests that the user manager loads the list of users
mMockUserManager.loadKnownUsers();
}
/** Tests that suspend() unregisters subscribers from the event bus. */
public void testSuspend_UnregistersFromEventBus() {
// GIVEN an initialized controller
mController.init();
// WHEN the controller is suspended
mController.suspend();
// THEN the controller unregisters from the event bus
assertEquals(0, mFakeEventBus.countRegisteredReceivers());
}
/** Tests that the UI updates when users are loaded. */
public void testKnownUsersLoadedEvent_UpdatesUi() throws Exception {
// GIVEN the controller is inited
mController.init();
// WHEN a KnownUsersLoadedEvent is sent over the event bus
JsonUser user = new JsonUser("idA", "nameA");
mFakeEventBus.post(new KnownUsersLoadedEvent(ImmutableSet.of(user)));
// THEN the UI is updated
verify(mMockFragmentUi).showUsers(ImmutableList.of(user));
}
/** Tests that settings are shown when requested. */
public void testSettingsPress_ShowsSettings() {
// GIVEN an inited controller
mController.init();
// WHEN the settings button is pressed
mController.onSettingsPressed();
// THEN the settings screen is opened
verify(mMockUi).showSettings();
}
/** Tests that selecting a user causes a transition to the tent selection screen. */
public void testSelectingUser_SetsUserAndOpensTentSelection() throws Exception {
// GIVEN an controller inited controller with users loaded
mController.init();
JsonUser user = new JsonUser("idA", "nameA");
mFakeEventBus.post(new KnownUsersLoadedEvent(ImmutableSet.of(user)));
// WHEN one of the users is selected
mController.onUserSelected(user);
// THEN that user is set as the active user
verify(mMockUserManager).setActiveUser(user);
// THEN the tent selection screen is shown
verify(mMockUi).showTentSelectionScreen();
}
/** Tests that spinner is shown when the controller is first initialized. */
public void testInit_showsSpinner() {
// WHEN controller is inited
mController.init();
// THEN spinner is shown
verify(mMockFragmentUi).showSpinner(true);
}
/** Tests that successful user load hides the spinner. */
public void testUsersLoaded_hidesSpinner() {
// GIVEN initialized controller
mController.init();
// WHEN users are loaded
JsonUser user = new JsonUser("idA", "nameA");
mFakeEventBus.post(new KnownUsersLoadedEvent(ImmutableSet.of(user)));
// THEN the spinner is hidden
verify(mMockFragmentUi).showSpinner(false);
}
/** Tests that the sync failed dialog appears when loading users fails. */
public void testUserLoadFails_showsSyncFailedDialog() {
// GIVEN initialized controller
mController.init();
// WHEN users fail to load
mFakeEventBus.post(new KnownUsersLoadFailedEvent(KnownUsersLoadFailedEvent.REASON_UNKNOWN));
// THEN the sync fail dialog is shown
verify(mMockUi).showSyncFailedDialog(true);
}
/** Tests that the sync failed dialog is hidden when users are successfully loaded. */
public void testUserLoaded_hidesSyncFailedDialog() {
// GIVEN initialized controller
mController.init();
// WHEN users are loaded
JsonUser user = new JsonUser("idA", "nameA");
mFakeEventBus.post(new KnownUsersLoadedEvent(ImmutableSet.of(user)));
// THEN the sync fail dialog is hidden
verify(mMockUi).showSyncFailedDialog(false);
}
/** Tests that users are requested when a retry is requested. */
public void testOnSyncRetry_requestsUsers() {
// GIVEN initialized controller
mController.init();
// WHEN onSyncRetry is called
mController.onSyncRetry();
// THEN users are requested
// Note: already called once in init().
verify(mMockUserManager, times(2)).loadKnownUsers();
}
/** Tests that the spinner is shown when a retry is requested. */
public void testOnSyncRetry_showsSpinner() {
// GIVEN initialized controller
mController.init();
// WHEN onSyncRetry is called
mController.onSyncRetry();
// THEN spinner is shown
// Note: already shown once in init().
verify(mMockFragmentUi, times(2)).showSpinner(true);
}
/** Tests that the spinner is hidden whenever a user is added. */
public void testOnUserAdded_showsSpinner() {
// GIVEN initialized controller
mController.init();
// WHEN a user is added
JsonUser user = new JsonUser("idA", "nameA");
mFakeEventBus.post(new UserAddedEvent(user));
// THEN spinner is hidden
verify(mMockFragmentUi).showSpinner(false);
}
/** Tests that the spinner is hidden whenever a user add operation fails. */
public void testOnUserAddFailed_showsSpinner() {
// GIVEN initialized controller
mController.init();
// WHEN a user fails to be added
JsonUser user = new JsonUser("idA", "nameA");
mFakeEventBus.post(new UserAddFailedEvent(new JsonNewUser(), 0));
// THEN spinner is hidden
verify(mMockFragmentUi).showSpinner(false);
}
/** Tests that users are reloaded if the server becomes healthy and users are unavailable. */
public void testOnServerHealthy_reloadsUsersIfNotAvailable() {
// GIVEN initialized controller, no users loaded, server unhealthy
when(mTroubleshooter.isServerHealthy()).thenReturn(false);
mController.init();
// WHEN server becomes healthy
when(mTroubleshooter.isServerHealthy()).thenReturn(true);
mFakeEventBus.post(new TroubleshootingActionsChangedEvent(
ImmutableSet.of(TroubleshootingAction.CHECK_PACKAGE_SERVER_CONFIGURATION), null));
// THEN users are reloaded
// Note: already called once in init()
verify(mMockUserManager, times(2)).loadKnownUsers();
}
/** Tests that users are not reloaded if the server becomes healthy and users are available. */
public void testOnServerHealthy_doesNothingIfUsersAvailable() {
// GIVEN initialized controller, users loaded, server unhealthy
when(mTroubleshooter.isServerHealthy()).thenReturn(false);
mController.init();
JsonUser user = new JsonUser("idA", "nameA");
mFakeEventBus.post(new KnownUsersLoadedEvent(ImmutableSet.of(user)));
// WHEN server becomes healthy
when(mTroubleshooter.isServerHealthy()).thenReturn(true);
mFakeEventBus.post(new TroubleshootingActionsChangedEvent(
ImmutableSet.of(TroubleshootingAction.CHECK_PACKAGE_SERVER_CONFIGURATION), null));
// THEN users are not reloaded
verify(mMockUserManager, times(1)).loadKnownUsers();
}
/**
* Tests that TroubleshootingActionsChangedEvents do not trigger user reload if server is still
* unhealthy.
*/
public void testOnTroubleshootingActionsChanged_checksServerHealthy() {
// GIVEN initialized controller, no users loaded, server unhealthy
when(mTroubleshooter.isServerHealthy()).thenReturn(false);
mController.init();
// WHEN TroubleshootingActions change but server is still unhealthy
mFakeEventBus.post(new TroubleshootingActionsChangedEvent(
ImmutableSet.of(TroubleshootingAction.CHECK_PACKAGE_SERVER_CONFIGURATION), null));
// THEN users are not reloaded
// Note: this function is called once during init(), so expect it to be called once, but
// only once.
verify(mMockUserManager, times(1)).loadKnownUsers();
}
@Override protected void setUp() throws Exception {
super.setUp();
MockitoAnnotations.initMocks(this);
mFakeEventBus = new FakeEventBus();
mController = new LoginController(
mMockUserManager,
mFakeEventBus,
mTroubleshooter,
mMockUi,
mMockFragmentUi);
}
}