From 149c6be1bfd4bd84381757940fece1be7b9801aa Mon Sep 17 00:00:00 2001 From: Allan Wang Date: Mon, 31 Dec 2018 18:57:28 -0500 Subject: Enhancement/coroutines (#1273) * Convert rest of fbcookie to suspended methods * Replace active checks with yield * Apply spotless * Switch cookie domain to exact url * Optimize imports and enable travis tests again * Update proguard rules * Remove unnecessary yield * Remove unused flyweight * Remove unused disposable and method * Use contexthelper instead of dispatcher main * Convert login activity to coroutines * Use kau helper methods for coroutines * Enhancement/offline site (#1288) * Begin conversion of offline site logic * Fix offline tests and add validation tests * Ignore cookie in jsoup if it is blank * Force load and zip to be in io * Use different zip files to fix tests * Log all test output * Do not log stdout * Allow test skip for fb offline --- .../frost/debugger/OfflineWebsiteTest.kt | 225 ++++++++++++++++++++- 1 file changed, 216 insertions(+), 9 deletions(-) (limited to 'app/src/test/kotlin/com/pitchedapps/frost/debugger') diff --git a/app/src/test/kotlin/com/pitchedapps/frost/debugger/OfflineWebsiteTest.kt b/app/src/test/kotlin/com/pitchedapps/frost/debugger/OfflineWebsiteTest.kt index f7dad4d3..07c92fbf 100644 --- a/app/src/test/kotlin/com/pitchedapps/frost/debugger/OfflineWebsiteTest.kt +++ b/app/src/test/kotlin/com/pitchedapps/frost/debugger/OfflineWebsiteTest.kt @@ -18,24 +18,231 @@ package com.pitchedapps.frost.debugger import com.pitchedapps.frost.facebook.FB_URL_BASE import com.pitchedapps.frost.internal.COOKIE +import kotlinx.coroutines.runBlocking +import okhttp3.mockwebserver.Dispatcher +import okhttp3.mockwebserver.MockResponse +import okhttp3.mockwebserver.MockWebServer +import okhttp3.mockwebserver.RecordedRequest +import org.junit.Assume.assumeTrue import org.junit.Test import java.io.File -import java.util.concurrent.CountDownLatch +import java.util.zip.ZipFile +import kotlin.test.AfterTest +import kotlin.test.BeforeTest +import kotlin.test.assertEquals +import kotlin.test.assertNotNull +import kotlin.test.assertTrue /** * Created by Allan Wang on 05/01/18. */ class OfflineWebsiteTest { + lateinit var server: MockWebServer + lateinit var baseDir: File + + @BeforeTest + fun before() { + val buildPath = if (File("").absoluteFile.name == "app") "build/offline_test" else "app/build/offline_test" + baseDir = File(buildPath) + assertTrue(baseDir.deleteRecursively(), "Failed to clean base dir") + server = MockWebServer() + server.start() + } + + @AfterTest + fun after() { + server.shutdown() + } + + private fun zipAndFetch(url: String = server.url("/").toString(), cookie: String = ""): ZipFile { + val name = "test${System.currentTimeMillis()}" + runBlocking { + val success = OfflineWebsite(url, cookie, baseDir = baseDir) + .loadAndZip(name) + assertTrue(success, "An error occurred") + } + + return ZipFile(File(baseDir, "$name.zip")) + } + + private val tagWhitespaceRegex = Regex(">\\s+<", setOf(RegexOption.MULTILINE)) + + private fun ZipFile.assertContentEquals(path: String, content: String) { + val entry = getEntry(path) + assertNotNull(entry, "Entry $path not found") + val actualContent = getInputStream(entry).bufferedReader().use { it.readText() } + assertEquals( + content.replace(tagWhitespaceRegex, "><").toLowerCase(), + actualContent.replace(tagWhitespaceRegex, "><").toLowerCase(), "Content mismatch for $path" + ) + } + + @Test + fun fbOffline() { + // Not really a test. Skip in CI + assumeTrue(COOKIE.isNotEmpty()) + zipAndFetch(FB_URL_BASE) + } + + @Test + fun basicSingleFile() { + val content = """ + + + + +

Single File Test

+ + + """.trimIndent() + + server.enqueue(MockResponse().setBody(content)) + + val zip = zipAndFetch() + + assertEquals(1, zip.size(), "1 file expected") + zip.assertContentEquals("index.html", content) + } + @Test - fun basic() { - val countdown = CountDownLatch(1) - val buildPath = if (File(".").parentFile?.name == "app") "build/offline_test" else "app/build/offline_test" - OfflineWebsite(FB_URL_BASE, COOKIE, baseDir = File(buildPath)) - .loadAndZip("test") { - println("Outcome $it") - countdown.countDown() + fun withCssAsset() { + val cssUrl = server.url("1.css") + + val content = """ + + + + + + +

Css File Test

+ + + """.trimIndent() + + val css1 = """ + .hello { + display: none; } - countdown.await() + """.trimIndent() + + server.setDispatcher(object : Dispatcher() { + override fun dispatch(request: RecordedRequest): MockResponse = + when { + request.path.contains(cssUrl.encodedPath()) -> MockResponse().setBody(css1) + else -> MockResponse().setBody(content) + } + }) + + val zip = zipAndFetch() + + assertEquals(2, zip.size(), "2 files expected") + zip.assertContentEquals("index.html", content.replace(cssUrl.toString(), "assets/a0_1.css")) + zip.assertContentEquals("assets/a0_1.css", css1) + } + + @Test + fun withJsAsset() { + val jsUrl = server.url("1.js") + + val content = """ + + + + +

Js File Test

+ + + + """.trimIndent() + + val js1 = """ + console.log('hello'); + """.trimIndent() + + server.setDispatcher(object : Dispatcher() { + override fun dispatch(request: RecordedRequest): MockResponse = + when { + request.path.contains(jsUrl.encodedPath()) -> MockResponse().setBody(js1) + else -> MockResponse().setBody(content) + } + }) + + val zip = zipAndFetch() + + assertEquals(2, zip.size(), "2 files expected") + zip.assertContentEquals("index.html", content.replace(jsUrl.toString(), "assets/a0_1.js.txt")) + zip.assertContentEquals("assets/a0_1.js.txt", js1) + } + + @Test + fun fullTest() { + val css1Url = server.url("1.css") + val css2Url = server.url("2.css") + val js1Url = server.url("1.js") + val js2Url = server.url("2.js") + + val content = """ + + + + + + + +

Multi File Test

+ + + + + """.trimIndent() + + val css1 = """ + .hello { + display: none; + } + """.trimIndent() + + val css2 = """ + .world { + display: none; + } + """.trimIndent() + + val js1 = """ + console.log('hello'); + """.trimIndent() + + val js2 = """ + console.log('world'); + """.trimIndent() + + server.setDispatcher(object : Dispatcher() { + override fun dispatch(request: RecordedRequest): MockResponse = + when { + request.path.contains(css1Url.encodedPath()) -> MockResponse().setBody(css1) + request.path.contains(css2Url.encodedPath()) -> MockResponse().setBody(css2) + request.path.contains(js1Url.encodedPath()) -> MockResponse().setBody(js1) + request.path.contains(js2Url.encodedPath()) -> MockResponse().setBody(js2) + else -> MockResponse().setBody(content) + } + }) + + val zip = zipAndFetch() + + assertEquals(5, zip.size(), "2 files expected") + zip.assertContentEquals( + "index.html", content + .replace(css1Url.toString(), "assets/a0_1.css") + .replace(css2Url.toString(), "assets/a1_2.css") + .replace(js1Url.toString(), "assets/a2_1.js.txt") + .replace(js2Url.toString(), "assets/a3_2.js.txt") + ) + + zip.assertContentEquals("assets/a0_1.css", css1) + zip.assertContentEquals("assets/a1_2.css", css2) + zip.assertContentEquals("assets/a2_1.js.txt", js1) + zip.assertContentEquals("assets/a3_2.js.txt", js2) } } -- cgit v1.2.3