Add tests for FreshRSS adapters
This commit is contained in:
parent
be90fa8d99
commit
25ebc8305d
@ -2,6 +2,8 @@ package com.readrops.api.services.freshrss.adapters
|
|||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import com.readrops.api.utils.exceptions.ParseException
|
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.readrops.db.entities.Feed
|
||||||
import com.squareup.moshi.FromJson
|
import com.squareup.moshi.FromJson
|
||||||
import com.squareup.moshi.JsonReader
|
import com.squareup.moshi.JsonReader
|
||||||
@ -29,11 +31,11 @@ class FreshRSSFeedsAdapter {
|
|||||||
while (reader.hasNext()) {
|
while (reader.hasNext()) {
|
||||||
with(feed) {
|
with(feed) {
|
||||||
when (reader.selectName(NAMES)) {
|
when (reader.selectName(NAMES)) {
|
||||||
0 -> name = reader.nextString()
|
0 -> name = reader.nextNonEmptyString()
|
||||||
1 -> url = reader.nextString()
|
1 -> url = reader.nextNonEmptyString()
|
||||||
2 -> siteUrl = reader.nextString()
|
2 -> siteUrl = reader.nextNullableString()
|
||||||
3 -> iconUrl = reader.nextString()
|
3 -> iconUrl = reader.nextNullableString()
|
||||||
4 -> remoteId = reader.nextString()
|
4 -> remoteId = reader.nextNonEmptyString()
|
||||||
5 -> remoteFolderId = getCategoryId(reader)
|
5 -> remoteFolderId = getCategoryId(reader)
|
||||||
else -> reader.skipValue()
|
else -> reader.skipValue()
|
||||||
}
|
}
|
||||||
@ -62,7 +64,7 @@ class FreshRSSFeedsAdapter {
|
|||||||
|
|
||||||
while (reader.hasNext()) {
|
while (reader.hasNext()) {
|
||||||
when (reader.nextName()) {
|
when (reader.nextName()) {
|
||||||
"id" -> id = reader.nextString()
|
"id" -> id = reader.nextNullableString()
|
||||||
else -> reader.skipValue()
|
else -> reader.skipValue()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package com.readrops.api.services.freshrss.adapters
|
|||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import com.readrops.api.utils.exceptions.ParseException
|
import com.readrops.api.utils.exceptions.ParseException
|
||||||
|
import com.readrops.api.utils.extensions.nextNonEmptyString
|
||||||
import com.readrops.db.entities.Folder
|
import com.readrops.db.entities.Folder
|
||||||
import com.squareup.moshi.FromJson
|
import com.squareup.moshi.FromJson
|
||||||
import com.squareup.moshi.JsonReader
|
import com.squareup.moshi.JsonReader
|
||||||
@ -33,7 +34,7 @@ class FreshRSSFoldersAdapter {
|
|||||||
with(folder) {
|
with(folder) {
|
||||||
when (reader.selectName(NAMES)) {
|
when (reader.selectName(NAMES)) {
|
||||||
0 -> {
|
0 -> {
|
||||||
val id = reader.nextString()
|
val id = reader.nextNonEmptyString()
|
||||||
name = StringTokenizer(id, "/")
|
name = StringTokenizer(id, "/")
|
||||||
.toList()
|
.toList()
|
||||||
.last() as String
|
.last() as String
|
||||||
|
@ -4,6 +4,8 @@ import android.util.TimingLogger
|
|||||||
import com.readrops.api.services.freshrss.FreshRSSDataSource.GOOGLE_READ
|
import com.readrops.api.services.freshrss.FreshRSSDataSource.GOOGLE_READ
|
||||||
import com.readrops.api.services.freshrss.FreshRSSDataSource.GOOGLE_STARRED
|
import com.readrops.api.services.freshrss.FreshRSSDataSource.GOOGLE_STARRED
|
||||||
import com.readrops.api.utils.exceptions.ParseException
|
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.Item
|
import com.readrops.db.entities.Item
|
||||||
import com.squareup.moshi.JsonAdapter
|
import com.squareup.moshi.JsonAdapter
|
||||||
import com.squareup.moshi.JsonReader
|
import com.squareup.moshi.JsonReader
|
||||||
@ -18,7 +20,6 @@ class FreshRSSItemsAdapter : JsonAdapter<List<Item>>() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun fromJson(reader: JsonReader): List<Item>? {
|
override fun fromJson(reader: JsonReader): List<Item>? {
|
||||||
val logger = TimingLogger(TAG, "item parsing")
|
|
||||||
val items = mutableListOf<Item>()
|
val items = mutableListOf<Item>()
|
||||||
|
|
||||||
return try {
|
return try {
|
||||||
@ -29,9 +30,6 @@ class FreshRSSItemsAdapter : JsonAdapter<List<Item>>() {
|
|||||||
|
|
||||||
reader.endObject()
|
reader.endObject()
|
||||||
|
|
||||||
logger.addSplit("item parsing done")
|
|
||||||
logger.dumpToLog()
|
|
||||||
|
|
||||||
items
|
items
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
throw ParseException(e.message)
|
throw ParseException(e.message)
|
||||||
@ -48,15 +46,15 @@ class FreshRSSItemsAdapter : JsonAdapter<List<Item>>() {
|
|||||||
while (reader.hasNext()) {
|
while (reader.hasNext()) {
|
||||||
with(item) {
|
with(item) {
|
||||||
when (reader.selectName(NAMES)) {
|
when (reader.selectName(NAMES)) {
|
||||||
0 -> remoteId = reader.nextString()
|
0 -> remoteId = reader.nextNonEmptyString()
|
||||||
1 -> pubDate = LocalDateTime(reader.nextLong() * 1000L,
|
1 -> pubDate = LocalDateTime(reader.nextLong() * 1000L,
|
||||||
DateTimeZone.getDefault())
|
DateTimeZone.getDefault())
|
||||||
2 -> title = reader.nextString()
|
2 -> title = reader.nextNonEmptyString()
|
||||||
3 -> content = getContent(reader)
|
3 -> content = getContent(reader)
|
||||||
4 -> link = getLink(reader)
|
4 -> link = getLink(reader)
|
||||||
5 -> getStates(reader, this)
|
5 -> getStates(reader, this)
|
||||||
6 -> feedRemoteId = getRemoteFeedId(reader)
|
6 -> feedRemoteId = getRemoteFeedId(reader)
|
||||||
7 -> author = reader.nextString()
|
7 -> author = reader.nextNullableString()
|
||||||
else -> reader.skipValue()
|
else -> reader.skipValue()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -75,7 +73,7 @@ class FreshRSSItemsAdapter : JsonAdapter<List<Item>>() {
|
|||||||
|
|
||||||
while (reader.hasNext()) {
|
while (reader.hasNext()) {
|
||||||
when (reader.nextName()) {
|
when (reader.nextName()) {
|
||||||
"content" -> content = reader.nextString()
|
"content" -> content = reader.nextNullableString()
|
||||||
else -> reader.skipValue()
|
else -> reader.skipValue()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -92,7 +90,7 @@ class FreshRSSItemsAdapter : JsonAdapter<List<Item>>() {
|
|||||||
reader.beginObject()
|
reader.beginObject()
|
||||||
|
|
||||||
when (reader.nextName()) {
|
when (reader.nextName()) {
|
||||||
"href" -> href = reader.nextString()
|
"href" -> href = reader.nextNullableString()
|
||||||
else -> reader.skipValue()
|
else -> reader.skipValue()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,6 +108,7 @@ class FreshRSSItemsAdapter : JsonAdapter<List<Item>>() {
|
|||||||
when (reader.nextString()) {
|
when (reader.nextString()) {
|
||||||
GOOGLE_READ -> item.isRead = true
|
GOOGLE_READ -> item.isRead = true
|
||||||
GOOGLE_STARRED -> item.isStarred = true
|
GOOGLE_STARRED -> item.isStarred = true
|
||||||
|
else -> reader.skipValue()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,6 +134,6 @@ class FreshRSSItemsAdapter : JsonAdapter<List<Item>>() {
|
|||||||
val NAMES: JsonReader.Options = JsonReader.Options.of("id", "published", "title",
|
val NAMES: JsonReader.Options = JsonReader.Options.of("id", "published", "title",
|
||||||
"summary", "alternate", "categories", "origin", "author")
|
"summary", "alternate", "categories", "origin", "author")
|
||||||
|
|
||||||
val TAG = FreshRSSItemsAdapter::class.java.simpleName
|
val TAG: String = FreshRSSItemsAdapter::class.java.simpleName
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
package com.readrops.api.services.freshrss.adapters
|
||||||
|
|
||||||
|
import com.readrops.api.TestUtils
|
||||||
|
import com.readrops.db.entities.Feed
|
||||||
|
import com.squareup.moshi.Moshi
|
||||||
|
import com.squareup.moshi.Types
|
||||||
|
import junit.framework.TestCase.assertEquals
|
||||||
|
import okio.Buffer
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
class FreshRSSFeedsAdapterTest {
|
||||||
|
|
||||||
|
private val adapter = Moshi.Builder()
|
||||||
|
.add(FreshRSSFeedsAdapter())
|
||||||
|
.build()
|
||||||
|
.adapter<List<Feed>>(Types.newParameterizedType(List::class.java, Feed::class.java))
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun validFeedsTest() {
|
||||||
|
val stream = TestUtils.loadResource("services/freshrss/adapters/feeds.json")
|
||||||
|
|
||||||
|
val feed = adapter.fromJson(Buffer().readFrom(stream))!![0]
|
||||||
|
|
||||||
|
with(feed) {
|
||||||
|
assertEquals(remoteId, "feed/2")
|
||||||
|
assertEquals(name, "FreshRSS @ GitHub")
|
||||||
|
assertEquals(url, "https://github.com/FreshRSS/FreshRSS/releases.atom")
|
||||||
|
assertEquals(siteUrl, "https://github.com/FreshRSS/FreshRSS/")
|
||||||
|
assertEquals(iconUrl, "iconUrl")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
package com.readrops.api.services.freshrss.adapters
|
||||||
|
|
||||||
|
import com.readrops.api.TestUtils
|
||||||
|
import com.readrops.db.entities.Folder
|
||||||
|
import com.squareup.moshi.Moshi
|
||||||
|
import com.squareup.moshi.Types
|
||||||
|
import junit.framework.TestCase.assertEquals
|
||||||
|
import okio.Buffer
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
class FreshRSSFoldersAdapterTest {
|
||||||
|
|
||||||
|
private val adapter = Moshi.Builder()
|
||||||
|
.add(FreshRSSFoldersAdapter())
|
||||||
|
.build()
|
||||||
|
.adapter<List<Folder>>(Types.newParameterizedType(List::class.java, Folder::class.java))
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun validFoldersTest() {
|
||||||
|
val stream = TestUtils.loadResource("services/freshrss/adapters/folders.json")
|
||||||
|
|
||||||
|
val folders = adapter.fromJson(Buffer().readFrom(stream))!!
|
||||||
|
|
||||||
|
assertEquals(folders.size, 1)
|
||||||
|
|
||||||
|
with(folders[0]) {
|
||||||
|
assertEquals(name, "Blogs")
|
||||||
|
assertEquals(remoteId, "user/-/label/Blogs")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,43 @@
|
|||||||
|
package com.readrops.api.services.freshrss.adapters
|
||||||
|
|
||||||
|
import com.readrops.api.TestUtils
|
||||||
|
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.joda.time.LocalDateTime
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
class FreshRSSItemsAdapterTest {
|
||||||
|
|
||||||
|
private val adapter = Moshi.Builder()
|
||||||
|
.add(Types.newParameterizedType(List::class.java, Item::class.java), FreshRSSItemsAdapter())
|
||||||
|
.build()
|
||||||
|
.adapter<List<Item>>(Types.newParameterizedType(List::class.java, Item::class.java))
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun validItemsTest() {
|
||||||
|
val stream = TestUtils.loadResource("services/freshrss/adapters/items.json")
|
||||||
|
|
||||||
|
val items = adapter.fromJson(Buffer().readFrom(stream))!!
|
||||||
|
|
||||||
|
with(items[0]) {
|
||||||
|
assertEquals(remoteId, "tag:google.com,2005:reader/item/0005c62466ee28fe")
|
||||||
|
assertEquals(title, "GNOME’s Default Theme is Getting a Revamp")
|
||||||
|
assertNotNull(content)
|
||||||
|
assertEquals(link, "http://feedproxy.google.com/~r/d0od/~3/4Zk-fncSuek/adwaita-borderless-theme-in-development-gnome-41")
|
||||||
|
assertEquals(author, "Joey Sneddon")
|
||||||
|
assertEquals(pubDate, LocalDateTime(1625234040 * 1000L))
|
||||||
|
assertEquals(isRead, false)
|
||||||
|
assertEquals(isStarred, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
with(items[1]) {
|
||||||
|
assertEquals(isRead, true)
|
||||||
|
assertEquals(isStarred, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
17
api/src/test/resources/services/freshrss/adapters/feeds.json
Normal file
17
api/src/test/resources/services/freshrss/adapters/feeds.json
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"subscriptions": [
|
||||||
|
{
|
||||||
|
"id": "feed/2",
|
||||||
|
"title": "FreshRSS @ GitHub",
|
||||||
|
"categories": [
|
||||||
|
{
|
||||||
|
"id": "user/-/label/Sans catégorie",
|
||||||
|
"label": "Sans catégorie"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"url": "https://github.com/FreshRSS/FreshRSS/releases.atom",
|
||||||
|
"htmlUrl": "https://github.com/FreshRSS/FreshRSS/",
|
||||||
|
"iconUrl": "iconUrl"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"tags": [
|
||||||
|
{
|
||||||
|
"id": "user/-/state/com.google/starred"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "user/-/label/Blogs",
|
||||||
|
"type": "folder"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
57
api/src/test/resources/services/freshrss/adapters/items.json
Normal file
57
api/src/test/resources/services/freshrss/adapters/items.json
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
{
|
||||||
|
"id": "user/-/state/com.google/reading-list",
|
||||||
|
"updated": 1625235516,
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"id": "tag:google.com,2005:reader/item/0005c62466ee28fe",
|
||||||
|
"crawlTimeMsec": "1625234531559",
|
||||||
|
"timestampUsec": "1625234531559678",
|
||||||
|
"published": 1625234040,
|
||||||
|
"title": "GNOME’s Default Theme is Getting a Revamp",
|
||||||
|
"summary": {
|
||||||
|
"content": "<p><img width=\"406\" height=\"232\" src=\"https://149366088.v2.pressablecdn.com/wp-content/uploads/2021/07/borderless-adwaita-tile-406x232.jpg\" alt=\"a screenshot of Adwaita borderless theme\" loading=\"lazy\">GNOME developers are working a \"borderless\" version of the Adwaita GTK theme for potential inclusion in GNOME 41. More details and pictures inside.</p>\n<p>This post, <a rel=\"nofollow\" href=\"https://www.omgubuntu.co.uk/2021/07/adwaita-borderless-theme-in-development-gnome-41\">GNOME’s Default Theme is Getting a Revamp</a> is from <a rel=\"nofollow\" href=\"https://www.omgubuntu.co.uk/\">OMG! Ubuntu!</a>. Do not reproduce elsewhere without permission.</p><div>\n<a href=\"https://feeds.feedburner.com/~ff/d0od?a=4Zk-fncSuek:uQOFOGAnOHI:wBxX2hOkimM\"><img src=\"https://feeds.feedburner.com/~ff/d0od?i=4Zk-fncSuek:uQOFOGAnOHI:wBxX2hOkimM\" border=\"0\"></a> <a href=\"https://feeds.feedburner.com/~ff/d0od?a=4Zk-fncSuek:uQOFOGAnOHI:I9og5sOYxJI\"><img src=\"https://feeds.feedburner.com/~ff/d0od?d=I9og5sOYxJI\" border=\"0\"></a> <a href=\"https://feeds.feedburner.com/~ff/d0od?a=4Zk-fncSuek:uQOFOGAnOHI:qj6IDK7rITs\"><img src=\"https://feeds.feedburner.com/~ff/d0od?d=qj6IDK7rITs\" border=\"0\"></a> <a href=\"https://feeds.feedburner.com/~ff/d0od?a=4Zk-fncSuek:uQOFOGAnOHI:V_sGLiPBpWU\"><img src=\"https://feeds.feedburner.com/~ff/d0od?i=4Zk-fncSuek:uQOFOGAnOHI:V_sGLiPBpWU\" border=\"0\"></a> <a href=\"https://feeds.feedburner.com/~ff/d0od?a=4Zk-fncSuek:uQOFOGAnOHI:gIN9vFwOqvQ\"><img src=\"https://feeds.feedburner.com/~ff/d0od?i=4Zk-fncSuek:uQOFOGAnOHI:gIN9vFwOqvQ\" border=\"0\"></a> <a href=\"https://feeds.feedburner.com/~ff/d0od?a=4Zk-fncSuek:uQOFOGAnOHI:yIl2AUoC8zA\"><img src=\"https://feeds.feedburner.com/~ff/d0od?d=yIl2AUoC8zA\" border=\"0\"></a>\n</div><img src=\"https://feeds.feedburner.com/~r/d0od/~4/4Zk-fncSuek\" height=\"1\" width=\"1\" alt=\"\">"
|
||||||
|
},
|
||||||
|
"alternate": [
|
||||||
|
{
|
||||||
|
"href": "http://feedproxy.google.com/~r/d0od/~3/4Zk-fncSuek/adwaita-borderless-theme-in-development-gnome-41"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"categories": [
|
||||||
|
"user/-/state/com.google/reading-list",
|
||||||
|
"user/-/label/Libre"
|
||||||
|
],
|
||||||
|
"origin": {
|
||||||
|
"streamId": "feed/15",
|
||||||
|
"title": "OMG! Ubuntu!"
|
||||||
|
},
|
||||||
|
"author": "Joey Sneddon"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "tag:google.com,2005:reader/item/0005c62466ee28fe",
|
||||||
|
"crawlTimeMsec": "1625234531559",
|
||||||
|
"timestampUsec": "1625234531559678",
|
||||||
|
"published": 1625234040,
|
||||||
|
"title": "GNOME’s Default Theme is Getting a Revamp",
|
||||||
|
"summary": {
|
||||||
|
"content": "<p><img width=\"406\" height=\"232\" src=\"https://149366088.v2.pressablecdn.com/wp-content/uploads/2021/07/borderless-adwaita-tile-406x232.jpg\" alt=\"a screenshot of Adwaita borderless theme\" loading=\"lazy\">GNOME developers are working a \"borderless\" version of the Adwaita GTK theme for potential inclusion in GNOME 41. More details and pictures inside.</p>\n<p>This post, <a rel=\"nofollow\" href=\"https://www.omgubuntu.co.uk/2021/07/adwaita-borderless-theme-in-development-gnome-41\">GNOME’s Default Theme is Getting a Revamp</a> is from <a rel=\"nofollow\" href=\"https://www.omgubuntu.co.uk/\">OMG! Ubuntu!</a>. Do not reproduce elsewhere without permission.</p><div>\n<a href=\"https://feeds.feedburner.com/~ff/d0od?a=4Zk-fncSuek:uQOFOGAnOHI:wBxX2hOkimM\"><img src=\"https://feeds.feedburner.com/~ff/d0od?i=4Zk-fncSuek:uQOFOGAnOHI:wBxX2hOkimM\" border=\"0\"></a> <a href=\"https://feeds.feedburner.com/~ff/d0od?a=4Zk-fncSuek:uQOFOGAnOHI:I9og5sOYxJI\"><img src=\"https://feeds.feedburner.com/~ff/d0od?d=I9og5sOYxJI\" border=\"0\"></a> <a href=\"https://feeds.feedburner.com/~ff/d0od?a=4Zk-fncSuek:uQOFOGAnOHI:qj6IDK7rITs\"><img src=\"https://feeds.feedburner.com/~ff/d0od?d=qj6IDK7rITs\" border=\"0\"></a> <a href=\"https://feeds.feedburner.com/~ff/d0od?a=4Zk-fncSuek:uQOFOGAnOHI:V_sGLiPBpWU\"><img src=\"https://feeds.feedburner.com/~ff/d0od?i=4Zk-fncSuek:uQOFOGAnOHI:V_sGLiPBpWU\" border=\"0\"></a> <a href=\"https://feeds.feedburner.com/~ff/d0od?a=4Zk-fncSuek:uQOFOGAnOHI:gIN9vFwOqvQ\"><img src=\"https://feeds.feedburner.com/~ff/d0od?i=4Zk-fncSuek:uQOFOGAnOHI:gIN9vFwOqvQ\" border=\"0\"></a> <a href=\"https://feeds.feedburner.com/~ff/d0od?a=4Zk-fncSuek:uQOFOGAnOHI:yIl2AUoC8zA\"><img src=\"https://feeds.feedburner.com/~ff/d0od?d=yIl2AUoC8zA\" border=\"0\"></a>\n</div><img src=\"https://feeds.feedburner.com/~r/d0od/~4/4Zk-fncSuek\" height=\"1\" width=\"1\" alt=\"\">"
|
||||||
|
},
|
||||||
|
"alternate": [
|
||||||
|
{
|
||||||
|
"href": "http://feedproxy.google.com/~r/d0od/~3/4Zk-fncSuek/adwaita-borderless-theme-in-development-gnome-41"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"categories": [
|
||||||
|
"user/-/state/com.google/reading-list",
|
||||||
|
"user/-/label/Libre",
|
||||||
|
"user/-/state/com.google/starred",
|
||||||
|
"user/-/state/com.google/read"
|
||||||
|
],
|
||||||
|
"origin": {
|
||||||
|
"streamId": "feed/15",
|
||||||
|
"title": "OMG! Ubuntu!"
|
||||||
|
},
|
||||||
|
"author": "Joey Sneddon"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"continuation": 1620164205822673
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user