Use multiple streams based on a byteArray for parsing the body response

This commit is contained in:
Shinokuni 2020-09-13 15:15:42 +02:00
parent 15e1723893
commit 156601e0c5
2 changed files with 44 additions and 13 deletions

View File

@ -5,12 +5,15 @@ import android.content.Context
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
import com.readrops.api.utils.HttpManager
import com.readrops.api.utils.LibUtils
import com.readrops.api.utils.ParseException
import com.readrops.api.utils.UnknownFormatException
import junit.framework.TestCase.*
import okhttp3.Headers
import okhttp3.HttpUrl
import okhttp3.mockwebserver.MockResponse
import okhttp3.mockwebserver.MockWebServer
import okio.Buffer
import org.junit.After
import org.junit.Before
import org.junit.Test
@ -40,15 +43,42 @@ class LocalRSSDataSourceTest {
@Test
fun successfulQueryTest() {
val stream = context.resources.assets.open("localfeed/rss_feed.xml")
mockServer.enqueue(MockResponse().setResponseCode(HttpURLConnection.HTTP_OK)
.addHeader(LibUtils.CONTENT_TYPE_HEADER, "application/xml; charset=UTF-8")
.addHeader(LibUtils.ETAG_HEADER, "ETag-value")
.addHeader(LibUtils.LAST_MODIFIED_HEADER, "Last-Modified")
.setBody(Buffer().readFrom(stream)))
val pair = localRSSDataSource.queryRSSResource(url.toString(), null, true)
val feed = pair?.first!!
assertEquals(feed.name, "Hacker News")
assertEquals(feed.siteUrl, "https://news.ycombinator.com/")
assertEquals(feed.description, "Links for the intellectually curious, ranked by readers.")
assertEquals(feed.etag, "ETag-value")
assertEquals(feed.lastModified, "Last-Modified")
assertEquals(pair.second.size, 7)
}
@Test
fun headersTest() {
val stream = context.resources.assets.open("localfeed/rss_feed.xml")
mockServer.enqueue(MockResponse().setResponseCode(HttpURLConnection.HTTP_OK)
.addHeader("Content-Type", "application/rss+xml; charset=UTF-8")
.setBody(context.resources.assets.open("localfeed/rss_feed.xml").toString()))
.setBody(Buffer().readFrom(stream)))
val headers = Headers.headersOf(LibUtils.ETAG_HEADER, "ETag", LibUtils.LAST_MODIFIED_HEADER, "Last-Modified")
localRSSDataSource.queryRSSResource(url.toString(), headers, false)
val pair = localRSSDataSource.queryRSSResource(url.toString(), null, false)
val request = mockServer.takeRequest()
assertNotNull(pair?.first)
assertNotNull(pair?.second)
assertEquals(request.headers[LibUtils.ETAG_HEADER], "ETag")
assertEquals(request.headers[LibUtils.LAST_MODIFIED_HEADER], "Last-Modified")
}
@Test

View File

@ -11,6 +11,7 @@ import okhttp3.Headers
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import java.io.ByteArrayInputStream
import java.io.IOException
import java.io.InputStream
import java.net.HttpURLConnection
@ -38,14 +39,16 @@ class LocalRSSDataSource(private val httpClient: OkHttpClient) {
var type = LocalRSSHelper.getRSSType(contentType)
val bodyArray = response.peekBody(Long.MAX_VALUE).bytes()
// if we can't guess type based on content-type header, we use the content
if (type == LocalRSSHelper.RSSType.UNKNOWN)
type = LocalRSSHelper.getRSSContentType(response.body?.byteStream()!!)
type = LocalRSSHelper.getRSSContentType(ByteArrayInputStream(bodyArray))
// if we can't guess type even with the content, we are unable to go further
if (type == LocalRSSHelper.RSSType.UNKNOWN) throw UnknownFormatException("Unable to guess $url RSS type")
val feed = parseFeed(response, type)
val items = if (withItems) parseItems(response.body?.byteStream()!!, type) else listOf()
val feed = parseFeed(ByteArrayInputStream(bodyArray), type, response)
val items = if (withItems) parseItems(ByteArrayInputStream(bodyArray), type) else listOf()
response.body?.close()
Pair(feed, items)
@ -80,18 +83,17 @@ class LocalRSSDataSource(private val httpClient: OkHttpClient) {
return httpClient.newCall(requestBuilder.build()).execute()
}
private fun parseFeed(response: Response, type: LocalRSSHelper.RSSType): Feed {
private fun parseFeed(stream: InputStream, type: LocalRSSHelper.RSSType, response: Response): Feed {
val feed = if (type != LocalRSSHelper.RSSType.JSONFEED) {
val adapter = XmlAdapter.xmlFeedAdapterFactory(type)
//adapter.fromXml(response.body?.byteStream()!!)
Feed()
adapter.fromXml(stream)
} else {
Feed()
}
feed.etag = response.header(LibUtils.ETAG_HEADER)
feed.lastModified = response.header(LibUtils.IF_MODIFIED_HEADER)
feed.lastModified = response.header(LibUtils.LAST_MODIFIED_HEADER)
return feed
}
@ -100,8 +102,7 @@ class LocalRSSDataSource(private val httpClient: OkHttpClient) {
return if (type != LocalRSSHelper.RSSType.JSONFEED) {
val adapter = XmlAdapter.xmlItemsAdapterFactory(type)
//adapter.fromXml(inputStream)
listOf()
adapter.fromXml(inputStream)
} else {
listOf()
}