TypefaceCompatTest.java revision 0b03693667d95d2202dfbb24866665ff061acce1
1/*
2 * Copyright (C) 2017 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
17package android.support.v4.graphics;
18
19import static android.content.res.AssetManager.ACCESS_BUFFER;
20
21import static org.junit.Assert.assertEquals;
22import static org.junit.Assert.assertNotNull;
23import static org.junit.Assert.assertTrue;
24import static org.mockito.Mockito.mock;
25import static org.mockito.Mockito.verify;
26
27import android.graphics.Typeface;
28import android.os.Build;
29import android.os.Bundle;
30import android.os.ParcelFileDescriptor;
31import android.support.test.filters.SmallTest;
32import android.support.test.runner.AndroidJUnit4;
33import android.support.v4.BaseInstrumentationTestCase;
34import android.support.v4.app.TestSupportActivity;
35import android.support.v4.graphics.TypefaceCompat.FontRequestCallback;
36import android.support.v4.graphics.fonts.FontRequest;
37import android.support.v4.graphics.fonts.FontResult;
38import android.support.v4.provider.FontsContractCompat;
39import android.util.Base64;
40
41import org.junit.Before;
42import org.junit.Test;
43import org.junit.runner.RunWith;
44
45import java.io.File;
46import java.io.FileOutputStream;
47import java.io.IOException;
48import java.io.InputStream;
49import java.util.ArrayList;
50import java.util.Arrays;
51import java.util.List;
52
53/**
54 * Tests for {@link TypefaceCompatBaseImpl}.
55 */
56@SmallTest
57@RunWith(AndroidJUnit4.class)
58public class TypefaceCompatTest extends BaseInstrumentationTestCase<TestSupportActivity> {
59    private static final String TEST_FONT_FILE = "samplefont.ttf";
60    private static final String PROVIDER = "com.test.fontprovider.authority";
61    private static final String QUERY_CACHED = "query_cached";
62    private static final String QUERY = "query";
63    private static final String PACKAGE = "com.test.fontprovider.package";
64    private static final byte[] BYTE_ARRAY =
65            Base64.decode("e04fd020ea3a6910a2d808002b30", Base64.DEFAULT);
66    private static final List<List<byte[]>> CERTS = Arrays.asList(Arrays.asList(BYTE_ARRAY));
67
68    private TypefaceCompatBaseImpl mCompat;
69
70    public TypefaceCompatTest() {
71        super(TestSupportActivity.class);
72    }
73
74    @Before
75    public void setup() {
76        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
77            mCompat = new TypefaceCompatApi24Impl(mActivityTestRule.getActivity());
78        } else {
79            mCompat = new TypefaceCompatBaseImpl(mActivityTestRule.getActivity());
80        }
81        TypefaceCompatBaseImpl.putInCache(PROVIDER, QUERY_CACHED, Typeface.MONOSPACE);
82    }
83
84    @Test
85    public void testReceiveResult_cachedResult() {
86        FontRequestCallback callback = mock(FontRequestCallback.class);
87
88        mCompat.receiveResult(new FontRequest(PROVIDER, PACKAGE, QUERY_CACHED, CERTS),
89                callback, 0, null);
90
91        verify(callback).onTypefaceRetrieved(Typeface.MONOSPACE);
92    }
93
94    @Test
95    public void testReceiveResult_resultCodeProviderNotFound() {
96        FontRequestCallback callback = mock(FontRequestCallback.class);
97
98        mCompat.receiveResult(new FontRequest(PROVIDER, PACKAGE, QUERY, CERTS), callback,
99                FontsContractCompat.RESULT_CODE_PROVIDER_NOT_FOUND, null);
100
101        verify(callback).onTypefaceRequestFailed(
102                FontRequestCallback.FAIL_REASON_PROVIDER_NOT_FOUND);
103    }
104
105    @Test
106    public void testReceiveResult_resultCodeFontNotFound() {
107        FontRequestCallback callback = mock(FontRequestCallback.class);
108
109        mCompat.receiveResult(new FontRequest(PROVIDER, PACKAGE, QUERY, CERTS), callback,
110                FontsContractCompat.Columns.RESULT_CODE_FONT_NOT_FOUND, null);
111
112        verify(callback).onTypefaceRequestFailed(
113                FontRequestCallback.FAIL_REASON_FONT_NOT_FOUND);
114    }
115
116    @Test
117    public void testReceiveResult_nullBundle() {
118        FontRequestCallback callback = mock(FontRequestCallback.class);
119
120        mCompat.receiveResult(new FontRequest(PROVIDER, PACKAGE, QUERY, CERTS), callback,
121                FontsContractCompat.Columns.RESULT_CODE_OK, null);
122
123        verify(callback).onTypefaceRequestFailed(
124                FontRequestCallback.FAIL_REASON_FONT_NOT_FOUND);
125    }
126
127    @Test
128    public void testReceiveResult_nullResult() {
129        FontRequestCallback callback = mock(FontRequestCallback.class);
130
131        mCompat.receiveResult(new FontRequest(PROVIDER, PACKAGE, QUERY, CERTS), callback,
132                FontsContractCompat.Columns.RESULT_CODE_OK, new Bundle());
133
134        verify(callback).onTypefaceRequestFailed(
135                FontRequestCallback.FAIL_REASON_FONT_NOT_FOUND);
136    }
137
138    @Test
139    public void testReceiveResult_emptyResult() {
140        FontRequestCallback callback = mock(FontRequestCallback.class);
141        Bundle bundle = new Bundle();
142        bundle.putParcelableArrayList(
143                FontsContractCompat.PARCEL_FONT_RESULTS, new ArrayList<FontResult>());
144
145        mCompat.receiveResult(new FontRequest(PROVIDER, PACKAGE, QUERY, CERTS), callback,
146                FontsContractCompat.Columns.RESULT_CODE_OK, bundle);
147
148        verify(callback).onTypefaceRequestFailed(
149                FontRequestCallback.FAIL_REASON_FONT_NOT_FOUND);
150    }
151
152    @Test
153    public void testTypefaceRequestFailureConstantsAreInSync() {
154        // Error codes from the provider are positive numbers and are in sync
155        assertEquals(FontsContractCompat.Columns.RESULT_CODE_FONT_NOT_FOUND,
156                TypefaceCompat.FontRequestCallback.FAIL_REASON_FONT_NOT_FOUND);
157        assertEquals(FontsContractCompat.Columns.RESULT_CODE_FONT_UNAVAILABLE,
158                TypefaceCompat.FontRequestCallback.FAIL_REASON_FONT_UNAVAILABLE);
159        assertEquals(FontsContractCompat.Columns.RESULT_CODE_MALFORMED_QUERY,
160                TypefaceCompat.FontRequestCallback.FAIL_REASON_MALFORMED_QUERY);
161
162        // Internal errors are negative
163        assertTrue(0 > TypefaceCompat.FontRequestCallback.FAIL_REASON_PROVIDER_NOT_FOUND);
164        assertTrue(0 > TypefaceCompat.FontRequestCallback.FAIL_REASON_WRONG_CERTIFICATES);
165        assertTrue(0 > TypefaceCompat.FontRequestCallback.FAIL_REASON_FONT_LOAD_ERROR);
166    }
167
168    private File loadFont() {
169        File cacheFile = new File(mActivityTestRule.getActivity().getCacheDir(), TEST_FONT_FILE);
170        try {
171            copyToCacheFile(TEST_FONT_FILE, cacheFile);
172            return cacheFile;
173        } catch (IOException e) {
174            e.printStackTrace();
175        }
176        return null;
177    }
178
179    private void copyToCacheFile(final String assetPath, final File cacheFile)
180            throws IOException {
181        InputStream is = null;
182        FileOutputStream fos = null;
183        try {
184            is = mActivityTestRule.getActivity().getAssets().open(assetPath, ACCESS_BUFFER);
185            fos = new FileOutputStream(cacheFile, false);
186            byte[] buffer = new byte[1024];
187            int readLen;
188            while ((readLen = is.read(buffer)) != -1) {
189                fos.write(buffer, 0, readLen);
190            }
191        } finally {
192            if (is != null) {
193                is.close();
194            }
195            if (fos != null) {
196                fos.close();
197            }
198        }
199    }
200
201    @Test
202    public void testCreateTypeface() throws IOException, InterruptedException {
203        File file = loadFont();
204        ParcelFileDescriptor pfd =
205                ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
206        try {
207            FontResult result = new FontResult(pfd, 0, null, 400, false /* italic */);
208            Typeface typeface = mCompat.createTypeface(Arrays.asList(result));
209
210            assertNotNull(typeface);
211        } finally {
212            if (file != null) {
213                file.delete();
214            }
215            if (pfd != null) {
216                pfd.close();
217            }
218        }
219    }
220}
221