From 68f34152dce790e7000b37ae50aa7bc93d96e48f Mon Sep 17 00:00:00 2001
From: Konrad Pozniak
Date: Thu, 2 Apr 2020 23:37:38 +0200
Subject: [PATCH] replace HtmlUtils with HtmlCompat (#1741)
* replace HtmlUtils with HtmlCompat
* fix tests
---
.../tusky/adapter/StatusBaseViewHolder.java | 6 +--
.../com/keylesspalace/tusky/db/Converters.kt | 7 +--
.../com/keylesspalace/tusky/di/AppModule.kt | 7 ---
.../tusky/di/RepositoryModule.kt | 13 ++---
.../com/keylesspalace/tusky/entity/Account.kt | 33 +++---------
.../com/keylesspalace/tusky/entity/Card.kt | 10 ++--
.../tusky/json/SpannedTypeAdapter.java | 17 ++++--
.../tusky/repository/TimelineRepository.kt | 17 +++---
.../keylesspalace/tusky/util/HtmlConverter.kt | 22 --------
.../keylesspalace/tusky/util/HtmlUtils.java | 52 -------------------
.../tusky/util/StatusViewHelper.kt | 5 +-
.../tusky/viewdata/PollViewData.kt | 4 +-
.../tusky/fragment/TimelineRepositoryTest.kt | 37 ++++++-------
13 files changed, 65 insertions(+), 165 deletions(-)
delete mode 100644 app/src/main/java/com/keylesspalace/tusky/util/HtmlConverter.kt
delete mode 100644 app/src/main/java/com/keylesspalace/tusky/util/HtmlUtils.java
diff --git a/app/src/main/java/com/keylesspalace/tusky/adapter/StatusBaseViewHolder.java b/app/src/main/java/com/keylesspalace/tusky/adapter/StatusBaseViewHolder.java
index 71156967b..f808cb1bb 100644
--- a/app/src/main/java/com/keylesspalace/tusky/adapter/StatusBaseViewHolder.java
+++ b/app/src/main/java/com/keylesspalace/tusky/adapter/StatusBaseViewHolder.java
@@ -20,6 +20,7 @@ import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
+import androidx.core.text.HtmlCompat;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
@@ -38,7 +39,6 @@ import com.keylesspalace.tusky.entity.Status;
import com.keylesspalace.tusky.interfaces.StatusActionListener;
import com.keylesspalace.tusky.util.CardViewMode;
import com.keylesspalace.tusky.util.CustomEmojiHelper;
-import com.keylesspalace.tusky.util.HtmlUtils;
import com.keylesspalace.tusky.util.ImageLoadingHelper;
import com.keylesspalace.tusky.util.LinkHelper;
import com.keylesspalace.tusky.util.StatusDisplayOptions;
@@ -884,7 +884,7 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
protected CharSequence getFavsText(Context context, int count) {
if (count > 0) {
String countString = numberFormat.format(count);
- return HtmlUtils.fromHtml(context.getResources().getQuantityString(R.plurals.favs, count, countString));
+ return HtmlCompat.fromHtml(context.getResources().getQuantityString(R.plurals.favs, count, countString), HtmlCompat.FROM_HTML_MODE_LEGACY);
} else {
return "";
}
@@ -893,7 +893,7 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
protected CharSequence getReblogsText(Context context, int count) {
if (count > 0) {
String countString = numberFormat.format(count);
- return HtmlUtils.fromHtml(context.getResources().getQuantityString(R.plurals.reblogs, count, countString));
+ return HtmlCompat.fromHtml(context.getResources().getQuantityString(R.plurals.reblogs, count, countString), HtmlCompat.FROM_HTML_MODE_LEGACY);
} else {
return "";
}
diff --git a/app/src/main/java/com/keylesspalace/tusky/db/Converters.kt b/app/src/main/java/com/keylesspalace/tusky/db/Converters.kt
index 0074b8d9b..09f8a5cbd 100644
--- a/app/src/main/java/com/keylesspalace/tusky/db/Converters.kt
+++ b/app/src/main/java/com/keylesspalace/tusky/db/Converters.kt
@@ -16,6 +16,8 @@
package com.keylesspalace.tusky.db
import android.text.Spanned
+import androidx.core.text.parseAsHtml
+import androidx.core.text.toHtml
import androidx.room.TypeConverter
import com.google.gson.GsonBuilder
import com.google.gson.reflect.TypeToken
@@ -27,7 +29,6 @@ import com.keylesspalace.tusky.entity.Emoji
import com.keylesspalace.tusky.entity.Poll
import com.keylesspalace.tusky.entity.Status
import com.keylesspalace.tusky.json.SpannedTypeAdapter
-import com.keylesspalace.tusky.util.HtmlUtils
import java.net.URLDecoder
import java.net.URLEncoder
import java.util.*
@@ -128,7 +129,7 @@ class Converters {
if(spanned == null) {
return null
}
- return HtmlUtils.toHtml(spanned)
+ return spanned.toHtml()
}
@TypeConverter
@@ -136,7 +137,7 @@ class Converters {
if(spannedString == null) {
return null
}
- return HtmlUtils.fromHtml(spannedString)
+ return spannedString.parseAsHtml()
}
@TypeConverter
diff --git a/app/src/main/java/com/keylesspalace/tusky/di/AppModule.kt b/app/src/main/java/com/keylesspalace/tusky/di/AppModule.kt
index a4f2eb5eb..e87ef2894 100644
--- a/app/src/main/java/com/keylesspalace/tusky/di/AppModule.kt
+++ b/app/src/main/java/com/keylesspalace/tusky/di/AppModule.kt
@@ -29,8 +29,6 @@ import com.keylesspalace.tusky.db.AppDatabase
import com.keylesspalace.tusky.network.MastodonApi
import com.keylesspalace.tusky.network.TimelineCases
import com.keylesspalace.tusky.network.TimelineCasesImpl
-import com.keylesspalace.tusky.util.HtmlConverter
-import com.keylesspalace.tusky.util.HtmlConverterImpl
import dagger.Module
import dagger.Provides
import javax.inject.Singleton
@@ -84,9 +82,4 @@ class AppModule {
.build()
}
- @Provides
- @Singleton
- fun providesHtmlConverter(): HtmlConverter {
- return HtmlConverterImpl()
- }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/keylesspalace/tusky/di/RepositoryModule.kt b/app/src/main/java/com/keylesspalace/tusky/di/RepositoryModule.kt
index 1b5206a74..af8cfb886 100644
--- a/app/src/main/java/com/keylesspalace/tusky/di/RepositoryModule.kt
+++ b/app/src/main/java/com/keylesspalace/tusky/di/RepositoryModule.kt
@@ -6,17 +6,18 @@ import com.keylesspalace.tusky.db.AppDatabase
import com.keylesspalace.tusky.network.MastodonApi
import com.keylesspalace.tusky.repository.TimelineRepository
import com.keylesspalace.tusky.repository.TimelineRepositoryImpl
-import com.keylesspalace.tusky.util.HtmlConverter
import dagger.Module
import dagger.Provides
@Module
class RepositoryModule {
@Provides
- fun providesTimelineRepository(db: AppDatabase, mastodonApi: MastodonApi,
- accountManager: AccountManager, gson: Gson,
- htmlConverter: HtmlConverter): TimelineRepository {
- return TimelineRepositoryImpl(db.timelineDao(), mastodonApi, accountManager, gson,
- htmlConverter)
+ fun providesTimelineRepository(
+ db: AppDatabase,
+ mastodonApi: MastodonApi,
+ accountManager: AccountManager,
+ gson: Gson
+ ): TimelineRepository {
+ return TimelineRepositoryImpl(db.timelineDao(), mastodonApi, accountManager, gson)
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/keylesspalace/tusky/entity/Account.kt b/app/src/main/java/com/keylesspalace/tusky/entity/Account.kt
index 62990758e..d4940fe0e 100644
--- a/app/src/main/java/com/keylesspalace/tusky/entity/Account.kt
+++ b/app/src/main/java/com/keylesspalace/tusky/entity/Account.kt
@@ -15,24 +15,16 @@
package com.keylesspalace.tusky.entity
-import android.os.Parcel
-import android.os.Parcelable
import android.text.Spanned
-
import com.google.gson.annotations.SerializedName
-import com.keylesspalace.tusky.util.HtmlUtils
-import kotlinx.android.parcel.Parceler
-import kotlinx.android.parcel.Parcelize
-import kotlinx.android.parcel.WriteWith
-import java.util.*
+import java.util.Date
-@Parcelize
data class Account(
val id: String,
@SerializedName("username") val localUsername: String,
@SerializedName("acct") val username: String,
@SerializedName("display_name") val displayName: String?, // should never be null per Api definition, but some servers break the contract
- val note: @WriteWith() Spanned,
+ val note: Spanned,
val url: String,
val avatar: String,
val header: String,
@@ -46,7 +38,7 @@ data class Account(
val fields: List? = emptyList(), //nullable for backward compatibility
val moved: Account? = null
-) : Parcelable {
+) {
val name: String
get() = if (displayName.isNullOrEmpty()) {
@@ -86,31 +78,20 @@ data class Account(
fun isRemote(): Boolean = this.username != this.localUsername
}
-@Parcelize
data class AccountSource(
val privacy: Status.Visibility,
val sensitive: Boolean,
val note: String,
val fields: List?
-): Parcelable
+)
-@Parcelize
data class Field (
val name: String,
- val value: @WriteWith() Spanned,
+ val value: Spanned,
@SerializedName("verified_at") val verifiedAt: Date?
-): Parcelable
+)
-@Parcelize
data class StringField (
val name: String,
val value: String
-): Parcelable
-
-object SpannedParceler : Parceler {
- override fun create(parcel: Parcel): Spanned = HtmlUtils.fromHtml(parcel.readString())
-
- override fun Spanned.write(parcel: Parcel, flags: Int) {
- parcel.writeString(HtmlUtils.toHtml(this))
- }
-}
\ No newline at end of file
+)
diff --git a/app/src/main/java/com/keylesspalace/tusky/entity/Card.kt b/app/src/main/java/com/keylesspalace/tusky/entity/Card.kt
index c6f82637f..43e54f010 100644
--- a/app/src/main/java/com/keylesspalace/tusky/entity/Card.kt
+++ b/app/src/main/java/com/keylesspalace/tusky/entity/Card.kt
@@ -15,23 +15,19 @@
package com.keylesspalace.tusky.entity
-import android.os.Parcelable
import android.text.Spanned
import com.google.gson.annotations.SerializedName
-import kotlinx.android.parcel.Parcelize
-import kotlinx.android.parcel.WriteWith
-@Parcelize
data class Card(
val url: String,
- val title: @WriteWith() Spanned,
- val description: @WriteWith() Spanned,
+ val title: Spanned,
+ val description: Spanned,
@SerializedName("author_name") val authorName: String,
val image: String,
val type: String,
val width: Int,
val height: Int
-) : Parcelable {
+) {
override fun hashCode(): Int {
return url.hashCode()
diff --git a/app/src/main/java/com/keylesspalace/tusky/json/SpannedTypeAdapter.java b/app/src/main/java/com/keylesspalace/tusky/json/SpannedTypeAdapter.java
index cabd3eb86..a884695f8 100644
--- a/app/src/main/java/com/keylesspalace/tusky/json/SpannedTypeAdapter.java
+++ b/app/src/main/java/com/keylesspalace/tusky/json/SpannedTypeAdapter.java
@@ -18,6 +18,8 @@ package com.keylesspalace.tusky.json;
import android.text.Spanned;
import android.text.SpannedString;
+import androidx.core.text.HtmlCompat;
+
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
@@ -25,7 +27,6 @@ import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
-import com.keylesspalace.tusky.util.HtmlUtils;
import java.lang.reflect.Type;
@@ -35,7 +36,9 @@ public class SpannedTypeAdapter implements JsonDeserializer, JsonSerial
throws JsonParseException {
String string = json.getAsString();
if (string != null) {
- return HtmlUtils.fromHtml(string);
+ /* Html.fromHtml returns trailing whitespace if the html ends in a
tag, which
+ * all status contents do, so it should be trimmed. */
+ return (Spanned)trimTrailingWhitespace(HtmlCompat.fromHtml(string, HtmlCompat.FROM_HTML_MODE_LEGACY));
} else {
return new SpannedString("");
}
@@ -43,6 +46,14 @@ public class SpannedTypeAdapter implements JsonDeserializer, JsonSerial
@Override
public JsonElement serialize(Spanned src, Type typeOfSrc, JsonSerializationContext context) {
- return new JsonPrimitive(HtmlUtils.toHtml(src));
+ return new JsonPrimitive(HtmlCompat.toHtml(src, HtmlCompat.TO_HTML_PARAGRAPH_LINES_INDIVIDUAL));
+ }
+
+ private static CharSequence trimTrailingWhitespace(CharSequence s) {
+ int i = s.length();
+ do {
+ i--;
+ } while (i >= 0 && Character.isWhitespace(s.charAt(i)));
+ return s.subSequence(0, i + 1);
}
}
diff --git a/app/src/main/java/com/keylesspalace/tusky/repository/TimelineRepository.kt b/app/src/main/java/com/keylesspalace/tusky/repository/TimelineRepository.kt
index f16bb542c..0023a9f88 100644
--- a/app/src/main/java/com/keylesspalace/tusky/repository/TimelineRepository.kt
+++ b/app/src/main/java/com/keylesspalace/tusky/repository/TimelineRepository.kt
@@ -1,6 +1,8 @@
package com.keylesspalace.tusky.repository
import android.text.SpannedString
+import androidx.core.text.parseAsHtml
+import androidx.core.text.toHtml
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.keylesspalace.tusky.db.*
@@ -9,7 +11,6 @@ import com.keylesspalace.tusky.network.MastodonApi
import com.keylesspalace.tusky.repository.TimelineRequestMode.DISK
import com.keylesspalace.tusky.repository.TimelineRequestMode.NETWORK
import com.keylesspalace.tusky.util.Either
-import com.keylesspalace.tusky.util.HtmlConverter
import com.keylesspalace.tusky.util.dec
import com.keylesspalace.tusky.util.inc
import io.reactivex.Single
@@ -40,8 +41,7 @@ class TimelineRepositoryImpl(
private val timelineDao: TimelineDao,
private val mastodonApi: MastodonApi,
private val accountManager: AccountManager,
- private val gson: Gson,
- private val htmlConverter: HtmlConverter
+ private val gson: Gson
) : TimelineRepository {
init {
@@ -150,7 +150,7 @@ class TimelineRepositoryImpl(
for (status in statuses) {
timelineDao.insertInTransaction(
- status.toEntity(accountId, htmlConverter, gson),
+ status.toEntity(accountId, gson),
status.account.toEntity(accountId, gson),
status.reblog?.account?.toEntity(accountId, gson)
)
@@ -214,7 +214,7 @@ class TimelineRepositoryImpl(
inReplyToId = status.inReplyToId,
inReplyToAccountId = status.inReplyToAccountId,
reblog = null,
- content = status.content?.let(htmlConverter::fromHtml) ?: SpannedString(""),
+ content = status.content?.parseAsHtml() ?: SpannedString(""),
createdAt = Date(status.createdAt),
emojis = emojis,
reblogsCount = status.reblogsCount,
@@ -269,7 +269,7 @@ class TimelineRepositoryImpl(
inReplyToId = status.inReplyToId,
inReplyToAccountId = status.inReplyToAccountId,
reblog = null,
- content = status.content?.let(htmlConverter::fromHtml) ?: SpannedString(""),
+ content = status.content?.parseAsHtml() ?: SpannedString(""),
createdAt = Date(status.createdAt),
emojis = emojis,
reblogsCount = status.reblogsCount,
@@ -362,7 +362,6 @@ fun Placeholder.toEntity(timelineUserId: Long): TimelineStatusEntity {
}
fun Status.toEntity(timelineUserId: Long,
- htmlConverter: HtmlConverter,
gson: Gson): TimelineStatusEntity {
val actionable = actionableStatus
return TimelineStatusEntity(
@@ -372,7 +371,7 @@ fun Status.toEntity(timelineUserId: Long,
authorServerId = actionable.account.id,
inReplyToId = actionable.inReplyToId,
inReplyToAccountId = actionable.inReplyToAccountId,
- content = htmlConverter.toHtml(actionable.content),
+ content = actionable.content.toHtml(),
createdAt = actionable.createdAt.time,
emojis = actionable.emojis.let(gson::toJson),
reblogsCount = actionable.reblogsCount,
@@ -385,7 +384,7 @@ fun Status.toEntity(timelineUserId: Long,
visibility = actionable.visibility,
attachments = actionable.attachments.let(gson::toJson),
mentions = actionable.mentions.let(gson::toJson),
- application = actionable.let(gson::toJson),
+ application = actionable.application.let(gson::toJson),
reblogServerId = reblog?.id,
reblogAccountId = reblog?.let { this.account.id },
poll = actionable.poll.let(gson::toJson),
diff --git a/app/src/main/java/com/keylesspalace/tusky/util/HtmlConverter.kt b/app/src/main/java/com/keylesspalace/tusky/util/HtmlConverter.kt
deleted file mode 100644
index 72efc28c6..000000000
--- a/app/src/main/java/com/keylesspalace/tusky/util/HtmlConverter.kt
+++ /dev/null
@@ -1,22 +0,0 @@
-package com.keylesspalace.tusky.util
-
-import android.text.Spanned
-
-/**
- * Abstracting away Android-specific things.
- */
-interface HtmlConverter {
- fun fromHtml(html: String): Spanned
-
- fun toHtml(text: Spanned): String
-}
-
-internal class HtmlConverterImpl : HtmlConverter {
- override fun fromHtml(html: String): Spanned {
- return HtmlUtils.fromHtml(html)
- }
-
- override fun toHtml(text: Spanned): String {
- return HtmlUtils.toHtml(text)
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/keylesspalace/tusky/util/HtmlUtils.java b/app/src/main/java/com/keylesspalace/tusky/util/HtmlUtils.java
deleted file mode 100644
index cba8f2fab..000000000
--- a/app/src/main/java/com/keylesspalace/tusky/util/HtmlUtils.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/* Copyright 2017 Andrew Dawson
- *
- * This file is a part of Tusky.
- *
- * This program is free software; you can redistribute it and/or modify it under the terms of the
- * GNU General Public License as published by the Free Software Foundation; either version 3 of the
- * License, or (at your option) any later version.
- *
- * Tusky is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
- * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
- * Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with Tusky; if not,
- * see . */
-
-package com.keylesspalace.tusky.util;
-
-import android.os.Build;
-import android.text.Html;
-import android.text.Spanned;
-
-public class HtmlUtils {
- private static CharSequence trimTrailingWhitespace(CharSequence s) {
- int i = s.length();
- do {
- i--;
- } while (i >= 0 && Character.isWhitespace(s.charAt(i)));
- return s.subSequence(0, i + 1);
- }
-
- public static Spanned fromHtml(String html) {
- Spanned result;
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
- result = Html.fromHtml(html, Html.FROM_HTML_MODE_LEGACY);
- } else {
- result = Html.fromHtml(html);
- }
- /* Html.fromHtml returns trailing whitespace if the html ends in a tag, which
- * all status contents do, so it should be trimmed. */
- return (Spanned) trimTrailingWhitespace(result);
- }
-
- public static String toHtml(Spanned text) {
- String result;
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
- result = Html.toHtml(text, Html.TO_HTML_PARAGRAPH_LINES_CONSECUTIVE);
- } else {
- result = Html.toHtml(text);
- }
- return result;
- }
-}
diff --git a/app/src/main/java/com/keylesspalace/tusky/util/StatusViewHelper.kt b/app/src/main/java/com/keylesspalace/tusky/util/StatusViewHelper.kt
index 98660bc39..79c0c4b84 100644
--- a/app/src/main/java/com/keylesspalace/tusky/util/StatusViewHelper.kt
+++ b/app/src/main/java/com/keylesspalace/tusky/util/StatusViewHelper.kt
@@ -171,15 +171,12 @@ class StatusViewHelper(private val itemView: View) {
sensitiveMediaWarning.visibility = View.GONE
sensitiveMediaShow.visibility = View.GONE
} else {
-
- val hiddenContentText: String = if (sensitive) {
+ sensitiveMediaWarning.text = if (sensitive) {
context.getString(R.string.status_sensitive_media_title)
} else {
context.getString(R.string.status_media_hidden_title)
}
- sensitiveMediaWarning.text = HtmlUtils.fromHtml(hiddenContentText)
-
sensitiveMediaWarning.visibility = if (showingContent) View.GONE else View.VISIBLE
sensitiveMediaShow.visibility = if (showingContent) View.VISIBLE else View.GONE
sensitiveMediaShow.setOnClickListener { v ->
diff --git a/app/src/main/java/com/keylesspalace/tusky/viewdata/PollViewData.kt b/app/src/main/java/com/keylesspalace/tusky/viewdata/PollViewData.kt
index 729893215..b6eefd713 100644
--- a/app/src/main/java/com/keylesspalace/tusky/viewdata/PollViewData.kt
+++ b/app/src/main/java/com/keylesspalace/tusky/viewdata/PollViewData.kt
@@ -18,10 +18,10 @@ package com.keylesspalace.tusky.viewdata
import android.content.Context
import android.text.SpannableStringBuilder
import android.text.Spanned
+import androidx.core.text.parseAsHtml
import com.keylesspalace.tusky.R
import com.keylesspalace.tusky.entity.Poll
import com.keylesspalace.tusky.entity.PollOption
-import com.keylesspalace.tusky.util.HtmlUtils
import java.util.*
import kotlin.math.roundToInt
@@ -52,7 +52,7 @@ fun calculatePercent(fraction: Int, totalVoters: Int?, totalVotes: Int): Int {
}
fun buildDescription(title: String, percent: Int, context: Context): Spanned {
- return SpannableStringBuilder(HtmlUtils.fromHtml(context.getString(R.string.poll_percent_format, percent)))
+ return SpannableStringBuilder(context.getString(R.string.poll_percent_format, percent).parseAsHtml())
.append(" ")
.append(title)
}
diff --git a/app/src/test/java/com/keylesspalace/tusky/fragment/TimelineRepositoryTest.kt b/app/src/test/java/com/keylesspalace/tusky/fragment/TimelineRepositoryTest.kt
index f80f57b8c..a3db3b448 100644
--- a/app/src/test/java/com/keylesspalace/tusky/fragment/TimelineRepositoryTest.kt
+++ b/app/src/test/java/com/keylesspalace/tusky/fragment/TimelineRepositoryTest.kt
@@ -1,6 +1,8 @@
package com.keylesspalace.tusky.fragment
-import android.text.Spanned
+import android.text.SpannableString
+import android.text.SpannedString
+import androidx.test.ext.junit.runners.AndroidJUnit4
import com.google.gson.Gson
import com.keylesspalace.tusky.SpanUtilsTest
import com.keylesspalace.tusky.db.AccountEntity
@@ -12,7 +14,6 @@ import com.keylesspalace.tusky.entity.Status
import com.keylesspalace.tusky.network.MastodonApi
import com.keylesspalace.tusky.repository.*
import com.keylesspalace.tusky.util.Either
-import com.keylesspalace.tusky.util.HtmlConverter
import com.nhaarman.mockitokotlin2.isNull
import com.nhaarman.mockitokotlin2.verify
import com.nhaarman.mockitokotlin2.verifyNoMoreInteractions
@@ -24,14 +25,18 @@ import io.reactivex.schedulers.TestScheduler
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Test
+import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.any
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.Mock
import org.mockito.MockitoAnnotations
+import org.robolectric.annotation.Config
import java.util.*
import java.util.concurrent.TimeUnit
import kotlin.collections.ArrayList
+@Config(sdk = [28])
+@RunWith(AndroidJUnit4::class)
class TimelineRepositoryTest {
@Mock
lateinit var timelineDao: TimelineDao
@@ -56,15 +61,6 @@ class TimelineRepositoryTest {
domain = "domain.com",
isActive = true
)
- private val htmlConverter = object : HtmlConverter {
- override fun fromHtml(html: String): Spanned {
- return SpanUtilsTest.FakeSpannable(html)
- }
-
- override fun toHtml(text: Spanned): String {
- return text.toString()
- }
- }
@Before
fun setup() {
@@ -74,8 +70,7 @@ class TimelineRepositoryTest {
gson = Gson()
testScheduler = TestScheduler()
RxJavaPlugins.setIoSchedulerHandler { testScheduler }
- subject = TimelineRepositoryImpl(timelineDao, mastodonApi, accountManager, gson,
- htmlConverter)
+ subject = TimelineRepositoryImpl(timelineDao, mastodonApi, accountManager, gson)
}
@Test
@@ -97,7 +92,7 @@ class TimelineRepositoryTest {
verify(timelineDao).insertStatusIfNotThere(Placeholder("1").toEntity(account.id))
for (status in statuses) {
verify(timelineDao).insertInTransaction(
- status.toEntity(account.id, htmlConverter, gson),
+ status.toEntity(account.id, gson),
status.account.toEntity(account.id, gson),
null
)
@@ -129,7 +124,7 @@ class TimelineRepositoryTest {
// We assume for now that overlapped one is inserted but it's not that important
for (status in response) {
verify(timelineDao).insertInTransaction(
- status.toEntity(account.id, htmlConverter, gson),
+ status.toEntity(account.id, gson),
status.account.toEntity(account.id, gson),
null
)
@@ -159,7 +154,7 @@ class TimelineRepositoryTest {
verify(timelineDao).deleteRange(account.id, response.last().id, response.first().id)
for (status in response) {
verify(timelineDao).insertInTransaction(
- status.toEntity(account.id, htmlConverter, gson),
+ status.toEntity(account.id, gson),
status.account.toEntity(account.id, gson),
null
)
@@ -201,7 +196,7 @@ class TimelineRepositoryTest {
// We assume for now that overlapped one is inserted but it's not that important
for (status in response) {
verify(timelineDao).insertInTransaction(
- status.toEntity(account.id, htmlConverter, gson),
+ status.toEntity(account.id, gson),
status.account.toEntity(account.id, gson),
null
)
@@ -246,7 +241,7 @@ class TimelineRepositoryTest {
for (status in response) {
verify(timelineDao).insertInTransaction(
- status.toEntity(account.id, htmlConverter, gson),
+ status.toEntity(account.id, gson),
status.account.toEntity(account.id, gson),
null
)
@@ -263,7 +258,7 @@ class TimelineRepositoryTest {
val status = makeStatus("2")
val dbStatus = makeStatus("1")
val dbResult = TimelineStatusWithAccount()
- dbResult.status = dbStatus.toEntity(account.id, htmlConverter, gson)
+ dbResult.status = dbStatus.toEntity(account.id, gson)
dbResult.account = status.account.toEntity(account.id, gson)
whenever(mastodonApi.homeTimelineSingle(any(), any(), any()))
@@ -297,7 +292,7 @@ class TimelineRepositoryTest {
return Status(
id = id,
account = account,
- content = SpanUtilsTest.FakeSpannable("hello$id"),
+ content = SpannableString("hello$id"),
createdAt = Date(),
emojis = listOf(),
reblogsCount = 3,
@@ -328,7 +323,7 @@ class TimelineRepositoryTest {
localUsername = "test$id",
username = "test$id@example.com",
displayName = "Example Account $id",
- note = SpanUtilsTest.FakeSpannable("Note! $id"),
+ note = SpannableString("Note! $id"),
url = "https://example.com/@test$id",
avatar = "avatar$id",
header = "Header$id",