1 /*
2  * Copyright (C) 2021 The Android Open Source Project
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.settingslib.widget;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 
21 import static org.mockito.ArgumentMatchers.any;
22 import static org.mockito.Mockito.doNothing;
23 import static org.mockito.Mockito.doReturn;
24 import static org.mockito.Mockito.mock;
25 import static org.mockito.Mockito.spy;
26 import static org.mockito.Mockito.verify;
27 
28 import android.content.Context;
29 import android.graphics.drawable.AnimatedImageDrawable;
30 import android.graphics.drawable.AnimatedVectorDrawable;
31 import android.graphics.drawable.AnimationDrawable;
32 import android.net.Uri;
33 import android.util.AttributeSet;
34 import android.view.View;
35 import android.view.ViewGroup;
36 import android.widget.FrameLayout;
37 import android.widget.ImageView;
38 
39 import androidx.preference.PreferenceViewHolder;
40 import androidx.test.core.app.ApplicationProvider;
41 
42 import com.airbnb.lottie.LottieAnimationView;
43 
44 import org.junit.Before;
45 import org.junit.Test;
46 import org.junit.runner.RunWith;
47 import org.mockito.Mock;
48 import org.mockito.MockitoAnnotations;
49 import org.robolectric.Robolectric;
50 import org.robolectric.RobolectricTestRunner;
51 
52 @RunWith(RobolectricTestRunner.class)
53 public class IllustrationPreferenceTest {
54 
55     @Mock
56     private ViewGroup mRootView;
57     private Uri mImageUri;
58     private ImageView mBackgroundView;
59     private LottieAnimationView mAnimationView;
60     private IllustrationPreference mPreference;
61     private PreferenceViewHolder mViewHolder;
62     private FrameLayout mMiddleGroundLayout;
63     private final Context mContext = ApplicationProvider.getApplicationContext();
64 
65     @Before
setUp()66     public void setUp() {
67         MockitoAnnotations.initMocks(this);
68 
69         mImageUri = new Uri.Builder().build();
70         mBackgroundView = new ImageView(mContext);
71         mAnimationView = spy(new LottieAnimationView(mContext));
72         mMiddleGroundLayout = new FrameLayout(mContext);
73         final FrameLayout illustrationFrame = new FrameLayout(mContext);
74         illustrationFrame.setLayoutParams(
75                 new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
76                         ViewGroup.LayoutParams.WRAP_CONTENT));
77         doReturn(mMiddleGroundLayout).when(mRootView).findViewById(R.id.middleground_layout);
78         doReturn(mBackgroundView).when(mRootView).findViewById(R.id.background_view);
79         doReturn(mAnimationView).when(mRootView).findViewById(R.id.lottie_view);
80         doReturn(illustrationFrame).when(mRootView).findViewById(R.id.illustration_frame);
81         mViewHolder = spy(PreferenceViewHolder.createInstanceForTests(mRootView));
82 
83         final AttributeSet attributeSet = Robolectric.buildAttributeSet().build();
84         mPreference = new IllustrationPreference(mContext, attributeSet);
85     }
86 
87     @Test
setMiddleGroundView_middleGroundView_shouldVisible()88     public void setMiddleGroundView_middleGroundView_shouldVisible() {
89         final View view = new View(mContext);
90         mMiddleGroundLayout.setVisibility(View.GONE);
91 
92         mPreference.setMiddleGroundView(view);
93         mPreference.onBindViewHolder(mViewHolder);
94 
95         assertThat(mMiddleGroundLayout.getVisibility()).isEqualTo(View.VISIBLE);
96     }
97 
98     @Test
enableAnimationAutoScale_shouldChangeScaleType()99     public void enableAnimationAutoScale_shouldChangeScaleType() {
100         mPreference.enableAnimationAutoScale(true);
101         mPreference.onBindViewHolder(mViewHolder);
102 
103         assertThat(mAnimationView.getScaleType()).isEqualTo(ImageView.ScaleType.CENTER_CROP);
104     }
105 
106     @Test
playAnimationWithUri_animatedImageDrawable_success()107     public void playAnimationWithUri_animatedImageDrawable_success() {
108         final AnimatedImageDrawable drawable = mock(AnimatedImageDrawable.class);
109         doReturn(drawable).when(mAnimationView).getDrawable();
110 
111         mPreference.setImageUri(mImageUri);
112         mPreference.onBindViewHolder(mViewHolder);
113 
114         verify(drawable).start();
115     }
116 
117     @Test
playAnimationWithUri_animatedVectorDrawable_success()118     public void playAnimationWithUri_animatedVectorDrawable_success() {
119         final AnimatedVectorDrawable drawable = mock(AnimatedVectorDrawable.class);
120         doReturn(drawable).when(mAnimationView).getDrawable();
121 
122         mPreference.setImageUri(mImageUri);
123         mPreference.onBindViewHolder(mViewHolder);
124 
125         verify(drawable).start();
126     }
127 
128     @Test
playAnimationWithUri_animationDrawable_success()129     public void playAnimationWithUri_animationDrawable_success() {
130         final AnimationDrawable drawable = mock(AnimationDrawable.class);
131         doReturn(drawable).when(mAnimationView).getDrawable();
132 
133         mPreference.setImageUri(mImageUri);
134         mPreference.onBindViewHolder(mViewHolder);
135 
136         verify(drawable).start();
137     }
138 
139     @Test
playLottieAnimationWithUri_verifyFailureListener()140     public void playLottieAnimationWithUri_verifyFailureListener() {
141         doReturn(null).when(mAnimationView).getDrawable();
142 
143         mPreference.setImageUri(mImageUri);
144         mPreference.onBindViewHolder(mViewHolder);
145 
146         verify(mAnimationView).setFailureListener(any());
147     }
148 
149     @Test
playLottieAnimationWithResource_verifyFailureListener()150     public void playLottieAnimationWithResource_verifyFailureListener() {
151         // fake the valid lottie image
152         final int fakeValidResId = 111;
153         doNothing().when(mAnimationView).setImageResource(fakeValidResId);
154         doReturn(null).when(mAnimationView).getDrawable();
155 
156         mPreference.setLottieAnimationResId(fakeValidResId);
157         mPreference.onBindViewHolder(mViewHolder);
158 
159         verify(mAnimationView).setFailureListener(any());
160     }
161 
162     @Test
setMaxHeight_smallerThanRestrictedHeight_matchResult()163     public void setMaxHeight_smallerThanRestrictedHeight_matchResult() {
164         final int restrictedHeight =
165                 mContext.getResources().getDimensionPixelSize(
166                         R.dimen.settingslib_illustration_height);
167         final int maxHeight = restrictedHeight - 200;
168 
169         mPreference.setMaxHeight(maxHeight);
170         mPreference.onBindViewHolder(mViewHolder);
171 
172         assertThat(mBackgroundView.getMaxHeight()).isEqualTo(maxHeight);
173         assertThat(mAnimationView.getMaxHeight()).isEqualTo(maxHeight);
174     }
175 
176     @Test
setMaxHeight_largerThanRestrictedHeight_specificHeight()177     public void setMaxHeight_largerThanRestrictedHeight_specificHeight() {
178         final int restrictedHeight =
179                 mContext.getResources().getDimensionPixelSize(
180                         R.dimen.settingslib_illustration_height);
181         final int maxHeight = restrictedHeight + 200;
182 
183         mPreference.setMaxHeight(maxHeight);
184         mPreference.onBindViewHolder(mViewHolder);
185 
186         assertThat(mBackgroundView.getMaxHeight()).isEqualTo(restrictedHeight);
187         assertThat(mAnimationView.getMaxHeight()).isEqualTo(restrictedHeight);
188     }
189 }
190