1d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam/*
2d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam * Copyright (C) 2016 The Android Open Source Project
3d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam *
4d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam * Licensed under the Apache License, Version 2.0 (the "License");
5d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam * you may not use this file except in compliance with the License.
6d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam * You may obtain a copy of the License at
7d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam *
8d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam *      http://www.apache.org/licenses/LICENSE-2.0
9d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam *
10d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam * Unless required by applicable law or agreed to in writing, software
11d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam * distributed under the License is distributed on an "AS IS" BASIS,
12d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam * See the License for the specific language governing permissions and
14d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam * limitations under the License.
15d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam */
16d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam
17618a4449bb3e9be43586040ea2fb9a6371365ae7Maurice Lampackage com.android.setupwizardlib.view;
18d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam
19e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lamimport static com.google.common.truth.Truth.assertThat;
20e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam
212614260933341bd4ea7bb37a3435f46f82cacef7Maurice Lamimport static org.junit.Assert.assertEquals;
222614260933341bd4ea7bb37a3435f46f82cacef7Maurice Lamimport static org.junit.Assert.assertFalse;
2351f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lamimport static org.junit.Assert.assertSame;
242614260933341bd4ea7bb37a3435f46f82cacef7Maurice Lamimport static org.junit.Assert.assertTrue;
2551f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lamimport static org.mockito.Matchers.eq;
26e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lamimport static org.mockito.Mockito.doReturn;
2751f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lamimport static org.mockito.Mockito.mock;
2851f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lamimport static org.mockito.Mockito.spy;
2951f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lamimport static org.mockito.Mockito.verify;
30618a4449bb3e9be43586040ea2fb9a6371365ae7Maurice Lamimport static org.robolectric.RuntimeEnvironment.application;
312614260933341bd4ea7bb37a3435f46f82cacef7Maurice Lam
3263cdc5ccb7f1f61d0e752e38d7e57c690658a0acMaurice Lamimport android.annotation.SuppressLint;
3351f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lamimport android.content.Context;
3451f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lamimport android.content.ContextWrapper;
35618a4449bb3e9be43586040ea2fb9a6371365ae7Maurice Lamimport android.os.Build.VERSION;
36618a4449bb3e9be43586040ea2fb9a6371365ae7Maurice Lamimport android.os.Build.VERSION_CODES;
37d832154e333a3a45b5faecd518b664ddd297183cMaurice Lamimport android.text.Annotation;
38d832154e333a3a45b5faecd518b664ddd297183cMaurice Lamimport android.text.SpannableStringBuilder;
39d832154e333a3a45b5faecd518b664ddd297183cMaurice Lamimport android.text.Spanned;
40d832154e333a3a45b5faecd518b664ddd297183cMaurice Lamimport android.text.style.TextAppearanceSpan;
41e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lamimport android.view.MotionEvent;
42d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam
43618a4449bb3e9be43586040ea2fb9a6371365ae7Maurice Lamimport com.android.setupwizardlib.robolectric.SuwLibRobolectricTestRunner;
44d832154e333a3a45b5faecd518b664ddd297183cMaurice Lamimport com.android.setupwizardlib.span.LinkSpan;
4551f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lamimport com.android.setupwizardlib.span.LinkSpan.OnLinkClickListener;
46e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lamimport com.android.setupwizardlib.view.TouchableMovementMethod.TouchableLinkMovementMethod;
47d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam
482614260933341bd4ea7bb37a3435f46f82cacef7Maurice Lamimport org.junit.Test;
492614260933341bd4ea7bb37a3435f46f82cacef7Maurice Lamimport org.junit.runner.RunWith;
50618a4449bb3e9be43586040ea2fb9a6371365ae7Maurice Lamimport org.robolectric.annotation.Config;
512614260933341bd4ea7bb37a3435f46f82cacef7Maurice Lam
52d832154e333a3a45b5faecd518b664ddd297183cMaurice Lamimport java.util.Arrays;
53d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam
54618a4449bb3e9be43586040ea2fb9a6371365ae7Maurice Lam@RunWith(SuwLibRobolectricTestRunner.class)
55618a4449bb3e9be43586040ea2fb9a6371365ae7Maurice Lam@Config(sdk = { Config.OLDEST_SDK, Config.NEWEST_SDK })
562614260933341bd4ea7bb37a3435f46f82cacef7Maurice Lampublic class RichTextViewTest {
57d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam
582614260933341bd4ea7bb37a3435f46f82cacef7Maurice Lam    @Test
59d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam    public void testLinkAnnotation() {
60d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam        Annotation link = new Annotation("link", "foobar");
61d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam        SpannableStringBuilder ssb = new SpannableStringBuilder("Hello world");
62d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam        ssb.setSpan(link, 1, 2, 0 /* flags */);
63d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam
64618a4449bb3e9be43586040ea2fb9a6371365ae7Maurice Lam        RichTextView textView = new RichTextView(application);
65d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam        textView.setText(ssb);
66d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam
67d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam        final CharSequence text = textView.getText();
68d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam        assertTrue("Text should be spanned", text instanceof Spanned);
69d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam
70e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam        assertThat(textView.getMovementMethod()).isInstanceOf(TouchableLinkMovementMethod.class);
71e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam
72d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam        Object[] spans = ((Spanned) text).getSpans(0, text.length(), Annotation.class);
73d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam        assertEquals("Annotation should be removed " + Arrays.toString(spans), 0, spans.length);
74d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam
75d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam        spans = ((Spanned) text).getSpans(0, text.length(), LinkSpan.class);
76d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam        assertEquals("There should be one span " + Arrays.toString(spans), 1, spans.length);
77d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam        assertTrue("The span should be a LinkSpan", spans[0] instanceof LinkSpan);
78d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam        assertEquals("The LinkSpan should have id \"foobar\"",
79d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam                "foobar", ((LinkSpan) spans[0]).getId());
80d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam    }
81d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam
822614260933341bd4ea7bb37a3435f46f82cacef7Maurice Lam    @Test
8351f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam    public void testOnLinkClickListener() {
8451f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam        Annotation link = new Annotation("link", "foobar");
8551f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam        SpannableStringBuilder ssb = new SpannableStringBuilder("Hello world");
8651f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam        ssb.setSpan(link, 1, 2, 0 /* flags */);
8751f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam
88618a4449bb3e9be43586040ea2fb9a6371365ae7Maurice Lam        RichTextView textView = new RichTextView(application);
8951f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam        textView.setText(ssb);
9051f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam
9151f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam        OnLinkClickListener listener = mock(OnLinkClickListener.class);
9251f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam        textView.setOnLinkClickListener(listener);
9351f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam
9451f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam        assertSame(listener, textView.getOnLinkClickListener());
9551f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam
9651f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam        CharSequence text = textView.getText();
9751f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam        LinkSpan[] spans = ((Spanned) text).getSpans(0, text.length(), LinkSpan.class);
9851f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam        spans[0].onClick(textView);
9951f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam
10051f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam        verify(listener).onLinkClick(eq(spans[0]));
10151f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam    }
10251f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam
10351f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam    @Test
10451f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam    public void testLegacyContextOnClickListener() {
10551f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam        // Click listener implemented by context should still be invoked for compatibility.
10651f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam        Annotation link = new Annotation("link", "foobar");
10751f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam        SpannableStringBuilder ssb = new SpannableStringBuilder("Hello world");
10851f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam        ssb.setSpan(link, 1, 2, 0 /* flags */);
10951f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam
110618a4449bb3e9be43586040ea2fb9a6371365ae7Maurice Lam        TestContext context = spy(new TestContext(application));
11151f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam        RichTextView textView = new RichTextView(context);
11251f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam        textView.setText(ssb);
11351f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam
11451f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam        CharSequence text = textView.getText();
11551f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam        LinkSpan[] spans = ((Spanned) text).getSpans(0, text.length(), LinkSpan.class);
11651f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam        spans[0].onClick(textView);
11751f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam
11851f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam        verify(context).onClick(eq(spans[0]));
11951f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam    }
12051f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam
12151f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam    @Test
122e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam    public void onTouchEvent_clickOnLinks_shouldReturnTrue() {
123e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam        Annotation link = new Annotation("link", "foobar");
124e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam        SpannableStringBuilder ssb = new SpannableStringBuilder("Hello world");
125e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam        ssb.setSpan(link, 0, 2, 0 /* flags */);
126e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam
127e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam        RichTextView textView = new RichTextView(application);
128e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam        textView.setText(ssb);
129e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam
130e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam        TouchableLinkMovementMethod mockMovementMethod = mock(TouchableLinkMovementMethod.class);
131e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam        textView.setMovementMethod(mockMovementMethod);
132e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam
133e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam        MotionEvent motionEvent =
134e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam                MotionEvent.obtain(123, 22, MotionEvent.ACTION_DOWN, 0, 0, 0);
135e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam        doReturn(motionEvent).when(mockMovementMethod).getLastTouchEvent();
136e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam        doReturn(true).when(mockMovementMethod).isLastTouchEventHandled();
137e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam        assertThat(textView.onTouchEvent(motionEvent)).isTrue();
138e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam    }
139e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam
140e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam    @Test
141e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam    public void onTouchEvent_clickOutsideLinks_shouldReturnFalse() {
142e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam        Annotation link = new Annotation("link", "foobar");
143e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam        SpannableStringBuilder ssb = new SpannableStringBuilder("Hello world");
144e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam        ssb.setSpan(link, 0, 2, 0 /* flags */);
145e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam
146e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam        RichTextView textView = new RichTextView(application);
147e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam        textView.setText(ssb);
148e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam
149e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam        TouchableLinkMovementMethod mockMovementMethod = mock(TouchableLinkMovementMethod.class);
150e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam        textView.setMovementMethod(mockMovementMethod);
151e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam
152e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam        MotionEvent motionEvent =
153e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam                MotionEvent.obtain(123, 22, MotionEvent.ACTION_DOWN, 0, 0, 0);
154e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam        doReturn(motionEvent).when(mockMovementMethod).getLastTouchEvent();
155e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam        doReturn(false).when(mockMovementMethod).isLastTouchEventHandled();
156e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam        assertThat(textView.onTouchEvent(motionEvent)).isFalse();
157e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam    }
158e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam
159e58194099d9133ce7b2e19fe7c717679b62fddb2Maurice Lam    @Test
160d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam    public void testTextStyle() {
161d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam        Annotation link = new Annotation("textAppearance", "foobar");
162d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam        SpannableStringBuilder ssb = new SpannableStringBuilder("Hello world");
163d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam        ssb.setSpan(link, 1, 2, 0 /* flags */);
164d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam
165618a4449bb3e9be43586040ea2fb9a6371365ae7Maurice Lam        RichTextView textView = new RichTextView(application);
166d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam        textView.setText(ssb);
167d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam
168d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam        final CharSequence text = textView.getText();
169d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam        assertTrue("Text should be spanned", text instanceof Spanned);
170d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam
171d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam        Object[] spans = ((Spanned) text).getSpans(0, text.length(), Annotation.class);
172d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam        assertEquals("Annotation should be removed " + Arrays.toString(spans), 0, spans.length);
173d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam
174d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam        spans = ((Spanned) text).getSpans(0, text.length(), TextAppearanceSpan.class);
175d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam        assertEquals("There should be one span " + Arrays.toString(spans), 1, spans.length);
176d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam        assertTrue("The span should be a TextAppearanceSpan",
177d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam                spans[0] instanceof TextAppearanceSpan);
178d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam    }
1799a3d23293ecf8b76b8c22e1381005751a88a458aAjay Nadathur
1802614260933341bd4ea7bb37a3435f46f82cacef7Maurice Lam    @Test
18151f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam    public void testTextContainingLinksAreFocusable() {
1829a3d23293ecf8b76b8c22e1381005751a88a458aAjay Nadathur        Annotation testLink = new Annotation("link", "value");
1839a3d23293ecf8b76b8c22e1381005751a88a458aAjay Nadathur        SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder("Linked");
1849a3d23293ecf8b76b8c22e1381005751a88a458aAjay Nadathur        spannableStringBuilder.setSpan(testLink, 0, 3, 0);
1859a3d23293ecf8b76b8c22e1381005751a88a458aAjay Nadathur
186618a4449bb3e9be43586040ea2fb9a6371365ae7Maurice Lam        RichTextView view = new RichTextView(application);
1879a3d23293ecf8b76b8c22e1381005751a88a458aAjay Nadathur        view.setText(spannableStringBuilder);
1889a3d23293ecf8b76b8c22e1381005751a88a458aAjay Nadathur
1899a3d23293ecf8b76b8c22e1381005751a88a458aAjay Nadathur        assertTrue("TextView should be focusable since it contains spans", view.isFocusable());
1909a3d23293ecf8b76b8c22e1381005751a88a458aAjay Nadathur    }
1919a3d23293ecf8b76b8c22e1381005751a88a458aAjay Nadathur
1929a3d23293ecf8b76b8c22e1381005751a88a458aAjay Nadathur
19363cdc5ccb7f1f61d0e752e38d7e57c690658a0acMaurice Lam    @SuppressLint("SetTextI18n")  // It's OK. This is just a test.
1942614260933341bd4ea7bb37a3435f46f82cacef7Maurice Lam    @Test
1959a3d23293ecf8b76b8c22e1381005751a88a458aAjay Nadathur    public void testTextContainingNoLinksAreNotFocusable() {
196618a4449bb3e9be43586040ea2fb9a6371365ae7Maurice Lam        RichTextView textView = new RichTextView(application);
1979a3d23293ecf8b76b8c22e1381005751a88a458aAjay Nadathur        textView.setText("Thou shall not be focusable!");
1989a3d23293ecf8b76b8c22e1381005751a88a458aAjay Nadathur
1999a3d23293ecf8b76b8c22e1381005751a88a458aAjay Nadathur        assertFalse("TextView should not be focusable since it does not contain any span",
2009a3d23293ecf8b76b8c22e1381005751a88a458aAjay Nadathur                textView.isFocusable());
2019a3d23293ecf8b76b8c22e1381005751a88a458aAjay Nadathur    }
2029a3d23293ecf8b76b8c22e1381005751a88a458aAjay Nadathur
2039a3d23293ecf8b76b8c22e1381005751a88a458aAjay Nadathur
2049a3d23293ecf8b76b8c22e1381005751a88a458aAjay Nadathur    // Based on the text contents of the text view, the "focusable" property of the element
2059a3d23293ecf8b76b8c22e1381005751a88a458aAjay Nadathur    // should also be automatically changed.
20663cdc5ccb7f1f61d0e752e38d7e57c690658a0acMaurice Lam    @SuppressLint("SetTextI18n")  // It's OK. This is just a test.
2072614260933341bd4ea7bb37a3435f46f82cacef7Maurice Lam    @Test
20851f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam    public void testRichTextViewFocusChangesWithTextChange() {
209618a4449bb3e9be43586040ea2fb9a6371365ae7Maurice Lam        RichTextView textView = new RichTextView(application);
2109a3d23293ecf8b76b8c22e1381005751a88a458aAjay Nadathur        textView.setText("Thou shall not be focusable!");
2119a3d23293ecf8b76b8c22e1381005751a88a458aAjay Nadathur
2129a3d23293ecf8b76b8c22e1381005751a88a458aAjay Nadathur        assertFalse(textView.isFocusable());
213618a4449bb3e9be43586040ea2fb9a6371365ae7Maurice Lam        assertFalse(textView.isFocusableInTouchMode());
2149a3d23293ecf8b76b8c22e1381005751a88a458aAjay Nadathur
2159a3d23293ecf8b76b8c22e1381005751a88a458aAjay Nadathur        SpannableStringBuilder spannableStringBuilder =
2169a3d23293ecf8b76b8c22e1381005751a88a458aAjay Nadathur                new SpannableStringBuilder("I am focusable");
2179a3d23293ecf8b76b8c22e1381005751a88a458aAjay Nadathur        spannableStringBuilder.setSpan(new Annotation("link", "focus:on_me"), 0, 1, 0);
2189a3d23293ecf8b76b8c22e1381005751a88a458aAjay Nadathur        textView.setText(spannableStringBuilder);
2199a3d23293ecf8b76b8c22e1381005751a88a458aAjay Nadathur        assertTrue(textView.isFocusable());
220618a4449bb3e9be43586040ea2fb9a6371365ae7Maurice Lam        if (VERSION.SDK_INT >= VERSION_CODES.N_MR1) {
221618a4449bb3e9be43586040ea2fb9a6371365ae7Maurice Lam            assertTrue(textView.isFocusableInTouchMode());
222618a4449bb3e9be43586040ea2fb9a6371365ae7Maurice Lam            assertFalse(textView.getRevealOnFocusHint());
223618a4449bb3e9be43586040ea2fb9a6371365ae7Maurice Lam        } else {
224618a4449bb3e9be43586040ea2fb9a6371365ae7Maurice Lam            assertFalse(textView.isFocusableInTouchMode());
225618a4449bb3e9be43586040ea2fb9a6371365ae7Maurice Lam        }
2269a3d23293ecf8b76b8c22e1381005751a88a458aAjay Nadathur    }
22751f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam
22851f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam    public static class TestContext extends ContextWrapper implements LinkSpan.OnClickListener {
22951f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam
23051f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam        public TestContext(Context base) {
23151f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam            super(base);
23251f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam        }
23351f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam
23451f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam        @Override
23551f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam        public void onClick(LinkSpan span) {
23651f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam            // Ignore. Can be verified using Mockito
23751f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam        }
23851f4609c813c2336bd12eaf7d6a719fd7f2fc5f2Maurice Lam    }
239d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam}
240