blob: 2e585440c263e97cd95fa2adb22c0bcf00097f4d [file] [log] [blame]
// Copyright 2018 The Feed Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.android.libraries.feed.piet;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Color;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.TransitionDrawable;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import com.google.android.libraries.feed.common.time.testing.FakeClock;
import com.google.android.libraries.feed.piet.host.AssetProvider;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.shadows.ShadowLooper;
/** Tests of the {@link LoadImageCallback}. */
@RunWith(RobolectricTestRunner.class)
public class LoadImageCallbackTest {
private static final int FADE_IMAGE_THRESHOLD_MS = 682;
private static final Integer NO_OVERLAY_COLOR = null;
private static final boolean FADE_IMAGE = true;
private static final boolean NO_FADE_IMAGE = false;
@Mock private HostProviders hostProviders;
@Mock private AssetProvider assetProvider;
@Mock private FrameContext frameContext;
private final Drawable initialDrawable = new ColorDrawable(Color.RED);
private final Drawable finalDrawable =
new BitmapDrawable(Bitmap.createBitmap(12, 34, Config.ARGB_8888));
private final FakeClock clock = new FakeClock();
private AdapterParameters parameters;
private Context context;
@Before
public void setup() {
initMocks(this);
context = Robolectric.buildActivity(Activity.class).get();
when(hostProviders.getAssetProvider()).thenReturn(assetProvider);
when(assetProvider.getFadeImageThresholdMs()).thenReturn(FADE_IMAGE_THRESHOLD_MS);
when(frameContext.getFrameView()).thenReturn(new FrameLayout(context));
parameters =
new AdapterParameters(
context,
null,
hostProviders,
null,
mock(ElementAdapterFactory.class),
mock(TemplateBinder.class),
clock);
}
@Test
public void testInitialDrawable_fromImageView() {
ImageView imageView = new ImageView(context);
imageView.setImageDrawable(initialDrawable);
LoadImageCallback callback =
new LoadImageCallback(
imageView, ScaleType.CENTER, NO_OVERLAY_COLOR, FADE_IMAGE, parameters, frameContext);
clock.advance(FADE_IMAGE_THRESHOLD_MS + 1);
callback.accept(finalDrawable);
assertThat(imageView.getDrawable()).isInstanceOf(TransitionDrawable.class);
TransitionDrawable drawable = (TransitionDrawable) imageView.getDrawable();
assertThat(drawable.getDrawable(0)).isSameAs(initialDrawable);
assertThat(drawable.getDrawable(1)).isSameAs(finalDrawable);
}
@Test
public void testInitialDrawable_transparent() {
ImageView imageView = new ImageView(context);
LoadImageCallback callback =
new LoadImageCallback(
imageView, ScaleType.CENTER, NO_OVERLAY_COLOR, FADE_IMAGE, parameters, frameContext);
clock.advance(FADE_IMAGE_THRESHOLD_MS + 1);
callback.accept(finalDrawable);
assertThat(imageView.getDrawable()).isInstanceOf(TransitionDrawable.class);
TransitionDrawable drawable = (TransitionDrawable) imageView.getDrawable();
assertThat(((ColorDrawable) drawable.getDrawable(0)).getColor()).isEqualTo(Color.TRANSPARENT);
}
@Test
public void testQuickLoad_doesntFade_fadingDisabled() {
ImageView imageView = new ImageView(context);
LoadImageCallback callback =
new LoadImageCallback(
imageView, ScaleType.CENTER, NO_OVERLAY_COLOR, NO_FADE_IMAGE, parameters, frameContext);
clock.advance(FADE_IMAGE_THRESHOLD_MS + 1);
callback.accept(finalDrawable);
assertThat(imageView.getDrawable()).isSameAs(finalDrawable);
}
@Test
public void testQuickLoad_doesntFade_loadsBeforeTimeout() {
ImageView imageView = new ImageView(context);
LoadImageCallback callback =
new LoadImageCallback(
imageView, ScaleType.CENTER, NO_OVERLAY_COLOR, FADE_IMAGE, parameters, frameContext);
clock.advance(FADE_IMAGE_THRESHOLD_MS - 1);
callback.accept(finalDrawable);
assertThat(imageView.getDrawable()).isSameAs(finalDrawable);
}
@Test
public void testDelayedTask() {
ImageView imageView = new ImageView(context);
LoadImageCallback callback =
new LoadImageCallback(
imageView, ScaleType.CENTER, NO_OVERLAY_COLOR, FADE_IMAGE, parameters, frameContext);
clock.advance(FADE_IMAGE_THRESHOLD_MS + 1);
callback.accept(finalDrawable);
// Starts as transition drawable.
assertThat(imageView.getDrawable()).isInstanceOf(TransitionDrawable.class);
ShadowLooper.runUiThreadTasksIncludingDelayedTasks();
// After the delayed task is run, the drawable is set to the finalDrawable instead of the
// TransitionDrawable to allow for garbage collection of the TransitionDrawable and
// initialDrawable.
assertThat(imageView.getDrawable()).isSameAs(finalDrawable);
}
@Test
public void testSetsScaleType() {
ImageView imageView = new ImageView(context);
LoadImageCallback callback =
new LoadImageCallback(
imageView, ScaleType.CENTER, NO_OVERLAY_COLOR, NO_FADE_IMAGE, parameters, frameContext);
callback.accept(finalDrawable);
assertThat(imageView.getScaleType()).isEqualTo(ScaleType.CENTER);
}
@Test
public void testSetsOverlayColor() {
int color = 0xFEEDFACE;
ImageView imageView = new ImageView(context);
LoadImageCallback callback =
new LoadImageCallback(
imageView, ScaleType.CENTER, color, NO_FADE_IMAGE, parameters, frameContext);
callback.accept(finalDrawable);
assertThat(imageView.getDrawable().getColorFilter())
.isEqualTo(new PorterDuffColorFilter(color, Mode.SRC_IN));
}
@Test
public void testSetsOverlayColor_null() {
ImageView imageView = new ImageView(context);
LoadImageCallback callback =
new LoadImageCallback(
imageView, ScaleType.CENTER, NO_OVERLAY_COLOR, NO_FADE_IMAGE, parameters, frameContext);
callback.accept(finalDrawable);
assertThat(imageView.getDrawable().getColorFilter()).isNull();
}
}