SetupActivityTest.java 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. package briarproject.activity;
  2. import android.content.Context;
  3. import android.content.Intent;
  4. import android.content.SharedPreferences;
  5. import android.support.design.widget.TextInputLayout;
  6. import android.widget.Button;
  7. import android.widget.EditText;
  8. import com.google.common.base.Strings;
  9. import org.briarproject.BuildConfig;
  10. import org.briarproject.R;
  11. import org.briarproject.android.NavDrawerActivity;
  12. import org.briarproject.android.controller.SetupController;
  13. import org.briarproject.android.controller.handler.ResultHandler;
  14. import org.briarproject.android.util.StrengthMeter;
  15. import org.briarproject.api.identity.AuthorConstants;
  16. import org.junit.Assert;
  17. import org.junit.Before;
  18. import org.junit.Test;
  19. import org.junit.runner.RunWith;
  20. import org.mockito.ArgumentCaptor;
  21. import org.mockito.Captor;
  22. import org.mockito.Mock;
  23. import org.mockito.Mockito;
  24. import org.mockito.MockitoAnnotations;
  25. import org.robolectric.Robolectric;
  26. import org.robolectric.RobolectricGradleTestRunner;
  27. import org.robolectric.annotation.Config;
  28. import org.robolectric.shadows.ShadowActivity;
  29. import static junit.framework.Assert.assertEquals;
  30. import static org.briarproject.api.crypto.PasswordStrengthEstimator.NONE;
  31. import static org.briarproject.api.crypto.PasswordStrengthEstimator.QUITE_STRONG;
  32. import static org.briarproject.api.crypto.PasswordStrengthEstimator.QUITE_WEAK;
  33. import static org.briarproject.api.crypto.PasswordStrengthEstimator.STRONG;
  34. import static org.briarproject.api.crypto.PasswordStrengthEstimator.WEAK;
  35. import static org.junit.Assert.assertTrue;
  36. import static org.mockito.Matchers.anyString;
  37. import static org.mockito.Matchers.eq;
  38. import static org.mockito.Mockito.mock;
  39. import static org.mockito.Mockito.timeout;
  40. import static org.mockito.Mockito.times;
  41. import static org.mockito.Mockito.verify;
  42. import static org.mockito.Mockito.when;
  43. import static org.robolectric.Shadows.shadowOf;
  44. @RunWith(RobolectricGradleTestRunner.class)
  45. @Config(constants = BuildConfig.class, sdk = 21,
  46. application = TestBriarApplication.class)
  47. public class SetupActivityTest {
  48. private TestSetupActivity setupActivity;
  49. private TextInputLayout nicknameEntryWrapper;
  50. private TextInputLayout passwordEntryWrapper;
  51. private TextInputLayout passwordConfirmationWrapper;
  52. private EditText nicknameEntry;
  53. private EditText passwordEntry;
  54. private EditText passwordConfirmation;
  55. private StrengthMeter strengthMeter;
  56. private Button createAccountButton;
  57. @Mock
  58. private SetupController setupController;
  59. @Captor
  60. private ArgumentCaptor<ResultHandler<Long>> resultCaptor;
  61. @Before
  62. public void setUp() {
  63. MockitoAnnotations.initMocks(this);
  64. setupActivity = Robolectric.setupActivity(TestSetupActivity.class);
  65. nicknameEntryWrapper = (TextInputLayout) setupActivity
  66. .findViewById(R.id.nickname_entry_wrapper);
  67. passwordEntryWrapper = (TextInputLayout) setupActivity
  68. .findViewById(R.id.password_entry_wrapper);
  69. passwordConfirmationWrapper = (TextInputLayout) setupActivity
  70. .findViewById(R.id.password_confirm_wrapper);
  71. nicknameEntry =
  72. (EditText) setupActivity.findViewById(R.id.nickname_entry);
  73. passwordEntry =
  74. (EditText) setupActivity.findViewById(R.id.password_entry);
  75. passwordConfirmation =
  76. (EditText) setupActivity.findViewById(R.id.password_confirm);
  77. strengthMeter =
  78. (StrengthMeter) setupActivity.findViewById(R.id.strength_meter);
  79. createAccountButton =
  80. (Button) setupActivity.findViewById(R.id.create_account);
  81. }
  82. private void testStrengthMeter(String pass, float strength, int color) {
  83. passwordEntry.setText(pass);
  84. assertEquals(strengthMeter.getProgress(),
  85. (int) (strengthMeter.getMax() * strength));
  86. assertEquals(color, strengthMeter.getColor());
  87. }
  88. @Test
  89. public void testPasswordMatchUI() {
  90. // Password mismatch
  91. passwordEntry.setText("really.safe.password");
  92. passwordConfirmation.setText("really.safe.pass");
  93. assertEquals(createAccountButton.isEnabled(), false);
  94. assertEquals(passwordConfirmationWrapper.getError(),
  95. setupActivity.getString(R.string.passwords_do_not_match));
  96. // Button enabled
  97. passwordEntry.setText("really.safe.pass");
  98. passwordConfirmation.setText("really.safe.pass");
  99. // Confirm that the password mismatch error message is not visible
  100. Assert.assertNotEquals(passwordConfirmationWrapper.getError(),
  101. setupActivity.getString(R.string.passwords_do_not_match));
  102. // Nick has not been set, expect the button to be disabled
  103. assertEquals(createAccountButton.isEnabled(), false);
  104. }
  105. @Test
  106. public void testCreateAccountUI() {
  107. SetupController mockedController = this.setupController;
  108. setupActivity.setController(mockedController);
  109. // Mock strong password strength answer
  110. when(mockedController.estimatePasswordStrength(anyString())).thenReturn(
  111. STRONG);
  112. String safePass = "really.safe.password";
  113. String nick = "nick.nickerton";
  114. passwordEntry.setText(safePass);
  115. passwordConfirmation.setText(safePass);
  116. nicknameEntry.setText(nick);
  117. // Confirm that the create account button is clickable
  118. assertEquals(createAccountButton.isEnabled(), true);
  119. createAccountButton.performClick();
  120. // Verify that the controller's method was called with the correct
  121. // params and get the callback
  122. verify(mockedController, times(1))
  123. .createIdentity(eq(nick), eq(safePass), resultCaptor.capture());
  124. // execute the callback
  125. resultCaptor.getValue().onResult(1L);
  126. assertEquals(setupActivity.isFinishing(), true);
  127. // Confirm that the correct Activity has been started
  128. ShadowActivity shadowActivity = shadowOf(setupActivity);
  129. Intent intent = shadowActivity.peekNextStartedActivity();
  130. assertEquals(intent.getComponent().getClassName(),
  131. NavDrawerActivity.class.getName());
  132. }
  133. @Test
  134. public void testNicknameUI() {
  135. Assert.assertNotNull(setupActivity);
  136. String longNick =
  137. Strings.padEnd("*", AuthorConstants.MAX_AUTHOR_NAME_LENGTH + 1,
  138. '*');
  139. nicknameEntry.setText(longNick);
  140. // Nickname should be too long
  141. assertEquals(nicknameEntryWrapper.getError(),
  142. setupActivity.getString(R.string.name_too_long));
  143. }
  144. @Test
  145. public void testAccountCreation() {
  146. SetupController controller = setupActivity.getController();
  147. // mock a resulthandler
  148. ResultHandler<Long> resultHandler =
  149. (ResultHandler<Long>) mock(ResultHandler.class);
  150. controller
  151. .createIdentity("nick", "some.strong.pass", resultHandler);
  152. // blocking verification call with timeout that waits until the mocked
  153. // result gets called with handle 0L, the expected value
  154. verify(resultHandler, timeout(2000).times(1)).onResult(0L);
  155. SharedPreferences prefs =
  156. setupActivity.getSharedPreferences("db", Context.MODE_PRIVATE);
  157. // Confirm database key
  158. assertTrue(prefs.contains("key"));
  159. // Note that Robolectric uses its own persistant storage that it
  160. // wipes clean after each test run, no need to clean up manually.
  161. }
  162. @Test
  163. public void testStrengthMeter() {
  164. SetupController controller = setupActivity.getController();
  165. String strongPass = "very.strong.password.123";
  166. String weakPass = "we";
  167. String quiteStrongPass = "quite.strong";
  168. float val = controller.estimatePasswordStrength(strongPass);
  169. assertTrue(val == STRONG);
  170. val = controller.estimatePasswordStrength(weakPass);
  171. assertTrue(val < WEAK && val > NONE);
  172. val = controller.estimatePasswordStrength(quiteStrongPass);
  173. assertTrue(val < STRONG && val > QUITE_WEAK);
  174. }
  175. @Test
  176. public void testStrengthMeterUI() {
  177. Assert.assertNotNull(setupActivity);
  178. // replace the setup controller with our mocked copy
  179. SetupController mockedController = this.setupController;
  180. setupActivity.setController(mockedController);
  181. // Mock answers for UI testing only
  182. when(mockedController.estimatePasswordStrength("strong")).thenReturn(
  183. STRONG);
  184. when(mockedController.estimatePasswordStrength("qstring")).thenReturn(
  185. QUITE_STRONG);
  186. when(mockedController.estimatePasswordStrength("qweak")).thenReturn(
  187. QUITE_WEAK);
  188. when(mockedController.estimatePasswordStrength("weak")).thenReturn(
  189. WEAK);
  190. when(mockedController.estimatePasswordStrength("empty")).thenReturn(
  191. NONE);
  192. // Test the meters progress and color for several values
  193. testStrengthMeter("strong", STRONG, StrengthMeter.GREEN);
  194. Mockito.verify(mockedController, Mockito.times(1))
  195. .estimatePasswordStrength(eq("strong"));
  196. testStrengthMeter("qstring", QUITE_STRONG, StrengthMeter.LIME);
  197. Mockito.verify(mockedController, Mockito.times(1))
  198. .estimatePasswordStrength(eq("qstring"));
  199. testStrengthMeter("qweak", QUITE_WEAK, StrengthMeter.YELLOW);
  200. Mockito.verify(mockedController, Mockito.times(1))
  201. .estimatePasswordStrength(eq("qweak"));
  202. testStrengthMeter("weak", WEAK, StrengthMeter.ORANGE);
  203. Mockito.verify(mockedController, Mockito.times(1))
  204. .estimatePasswordStrength(eq("weak"));
  205. // Not sure this should be the correct behaviour on an empty input ?
  206. testStrengthMeter("empty", NONE, StrengthMeter.RED);
  207. Mockito.verify(mockedController, Mockito.times(1))
  208. .estimatePasswordStrength(eq("empty"));
  209. }
  210. }