Respect filter expiration date when applying filters (#2661)
* Respect filter expiration date when applying filters. #2578 * Fix typing for filter `expires_in` api points
This commit is contained in:
parent
be4645ec38
commit
b21def5041
|
@ -56,7 +56,7 @@ class FiltersActivity : BaseActivity() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateFilter(filter: Filter, itemIndex: Int) {
|
private fun updateFilter(filter: Filter, itemIndex: Int) {
|
||||||
api.updateFilter(filter.id, filter.phrase, filter.context, filter.irreversible, filter.wholeWord, filter.expiresAt)
|
api.updateFilter(filter.id, filter.phrase, filter.context, filter.irreversible, filter.wholeWord, null)
|
||||||
.enqueue(object : Callback<Filter> {
|
.enqueue(object : Callback<Filter> {
|
||||||
override fun onFailure(call: Call<Filter>, t: Throwable) {
|
override fun onFailure(call: Call<Filter>, t: Throwable) {
|
||||||
Toast.makeText(this@FiltersActivity, "Error updating filter '${filter.phrase}'", Toast.LENGTH_SHORT).show()
|
Toast.makeText(this@FiltersActivity, "Error updating filter '${filter.phrase}'", Toast.LENGTH_SHORT).show()
|
||||||
|
@ -102,7 +102,7 @@ class FiltersActivity : BaseActivity() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createFilter(phrase: String, wholeWord: Boolean) {
|
private fun createFilter(phrase: String, wholeWord: Boolean) {
|
||||||
api.createFilter(phrase, listOf(context), false, wholeWord, "").enqueue(object : Callback<Filter> {
|
api.createFilter(phrase, listOf(context), false, wholeWord, null).enqueue(object : Callback<Filter> {
|
||||||
override fun onResponse(call: Call<Filter>, response: Response<Filter>) {
|
override fun onResponse(call: Call<Filter>, response: Response<Filter>) {
|
||||||
val filterResponse = response.body()
|
val filterResponse = response.body()
|
||||||
if (response.isSuccessful && filterResponse != null) {
|
if (response.isSuccessful && filterResponse != null) {
|
||||||
|
|
|
@ -16,12 +16,13 @@
|
||||||
package com.keylesspalace.tusky.entity
|
package com.keylesspalace.tusky.entity
|
||||||
|
|
||||||
import com.google.gson.annotations.SerializedName
|
import com.google.gson.annotations.SerializedName
|
||||||
|
import java.util.Date
|
||||||
|
|
||||||
data class Filter(
|
data class Filter(
|
||||||
val id: String,
|
val id: String,
|
||||||
val phrase: String,
|
val phrase: String,
|
||||||
val context: List<String>,
|
val context: List<String>,
|
||||||
@SerializedName("expires_at") val expiresAt: String?,
|
@SerializedName("expires_at") val expiresAt: Date?,
|
||||||
val irreversible: Boolean,
|
val irreversible: Boolean,
|
||||||
@SerializedName("whole_word") val wholeWord: Boolean
|
@SerializedName("whole_word") val wholeWord: Boolean
|
||||||
) {
|
) {
|
||||||
|
|
|
@ -3,6 +3,7 @@ package com.keylesspalace.tusky.network
|
||||||
import android.text.TextUtils
|
import android.text.TextUtils
|
||||||
import com.keylesspalace.tusky.entity.Filter
|
import com.keylesspalace.tusky.entity.Filter
|
||||||
import com.keylesspalace.tusky.entity.Status
|
import com.keylesspalace.tusky.entity.Status
|
||||||
|
import java.util.Date
|
||||||
import java.util.regex.Pattern
|
import java.util.regex.Pattern
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@ -54,7 +55,9 @@ class FilterModel @Inject constructor() {
|
||||||
|
|
||||||
private fun makeFilter(filters: List<Filter>): Pattern? {
|
private fun makeFilter(filters: List<Filter>): Pattern? {
|
||||||
if (filters.isEmpty()) return null
|
if (filters.isEmpty()) return null
|
||||||
val tokens = filters.map { filterToRegexToken(it) }
|
val tokens = filters
|
||||||
|
.filter { it.expiresAt?.before(Date()) != true }
|
||||||
|
.map { filterToRegexToken(it) }
|
||||||
|
|
||||||
return Pattern.compile(TextUtils.join("|", tokens), Pattern.CASE_INSENSITIVE)
|
return Pattern.compile(TextUtils.join("|", tokens), Pattern.CASE_INSENSITIVE)
|
||||||
}
|
}
|
||||||
|
|
|
@ -536,7 +536,7 @@ interface MastodonApi {
|
||||||
@Field("context[]") context: List<String>,
|
@Field("context[]") context: List<String>,
|
||||||
@Field("irreversible") irreversible: Boolean?,
|
@Field("irreversible") irreversible: Boolean?,
|
||||||
@Field("whole_word") wholeWord: Boolean?,
|
@Field("whole_word") wholeWord: Boolean?,
|
||||||
@Field("expires_in") expiresIn: String?
|
@Field("expires_in") expiresIn: Int?
|
||||||
): Call<Filter>
|
): Call<Filter>
|
||||||
|
|
||||||
@FormUrlEncoded
|
@FormUrlEncoded
|
||||||
|
@ -547,7 +547,7 @@ interface MastodonApi {
|
||||||
@Field("context[]") context: List<String>,
|
@Field("context[]") context: List<String>,
|
||||||
@Field("irreversible") irreversible: Boolean?,
|
@Field("irreversible") irreversible: Boolean?,
|
||||||
@Field("whole_word") wholeWord: Boolean?,
|
@Field("whole_word") wholeWord: Boolean?,
|
||||||
@Field("expires_in") expiresIn: String?
|
@Field("expires_in") expiresIn: Int?
|
||||||
): Call<Filter>
|
): Call<Filter>
|
||||||
|
|
||||||
@DELETE("api/v1/filters/{id}")
|
@DELETE("api/v1/filters/{id}")
|
||||||
|
|
|
@ -14,6 +14,7 @@ import org.junit.Test
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
import org.mockito.kotlin.mock
|
import org.mockito.kotlin.mock
|
||||||
import org.robolectric.annotation.Config
|
import org.robolectric.annotation.Config
|
||||||
|
import java.time.Instant
|
||||||
import java.util.ArrayList
|
import java.util.ArrayList
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
|
|
||||||
|
@ -50,7 +51,23 @@ class FilterTest {
|
||||||
expiresAt = null,
|
expiresAt = null,
|
||||||
irreversible = false,
|
irreversible = false,
|
||||||
wholeWord = true
|
wholeWord = true
|
||||||
)
|
),
|
||||||
|
Filter(
|
||||||
|
id = "123",
|
||||||
|
phrase = "expired",
|
||||||
|
context = listOf(Filter.HOME),
|
||||||
|
expiresAt = Date.from(Instant.now().minusSeconds(10)),
|
||||||
|
irreversible = false,
|
||||||
|
wholeWord = true
|
||||||
|
),
|
||||||
|
Filter(
|
||||||
|
id = "123",
|
||||||
|
phrase = "unexpired",
|
||||||
|
context = listOf(Filter.HOME),
|
||||||
|
expiresAt = Date.from(Instant.now().plusSeconds(3600)),
|
||||||
|
irreversible = false,
|
||||||
|
wholeWord = true
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
filterModel.initWithFilters(filters)
|
filterModel.initWithFilters(filters)
|
||||||
|
@ -148,6 +165,23 @@ class FilterTest {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun shouldNotFilter_whenFilterIsExpired() {
|
||||||
|
assertFalse(
|
||||||
|
filterModel.shouldFilterStatus(
|
||||||
|
mockStatus(content = "content matching expired filter should not be filtered")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun shouldFilter_whenFilterIsUnexpired() {
|
||||||
|
assertTrue(
|
||||||
|
filterModel.shouldFilterStatus(
|
||||||
|
mockStatus(content = "content matching unexpired filter should be filtered")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
private fun mockStatus(
|
private fun mockStatus(
|
||||||
content: String = "",
|
content: String = "",
|
||||||
spoilerText: String = "",
|
spoilerText: String = "",
|
||||||
|
|
Loading…
Reference in New Issue