Loading src/com/android/contacts/detail/ContactDetailDisplayUtils.java +9 −28 Original line number Original line Diff line number Diff line Loading @@ -249,36 +249,15 @@ public class ContactDetailDisplayUtils { } } } } /** /** Creates the view that represents a stream item. */ * Displays the social stream items under the given layout. public static View createStreamItemView(LayoutInflater inflater, Context context, */ StreamItemEntry streamItem, LinearLayout parent) { public static void showSocialStreamItems(LayoutInflater inflater, Context context, Result contactData, LinearLayout streamContainer, View.OnClickListener listener) { if (streamContainer != null) { streamContainer.removeAllViews(); List<StreamItemEntry> streamItems = contactData.getStreamItems(); for (StreamItemEntry streamItem : streamItems) { addStreamItemToContainer(inflater, context, streamItem, streamContainer, listener); } } } public static View addStreamItemToContainer(LayoutInflater inflater, Context context, StreamItemEntry streamItem, LinearLayout streamContainer, View.OnClickListener listener) { View oneColumnView = inflater.inflate(R.layout.stream_item_one_column, View oneColumnView = inflater.inflate(R.layout.stream_item_one_column, streamContainer, false); parent, false); ViewGroup contentBox = (ViewGroup) oneColumnView.findViewById(R.id.stream_item_content); ViewGroup contentBox = (ViewGroup) oneColumnView.findViewById(R.id.stream_item_content); int internalPadding = context.getResources().getDimensionPixelSize( int internalPadding = context.getResources().getDimensionPixelSize( R.dimen.detail_update_section_internal_padding); R.dimen.detail_update_section_internal_padding); // Add the listener only if there is an action and corresponding URI. if (streamItem.getAction() != null && streamItem.getActionUri() != null) { contentBox.setTag(streamItem); contentBox.setOnClickListener(listener); contentBox.setFocusable(true); } // TODO: This is not the correct layout for a stream item with photos. Photos should be // TODO: This is not the correct layout for a stream item with photos. Photos should be // displayed first, then the update text either to the right of the final image (if there // displayed first, then the update text either to the right of the final image (if there // are an odd number of images) or below the last row of images (if there are an even // are an odd number of images) or below the last row of images (if there are an even Loading Loading @@ -335,8 +314,8 @@ public class ContactDetailDisplayUtils { } } } } if (streamContainer != null) { if (parent != null) { streamContainer.addView(oneColumnView); parent.addView(oneColumnView); } } return oneColumnView; return oneColumnView; Loading @@ -358,7 +337,9 @@ public class ContactDetailDisplayUtils { } else { } else { commentsView.setVisibility(View.GONE); commentsView.setVisibility(View.GONE); } } if (parent != null) { parent.addView(textUpdate); parent.addView(textUpdate); } return textUpdate; return textUpdate; } } Loading src/com/android/contacts/detail/ContactDetailUpdatesFragment.java +19 −4 Original line number Original line Diff line number Diff line Loading @@ -66,16 +66,31 @@ public class ContactDetailUpdatesFragment extends ListFragment @Override @Override public void onClick(View view) { public void onClick(View view) { StreamItemEntry streamItemEntry = (StreamItemEntry) view.getTag(); StreamItemEntry streamItemEntry = (StreamItemEntry) view.getTag(); if (streamItemEntry == null) { // Ignore if this item does not have a stream item associated with it. return; } String actionUri = streamItemEntry.getActionUri(); if (actionUri == null) { // Ignore if this item does not have a URI. return; } // Parse the URI. Uri uri; Uri uri; try { try { uri = Uri.parse(streamItemEntry.getActionUri()); uri = Uri.parse(actionUri); } catch (Throwable throwable) { } catch (Throwable throwable) { // This may fail if the URI is invalid: instead of failing, just ignore it. Log.e(TAG, "invalid URI for stream item #" + streamItemEntry.getId() + ": " Log.e(TAG, "invalid URI for stream item #" + streamItemEntry.getId() + ": " + streamItemEntry.getActionUri()); + actionUri); return; } String action = streamItemEntry.getAction(); if (action == null) { // Ignore if this item does not have an action. return; return; } } Intent streamItemIntent = new Intent(streamItemEntry.getAction(), uri); startActivity(new Intent(action, uri)); startActivity(streamItemIntent); } } }; }; Loading src/com/android/contacts/detail/StreamItemAdapter.java +13 −2 Original line number Original line Diff line number Diff line Loading @@ -74,8 +74,19 @@ public class StreamItemAdapter extends BaseAdapter { if (position == 0) { if (position == 0) { return mInflater.inflate(R.layout.updates_header_contact, null); return mInflater.inflate(R.layout.updates_header_contact, null); } } return ContactDetailDisplayUtils.addStreamItemToContainer( StreamItemEntry streamItem = (StreamItemEntry) getItem(position); mInflater, mContext, (StreamItemEntry) getItem(position), null, mListener); View view = ContactDetailDisplayUtils.createStreamItemView( mInflater, mContext, streamItem, null); if (streamItem.getAction() != null && streamItem.getActionUri() != null) { view.setTag(streamItem); view.setFocusable(true); view.setOnClickListener(mListener); } else { view.setTag(null); view.setFocusable(false); view.setOnClickListener(null); } return view; } } @Override @Override Loading tests/src/com/android/contacts/detail/ContactDetailDisplayUtilsTest.java +2 −143 Original line number Original line Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.contacts.detail; import com.android.contacts.R; import com.android.contacts.R; import com.android.contacts.util.StreamItemEntry; import com.android.contacts.util.StreamItemEntry; import com.android.contacts.util.StreamItemEntryBuilder; import android.content.Context; import android.content.Context; import android.test.AndroidTestCase; import android.test.AndroidTestCase; Loading @@ -27,7 +28,6 @@ import android.text.Spanned; import android.view.LayoutInflater; import android.view.LayoutInflater; import android.view.View; import android.view.View; import android.view.ViewGroup; import android.view.ViewGroup; import android.widget.LinearLayout; import android.widget.TextView; import android.widget.TextView; /** /** Loading @@ -37,14 +37,11 @@ import android.widget.TextView; public class ContactDetailDisplayUtilsTest extends AndroidTestCase { public class ContactDetailDisplayUtilsTest extends AndroidTestCase { private static final String TEST_STREAM_ITEM_TEXT = "text"; private static final String TEST_STREAM_ITEM_TEXT = "text"; private LinearLayout mParent; private LayoutInflater mLayoutInflater; private LayoutInflater mLayoutInflater; private FakeOnClickListener mListener = new FakeOnClickListener(); @Override @Override protected void setUp() throws Exception { protected void setUp() throws Exception { super.setUp(); super.setUp(); mParent = new LinearLayout(getContext()); mLayoutInflater = mLayoutInflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); } } Loading Loading @@ -72,81 +69,6 @@ public class ContactDetailDisplayUtilsTest extends AndroidTestCase { assertGone(streamItemView, R.id.stream_item_comments); assertGone(streamItemView, R.id.stream_item_comments); } } public void testAddStreamItemToContainer_NoAction() { StreamItemEntry streamItem = getTestBuilder() .setAction(null) .setActionUri(null) .build(); addStreamItemToContainer(streamItem, mListener); assertStreamItemNotClickable(); } public void testAddStreamItemToContainer_WithActionButNoActionUri() { StreamItemEntry streamItem = getTestBuilder() .setAction("action") .setActionUri(null) .build(); addStreamItemToContainer(streamItem, mListener); assertStreamItemNotClickable(); } public void testAddStreamItemToContainer_WithActionUriButNoAction() { StreamItemEntry streamItem = getTestBuilder() .setAction(null) .setActionUri("http://www.google.com") .build(); addStreamItemToContainer(streamItem, mListener); assertStreamItemNotClickable(); } public void testAddStreamItemToContainer_WithActionAndActionUri() { StreamItemEntry streamItem = getTestBuilder() .setAction("action") .setActionUri("http://www.google.com") .build(); addStreamItemToContainer(streamItem, mListener); assertStreamItemClickable(); assertStreamItemHasOnClickListener(); assertStreamItemHasTag(streamItem); } /** Checks that the stream item view is clickable. */ private void assertStreamItemClickable() { View streamItemView = mParent.findViewById(R.id.stream_item_content); assertNotNull("should have a stream item", streamItemView); assertTrue("should be clickable", streamItemView.isClickable()); assertTrue("should be focusable", streamItemView.isFocusable()); } /** Asserts that there is a stream item but it is not clickable. */ private void assertStreamItemNotClickable() { View streamItemView = mParent.findViewById(R.id.stream_item_content); assertNotNull("should have a stream item", streamItemView); assertFalse("should not be clickable", streamItemView.isClickable()); assertFalse("should not be focusable", streamItemView.isFocusable()); } /** Checks that the stream item view has a click listener. */ private void assertStreamItemHasOnClickListener() { // Check that the on-click listener is invoked when clicked. View streamItemView = mParent.findViewById(R.id.stream_item_content); assertFalse("listener should have not been invoked yet", mListener.clicked); streamItemView.performClick(); assertTrue("listener should have been invoked", mListener.clicked); } /** Checks that the stream item view has the given stream item as its tag. */ private void assertStreamItemHasTag(StreamItemEntry streamItem) { // The view's tag should point to the stream item entry for this view. View streamItemView = mParent.findViewById(R.id.stream_item_content); Object tag = streamItemView.getTag(); assertNotNull("should have a tag", tag); assertTrue("should be a StreamItemEntry", tag instanceof StreamItemEntry); StreamItemEntry streamItemTag = (StreamItemEntry) tag; // The streamItem itself should be in the tag. assertSame(streamItem, streamItemTag); } /** Checks that the given id corresponds to a visible text view with the expected text. */ /** Checks that the given id corresponds to a visible text view with the expected text. */ private void assertHasText(View parent, int textViewId, String expectedText) { private void assertHasText(View parent, int textViewId, String expectedText) { TextView textView = (TextView) parent.findViewById(textViewId); TextView textView = (TextView) parent.findViewById(textViewId); Loading Loading @@ -187,70 +109,7 @@ public class ContactDetailDisplayUtilsTest extends AndroidTestCase { */ */ private View addStreamItemText(StreamItemEntry streamItem) { private View addStreamItemText(StreamItemEntry streamItem) { return ContactDetailDisplayUtils.addStreamItemText( return ContactDetailDisplayUtils.addStreamItemText( mLayoutInflater, getContext(), streamItem, mParent); mLayoutInflater, getContext(), streamItem, null); } /** * Calls {@link ContactDetailDisplayUtils#addStreamItemToContainer(LayoutInflater, * Context,StreamItemEntry, LinearLayout, android.view.View.OnClickListener)} with the default * parameters and the given stream item and listener. */ private void addStreamItemToContainer(StreamItemEntry streamItem, View.OnClickListener listener) { ContactDetailDisplayUtils.addStreamItemToContainer(mLayoutInflater, getContext(), streamItem, mParent, listener); } /** * Simple fake implementation of {@link View.OnClickListener} which sets a member variable to * true when clicked. */ private final class FakeOnClickListener implements View.OnClickListener { public boolean clicked = false; @Override public void onClick(View view) { clicked = true; } } private static class StreamItemEntryBuilder { private long mId; private String mText; private String mComment; private long mTimestamp; private String mAction; private String mActionUri; private String mResPackage; private int mIconRes; private int mLabelRes; public StreamItemEntryBuilder() {} public StreamItemEntryBuilder setText(String text) { mText = text; return this; } public StreamItemEntryBuilder setComment(String comment) { mComment = comment; return this; } public StreamItemEntryBuilder setAction(String action) { mAction = action; return this; } public StreamItemEntryBuilder setActionUri(String actionUri) { mActionUri = actionUri; return this; } public StreamItemEntry build() { return new StreamItemEntry(mId, mText, mComment, mTimestamp, mAction, mActionUri, mResPackage, mIconRes, mLabelRes); } } } private StreamItemEntryBuilder getTestBuilder() { private StreamItemEntryBuilder getTestBuilder() { Loading tests/src/com/android/contacts/detail/StreamItemAdapterTest.java 0 → 100644 +173 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2011 The Android Open Source Project * * 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.android.contacts.detail; import com.android.contacts.util.StreamItemEntry; import com.android.contacts.util.StreamItemEntryBuilder; import com.google.common.collect.Lists; import android.content.Intent; import android.test.AndroidTestCase; import android.view.View; import java.util.ArrayList; /** * Unit tests for {@link StreamItemAdapter}. */ public class StreamItemAdapterTest extends AndroidTestCase { private StreamItemAdapter mAdapter; private FakeOnClickListener mListener; private View mView; @Override protected void setUp() throws Exception { super.setUp(); mListener = new FakeOnClickListener(); mAdapter = new StreamItemAdapter(getContext(), mListener); } @Override protected void tearDown() throws Exception { mAdapter = null; mListener = null; super.tearDown(); } public void testGetCount_Empty() { mAdapter.setStreamItems(createStreamItemList(0)); // There is actually one view: the header. assertEquals(1, mAdapter.getCount()); } public void testGetCount_NonEmpty() { mAdapter.setStreamItems(createStreamItemList(3)); // There is one extra view: the header. assertEquals(4, mAdapter.getCount()); } public void testGetView_WithAction() { StreamItemEntry streamItem = createStreamItemWithAction(); mAdapter.setStreamItems(Lists.newArrayList(streamItem)); mView = mAdapter.getView(1, null, null); assertStreamItemViewHasTag(streamItem); assertStreamItemViewHasOnClickListener(); assertStreamItemViewFocusable(); } public void testGetView_WithoutAction() { mAdapter.setStreamItems(Lists.newArrayList(createStreamItemWithoutAction())); mView = mAdapter.getView(1, null, null); assertStreamItemViewHasNoTag(); assertStreamItemViewHasNoOnClickListener(); assertStreamItemViewNotFocusable(); } public void testGetView_Header() { // Just check that we can inflate it correctly. mView = mAdapter.getView(0, null, null); } /** Counter used by {@link #createStreamItemEntryBuilder()} to create unique builders. */ private int mCreateStreamItemEntryBuilderCounter = 0; /** Returns a stream item builder with basic information in it. */ private StreamItemEntryBuilder createStreamItemEntryBuilder() { return new StreamItemEntryBuilder().setText( "text #" + mCreateStreamItemEntryBuilderCounter++); } /** Returns a stream item with an action and action URI set. */ private StreamItemEntry createStreamItemWithAction() { return createStreamItemEntryBuilder() .setAction(Intent.ACTION_VIEW) .setActionUri("http://www.google.com") .build(); } /** Returns a stream item without an action and action URI set. */ private StreamItemEntry createStreamItemWithoutAction() { return createStreamItemEntryBuilder() .setAction(null) .setActionUri(null) .build(); } /** Creates a list containing the given number of {@link StreamItemEntry}s. */ private ArrayList<StreamItemEntry> createStreamItemList(int count) { ArrayList<StreamItemEntry> list = Lists.newArrayList(); for (int index = 0; index < count; ++index) { list.add(createStreamItemEntryBuilder().build()); } return list; } /** Checks that the stream item view has a click listener. */ private void assertStreamItemViewHasOnClickListener() { assertFalse("listener should have not been invoked yet", mListener.clicked); mView.performClick(); assertTrue("listener should have been invoked", mListener.clicked); } /** Checks that the stream item view does not have a click listener. */ private void assertStreamItemViewHasNoOnClickListener() { assertFalse("listener should have not been invoked yet", mListener.clicked); mView.performClick(); assertFalse("listener should have not been invoked", mListener.clicked); } /** Checks that the stream item view is clickable. */ private void assertStreamItemViewFocusable() { assertNotNull("should have a stream item", mView); assertTrue("should be focusable", mView.isFocusable()); } /** Asserts that there is a stream item but it is not clickable. */ private void assertStreamItemViewNotFocusable() { assertNotNull("should have a stream item", mView); assertFalse("should not be focusable", mView.isFocusable()); } /** Checks that the stream item view has the given stream item as its tag. */ private void assertStreamItemViewHasTag(StreamItemEntry streamItem) { Object tag = mView.getTag(); assertNotNull("should have a tag", tag); assertTrue("should be a StreamItemEntry", tag instanceof StreamItemEntry); StreamItemEntry streamItemTag = (StreamItemEntry) tag; // The streamItem itself should be in the tag. assertSame(streamItem, streamItemTag); } /** Checks that the stream item view has the given stream item as its tag. */ private void assertStreamItemViewHasNoTag() { Object tag = mView.getTag(); assertNull("should not have a tag", tag); } /** * Simple fake implementation of {@link View.OnClickListener} which sets a member variable to * true when clicked. */ private final class FakeOnClickListener implements View.OnClickListener { public boolean clicked = false; @Override public void onClick(View view) { clicked = true; } } } Loading
src/com/android/contacts/detail/ContactDetailDisplayUtils.java +9 −28 Original line number Original line Diff line number Diff line Loading @@ -249,36 +249,15 @@ public class ContactDetailDisplayUtils { } } } } /** /** Creates the view that represents a stream item. */ * Displays the social stream items under the given layout. public static View createStreamItemView(LayoutInflater inflater, Context context, */ StreamItemEntry streamItem, LinearLayout parent) { public static void showSocialStreamItems(LayoutInflater inflater, Context context, Result contactData, LinearLayout streamContainer, View.OnClickListener listener) { if (streamContainer != null) { streamContainer.removeAllViews(); List<StreamItemEntry> streamItems = contactData.getStreamItems(); for (StreamItemEntry streamItem : streamItems) { addStreamItemToContainer(inflater, context, streamItem, streamContainer, listener); } } } public static View addStreamItemToContainer(LayoutInflater inflater, Context context, StreamItemEntry streamItem, LinearLayout streamContainer, View.OnClickListener listener) { View oneColumnView = inflater.inflate(R.layout.stream_item_one_column, View oneColumnView = inflater.inflate(R.layout.stream_item_one_column, streamContainer, false); parent, false); ViewGroup contentBox = (ViewGroup) oneColumnView.findViewById(R.id.stream_item_content); ViewGroup contentBox = (ViewGroup) oneColumnView.findViewById(R.id.stream_item_content); int internalPadding = context.getResources().getDimensionPixelSize( int internalPadding = context.getResources().getDimensionPixelSize( R.dimen.detail_update_section_internal_padding); R.dimen.detail_update_section_internal_padding); // Add the listener only if there is an action and corresponding URI. if (streamItem.getAction() != null && streamItem.getActionUri() != null) { contentBox.setTag(streamItem); contentBox.setOnClickListener(listener); contentBox.setFocusable(true); } // TODO: This is not the correct layout for a stream item with photos. Photos should be // TODO: This is not the correct layout for a stream item with photos. Photos should be // displayed first, then the update text either to the right of the final image (if there // displayed first, then the update text either to the right of the final image (if there // are an odd number of images) or below the last row of images (if there are an even // are an odd number of images) or below the last row of images (if there are an even Loading Loading @@ -335,8 +314,8 @@ public class ContactDetailDisplayUtils { } } } } if (streamContainer != null) { if (parent != null) { streamContainer.addView(oneColumnView); parent.addView(oneColumnView); } } return oneColumnView; return oneColumnView; Loading @@ -358,7 +337,9 @@ public class ContactDetailDisplayUtils { } else { } else { commentsView.setVisibility(View.GONE); commentsView.setVisibility(View.GONE); } } if (parent != null) { parent.addView(textUpdate); parent.addView(textUpdate); } return textUpdate; return textUpdate; } } Loading
src/com/android/contacts/detail/ContactDetailUpdatesFragment.java +19 −4 Original line number Original line Diff line number Diff line Loading @@ -66,16 +66,31 @@ public class ContactDetailUpdatesFragment extends ListFragment @Override @Override public void onClick(View view) { public void onClick(View view) { StreamItemEntry streamItemEntry = (StreamItemEntry) view.getTag(); StreamItemEntry streamItemEntry = (StreamItemEntry) view.getTag(); if (streamItemEntry == null) { // Ignore if this item does not have a stream item associated with it. return; } String actionUri = streamItemEntry.getActionUri(); if (actionUri == null) { // Ignore if this item does not have a URI. return; } // Parse the URI. Uri uri; Uri uri; try { try { uri = Uri.parse(streamItemEntry.getActionUri()); uri = Uri.parse(actionUri); } catch (Throwable throwable) { } catch (Throwable throwable) { // This may fail if the URI is invalid: instead of failing, just ignore it. Log.e(TAG, "invalid URI for stream item #" + streamItemEntry.getId() + ": " Log.e(TAG, "invalid URI for stream item #" + streamItemEntry.getId() + ": " + streamItemEntry.getActionUri()); + actionUri); return; } String action = streamItemEntry.getAction(); if (action == null) { // Ignore if this item does not have an action. return; return; } } Intent streamItemIntent = new Intent(streamItemEntry.getAction(), uri); startActivity(new Intent(action, uri)); startActivity(streamItemIntent); } } }; }; Loading
src/com/android/contacts/detail/StreamItemAdapter.java +13 −2 Original line number Original line Diff line number Diff line Loading @@ -74,8 +74,19 @@ public class StreamItemAdapter extends BaseAdapter { if (position == 0) { if (position == 0) { return mInflater.inflate(R.layout.updates_header_contact, null); return mInflater.inflate(R.layout.updates_header_contact, null); } } return ContactDetailDisplayUtils.addStreamItemToContainer( StreamItemEntry streamItem = (StreamItemEntry) getItem(position); mInflater, mContext, (StreamItemEntry) getItem(position), null, mListener); View view = ContactDetailDisplayUtils.createStreamItemView( mInflater, mContext, streamItem, null); if (streamItem.getAction() != null && streamItem.getActionUri() != null) { view.setTag(streamItem); view.setFocusable(true); view.setOnClickListener(mListener); } else { view.setTag(null); view.setFocusable(false); view.setOnClickListener(null); } return view; } } @Override @Override Loading
tests/src/com/android/contacts/detail/ContactDetailDisplayUtilsTest.java +2 −143 Original line number Original line Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.contacts.detail; import com.android.contacts.R; import com.android.contacts.R; import com.android.contacts.util.StreamItemEntry; import com.android.contacts.util.StreamItemEntry; import com.android.contacts.util.StreamItemEntryBuilder; import android.content.Context; import android.content.Context; import android.test.AndroidTestCase; import android.test.AndroidTestCase; Loading @@ -27,7 +28,6 @@ import android.text.Spanned; import android.view.LayoutInflater; import android.view.LayoutInflater; import android.view.View; import android.view.View; import android.view.ViewGroup; import android.view.ViewGroup; import android.widget.LinearLayout; import android.widget.TextView; import android.widget.TextView; /** /** Loading @@ -37,14 +37,11 @@ import android.widget.TextView; public class ContactDetailDisplayUtilsTest extends AndroidTestCase { public class ContactDetailDisplayUtilsTest extends AndroidTestCase { private static final String TEST_STREAM_ITEM_TEXT = "text"; private static final String TEST_STREAM_ITEM_TEXT = "text"; private LinearLayout mParent; private LayoutInflater mLayoutInflater; private LayoutInflater mLayoutInflater; private FakeOnClickListener mListener = new FakeOnClickListener(); @Override @Override protected void setUp() throws Exception { protected void setUp() throws Exception { super.setUp(); super.setUp(); mParent = new LinearLayout(getContext()); mLayoutInflater = mLayoutInflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); } } Loading Loading @@ -72,81 +69,6 @@ public class ContactDetailDisplayUtilsTest extends AndroidTestCase { assertGone(streamItemView, R.id.stream_item_comments); assertGone(streamItemView, R.id.stream_item_comments); } } public void testAddStreamItemToContainer_NoAction() { StreamItemEntry streamItem = getTestBuilder() .setAction(null) .setActionUri(null) .build(); addStreamItemToContainer(streamItem, mListener); assertStreamItemNotClickable(); } public void testAddStreamItemToContainer_WithActionButNoActionUri() { StreamItemEntry streamItem = getTestBuilder() .setAction("action") .setActionUri(null) .build(); addStreamItemToContainer(streamItem, mListener); assertStreamItemNotClickable(); } public void testAddStreamItemToContainer_WithActionUriButNoAction() { StreamItemEntry streamItem = getTestBuilder() .setAction(null) .setActionUri("http://www.google.com") .build(); addStreamItemToContainer(streamItem, mListener); assertStreamItemNotClickable(); } public void testAddStreamItemToContainer_WithActionAndActionUri() { StreamItemEntry streamItem = getTestBuilder() .setAction("action") .setActionUri("http://www.google.com") .build(); addStreamItemToContainer(streamItem, mListener); assertStreamItemClickable(); assertStreamItemHasOnClickListener(); assertStreamItemHasTag(streamItem); } /** Checks that the stream item view is clickable. */ private void assertStreamItemClickable() { View streamItemView = mParent.findViewById(R.id.stream_item_content); assertNotNull("should have a stream item", streamItemView); assertTrue("should be clickable", streamItemView.isClickable()); assertTrue("should be focusable", streamItemView.isFocusable()); } /** Asserts that there is a stream item but it is not clickable. */ private void assertStreamItemNotClickable() { View streamItemView = mParent.findViewById(R.id.stream_item_content); assertNotNull("should have a stream item", streamItemView); assertFalse("should not be clickable", streamItemView.isClickable()); assertFalse("should not be focusable", streamItemView.isFocusable()); } /** Checks that the stream item view has a click listener. */ private void assertStreamItemHasOnClickListener() { // Check that the on-click listener is invoked when clicked. View streamItemView = mParent.findViewById(R.id.stream_item_content); assertFalse("listener should have not been invoked yet", mListener.clicked); streamItemView.performClick(); assertTrue("listener should have been invoked", mListener.clicked); } /** Checks that the stream item view has the given stream item as its tag. */ private void assertStreamItemHasTag(StreamItemEntry streamItem) { // The view's tag should point to the stream item entry for this view. View streamItemView = mParent.findViewById(R.id.stream_item_content); Object tag = streamItemView.getTag(); assertNotNull("should have a tag", tag); assertTrue("should be a StreamItemEntry", tag instanceof StreamItemEntry); StreamItemEntry streamItemTag = (StreamItemEntry) tag; // The streamItem itself should be in the tag. assertSame(streamItem, streamItemTag); } /** Checks that the given id corresponds to a visible text view with the expected text. */ /** Checks that the given id corresponds to a visible text view with the expected text. */ private void assertHasText(View parent, int textViewId, String expectedText) { private void assertHasText(View parent, int textViewId, String expectedText) { TextView textView = (TextView) parent.findViewById(textViewId); TextView textView = (TextView) parent.findViewById(textViewId); Loading Loading @@ -187,70 +109,7 @@ public class ContactDetailDisplayUtilsTest extends AndroidTestCase { */ */ private View addStreamItemText(StreamItemEntry streamItem) { private View addStreamItemText(StreamItemEntry streamItem) { return ContactDetailDisplayUtils.addStreamItemText( return ContactDetailDisplayUtils.addStreamItemText( mLayoutInflater, getContext(), streamItem, mParent); mLayoutInflater, getContext(), streamItem, null); } /** * Calls {@link ContactDetailDisplayUtils#addStreamItemToContainer(LayoutInflater, * Context,StreamItemEntry, LinearLayout, android.view.View.OnClickListener)} with the default * parameters and the given stream item and listener. */ private void addStreamItemToContainer(StreamItemEntry streamItem, View.OnClickListener listener) { ContactDetailDisplayUtils.addStreamItemToContainer(mLayoutInflater, getContext(), streamItem, mParent, listener); } /** * Simple fake implementation of {@link View.OnClickListener} which sets a member variable to * true when clicked. */ private final class FakeOnClickListener implements View.OnClickListener { public boolean clicked = false; @Override public void onClick(View view) { clicked = true; } } private static class StreamItemEntryBuilder { private long mId; private String mText; private String mComment; private long mTimestamp; private String mAction; private String mActionUri; private String mResPackage; private int mIconRes; private int mLabelRes; public StreamItemEntryBuilder() {} public StreamItemEntryBuilder setText(String text) { mText = text; return this; } public StreamItemEntryBuilder setComment(String comment) { mComment = comment; return this; } public StreamItemEntryBuilder setAction(String action) { mAction = action; return this; } public StreamItemEntryBuilder setActionUri(String actionUri) { mActionUri = actionUri; return this; } public StreamItemEntry build() { return new StreamItemEntry(mId, mText, mComment, mTimestamp, mAction, mActionUri, mResPackage, mIconRes, mLabelRes); } } } private StreamItemEntryBuilder getTestBuilder() { private StreamItemEntryBuilder getTestBuilder() { Loading
tests/src/com/android/contacts/detail/StreamItemAdapterTest.java 0 → 100644 +173 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2011 The Android Open Source Project * * 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.android.contacts.detail; import com.android.contacts.util.StreamItemEntry; import com.android.contacts.util.StreamItemEntryBuilder; import com.google.common.collect.Lists; import android.content.Intent; import android.test.AndroidTestCase; import android.view.View; import java.util.ArrayList; /** * Unit tests for {@link StreamItemAdapter}. */ public class StreamItemAdapterTest extends AndroidTestCase { private StreamItemAdapter mAdapter; private FakeOnClickListener mListener; private View mView; @Override protected void setUp() throws Exception { super.setUp(); mListener = new FakeOnClickListener(); mAdapter = new StreamItemAdapter(getContext(), mListener); } @Override protected void tearDown() throws Exception { mAdapter = null; mListener = null; super.tearDown(); } public void testGetCount_Empty() { mAdapter.setStreamItems(createStreamItemList(0)); // There is actually one view: the header. assertEquals(1, mAdapter.getCount()); } public void testGetCount_NonEmpty() { mAdapter.setStreamItems(createStreamItemList(3)); // There is one extra view: the header. assertEquals(4, mAdapter.getCount()); } public void testGetView_WithAction() { StreamItemEntry streamItem = createStreamItemWithAction(); mAdapter.setStreamItems(Lists.newArrayList(streamItem)); mView = mAdapter.getView(1, null, null); assertStreamItemViewHasTag(streamItem); assertStreamItemViewHasOnClickListener(); assertStreamItemViewFocusable(); } public void testGetView_WithoutAction() { mAdapter.setStreamItems(Lists.newArrayList(createStreamItemWithoutAction())); mView = mAdapter.getView(1, null, null); assertStreamItemViewHasNoTag(); assertStreamItemViewHasNoOnClickListener(); assertStreamItemViewNotFocusable(); } public void testGetView_Header() { // Just check that we can inflate it correctly. mView = mAdapter.getView(0, null, null); } /** Counter used by {@link #createStreamItemEntryBuilder()} to create unique builders. */ private int mCreateStreamItemEntryBuilderCounter = 0; /** Returns a stream item builder with basic information in it. */ private StreamItemEntryBuilder createStreamItemEntryBuilder() { return new StreamItemEntryBuilder().setText( "text #" + mCreateStreamItemEntryBuilderCounter++); } /** Returns a stream item with an action and action URI set. */ private StreamItemEntry createStreamItemWithAction() { return createStreamItemEntryBuilder() .setAction(Intent.ACTION_VIEW) .setActionUri("http://www.google.com") .build(); } /** Returns a stream item without an action and action URI set. */ private StreamItemEntry createStreamItemWithoutAction() { return createStreamItemEntryBuilder() .setAction(null) .setActionUri(null) .build(); } /** Creates a list containing the given number of {@link StreamItemEntry}s. */ private ArrayList<StreamItemEntry> createStreamItemList(int count) { ArrayList<StreamItemEntry> list = Lists.newArrayList(); for (int index = 0; index < count; ++index) { list.add(createStreamItemEntryBuilder().build()); } return list; } /** Checks that the stream item view has a click listener. */ private void assertStreamItemViewHasOnClickListener() { assertFalse("listener should have not been invoked yet", mListener.clicked); mView.performClick(); assertTrue("listener should have been invoked", mListener.clicked); } /** Checks that the stream item view does not have a click listener. */ private void assertStreamItemViewHasNoOnClickListener() { assertFalse("listener should have not been invoked yet", mListener.clicked); mView.performClick(); assertFalse("listener should have not been invoked", mListener.clicked); } /** Checks that the stream item view is clickable. */ private void assertStreamItemViewFocusable() { assertNotNull("should have a stream item", mView); assertTrue("should be focusable", mView.isFocusable()); } /** Asserts that there is a stream item but it is not clickable. */ private void assertStreamItemViewNotFocusable() { assertNotNull("should have a stream item", mView); assertFalse("should not be focusable", mView.isFocusable()); } /** Checks that the stream item view has the given stream item as its tag. */ private void assertStreamItemViewHasTag(StreamItemEntry streamItem) { Object tag = mView.getTag(); assertNotNull("should have a tag", tag); assertTrue("should be a StreamItemEntry", tag instanceof StreamItemEntry); StreamItemEntry streamItemTag = (StreamItemEntry) tag; // The streamItem itself should be in the tag. assertSame(streamItem, streamItemTag); } /** Checks that the stream item view has the given stream item as its tag. */ private void assertStreamItemViewHasNoTag() { Object tag = mView.getTag(); assertNull("should not have a tag", tag); } /** * Simple fake implementation of {@link View.OnClickListener} which sets a member variable to * true when clicked. */ private final class FakeOnClickListener implements View.OnClickListener { public boolean clicked = false; @Override public void onClick(View view) { clicked = true; } } }