aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-android/app/src/test/kotlin/org/meshbay/client
diff options
context:
space:
mode:
Diffstat (limited to 'packages/meshbay-android/app/src/test/kotlin/org/meshbay/client')
-rw-r--r--packages/meshbay-android/app/src/test/kotlin/org/meshbay/client/CastRelayTest.kt68
1 files changed, 59 insertions, 9 deletions
diff --git a/packages/meshbay-android/app/src/test/kotlin/org/meshbay/client/CastRelayTest.kt b/packages/meshbay-android/app/src/test/kotlin/org/meshbay/client/CastRelayTest.kt
index 8013e29..14f49cf 100644
--- a/packages/meshbay-android/app/src/test/kotlin/org/meshbay/client/CastRelayTest.kt
+++ b/packages/meshbay-android/app/src/test/kotlin/org/meshbay/client/CastRelayTest.kt
@@ -158,9 +158,38 @@ class CastRelayTest {
assertEquals(200, get(r.getString("url"), readBytes = 0).status)
}
- @Test fun `a photo starts the relay and is served behind the token, re-addressed when it changes`() {
+ private fun send(bytes: ByteArray, type: String, meta: JSONObject = JSONObject(),
+ cover: ByteArray? = null): String {
+ relay.beginFile(type, bytes.size.toLong(), cover, cover?.let { "image/jpeg" }, meta)
+ var at = 0
+ while (at < bytes.size) { val n = minOf(3, bytes.size - at); relay.writeFile(bytes, at, n); at += n }
+ return relay.endFile().getString("url")
+ }
+
+ private fun getRange(url: String, range: String): Reply {
+ val u = java.net.URI(url)
+ Socket(u.host, u.port).use { s ->
+ s.soTimeout = 5000
+ s.getOutputStream().write("GET ${u.rawPath}?${u.rawQuery} HTTP/1.1\r\nHost: x\r\nRange: $range\r\n\r\n".toByteArray())
+ val input = DataInputStream(s.getInputStream())
+ val lines = ArrayList<String>()
+ val line = StringBuilder()
+ while (true) {
+ val c = input.read()
+ if (c == -1) break
+ if (c == '\n'.code) { val l = line.toString().trimEnd('\r'); if (l.isEmpty()) break; lines.add(l); line.clear() }
+ else line.append(c.toChar())
+ }
+ val headers = lines.drop(1).associate { it.substringBefore(':').lowercase() to it.substringAfter(':').trim() }
+ val body = ByteArray(headers["content-length"]?.toInt() ?: 0)
+ input.readFully(body)
+ return Reply(lines[0].split(' ')[1].toInt(), headers, body)
+ }
+ }
+
+ @Test fun `a file starts the relay and is served behind the token, re-addressed when it changes`() {
val jpeg = byteArrayOf(0xFF.toByte(), 0xD8.toByte(), 1, 2, 3, 0xFF.toByte(), 0xD9.toByte())
- val first = relay.showImage(jpeg, "image/jpeg").getString("url")
+ val first = send(jpeg, "image/jpeg")
assertTrue(relay.active)
val reply = get(first)
assertEquals(200, reply.status)
@@ -169,21 +198,42 @@ class CastRelayTest {
assertArrayEquals(jpeg, reply.body)
assertEquals(403, get(first.replace(Regex("t=[0-9a-f]+"), "t=x")).status)
// A receiver handed the same address twice shows what it already has.
- val second = relay.showImage(byteArrayOf(9), "image/jpeg").getString("url")
+ val second = send(byteArrayOf(9), "image/jpeg")
assertNotEquals(first, second)
assertArrayEquals(byteArrayOf(9), get(second).body)
}
- @Test fun `only a picture is served as one`() {
- val refused = try { relay.showImage(byteArrayOf(1), "text/html"); false } catch (e: IllegalArgumentException) { true }
+ @Test fun `a track is served with its cover, and by range`() {
+ val track = ByteArray(20) { it.toByte() }
+ val cover = byteArrayOf(0xFF.toByte(), 0xD8.toByte(), 7)
+ val url = send(track, "audio/flac", JSONObject().put("title", "A Song").put("artist", "Some Band"), cover)
+ assertEquals("audio/flac", relay.fileType)
+ val meta = relay.fileMeta()!!
+ assertEquals("A Song", meta.getString("title"))
+ assertArrayEquals(cover, get(meta.getString("cover")).body)
+ val part = getRange(url, "bytes=5-9")
+ assertEquals(206, part.status)
+ assertEquals("bytes 5-9/20", part.headers["content-range"])
+ assertArrayEquals(track.copyOfRange(5, 10), part.body)
+ assertArrayEquals(track.copyOfRange(15, 20), getRange(url, "bytes=15-").body)
+ assertEquals(416, getRange(url, "bytes=50-60").status)
+ }
+
+ @Test fun `only a whole picture or sound is served as one`() {
+ val refused = try { relay.beginFile("text/html", 1, null, null, JSONObject()); false } catch (e: IllegalArgumentException) { true }
assertTrue(refused)
- assertNull(relay.imageUrl)
+ assertNull(relay.fileUrl)
+ relay.beginFile("audio/mpeg", 10, null, null, JSONObject())
+ relay.writeFile(byteArrayOf(1, 2, 3))
+ val short = try { relay.endFile(); false } catch (e: IllegalStateException) { true }
+ assertTrue(short)
+ assertNull(relay.fileUrl)
}
- @Test fun `a film started over a photo takes the photo down`() {
- relay.showImage(byteArrayOf(1), "image/jpeg")
+ @Test fun `a film started over a file takes the file down`() {
+ send(byteArrayOf(1), "image/jpeg")
relay.start(null, null)
- assertNull(relay.imageUrl)
+ assertNull(relay.fileUrl)
}
@Test fun `the preflight is answered before the token is checked`() {