blob: 7b7c382ea211af5a09615d61a173115d13ace267 [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.touch_to_fill;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.chromium.chrome.browser.touch_to_fill.CredentialProperties.DEFAULT_ITEM_TYPE;
import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.CREDENTIAL_LIST;
import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.FORMATTED_URL;
import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.ORIGIN_SECURE;
import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.VIEW_EVENT_LISTENER;
import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.VISIBLE;
import android.graphics.Bitmap;
import androidx.annotation.Px;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.chromium.base.Callback;
import org.chromium.base.test.BaseRobolectricTestRunner;
import org.chromium.chrome.browser.touch_to_fill.data.Credential;
import org.chromium.ui.modelutil.MVCListAdapter;
import org.chromium.ui.modelutil.PropertyModel;
import java.util.Arrays;
import java.util.Collections;
/**
* Controller tests verify that the Touch To Fill controller modifies the model if the API is used
* properly.
*/
@RunWith(BaseRobolectricTestRunner.class)
public class TouchToFillControllerTest {
private static final String TEST_URL = "www.example.xyz";
private static final String TEST_SUBDOMAIN_URL = "subdomain.example.xyz";
private static final Credential ANA = new Credential("Ana", "S3cr3t", "Ana", TEST_URL, false);
private static final Credential BOB =
new Credential("Bob", "*****", "Bob", TEST_SUBDOMAIN_URL, true);
private static final Credential CARL =
new Credential("Carl", "G3h3!m", "Carl", TEST_URL, false);
private static final @Px int DESIRED_FAVICON_SIZE = 64;
@Mock
private TouchToFillComponent.Delegate mMockDelegate;
// Can't be local, as it has to be initialized by initMocks.
@Captor
private ArgumentCaptor<Callback<Bitmap>> mCallbackArgumentCaptor;
private final TouchToFillMediator mMediator = new TouchToFillMediator();
private final PropertyModel mModel = TouchToFillProperties.createDefaultModel(mMediator);
public TouchToFillControllerTest() {
MockitoAnnotations.initMocks(this);
}
@Before
public void setUp() {
mMediator.initialize(mMockDelegate, mModel, DESIRED_FAVICON_SIZE);
}
@Test
public void testCreatesValidDefaultModel() {
assertNotNull(mModel.get(CREDENTIAL_LIST));
assertNotNull(mModel.get(VIEW_EVENT_LISTENER));
assertThat(mModel.get(VISIBLE), is(false));
assertThat(mModel.get(FORMATTED_URL), is(nullValue()));
assertThat(mModel.get(ORIGIN_SECURE), is(false));
}
@Test
public void testShowCredentialsSetsFormattedUrl() {
mMediator.showCredentials(TEST_URL, true, Arrays.asList(ANA, CARL, BOB));
assertThat(mModel.get(FORMATTED_URL), is(TEST_URL));
assertThat(mModel.get(ORIGIN_SECURE), is(true));
}
@Test
public void testShowCredentialsSetsCredentialListAndRequestsFavicons() {
mMediator.showCredentials(TEST_URL, true, Arrays.asList(ANA, CARL, BOB));
MVCListAdapter.ModelList credentialList = mModel.get(CREDENTIAL_LIST);
assertThat(credentialList.size(), is(3));
// TODO(https://crbug.com/1013209): Simplify this after adding equals to ModelList.
assertThat(credentialList.get(0).type, is(DEFAULT_ITEM_TYPE));
assertThat(credentialList.get(0).model.get(CredentialProperties.CREDENTIAL), is(ANA));
assertThat(credentialList.get(0).model.get(CredentialProperties.FAVICON), is(nullValue()));
assertThat(credentialList.get(1).type, is(DEFAULT_ITEM_TYPE));
assertThat(credentialList.get(1).model.get(CredentialProperties.CREDENTIAL), is(CARL));
assertThat(credentialList.get(1).model.get(CredentialProperties.FAVICON), is(nullValue()));
assertThat(credentialList.get(2).type, is(DEFAULT_ITEM_TYPE));
assertThat(credentialList.get(2).model.get(CredentialProperties.CREDENTIAL), is(BOB));
assertThat(credentialList.get(2).model.get(CredentialProperties.FAVICON), is(nullValue()));
// ANA and CARL both have TEST_URL as their origin URL
verify(mMockDelegate, times(2)).fetchFavicon(eq(TEST_URL), eq(DESIRED_FAVICON_SIZE), any());
verify(mMockDelegate).fetchFavicon(eq(BOB.getOriginUrl()), eq(DESIRED_FAVICON_SIZE), any());
}
@Test
public void testFetchFaviconUpdatesModel() {
mMediator.showCredentials(TEST_URL, true, Collections.singletonList(CARL));
MVCListAdapter.ModelList credentialList = mModel.get(CREDENTIAL_LIST);
assertThat(credentialList.size(), is(1));
// TODO(https://crbug.com/1013209): Simplify this after adding equals to ModelList.
assertThat(credentialList.get(0).type, is(DEFAULT_ITEM_TYPE));
assertThat(credentialList.get(0).model.get(CredentialProperties.CREDENTIAL), is(CARL));
assertThat(credentialList.get(0).model.get(CredentialProperties.FAVICON), is(nullValue()));
// ANA and CARL both have TEST_URL as their origin URL
verify(mMockDelegate)
.fetchFavicon(
eq(TEST_URL), eq(DESIRED_FAVICON_SIZE), mCallbackArgumentCaptor.capture());
Callback<Bitmap> callback = mCallbackArgumentCaptor.getValue();
Bitmap bitmap = Bitmap.createBitmap(
DESIRED_FAVICON_SIZE, DESIRED_FAVICON_SIZE, Bitmap.Config.ARGB_8888);
callback.onResult(bitmap);
assertThat(credentialList.get(0).model.get(CredentialProperties.FAVICON), is(bitmap));
}
@Test
public void testClearsCredentialListWhenShowingAgain() {
mMediator.showCredentials(TEST_URL, true, Collections.singletonList(ANA));
MVCListAdapter.ModelList credentialList = mModel.get(CREDENTIAL_LIST);
// TODO(https://crbug.com/1013209): Simplify this after adding equals to ModelList.
assertThat(credentialList.size(), is(1));
assertThat(credentialList.get(0).type, is(DEFAULT_ITEM_TYPE));
assertThat(credentialList.get(0).model.get(CredentialProperties.CREDENTIAL), is(ANA));
assertThat(credentialList.get(0).model.get(CredentialProperties.FAVICON), is(nullValue()));
// Showing the sheet a second time should replace all changed credentials.
mMediator.showCredentials(TEST_URL, true, Collections.singletonList(BOB));
credentialList = mModel.get(CREDENTIAL_LIST);
// TODO(https://crbug.com/1013209): Simplify this after adding equals to ModelList.
assertThat(credentialList.size(), is(1));
assertThat(credentialList.get(0).type, is(DEFAULT_ITEM_TYPE));
assertThat(credentialList.get(0).model.get(CredentialProperties.CREDENTIAL), is(BOB));
assertThat(credentialList.get(0).model.get(CredentialProperties.FAVICON), is(nullValue()));
}
@Test
public void testShowCredentialsSetsVisibile() {
mMediator.showCredentials(TEST_URL, true, Arrays.asList(ANA, CARL, BOB));
assertThat(mModel.get(VISIBLE), is(true));
}
@Test
public void testCallsCallbackAndHidesOnSelectingItem() {
mMediator.showCredentials(TEST_URL, true, Arrays.asList(ANA, CARL));
mMediator.onSelectItemAt(1);
verify(mMockDelegate).onCredentialSelected(CARL);
assertThat(mModel.get(VISIBLE), is(false));
}
@Test
public void testCallsDelegateAndHidesOnDismiss() {
mMediator.showCredentials(TEST_URL, true, Arrays.asList(ANA, CARL));
mMediator.onDismissed();
verify(mMockDelegate).onDismissed();
assertThat(mModel.get(VISIBLE), is(false));
}
}