• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 Google Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.car.carlauncher.homescreen;
18 
19 import static androidx.test.espresso.Espresso.onView;
20 import static androidx.test.espresso.assertion.ViewAssertions.matches;
21 import static androidx.test.espresso.matcher.ViewMatchers.isDescendantOfA;
22 import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
23 import static androidx.test.espresso.matcher.ViewMatchers.withId;
24 import static androidx.test.espresso.matcher.ViewMatchers.withText;
25 
26 import static org.hamcrest.CoreMatchers.allOf;
27 import static org.hamcrest.CoreMatchers.not;
28 import static org.junit.Assert.assertNotNull;
29 import static org.mockito.Mockito.mock;
30 import static org.mockito.Mockito.verify;
31 import static org.mockito.Mockito.when;
32 
33 import android.graphics.drawable.Drawable;
34 import android.widget.ImageButton;
35 
36 import androidx.test.ext.junit.runners.AndroidJUnit4;
37 import androidx.test.filters.Suppress;
38 import androidx.test.platform.app.InstrumentationRegistry;
39 import androidx.test.rule.ActivityTestRule;
40 
41 import com.android.car.carlauncher.CarLauncher;
42 import com.android.car.carlauncher.R;
43 import com.android.car.carlauncher.homescreen.ui.CardHeader;
44 import com.android.car.carlauncher.homescreen.ui.DescriptiveTextView;
45 import com.android.car.carlauncher.homescreen.ui.DescriptiveTextWithControlsView;
46 import com.android.car.carlauncher.homescreen.ui.TextBlockView;
47 
48 import org.junit.Rule;
49 import org.junit.Test;
50 import org.junit.runner.RunWith;
51 
52 @Suppress // To be ignored until b/224978827 is fixed
53 @RunWith(AndroidJUnit4.class)
54 public class HomeCardFragmentTest {
55 
56     private static final String DESCRIPTIVE_TEXT_TITLE = "Test title text";
57     private static final String DESCRIPTIVE_TEXT_SUBTITLE = "Test subtitle text";
58     private static final String DESCRIPTIVE_TEXT_FOOTER = "Descriptive footer";
59     private static final String TEXT_BLOCK_CONTENT = "Test text for text block";
60     private static final String TEXT_BLOCK_FOOTER = "Text block footer";
61     private static final CardHeader CARD_HEADER = new CardHeader("Test App Name", /* appIcon= */
62             null);
63     private static final DescriptiveTextView DESCRIPTIVE_TEXT_VIEW =
64             new DescriptiveTextView(/* image = */ null, DESCRIPTIVE_TEXT_TITLE,
65                     DESCRIPTIVE_TEXT_SUBTITLE, DESCRIPTIVE_TEXT_FOOTER);
66     private static final DescriptiveTextView DESCRIPTIVE_TEXT_VIEW_NO_FOOTER =
67             new DescriptiveTextView(/* image = */ null, DESCRIPTIVE_TEXT_TITLE,
68                     DESCRIPTIVE_TEXT_SUBTITLE);
69     private static final TextBlockView TEXT_BLOCK_VIEW = new TextBlockView(TEXT_BLOCK_CONTENT,
70             TEXT_BLOCK_FOOTER);
71     private static final TextBlockView TEXT_BLOCK_VIEW_NO_FOOTER = new TextBlockView(
72             TEXT_BLOCK_CONTENT);
73 
74     @Rule
75     public ActivityTestRule<CarLauncher> mActivityTestRule = new ActivityTestRule<CarLauncher>(
76             CarLauncher.class);
77 
78     @Test
updateContentView_descriptiveTextWithFooter_displaysTapForMoreView()79     public void updateContentView_descriptiveTextWithFooter_displaysTapForMoreView() {
80         HomeCardFragment fragment = (HomeCardFragment) mActivityTestRule.getActivity()
81                 .getSupportFragmentManager().findFragmentById(R.id.top_card);
82         fragment.updateHeaderView(CARD_HEADER);
83         fragment.updateContentView(DESCRIPTIVE_TEXT_VIEW);
84 
85         onView(allOf(withId(R.id.descriptive_text_layout),
86                 isDescendantOfA(withId(R.id.top_card)))).check(
87                 matches(isDisplayed()));
88         onView(allOf(withId(R.id.primary_text), withText(DESCRIPTIVE_TEXT_TITLE),
89                 isDescendantOfA(withId(R.id.descriptive_text_layout)),
90                 isDescendantOfA(withId(R.id.top_card)))).check(matches(isDisplayed()));
91         onView(allOf(withId(R.id.secondary_text), withText(DESCRIPTIVE_TEXT_SUBTITLE),
92                 isDescendantOfA(withId(R.id.descriptive_text_layout)),
93                 isDescendantOfA(withId(R.id.top_card)))).check(matches(isDisplayed()));
94         onView(allOf(withId(R.id.tap_for_more_text), withText(DESCRIPTIVE_TEXT_FOOTER),
95                 isDescendantOfA(withId(R.id.descriptive_text_layout)),
96                 isDescendantOfA(withId(R.id.top_card)))).check(matches(isDisplayed()));
97     }
98 
99     @Test
updateContentView_descriptiveTextWithNoFooter_hidesTapForMoreView()100     public void updateContentView_descriptiveTextWithNoFooter_hidesTapForMoreView() {
101         HomeCardFragment fragment = (HomeCardFragment) mActivityTestRule.getActivity()
102                 .getSupportFragmentManager().findFragmentById(R.id.top_card);
103         fragment.updateHeaderView(CARD_HEADER);
104         fragment.updateContentView(DESCRIPTIVE_TEXT_VIEW_NO_FOOTER);
105 
106         onView(allOf(withId(R.id.descriptive_text_layout),
107                 isDescendantOfA(withId(R.id.top_card)))).check(
108                 matches(isDisplayed()));
109         onView(allOf(withId(R.id.primary_text), withText(DESCRIPTIVE_TEXT_TITLE),
110                 isDescendantOfA(withId(R.id.descriptive_text_layout)),
111                 isDescendantOfA(withId(R.id.top_card)))).check(matches(isDisplayed()));
112         onView(allOf(withId(R.id.secondary_text), withText(DESCRIPTIVE_TEXT_SUBTITLE),
113                 isDescendantOfA(withId(R.id.descriptive_text_layout)),
114                 isDescendantOfA(withId(R.id.top_card)))).check(matches(isDisplayed()));
115         onView(allOf(withId(R.id.tap_for_more_text),
116                 isDescendantOfA(withId(R.id.descriptive_text_layout)),
117                 isDescendantOfA(withId(R.id.top_card)))).check(matches(not(isDisplayed())));
118     }
119 
120     @Test
updateContentView_textBlockWithFooter_displaysTapForMoreView()121     public void updateContentView_textBlockWithFooter_displaysTapForMoreView() {
122         HomeCardFragment fragment = (HomeCardFragment) mActivityTestRule.getActivity()
123                 .getSupportFragmentManager().findFragmentById(R.id.top_card);
124         fragment.updateHeaderView(CARD_HEADER);
125         fragment.updateContentView(TEXT_BLOCK_VIEW);
126 
127         onView(allOf(withId(R.id.text_block_layout), isDescendantOfA(withId(R.id.top_card)))).check(
128                 matches(isDisplayed()));
129         onView(allOf(withId(R.id.text_block), withText(TEXT_BLOCK_CONTENT),
130                 isDescendantOfA(withId(R.id.text_block_layout)),
131                 isDescendantOfA(withId(R.id.top_card)))).check(matches(isDisplayed()));
132         onView(allOf(withId(R.id.tap_for_more_text), withText(TEXT_BLOCK_FOOTER),
133                 isDescendantOfA(withId(R.id.text_block_layout)),
134                 isDescendantOfA(withId(R.id.top_card)))).check(matches(isDisplayed()));
135     }
136 
137     @Test
updateContentView_textBlockNoFooter_hidesTapForMoreView()138     public void updateContentView_textBlockNoFooter_hidesTapForMoreView() {
139         HomeCardFragment fragment = (HomeCardFragment) mActivityTestRule.getActivity()
140                 .getSupportFragmentManager().findFragmentById(R.id.top_card);
141         fragment.updateHeaderView(CARD_HEADER);
142         fragment.updateContentView(TEXT_BLOCK_VIEW_NO_FOOTER);
143 
144         onView(allOf(withId(R.id.text_block_layout), isDescendantOfA(withId(R.id.top_card)))).check(
145                 matches(isDisplayed()));
146         onView(allOf(withId(R.id.text_block), withText(TEXT_BLOCK_CONTENT),
147                 isDescendantOfA(withId(R.id.text_block_layout)),
148                 isDescendantOfA(withId(R.id.top_card)))).check(matches(isDisplayed()));
149         onView(allOf(withId(R.id.tap_for_more_text),
150                 isDescendantOfA(withId(R.id.text_block_layout)),
151                 isDescendantOfA(withId(R.id.top_card)))).check(matches(not(isDisplayed())));
152     }
153 
154     @Test
updateControlBarButton_updatesButtonSelectedState()155     public void updateControlBarButton_updatesButtonSelectedState() {
156         HomeCardFragment fragment = (HomeCardFragment) mActivityTestRule.getActivity()
157                 .getSupportFragmentManager().findFragmentById(R.id.top_card);
158         assertNotNull(fragment);
159 
160         ImageButton leftImageButton = mock(ImageButton.class);
161         fragment.setControlBarLeftButton(leftImageButton);
162 
163         Drawable mockIcon = mock(Drawable.class);
164         DescriptiveTextWithControlsView.Control buttonControl = mock(
165                 DescriptiveTextWithControlsView.Control.class);
166         DescriptiveTextWithControlsView.Control leftButtonControl = mock(
167                 DescriptiveTextWithControlsView.Control.class);
168 
169         // unselects the button in case the icon doesn't have a selected state
170         when(mockIcon.getState()).thenReturn(new int[0]);
171         when(leftButtonControl.getIcon()).thenReturn(mockIcon);
172         DescriptiveTextWithControlsView controlView = new DescriptiveTextWithControlsView(null,
173                 "test", "test", leftButtonControl, buttonControl, buttonControl);
174         fragment.updateHeaderView(CARD_HEADER);
175         fragment.updateContentView(controlView);
176         InstrumentationRegistry.getInstrumentation().waitForIdleSync();
177         verify(leftImageButton).setSelected(false);
178 
179         // selects the button in case the icon have a selected state
180         when(mockIcon.getState()).thenReturn(new int[]{android.R.attr.state_selected});
181         when(leftButtonControl.getIcon()).thenReturn(mockIcon);
182         controlView = new DescriptiveTextWithControlsView(null,
183                 "test", "test", leftButtonControl, buttonControl, buttonControl);
184         fragment.updateContentView(controlView);
185         InstrumentationRegistry.getInstrumentation().waitForIdleSync();
186         verify(leftImageButton).setSelected(true);
187     }
188 }
189