Call JSONItemsAdapter in JSONFeedAdapter

This commit is contained in:
Shinokuni 2021-09-04 17:42:24 +02:00
parent 6f2aad79c0
commit 0ac0a1c347
4 changed files with 122 additions and 144 deletions

View File

@ -4,18 +4,21 @@ import com.readrops.api.utils.exceptions.ParseException
import com.readrops.api.utils.extensions.nextNonEmptyString
import com.readrops.api.utils.extensions.nextNullableString
import com.readrops.db.entities.Feed
import com.squareup.moshi.FromJson
import com.squareup.moshi.JsonReader
import com.squareup.moshi.ToJson
import com.readrops.db.entities.Item
import com.squareup.moshi.*
class JSONFeedAdapter {
class JSONFeedAdapter : JsonAdapter<Pair<Feed, List<Item>>>() {
@ToJson
fun toJson(feed: Feed) = ""
override fun toJson(writer: JsonWriter, value: Pair<Feed, List<Item>>?) {
TODO("Not yet implemented")
}
@FromJson
fun fromJson(reader: JsonReader): Feed = try {
override fun fromJson(reader: JsonReader): Pair<Feed, List<Item>> = try {
val feed = Feed()
val items = arrayListOf<Item>()
val itemAdapter = JSONItemsAdapter()
reader.beginObject()
while (reader.hasNext()) {
@ -25,19 +28,20 @@ class JSONFeedAdapter {
1 -> siteUrl = reader.nextNullableString()
2 -> url = reader.nextNullableString()
3 -> description = reader.nextNullableString()
4 -> items += itemAdapter.fromJson(reader)
else -> reader.skipValue()
}
}
}
reader.endObject()
feed
Pair(feed, items)
} catch (e: Exception) {
throw ParseException(e.message)
}
companion object {
val names: JsonReader.Options = JsonReader.Options.of("title", "home_page_url",
"feed_url", "description")
"feed_url", "description", "items")
}
}

View File

@ -17,59 +17,50 @@ class JSONItemsAdapter : JsonAdapter<List<Item>>() {
// not useful
}
override fun fromJson(reader: JsonReader): List<Item> = try {
override fun fromJson(reader: JsonReader): List<Item> = with(reader) {
val items = arrayListOf<Item>()
reader.beginObject()
while (reader.hasNext()) {
when (reader.nextName()) {
"items" -> parseItems(reader, items)
else -> reader.skipValue()
}
}
items
} catch (e: Exception) {
throw ParseException(e.message)
}
private fun parseItems(reader: JsonReader, items: MutableList<Item>) = with(reader) {
beginArray()
while (hasNext()) {
beginObject()
val item = Item()
var contentText: String? = null
var contentHtml: String? = null
try {
beginArray()
while (hasNext()) {
with(item) {
when (selectName(names)) {
0 -> guid = nextNonEmptyString()
1 -> link = nextNonEmptyString()
2 -> title = nextNonEmptyString()
3 -> contentHtml = nextNullableString()
4 -> contentText = nextNullableString()
5 -> description = nextNullableString()
6 -> imageLink = nextNullableString()
7 -> pubDate = DateUtils.parse(nextNullableString())
8 -> author = parseAuthor(reader) // jsonfeed 1.0
9 -> author = parseAuthors(reader) // jsonfeed 1.1
else -> skipValue()
beginObject()
val item = Item()
var contentText: String? = null
var contentHtml: String? = null
while (hasNext()) {
with(item) {
when (selectName(names)) {
0 -> guid = nextNonEmptyString()
1 -> link = nextNonEmptyString()
2 -> title = nextNonEmptyString()
3 -> contentHtml = nextNullableString()
4 -> contentText = nextNullableString()
5 -> description = nextNullableString()
6 -> imageLink = nextNullableString()
7 -> pubDate = DateUtils.parse(nextNullableString())
8 -> author = parseAuthor(reader) // jsonfeed 1.0
9 -> author = parseAuthors(reader) // jsonfeed 1.1
else -> skipValue()
}
}
}
validateItem(item)
item.content = if (contentHtml != null) contentHtml else contentText
if (item.pubDate == null) item.pubDate = LocalDateTime.now()
endObject()
items += item
}
validateItem(item)
item.content = if (contentHtml != null) contentHtml else contentText
if (item.pubDate == null) item.pubDate = LocalDateTime.now()
endObject()
items += item
endArray()
items
} catch (e: Exception) {
throw ParseException(e.message)
}
endArray()
}
private fun parseAuthor(reader: JsonReader): String? {

View File

@ -1,29 +1,95 @@
package com.readrops.api.localfeed.json
import com.readrops.api.TestUtils
import com.readrops.api.utils.DateUtils
import com.readrops.api.utils.exceptions.ParseException
import com.readrops.db.entities.Feed
import com.readrops.db.entities.Item
import com.squareup.moshi.Moshi
import com.squareup.moshi.Types
import junit.framework.TestCase
import junit.framework.TestCase.assertEquals
import junit.framework.TestCase.assertTrue
import okio.Buffer
import org.junit.Assert.assertThrows
import org.junit.Test
class JSONFeedAdapterTest {
private val adapter = Moshi.Builder()
.add(JSONFeedAdapter())
.add(Types.newParameterizedType(Pair::class.java, Feed::class.java,
Types.newParameterizedType(List::class.java, Item::class.java)), JSONFeedAdapter())
.build()
.adapter(Feed::class.java)
.adapter<Pair<Feed, List<Item>>>(Types.newParameterizedType(Pair::class.java, Feed::class.java,
Types.newParameterizedType(List::class.java, Item::class.java)))
@Test
fun normalCasesTest() {
val stream = TestUtils.loadResource("localfeed/json/json_feed.json")
val feed = adapter.fromJson(Buffer().readFrom(stream))!!
val pair = adapter.fromJson(Buffer().readFrom(stream))!!
val feed = pair.first
val items = pair.second
assertEquals(feed.name, "News from Flying Meat")
assertEquals(feed.url, "http://flyingmeat.com/blog/feed.json")
assertEquals(feed.siteUrl, "http://flyingmeat.com/blog/")
assertEquals(feed.description, "News from your friends at Flying Meat.")
with(feed) {
assertEquals(name, "News from Flying Meat")
assertEquals(url, "http://flyingmeat.com/blog/feed.json")
assertEquals(siteUrl, "http://flyingmeat.com/blog/")
assertEquals(description, "News from your friends at Flying Meat.")
}
with(items[0]) {
assertEquals(items.size, 10)
assertEquals(guid, "http://flyingmeat.com/blog/archives/2017/9/acorn_and_10.13.html")
assertEquals(title, "Acorn and 10.13")
assertEquals(link, "http://flyingmeat.com/blog/archives/2017/9/acorn_and_10.13.html")
assertEquals(pubDate, DateUtils.parse("2017-09-25T14:27:27-07:00"))
assertEquals(author, "Author 1")
TestCase.assertNotNull(content)
}
}
@Test
fun otherCasesTest() {
val stream = TestUtils.loadResource("localfeed/json/json_items_other_cases.json")
val item = adapter.fromJson(Buffer().readFrom(stream))!!.second[0]
assertEquals(item.description, "This is a summary")
assertEquals(item.content, "content_html")
assertEquals(item.imageLink, "https://image.com")
assertEquals(item.author, "Author 1, Author 3, Author 4, Author 5, ...")
}
@Test
fun nullDateTest() {
val stream = TestUtils.loadResource("localfeed/json/json_items_no_date.json")
val item = adapter.fromJson(Buffer().readFrom(stream))!!.second[0]
TestCase.assertNotNull(item.pubDate)
}
@Test
fun nullTitleTest() {
val stream = TestUtils.loadResource("localfeed/json/json_items_no_title.json")
val exception = assertThrows(ParseException::class.java) {
adapter.fromJson(Buffer().readFrom(stream))
}
assertEquals("Item title is required", exception.message)
}
@Test
fun nullLinkTest() {
val stream = TestUtils.loadResource("localfeed/json/json_items_no_link.json")
val exception = assertThrows(ParseException::class.java) {
adapter.fromJson(Buffer().readFrom(stream))
}
assertEquals("Item link is required", exception.message)
}
}

View File

@ -1,83 +0,0 @@
package com.readrops.api.localfeed.json
import com.readrops.api.TestUtils
import com.readrops.api.utils.DateUtils
import com.readrops.api.utils.exceptions.ParseException
import com.readrops.db.entities.Item
import com.squareup.moshi.Moshi
import com.squareup.moshi.Types
import junit.framework.TestCase.assertEquals
import junit.framework.TestCase.assertNotNull
import okio.Buffer
import org.junit.Rule
import org.junit.Test
import org.junit.rules.ExpectedException
class JSONItemsAdapterTest {
private val adapter = Moshi.Builder()
.add(Types.newParameterizedType(List::class.java, Item::class.java), JSONItemsAdapter())
.build()
.adapter<List<Item>>(Types.newParameterizedType(List::class.java, Item::class.java))
@get:Rule
val expectedException: ExpectedException = ExpectedException.none()
@Test
fun normalCasesTest() {
val stream = TestUtils.loadResource("localfeed/json/json_feed.json")
val items = adapter.fromJson(Buffer().readFrom(stream))!!
val item = items.first()
assertEquals(items.size, 10)
assertEquals(item.guid, "http://flyingmeat.com/blog/archives/2017/9/acorn_and_10.13.html")
assertEquals(item.title, "Acorn and 10.13")
assertEquals(item.link, "http://flyingmeat.com/blog/archives/2017/9/acorn_and_10.13.html")
assertEquals(item.pubDate, DateUtils.parse("2017-09-25T14:27:27-07:00"))
assertEquals(item.author, "Author 1")
assertNotNull(item.content)
}
@Test
fun otherCasesTest() {
val stream = TestUtils.loadResource("localfeed/json/json_items_other_cases.json")
val item = adapter.fromJson(Buffer().readFrom(stream))!!.first()
assertEquals(item.description, "This is a summary")
assertEquals(item.content, "content_html")
assertEquals(item.imageLink, "https://image.com")
assertEquals(item.author, "Author 1, Author 3, Author 4, Author 5, ...")
}
@Test
fun nullDateTest() {
val stream = TestUtils.loadResource("localfeed/json/json_items_no_date.json")
val item = adapter.fromJson(Buffer().readFrom(stream))!!.first()
assertNotNull(item.pubDate)
}
@Test
fun nullTitleTest() {
val stream = TestUtils.loadResource("localfeed/json/json_items_no_title.json")
expectedException.expect(ParseException::class.java)
expectedException.expectMessage("Item title is required")
adapter.fromJson(Buffer().readFrom(stream))
}
@Test
fun nullLinkTest() {
val stream = TestUtils.loadResource("localfeed/json/json_items_no_link.json")
expectedException.expect(ParseException::class.java)
expectedException.expectMessage("Item link is required")
adapter.fromJson(Buffer().readFrom(stream))
}
}