chromium/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/LargeMessageCardViewBinderUnitTest.java

// Copyright 2022 The Chromium Authors
// 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.tasks.tab_management;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;

import static org.chromium.chrome.browser.tasks.tab_management.TabListModel.CardProperties.CARD_ALPHA;

import android.graphics.drawable.Drawable;
import android.view.View.OnClickListener;

import androidx.test.filters.SmallTest;

import org.junit.After;
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.tab.state.ShoppingPersistedTabData;
import org.chromium.ui.modelutil.PropertyModel;
import org.chromium.ui.modelutil.PropertyModelChangeProcessor;

/** Tests for {@link LargeMessageCardViewBinder}. */
@RunWith(BaseRobolectricTestRunner.class)
public class LargeMessageCardViewBinderUnitTest {
    private static final String FAKE_DISPLAY_TEXT = "Fake Text";
    private static final int FAKE_ICON_WIDTH = 666;
    private static final int FAKE_ICON_HEIGHT = 999;

    @Mock LargeMessageCardView mMockLargeCardView;

    @Mock MessageCardView.DismissActionProvider mMockDismissActionProvider1;

    @Mock MessageCardView.DismissActionProvider mMockDismissActionProvider2;

    @Mock MessageCardView.ReviewActionProvider mMockReviewActionProvider1;

    @Mock MessageCardView.ReviewActionProvider mMockReviewActionProvider2;

    @Mock ShoppingPersistedTabData.PriceDrop mMockPriceDrop;

    @Mock MessageCardView.IconProvider mMockIconProvider;

    @Mock Drawable mMockDrawable;

    @Mock private OnClickListener mMockOnClickListenerMock;

    @Captor ArgumentCaptor<Callback<Drawable>> mCallbackDrawableArgumentCaptor;

    private PropertyModel mModel;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);

        mModel = new PropertyModel(MessageCardViewProperties.ALL_KEYS);
        PropertyModelChangeProcessor.create(
                mModel, mMockLargeCardView, LargeMessageCardViewBinder::bind);
    }

    @After
    public void tearDown() {
        verifyNoMoreInteractions(
                mMockLargeCardView,
                mMockDismissActionProvider1,
                mMockDismissActionProvider2,
                mMockReviewActionProvider1,
                mMockReviewActionProvider2,
                mMockPriceDrop,
                mMockIconProvider,
                mMockDrawable,
                mMockOnClickListenerMock);
    }

    @Test
    @SmallTest
    public void updateContntDescriptionText() {
        mModel.set(MessageCardViewProperties.DISMISS_BUTTON_CONTENT_DESCRIPTION, FAKE_DISPLAY_TEXT);
        verify(mMockLargeCardView, times(1)).setDismissButtonContentDescription(FAKE_DISPLAY_TEXT);
        verify(mMockLargeCardView, times(1)).setDismissButtonOnClickListener(any());

        mModel.set(MessageCardViewProperties.DISMISS_BUTTON_CONTENT_DESCRIPTION, null);
        verify(mMockLargeCardView, times(1)).setDismissButtonContentDescription(null);
        verify(mMockLargeCardView, times(2)).setDismissButtonOnClickListener(any());
    }

    @Test
    @SmallTest
    public void updateActionButtonText() {
        mModel.set(MessageCardViewProperties.ACTION_TEXT, FAKE_DISPLAY_TEXT);
        verify(mMockLargeCardView, times(1)).setActionText(FAKE_DISPLAY_TEXT);
        verify(mMockLargeCardView, times(1)).setActionButtonOnClickListener(any());

        mModel.set(MessageCardViewProperties.ACTION_TEXT, null);
        verify(mMockLargeCardView, times(1)).setActionText(null);
        verify(mMockLargeCardView, times(2)).setActionButtonOnClickListener(any());
    }

    @Test
    @SmallTest
    public void updateSecondaryActionButtonText() {
        mModel.set(MessageCardViewProperties.SECONDARY_ACTION_TEXT, FAKE_DISPLAY_TEXT);
        verify(mMockLargeCardView, times(1)).setSecondaryActionText(FAKE_DISPLAY_TEXT);
    }

    @Test
    @SmallTest
    public void updateSecondaryActionButtonOnClickListener() {
        mModel.set(
                MessageCardViewProperties.SECONDARY_ACTION_BUTTON_CLICK_HANDLER,
                mMockOnClickListenerMock);
        verify(mMockLargeCardView, times(1))
                .setSecondaryActionButtonOnClickListener(mMockOnClickListenerMock);
    }

    @Test
    @SmallTest
    public void updateTitleText() {
        mModel.set(MessageCardViewProperties.TITLE_TEXT, FAKE_DISPLAY_TEXT);
        verify(mMockLargeCardView, times(1)).setTitleText(FAKE_DISPLAY_TEXT);

        mModel.set(MessageCardViewProperties.TITLE_TEXT, null);
        verify(mMockLargeCardView, times(1)).setTitleText(null);
    }

    @Test
    @SmallTest
    public void updatePriceDropInfo() {
        mModel.set(MessageCardViewProperties.PRICE_DROP, mMockPriceDrop);
        verify(mMockLargeCardView, times(1)).setupPriceInfoBox(mMockPriceDrop);
    }

    @Test
    @SmallTest
    public void updateIconVisibility() {
        mModel.set(MessageCardViewProperties.IS_ICON_VISIBLE, true);
        verify(mMockLargeCardView, times(1)).setIconVisibility(true);

        mModel.set(MessageCardViewProperties.IS_ICON_VISIBLE, false);
        verify(mMockLargeCardView, times(1)).setIconVisibility(false);
    }

    @Test
    @SmallTest
    public void updateIconWidth() {
        mModel.set(MessageCardViewProperties.ICON_WIDTH_IN_PIXELS, FAKE_ICON_WIDTH);
        verify(mMockLargeCardView, times(1)).updateIconWidth(FAKE_ICON_WIDTH);
    }

    @Test
    @SmallTest
    public void updateIconHeight() {
        mModel.set(MessageCardViewProperties.ICON_HEIGHT_IN_PIXELS, FAKE_ICON_HEIGHT);
        verify(mMockLargeCardView, times(1)).updateIconHeight(FAKE_ICON_HEIGHT);
    }

    @Test
    @SmallTest
    public void updateCloseIconVisibility() {
        mModel.set(MessageCardViewProperties.IS_CLOSE_BUTTON_VISIBLE, false);
        verify(mMockLargeCardView, times(1)).setCloseButtonVisibility(false);

        mModel.set(MessageCardViewProperties.IS_CLOSE_BUTTON_VISIBLE, true);
        verify(mMockLargeCardView, times(1)).setCloseButtonVisibility(true);
    }

    @Test
    @SmallTest
    public void updateIconDrawable() {
        mModel =
                new PropertyModel.Builder(MessageCardViewProperties.ALL_KEYS)
                        .with(MessageCardViewProperties.ICON_PROVIDER, mMockIconProvider)
                        .build();

        LargeMessageCardViewBinder.updateIconDrawable(mModel, mMockLargeCardView);
        verify(mMockIconProvider).fetchIconDrawable(mCallbackDrawableArgumentCaptor.capture());
        Callback<Drawable> callback = mCallbackDrawableArgumentCaptor.getValue();
        callback.onResult(mMockDrawable);
        verify(mMockLargeCardView, times(1)).setIconDrawable(mMockDrawable);
    }

    @Test
    @SmallTest
    public void updateCardAlpha() {
        mModel.set(CARD_ALPHA, 0.5f);
        verify(mMockLargeCardView, times(1)).setAlpha(0.5f);
    }

    @Test
    @SmallTest
    public void handleDismissActionButton_NoServiceProvider() {
        mModel =
                new PropertyModel.Builder(MessageCardViewProperties.ALL_KEYS)
                        .with(
                                MessageCardViewProperties.UI_DISMISS_ACTION_PROVIDER,
                                mMockDismissActionProvider1)
                        .with(
                                MessageCardViewProperties.MESSAGE_TYPE,
                                MessageService.MessageType.FOR_TESTING)
                        .with(
                                MessageCardViewProperties.MESSAGE_SERVICE_DISMISS_ACTION_PROVIDER,
                                null)
                        .build();

        LargeMessageCardViewBinder.handleDismissActionButton(mModel);
        verify(mMockDismissActionProvider1, times(1))
                .dismiss(MessageService.MessageType.FOR_TESTING);
    }

    @Test
    @SmallTest
    public void handleDismissActionButton_NoUiProvider() {
        mModel =
                new PropertyModel.Builder(MessageCardViewProperties.ALL_KEYS)
                        .with(MessageCardViewProperties.UI_DISMISS_ACTION_PROVIDER, null)
                        .with(
                                MessageCardViewProperties.MESSAGE_TYPE,
                                MessageService.MessageType.FOR_TESTING)
                        .with(
                                MessageCardViewProperties.MESSAGE_SERVICE_DISMISS_ACTION_PROVIDER,
                                mMockDismissActionProvider1)
                        .build();

        LargeMessageCardViewBinder.handleDismissActionButton(mModel);
        verify(mMockDismissActionProvider1, times(1))
                .dismiss(MessageService.MessageType.FOR_TESTING);
    }

    @Test
    @SmallTest
    public void handleDismissActionButton() {
        mModel =
                new PropertyModel.Builder(MessageCardViewProperties.ALL_KEYS)
                        .with(
                                MessageCardViewProperties.UI_DISMISS_ACTION_PROVIDER,
                                mMockDismissActionProvider1)
                        .with(
                                MessageCardViewProperties.MESSAGE_TYPE,
                                MessageService.MessageType.FOR_TESTING)
                        .with(
                                MessageCardViewProperties.MESSAGE_SERVICE_DISMISS_ACTION_PROVIDER,
                                mMockDismissActionProvider2)
                        .build();

        LargeMessageCardViewBinder.handleDismissActionButton(mModel);
        verify(mMockDismissActionProvider1, times(1))
                .dismiss(MessageService.MessageType.FOR_TESTING);
        verify(mMockDismissActionProvider2, times(1))
                .dismiss(MessageService.MessageType.FOR_TESTING);
    }

    @Test
    @SmallTest
    public void handleReviewActionButton() {
        mModel =
                new PropertyModel.Builder(MessageCardViewProperties.ALL_KEYS)
                        .with(
                                MessageCardViewProperties.UI_DISMISS_ACTION_PROVIDER,
                                mMockDismissActionProvider1)
                        .with(
                                MessageCardViewProperties.UI_ACTION_PROVIDER,
                                mMockReviewActionProvider1)
                        .with(
                                MessageCardViewProperties.MESSAGE_SERVICE_ACTION_PROVIDER,
                                mMockReviewActionProvider2)
                        .with(
                                MessageCardViewProperties.MESSAGE_TYPE,
                                MessageService.MessageType.FOR_TESTING)
                        .with(MessageCardViewProperties.SHOULD_KEEP_AFTER_REVIEW, false)
                        .build();

        LargeMessageCardViewBinder.handleReviewActionButton(mModel);
        verify(mMockReviewActionProvider1, times(1)).review();
        verify(mMockReviewActionProvider2, times(1)).review();
        verify(mMockDismissActionProvider1, times(1))
                .dismiss(MessageService.MessageType.FOR_TESTING);
    }

    @Test
    @SmallTest
    public void handleReviewActionButton_NoUiProvider() {
        mModel =
                new PropertyModel.Builder(MessageCardViewProperties.ALL_KEYS)
                        .with(
                                MessageCardViewProperties.UI_DISMISS_ACTION_PROVIDER,
                                mMockDismissActionProvider1)
                        .with(MessageCardViewProperties.UI_ACTION_PROVIDER, null)
                        .with(
                                MessageCardViewProperties.MESSAGE_SERVICE_ACTION_PROVIDER,
                                mMockReviewActionProvider1)
                        .with(
                                MessageCardViewProperties.MESSAGE_TYPE,
                                MessageService.MessageType.FOR_TESTING)
                        .with(MessageCardViewProperties.SHOULD_KEEP_AFTER_REVIEW, false)
                        .build();

        LargeMessageCardViewBinder.handleReviewActionButton(mModel);
        verify(mMockReviewActionProvider1, times(1)).review();
        verify(mMockDismissActionProvider1, times(1))
                .dismiss(MessageService.MessageType.FOR_TESTING);
    }

    @Test
    @SmallTest
    public void handleReviewActionButton_NoServiceProvider() {
        mModel =
                new PropertyModel.Builder(MessageCardViewProperties.ALL_KEYS)
                        .with(
                                MessageCardViewProperties.UI_DISMISS_ACTION_PROVIDER,
                                mMockDismissActionProvider1)
                        .with(
                                MessageCardViewProperties.UI_ACTION_PROVIDER,
                                mMockReviewActionProvider1)
                        .with(MessageCardViewProperties.MESSAGE_SERVICE_ACTION_PROVIDER, null)
                        .with(
                                MessageCardViewProperties.MESSAGE_TYPE,
                                MessageService.MessageType.FOR_TESTING)
                        .with(MessageCardViewProperties.SHOULD_KEEP_AFTER_REVIEW, false)
                        .build();

        LargeMessageCardViewBinder.handleReviewActionButton(mModel);
        verify(mMockReviewActionProvider1, times(1)).review();
        verify(mMockDismissActionProvider1, times(1))
                .dismiss(MessageService.MessageType.FOR_TESTING);
    }

    @Test
    @SmallTest
    public void handleReviewActionButton_NoDismissProvider() {
        mModel =
                new PropertyModel.Builder(MessageCardViewProperties.ALL_KEYS)
                        .with(MessageCardViewProperties.UI_DISMISS_ACTION_PROVIDER, null)
                        .with(
                                MessageCardViewProperties.UI_ACTION_PROVIDER,
                                mMockReviewActionProvider1)
                        .with(
                                MessageCardViewProperties.MESSAGE_SERVICE_ACTION_PROVIDER,
                                mMockReviewActionProvider2)
                        .with(
                                MessageCardViewProperties.MESSAGE_TYPE,
                                MessageService.MessageType.FOR_TESTING)
                        .with(MessageCardViewProperties.SHOULD_KEEP_AFTER_REVIEW, false)
                        .build();

        LargeMessageCardViewBinder.handleReviewActionButton(mModel);
        verify(mMockReviewActionProvider1, times(1)).review();
        verify(mMockReviewActionProvider2, times(1)).review();
    }

    @Test
    @SmallTest
    public void handleReviewActionButton_DismissNotAllowed() {
        mModel =
                new PropertyModel.Builder(MessageCardViewProperties.ALL_KEYS)
                        .with(
                                MessageCardViewProperties.UI_DISMISS_ACTION_PROVIDER,
                                mMockDismissActionProvider1)
                        .with(
                                MessageCardViewProperties.UI_ACTION_PROVIDER,
                                mMockReviewActionProvider1)
                        .with(
                                MessageCardViewProperties.MESSAGE_SERVICE_ACTION_PROVIDER,
                                mMockReviewActionProvider2)
                        .with(
                                MessageCardViewProperties.MESSAGE_TYPE,
                                MessageService.MessageType.FOR_TESTING)
                        .with(MessageCardViewProperties.SHOULD_KEEP_AFTER_REVIEW, true)
                        .build();

        LargeMessageCardViewBinder.handleReviewActionButton(mModel);
        verify(mMockReviewActionProvider1, times(1)).review();
        verify(mMockReviewActionProvider2, times(1)).review();
        verify(mMockDismissActionProvider1, never())
                .dismiss(MessageService.MessageType.FOR_TESTING);
    }
}