From b464f91668b1985e59b5555450011783da771211 Mon Sep 17 00:00:00 2001 From: Allan Wang Date: Sun, 31 Mar 2019 20:15:03 -0400 Subject: Add stricter parsing tests --- .../com/pitchedapps/frost/facebook/parsers/FrostParser.kt | 12 ++++++++---- .../com/pitchedapps/frost/facebook/parsers/MessageParser.kt | 4 ++++ .../com/pitchedapps/frost/facebook/parsers/NotifParser.kt | 4 ++++ .../com/pitchedapps/frost/facebook/parsers/SearchParser.kt | 5 ++++- .../com/pitchedapps/frost/fragments/RecyclerFragmentBase.kt | 3 ++- .../com/pitchedapps/frost/facebook/parsers/FbParseTest.kt | 6 ++++-- 6 files changed, 26 insertions(+), 8 deletions(-) diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/FrostParser.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/FrostParser.kt index 5709bb9f..90c8848c 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/FrostParser.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/FrostParser.kt @@ -38,7 +38,7 @@ import org.jsoup.select.Elements * The return type must be nonnull if no parsing errors occurred, as null signifies a parse error * If null really must be allowed, use Optionals */ -interface FrostParser { +interface FrostParser { /** * Name associated to parser @@ -76,11 +76,15 @@ const val FALLBACK_TIME_MOD = 1000000 data class FrostLink(val text: String, val href: String) -data class ParseResponse(val cookie: String, val data: T) { +data class ParseResponse(val cookie: String, val data: T) { override fun toString() = "ParseResponse\ncookie: $cookie\ndata:\n$data" } -interface ParseNotification { +interface ParseData { + val isEmpty: Boolean +} + +interface ParseNotification : ParseData { fun getUnreadNotifications(data: CookieModel): List } @@ -95,7 +99,7 @@ internal fun List.toJsonString(tag: String, indent: Int) = StringBuilder( * T should have a readable toString() function * [redirectToText] dictates whether all data should be converted to text then back to document before parsing */ -internal abstract class FrostParserBase(private val redirectToText: Boolean) : FrostParser { +internal abstract class FrostParserBase(private val redirectToText: Boolean) : FrostParser { final override fun parse(cookie: String?) = parseFromUrl(cookie, url) diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/MessageParser.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/MessageParser.kt index f05c42e9..529ac23a 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/MessageParser.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/MessageParser.kt @@ -46,6 +46,10 @@ data class FrostMessages( val seeMore: FrostLink?, val extraLinks: List ) : ParseNotification { + + override val isEmpty: Boolean + get() = threads.isEmpty() + override fun toString() = StringBuilder().apply { append("FrostMessages {\n") append(threads.toJsonString("threads", 1)) diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/NotifParser.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/NotifParser.kt index b8aa899b..422ec384 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/NotifParser.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/NotifParser.kt @@ -36,6 +36,10 @@ data class FrostNotifs( val notifs: List, val seeMore: FrostLink? ) : ParseNotification { + + override val isEmpty: Boolean + get() = notifs.isEmpty() + override fun toString() = StringBuilder().apply { append("FrostNotifs {\n") append(notifs.toJsonString("notifs", 1)) diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/SearchParser.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/SearchParser.kt index 7869d881..b044ee58 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/SearchParser.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/parsers/SearchParser.kt @@ -40,7 +40,10 @@ enum class SearchKeys(val key: String) { EVENTS("keywords_events") } -data class FrostSearches(val results: List) { +data class FrostSearches(val results: List) : ParseData { + + override val isEmpty: Boolean + get() = results.isEmpty() override fun toString() = StringBuilder().apply { append("FrostSearches {\n") diff --git a/app/src/main/kotlin/com/pitchedapps/frost/fragments/RecyclerFragmentBase.kt b/app/src/main/kotlin/com/pitchedapps/frost/fragments/RecyclerFragmentBase.kt index ed6a4cf0..9f2d704c 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/fragments/RecyclerFragmentBase.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/fragments/RecyclerFragmentBase.kt @@ -25,6 +25,7 @@ import com.mikepenz.fastadapter.adapters.ModelAdapter import com.pitchedapps.frost.R import com.pitchedapps.frost.facebook.FbCookie import com.pitchedapps.frost.facebook.parsers.FrostParser +import com.pitchedapps.frost.facebook.parsers.ParseData import com.pitchedapps.frost.facebook.parsers.ParseResponse import com.pitchedapps.frost.utils.L import com.pitchedapps.frost.utils.frostJsoup @@ -94,7 +95,7 @@ abstract class GenericRecyclerFragment> : RecyclerFragment open fun getAdapter(): FastAdapter> = fastAdapter(this.adapter) } -abstract class FrostParserFragment> : RecyclerFragment() { +abstract class FrostParserFragment> : RecyclerFragment() { /** * The parser to make this all happen diff --git a/app/src/test/kotlin/com/pitchedapps/frost/facebook/parsers/FbParseTest.kt b/app/src/test/kotlin/com/pitchedapps/frost/facebook/parsers/FbParseTest.kt index 075f045e..4fe43ca8 100644 --- a/app/src/test/kotlin/com/pitchedapps/frost/facebook/parsers/FbParseTest.kt +++ b/app/src/test/kotlin/com/pitchedapps/frost/facebook/parsers/FbParseTest.kt @@ -22,6 +22,7 @@ import com.pitchedapps.frost.internal.assertDescending import com.pitchedapps.frost.internal.authDependent import org.junit.BeforeClass import org.junit.Test +import kotlin.test.assertFalse import kotlin.test.assertNotNull import kotlin.test.assertTrue import kotlin.test.fail @@ -39,13 +40,14 @@ class FbParseTest { } } - private inline fun FrostParser.test(action: T.() -> Unit = {}) = + private inline fun FrostParser.test(action: T.() -> Unit = {}) = parse(COOKIE).test(url, action) - private inline fun ParseResponse?.test(url: String, action: T.() -> Unit = {}) { + private inline fun ParseResponse?.test(url: String, action: T.() -> Unit = {}) { val response = this ?: fail("${T::class.simpleName} parser returned null for $url") println(response) + assertFalse(response.data.isEmpty, "${T::class.simpleName} parser returned empty data for $url") response.data.action() } -- cgit v1.2.3 From 77d28c77ead6a2477e1e4df1b8e74bd08a3c2efd Mon Sep 17 00:00:00 2001 From: Allan Wang Date: Thu, 25 Apr 2019 15:39:04 -0700 Subject: Move search view binding to separate func --- .../kotlin/com/pitchedapps/frost/activities/BaseMainActivity.kt | 6 +++++- app/src/main/kotlin/com/pitchedapps/frost/facebook/FbItem.kt | 3 +++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseMainActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseMainActivity.kt index d8b29ddc..49d5f8bf 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseMainActivity.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseMainActivity.kt @@ -383,6 +383,11 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract, R.id.action_settings to GoogleMaterial.Icon.gmd_settings, R.id.action_search to GoogleMaterial.Icon.gmd_search ) + bindSearchView(menu) + return true + } + + private fun bindSearchView(menu: Menu) { searchViewBindIfNull { bindSearchView(menu, R.id.action_search, Prefs.iconColor) { textCallback = { query, searchView -> @@ -414,7 +419,6 @@ abstract class BaseMainActivity : BaseActivity(), MainActivityContract, onItemClick = { _, key, _, _ -> launchWebOverlay(key) } } } - return true } @SuppressLint("RestrictedApi") diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbItem.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbItem.kt index 9ee34ab7..82e15111 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbItem.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbItem.kt @@ -56,6 +56,9 @@ enum class FbItem( PHOTOS(R.string.photos, GoogleMaterial.Icon.gmd_photo, "me/photos"), PROFILE(R.string.profile, CommunityMaterial.Icon.cmd_account, "me"), SAVED(R.string.saved, GoogleMaterial.Icon.gmd_bookmark, "saved"), + /** + * Note that this url only works if a query (?q=) is provided + */ _SEARCH(R.string.kau_search, GoogleMaterial.Icon.gmd_search, "search/top"), SETTINGS(R.string.settings, GoogleMaterial.Icon.gmd_settings, "settings"), ; -- cgit v1.2.3 From b8ab09e645333a76aee19637bda3c4e76f51f5e1 Mon Sep 17 00:00:00 2001 From: Allan Wang Date: Thu, 25 Apr 2019 15:43:38 -0700 Subject: Update some tests --- .../kotlin/com/pitchedapps/frost/facebook/parsers/FbParseTest.kt | 2 ++ app/src/test/kotlin/com/pitchedapps/frost/internal/Internal.kt | 5 +++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/app/src/test/kotlin/com/pitchedapps/frost/facebook/parsers/FbParseTest.kt b/app/src/test/kotlin/com/pitchedapps/frost/facebook/parsers/FbParseTest.kt index 4fe43ca8..11e2502b 100644 --- a/app/src/test/kotlin/com/pitchedapps/frost/facebook/parsers/FbParseTest.kt +++ b/app/src/test/kotlin/com/pitchedapps/frost/facebook/parsers/FbParseTest.kt @@ -21,6 +21,7 @@ import com.pitchedapps.frost.internal.assertComponentsNotEmpty import com.pitchedapps.frost.internal.assertDescending import com.pitchedapps.frost.internal.authDependent import org.junit.BeforeClass +import org.junit.Ignore import org.junit.Test import kotlin.test.assertFalse import kotlin.test.assertNotNull @@ -64,6 +65,7 @@ class FbParseTest { @Test fun messageUser() = MessageParser.queryUser(COOKIE, "allan").test("allan query") + @Ignore("No longer works as search results don't appear in html") @Test fun search() = SearchParser.test() diff --git a/app/src/test/kotlin/com/pitchedapps/frost/internal/Internal.kt b/app/src/test/kotlin/com/pitchedapps/frost/internal/Internal.kt index b8d9635a..41473e86 100644 --- a/app/src/test/kotlin/com/pitchedapps/frost/internal/Internal.kt +++ b/app/src/test/kotlin/com/pitchedapps/frost/internal/Internal.kt @@ -59,7 +59,7 @@ val AUTH: RequestAuth by lazy { } } -val VALID_COOKIE: Boolean by lazy { +private val VALID_COOKIE: Boolean by lazy { val data = testJsoup(FbItem.SETTINGS.url) data.title() == "Settings" } @@ -68,7 +68,8 @@ fun testJsoup(url: String) = frostJsoup(COOKIE, url) fun authDependent() { println("Auth Dependent") - Assume.assumeTrue(COOKIE.isNotEmpty() && VALID_COOKIE) + Assume.assumeTrue("Cookie cannot be empty", COOKIE.isNotEmpty()) + Assume.assumeTrue("Cookie is not valid", VALID_COOKIE) } /** -- cgit v1.2.3