diff options
author | Allan Wang <me@allanwang.ca> | 2018-12-31 18:57:28 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-12-31 18:57:28 -0500 |
commit | 149c6be1bfd4bd84381757940fece1be7b9801aa (patch) | |
tree | 85fe10e3ee3ea34ad717f0d61975ca0119dd36d5 /app/src/test/kotlin | |
parent | 7661bbfc9b8f34bf9d92dc08a9fcd7cc6ec7cbb3 (diff) | |
download | frost-149c6be1bfd4bd84381757940fece1be7b9801aa.tar.gz frost-149c6be1bfd4bd84381757940fece1be7b9801aa.tar.bz2 frost-149c6be1bfd4bd84381757940fece1be7b9801aa.zip |
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
Diffstat (limited to 'app/src/test/kotlin')
-rw-r--r-- | app/src/test/kotlin/com/pitchedapps/frost/debugger/OfflineWebsiteTest.kt | 225 | ||||
-rw-r--r-- | app/src/test/kotlin/com/pitchedapps/frost/kotlin/FlyweightTest.kt (renamed from app/src/test/kotlin/com/pitchedapps/frost/rx/FlyweightTest.kt) | 3 | ||||
-rw-r--r-- | app/src/test/kotlin/com/pitchedapps/frost/rx/ResettableFlyweightTest.kt | 73 |
3 files changed, 217 insertions, 84 deletions
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 = """ + <!DOCTYPE html> + <html> + <head></head> + <body> + <h1>Single File Test</h1> + </body> + </html> + """.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 = """ + <!DOCTYPE html> + <html> + <head> + <link rel="stylesheet" href="$cssUrl"> + </head> + <body> + <h1>Css File Test</h1> + </body> + </html> + """.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 = """ + <!DOCTYPE html> + <html> + <head></head> + <body> + <h1>Js File Test</h1> + <script type="text/javascript" src="$jsUrl"></script> + </body> + </html> + """.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 = """ + <!DOCTYPE html> + <html> + <head> + <link rel="stylesheet" href="$css1Url"> + <link rel="stylesheet" href="$css2Url"> + </head> + <body> + <h1>Multi File Test</h1> + <script type="text/javascript" src="$js1Url"></script> + <script type="text/javascript" src="$js2Url"></script> + </body> + </html> + """.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) } } diff --git a/app/src/test/kotlin/com/pitchedapps/frost/rx/FlyweightTest.kt b/app/src/test/kotlin/com/pitchedapps/frost/kotlin/FlyweightTest.kt index b58878cb..0eee530e 100644 --- a/app/src/test/kotlin/com/pitchedapps/frost/rx/FlyweightTest.kt +++ b/app/src/test/kotlin/com/pitchedapps/frost/kotlin/FlyweightTest.kt @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -package com.pitchedapps.frost.rx +package com.pitchedapps.frost.kotlin import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.async @@ -118,7 +118,6 @@ class FlyweightTest { "Incorrect error found on fetch cancelled by destruction" ) } - println("Done") } } } diff --git a/app/src/test/kotlin/com/pitchedapps/frost/rx/ResettableFlyweightTest.kt b/app/src/test/kotlin/com/pitchedapps/frost/rx/ResettableFlyweightTest.kt deleted file mode 100644 index 26a5a8de..00000000 --- a/app/src/test/kotlin/com/pitchedapps/frost/rx/ResettableFlyweightTest.kt +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2018 Allan Wang - * - * 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. - * - * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. - */ -package com.pitchedapps.frost.rx - -import com.pitchedapps.frost.internal.concurrentTest -import org.junit.Before -import org.junit.Test - -/** - * Created by Allan Wang on 07/01/18. - */ -private inline val threadId - get() = Thread.currentThread().id - -class ResettableFlyweightTest { - - class IntFlyweight : RxFlyweight<Int, Long, Long>() { - override fun call(input: Int): Long { - println("Call for $input on thread $threadId") - Thread.sleep(20) - return System.currentTimeMillis() - } - - override fun validate(input: Int, cond: Long) = System.currentTimeMillis() - cond < 500 - - override fun cache(input: Int): Long = System.currentTimeMillis() - } - - private lateinit var flyweight: IntFlyweight - - @Before - fun init() { - flyweight = IntFlyweight() - } - - @Test - fun testCache() = concurrentTest { result -> - flyweight(1).subscribe { i, _ -> - flyweight(1).subscribe { j, _ -> - if (i != null && i == j) - result.onComplete() - else - result.onError("Did not use cache during calls") - } - } - } - - @Test - fun testNoCache() = concurrentTest { result -> - flyweight(1).subscribe { i, _ -> - flyweight(2).subscribe { j, _ -> - if (i != null && i != j) - result.onComplete() - else - result.onError("Should not use cache for calls with different keys") - } - } - } -} |