1 // Copyright 2019 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 package org.chromium.chrome.browser.contextmenu;
6 
7 import static org.hamcrest.CoreMatchers.equalTo;
8 import static org.hamcrest.MatcherAssert.assertThat;
9 import static org.junit.Assert.assertFalse;
10 import static org.junit.Assert.assertTrue;
11 
12 import android.graphics.Bitmap;
13 import android.graphics.drawable.BitmapDrawable;
14 import android.view.View;
15 import android.widget.ImageView;
16 import android.widget.TextView;
17 
18 import androidx.test.filters.SmallTest;
19 
20 import org.junit.BeforeClass;
21 import org.junit.Test;
22 import org.junit.runner.RunWith;
23 
24 import org.chromium.base.test.UiThreadTest;
25 import org.chromium.chrome.R;
26 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
27 import org.chromium.content_public.browser.test.util.TestThreadUtils;
28 import org.chromium.ui.modelutil.PropertyModel;
29 import org.chromium.ui.modelutil.PropertyModelChangeProcessor;
30 import org.chromium.ui.test.util.DummyUiActivity;
31 import org.chromium.ui.test.util.DummyUiActivityTestCase;
32 
33 /**
34  * Tests for RevampedContextMenu item view, {@link RevampedContextMenuItemViewBinder}, and {@link
35  * RevampedContextMenuItemWithIconButtonViewBinder}.
36  */
37 @RunWith(ChromeJUnit4ClassRunner.class)
38 public class RevampedContextMenuItemViewTest extends DummyUiActivityTestCase {
39     private static final String TEXT = "Useful menu item";
40     private static final String APP = "Some app";
41 
42     private View mShareItemView;
43     private TextView mText;
44     private ImageView mIcon;
45     private PropertyModel mModel;
46     private PropertyModelChangeProcessor mMCP;
47 
48     private boolean mIsClicked;
49 
50     @BeforeClass
setUpBeforeActivityLaunched()51     public static void setUpBeforeActivityLaunched() {
52         DummyUiActivity.setTestLayout(org.chromium.chrome.R.layout.revamped_context_menu_share_row);
53     }
54 
55     @Override
setUpTest()56     public void setUpTest() throws Exception {
57         super.setUpTest();
58 
59         TestThreadUtils.runOnUiThreadBlocking(() -> {
60             mShareItemView = getActivity().findViewById(android.R.id.content);
61             mText = mShareItemView.findViewById(R.id.menu_row_text);
62             mIcon = mShareItemView.findViewById(R.id.menu_row_share_icon);
63             mModel = new PropertyModel
64                              .Builder(RevampedContextMenuItemWithIconButtonProperties.ALL_KEYS)
65                              .with(RevampedContextMenuItemWithIconButtonProperties.TEXT, "")
66                              .with(RevampedContextMenuItemWithIconButtonProperties.BUTTON_IMAGE,
67                                      null)
68                              .with(RevampedContextMenuItemWithIconButtonProperties
69                                              .BUTTON_CONTENT_DESC,
70                                      "")
71                              .with(RevampedContextMenuItemWithIconButtonProperties
72                                              .BUTTON_CLICK_LISTENER,
73                                      null)
74                              .build();
75             mMCP = PropertyModelChangeProcessor.create(
76                     mModel, mShareItemView, RevampedContextMenuItemWithIconButtonViewBinder::bind);
77         });
78     }
79 
80     @Override
tearDownTest()81     public void tearDownTest() throws Exception {
82         TestThreadUtils.runOnUiThreadBlocking(mMCP::destroy);
83         super.tearDownTest();
84     }
85 
86     @Test
87     @SmallTest
88     @UiThreadTest
testText()89     public void testText() {
90         TestThreadUtils.runOnUiThreadBlocking(
91                 () -> mModel.set(RevampedContextMenuItemWithIconButtonProperties.TEXT, TEXT));
92         assertThat("Incorrect item text.", mText.getText(), equalTo(TEXT));
93     }
94 
95     @Test
96     @SmallTest
97     @UiThreadTest
testShareIcon()98     public void testShareIcon() {
99         assertThat("Incorrect initial icon visibility.", mIcon.getVisibility(), equalTo(View.GONE));
100         final Bitmap bitmap = Bitmap.createBitmap(4, 4, Bitmap.Config.ARGB_8888);
101         final BitmapDrawable drawable = new BitmapDrawable(mIcon.getResources(), bitmap);
102         TestThreadUtils.runOnUiThreadBlocking(() -> {
103             mModel.set(RevampedContextMenuItemWithIconButtonProperties.BUTTON_IMAGE, drawable);
104             mModel.set(RevampedContextMenuItemWithIconButtonProperties.BUTTON_CONTENT_DESC, APP);
105         });
106         assertThat("Incorrect icon drawable.", mIcon.getDrawable(), equalTo(drawable));
107         assertThat("Incorrect icon visibility.", mIcon.getVisibility(), equalTo(View.VISIBLE));
108         assertThat("Incorrect icon content description.", mIcon.getContentDescription(),
109                 equalTo(mShareItemView.getContext().getString(
110                         R.string.accessibility_menu_share_via, APP)));
111     }
112 
113     @Test
114     @SmallTest
115     @UiThreadTest
testShareIconClick()116     public void testShareIconClick() {
117         assertFalse("Icon has onClickListeners when it shouldn't, yet, have.",
118                 mIcon.hasOnClickListeners());
119         TestThreadUtils.runOnUiThreadBlocking(() -> {
120             mModel.set(RevampedContextMenuItemWithIconButtonProperties.BUTTON_CLICK_LISTENER,
121                     this::click);
122             mIcon.callOnClick();
123         });
124         assertTrue("Icon hasn't been clicked.", mIsClicked);
125     }
126 
click(View v)127     private void click(View v) {
128         mIsClicked = true;
129     }
130 }
131