package org.edx.mobile.discussions;
import android.graphics.Typeface;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.style.ForegroundColorSpan;
import android.text.style.StyleSpan;
import android.view.View;
import android.widget.TextView;
import org.apache.commons.lang.time.DateUtils;
import org.edx.mobile.R;
import org.edx.mobile.discussion.DiscussionTextUtils;
import org.edx.mobile.discussion.IAuthorData;
import org.edx.mobile.test.BaseTestCase;
import org.edx.mobile.test.util.TimeUtilsForTests;
import org.edx.mobile.util.ResourceUtil;
import org.junit.Test;
import org.mockito.Mockito;
import java.util.Date;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
public class DiscussionTextUtilsTest extends BaseTestCase {
@Test
public void testSetAuthorAttributionText_AllCombinations() {
final TextView textView = new TextView(context);
// Input values
final String author = "author";
final String label = "label";
final Date creationDate = new Date(TimeUtilsForTests.DEFAULT_TIME);
// Expected output constructs
final long now = DateUtils.addDays(creationDate, 1).getTime(); // A day after the creationDate
final String relativeTime = "Yesterday";
final String outputAuthor = ResourceUtil.getFormattedString(context.getResources(),
R.string.discussion_post_author_attribution, "author", author).toString();
final String outputAuthorLbl = ResourceUtil.getFormattedString(context.getResources(),
R.string.discussion_post_author_label_attribution, "text", label).toString();
final String endorsePrefix = context.getString(R.string.discussion_post_endorsed);
final String answerPrefix = context.getString(R.string.discussion_post_marked_as_answer);
// For endorsed
assertSetAuthorAttributionText(textView,
DiscussionTextUtils.AuthorAttributionLabel.ENDORSEMENT,
new StubAuthorData(author, label, creationDate), now,
endorsePrefix + " " + relativeTime + " " + outputAuthor + " " + outputAuthorLbl);
assertSetAuthorAttributionText(textView,
DiscussionTextUtils.AuthorAttributionLabel.ENDORSEMENT,
new StubAuthorData(null, label, creationDate), now,
endorsePrefix + " " + relativeTime + " " + outputAuthorLbl);
assertSetAuthorAttributionText(textView,
DiscussionTextUtils.AuthorAttributionLabel.ENDORSEMENT,
new StubAuthorData(author, null, creationDate), now,
endorsePrefix + " " + relativeTime + " " + outputAuthor);
assertSetAuthorAttributionText(textView,
DiscussionTextUtils.AuthorAttributionLabel.ENDORSEMENT,
new StubAuthorData(author, label, null), now,
endorsePrefix + " " + outputAuthor + " " + outputAuthorLbl);
assertSetAuthorAttributionText(textView,
DiscussionTextUtils.AuthorAttributionLabel.ENDORSEMENT,
new StubAuthorData(null, null, creationDate), now,
endorsePrefix + " " + relativeTime);
assertSetAuthorAttributionText(textView,
DiscussionTextUtils.AuthorAttributionLabel.ENDORSEMENT,
new StubAuthorData(author, null, null), now,
endorsePrefix + " " + outputAuthor);
assertSetAuthorAttributionText(textView,
DiscussionTextUtils.AuthorAttributionLabel.ENDORSEMENT,
new StubAuthorData(null, label, null), now,
endorsePrefix + " " + outputAuthorLbl);
// For answer
assertSetAuthorAttributionText(textView,
DiscussionTextUtils.AuthorAttributionLabel.ANSWER,
new StubAuthorData(author, label, creationDate), now,
answerPrefix + " " + relativeTime + " " + outputAuthor + " " + outputAuthorLbl);
assertSetAuthorAttributionText(textView,
DiscussionTextUtils.AuthorAttributionLabel.ANSWER,
new StubAuthorData(null, label, creationDate), now,
answerPrefix + " " + relativeTime + " " + outputAuthorLbl);
assertSetAuthorAttributionText(textView,
DiscussionTextUtils.AuthorAttributionLabel.ANSWER,
new StubAuthorData(author, null, creationDate), now,
answerPrefix + " " + relativeTime + " " + outputAuthor);
assertSetAuthorAttributionText(textView,
DiscussionTextUtils.AuthorAttributionLabel.ANSWER,
new StubAuthorData(author, label, null), now,
answerPrefix + " " + outputAuthor + " " + outputAuthorLbl);
assertSetAuthorAttributionText(textView,
DiscussionTextUtils.AuthorAttributionLabel.ANSWER,
new StubAuthorData(null, null, creationDate), now,
answerPrefix + " " + relativeTime);
assertSetAuthorAttributionText(textView,
DiscussionTextUtils.AuthorAttributionLabel.ANSWER,
new StubAuthorData(author, null, null), now,
answerPrefix + " " + outputAuthor);
assertSetAuthorAttributionText(textView,
DiscussionTextUtils.AuthorAttributionLabel.ANSWER,
new StubAuthorData(null, label, null), now,
answerPrefix + " " + outputAuthorLbl);
// Empty Case
assertSetAuthorAttributionText(textView,
DiscussionTextUtils.AuthorAttributionLabel.ANSWER,
new StubAuthorData(null, null, null), now,
null);
}
private void assertSetAuthorAttributionText(TextView textView,
DiscussionTextUtils.AuthorAttributionLabel type,
IAuthorData input,
long now, String expectedOutput) {
final Runnable listener = Mockito.mock(Runnable.class);
DiscussionTextUtils.setAuthorAttributionText(textView, type, input, now, listener);
if (expectedOutput == null) {
assertTrue(textView.getVisibility() == View.GONE);
} else {
String output = textView.getText().toString();
assertEquals(expectedOutput, output);
if (!input.isAuthorAnonymous()) {
// Test whether author span is clickable or not
int start = output.indexOf(input.getAuthor());
int end = start + input.getAuthor().length();
Spanned text = (Spanned) textView.getText();
StyleSpan[] styleSpans = text.getSpans(start, end, StyleSpan.class);
ForegroundColorSpan[] colorSpans = text.getSpans(start, end, ForegroundColorSpan.class);
if (config.isUserProfilesEnabled()) {
// Verify that the author text is bold
assertEquals(1, styleSpans.length);
assertEquals(start, text.getSpanStart(styleSpans[0]));
assertEquals(end, text.getSpanEnd(styleSpans[0]));
assertEquals(Typeface.BOLD, styleSpans[0].getStyle());
// Verify that the correct foreground color is set
assertEquals(1, colorSpans.length);
assertEquals(start, text.getSpanStart(colorSpans[0]));
assertEquals(end, text.getSpanEnd(colorSpans[0]));
assertEquals(context.getResources().getColor(R.color.edx_brand_primary_base),
colorSpans[0].getForegroundColor());
// Verify that the whole text view is clickable
textView.performClick();
Mockito.verify(listener).run();
} else {
assertEquals(0, styleSpans.length);
assertEquals(0, colorSpans.length);
assertFalse(textView.isClickable());
}
}
}
}
@Test
public void testSetAuthor_AllCombinations() {
final TextView textView = new TextView(context);
// Input values
final String author = "author";
final String label = "label";
final Date creationDate = Mockito.mock(Date.class);
// Expected output constructs
final String outputAuthorLbl = ResourceUtil.getFormattedString(context.getResources(),
R.string.discussion_post_author_label_attribution, "text", label).toString();
assertSetAuthorText(textView,
new StubAuthorData(author, label, creationDate),
author + " " + outputAuthorLbl);
assertSetAuthorText(textView,
new StubAuthorData(author, null, creationDate),
author);
assertSetAuthorText(textView,
new StubAuthorData(null, label, creationDate),
outputAuthorLbl);
assertSetAuthorText(textView,
new StubAuthorData(null, null, creationDate),
outputAuthorLbl);
}
private void assertSetAuthorText(TextView textView, IAuthorData input,
String expectedOutput) {
DiscussionTextUtils.setAuthorText(textView, input);
if (expectedOutput == null) {
assertTrue(textView.getVisibility() == View.GONE);
} else {
String output = textView.getText().toString();
assertEquals(expectedOutput, output);
if (!input.isAuthorAnonymous()) {
int start = output.indexOf(input.getAuthor());
int end = start + input.getAuthor().length();
Spanned text = (Spanned) textView.getText();
StyleSpan[] styleSpans = text.getSpans(start, end, StyleSpan.class);
ForegroundColorSpan[] colorSpans = text.getSpans(start, end, ForegroundColorSpan.class);
// Verify that the author text is bold
assertEquals(1, styleSpans.length);
assertEquals(start, text.getSpanStart(styleSpans[0]));
assertEquals(end, text.getSpanEnd(styleSpans[0]));
assertEquals(Typeface.BOLD, styleSpans[0].getStyle());
// Verify that the correct foreground color is set
assertEquals(1, colorSpans.length);
assertEquals(start, text.getSpanStart(colorSpans[0]));
assertEquals(end, text.getSpanEnd(colorSpans[0]));
assertEquals(context.getResources().getColor(R.color.edx_brand_primary_base),
colorSpans[0].getForegroundColor());
}
}
}
private static class StubAuthorData implements IAuthorData {
private final String author, authorLabel;
private final Date createdDate;
public StubAuthorData(String author, String authorLabel, Date createdDate) {
this.author = author;
this.authorLabel = authorLabel;
this.createdDate = createdDate;
}
@Override
public String getAuthor() {
return author;
}
@Override
public String getAuthorLabel() {
return authorLabel;
}
@Override
public Date getCreatedAt() {
return createdDate;
}
@Override
public boolean isAuthorAnonymous() {
return TextUtils.isEmpty(author);
}
}
}