From 1769dbcef9786b847ffeaebdf6ecced45da9222c Mon Sep 17 00:00:00 2001 From: Allan Wang Date: Tue, 26 Dec 2017 03:37:32 -0500 Subject: Enhancement/fb requests (#575) * Update lambdas to references * Simplify regex and parsers * Fix some parsing and add more tests * Improve message parser and tests * Simplify parser * Shorten interfaces * Push rem * Create notification parser * Clean up notification service * Clean up notification service * Add safe cookie fallback * Fix cookie reference * Make parsers only hold cookie string * Clean up cookie references * Fix up login and event theme * Update changelog Remove workspace backup --- .../com/pitchedapps/frost/facebook/FbParseTest.kt | 46 +++++++++++++++++++ .../com/pitchedapps/frost/facebook/FbRegexTest.kt | 41 +++++++++++++++++ .../pitchedapps/frost/facebook/FbRequestTest.kt | 45 +++++++----------- .../com/pitchedapps/frost/internal/Internal.kt | 53 ++++++++++++++++++++-- .../pitchedapps/frost/parsers/MessageParserTest.kt | 4 +- .../pitchedapps/frost/parsers/ParserTestHelper.kt | 2 +- 6 files changed, 158 insertions(+), 33 deletions(-) create mode 100644 app/src/test/kotlin/com/pitchedapps/frost/facebook/FbParseTest.kt create mode 100644 app/src/test/kotlin/com/pitchedapps/frost/facebook/FbRegexTest.kt (limited to 'app/src/test') diff --git a/app/src/test/kotlin/com/pitchedapps/frost/facebook/FbParseTest.kt b/app/src/test/kotlin/com/pitchedapps/frost/facebook/FbParseTest.kt new file mode 100644 index 00000000..65777f97 --- /dev/null +++ b/app/src/test/kotlin/com/pitchedapps/frost/facebook/FbParseTest.kt @@ -0,0 +1,46 @@ +package com.pitchedapps.frost.facebook + +import com.pitchedapps.frost.internal.COOKIE +import com.pitchedapps.frost.internal.assertComponentsNotEmpty +import com.pitchedapps.frost.internal.assertDescending +import com.pitchedapps.frost.internal.authDependent +import com.pitchedapps.frost.parsers.* +import org.junit.BeforeClass +import org.junit.Test +import kotlin.test.fail + +/** + * Created by Allan Wang on 24/12/17. + */ +class FbParseTest { + + companion object { + @BeforeClass + @JvmStatic + fun before() { + authDependent() + } + } + + private inline fun FrostParser.test(action: T.() -> Unit = {}) { + val response = parse(COOKIE) + ?: fail("${this::class.java.simpleName} returned null for $url") + println(response) + response.data.action() + } + + @Test + fun message() = MessageParser.test { + threads.forEach(FrostThread::assertComponentsNotEmpty) + threads.map(FrostThread::time).assertDescending("thread time values") + } + + @Test + fun search() = SearchParser.test() + + @Test + fun notif() = NotifParser.test { + notifs.forEach(FrostNotif::assertComponentsNotEmpty) + notifs.map(FrostNotif::time).assertDescending("notif time values") + } +} \ No newline at end of file diff --git a/app/src/test/kotlin/com/pitchedapps/frost/facebook/FbRegexTest.kt b/app/src/test/kotlin/com/pitchedapps/frost/facebook/FbRegexTest.kt new file mode 100644 index 00000000..a21bcb13 --- /dev/null +++ b/app/src/test/kotlin/com/pitchedapps/frost/facebook/FbRegexTest.kt @@ -0,0 +1,41 @@ +package com.pitchedapps.frost.facebook + +import org.apache.commons.text.StringEscapeUtils +import org.junit.Test +import kotlin.test.assertEquals + +/** + * Created by Allan Wang on 24/12/17. + */ +class FbRegexTest { + @Test + fun userIdRegex() { + val id = 12349876L + val cookie = "wd=1366x615; c_user=$id; act=1234%2F12; m_pixel_ratio=1; presence=hello; x-referer=asdfasdf" + assertEquals(id, FB_USER_MATCHER.find(cookie)[1]?.toLong()) + } + + @Test + fun fbDtsgRegex() { + val fb_dtsg = "readme" + val input = "data-sigil=\"mbasic_inline_feed_composer\">\u003Cinput type=\"hidden\" name=\"fb_dtsg\" value=\"$fb_dtsg\" autocomplete=\"off\" \\/>\u003Cinput type=\"hidden\" name=\"privacyx\" value=\"12345\"" + assertEquals(fb_dtsg, FB_DTSG_MATCHER.find(input)[1]) + } + + @Test + fun ppRegex() { + val img = "https\\3a //scontent-yyz1-1.xx.fbcdn.net/v/asdf1234.jpg?efg\\3d 333\\26 oh\\3d 77\\26 oe\\3d 444" + val ppStyle = "background:#d8dce6 url('$img') no-repeat center;background-size:100% 100%;-webkit-background-size:100% 100%;width:58px;height:58px;" + assertEquals(StringEscapeUtils.unescapeCsv(img), StringEscapeUtils.unescapeCsv(FB_CSS_URL_MATCHER.find(ppStyle)[1])) + } + + @Test + fun msgNotifIdRegex() { + val id = 1273491646093428L + val data = "threadlist_row_other_user_fbid_thread_fbid_$id" + assertEquals(id, FB_MESSAGE_NOTIF_ID_MATCHER.find(data)[1]?.toLong(), "thread_fbid mismatch") + val userData = "threadlist_row_other_user_fbid_${id}thread_fbid_" + assertEquals(id, FB_MESSAGE_NOTIF_ID_MATCHER.find(userData)[1]?.toLong(), "user_fbid mismatch") + + } +} \ No newline at end of file diff --git a/app/src/test/kotlin/com/pitchedapps/frost/facebook/FbRequestTest.kt b/app/src/test/kotlin/com/pitchedapps/frost/facebook/FbRequestTest.kt index a521ceda..16894b16 100644 --- a/app/src/test/kotlin/com/pitchedapps/frost/facebook/FbRequestTest.kt +++ b/app/src/test/kotlin/com/pitchedapps/frost/facebook/FbRequestTest.kt @@ -1,14 +1,13 @@ package com.pitchedapps.frost.facebook +import com.pitchedapps.frost.internal.AUTH import com.pitchedapps.frost.internal.COOKIE -import com.pitchedapps.frost.internal.FB_DTSG import com.pitchedapps.frost.internal.USER_ID -import org.junit.Assume +import com.pitchedapps.frost.internal.authDependent +import okhttp3.Call import org.junit.BeforeClass import org.junit.Test -import kotlin.test.assertEquals -import kotlin.test.assertFalse -import kotlin.test.assertNotNull +import kotlin.test.* /** * Created by Allan Wang on 21/12/17. @@ -19,44 +18,34 @@ class FbRequestTest { @BeforeClass @JvmStatic fun before() { - Assume.assumeTrue(COOKIE.isNotEmpty()) + authDependent() } - - val AUTH: RequestAuth by lazy { RequestAuth(USER_ID, COOKIE, FB_DTSG) } } - @Test - fun userIdRegex() { - val id = 12349876L - val cookie = "wd=1366x615; c_user=$id; act=1234%2F12; m_pixel_ratio=1; presence=hello; x-referer=asdfasdf" - assertEquals(id, FB_USER_MATCHER.find(cookie)?.groupValues?.get(1)?.toLong()) - } - - @Test - fun fbDtsgRegex() { - val fb_dtsg = "readme" - val input = "data-sigil=\"mbasic_inline_feed_composer\">\u003Cinput type=\"hidden\" name=\"fb_dtsg\" value=\"$fb_dtsg\" autocomplete=\"off\" \\/>\u003Cinput type=\"hidden\" name=\"privacyx\" value=\"12345\"" - assertEquals(fb_dtsg, FB_DTSG_MATCHER.find(input)?.groupValues?.get(1)) + /** + * Used to emulate [executeAndCheck] + * Must be consistent with that method + */ + private fun Call.assertNoError() { + val data = execute().body()?.string() ?: fail("Content was null") + println("Call response: $data") + assertTrue(data.isNotEmpty(), "Content was empty") + assertFalse(data.contains("error"), "Content had error") } @Test fun auth() { val auth = (USER_ID to COOKIE).getAuth() assertNotNull(auth) - assertEquals(USER_ID, auth!!.userId) + assertEquals(USER_ID, auth.userId) assertEquals(COOKIE, auth.cookie) - println("Test auth: priv $FB_DTSG, test ${auth.fb_dtsg}") + println("Test auth: ${auth.fb_dtsg}") } @Test fun markNotification() { val notifId = 1513544657695779 - - val out = AUTH.markNotificationRead(notifId) - .execute().body()?.string() ?: "" - println(out) - - assertFalse(out.contains("error")) + AUTH.markNotificationRead(notifId).assertNoError() } } \ No newline at end of file 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 91eb968d..deaed333 100644 --- a/app/src/test/kotlin/com/pitchedapps/frost/internal/Internal.kt +++ b/app/src/test/kotlin/com/pitchedapps/frost/internal/Internal.kt @@ -1,9 +1,15 @@ package com.pitchedapps.frost.internal -import com.pitchedapps.frost.facebook.FB_USER_MATCHER +import com.pitchedapps.frost.facebook.* +import com.pitchedapps.frost.utils.frostJsoup +import org.junit.Assume import java.io.File import java.io.FileInputStream import java.util.* +import kotlin.reflect.full.starProjectedType +import kotlin.test.assertEquals +import kotlin.test.assertTrue +import kotlin.test.fail /** * Created by Allan Wang on 21/12/17. @@ -24,5 +30,46 @@ val PROPS: Properties by lazy { } val COOKIE: String by lazy { PROPS.getProperty("COOKIE") ?: "" } -val FB_DTSG: String by lazy { PROPS.getProperty("FB_DTSG") ?: "" } -val USER_ID: Long by lazy { FB_USER_MATCHER.find(COOKIE)?.groupValues?.get(1)?.toLong() ?: -1 } +val USER_ID: Long by lazy { FB_USER_MATCHER.find(COOKIE)[1]?.toLong() ?: -1 } +val AUTH: RequestAuth by lazy { + (USER_ID to COOKIE).getAuth().apply { + println("Auth:\nuser:$userId\nfb_dtsg: $fb_dtsg\nrev: $rev\nvalid: $isValid") + } +} + +val VALID_COOKIE: Boolean by lazy { + val data = testJsoup(FbItem.SETTINGS.url) + data.title() == "Settings" +} + +fun testJsoup(url: String) = frostJsoup(COOKIE, url) + +fun authDependent() { + println("Auth Dependent") + Assume.assumeTrue(COOKIE.isNotEmpty() && VALID_COOKIE) + Assume.assumeTrue(AUTH.isValid) +} + +/** + * Check that component strings are nonempty and are properly parsed + * To be used for data classes + */ +fun Any.assertComponentsNotEmpty() { + val components = this::class.members.filter { it.name.startsWith("component") } + if (components.isEmpty()) + fail("${this::class.simpleName} has no components") + components.forEach { + when (it.returnType) { + String::class.starProjectedType -> { + val result = it.call(this) as String + assertTrue(result.isNotEmpty(), "${it.name} returned empty string") + if (result.startsWith("https")) + assertTrue(result.startsWith("https://"), "${it.name} has poorly formatted output $result") + } + } + } +} + +fun > List.assertDescending(tag: String) { + assertEquals(sortedDescending(), this, "$tag not sorted in descending order") +} \ No newline at end of file diff --git a/app/src/test/kotlin/com/pitchedapps/frost/parsers/MessageParserTest.kt b/app/src/test/kotlin/com/pitchedapps/frost/parsers/MessageParserTest.kt index 61c69c40..ecebed04 100644 --- a/app/src/test/kotlin/com/pitchedapps/frost/parsers/MessageParserTest.kt +++ b/app/src/test/kotlin/com/pitchedapps/frost/parsers/MessageParserTest.kt @@ -1,6 +1,8 @@ package com.pitchedapps.frost.parsers +import com.pitchedapps.frost.facebook.FB_EPOCH_MATCHER import com.pitchedapps.frost.facebook.formattedFbUrl +import com.pitchedapps.frost.facebook.get import org.junit.Test import kotlin.test.assertEquals @@ -15,7 +17,7 @@ class MessageParserTest { @Test fun parseEpoch() { val input = "{\"time\":1507301642,\"short\":true,\"forceseconds\":false}" - assertEquals(1507301642, FrostRegex.epoch.find(input)!!.groupValues[1].toLong()) + assertEquals(1507301642, FB_EPOCH_MATCHER.find(input)[1]!!.toLong()) } @Test diff --git a/app/src/test/kotlin/com/pitchedapps/frost/parsers/ParserTestHelper.kt b/app/src/test/kotlin/com/pitchedapps/frost/parsers/ParserTestHelper.kt index be5ac624..53495ecb 100644 --- a/app/src/test/kotlin/com/pitchedapps/frost/parsers/ParserTestHelper.kt +++ b/app/src/test/kotlin/com/pitchedapps/frost/parsers/ParserTestHelper.kt @@ -18,5 +18,5 @@ fun T.getResource(path: String): String? { fun T.debug(path: String, parser: FrostParser

) { val content = getResource("priv/$path.html") ?: return - println(parser.debug(content)) +// println(parser.debug(content)) } \ No newline at end of file -- cgit v1.2.3