diff --git a/app/src/main/java/com/google/samples/apps/nowinandroid/ui/NiaNavGraph.kt b/app/src/main/java/com/google/samples/apps/nowinandroid/ui/NiaNavGraph.kt index 505dfd8e9..1650f5dbb 100644 --- a/app/src/main/java/com/google/samples/apps/nowinandroid/ui/NiaNavGraph.kt +++ b/app/src/main/java/com/google/samples/apps/nowinandroid/ui/NiaNavGraph.kt @@ -74,7 +74,7 @@ fun NiaNavGraph( InterestsDestinations.TOPIC_ROUTE, arguments = listOf( navArgument(TopicDestinationsArgs.TOPIC_ID_ARG) { - type = NavType.IntType + type = NavType.StringType } ) ) { diff --git a/core-database/schemas/com.google.samples.apps.nowinandroid.core.database.NiADatabase/8.json b/core-database/schemas/com.google.samples.apps.nowinandroid.core.database.NiADatabase/8.json new file mode 100644 index 000000000..bb9281206 --- /dev/null +++ b/core-database/schemas/com.google.samples.apps.nowinandroid.core.database.NiADatabase/8.json @@ -0,0 +1,438 @@ +{ + "formatVersion": 1, + "database": { + "version": 8, + "identityHash": "28ce6650a00ef6281cef0045f5539112", + "entities": [ + { + "tableName": "authors", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `name` TEXT NOT NULL, `image_url` TEXT NOT NULL, `twitter` TEXT NOT NULL DEFAULT '', `medium_page` TEXT NOT NULL DEFAULT '', PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "imageUrl", + "columnName": "image_url", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "twitter", + "columnName": "twitter", + "affinity": "TEXT", + "notNull": true, + "defaultValue": "''" + }, + { + "fieldPath": "mediumPage", + "columnName": "medium_page", + "affinity": "TEXT", + "notNull": true, + "defaultValue": "''" + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "episodes_authors", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`episode_id` TEXT NOT NULL, `author_id` TEXT NOT NULL, PRIMARY KEY(`episode_id`, `author_id`), FOREIGN KEY(`episode_id`) REFERENCES `episodes`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE , FOREIGN KEY(`author_id`) REFERENCES `authors`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "episodeId", + "columnName": "episode_id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "authorId", + "columnName": "author_id", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "episode_id", + "author_id" + ], + "autoGenerate": false + }, + "indices": [ + { + "name": "index_episodes_authors_episode_id", + "unique": false, + "columnNames": [ + "episode_id" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_episodes_authors_episode_id` ON `${TABLE_NAME}` (`episode_id`)" + }, + { + "name": "index_episodes_authors_author_id", + "unique": false, + "columnNames": [ + "author_id" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_episodes_authors_author_id` ON `${TABLE_NAME}` (`author_id`)" + } + ], + "foreignKeys": [ + { + "table": "episodes", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "episode_id" + ], + "referencedColumns": [ + "id" + ] + }, + { + "table": "authors", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "author_id" + ], + "referencedColumns": [ + "id" + ] + } + ] + }, + { + "tableName": "episodes", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `name` TEXT NOT NULL, `publish_date` INTEGER NOT NULL, `alternate_video` TEXT, `alternate_audio` TEXT, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "publishDate", + "columnName": "publish_date", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "alternateVideo", + "columnName": "alternate_video", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "alternateAudio", + "columnName": "alternate_audio", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "news_resources_authors", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`news_resource_id` TEXT NOT NULL, `author_id` TEXT NOT NULL, PRIMARY KEY(`news_resource_id`, `author_id`), FOREIGN KEY(`news_resource_id`) REFERENCES `news_resources`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE , FOREIGN KEY(`author_id`) REFERENCES `authors`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "newsResourceId", + "columnName": "news_resource_id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "authorId", + "columnName": "author_id", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "news_resource_id", + "author_id" + ], + "autoGenerate": false + }, + "indices": [ + { + "name": "index_news_resources_authors_news_resource_id", + "unique": false, + "columnNames": [ + "news_resource_id" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_news_resources_authors_news_resource_id` ON `${TABLE_NAME}` (`news_resource_id`)" + }, + { + "name": "index_news_resources_authors_author_id", + "unique": false, + "columnNames": [ + "author_id" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_news_resources_authors_author_id` ON `${TABLE_NAME}` (`author_id`)" + } + ], + "foreignKeys": [ + { + "table": "news_resources", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "news_resource_id" + ], + "referencedColumns": [ + "id" + ] + }, + { + "table": "authors", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "author_id" + ], + "referencedColumns": [ + "id" + ] + } + ] + }, + { + "tableName": "news_resources", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `episode_id` TEXT NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `url` TEXT NOT NULL, `header_image_url` TEXT, `publish_date` INTEGER NOT NULL, `type` TEXT NOT NULL, PRIMARY KEY(`id`), FOREIGN KEY(`episode_id`) REFERENCES `episodes`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "episodeId", + "columnName": "episode_id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "title", + "columnName": "title", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "content", + "columnName": "content", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "url", + "columnName": "url", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "headerImageUrl", + "columnName": "header_image_url", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "publishDate", + "columnName": "publish_date", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "type", + "columnName": "type", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [ + { + "table": "episodes", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "episode_id" + ], + "referencedColumns": [ + "id" + ] + } + ] + }, + { + "tableName": "news_resources_topics", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`news_resource_id` TEXT NOT NULL, `topic_id` TEXT NOT NULL, PRIMARY KEY(`news_resource_id`, `topic_id`), FOREIGN KEY(`news_resource_id`) REFERENCES `news_resources`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE , FOREIGN KEY(`topic_id`) REFERENCES `topics`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "newsResourceId", + "columnName": "news_resource_id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "topicId", + "columnName": "topic_id", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "news_resource_id", + "topic_id" + ], + "autoGenerate": false + }, + "indices": [ + { + "name": "index_news_resources_topics_news_resource_id", + "unique": false, + "columnNames": [ + "news_resource_id" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_news_resources_topics_news_resource_id` ON `${TABLE_NAME}` (`news_resource_id`)" + }, + { + "name": "index_news_resources_topics_topic_id", + "unique": false, + "columnNames": [ + "topic_id" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_news_resources_topics_topic_id` ON `${TABLE_NAME}` (`topic_id`)" + } + ], + "foreignKeys": [ + { + "table": "news_resources", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "news_resource_id" + ], + "referencedColumns": [ + "id" + ] + }, + { + "table": "topics", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "topic_id" + ], + "referencedColumns": [ + "id" + ] + } + ] + }, + { + "tableName": "topics", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `name` TEXT NOT NULL, `shortDescription` TEXT NOT NULL, `longDescription` TEXT NOT NULL DEFAULT '', `url` TEXT NOT NULL DEFAULT '', `imageUrl` TEXT NOT NULL DEFAULT '', PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "shortDescription", + "columnName": "shortDescription", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "longDescription", + "columnName": "longDescription", + "affinity": "TEXT", + "notNull": true, + "defaultValue": "''" + }, + { + "fieldPath": "url", + "columnName": "url", + "affinity": "TEXT", + "notNull": true, + "defaultValue": "''" + }, + { + "fieldPath": "imageUrl", + "columnName": "imageUrl", + "affinity": "TEXT", + "notNull": true, + "defaultValue": "''" + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + } + ], + "views": [], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '28ce6650a00ef6281cef0045f5539112')" + ] + } +} \ No newline at end of file diff --git a/core-database/src/androidTest/java/com/google/samples/apps/nowinandroid/core/database/dao/NewsResourceDaoTest.kt b/core-database/src/androidTest/java/com/google/samples/apps/nowinandroid/core/database/dao/NewsResourceDaoTest.kt index 06c86bab9..2f9eedf71 100644 --- a/core-database/src/androidTest/java/com/google/samples/apps/nowinandroid/core/database/dao/NewsResourceDaoTest.kt +++ b/core-database/src/androidTest/java/com/google/samples/apps/nowinandroid/core/database/dao/NewsResourceDaoTest.kt @@ -60,19 +60,19 @@ class NewsResourceDaoTest { fun newsResourceDao_fetches_items_by_descending_publish_date() = runTest { val newsResourceEntities = listOf( testNewsResource( - id = 0, + id = "0", millisSinceEpoch = 0, ), testNewsResource( - id = 1, + id = "1", millisSinceEpoch = 3, ), testNewsResource( - id = 2, + id = "2", millisSinceEpoch = 1, ), testNewsResource( - id = 3, + id = "3", millisSinceEpoch = 2, ), ) @@ -102,29 +102,29 @@ class NewsResourceDaoTest { fun newsResourceDao_filters_items_by_topic_ids_by_descending_publish_date() = runTest { val topicEntities = listOf( testTopicEntity( - id = 1, + id = "1", name = "1" ), testTopicEntity( - id = 2, + id = "2", name = "2" ), ) val newsResourceEntities = listOf( testNewsResource( - id = 0, + id = "0", millisSinceEpoch = 0, ), testNewsResource( - id = 1, + id = "1", millisSinceEpoch = 3, ), testNewsResource( - id = 2, + id = "2", millisSinceEpoch = 1, ), testNewsResource( - id = 3, + id = "3", millisSinceEpoch = 2, ), ) @@ -133,7 +133,7 @@ class NewsResourceDaoTest { .distinct() val newsResourceTopicCrossRefEntities = topicEntities.mapIndexed { index, topicEntity -> NewsResourceTopicCrossRef( - newsResourceId = index, + newsResourceId = index.toString(), topicId = topicEntity.id ) } @@ -158,7 +158,7 @@ class NewsResourceDaoTest { ).first() assertEquals( - listOf(1, 0), + listOf("1", "0"), filteredNewsResources.map { it.entity.id } ) } @@ -167,29 +167,29 @@ class NewsResourceDaoTest { fun newsResourceDao_filters_items_by_author_ids_by_descending_publish_date() = runTest { val authorEntities = listOf( testAuthorEntity( - id = 1, + id = "1", name = "1" ), testAuthorEntity( - id = 2, + id = "2", name = "2" ), ) val newsResourceEntities = listOf( testNewsResource( - id = 0, + id = "0", millisSinceEpoch = 0, ), testNewsResource( - id = 1, + id = "1", millisSinceEpoch = 3, ), testNewsResource( - id = 2, + id = "2", millisSinceEpoch = 1, ), testNewsResource( - id = 3, + id = "3", millisSinceEpoch = 2, ), ) @@ -198,7 +198,7 @@ class NewsResourceDaoTest { .distinct() val newsResourceAuthorCrossRefEntities = authorEntities.mapIndexed { index, authorEntity -> NewsResourceAuthorCrossRef( - newsResourceId = index, + newsResourceId = index.toString(), authorId = authorEntity.id ) } @@ -215,7 +215,7 @@ class NewsResourceDaoTest { ).first() assertEquals( - listOf(1, 0), + listOf("1", "0"), filteredNewsResources.map { it.entity.id } ) } @@ -225,44 +225,44 @@ class NewsResourceDaoTest { runTest { val topicEntities = listOf( testTopicEntity( - id = 1, + id = "1", name = "1" ), testTopicEntity( - id = 2, + id = "2", name = "2" ), ) val authorEntities = listOf( testAuthorEntity( - id = 1, + id = "1", name = "1" ), testAuthorEntity( - id = 2, + id = "2", name = "2" ), ) val newsResourceEntities = listOf( testNewsResource( - id = 0, + id = "0", millisSinceEpoch = 0, ), testNewsResource( - id = 1, + id = "1", millisSinceEpoch = 3, ), testNewsResource( - id = 2, + id = "2", millisSinceEpoch = 1, ), testNewsResource( - id = 3, + id = "3", millisSinceEpoch = 2, ), // Should be missing as no topics or authors match it testNewsResource( - id = 4, + id = "4", millisSinceEpoch = 10, ), ) @@ -271,7 +271,7 @@ class NewsResourceDaoTest { .distinct() val newsResourceTopicCrossRefEntities = topicEntities.mapIndexed { index, topicEntity -> NewsResourceTopicCrossRef( - newsResourceId = index, + newsResourceId = index.toString(), topicId = topicEntity.id ) } @@ -279,7 +279,7 @@ class NewsResourceDaoTest { authorEntities.mapIndexed { index, authorEntity -> NewsResourceAuthorCrossRef( // Offset news resources by two - newsResourceId = index + 2, + newsResourceId = (index + 2).toString(), authorId = authorEntity.id ) } @@ -301,7 +301,7 @@ class NewsResourceDaoTest { ).first() assertEquals( - listOf(1, 3, 2, 0), + listOf("1", "3", "2", "0"), filteredNewsResources.map { it.entity.id } ) } @@ -311,19 +311,19 @@ class NewsResourceDaoTest { runTest { val newsResourceEntities = listOf( testNewsResource( - id = 0, + id = "0", millisSinceEpoch = 0, ), testNewsResource( - id = 1, + id = "1", millisSinceEpoch = 3, ), testNewsResource( - id = 2, + id = "2", millisSinceEpoch = 1, ), testNewsResource( - id = 3, + id = "3", millisSinceEpoch = 2, ), ) @@ -334,7 +334,7 @@ class NewsResourceDaoTest { episodeDao.upsertEpisodes(episodeEntityShells) newsResourceDao.upsertNewsResources(newsResourceEntities) - val (toDelete, toKeep) = newsResourceEntities.partition { it.id % 2 == 0 } + val (toDelete, toKeep) = newsResourceEntities.partition { it.id.toInt() % 2 == 0 } newsResourceDao.deleteNewsResources( toDelete.map(NewsResourceEntity::id) @@ -351,7 +351,7 @@ class NewsResourceDaoTest { } private fun testAuthorEntity( - id: Int = 0, + id: String = "0", name: String ) = AuthorEntity( id = id, @@ -362,7 +362,7 @@ private fun testAuthorEntity( ) private fun testTopicEntity( - id: Int = 0, + id: String = "0", name: String ) = TopicEntity( id = id, @@ -374,11 +374,11 @@ private fun testTopicEntity( ) private fun testNewsResource( - id: Int = 0, + id: String = "0", millisSinceEpoch: Long = 0 ) = NewsResourceEntity( id = id, - episodeId = 0, + episodeId = "0", title = "", content = "", url = "", diff --git a/core-database/src/main/java/com/google/samples/apps/nowinandroid/core/database/NiADatabase.kt b/core-database/src/main/java/com/google/samples/apps/nowinandroid/core/database/NiADatabase.kt index 8db2e987c..266a4c20e 100644 --- a/core-database/src/main/java/com/google/samples/apps/nowinandroid/core/database/NiADatabase.kt +++ b/core-database/src/main/java/com/google/samples/apps/nowinandroid/core/database/NiADatabase.kt @@ -44,7 +44,7 @@ import com.google.samples.apps.nowinandroid.core.database.util.NewsResourceTypeC NewsResourceTopicCrossRef::class, TopicEntity::class, ], - version = 7, + version = 8, autoMigrations = [ AutoMigration(from = 1, to = 2), AutoMigration(from = 2, to = 3, spec = DatabaseMigrations.Schema2to3::class), @@ -52,6 +52,7 @@ import com.google.samples.apps.nowinandroid.core.database.util.NewsResourceTypeC AutoMigration(from = 4, to = 5), AutoMigration(from = 5, to = 6), AutoMigration(from = 6, to = 7), + AutoMigration(from = 7, to = 8), ], exportSchema = true, ) diff --git a/core-database/src/main/java/com/google/samples/apps/nowinandroid/core/database/dao/AuthorDao.kt b/core-database/src/main/java/com/google/samples/apps/nowinandroid/core/database/dao/AuthorDao.kt index 40592e9ad..35c87678f 100644 --- a/core-database/src/main/java/com/google/samples/apps/nowinandroid/core/database/dao/AuthorDao.kt +++ b/core-database/src/main/java/com/google/samples/apps/nowinandroid/core/database/dao/AuthorDao.kt @@ -64,5 +64,5 @@ interface AuthorDao { WHERE id in (:ids) """ ) - suspend fun deleteAuthors(ids: List) + suspend fun deleteAuthors(ids: List) } diff --git a/core-database/src/main/java/com/google/samples/apps/nowinandroid/core/database/dao/EpisodeDao.kt b/core-database/src/main/java/com/google/samples/apps/nowinandroid/core/database/dao/EpisodeDao.kt index dfffc31fe..40da3f2ca 100644 --- a/core-database/src/main/java/com/google/samples/apps/nowinandroid/core/database/dao/EpisodeDao.kt +++ b/core-database/src/main/java/com/google/samples/apps/nowinandroid/core/database/dao/EpisodeDao.kt @@ -66,5 +66,5 @@ interface EpisodeDao { WHERE id in (:ids) """ ) - suspend fun deleteEpisodes(ids: List) + suspend fun deleteEpisodes(ids: List) } diff --git a/core-database/src/main/java/com/google/samples/apps/nowinandroid/core/database/dao/NewsResourceDao.kt b/core-database/src/main/java/com/google/samples/apps/nowinandroid/core/database/dao/NewsResourceDao.kt index c2ffa2214..f03b1704d 100644 --- a/core-database/src/main/java/com/google/samples/apps/nowinandroid/core/database/dao/NewsResourceDao.kt +++ b/core-database/src/main/java/com/google/samples/apps/nowinandroid/core/database/dao/NewsResourceDao.kt @@ -59,8 +59,8 @@ interface NewsResourceDao { """ ) fun getNewsResourcesStream( - filterAuthorIds: Set = emptySet(), - filterTopicIds: Set = emptySet(), + filterAuthorIds: Set = emptySet(), + filterTopicIds: Set = emptySet(), ): Flow> /** @@ -104,5 +104,5 @@ interface NewsResourceDao { WHERE id in (:ids) """ ) - suspend fun deleteNewsResources(ids: List) + suspend fun deleteNewsResources(ids: List) } diff --git a/core-database/src/main/java/com/google/samples/apps/nowinandroid/core/database/dao/TopicDao.kt b/core-database/src/main/java/com/google/samples/apps/nowinandroid/core/database/dao/TopicDao.kt index 6d91e139b..d03fd6a30 100644 --- a/core-database/src/main/java/com/google/samples/apps/nowinandroid/core/database/dao/TopicDao.kt +++ b/core-database/src/main/java/com/google/samples/apps/nowinandroid/core/database/dao/TopicDao.kt @@ -36,7 +36,7 @@ interface TopicDao { WHERE id = :topicId """ ) - fun getTopicEntity(topicId: Int): Flow + fun getTopicEntity(topicId: String): Flow @Query(value = "SELECT * FROM topics") fun getTopicEntitiesStream(): Flow> @@ -47,7 +47,7 @@ interface TopicDao { WHERE id IN (:ids) """ ) - fun getTopicEntitiesStream(ids: Set): Flow> + fun getTopicEntitiesStream(ids: Set): Flow> /** * Inserts [topicEntities] into the db if they don't exist, and ignores those that do @@ -80,5 +80,5 @@ interface TopicDao { WHERE id in (:ids) """ ) - suspend fun deleteTopics(ids: List) + suspend fun deleteTopics(ids: List) } diff --git a/core-database/src/main/java/com/google/samples/apps/nowinandroid/core/database/model/AuthorEntity.kt b/core-database/src/main/java/com/google/samples/apps/nowinandroid/core/database/model/AuthorEntity.kt index 1e0e55d84..5564708c8 100644 --- a/core-database/src/main/java/com/google/samples/apps/nowinandroid/core/database/model/AuthorEntity.kt +++ b/core-database/src/main/java/com/google/samples/apps/nowinandroid/core/database/model/AuthorEntity.kt @@ -30,7 +30,7 @@ import com.google.samples.apps.nowinandroid.core.model.data.Author ) data class AuthorEntity( @PrimaryKey - val id: Int, + val id: String, val name: String, @ColumnInfo(name = "image_url") val imageUrl: String, diff --git a/core-database/src/main/java/com/google/samples/apps/nowinandroid/core/database/model/EpisodeAuthorCrossRef.kt b/core-database/src/main/java/com/google/samples/apps/nowinandroid/core/database/model/EpisodeAuthorCrossRef.kt index 9de749ba0..368945680 100644 --- a/core-database/src/main/java/com/google/samples/apps/nowinandroid/core/database/model/EpisodeAuthorCrossRef.kt +++ b/core-database/src/main/java/com/google/samples/apps/nowinandroid/core/database/model/EpisodeAuthorCrossRef.kt @@ -48,7 +48,7 @@ import androidx.room.Index ) data class EpisodeAuthorCrossRef( @ColumnInfo(name = "episode_id") - val episodeId: Int, + val episodeId: String, @ColumnInfo(name = "author_id") - val authorId: Long, + val authorId: String, ) diff --git a/core-database/src/main/java/com/google/samples/apps/nowinandroid/core/database/model/EpisodeEntity.kt b/core-database/src/main/java/com/google/samples/apps/nowinandroid/core/database/model/EpisodeEntity.kt index eddddcb33..6d3d6adeb 100644 --- a/core-database/src/main/java/com/google/samples/apps/nowinandroid/core/database/model/EpisodeEntity.kt +++ b/core-database/src/main/java/com/google/samples/apps/nowinandroid/core/database/model/EpisodeEntity.kt @@ -30,7 +30,7 @@ import kotlinx.datetime.Instant ) data class EpisodeEntity( @PrimaryKey - val id: Int, + val id: String, val name: String, @ColumnInfo(name = "publish_date") val publishDate: Instant, diff --git a/core-database/src/main/java/com/google/samples/apps/nowinandroid/core/database/model/NewsResourceAuthorCrossRef.kt b/core-database/src/main/java/com/google/samples/apps/nowinandroid/core/database/model/NewsResourceAuthorCrossRef.kt index fbd8ce0b4..36cd4297a 100644 --- a/core-database/src/main/java/com/google/samples/apps/nowinandroid/core/database/model/NewsResourceAuthorCrossRef.kt +++ b/core-database/src/main/java/com/google/samples/apps/nowinandroid/core/database/model/NewsResourceAuthorCrossRef.kt @@ -48,7 +48,7 @@ import androidx.room.Index ) data class NewsResourceAuthorCrossRef( @ColumnInfo(name = "news_resource_id") - val newsResourceId: Int, + val newsResourceId: String, @ColumnInfo(name = "author_id") - val authorId: Int, + val authorId: String, ) diff --git a/core-database/src/main/java/com/google/samples/apps/nowinandroid/core/database/model/NewsResourceEntity.kt b/core-database/src/main/java/com/google/samples/apps/nowinandroid/core/database/model/NewsResourceEntity.kt index 28d8d858e..e74135f12 100644 --- a/core-database/src/main/java/com/google/samples/apps/nowinandroid/core/database/model/NewsResourceEntity.kt +++ b/core-database/src/main/java/com/google/samples/apps/nowinandroid/core/database/model/NewsResourceEntity.kt @@ -41,9 +41,9 @@ import kotlinx.datetime.Instant ) data class NewsResourceEntity( @PrimaryKey - val id: Int, + val id: String, @ColumnInfo(name = "episode_id") - val episodeId: Int, + val episodeId: String, val title: String, val content: String, val url: String, diff --git a/core-database/src/main/java/com/google/samples/apps/nowinandroid/core/database/model/NewsResourceTopicCrossRef.kt b/core-database/src/main/java/com/google/samples/apps/nowinandroid/core/database/model/NewsResourceTopicCrossRef.kt index aec38b641..dac2b5f0b 100644 --- a/core-database/src/main/java/com/google/samples/apps/nowinandroid/core/database/model/NewsResourceTopicCrossRef.kt +++ b/core-database/src/main/java/com/google/samples/apps/nowinandroid/core/database/model/NewsResourceTopicCrossRef.kt @@ -48,7 +48,7 @@ import androidx.room.Index ) data class NewsResourceTopicCrossRef( @ColumnInfo(name = "news_resource_id") - val newsResourceId: Int, + val newsResourceId: String, @ColumnInfo(name = "topic_id") - val topicId: Int, + val topicId: String, ) diff --git a/core-database/src/main/java/com/google/samples/apps/nowinandroid/core/database/model/TopicEntity.kt b/core-database/src/main/java/com/google/samples/apps/nowinandroid/core/database/model/TopicEntity.kt index 535f4858b..043d110cd 100644 --- a/core-database/src/main/java/com/google/samples/apps/nowinandroid/core/database/model/TopicEntity.kt +++ b/core-database/src/main/java/com/google/samples/apps/nowinandroid/core/database/model/TopicEntity.kt @@ -30,7 +30,7 @@ import com.google.samples.apps.nowinandroid.core.model.data.Topic ) data class TopicEntity( @PrimaryKey - val id: Int, + val id: String, val name: String, val shortDescription: String, @ColumnInfo(defaultValue = "") diff --git a/core-datastore/src/main/java/com/google/samples/apps/nowinandroid/core/datastore/IntToStringIdsMigration.kt b/core-datastore/src/main/java/com/google/samples/apps/nowinandroid/core/datastore/IntToStringIdsMigration.kt new file mode 100644 index 000000000..4e6e49300 --- /dev/null +++ b/core-datastore/src/main/java/com/google/samples/apps/nowinandroid/core/datastore/IntToStringIdsMigration.kt @@ -0,0 +1,50 @@ +/* + * Copyright 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.samples.apps.nowinandroid.core.datastore + +import androidx.datastore.core.DataMigration + +/** + * Migrates saved ids from [Int] to [String] types + */ +object IntToStringIdsMigration : DataMigration { + + override suspend fun cleanUp() = Unit + + override suspend fun migrate(currentData: UserPreferences): UserPreferences = + currentData.copy { + // Migrate topic ids + followedTopicIds.clear() + followedTopicIds.addAll( + currentData.deprecatedIntFollowedTopicIdsList.map(Int::toString) + ) + deprecatedIntFollowedTopicIds.clear() + + // Migrate author ids + followedAuthorIds.clear() + followedAuthorIds.addAll( + currentData.deprecatedIntFollowedAuthorIdsList.map(Int::toString) + ) + deprecatedIntFollowedAuthorIds.clear() + + // Mark migration as complete + hasDoneIntToStringIdMigration = true + } + + override suspend fun shouldMigrate(currentData: UserPreferences): Boolean = + !currentData.hasDoneIntToStringIdMigration +} diff --git a/core-datastore/src/main/java/com/google/samples/apps/nowinandroid/core/datastore/NiaPreferences.kt b/core-datastore/src/main/java/com/google/samples/apps/nowinandroid/core/datastore/NiaPreferences.kt index c1a6a33f5..9e00e912c 100644 --- a/core-datastore/src/main/java/com/google/samples/apps/nowinandroid/core/datastore/NiaPreferences.kt +++ b/core-datastore/src/main/java/com/google/samples/apps/nowinandroid/core/datastore/NiaPreferences.kt @@ -28,7 +28,7 @@ import kotlinx.coroutines.flow.retry class NiaPreferences @Inject constructor( private val userPreferences: DataStore ) { - suspend fun setFollowedTopicIds(followedTopicIds: Set) { + suspend fun setFollowedTopicIds(followedTopicIds: Set) { try { userPreferences.updateData { it.copy { @@ -41,7 +41,7 @@ class NiaPreferences @Inject constructor( } } - suspend fun toggleFollowedTopicId(followedTopicId: Int, followed: Boolean) { + suspend fun toggleFollowedTopicId(followedTopicId: String, followed: Boolean) { try { userPreferences.updateData { it.copy { @@ -60,7 +60,7 @@ class NiaPreferences @Inject constructor( } } - val followedTopicIds: Flow> = userPreferences.data + val followedTopicIds: Flow> = userPreferences.data .retry { Log.e("NiaPreferences", "Failed to read user preferences", it) true @@ -105,7 +105,7 @@ class NiaPreferences @Inject constructor( } } - suspend fun setFollowedAuthorIds(followedAuthorIds: Set) { + suspend fun setFollowedAuthorIds(followedAuthorIds: Set) { try { userPreferences.updateData { it.copy { @@ -118,7 +118,7 @@ class NiaPreferences @Inject constructor( } } - suspend fun toggleFollowedAuthorId(followedAuthorId: Int, followed: Boolean) { + suspend fun toggleFollowedAuthorId(followedAuthorId: String, followed: Boolean) { try { userPreferences.updateData { it.copy { @@ -137,7 +137,7 @@ class NiaPreferences @Inject constructor( } } - val followedAuthorIds: Flow> = userPreferences.data + val followedAuthorIds: Flow> = userPreferences.data .retry { Log.e("NiaPreferences", "Failed to read user preferences", it) true diff --git a/core-datastore/src/main/java/com/google/samples/apps/nowinandroid/core/datastore/di/DataStoreModule.kt b/core-datastore/src/main/java/com/google/samples/apps/nowinandroid/core/datastore/di/DataStoreModule.kt index 4978da0dc..f4eb8f848 100644 --- a/core-datastore/src/main/java/com/google/samples/apps/nowinandroid/core/datastore/di/DataStoreModule.kt +++ b/core-datastore/src/main/java/com/google/samples/apps/nowinandroid/core/datastore/di/DataStoreModule.kt @@ -20,6 +20,7 @@ import android.content.Context import androidx.datastore.core.DataStore import androidx.datastore.core.DataStoreFactory import androidx.datastore.dataStoreFile +import com.google.samples.apps.nowinandroid.core.datastore.IntToStringIdsMigration import com.google.samples.apps.nowinandroid.core.datastore.UserPreferences import com.google.samples.apps.nowinandroid.core.datastore.UserPreferencesSerializer import com.google.samples.apps.nowinandroid.core.network.Dispatcher @@ -47,7 +48,10 @@ object DataStoreModule { ): DataStore = DataStoreFactory.create( serializer = userPreferencesSerializer, - scope = CoroutineScope(ioDispatcher + SupervisorJob()) + scope = CoroutineScope(ioDispatcher + SupervisorJob()), + migrations = listOf( + IntToStringIdsMigration, + ) ) { context.dataStoreFile("user_preferences.pb") } diff --git a/core-datastore/src/main/proto/com/google/samples/apps/nowinandroid/data/user_preferences.proto b/core-datastore/src/main/proto/com/google/samples/apps/nowinandroid/data/user_preferences.proto index ec6689dc8..466565e9e 100644 --- a/core-datastore/src/main/proto/com/google/samples/apps/nowinandroid/data/user_preferences.proto +++ b/core-datastore/src/main/proto/com/google/samples/apps/nowinandroid/data/user_preferences.proto @@ -21,10 +21,13 @@ option java_multiple_files = true; message UserPreferences { reserved 2; - repeated int32 followed_topic_ids = 1; + repeated int32 deprecated_int_followed_topic_ids = 1; int32 topicChangeListVersion = 3; int32 authorChangeListVersion = 4; int32 episodeChangeListVersion = 5; int32 newsResourceChangeListVersion = 6; - repeated int32 followed_author_ids = 7; + repeated int32 deprecated_int_followed_author_ids = 7; + bool has_done_int_to_string_id_migration = 8; + repeated string followed_topic_ids = 9; + repeated string followed_author_ids = 10; } diff --git a/core-datastore/src/test/java/com/google/samples/apps/nowinandroid/core/datastore/IntToStringIdsMigrationTest.kt b/core-datastore/src/test/java/com/google/samples/apps/nowinandroid/core/datastore/IntToStringIdsMigrationTest.kt new file mode 100644 index 000000000..8c62452b8 --- /dev/null +++ b/core-datastore/src/test/java/com/google/samples/apps/nowinandroid/core/datastore/IntToStringIdsMigrationTest.kt @@ -0,0 +1,86 @@ +/* + * Copyright 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.samples.apps.nowinandroid.core.datastore + +import kotlinx.coroutines.test.runTest +import org.junit.Assert.assertEquals +import org.junit.Assert.assertTrue +import org.junit.Test + +/** + * Unit test for [IntToStringIdsMigration] + */ +class IntToStringIdsMigrationTest { + + @Test + fun IntToStringIdsMigration_should_migrate_topic_ids() = runTest { + // Set up existing preferences with topic int ids + val preMigrationUserPreferences = userPreferences { + deprecatedIntFollowedTopicIds.addAll(listOf(1, 2, 3)) + } + // Assert that there are no string topic ids yet + assertEquals( + emptyList(), + preMigrationUserPreferences.followedTopicIdsList + ) + + // Run the migration + val postMigrationUserPreferences = + IntToStringIdsMigration.migrate(preMigrationUserPreferences) + + // Assert the deprecated int topic ids have been migrated to the string topic ids + assertEquals( + userPreferences { + followedTopicIds.addAll(listOf("1", "2", "3")) + hasDoneIntToStringIdMigration = true + }, + postMigrationUserPreferences + ) + + // Assert that the migration has been marked complete + assertTrue(postMigrationUserPreferences.hasDoneIntToStringIdMigration) + } + + @Test + fun IntToStringIdsMigration_should_migrate_author_ids() = runTest { + // Set up existing preferences with author int ids + val preMigrationUserPreferences = userPreferences { + deprecatedIntFollowedAuthorIds.addAll(listOf(4, 5, 6)) + } + // Assert that there are no string author ids yet + assertEquals( + emptyList(), + preMigrationUserPreferences.followedAuthorIdsList + ) + + // Run the migration + val postMigrationUserPreferences = + IntToStringIdsMigration.migrate(preMigrationUserPreferences) + + // Assert the deprecated int author ids have been migrated to the string author ids + assertEquals( + userPreferences { + followedAuthorIds.addAll(listOf("4", "5", "6")) + hasDoneIntToStringIdMigration = true + }, + postMigrationUserPreferences + ) + + // Assert that the migration has been marked complete + assertTrue(postMigrationUserPreferences.hasDoneIntToStringIdMigration) + } +} diff --git a/core-datastore/src/test/java/com/google/samples/apps/nowinandroid/core/datastore/UserPreferencesSerializerTest.kt b/core-datastore/src/test/java/com/google/samples/apps/nowinandroid/core/datastore/UserPreferencesSerializerTest.kt index b0906f7db..3b4015495 100644 --- a/core-datastore/src/test/java/com/google/samples/apps/nowinandroid/core/datastore/UserPreferencesSerializerTest.kt +++ b/core-datastore/src/test/java/com/google/samples/apps/nowinandroid/core/datastore/UserPreferencesSerializerTest.kt @@ -39,8 +39,8 @@ class UserPreferencesSerializerTest { @Test fun writingAndReadingUserPreferences_outputsCorrectValue() = runTest { val expectedUserPreferences = userPreferences { - followedTopicIds.add(0) - followedTopicIds.add(1) + followedTopicIds.add("0") + followedTopicIds.add("1") } val outputStream = ByteArrayOutputStream() diff --git a/core-domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/SyncUtilities.kt b/core-domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/SyncUtilities.kt index 35c628a06..e0b12ac9e 100644 --- a/core-domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/SyncUtilities.kt +++ b/core-domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/SyncUtilities.kt @@ -82,8 +82,8 @@ suspend fun Synchronizer.changeListSync( versionReader: (ChangeListVersions) -> Int, changeListFetcher: suspend (Int) -> List, versionUpdater: ChangeListVersions.(Int) -> ChangeListVersions, - modelDeleter: suspend (List) -> Unit, - modelUpdater: suspend (List) -> Unit, + modelDeleter: suspend (List) -> Unit, + modelUpdater: suspend (List) -> Unit, ) = suspendRunCatching { // Fetch the change list since last sync (akin to a git fetch) val currentVersion = versionReader(getChangeListVersions()) diff --git a/core-domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/repository/AuthorsRepository.kt b/core-domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/repository/AuthorsRepository.kt index ddcfc99b0..b480c65f6 100644 --- a/core-domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/repository/AuthorsRepository.kt +++ b/core-domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/repository/AuthorsRepository.kt @@ -29,15 +29,15 @@ interface AuthorsRepository : Syncable { /** * Sets the user's currently followed authors */ - suspend fun setFollowedAuthorIds(followedAuthorIds: Set) + suspend fun setFollowedAuthorIds(followedAuthorIds: Set) /** * Toggles the user's newly followed/unfollowed author */ - suspend fun toggleFollowedAuthorId(followedAuthorId: Int, followed: Boolean) + suspend fun toggleFollowedAuthorId(followedAuthorId: String, followed: Boolean) /** * Returns the users currently followed authors */ - fun getFollowedAuthorIdsStream(): Flow> + fun getFollowedAuthorIdsStream(): Flow> } diff --git a/core-domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/repository/LocalAuthorsRepository.kt b/core-domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/repository/LocalAuthorsRepository.kt index 43e17e102..911c2a399 100644 --- a/core-domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/repository/LocalAuthorsRepository.kt +++ b/core-domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/repository/LocalAuthorsRepository.kt @@ -44,13 +44,13 @@ class LocalAuthorsRepository @Inject constructor( authorDao.getAuthorEntitiesStream() .map { it.map(AuthorEntity::asExternalModel) } - override suspend fun setFollowedAuthorIds(followedAuthorIds: Set) = + override suspend fun setFollowedAuthorIds(followedAuthorIds: Set) = niaPreferences.setFollowedAuthorIds(followedAuthorIds) - override suspend fun toggleFollowedAuthorId(followedAuthorId: Int, followed: Boolean) = + override suspend fun toggleFollowedAuthorId(followedAuthorId: String, followed: Boolean) = niaPreferences.toggleFollowedAuthorId(followedAuthorId, followed) - override fun getFollowedAuthorIdsStream(): Flow> = niaPreferences.followedAuthorIds + override fun getFollowedAuthorIdsStream(): Flow> = niaPreferences.followedAuthorIds override suspend fun syncWith(synchronizer: Synchronizer): Boolean = synchronizer.changeListSync( diff --git a/core-domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/repository/LocalNewsRepository.kt b/core-domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/repository/LocalNewsRepository.kt index f5840600d..cb746337d 100644 --- a/core-domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/repository/LocalNewsRepository.kt +++ b/core-domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/repository/LocalNewsRepository.kt @@ -57,8 +57,8 @@ class LocalNewsRepository @Inject constructor( .map { it.map(PopulatedNewsResource::asExternalModel) } override fun getNewsResourcesStream( - filterAuthorIds: Set, - filterTopicIds: Set + filterAuthorIds: Set, + filterTopicIds: Set ): Flow> = newsResourceDao.getNewsResourcesStream( filterAuthorIds = filterAuthorIds, filterTopicIds = filterTopicIds diff --git a/core-domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/repository/LocalTopicsRepository.kt b/core-domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/repository/LocalTopicsRepository.kt index 83bc0999c..446464add 100644 --- a/core-domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/repository/LocalTopicsRepository.kt +++ b/core-domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/repository/LocalTopicsRepository.kt @@ -44,13 +44,13 @@ class LocalTopicsRepository @Inject constructor( topicDao.getTopicEntitiesStream() .map { it.map(TopicEntity::asExternalModel) } - override fun getTopic(id: Int): Flow = + override fun getTopic(id: String): Flow = topicDao.getTopicEntity(id).map { it.asExternalModel() } - override suspend fun setFollowedTopicIds(followedTopicIds: Set) = + override suspend fun setFollowedTopicIds(followedTopicIds: Set) = niaPreferences.setFollowedTopicIds(followedTopicIds) - override suspend fun toggleFollowedTopicId(followedTopicId: Int, followed: Boolean) = + override suspend fun toggleFollowedTopicId(followedTopicId: String, followed: Boolean) = niaPreferences.toggleFollowedTopicId(followedTopicId, followed) override fun getFollowedTopicIdsStream() = niaPreferences.followedTopicIds diff --git a/core-domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/repository/NewsRepository.kt b/core-domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/repository/NewsRepository.kt index 190423cc2..af56e1fde 100644 --- a/core-domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/repository/NewsRepository.kt +++ b/core-domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/repository/NewsRepository.kt @@ -33,7 +33,7 @@ interface NewsRepository : Syncable { * Returns available news resources as a stream filtered by authors or topics. */ fun getNewsResourcesStream( - filterAuthorIds: Set = emptySet(), - filterTopicIds: Set = emptySet(), + filterAuthorIds: Set = emptySet(), + filterTopicIds: Set = emptySet(), ): Flow> } diff --git a/core-domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/repository/TopicsRepository.kt b/core-domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/repository/TopicsRepository.kt index 96450c41e..e83940818 100644 --- a/core-domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/repository/TopicsRepository.kt +++ b/core-domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/repository/TopicsRepository.kt @@ -29,20 +29,20 @@ interface TopicsRepository : Syncable { /** * Gets data for a specific topic */ - fun getTopic(id: Int): Flow + fun getTopic(id: String): Flow /** * Sets the user's currently followed topics */ - suspend fun setFollowedTopicIds(followedTopicIds: Set) + suspend fun setFollowedTopicIds(followedTopicIds: Set) /** * Toggles the user's newly followed/unfollowed topic */ - suspend fun toggleFollowedTopicId(followedTopicId: Int, followed: Boolean) + suspend fun toggleFollowedTopicId(followedTopicId: String, followed: Boolean) /** * Returns the users currently followed topics */ - fun getFollowedTopicIdsStream(): Flow> + fun getFollowedTopicIdsStream(): Flow> } diff --git a/core-domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/repository/fake/FakeAuthorsRepository.kt b/core-domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/repository/fake/FakeAuthorsRepository.kt index 42aca55b2..4cce0dcc5 100644 --- a/core-domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/repository/fake/FakeAuthorsRepository.kt +++ b/core-domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/repository/fake/FakeAuthorsRepository.kt @@ -59,15 +59,15 @@ class FakeAuthorsRepository @Inject constructor( } .flowOn(ioDispatcher) - override suspend fun setFollowedAuthorIds(followedAuthorIds: Set) { + override suspend fun setFollowedAuthorIds(followedAuthorIds: Set) { niaPreferences.setFollowedAuthorIds(followedAuthorIds) } - override suspend fun toggleFollowedAuthorId(followedAuthorId: Int, followed: Boolean) { + override suspend fun toggleFollowedAuthorId(followedAuthorId: String, followed: Boolean) { niaPreferences.toggleFollowedAuthorId(followedAuthorId, followed) } - override fun getFollowedAuthorIdsStream(): Flow> = niaPreferences.followedAuthorIds + override fun getFollowedAuthorIdsStream(): Flow> = niaPreferences.followedAuthorIds override suspend fun syncWith(synchronizer: Synchronizer) = true } diff --git a/core-domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/repository/fake/FakeNewsRepository.kt b/core-domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/repository/fake/FakeNewsRepository.kt index 57251b0ea..d5698ac1b 100644 --- a/core-domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/repository/fake/FakeNewsRepository.kt +++ b/core-domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/repository/fake/FakeNewsRepository.kt @@ -56,8 +56,8 @@ class FakeNewsRepository @Inject constructor( .flowOn(ioDispatcher) override fun getNewsResourcesStream( - filterAuthorIds: Set, - filterTopicIds: Set, + filterAuthorIds: Set, + filterTopicIds: Set, ): Flow> = flow { emit( diff --git a/core-domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/repository/fake/FakeTopicsRepository.kt b/core-domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/repository/fake/FakeTopicsRepository.kt index 84a86c1e5..9f0675e8f 100644 --- a/core-domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/repository/fake/FakeTopicsRepository.kt +++ b/core-domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/repository/fake/FakeTopicsRepository.kt @@ -61,14 +61,14 @@ class FakeTopicsRepository @Inject constructor( } .flowOn(ioDispatcher) - override fun getTopic(id: Int): Flow { + override fun getTopic(id: String): Flow { return getTopicsStream().map { it.first { topic -> topic.id == id } } } - override suspend fun setFollowedTopicIds(followedTopicIds: Set) = + override suspend fun setFollowedTopicIds(followedTopicIds: Set) = niaPreferences.setFollowedTopicIds(followedTopicIds) - override suspend fun toggleFollowedTopicId(followedTopicId: Int, followed: Boolean) = + override suspend fun toggleFollowedTopicId(followedTopicId: String, followed: Boolean) = niaPreferences.toggleFollowedTopicId(followedTopicId, followed) override fun getFollowedTopicIdsStream() = niaPreferences.followedTopicIds diff --git a/core-domain/src/test/java/com/google/samples/apps/nowinandroid/core/database/model/PopulatedEpisodeKtTest.kt b/core-domain/src/test/java/com/google/samples/apps/nowinandroid/core/database/model/PopulatedEpisodeKtTest.kt index b818e8196..48587ae10 100644 --- a/core-domain/src/test/java/com/google/samples/apps/nowinandroid/core/database/model/PopulatedEpisodeKtTest.kt +++ b/core-domain/src/test/java/com/google/samples/apps/nowinandroid/core/database/model/PopulatedEpisodeKtTest.kt @@ -29,7 +29,7 @@ class PopulatedEpisodeKtTest { fun populated_episode_can_be_mapped_to_episode() { val populatedEpisode = PopulatedEpisode( entity = EpisodeEntity( - id = 0, + id = "0", name = "Test", publishDate = Instant.fromEpochMilliseconds(1), alternateAudio = "audio", @@ -37,8 +37,8 @@ class PopulatedEpisodeKtTest { ), newsResources = listOf( NewsResourceEntity( - id = 1, - episodeId = 0, + id = "1", + episodeId = "0", title = "news", content = "Hilt", url = "url", @@ -49,7 +49,7 @@ class PopulatedEpisodeKtTest { ), authors = listOf( AuthorEntity( - id = 2, + id = "2", name = "name", imageUrl = "imageUrl", twitter = "twitter", @@ -61,15 +61,15 @@ class PopulatedEpisodeKtTest { assertEquals( Episode( - id = 0, + id = "0", name = "Test", publishDate = Instant.fromEpochMilliseconds(1), alternateAudio = "audio", alternateVideo = "video", newsResources = listOf( NewsResource( - id = 1, - episodeId = 0, + id = "1", + episodeId = "0", title = "news", content = "Hilt", url = "url", @@ -82,7 +82,7 @@ class PopulatedEpisodeKtTest { ), authors = listOf( Author( - id = 2, + id = "2", name = "name", imageUrl = "imageUrl", twitter = "twitter", diff --git a/core-domain/src/test/java/com/google/samples/apps/nowinandroid/core/database/model/PopulatedNewsResourceKtTest.kt b/core-domain/src/test/java/com/google/samples/apps/nowinandroid/core/database/model/PopulatedNewsResourceKtTest.kt index e998dbae5..8202ff5dc 100644 --- a/core-domain/src/test/java/com/google/samples/apps/nowinandroid/core/database/model/PopulatedNewsResourceKtTest.kt +++ b/core-domain/src/test/java/com/google/samples/apps/nowinandroid/core/database/model/PopulatedNewsResourceKtTest.kt @@ -29,8 +29,8 @@ class PopulatedNewsResourceKtTest { fun populated_news_resource_can_be_mapped_to_news_resource() { val populatedNewsResource = PopulatedNewsResource( entity = NewsResourceEntity( - id = 1, - episodeId = 0, + id = "1", + episodeId = "0", title = "news", content = "Hilt", url = "url", @@ -39,7 +39,7 @@ class PopulatedNewsResourceKtTest { publishDate = Instant.fromEpochMilliseconds(1), ), episode = EpisodeEntity( - id = 4, + id = "4", name = "episode 4", publishDate = Instant.fromEpochMilliseconds(2), alternateAudio = "audio", @@ -47,7 +47,7 @@ class PopulatedNewsResourceKtTest { ), authors = listOf( AuthorEntity( - id = 2, + id = "2", name = "name", imageUrl = "imageUrl", twitter = "twitter", @@ -56,7 +56,7 @@ class PopulatedNewsResourceKtTest { ), topics = listOf( TopicEntity( - id = 3, + id = "3", name = "name", shortDescription = "short description", longDescription = "long description", @@ -69,8 +69,8 @@ class PopulatedNewsResourceKtTest { assertEquals( NewsResource( - id = 1, - episodeId = 0, + id = "1", + episodeId = "0", title = "news", content = "Hilt", url = "url", @@ -79,7 +79,7 @@ class PopulatedNewsResourceKtTest { publishDate = Instant.fromEpochMilliseconds(1), authors = listOf( Author( - id = 2, + id = "2", name = "name", imageUrl = "imageUrl", twitter = "twitter", @@ -88,7 +88,7 @@ class PopulatedNewsResourceKtTest { ), topics = listOf( Topic( - id = 3, + id = "3", name = "name", shortDescription = "short description", longDescription = "long description", diff --git a/core-domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/model/NetworkEntityKtTest.kt b/core-domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/model/NetworkEntityKtTest.kt index 4ddc2fdba..e8aa609e3 100644 --- a/core-domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/model/NetworkEntityKtTest.kt +++ b/core-domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/model/NetworkEntityKtTest.kt @@ -32,7 +32,7 @@ class NetworkEntityKtTest { @Test fun network_author_can_be_mapped_to_author_entity() { val networkModel = NetworkAuthor( - id = 0, + id = "0", name = "Test", imageUrl = "something", twitter = "twitter", @@ -40,7 +40,7 @@ class NetworkEntityKtTest { ) val entity = networkModel.asEntity() - assertEquals(0, entity.id) + assertEquals("0", entity.id) assertEquals("Test", entity.name) assertEquals("something", entity.imageUrl) } @@ -48,7 +48,7 @@ class NetworkEntityKtTest { @Test fun network_topic_can_be_mapped_to_topic_entity() { val networkModel = NetworkTopic( - id = 0, + id = "0", name = "Test", shortDescription = "short description", longDescription = "long description", @@ -57,7 +57,7 @@ class NetworkEntityKtTest { ) val entity = networkModel.asEntity() - assertEquals(0, entity.id) + assertEquals("0", entity.id) assertEquals("Test", entity.name) assertEquals("short description", entity.shortDescription) assertEquals("long description", entity.longDescription) @@ -69,8 +69,8 @@ class NetworkEntityKtTest { fun network_news_resource_can_be_mapped_to_news_resource_entity() { val networkModel = NetworkNewsResource( - id = 0, - episodeId = 2, + id = "0", + episodeId = "2", title = "title", content = "content", url = "url", @@ -80,8 +80,8 @@ class NetworkEntityKtTest { ) val entity = networkModel.asEntity() - assertEquals(0, entity.id) - assertEquals(2, entity.episodeId) + assertEquals("0", entity.id) + assertEquals("2", entity.episodeId) assertEquals("title", entity.title) assertEquals("content", entity.content) assertEquals("url", entity.url) @@ -91,8 +91,8 @@ class NetworkEntityKtTest { val expandedNetworkModel = NetworkNewsResourceExpanded( - id = 0, - episodeId = 2, + id = "0", + episodeId = "2", title = "title", content = "content", url = "url", @@ -103,8 +103,8 @@ class NetworkEntityKtTest { val entityFromExpanded = expandedNetworkModel.asEntity() - assertEquals(0, entityFromExpanded.id) - assertEquals(2, entityFromExpanded.episodeId) + assertEquals("0", entityFromExpanded.id) + assertEquals("2", entityFromExpanded.episodeId) assertEquals("title", entityFromExpanded.title) assertEquals("content", entityFromExpanded.content) assertEquals("url", entityFromExpanded.url) @@ -116,7 +116,7 @@ class NetworkEntityKtTest { @Test fun network_episode_can_be_mapped_to_episode_entity() { val networkModel = NetworkEpisode( - id = 0, + id = "0", name = "name", publishDate = Instant.fromEpochMilliseconds(1), alternateVideo = "alternateVideo", @@ -124,7 +124,7 @@ class NetworkEntityKtTest { ) val entity = networkModel.asEntity() - assertEquals(0, entity.id) + assertEquals("0", entity.id) assertEquals("name", entity.name) assertEquals("alternateVideo", entity.alternateVideo) assertEquals("alternateAudio", entity.alternateAudio) @@ -132,7 +132,7 @@ class NetworkEntityKtTest { val expandedNetworkModel = NetworkEpisodeExpanded( - id = 0, + id = "0", name = "name", publishDate = Instant.fromEpochMilliseconds(1), alternateVideo = "alternateVideo", @@ -141,7 +141,7 @@ class NetworkEntityKtTest { val entityFromExpanded = expandedNetworkModel.asEntity() - assertEquals(0, entityFromExpanded.id) + assertEquals("0", entityFromExpanded.id) assertEquals("name", entityFromExpanded.name) assertEquals("alternateVideo", entityFromExpanded.alternateVideo) assertEquals("alternateAudio", entityFromExpanded.alternateAudio) diff --git a/core-domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/repository/LocalAuthorsRepositoryTest.kt b/core-domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/repository/LocalAuthorsRepositoryTest.kt index ebb9718bc..4a5e61e06 100644 --- a/core-domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/repository/LocalAuthorsRepositoryTest.kt +++ b/core-domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/repository/LocalAuthorsRepositoryTest.kt @@ -145,9 +145,10 @@ class LocalAuthorsRepositoryTest { .map(NetworkAuthor::asEntity) .map(AuthorEntity::asExternalModel) + // Delete half of the items on the network val deletedItems = networkAuthors .map(Author::id) - .partition { it % 2 == 0 } + .partition { it.chars().sum() % 2 == 0 } .first .toSet() @@ -165,6 +166,7 @@ class LocalAuthorsRepositoryTest { .first() .map(AuthorEntity::asExternalModel) + // Assert that items marked deleted on the network have been deleted locally Assert.assertEquals( networkAuthors.map(Author::id) - deletedItems, dbAuthors.map(Author::id) diff --git a/core-domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/repository/LocalNewsRepositoryTest.kt b/core-domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/repository/LocalNewsRepositoryTest.kt index d960fe053..b51e9c493 100644 --- a/core-domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/repository/LocalNewsRepositoryTest.kt +++ b/core-domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/repository/LocalNewsRepositoryTest.kt @@ -184,9 +184,10 @@ class LocalNewsRepositoryTest { .map(NetworkNewsResource::asEntity) .map(NewsResourceEntity::asExternalModel) + // Delete half of the items on the network val deletedItems = newsResourcesFromNetwork .map(NewsResource::id) - .partition { it % 2 == 0 } + .partition { it.chars().sum() % 2 == 0 } .first .toSet() @@ -204,6 +205,7 @@ class LocalNewsRepositoryTest { .first() .map(PopulatedNewsResource::asExternalModel) + // Assert that items marked deleted on the network have been deleted locally assertEquals( newsResourcesFromNetwork.map(NewsResource::id) - deletedItems, newsResourcesFromDb.map(NewsResource::id) diff --git a/core-domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/repository/LocalTopicsRepositoryTest.kt b/core-domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/repository/LocalTopicsRepositoryTest.kt index 0adb1027b..ca50a980e 100644 --- a/core-domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/repository/LocalTopicsRepositoryTest.kt +++ b/core-domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/repository/LocalTopicsRepositoryTest.kt @@ -150,9 +150,10 @@ class LocalTopicsRepositoryTest { .map(NetworkTopic::asEntity) .map(TopicEntity::asExternalModel) + // Delete half of the items on the network val deletedItems = networkTopics .map(Topic::id) - .partition { it % 2 == 0 } + .partition { it.chars().sum() % 2 == 0 } .first .toSet() @@ -170,6 +171,7 @@ class LocalTopicsRepositoryTest { .first() .map(TopicEntity::asExternalModel) + // Assert that items marked deleted on the network have been deleted locally Assert.assertEquals( networkTopics.map(Topic::id) - deletedItems, dbTopics.map(Topic::id) @@ -185,18 +187,18 @@ class LocalTopicsRepositoryTest { @Test fun localTopicsRepository_toggle_followed_topics_logic_delegates_to_nia_preferences() = runTest { - subject.toggleFollowedTopicId(followedTopicId = 0, followed = true) + subject.toggleFollowedTopicId(followedTopicId = "0", followed = true) Assert.assertEquals( - setOf(0), + setOf("0"), subject.getFollowedTopicIdsStream() .first() ) - subject.toggleFollowedTopicId(followedTopicId = 1, followed = true) + subject.toggleFollowedTopicId(followedTopicId = "1", followed = true) Assert.assertEquals( - setOf(0, 1), + setOf("0", "1"), subject.getFollowedTopicIdsStream() .first() ) @@ -212,10 +214,10 @@ class LocalTopicsRepositoryTest { @Test fun localTopicsRepository_set_followed_topics_logic_delegates_to_nia_preferences() = runTest { - subject.setFollowedTopicIds(followedTopicIds = setOf(1, 2)) + subject.setFollowedTopicIds(followedTopicIds = setOf("1", "2")) Assert.assertEquals( - setOf(1, 2), + setOf("1", "2"), subject.getFollowedTopicIdsStream() .first() ) diff --git a/core-domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/testdoubles/TestAuthorDao.kt b/core-domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/testdoubles/TestAuthorDao.kt index c41349c39..4b2adbbd5 100644 --- a/core-domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/testdoubles/TestAuthorDao.kt +++ b/core-domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/testdoubles/TestAuthorDao.kt @@ -30,7 +30,7 @@ class TestAuthorDao : AuthorDao { private var entitiesStateFlow = MutableStateFlow( listOf( AuthorEntity( - id = 1, + id = "1", name = "Topic", imageUrl = "imageUrl", twitter = "twitter", @@ -52,7 +52,7 @@ class TestAuthorDao : AuthorDao { throw NotImplementedError("Unused in tests") } - override suspend fun deleteAuthors(ids: List) { + override suspend fun deleteAuthors(ids: List) { val idSet = ids.toSet() entitiesStateFlow.update { entities -> entities.filterNot { idSet.contains(it.id) } diff --git a/core-domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/testdoubles/TestEpisodeDao.kt b/core-domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/testdoubles/TestEpisodeDao.kt index 89049bd8f..3a1cca890 100644 --- a/core-domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/testdoubles/TestEpisodeDao.kt +++ b/core-domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/testdoubles/TestEpisodeDao.kt @@ -33,7 +33,7 @@ class TestEpisodeDao : EpisodeDao { private var entitiesStateFlow = MutableStateFlow( listOf( EpisodeEntity( - id = 1, + id = "1", name = "Episode", publishDate = Instant.fromEpochMilliseconds(0), alternateVideo = null, @@ -57,7 +57,7 @@ class TestEpisodeDao : EpisodeDao { throw NotImplementedError("Unused in tests") } - override suspend fun deleteEpisodes(ids: List) { + override suspend fun deleteEpisodes(ids: List) { val idSet = ids.toSet() entitiesStateFlow.update { entities -> entities.filterNot { idSet.contains(it.id) } diff --git a/core-domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/testdoubles/TestNewsResourceDao.kt b/core-domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/testdoubles/TestNewsResourceDao.kt index 561a10feb..82d432786 100644 --- a/core-domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/testdoubles/TestNewsResourceDao.kt +++ b/core-domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/testdoubles/TestNewsResourceDao.kt @@ -31,8 +31,8 @@ import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.update import kotlinx.datetime.Instant -val filteredInterestsIds = setOf(1) -val nonPresentInterestsIds = setOf(2) +val filteredInterestsIds = setOf("1") +val nonPresentInterestsIds = setOf("2") /** * Test double for [NewsResourceDao] @@ -42,8 +42,8 @@ class TestNewsResourceDao : NewsResourceDao { private var entitiesStateFlow = MutableStateFlow( listOf( NewsResourceEntity( - id = 1, - episodeId = 0, + id = "1", + episodeId = "0", title = "news", content = "Hilt", url = "url", @@ -64,8 +64,8 @@ class TestNewsResourceDao : NewsResourceDao { } override fun getNewsResourcesStream( - filterAuthorIds: Set, - filterTopicIds: Set + filterAuthorIds: Set, + filterTopicIds: Set ): Flow> = getNewsResourcesStream() .map { resources -> @@ -99,7 +99,7 @@ class TestNewsResourceDao : NewsResourceDao { authorCrossReferences = newsResourceAuthorCrossReferences } - override suspend fun deleteNewsResources(ids: List) { + override suspend fun deleteNewsResources(ids: List) { val idSet = ids.toSet() entitiesStateFlow.update { entities -> entities.filterNot { idSet.contains(it.id) } diff --git a/core-domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/testdoubles/TestNiaNetwork.kt b/core-domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/testdoubles/TestNiaNetwork.kt index cec2b00d9..2abfb89da 100644 --- a/core-domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/testdoubles/TestNiaNetwork.kt +++ b/core-domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/testdoubles/TestNiaNetwork.kt @@ -58,19 +58,19 @@ class TestNiaNetwork : NiANetwork { .mapToChangeList(idGetter = NetworkNewsResource::id), ) - override suspend fun getTopics(ids: List?): List = + override suspend fun getTopics(ids: List?): List = allTopics.matchIds( ids = ids, idGetter = NetworkTopic::id ) - override suspend fun getAuthors(ids: List?): List = + override suspend fun getAuthors(ids: List?): List = allAuthors.matchIds( ids = ids, idGetter = NetworkAuthor::id ) - override suspend fun getNewsResources(ids: List?): List = + override suspend fun getNewsResources(ids: List?): List = allNewsResources.matchIds( ids = ids, idGetter = NetworkNewsResource::id @@ -95,7 +95,7 @@ class TestNiaNetwork : NiANetwork { * Edits the change list for the backing [collectionType] for the given [id] mimicking * the server's change list registry */ - fun editCollection(collectionType: CollectionType, id: Int, isDelete: Boolean) { + fun editCollection(collectionType: CollectionType, id: String, isDelete: Boolean) { val changeList = changeLists.getValue(collectionType) val latestVersion = changeList.lastOrNull()?.changeListVersion ?: 0 val change = NetworkChangeList( @@ -117,8 +117,8 @@ fun List.after(version: Int?): List = * Return items from [this] whose id defined by [idGetter] is in [ids] if [ids] is not null */ private fun List.matchIds( - ids: List?, - idGetter: (T) -> Int + ids: List?, + idGetter: (T) -> String ) = when (ids) { null -> this else -> ids.toSet().let { idSet -> this.filter { idSet.contains(idGetter(it)) } } @@ -129,7 +129,7 @@ private fun List.matchIds( * [after] simulates which models have changed by excluding items before it */ private fun List.mapToChangeList( - idGetter: (T) -> Int + idGetter: (T) -> String ) = mapIndexed { index, item -> NetworkChangeList( id = idGetter(item), diff --git a/core-domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/testdoubles/TestTopicDao.kt b/core-domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/testdoubles/TestTopicDao.kt index 620df89b0..9def9fd11 100644 --- a/core-domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/testdoubles/TestTopicDao.kt +++ b/core-domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/testdoubles/TestTopicDao.kt @@ -31,7 +31,7 @@ class TestTopicDao : TopicDao { private var entitiesStateFlow = MutableStateFlow( listOf( TopicEntity( - id = 1, + id = "1", name = "Topic", shortDescription = "short description", longDescription = "long description", @@ -41,14 +41,14 @@ class TestTopicDao : TopicDao { ) ) - override fun getTopicEntity(topicId: Int): Flow { + override fun getTopicEntity(topicId: String): Flow { throw NotImplementedError("Unused in tests") } override fun getTopicEntitiesStream(): Flow> = entitiesStateFlow - override fun getTopicEntitiesStream(ids: Set): Flow> = + override fun getTopicEntitiesStream(ids: Set): Flow> = getTopicEntitiesStream() .map { topics -> topics.filter { it.id in ids } } @@ -62,7 +62,7 @@ class TestTopicDao : TopicDao { throw NotImplementedError("Unused in tests") } - override suspend fun deleteTopics(ids: List) { + override suspend fun deleteTopics(ids: List) { val idSet = ids.toSet() entitiesStateFlow.update { entities -> entities.filterNot { idSet.contains(it.id) } diff --git a/core-model/src/main/java/com/google/samples/apps/nowinandroid/core/model/data/Author.kt b/core-model/src/main/java/com/google/samples/apps/nowinandroid/core/model/data/Author.kt index 387a97adc..f1d85adf6 100644 --- a/core-model/src/main/java/com/google/samples/apps/nowinandroid/core/model/data/Author.kt +++ b/core-model/src/main/java/com/google/samples/apps/nowinandroid/core/model/data/Author.kt @@ -20,7 +20,7 @@ package com.google.samples.apps.nowinandroid.core.model.data * External data layer representation of an NiA Author */ data class Author( - val id: Int, + val id: String, val name: String, val imageUrl: String, val twitter: String, diff --git a/core-model/src/main/java/com/google/samples/apps/nowinandroid/core/model/data/Episode.kt b/core-model/src/main/java/com/google/samples/apps/nowinandroid/core/model/data/Episode.kt index f1e4fb336..7d1c1b420 100644 --- a/core-model/src/main/java/com/google/samples/apps/nowinandroid/core/model/data/Episode.kt +++ b/core-model/src/main/java/com/google/samples/apps/nowinandroid/core/model/data/Episode.kt @@ -22,7 +22,7 @@ import kotlinx.datetime.Instant * External data layer representation of an NiA episode */ data class Episode( - val id: Int, + val id: String, val name: String, val publishDate: Instant, val alternateVideo: String?, diff --git a/core-model/src/main/java/com/google/samples/apps/nowinandroid/core/model/data/NewsResource.kt b/core-model/src/main/java/com/google/samples/apps/nowinandroid/core/model/data/NewsResource.kt index b1c122385..d6faff63a 100644 --- a/core-model/src/main/java/com/google/samples/apps/nowinandroid/core/model/data/NewsResource.kt +++ b/core-model/src/main/java/com/google/samples/apps/nowinandroid/core/model/data/NewsResource.kt @@ -22,8 +22,8 @@ import kotlinx.datetime.Instant * External data layer representation of a fully populated NiA news resource */ data class NewsResource( - val id: Int, - val episodeId: Int, + val id: String, + val episodeId: String, val title: String, val content: String, val url: String, diff --git a/core-model/src/main/java/com/google/samples/apps/nowinandroid/core/model/data/Topic.kt b/core-model/src/main/java/com/google/samples/apps/nowinandroid/core/model/data/Topic.kt index f42dcad9a..cc45937b6 100644 --- a/core-model/src/main/java/com/google/samples/apps/nowinandroid/core/model/data/Topic.kt +++ b/core-model/src/main/java/com/google/samples/apps/nowinandroid/core/model/data/Topic.kt @@ -20,7 +20,7 @@ package com.google.samples.apps.nowinandroid.core.model.data * External data layer representation of a NiA Topic */ data class Topic( - val id: Int, + val id: String, val name: String, val shortDescription: String, val longDescription: String, diff --git a/core-network/src/main/java/com/google/samples/apps/nowinandroid/core/network/NiANetwork.kt b/core-network/src/main/java/com/google/samples/apps/nowinandroid/core/network/NiANetwork.kt index ae185435d..20ecae4cc 100644 --- a/core-network/src/main/java/com/google/samples/apps/nowinandroid/core/network/NiANetwork.kt +++ b/core-network/src/main/java/com/google/samples/apps/nowinandroid/core/network/NiANetwork.kt @@ -25,11 +25,11 @@ import com.google.samples.apps.nowinandroid.core.network.model.NetworkTopic * Interface representing network calls to the NIA backend */ interface NiANetwork { - suspend fun getTopics(ids: List? = null): List + suspend fun getTopics(ids: List? = null): List - suspend fun getAuthors(ids: List? = null): List + suspend fun getAuthors(ids: List? = null): List - suspend fun getNewsResources(ids: List? = null): List + suspend fun getNewsResources(ids: List? = null): List suspend fun getTopicChangeList(after: Int? = null): List diff --git a/core-network/src/main/java/com/google/samples/apps/nowinandroid/core/network/fake/FakeDataSource.kt b/core-network/src/main/java/com/google/samples/apps/nowinandroid/core/network/fake/FakeDataSource.kt index eee7b83ba..237df4651 100644 --- a/core-network/src/main/java/com/google/samples/apps/nowinandroid/core/network/fake/FakeDataSource.kt +++ b/core-network/src/main/java/com/google/samples/apps/nowinandroid/core/network/fake/FakeDataSource.kt @@ -28,7 +28,7 @@ import org.intellij.lang.annotations.Language object FakeDataSource { val sampleTopic = NetworkTopic( - id = 1, + id = "1", name = "UI", shortDescription = "Material Design, Navigation, Text, Paging, Compose, Accessibility (a11y), Internationalization (i18n), Localization (l10n), Animations, Large Screens, Widgets", longDescription = "Learn how to optimize your app's user interface - everything that users can see and interact with. Stay up to date on tocpis such as Material Design, Navigation, Text, Paging, Compose, Accessibility (a11y), Internationalization (i18n), Localization (l10n), Animations, Large Screens, Widgets, and many more!", @@ -36,13 +36,13 @@ object FakeDataSource { imageUrl = "https://firebasestorage.googleapis.com/v0/b/now-in-android.appspot.com/o/img%2Fic_topic_UI.svg?alt=media&token=5d1d25a8-db1b-4cf1-9706-82ba0d133bf9" ) val sampleResource = NetworkNewsResource( - id = 1, - episodeId = 57, + id = "1", + episodeId = "57", title = "Discontinuing Kotlin synthetics for views", content = "Synthetic properties to access views were created as a way to eliminate the common boilerplate of findViewById calls. These synthetics are provided by JetBrains in the Kotlin Android Extensions Gradle plugin (not to be confused with Android KTX).", url = "https://android-developers.googleblog.com/2022/02/discontinuing-kotlin-synthetics-for-views.html", headerImageUrl = "", - authors = listOf(1), + authors = listOf("1"), publishDate = LocalDateTime( year = 2022, monthNumber = 2, @@ -53,7 +53,7 @@ object FakeDataSource { nanosecond = 0 ).toInstant(TimeZone.UTC), type = Article, - topics = listOf(1, 8), + topics = listOf("3", "10"), ) @Language("JSON") @@ -235,11 +235,11 @@ object FakeDataSource { "publishDate": "2022-02-18T00:00:00.000Z", "type": "Article 📚", "topics": [ - "1", - "8" + "3", + "10" ], "authors": [ - 1 + "1" ] }, { @@ -252,10 +252,10 @@ object FakeDataSource { "publishDate": "2022-03-15T00:00:00.000Z", "type": "Article 📚", "topics": [ - "18" + "20" ], "authors": [ - 2 + "2" ] }, { @@ -268,10 +268,10 @@ object FakeDataSource { "publishDate": "2022-03-14T00:00:00.000Z", "type": "Article 📚", "topics": [ - "7" + "9" ], "authors": [ - 3 + "3" ] }, { @@ -284,11 +284,12 @@ object FakeDataSource { "publishDate": "2022-03-10T00:00:00.000Z", "type": "Article 📚", "topics": [ - "9", - "11" + "11", + "13" ], "authors": [ - 4 + "4", + "5" ] }, { @@ -301,7 +302,7 @@ object FakeDataSource { "publishDate": "2022-03-10T00:00:00.000Z", "type": "Event 📆", "topics": [ - "0" + "2" ], "authors": [] }, @@ -315,13 +316,13 @@ object FakeDataSource { "publishDate": "2022-03-09T00:00:00.000Z", "type": "Video 📺", "topics": [ - "9", - "1", - "13", - "0" + "11", + "3", + "15", + "2" ], "authors": [ - 6 + "6" ] }, { @@ -334,10 +335,11 @@ object FakeDataSource { "publishDate": "2022-03-08T00:00:00.000Z", "type": "Article 📚", "topics": [ - "7" + "9" ], "authors": [ - 7 + "7", + "8" ] }, { @@ -350,11 +352,11 @@ object FakeDataSource { "publishDate": "2022-03-07T00:00:00.000Z", "type": "Article 📚", "topics": [ - "1", - "19" + "3", + "21" ], "authors": [ - 9 + "9" ] }, { @@ -367,10 +369,10 @@ object FakeDataSource { "publishDate": "2022-03-03T00:00:00.000Z", "type": "Article 📚", "topics": [ - "10" + "12" ], "authors": [ - 10 + "10" ] }, { @@ -383,7 +385,7 @@ object FakeDataSource { "publishDate": "2022-02-23T00:00:00.000Z", "type": "Jetpack release 🚀", "topics": [ - "18" + "20" ], "authors": [] }, @@ -397,7 +399,7 @@ object FakeDataSource { "publishDate": "2022-02-23T00:00:00.000Z", "type": "Jetpack release 🚀", "topics": [ - "7" + "9" ], "authors": [] }, @@ -411,7 +413,7 @@ object FakeDataSource { "publishDate": "2022-02-23T00:00:00.000Z", "type": "Jetpack release 🚀", "topics": [ - "4" + "6" ], "authors": [] }, @@ -425,7 +427,7 @@ object FakeDataSource { "publishDate": "2022-02-23T00:00:00.000Z", "type": "Jetpack release 🚀", "topics": [ - "1" + "3" ], "authors": [] }, @@ -439,10 +441,10 @@ object FakeDataSource { "publishDate": "2022-02-23T00:00:00.000Z", "type": "Article 📚", "topics": [ - "4" + "6" ], "authors": [ - 11 + "11" ] }, { @@ -455,10 +457,10 @@ object FakeDataSource { "publishDate": "2022-02-17T00:00:00.000Z", "type": "Article 📚", "topics": [ - "1" + "3" ], "authors": [ - 12 + "12" ] }, { @@ -471,10 +473,10 @@ object FakeDataSource { "publishDate": "2022-02-09T00:00:00.000Z", "type": "Jetpack release 🚀", "topics": [ - "1" + "3" ], "authors": [ - 6 + "6" ] }, { @@ -487,10 +489,10 @@ object FakeDataSource { "publishDate": "2022-02-15T00:00:00.000Z", "type": "Article 📚", "topics": [ - "7" + "9" ], "authors": [ - 3 + "3" ] }, { @@ -503,10 +505,10 @@ object FakeDataSource { "publishDate": "2022-02-16T00:00:00.000Z", "type": "Article 📚", "topics": [ - "7" + "9" ], "authors": [ - 3 + "3" ] }, { @@ -519,10 +521,12 @@ object FakeDataSource { "publishDate": "2022-02-10T00:00:00.000Z", "type": "Article 📚", "topics": [ - "1", - "13" + "3", + "15" ], - "authors": [] + "authors": [ + "13" + ] }, { "id": "20", @@ -534,10 +538,10 @@ object FakeDataSource { "publishDate": "2022-02-10T00:00:00.000Z", "type": "Article 📚", "topics": [ - "13" + "15" ], "authors": [ - 14 + "14" ] }, { @@ -550,11 +554,11 @@ object FakeDataSource { "publishDate": "2022-02-09T00:00:00.000Z", "type": "Docs 📑", "topics": [ - "9", - "6" + "11", + "8" ], "authors": [ - 15 + "15" ] }, { @@ -567,10 +571,10 @@ object FakeDataSource { "publishDate": "2022-02-07T00:00:00.000Z", "type": "Video 📺", "topics": [ - "7" + "9" ], "authors": [ - 3 + "3" ] }, { @@ -583,10 +587,10 @@ object FakeDataSource { "publishDate": "2022-01-31T00:00:00.000Z", "type": "Article 📚", "topics": [ - "7" + "9" ], "authors": [ - 3 + "3" ] }, { @@ -599,10 +603,10 @@ object FakeDataSource { "publishDate": "2022-01-26T00:00:00.000Z", "type": "Article 📚", "topics": [ - "19" + "21" ], "authors": [ - 16 + "16" ] }, { @@ -615,10 +619,10 @@ object FakeDataSource { "publishDate": "2022-01-25T00:00:00.000Z", "type": "Article 📚", "topics": [ - "5" + "7" ], "authors": [ - 17 + "17" ] }, { @@ -631,10 +635,10 @@ object FakeDataSource { "publishDate": "2022-01-24T00:00:00.000Z", "type": "Article 📚", "topics": [ - "7" + "9" ], "authors": [ - 3 + "3" ] }, { @@ -647,10 +651,10 @@ object FakeDataSource { "publishDate": "2022-01-27T00:00:00.000Z", "type": "Article 📚", "topics": [ - "16" + "18" ], "authors": [ - 18 + "18" ] }, { @@ -663,7 +667,7 @@ object FakeDataSource { "publishDate": "2022-01-26T00:00:00.000Z", "type": "Jetpack release 🚀", "topics": [ - "1" + "3" ], "authors": [] }, @@ -677,7 +681,7 @@ object FakeDataSource { "publishDate": "2022-02-11T00:00:00.000Z", "type": "Jetpack release 🚀", "topics": [ - "9" + "11" ], "authors": [] }, @@ -691,10 +695,12 @@ object FakeDataSource { "publishDate": "2022-01-28T00:00:00.000Z", "type": "Article 📚", "topics": [ - "3" + "5" ], "authors": [ - 19 + "19", + "20", + "21" ] }, { @@ -707,7 +713,7 @@ object FakeDataSource { "publishDate": "2022-02-02T00:00:00.000Z", "type": "Article 📚", "topics": [ - "4" + "6" ], "authors": [] }, @@ -721,7 +727,7 @@ object FakeDataSource { "publishDate": "2022-02-11T00:00:00.000Z", "type": "Docs 📑", "topics": [ - "14" + "16" ], "authors": [] }, @@ -735,8 +741,8 @@ object FakeDataSource { "publishDate": "2022-02-11T00:00:00.000Z", "type": "Docs 📑", "topics": [ - "17", - "15" + "19", + "17" ], "authors": [] }, @@ -750,7 +756,7 @@ object FakeDataSource { "publishDate": "2022-01-21T00:00:00.000Z", "type": "Video 📺", "topics": [ - "15" + "17" ], "authors": [] }, @@ -764,7 +770,7 @@ object FakeDataSource { "publishDate": "2022-02-01T00:00:00.000Z", "type": "Podcast 🎙", "topics": [ - "1" + "3" ], "authors": [] }, @@ -778,10 +784,10 @@ object FakeDataSource { "publishDate": "2021-12-15T00:00:00.000Z", "type": "Article 📚", "topics": [ - "6" + "8" ], "authors": [ - 22 + "9" ] }, { @@ -794,12 +800,12 @@ object FakeDataSource { "publishDate": "2021-12-01T00:00:00.000Z", "type": "Article 📚", "topics": [ - "19", - "9", - "6" + "21", + "11", + "8" ], "authors": [ - 23 + "22" ] }, { @@ -812,10 +818,10 @@ object FakeDataSource { "publishDate": "2021-12-14T00:00:00.000Z", "type": "Article 📚", "topics": [ - "14" + "16" ], "authors": [ - 24 + "23" ] }, { @@ -828,10 +834,10 @@ object FakeDataSource { "publishDate": "2022-01-19T00:00:00.000Z", "type": "Article 📚", "topics": [ - "18" + "20" ], "authors": [ - 25 + "24" ] }, { @@ -844,10 +850,10 @@ object FakeDataSource { "publishDate": "2021-12-01T00:00:00.000Z", "type": "Article 📚", "topics": [ - "12" + "14" ], "authors": [ - 26 + "25" ] }, { @@ -860,10 +866,10 @@ object FakeDataSource { "publishDate": "2021-12-15T00:00:00.000Z", "type": "Video 📺", "topics": [ - "12" + "14" ], "authors": [ - 27 + "26" ] }, { @@ -876,10 +882,10 @@ object FakeDataSource { "publishDate": "2021-11-29T00:00:00.000Z", "type": "Video 📺", "topics": [ - "12" + "14" ], "authors": [ - 26 + "25" ] }, { @@ -892,10 +898,10 @@ object FakeDataSource { "publishDate": "2021-12-16T00:00:00.000Z", "type": "Article 📚", "topics": [ - "12" + "14" ], "authors": [ - 26 + "25" ] }, { @@ -908,9 +914,11 @@ object FakeDataSource { "publishDate": "2022-01-18T00:00:00.000Z", "type": "Video 📺", "topics": [ - "7" + "9" ], - "authors": [] + "authors": [ + "3" + ] }, { "id": "45", @@ -922,7 +930,7 @@ object FakeDataSource { "publishDate": "2021-12-01T00:00:00.000Z", "type": "Docs 📑", "topics": [ - "6" + "8" ], "authors": [] }, @@ -936,10 +944,10 @@ object FakeDataSource { "publishDate": "2022-01-18T00:00:00.000Z", "type": "Article 📚", "topics": [ - "1" + "3" ], "authors": [ - 23 + "22" ] }, { @@ -952,10 +960,10 @@ object FakeDataSource { "publishDate": "2021-12-15T00:00:00.000Z", "type": "Article 📚", "topics": [ - "6" + "8" ], "authors": [ - 28 + "27" ] }, { @@ -968,10 +976,10 @@ object FakeDataSource { "publishDate": "2021-12-03T00:00:00.000Z", "type": "Video 📺", "topics": [ - "15" + "17" ], "authors": [ - 29 + "28" ] }, { @@ -984,10 +992,10 @@ object FakeDataSource { "publishDate": "2021-12-10T00:00:00.000Z", "type": "Video 📺", "topics": [ - "15" + "17" ], "authors": [ - 29 + "28" ] }, { @@ -1000,10 +1008,10 @@ object FakeDataSource { "publishDate": "2021-12-22T00:00:00.000Z", "type": "Video 📺", "topics": [ - "15" + "17" ], "authors": [ - 29 + "28" ] }, { @@ -1016,10 +1024,10 @@ object FakeDataSource { "publishDate": "2022-01-14T00:00:00.000Z", "type": "Video 📺", "topics": [ - "17" + "19" ], "authors": [ - 30 + "29" ] }, { @@ -1032,10 +1040,13 @@ object FakeDataSource { "publishDate": "2021-11-30T00:00:00.000Z", "type": "Podcast 🎙", "topics": [ - "13" + "15" ], "authors": [ - 31 + "30", + "31", + "32", + "33" ] }, { @@ -1048,10 +1059,13 @@ object FakeDataSource { "publishDate": "2021-12-16T00:00:00.000Z", "type": "Podcast 🎙", "topics": [ - "8" + "10" ], "authors": [ - 31 + "30", + "31", + "32", + "34" ] }, { @@ -1064,10 +1078,13 @@ object FakeDataSource { "publishDate": "2022-01-11T00:00:00.000Z", "type": "Podcast 🎙", "topics": [ - "14" + "16" ], "authors": [ - 32 + "31", + "31", + "32", + "23" ] }, { @@ -1080,10 +1097,10 @@ object FakeDataSource { "publishDate": "2021-10-03T23:00:00.000Z", "type": "DAC - Android version features", "topics": [ - "13" + "15" ], "authors": [ - 14 + "14" ] }, { @@ -1096,7 +1113,7 @@ object FakeDataSource { "publishDate": "2021-12-07T00:00:00.000Z", "type": "Jetpack release 🚀", "topics": [ - "9" + "11" ], "authors": [] }, @@ -1110,7 +1127,7 @@ object FakeDataSource { "publishDate": "2021-12-07T00:00:00.000Z", "type": "Codelab", "topics": [ - "8" + "10" ], "authors": [] }, @@ -1124,11 +1141,11 @@ object FakeDataSource { "publishDate": "2021-12-14T00:00:00.000Z", "type": "Video 📺", "topics": [ - "8", - "6" + "10", + "8" ], "authors": [ - 6 + "6" ] }, { @@ -1141,12 +1158,12 @@ object FakeDataSource { "publishDate": "2022-01-19T00:00:00.000Z", "type": "Video 📺", "topics": [ - "8", - "1", - "6" + "10", + "3", + "8" ], "authors": [ - 36 + "35" ] }, { @@ -1159,10 +1176,10 @@ object FakeDataSource { "publishDate": "2022-03-01T00:00:00.000Z", "type": "Video 📺", "topics": [ - "6" + "8" ], "authors": [ - 37 + "36" ] }, { @@ -1175,10 +1192,10 @@ object FakeDataSource { "publishDate": "2022-03-25T00:00:00.000Z", "type": "Video 📺", "topics": [ - "6" + "8" ], "authors": [ - 38 + "31" ] }, { @@ -1191,10 +1208,10 @@ object FakeDataSource { "publishDate": "2021-07-18T23:00:00.000Z", "type": "Video 📺", "topics": [ - "3" + "5" ], "authors": [ - 39 + "37" ] }, { @@ -1207,10 +1224,10 @@ object FakeDataSource { "publishDate": "2021-08-22T23:00:00.000Z", "type": "Video 📺", "topics": [ - "6" + "8" ], "authors": [ - 40 + "23" ] }, { @@ -1223,10 +1240,10 @@ object FakeDataSource { "publishDate": "2021-09-26T23:00:00.000Z", "type": "Video 📺", "topics": [ - "6" + "8" ], "authors": [ - 41 + "38" ] }, { @@ -1239,11 +1256,11 @@ object FakeDataSource { "publishDate": "2021-11-15T00:00:00.000Z", "type": "Video 📺", "topics": [ - "12", - "5" + "14", + "7" ], "authors": [ - 26 + "25" ] }, { @@ -1256,7 +1273,7 @@ object FakeDataSource { "publishDate": "2021-05-17T23:00:00.000Z", "type": "Video 📺", "topics": [ - "0" + "2" ], "authors": [] }, @@ -1270,7 +1287,7 @@ object FakeDataSource { "publishDate": "2021-10-26T23:00:00.000Z", "type": "Video 📺", "topics": [ - "0" + "2" ], "authors": [] }, @@ -1284,10 +1301,10 @@ object FakeDataSource { "publishDate": "2021-11-30T00:00:00.000Z", "type": "Video 📺", "topics": [ - "1" + "3" ], "authors": [ - 42 + "39" ] }, { @@ -1300,10 +1317,10 @@ object FakeDataSource { "publishDate": "2021-11-29T00:00:00.000Z", "type": "Video 📺", "topics": [ - "12" + "14" ], "authors": [ - 43 + "25" ] }, { @@ -1316,10 +1333,10 @@ object FakeDataSource { "publishDate": "2021-11-22T00:00:00.000Z", "type": "Video 📺", "topics": [ - "12" + "14" ], "authors": [ - 43 + "25" ] }, { @@ -1332,11 +1349,11 @@ object FakeDataSource { "publishDate": "2021-11-19T00:00:00.000Z", "type": "Article 📚", "topics": [ - "6", - "4" + "8", + "6" ], "authors": [ - 44 + "40" ] }, { @@ -1349,8 +1366,8 @@ object FakeDataSource { "publishDate": "2021-11-17T00:00:00.000Z", "type": "Jetpack release 🚀", "topics": [ - "6", - "1" + "8", + "3" ], "authors": [] }, @@ -1364,8 +1381,8 @@ object FakeDataSource { "publishDate": "2021-11-17T00:00:00.000Z", "type": "Jetpack release 🚀", "topics": [ - "6", - "1" + "8", + "3" ], "authors": [] }, @@ -1379,8 +1396,8 @@ object FakeDataSource { "publishDate": "2021-11-17T00:00:00.000Z", "type": "Jetpack release 🚀", "topics": [ - "6", - "14" + "8", + "16" ], "authors": [] }, @@ -1394,8 +1411,8 @@ object FakeDataSource { "publishDate": "2021-11-17T00:00:00.000Z", "type": "Jetpack release 🚀", "topics": [ - "6", - "1" + "8", + "3" ], "authors": [] }, @@ -1409,8 +1426,8 @@ object FakeDataSource { "publishDate": "2021-11-17T00:00:00.000Z", "type": "Jetpack release 🚀", "topics": [ - "6", - "19" + "8", + "21" ], "authors": [] }, @@ -1424,10 +1441,10 @@ object FakeDataSource { "publishDate": "2021-11-17T00:00:00.000Z", "type": "Video 📺", "topics": [ - "1" + "3" ], "authors": [ - 42 + "39" ] }, { @@ -1440,7 +1457,7 @@ object FakeDataSource { "publishDate": "2021-11-16T00:00:00.000Z", "type": "Article 📚", "topics": [ - "3" + "5" ], "authors": [] }, @@ -1454,10 +1471,10 @@ object FakeDataSource { "publishDate": "2021-11-15T00:00:00.000Z", "type": "Video 📺", "topics": [ - "12" + "14" ], "authors": [ - 43 + "25" ] }, { @@ -1470,10 +1487,10 @@ object FakeDataSource { "publishDate": "2021-11-15T00:00:00.000Z", "type": "Video 📺", "topics": [ - "12" + "14" ], "authors": [ - 43 + "25" ] }, { @@ -1486,12 +1503,12 @@ object FakeDataSource { "publishDate": "2021-11-15T00:00:00.000Z", "type": "Podcast 🎙", "topics": [ + "7", "5", - "3", - "13" + "15" ], "authors": [ - 38 + "31" ] }, { @@ -1504,11 +1521,11 @@ object FakeDataSource { "publishDate": "2021-11-12T00:00:00.000Z", "type": "Article 📚", "topics": [ - "6", - "1" + "8", + "3" ], "authors": [ - 45 + "15" ] }, { @@ -1521,7 +1538,7 @@ object FakeDataSource { "publishDate": "2021-11-11T00:00:00.000Z", "type": "Video 📺", "topics": [ - "1" + "3" ], "authors": [] }, @@ -1535,7 +1552,7 @@ object FakeDataSource { "publishDate": "2021-11-09T00:00:00.000Z", "type": "Video 📺", "topics": [ - "0" + "2" ], "authors": [] }, @@ -1549,7 +1566,7 @@ object FakeDataSource { "publishDate": "2021-11-08T00:00:00.000Z", "type": "Video 📺", "topics": [ - "1" + "3" ], "authors": [] }, @@ -1563,10 +1580,10 @@ object FakeDataSource { "publishDate": "2021-11-01T00:00:00.000Z", "type": "Video 📺", "topics": [ - "1" + "3" ], "authors": [ - 41 + "38" ] }, { @@ -1579,11 +1596,11 @@ object FakeDataSource { "publishDate": "2021-10-27T23:00:00.000Z", "type": "Codelab", "topics": [ - "9", - "19" + "11", + "21" ], "authors": [ - 46 + "41" ] }, { @@ -1596,11 +1613,11 @@ object FakeDataSource { "publishDate": "2021-10-26T23:00:00.000Z", "type": "Article 📚", "topics": [ - "6", - "4" + "8", + "6" ], "authors": [ - 47 + "42" ] }, { @@ -1613,7 +1630,7 @@ object FakeDataSource { "publishDate": "2021-10-26T23:00:00.000Z", "type": "Video 📺", "topics": [ - "10" + "12" ], "authors": [] }, @@ -1627,7 +1644,7 @@ object FakeDataSource { "publishDate": "2021-10-26T23:00:00.000Z", "type": "Video 📺", "topics": [ - "10" + "12" ], "authors": [] }, @@ -1641,10 +1658,10 @@ object FakeDataSource { "publishDate": "2021-10-26T23:00:00.000Z", "type": "Article 📚", "topics": [ - "10" + "12" ], "authors": [ - 15 + "15" ] }, { @@ -1657,10 +1674,10 @@ object FakeDataSource { "publishDate": "2021-10-26T23:00:00.000Z", "type": "Article 📚", "topics": [ - "10" + "12" ], "authors": [ - 48 + "43" ] }, { @@ -1673,8 +1690,8 @@ object FakeDataSource { "publishDate": "2021-10-26T23:00:00.000Z", "type": "Video 📺", "topics": [ - "10", - "11" + "12", + "13" ], "authors": [] }, @@ -1688,7 +1705,7 @@ object FakeDataSource { "publishDate": "2021-10-26T23:00:00.000Z", "type": "Video 📺", "topics": [ - "1" + "3" ], "authors": [] }, @@ -1702,7 +1719,7 @@ object FakeDataSource { "publishDate": "2021-10-26T23:00:00.000Z", "type": "Video 📺", "topics": [ - "1" + "3" ], "authors": [] }, @@ -1716,7 +1733,7 @@ object FakeDataSource { "publishDate": "2021-10-26T23:00:00.000Z", "type": "Video 📺", "topics": [ - "1" + "3" ], "authors": [] }, @@ -1730,8 +1747,8 @@ object FakeDataSource { "publishDate": "2021-10-26T23:00:00.000Z", "type": "Video 📺", "topics": [ - "1", - "4" + "3", + "6" ], "authors": [] }, @@ -1745,7 +1762,7 @@ object FakeDataSource { "publishDate": "2021-10-26T23:00:00.000Z", "type": "Video 📺", "topics": [ - "1" + "3" ], "authors": [] }, @@ -1759,8 +1776,8 @@ object FakeDataSource { "publishDate": "2021-10-26T23:00:00.000Z", "type": "Article 📚", "topics": [ - "1", - "13" + "3", + "15" ], "authors": [] }, @@ -1774,8 +1791,8 @@ object FakeDataSource { "publishDate": "2021-10-26T23:00:00.000Z", "type": "Video 📺", "topics": [ - "6", - "1" + "8", + "3" ], "authors": [] }, @@ -1789,7 +1806,7 @@ object FakeDataSource { "publishDate": "2021-10-26T23:00:00.000Z", "type": "Video 📺", "topics": [ - "13" + "15" ], "authors": [] }, @@ -1803,7 +1820,7 @@ object FakeDataSource { "publishDate": "2021-10-26T23:00:00.000Z", "type": "Video 📺", "topics": [ - "13" + "15" ], "authors": [] }, @@ -1817,7 +1834,7 @@ object FakeDataSource { "publishDate": "2021-10-26T23:00:00.000Z", "type": "Video 📺", "topics": [ - "1" + "3" ], "authors": [] }, @@ -1831,10 +1848,10 @@ object FakeDataSource { "publishDate": "2021-10-20T23:00:00.000Z", "type": "Article 📚", "topics": [ - "8" + "10" ], "authors": [ - 26 + "25" ] }, { @@ -1847,7 +1864,7 @@ object FakeDataSource { "publishDate": "2021-10-20T23:00:00.000Z", "type": "API change", "topics": [ - "14" + "16" ], "authors": [] }, @@ -1861,7 +1878,7 @@ object FakeDataSource { "publishDate": "2021-10-20T23:00:00.000Z", "type": "Docs 📑", "topics": [ - "1" + "3" ], "authors": [] }, @@ -1875,8 +1892,8 @@ object FakeDataSource { "publishDate": "2021-10-20T23:00:00.000Z", "type": "Docs 📑", "topics": [ - "12", - "5" + "14", + "7" ], "authors": [] }, @@ -1890,7 +1907,7 @@ object FakeDataSource { "publishDate": "2021-10-20T23:00:00.000Z", "type": "Codelab", "topics": [ - "9" + "11" ], "authors": [] }, @@ -1904,7 +1921,7 @@ object FakeDataSource { "publishDate": "2021-10-20T23:00:00.000Z", "type": "Docs 📑", "topics": [ - "9" + "11" ], "authors": [] }, @@ -1918,8 +1935,8 @@ object FakeDataSource { "publishDate": "2021-10-20T23:00:00.000Z", "type": "Docs 📑", "topics": [ - "9", - "1" + "11", + "3" ], "authors": [] }, @@ -1933,8 +1950,8 @@ object FakeDataSource { "publishDate": "2021-10-20T23:00:00.000Z", "type": "Docs 📑", "topics": [ - "9", - "1" + "11", + "3" ], "authors": [] }, @@ -1948,7 +1965,7 @@ object FakeDataSource { "publishDate": "2021-10-20T23:00:00.000Z", "type": "Docs 📑", "topics": [ - "9" + "11" ], "authors": [] }, @@ -1962,11 +1979,11 @@ object FakeDataSource { "publishDate": "2021-10-17T23:00:00.000Z", "type": "Video 📺", "topics": [ - "7", - "1" + "9", + "3" ], "authors": [ - 41 + "38" ] }, { @@ -1979,11 +1996,11 @@ object FakeDataSource { "publishDate": "2021-10-17T23:00:00.000Z", "type": "Article 📚", "topics": [ - "10", - "11" + "12", + "13" ], "authors": [ - 10 + "10" ] }, { @@ -1996,10 +2013,10 @@ object FakeDataSource { "publishDate": "2021-10-17T23:00:00.000Z", "type": "Podcast 🎙", "topics": [ - "4" + "6" ], "authors": [ - 38 + "31" ] }, { @@ -2012,10 +2029,10 @@ object FakeDataSource { "publishDate": "2021-10-16T23:00:00.000Z", "type": "Video 📺", "topics": [ - "15" + "17" ], "authors": [ - 42 + "39" ] }, { @@ -2028,10 +2045,10 @@ object FakeDataSource { "publishDate": "2021-10-12T23:00:00.000Z", "type": "Article 📚", "topics": [ - "4" + "6" ], "authors": [ - 49 + "44" ] }, { @@ -2044,11 +2061,11 @@ object FakeDataSource { "publishDate": "2021-10-11T23:00:00.000Z", "type": "Article 📚", "topics": [ - "19", - "9" + "21", + "11" ], "authors": [ - 46 + "41" ] }, { @@ -2061,10 +2078,10 @@ object FakeDataSource { "publishDate": "2021-10-10T23:00:00.000Z", "type": "Video 📺", "topics": [ - "1" + "3" ], "authors": [ - 41 + "38" ] }, { @@ -2077,10 +2094,10 @@ object FakeDataSource { "publishDate": "2021-10-09T23:00:00.000Z", "type": "Article 📚", "topics": [ - "7" + "9" ], "authors": [ - 35 + "34" ] }, { @@ -2093,10 +2110,10 @@ object FakeDataSource { "publishDate": "2021-10-06T23:00:00.000Z", "type": "Article 📚", "topics": [ - "4" + "6" ], "authors": [ - 50 + "45" ] }, { @@ -2109,11 +2126,11 @@ object FakeDataSource { "publishDate": "2021-09-14T23:00:00.000Z", "type": "Article 📚", "topics": [ - "6", - "19" + "8", + "21" ], "authors": [ - 46 + "41" ] }, { @@ -2126,7 +2143,7 @@ object FakeDataSource { "publishDate": "2021-10-05T23:00:00.000Z", "type": "Event 📆", "topics": [ - "0" + "2" ], "authors": [] }, @@ -2140,10 +2157,10 @@ object FakeDataSource { "publishDate": "2021-10-03T23:00:00.000Z", "type": "Article 📚", "topics": [ - "13" + "15" ], "authors": [ - 14 + "14" ] }, { @@ -2156,10 +2173,10 @@ object FakeDataSource { "publishDate": "2021-09-20T23:00:00.000Z", "type": "Article 📚", "topics": [ - "11" + "13" ], "authors": [ - 51 + "46" ] }, { @@ -2172,10 +2189,10 @@ object FakeDataSource { "publishDate": "2021-09-16T23:00:00.000Z", "type": "DAC - Android version features", "topics": [ - "10" + "12" ], "authors": [ - 52 + "47" ] }, { @@ -2188,10 +2205,10 @@ object FakeDataSource { "publishDate": "2021-09-19T23:00:00.000Z", "type": "Video 📺", "topics": [ - "14" + "16" ], "authors": [ - 53 + "48" ] }, { @@ -2204,10 +2221,10 @@ object FakeDataSource { "publishDate": "2021-09-13T23:00:00.000Z", "type": "Podcast 🎙", "topics": [ - "1" + "3" ], "authors": [ - 38 + "31" ] }, { @@ -2220,10 +2237,10 @@ object FakeDataSource { "publishDate": "2021-09-12T23:00:00.000Z", "type": "Article 📚", "topics": [ - "14" + "16" ], "authors": [ - 54 + "49" ] }, { @@ -2236,10 +2253,10 @@ object FakeDataSource { "publishDate": "2021-09-09T23:00:00.000Z", "type": "Video 📺", "topics": [ - "15" + "17" ], "authors": [ - 29 + "28" ] }, { @@ -2252,11 +2269,11 @@ object FakeDataSource { "publishDate": "2021-09-08T23:00:00.000Z", "type": "Podcast 🎙", "topics": [ - "5", - "9" + "7", + "11" ], "authors": [ - 33 + "32" ] }, { @@ -2269,10 +2286,10 @@ object FakeDataSource { "publishDate": "2021-09-07T23:00:00.000Z", "type": "Article 📚", "topics": [ - "14" + "16" ], "authors": [ - 55 + "50" ] }, { @@ -2285,10 +2302,10 @@ object FakeDataSource { "publishDate": "2021-09-06T23:00:00.000Z", "type": "Article 📚", "topics": [ - "1" + "3" ], "authors": [ - 56 + "51" ] }, { @@ -2301,10 +2318,10 @@ object FakeDataSource { "publishDate": "2021-09-02T23:00:00.000Z", "type": "Video 📺", "topics": [ - "15" + "17" ], "authors": [ - 42 + "39" ] }, { @@ -2317,7 +2334,7 @@ object FakeDataSource { "publishDate": "2021-08-31T23:00:00.000Z", "type": "", "topics": [ - "15" + "17" ], "authors": [] }, @@ -2331,7 +2348,7 @@ object FakeDataSource { "publishDate": "2021-08-31T23:00:00.000Z", "type": "API change", "topics": [ - "6" + "8" ], "authors": [] }, @@ -2345,7 +2362,7 @@ object FakeDataSource { "publishDate": "2021-08-03T23:00:00.000Z", "type": "Jetpack release 🚀", "topics": [ - "7" + "9" ], "authors": [] }, @@ -2359,10 +2376,10 @@ object FakeDataSource { "publishDate": "2021-07-27T23:00:00.000Z", "type": "Article 📚", "topics": [ - "9" + "11" ], "authors": [ - 57 + "52" ] }, { @@ -2375,11 +2392,11 @@ object FakeDataSource { "publishDate": "2021-07-27T23:00:00.000Z", "type": "Article 📚", "topics": [ - "5", - "9" + "7", + "11" ], "authors": [ - 58 + "53" ] }, { @@ -2392,10 +2409,10 @@ object FakeDataSource { "publishDate": "2021-07-27T23:00:00.000Z", "type": "Article 📚", "topics": [ - "11" + "13" ], "authors": [ - 10 + "10" ] }, { @@ -2408,11 +2425,11 @@ object FakeDataSource { "publishDate": "2021-07-25T23:00:00.000Z", "type": "Video 📺", "topics": [ - "3", - "5" + "5", + "7" ], "authors": [ - 39 + "37" ] }, { @@ -2425,11 +2442,11 @@ object FakeDataSource { "publishDate": "2021-06-29T23:00:00.000Z", "type": "Podcast 🎙", "topics": [ - "9", - "2" + "11", + "4" ], "authors": [ - 59 + "54" ] }, { @@ -2442,7 +2459,7 @@ object FakeDataSource { "publishDate": "2021-06-29T23:00:00.000Z", "type": "Jetpack release 🚀", "topics": [ - "7" + "9" ], "authors": [] }, @@ -2456,11 +2473,11 @@ object FakeDataSource { "publishDate": "2021-06-27T23:00:00.000Z", "type": "Article 📚", "topics": [ - "7", - "10" + "9", + "12" ], "authors": [ - 60 + "55" ] }, { @@ -2473,10 +2490,10 @@ object FakeDataSource { "publishDate": "2021-06-14T23:00:00.000Z", "type": "Article 📚", "topics": [ - "1" + "3" ], "authors": [ - 26 + "25" ] }, { @@ -2489,11 +2506,11 @@ object FakeDataSource { "publishDate": "2021-06-13T23:00:00.000Z", "type": "Article 📚", "topics": [ - "6", - "1" + "8", + "3" ], "authors": [ - 61 + "56" ] }, { @@ -2506,10 +2523,10 @@ object FakeDataSource { "publishDate": "2021-06-13T23:00:00.000Z", "type": "Podcast 🎙", "topics": [ - "9" + "11" ], "authors": [ - 62 + "57" ] }, { @@ -2522,10 +2539,10 @@ object FakeDataSource { "publishDate": "2021-06-09T23:00:00.000Z", "type": "Article 📚", "topics": [ - "14" + "16" ], "authors": [ - 40 + "23" ] }, { @@ -2538,10 +2555,10 @@ object FakeDataSource { "publishDate": "2021-06-08T23:00:00.000Z", "type": "Article 📚", "topics": [ - "13" + "15" ], "authors": [ - 14 + "14" ] }, { @@ -2554,10 +2571,10 @@ object FakeDataSource { "publishDate": "2021-06-08T23:00:00.000Z", "type": "Video 📺", "topics": [ - "13" + "15" ], "authors": [ - 38 + "31" ] }, { @@ -2570,10 +2587,10 @@ object FakeDataSource { "publishDate": "2021-06-07T23:00:00.000Z", "type": "Podcast 🎙", "topics": [ - "10" + "12" ], "authors": [ - 33 + "32" ] }, { @@ -2586,10 +2603,10 @@ object FakeDataSource { "publishDate": "2021-06-06T23:00:00.000Z", "type": "Article 📚", "topics": [ - "1" + "3" ], "authors": [ - 63 + "58" ] }, { @@ -2602,10 +2619,10 @@ object FakeDataSource { "publishDate": "2021-06-02T23:00:00.000Z", "type": "Video 📺", "topics": [ - "1" + "3" ], "authors": [ - 64 + "59" ] }, { @@ -2618,10 +2635,10 @@ object FakeDataSource { "publishDate": "2021-06-01T23:00:00.000Z", "type": "Article 📚", "topics": [ - "1" + "3" ], "authors": [ - 26 + "25" ] }, { @@ -2634,10 +2651,10 @@ object FakeDataSource { "publishDate": "2021-06-01T23:00:00.000Z", "type": "Podcast 🎙", "topics": [ - "1" + "3" ], "authors": [ - 38 + "31" ] }, { @@ -2650,11 +2667,11 @@ object FakeDataSource { "publishDate": "2021-05-31T23:00:00.000Z", "type": "Article 📚", "topics": [ - "11", - "18" + "13", + "20" ], "authors": [ - 65 + "60" ] }, { @@ -2667,10 +2684,10 @@ object FakeDataSource { "publishDate": "2021-05-25T23:00:00.000Z", "type": "Article 📚", "topics": [ - "13" + "15" ], "authors": [ - 15 + "15" ] }, { @@ -2683,10 +2700,10 @@ object FakeDataSource { "publishDate": "2021-05-24T23:00:00.000Z", "type": "Article 📚", "topics": [ - "0" + "2" ], "authors": [ - 66 + "61" ] } ] diff --git a/core-network/src/main/java/com/google/samples/apps/nowinandroid/core/network/fake/FakeNiANetwork.kt b/core-network/src/main/java/com/google/samples/apps/nowinandroid/core/network/fake/FakeNiANetwork.kt index 77cd05a16..afabacbeb 100644 --- a/core-network/src/main/java/com/google/samples/apps/nowinandroid/core/network/fake/FakeNiANetwork.kt +++ b/core-network/src/main/java/com/google/samples/apps/nowinandroid/core/network/fake/FakeNiANetwork.kt @@ -36,17 +36,17 @@ class FakeNiANetwork @Inject constructor( @Dispatcher(IO) private val ioDispatcher: CoroutineDispatcher, private val networkJson: Json ) : NiANetwork { - override suspend fun getTopics(ids: List?): List = + override suspend fun getTopics(ids: List?): List = withContext(ioDispatcher) { networkJson.decodeFromString(FakeDataSource.topicsData) } - override suspend fun getNewsResources(ids: List?): List = + override suspend fun getNewsResources(ids: List?): List = withContext(ioDispatcher) { networkJson.decodeFromString(FakeDataSource.data) } - override suspend fun getAuthors(ids: List?): List = + override suspend fun getAuthors(ids: List?): List = withContext(ioDispatcher) { networkJson.decodeFromString(FakeDataSource.authors) } @@ -66,7 +66,7 @@ class FakeNiANetwork @Inject constructor( * [NetworkChangeList.id] */ private fun List.mapToChangeList( - idGetter: (T) -> Int + idGetter: (T) -> String ) = mapIndexed { index, item -> NetworkChangeList( id = idGetter(item), diff --git a/core-network/src/main/java/com/google/samples/apps/nowinandroid/core/network/model/NetworkAuthor.kt b/core-network/src/main/java/com/google/samples/apps/nowinandroid/core/network/model/NetworkAuthor.kt index 2f60f3ac8..d24c177b9 100644 --- a/core-network/src/main/java/com/google/samples/apps/nowinandroid/core/network/model/NetworkAuthor.kt +++ b/core-network/src/main/java/com/google/samples/apps/nowinandroid/core/network/model/NetworkAuthor.kt @@ -24,7 +24,7 @@ import kotlinx.serialization.Serializable */ @Serializable data class NetworkAuthor( - val id: Int, + val id: String, val name: String, val imageUrl: String, val twitter: String, diff --git a/core-network/src/main/java/com/google/samples/apps/nowinandroid/core/network/model/NetworkChangeList.kt b/core-network/src/main/java/com/google/samples/apps/nowinandroid/core/network/model/NetworkChangeList.kt index 9204e4715..814121ca4 100644 --- a/core-network/src/main/java/com/google/samples/apps/nowinandroid/core/network/model/NetworkChangeList.kt +++ b/core-network/src/main/java/com/google/samples/apps/nowinandroid/core/network/model/NetworkChangeList.kt @@ -29,7 +29,7 @@ data class NetworkChangeList( /** * The id of the model that was changed */ - val id: Int, + val id: String, /** * Unique consecutive, monotonically increasing version number in the collection describing * the relative point of change between models in the collection diff --git a/core-network/src/main/java/com/google/samples/apps/nowinandroid/core/network/model/NetworkEpisode.kt b/core-network/src/main/java/com/google/samples/apps/nowinandroid/core/network/model/NetworkEpisode.kt index b1efe2dcc..a2420b7d8 100644 --- a/core-network/src/main/java/com/google/samples/apps/nowinandroid/core/network/model/NetworkEpisode.kt +++ b/core-network/src/main/java/com/google/samples/apps/nowinandroid/core/network/model/NetworkEpisode.kt @@ -26,14 +26,14 @@ import kotlinx.serialization.Serializable */ @Serializable data class NetworkEpisode( - val id: Int, + val id: String, val name: String, @Serializable(InstantSerializer::class) val publishDate: Instant, val alternateVideo: String?, val alternateAudio: String?, - val newsResources: List = listOf(), - val authors: List = listOf(), + val newsResources: List = listOf(), + val authors: List = listOf(), ) /** @@ -41,7 +41,7 @@ data class NetworkEpisode( */ @Serializable data class NetworkEpisodeExpanded( - val id: Int, + val id: String, val name: String, @Serializable(InstantSerializer::class) val publishDate: Instant, diff --git a/core-network/src/main/java/com/google/samples/apps/nowinandroid/core/network/model/NetworkNewsResource.kt b/core-network/src/main/java/com/google/samples/apps/nowinandroid/core/network/model/NetworkNewsResource.kt index 70eabbeff..7a5242e41 100644 --- a/core-network/src/main/java/com/google/samples/apps/nowinandroid/core/network/model/NetworkNewsResource.kt +++ b/core-network/src/main/java/com/google/samples/apps/nowinandroid/core/network/model/NetworkNewsResource.kt @@ -28,8 +28,8 @@ import kotlinx.serialization.Serializable */ @Serializable data class NetworkNewsResource( - val id: Int, - val episodeId: Int, + val id: String, + val episodeId: String, val title: String, val content: String, val url: String, @@ -38,8 +38,8 @@ data class NetworkNewsResource( val publishDate: Instant, @Serializable(NewsResourceTypeSerializer::class) val type: NewsResourceType, - val authors: List = listOf(), - val topics: List = listOf(), + val authors: List = listOf(), + val topics: List = listOf(), ) /** @@ -47,8 +47,8 @@ data class NetworkNewsResource( */ @Serializable data class NetworkNewsResourceExpanded( - val id: Int, - val episodeId: Int, + val id: String, + val episodeId: String, val title: String, val content: String, val url: String, diff --git a/core-network/src/main/java/com/google/samples/apps/nowinandroid/core/network/model/NetworkTopic.kt b/core-network/src/main/java/com/google/samples/apps/nowinandroid/core/network/model/NetworkTopic.kt index 064b49c6a..e1043938f 100644 --- a/core-network/src/main/java/com/google/samples/apps/nowinandroid/core/network/model/NetworkTopic.kt +++ b/core-network/src/main/java/com/google/samples/apps/nowinandroid/core/network/model/NetworkTopic.kt @@ -24,7 +24,7 @@ import kotlinx.serialization.Serializable */ @Serializable data class NetworkTopic( - val id: Int, + val id: String, val name: String = "", val shortDescription: String = "", val longDescription: String = "", diff --git a/core-network/src/main/java/com/google/samples/apps/nowinandroid/core/network/retrofit/RetrofitNiANetwork.kt b/core-network/src/main/java/com/google/samples/apps/nowinandroid/core/network/retrofit/RetrofitNiANetwork.kt index 9b1b97999..1c9381a06 100644 --- a/core-network/src/main/java/com/google/samples/apps/nowinandroid/core/network/retrofit/RetrofitNiANetwork.kt +++ b/core-network/src/main/java/com/google/samples/apps/nowinandroid/core/network/retrofit/RetrofitNiANetwork.kt @@ -39,17 +39,17 @@ import retrofit2.http.Query private interface RetrofitNiANetworkApi { @GET(value = "topics") suspend fun getTopics( - @Query("id") ids: List?, + @Query("id") ids: List?, ): NetworkResponse> @GET(value = "authors") suspend fun getAuthors( - @Query("id") ids: List?, + @Query("id") ids: List?, ): NetworkResponse> @GET(value = "newsresources") suspend fun getNewsResources( - @Query("id") ids: List?, + @Query("id") ids: List?, ): NetworkResponse> @GET(value = "changelists/topics") @@ -102,13 +102,13 @@ class RetrofitNiANetwork @Inject constructor( .build() .create(RetrofitNiANetworkApi::class.java) - override suspend fun getTopics(ids: List?): List = + override suspend fun getTopics(ids: List?): List = networkApi.getTopics(ids = ids).data - override suspend fun getAuthors(ids: List?): List = + override suspend fun getAuthors(ids: List?): List = networkApi.getAuthors(ids = ids).data - override suspend fun getNewsResources(ids: List?): List = + override suspend fun getNewsResources(ids: List?): List = networkApi.getNewsResources(ids = ids).data override suspend fun getTopicChangeList(after: Int?): List = diff --git a/core-testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/repository/TestAuthorsRepository.kt b/core-testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/repository/TestAuthorsRepository.kt index 64dd54a20..787534387 100644 --- a/core-testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/repository/TestAuthorsRepository.kt +++ b/core-testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/repository/TestAuthorsRepository.kt @@ -27,7 +27,7 @@ class TestAuthorsRepository : AuthorsRepository { /** * The backing hot flow for the list of followed author ids for testing. */ - private val _followedAuthorIds: MutableSharedFlow> = + private val _followedAuthorIds: MutableSharedFlow> = MutableSharedFlow(replay = 1, onBufferOverflow = BufferOverflow.DROP_OLDEST) /** @@ -38,13 +38,13 @@ class TestAuthorsRepository : AuthorsRepository { override fun getAuthorsStream(): Flow> = authorsFlow - override fun getFollowedAuthorIdsStream(): Flow> = _followedAuthorIds + override fun getFollowedAuthorIdsStream(): Flow> = _followedAuthorIds - override suspend fun setFollowedAuthorIds(followedAuthorIds: Set) { + override suspend fun setFollowedAuthorIds(followedAuthorIds: Set) { _followedAuthorIds.tryEmit(followedAuthorIds) } - override suspend fun toggleFollowedAuthorId(followedAuthorId: Int, followed: Boolean) { + override suspend fun toggleFollowedAuthorId(followedAuthorId: String, followed: Boolean) { getCurrentFollowedAuthors()?.let { current -> _followedAuthorIds.tryEmit( if (followed) current.plus(followedAuthorId) @@ -65,5 +65,5 @@ class TestAuthorsRepository : AuthorsRepository { /** * A test-only API to allow querying the current followed topics. */ - fun getCurrentFollowedAuthors(): Set? = _followedAuthorIds.replayCache.firstOrNull() + fun getCurrentFollowedAuthors(): Set? = _followedAuthorIds.replayCache.firstOrNull() } diff --git a/core-testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/repository/TestNewsRepository.kt b/core-testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/repository/TestNewsRepository.kt index a7e2e2c8b..4e4da22c6 100644 --- a/core-testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/repository/TestNewsRepository.kt +++ b/core-testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/repository/TestNewsRepository.kt @@ -37,8 +37,8 @@ class TestNewsRepository : NewsRepository { override fun getNewsResourcesStream(): Flow> = newsResourcesFlow override fun getNewsResourcesStream( - filterAuthorIds: Set, - filterTopicIds: Set + filterAuthorIds: Set, + filterTopicIds: Set ): Flow> = getNewsResourcesStream().map { newsResources -> newsResources diff --git a/core-testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/repository/TestTopicsRepository.kt b/core-testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/repository/TestTopicsRepository.kt index 2f3f2a3c7..fb4dbf796 100644 --- a/core-testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/repository/TestTopicsRepository.kt +++ b/core-testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/repository/TestTopicsRepository.kt @@ -28,7 +28,7 @@ class TestTopicsRepository : TopicsRepository { /** * The backing hot flow for the list of followed topic ids for testing. */ - private val _followedTopicIds: MutableSharedFlow> = + private val _followedTopicIds: MutableSharedFlow> = MutableSharedFlow(replay = 1, onBufferOverflow = BufferOverflow.DROP_OLDEST) /** @@ -39,15 +39,15 @@ class TestTopicsRepository : TopicsRepository { override fun getTopicsStream(): Flow> = topicsFlow - override fun getTopic(id: Int): Flow { + override fun getTopic(id: String): Flow { return topicsFlow.map { topics -> topics.find { it.id == id }!! } } - override suspend fun setFollowedTopicIds(followedTopicIds: Set) { + override suspend fun setFollowedTopicIds(followedTopicIds: Set) { _followedTopicIds.tryEmit(followedTopicIds) } - override suspend fun toggleFollowedTopicId(followedTopicId: Int, followed: Boolean) { + override suspend fun toggleFollowedTopicId(followedTopicId: String, followed: Boolean) { getCurrentFollowedTopics()?.let { current -> _followedTopicIds.tryEmit( if (followed) current.plus(followedTopicId) @@ -56,7 +56,7 @@ class TestTopicsRepository : TopicsRepository { } } - override fun getFollowedTopicIdsStream(): Flow> = _followedTopicIds + override fun getFollowedTopicIdsStream(): Flow> = _followedTopicIds /** * A test-only API to allow controlling the list of topics from tests. @@ -68,7 +68,7 @@ class TestTopicsRepository : TopicsRepository { /** * A test-only API to allow querying the current followed topics. */ - fun getCurrentFollowedTopics(): Set? = _followedTopicIds.replayCache.firstOrNull() + fun getCurrentFollowedTopics(): Set? = _followedTopicIds.replayCache.firstOrNull() override suspend fun syncWith(synchronizer: Synchronizer) = true } diff --git a/core-ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt b/core-ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt index 48afd4ea8..a5d5aa8c3 100644 --- a/core-ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt +++ b/core-ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt @@ -300,8 +300,8 @@ fun ExpandedNewsResourcePreview() { } private val newsResource = NewsResource( - id = 1, - episodeId = 1, + id = "1", + episodeId = "1", title = "Title", content = "Content", url = "url", @@ -310,7 +310,7 @@ private val newsResource = NewsResource( type = Article, authors = listOf( Author( - id = 1, + id = "1", name = "Name", imageUrl = "", twitter = "", @@ -319,7 +319,7 @@ private val newsResource = NewsResource( ), topics = listOf( Topic( - id = 1, + id = "1", name = "Name", shortDescription = "Short description", longDescription = "Long description", diff --git a/feature-following/src/androidTest/java/com/google/samples/apps/nowinandroid/following/FollowingScreenTest.kt b/feature-following/src/androidTest/java/com/google/samples/apps/nowinandroid/following/FollowingScreenTest.kt index bffc281b9..e3f20bfb5 100644 --- a/feature-following/src/androidTest/java/com/google/samples/apps/nowinandroid/following/FollowingScreenTest.kt +++ b/feature-following/src/androidTest/java/com/google/samples/apps/nowinandroid/following/FollowingScreenTest.kt @@ -196,7 +196,7 @@ private const val TOPIC_IMAGE_URL = "Image URL" private val testTopics = listOf( FollowableTopic( Topic( - id = 0, + id = "0", name = TOPIC_1_NAME, shortDescription = TOPIC_SHORT_DESC, longDescription = TOPIC_LONG_DESC, @@ -207,7 +207,7 @@ private val testTopics = listOf( ), FollowableTopic( Topic( - id = 1, + id = "1", name = TOPIC_2_NAME, shortDescription = TOPIC_SHORT_DESC, longDescription = TOPIC_LONG_DESC, @@ -218,7 +218,7 @@ private val testTopics = listOf( ), FollowableTopic( Topic( - id = 2, + id = "2", name = TOPIC_3_NAME, shortDescription = TOPIC_SHORT_DESC, longDescription = TOPIC_LONG_DESC, @@ -232,7 +232,7 @@ private val testTopics = listOf( private val testAuthors = listOf( FollowableAuthor( Author( - id = 0, + id = "0", name = "Android Dev", imageUrl = "", twitter = "", @@ -242,7 +242,7 @@ private val testAuthors = listOf( ), FollowableAuthor( Author( - id = 1, + id = "1", name = "Android Dev 2", imageUrl = "", twitter = "", @@ -252,7 +252,7 @@ private val testAuthors = listOf( ), FollowableAuthor( Author( - id = 2, + id = "2", name = "Android Dev 3", imageUrl = "", twitter = "", diff --git a/feature-following/src/main/java/com/google/samples/apps/nowinandroid/feature/following/FollowingScreen.kt b/feature-following/src/main/java/com/google/samples/apps/nowinandroid/feature/following/FollowingScreen.kt index a7df67fb3..54cddb113 100644 --- a/feature-following/src/main/java/com/google/samples/apps/nowinandroid/feature/following/FollowingScreen.kt +++ b/feature-following/src/main/java/com/google/samples/apps/nowinandroid/feature/following/FollowingScreen.kt @@ -39,7 +39,7 @@ import com.google.samples.apps.nowinandroid.core.ui.component.NiaTopAppBar fun InterestsRoute( modifier: Modifier = Modifier, navigateToAuthor: () -> Unit, - navigateToTopic: (Int) -> Unit, + navigateToTopic: (String) -> Unit, viewModel: FollowingViewModel = hiltViewModel() ) { val uiState by viewModel.uiState.collectAsState() @@ -61,10 +61,10 @@ fun InterestsRoute( fun FollowingScreen( uiState: FollowingUiState, tabState: FollowingTabState, - followAuthor: (Int, Boolean) -> Unit, - followTopic: (Int, Boolean) -> Unit, + followAuthor: (String, Boolean) -> Unit, + followTopic: (String, Boolean) -> Unit, navigateToAuthor: () -> Unit, - navigateToTopic: (Int) -> Unit, + navigateToTopic: (String) -> Unit, switchTab: (Int) -> Unit, modifier: Modifier = Modifier, ) { @@ -104,10 +104,10 @@ private fun FollowingContent( tabState: FollowingTabState, switchTab: (Int) -> Unit, uiState: FollowingUiState.Interests, - navigateToTopic: (Int) -> Unit, - followTopic: (Int, Boolean) -> Unit, + navigateToTopic: (String) -> Unit, + followTopic: (String, Boolean) -> Unit, navigateToAuthor: () -> Unit, - followAuthor: (Int, Boolean) -> Unit, + followAuthor: (String, Boolean) -> Unit, modifier: Modifier = Modifier ) { Column(modifier) { diff --git a/feature-following/src/main/java/com/google/samples/apps/nowinandroid/feature/following/FollowingViewModel.kt b/feature-following/src/main/java/com/google/samples/apps/nowinandroid/feature/following/FollowingViewModel.kt index cb64d5985..5568c0504 100644 --- a/feature-following/src/main/java/com/google/samples/apps/nowinandroid/feature/following/FollowingViewModel.kt +++ b/feature-following/src/main/java/com/google/samples/apps/nowinandroid/feature/following/FollowingViewModel.kt @@ -79,13 +79,13 @@ class FollowingViewModel @Inject constructor( initialValue = FollowingUiState.Loading ) - fun followTopic(followedTopicId: Int, followed: Boolean) { + fun followTopic(followedTopicId: String, followed: Boolean) { viewModelScope.launch { topicsRepository.toggleFollowedTopicId(followedTopicId, followed) } } - fun followAuthor(followedAuthorId: Int, followed: Boolean) { + fun followAuthor(followedAuthorId: String, followed: Boolean) { viewModelScope.launch { authorsRepository.toggleFollowedAuthorId(followedAuthorId, followed) } diff --git a/feature-following/src/main/java/com/google/samples/apps/nowinandroid/feature/following/TabContent.kt b/feature-following/src/main/java/com/google/samples/apps/nowinandroid/feature/following/TabContent.kt index a0853e80c..5bf0c5103 100644 --- a/feature-following/src/main/java/com/google/samples/apps/nowinandroid/feature/following/TabContent.kt +++ b/feature-following/src/main/java/com/google/samples/apps/nowinandroid/feature/following/TabContent.kt @@ -29,8 +29,8 @@ import com.google.samples.apps.nowinandroid.core.model.data.FollowableTopic @Composable fun TopicsTabContent( topics: List, - onTopicClick: (Int) -> Unit, - onFollowButtonClick: (Int, Boolean) -> Unit, + onTopicClick: (String) -> Unit, + onFollowButtonClick: (String, Boolean) -> Unit, modifier: Modifier = Modifier ) { LazyColumn( @@ -55,7 +55,7 @@ fun TopicsTabContent( fun AuthorsTabContent( authors: List, onAuthorClick: () -> Unit, - onFollowButtonClick: (Int, Boolean) -> Unit, + onFollowButtonClick: (String, Boolean) -> Unit, modifier: Modifier = Modifier ) { LazyColumn( diff --git a/feature-following/src/test/java/com/google/samples/apps/nowinandroid/following/FollowingViewModelTest.kt b/feature-following/src/test/java/com/google/samples/apps/nowinandroid/following/FollowingViewModelTest.kt index 6a039d99f..72f221715 100644 --- a/feature-following/src/test/java/com/google/samples/apps/nowinandroid/following/FollowingViewModelTest.kt +++ b/feature-following/src/test/java/com/google/samples/apps/nowinandroid/following/FollowingViewModelTest.kt @@ -58,7 +58,7 @@ class FollowingViewModelTest { fun uiState_whenFollowedTopicsAreLoading_thenShowLoading() = runTest { viewModel.uiState.test { assertEquals(FollowingUiState.Loading, awaitItem()) - authorsRepository.setFollowedAuthorIds(setOf(1)) + authorsRepository.setFollowedAuthorIds(setOf("1")) topicsRepository.setFollowedTopicIds(emptySet()) cancel() } @@ -69,7 +69,7 @@ class FollowingViewModelTest { viewModel.uiState.test { assertEquals(FollowingUiState.Loading, awaitItem()) authorsRepository.setFollowedAuthorIds(emptySet()) - topicsRepository.setFollowedTopicIds(setOf(1)) + topicsRepository.setFollowedTopicIds(setOf("1")) cancel() } } @@ -198,7 +198,7 @@ private const val TOPIC_IMAGE_URL = "Image URL" private val testInputAuthors = listOf( FollowableAuthor( Author( - id = 0, + id = "0", name = "Android Dev", imageUrl = "", twitter = "", @@ -208,7 +208,7 @@ private val testInputAuthors = listOf( ), FollowableAuthor( Author( - id = 1, + id = "1", name = "Android Dev 2", imageUrl = "", twitter = "", @@ -218,7 +218,7 @@ private val testInputAuthors = listOf( ), FollowableAuthor( Author( - id = 2, + id = "2", name = "Android Dev 3", imageUrl = "", twitter = "", @@ -231,7 +231,7 @@ private val testInputAuthors = listOf( private val testOutputAuthors = listOf( FollowableAuthor( Author( - id = 0, + id = "0", name = "Android Dev", imageUrl = "", twitter = "", @@ -241,7 +241,7 @@ private val testOutputAuthors = listOf( ), FollowableAuthor( Author( - id = 1, + id = "1", name = "Android Dev 2", imageUrl = "", twitter = "", @@ -251,7 +251,7 @@ private val testOutputAuthors = listOf( ), FollowableAuthor( Author( - id = 2, + id = "2", name = "Android Dev 3", imageUrl = "", twitter = "", @@ -264,7 +264,7 @@ private val testOutputAuthors = listOf( private val testInputTopics = listOf( FollowableTopic( Topic( - id = 0, + id = "0", name = TOPIC_1_NAME, shortDescription = TOPIC_SHORT_DESC, longDescription = TOPIC_LONG_DESC, @@ -275,7 +275,7 @@ private val testInputTopics = listOf( ), FollowableTopic( Topic( - id = 1, + id = "1", name = TOPIC_2_NAME, shortDescription = TOPIC_SHORT_DESC, longDescription = TOPIC_LONG_DESC, @@ -286,7 +286,7 @@ private val testInputTopics = listOf( ), FollowableTopic( Topic( - id = 2, + id = "2", name = TOPIC_3_NAME, shortDescription = TOPIC_SHORT_DESC, longDescription = TOPIC_LONG_DESC, @@ -300,7 +300,7 @@ private val testInputTopics = listOf( private val testOutputTopics = listOf( FollowableTopic( Topic( - id = 0, + id = "0", name = TOPIC_1_NAME, shortDescription = TOPIC_SHORT_DESC, longDescription = TOPIC_LONG_DESC, @@ -311,7 +311,7 @@ private val testOutputTopics = listOf( ), FollowableTopic( Topic( - id = 1, + id = "1", name = TOPIC_2_NAME, shortDescription = TOPIC_SHORT_DESC, longDescription = TOPIC_LONG_DESC, @@ -322,7 +322,7 @@ private val testOutputTopics = listOf( ), FollowableTopic( Topic( - id = 2, + id = "2", name = TOPIC_3_NAME, shortDescription = TOPIC_SHORT_DESC, longDescription = TOPIC_LONG_DESC, diff --git a/feature-foryou/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreenTest.kt b/feature-foryou/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreenTest.kt index a9db3ab1f..d7c730e2a 100644 --- a/feature-foryou/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreenTest.kt +++ b/feature-foryou/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreenTest.kt @@ -74,7 +74,7 @@ class ForYouScreenTest { topics = listOf( FollowableTopic( topic = Topic( - id = 0, + id = "0", name = "Headlines", shortDescription = "", longDescription = "", @@ -85,7 +85,7 @@ class ForYouScreenTest { ), FollowableTopic( topic = Topic( - id = 1, + id = "1", name = "UI", shortDescription = "", longDescription = "", @@ -96,7 +96,7 @@ class ForYouScreenTest { ), FollowableTopic( topic = Topic( - id = 2, + id = "2", name = "Tools", shortDescription = "", longDescription = "", @@ -109,7 +109,7 @@ class ForYouScreenTest { authors = listOf( FollowableAuthor( author = Author( - id = 0, + id = "0", name = "Android Dev", imageUrl = "", twitter = "", @@ -119,7 +119,7 @@ class ForYouScreenTest { ), FollowableAuthor( author = Author( - id = 1, + id = "1", name = "Android Dev 2", imageUrl = "", twitter = "", @@ -173,7 +173,7 @@ class ForYouScreenTest { topics = listOf( FollowableTopic( topic = Topic( - id = 0, + id = "0", name = "Headlines", shortDescription = "", longDescription = "", @@ -184,7 +184,7 @@ class ForYouScreenTest { ), FollowableTopic( topic = Topic( - id = 1, + id = "1", name = "UI", shortDescription = "", longDescription = "", @@ -195,7 +195,7 @@ class ForYouScreenTest { ), FollowableTopic( topic = Topic( - id = 2, + id = "2", name = "Tools", shortDescription = "", longDescription = "", @@ -208,7 +208,7 @@ class ForYouScreenTest { authors = listOf( FollowableAuthor( author = Author( - id = 0, + id = "0", name = "Android Dev", imageUrl = "", twitter = "", @@ -218,7 +218,7 @@ class ForYouScreenTest { ), FollowableAuthor( author = Author( - id = 1, + id = "1", name = "Android Dev 2", imageUrl = "", twitter = "", @@ -278,7 +278,7 @@ class ForYouScreenTest { topics = listOf( FollowableTopic( topic = Topic( - id = 0, + id = "0", name = "Headlines", shortDescription = "", longDescription = "", @@ -289,7 +289,7 @@ class ForYouScreenTest { ), FollowableTopic( topic = Topic( - id = 1, + id = "1", name = "UI", shortDescription = "", longDescription = "", @@ -300,7 +300,7 @@ class ForYouScreenTest { ), FollowableTopic( topic = Topic( - id = 2, + id = "2", name = "Tools", shortDescription = "", longDescription = "", @@ -313,7 +313,7 @@ class ForYouScreenTest { authors = listOf( FollowableAuthor( author = Author( - id = 0, + id = "0", name = "Android Dev", imageUrl = "", twitter = "", @@ -323,7 +323,7 @@ class ForYouScreenTest { ), FollowableAuthor( author = Author( - id = 1, + id = "1", name = "Android Dev 2", imageUrl = "", twitter = "", diff --git a/feature-foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/AuthorsCarousel.kt b/feature-foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/AuthorsCarousel.kt index c94b25050..89c0793f7 100644 --- a/feature-foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/AuthorsCarousel.kt +++ b/feature-foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/AuthorsCarousel.kt @@ -52,7 +52,7 @@ import com.google.samples.apps.nowinandroid.core.ui.FollowButton @Composable fun AuthorsCarousel( authors: List, - onAuthorClick: (Int, Boolean) -> Unit, + onAuthorClick: (String, Boolean) -> Unit, modifier: Modifier = Modifier ) { LazyRow(modifier) { @@ -132,15 +132,15 @@ fun AuthorCarouselPreview() { AuthorsCarousel( authors = listOf( FollowableAuthor( - Author(1, "Android Dev", "", "", ""), + Author("1", "Android Dev", "", "", ""), false ), FollowableAuthor( - Author(2, "Android Dev2", "", "", ""), + Author("2", "Android Dev2", "", "", ""), true ), FollowableAuthor( - Author(3, "Android Dev3", "", "", ""), + Author("3", "Android Dev3", "", "", ""), false ) ), @@ -156,7 +156,7 @@ fun AuthorItemPreview() { MaterialTheme { Surface { AuthorItem( - author = Author(0, "Android Dev", "", "", ""), + author = Author("0", "Android Dev", "", "", ""), following = true, onAuthorClick = { } ) diff --git a/feature-foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreen.kt b/feature-foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreen.kt index 6a44c2b79..5eb97f677 100644 --- a/feature-foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreen.kt +++ b/feature-foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreen.kt @@ -94,10 +94,10 @@ fun ForYouRoute( @Composable fun ForYouScreen( uiState: ForYouFeedUiState, - onTopicCheckedChanged: (Int, Boolean) -> Unit, - onAuthorCheckedChanged: (Int, Boolean) -> Unit, + onTopicCheckedChanged: (String, Boolean) -> Unit, + onAuthorCheckedChanged: (String, Boolean) -> Unit, saveFollowedTopics: () -> Unit, - onNewsResourcesCheckedChanged: (Int, Boolean) -> Unit, + onNewsResourcesCheckedChanged: (String, Boolean) -> Unit, modifier: Modifier = Modifier, ) { LazyColumn( @@ -206,7 +206,7 @@ fun ForYouScreen( @Composable private fun TopicSelection( uiState: FeedWithInterestsSelection, - onTopicCheckedChanged: (Int, Boolean) -> Unit, + onTopicCheckedChanged: (String, Boolean) -> Unit, modifier: Modifier = Modifier ) { LazyHorizontalGrid( @@ -242,9 +242,9 @@ private fun TopicSelection( @Composable private fun SingleTopicButton( name: String, - topicId: Int, + topicId: String, isSelected: Boolean, - onClick: (Int, Boolean) -> Unit + onClick: (String, Boolean) -> Unit ) { Surface( modifier = Modifier @@ -306,7 +306,7 @@ fun ForYouScreenTopicSelection() { topics = listOf( FollowableTopic( topic = Topic( - id = 0, + id = "0", name = "Headlines", shortDescription = "", longDescription = "", @@ -317,7 +317,7 @@ fun ForYouScreenTopicSelection() { ), FollowableTopic( topic = Topic( - id = 1, + id = "1", name = "UI", shortDescription = "", longDescription = "", @@ -328,7 +328,7 @@ fun ForYouScreenTopicSelection() { ), FollowableTopic( topic = Topic( - id = 2, + id = "2", name = "Tools", shortDescription = "", longDescription = "", @@ -341,8 +341,8 @@ fun ForYouScreenTopicSelection() { feed = listOf( SaveableNewsResource( newsResource = NewsResource( - id = 1, - episodeId = 52, + id = "1", + episodeId = "52", title = "Thanks for helping us reach 1M YouTube Subscribers", content = "Thank you everyone for following the Now in Android series " + "and everything the Android Developers YouTube channel has to offer. " + @@ -354,7 +354,7 @@ fun ForYouScreenTopicSelection() { type = Video, topics = listOf( Topic( - id = 0, + id = "0", name = "Headlines", shortDescription = "", longDescription = "", @@ -368,8 +368,8 @@ fun ForYouScreenTopicSelection() { ), SaveableNewsResource( newsResource = NewsResource( - id = 2, - episodeId = 52, + id = "2", + episodeId = "52", title = "Transformations and customisations in the Paging Library", content = "A demonstration of different operations that can be performed " + "with Paging. Transformations like inserting separators, when to " + @@ -381,7 +381,7 @@ fun ForYouScreenTopicSelection() { type = Video, topics = listOf( Topic( - id = 1, + id = "1", name = "UI", shortDescription = "", longDescription = "", @@ -395,8 +395,8 @@ fun ForYouScreenTopicSelection() { ), SaveableNewsResource( newsResource = NewsResource( - id = 3, - episodeId = 52, + id = "3", + episodeId = "52", title = "Community tip on Paging", content = "Tips for using the Paging library from the developer community", url = "https://youtu.be/r5JgIyS3t3s", @@ -405,7 +405,7 @@ fun ForYouScreenTopicSelection() { type = Video, topics = listOf( Topic( - id = 1, + id = "1", name = "UI", shortDescription = "", longDescription = "", @@ -421,7 +421,7 @@ fun ForYouScreenTopicSelection() { authors = listOf( FollowableAuthor( author = Author( - id = 0, + id = "0", name = "Android Dev", imageUrl = "", twitter = "", @@ -431,7 +431,7 @@ fun ForYouScreenTopicSelection() { ), FollowableAuthor( author = Author( - id = 1, + id = "1", name = "Android Dev 2", imageUrl = "", twitter = "", @@ -441,7 +441,7 @@ fun ForYouScreenTopicSelection() { ), FollowableAuthor( author = Author( - id = 2, + id = "2", name = "Android Dev 3", imageUrl = "", twitter = "", diff --git a/feature-foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModel.kt b/feature-foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModel.kt index f40fc31da..f082a8cc8 100644 --- a/feature-foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModel.kt +++ b/feature-foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModel.kt @@ -79,7 +79,7 @@ class ForYouViewModel @Inject constructor( * This should be persisted to disk instead. */ private var savedNewsResources by savedStateHandle.saveable { - mutableStateOf>(emptySet()) + mutableStateOf>(emptySet()) } /** @@ -87,7 +87,7 @@ class ForYouViewModel @Inject constructor( * [SavedStateHandle]. */ private var inProgressTopicSelection by savedStateHandle.saveable { - mutableStateOf>(emptySet()) + mutableStateOf>(emptySet()) } /** @@ -95,7 +95,7 @@ class ForYouViewModel @Inject constructor( * [SavedStateHandle]. */ private var inProgressAuthorSelection by savedStateHandle.saveable { - mutableStateOf>(emptySet()) + mutableStateOf>(emptySet()) } val uiState: StateFlow = combine( @@ -170,7 +170,7 @@ class ForYouViewModel @Inject constructor( initialValue = ForYouFeedUiState.Loading ) - fun updateTopicSelection(topicId: Int, isChecked: Boolean) { + fun updateTopicSelection(topicId: String, isChecked: Boolean) { withMutableSnapshot { inProgressTopicSelection = // Update the in-progress selection based on whether the topic id was checked @@ -182,7 +182,7 @@ class ForYouViewModel @Inject constructor( } } - fun updateAuthorSelection(authorId: Int, isChecked: Boolean) { + fun updateAuthorSelection(authorId: String, isChecked: Boolean) { withMutableSnapshot { inProgressAuthorSelection = // Update the in-progress selection based on whether the author id was checked @@ -194,7 +194,7 @@ class ForYouViewModel @Inject constructor( } } - fun updateNewsResourceSaved(newsResourceId: Int, isChecked: Boolean) { + fun updateNewsResourceSaved(newsResourceId: String, isChecked: Boolean) { withMutableSnapshot { savedNewsResources = if (isChecked) { @@ -242,8 +242,8 @@ private sealed interface FollowedInterestsState { * The user has followed the given (non-empty) set of [topicIds] or [authorIds]. */ data class FollowedInterests( - val topicIds: Set, - val authorIds: Set + val topicIds: Set, + val authorIds: Set ) : FollowedInterestsState } diff --git a/feature-foryou/src/test/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModelTest.kt b/feature-foryou/src/test/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModelTest.kt index b7b18a089..97b1f8e8f 100644 --- a/feature-foryou/src/test/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModelTest.kt +++ b/feature-foryou/src/test/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModelTest.kt @@ -132,7 +132,7 @@ class ForYouViewModelTest { topics = listOf( FollowableTopic( topic = Topic( - id = 0, + id = "0", name = "Headlines", shortDescription = "", longDescription = "long description", @@ -143,7 +143,7 @@ class ForYouViewModelTest { ), FollowableTopic( topic = Topic( - id = 1, + id = "1", name = "UI", shortDescription = "", longDescription = "long description", @@ -154,7 +154,7 @@ class ForYouViewModelTest { ), FollowableTopic( topic = Topic( - id = 2, + id = "2", name = "Tools", shortDescription = "", longDescription = "long description", @@ -167,7 +167,7 @@ class ForYouViewModelTest { authors = listOf( FollowableAuthor( author = Author( - id = 0, + id = "0", name = "Android Dev", imageUrl = "", twitter = "", @@ -177,7 +177,7 @@ class ForYouViewModelTest { ), FollowableAuthor( author = Author( - id = 1, + id = "1", name = "Android Dev 2", imageUrl = "", twitter = "", @@ -187,7 +187,7 @@ class ForYouViewModelTest { ), FollowableAuthor( author = Author( - id = 2, + id = "2", name = "Android Dev 3", imageUrl = "", twitter = "", @@ -210,9 +210,9 @@ class ForYouViewModelTest { .test { awaitItem() authorsRepository.sendAuthors(sampleAuthors) - authorsRepository.setFollowedAuthorIds(setOf(0, 1)) + authorsRepository.setFollowedAuthorIds(setOf("0", "1")) topicsRepository.sendTopics(sampleTopics) - topicsRepository.setFollowedTopicIds(setOf(0, 1)) + topicsRepository.setFollowedTopicIds(setOf("0", "1")) newsRepository.sendNewsResources(sampleNewsResources) assertEquals( @@ -236,9 +236,9 @@ class ForYouViewModelTest { .test { awaitItem() authorsRepository.sendAuthors(sampleAuthors) - authorsRepository.setFollowedAuthorIds(setOf(0, 1)) + authorsRepository.setFollowedAuthorIds(setOf("0", "1")) topicsRepository.sendTopics(sampleTopics) - topicsRepository.setFollowedTopicIds(setOf(0, 1)) + topicsRepository.setFollowedTopicIds(setOf("0", "1")) newsRepository.sendNewsResources(sampleNewsResources) assertEquals( @@ -268,14 +268,14 @@ class ForYouViewModelTest { newsRepository.sendNewsResources(sampleNewsResources) awaitItem() - viewModel.updateTopicSelection(1, isChecked = true) + viewModel.updateTopicSelection("1", isChecked = true) assertEquals( ForYouFeedUiState.PopulatedFeed.FeedWithInterestsSelection( topics = listOf( FollowableTopic( topic = Topic( - id = 0, + id = "0", name = "Headlines", shortDescription = "", longDescription = "long description", @@ -286,7 +286,7 @@ class ForYouViewModelTest { ), FollowableTopic( topic = Topic( - id = 1, + id = "1", name = "UI", shortDescription = "", longDescription = "long description", @@ -297,7 +297,7 @@ class ForYouViewModelTest { ), FollowableTopic( topic = Topic( - id = 2, + id = "2", name = "Tools", shortDescription = "", longDescription = "long description", @@ -310,7 +310,7 @@ class ForYouViewModelTest { authors = listOf( FollowableAuthor( author = Author( - id = 0, + id = "0", name = "Android Dev", imageUrl = "", twitter = "", @@ -320,7 +320,7 @@ class ForYouViewModelTest { ), FollowableAuthor( author = Author( - id = 1, + id = "1", name = "Android Dev 2", imageUrl = "", twitter = "", @@ -330,7 +330,7 @@ class ForYouViewModelTest { ), FollowableAuthor( author = Author( - id = 2, + id = "2", name = "Android Dev 3", imageUrl = "", twitter = "", @@ -368,14 +368,14 @@ class ForYouViewModelTest { newsRepository.sendNewsResources(sampleNewsResources) awaitItem() - viewModel.updateAuthorSelection(1, isChecked = true) + viewModel.updateAuthorSelection("1", isChecked = true) assertEquals( ForYouFeedUiState.PopulatedFeed.FeedWithInterestsSelection( topics = listOf( FollowableTopic( topic = Topic( - id = 0, + id = "0", name = "Headlines", shortDescription = "", longDescription = "long description", @@ -386,7 +386,7 @@ class ForYouViewModelTest { ), FollowableTopic( topic = Topic( - id = 1, + id = "1", name = "UI", shortDescription = "", longDescription = "long description", @@ -397,7 +397,7 @@ class ForYouViewModelTest { ), FollowableTopic( topic = Topic( - id = 2, + id = "2", name = "Tools", shortDescription = "", longDescription = "long description", @@ -410,7 +410,7 @@ class ForYouViewModelTest { authors = listOf( FollowableAuthor( author = Author( - id = 0, + id = "0", name = "Android Dev", imageUrl = "", twitter = "", @@ -420,7 +420,7 @@ class ForYouViewModelTest { ), FollowableAuthor( author = Author( - id = 1, + id = "1", name = "Android Dev 2", imageUrl = "", twitter = "", @@ -430,7 +430,7 @@ class ForYouViewModelTest { ), FollowableAuthor( author = Author( - id = 2, + id = "2", name = "Android Dev 3", imageUrl = "", twitter = "", @@ -468,17 +468,17 @@ class ForYouViewModelTest { newsRepository.sendNewsResources(sampleNewsResources) awaitItem() - viewModel.updateTopicSelection(1, isChecked = true) + viewModel.updateTopicSelection("1", isChecked = true) awaitItem() - viewModel.updateTopicSelection(1, isChecked = false) + viewModel.updateTopicSelection("1", isChecked = false) assertEquals( ForYouFeedUiState.PopulatedFeed.FeedWithInterestsSelection( topics = listOf( FollowableTopic( topic = Topic( - id = 0, + id = "0", name = "Headlines", shortDescription = "", longDescription = "long description", @@ -489,7 +489,7 @@ class ForYouViewModelTest { ), FollowableTopic( topic = Topic( - id = 1, + id = "1", name = "UI", shortDescription = "", longDescription = "long description", @@ -500,7 +500,7 @@ class ForYouViewModelTest { ), FollowableTopic( topic = Topic( - id = 2, + id = "2", name = "Tools", shortDescription = "", longDescription = "long description", @@ -513,7 +513,7 @@ class ForYouViewModelTest { authors = listOf( FollowableAuthor( author = Author( - id = 0, + id = "0", name = "Android Dev", imageUrl = "", twitter = "", @@ -523,7 +523,7 @@ class ForYouViewModelTest { ), FollowableAuthor( author = Author( - id = 1, + id = "1", name = "Android Dev 2", imageUrl = "", twitter = "", @@ -533,7 +533,7 @@ class ForYouViewModelTest { ), FollowableAuthor( author = Author( - id = 2, + id = "2", name = "Android Dev 3", imageUrl = "", twitter = "", @@ -562,17 +562,17 @@ class ForYouViewModelTest { newsRepository.sendNewsResources(sampleNewsResources) awaitItem() - viewModel.updateAuthorSelection(1, isChecked = true) + viewModel.updateAuthorSelection("1", isChecked = true) awaitItem() - viewModel.updateAuthorSelection(1, isChecked = false) + viewModel.updateAuthorSelection("1", isChecked = false) assertEquals( ForYouFeedUiState.PopulatedFeed.FeedWithInterestsSelection( topics = listOf( FollowableTopic( topic = Topic( - id = 0, + id = "0", name = "Headlines", shortDescription = "", longDescription = "long description", @@ -583,7 +583,7 @@ class ForYouViewModelTest { ), FollowableTopic( topic = Topic( - id = 1, + id = "1", name = "UI", shortDescription = "", longDescription = "long description", @@ -594,7 +594,7 @@ class ForYouViewModelTest { ), FollowableTopic( topic = Topic( - id = 2, + id = "2", name = "Tools", shortDescription = "", longDescription = "long description", @@ -607,7 +607,7 @@ class ForYouViewModelTest { authors = listOf( FollowableAuthor( author = Author( - id = 0, + id = "0", name = "Android Dev", imageUrl = "", twitter = "", @@ -617,7 +617,7 @@ class ForYouViewModelTest { ), FollowableAuthor( author = Author( - id = 1, + id = "1", name = "Android Dev 2", imageUrl = "", twitter = "", @@ -627,7 +627,7 @@ class ForYouViewModelTest { ), FollowableAuthor( author = Author( - id = 2, + id = "2", name = "Android Dev 3", imageUrl = "", twitter = "", @@ -657,7 +657,7 @@ class ForYouViewModelTest { newsRepository.sendNewsResources(sampleNewsResources) awaitItem() - viewModel.updateTopicSelection(1, isChecked = true) + viewModel.updateTopicSelection("1", isChecked = true) awaitItem() viewModel.saveFollowedInterests() @@ -678,7 +678,7 @@ class ForYouViewModelTest { ), awaitItem() ) - assertEquals(setOf(1), topicsRepository.getCurrentFollowedTopics()) + assertEquals(setOf("1"), topicsRepository.getCurrentFollowedTopics()) assertEquals(emptySet(), authorsRepository.getCurrentFollowedAuthors()) cancel() } @@ -697,7 +697,7 @@ class ForYouViewModelTest { newsRepository.sendNewsResources(sampleNewsResources) awaitItem() - viewModel.updateAuthorSelection(0, isChecked = true) + viewModel.updateAuthorSelection("0", isChecked = true) awaitItem() viewModel.saveFollowedInterests() @@ -715,7 +715,7 @@ class ForYouViewModelTest { awaitItem() ) assertEquals(emptySet(), topicsRepository.getCurrentFollowedTopics()) - assertEquals(setOf(0), authorsRepository.getCurrentFollowedAuthors()) + assertEquals(setOf("0"), authorsRepository.getCurrentFollowedAuthors()) cancel() } } @@ -733,8 +733,8 @@ class ForYouViewModelTest { newsRepository.sendNewsResources(sampleNewsResources) awaitItem() - viewModel.updateAuthorSelection(1, isChecked = true) - viewModel.updateTopicSelection(1, isChecked = true) + viewModel.updateAuthorSelection("1", isChecked = true) + viewModel.updateTopicSelection("1", isChecked = true) awaitItem() viewModel.saveFollowedInterests() @@ -755,8 +755,8 @@ class ForYouViewModelTest { ), awaitItem() ) - assertEquals(setOf(1), topicsRepository.getCurrentFollowedTopics()) - assertEquals(setOf(1), authorsRepository.getCurrentFollowedAuthors()) + assertEquals(setOf("1"), topicsRepository.getCurrentFollowedTopics()) + assertEquals(setOf("1"), authorsRepository.getCurrentFollowedAuthors()) cancel() } } @@ -773,7 +773,7 @@ class ForYouViewModelTest { newsRepository.sendNewsResources(sampleNewsResources) awaitItem() - viewModel.updateTopicSelection(1, isChecked = true) + viewModel.updateTopicSelection("1", isChecked = true) viewModel.saveFollowedInterests() awaitItem() @@ -783,7 +783,7 @@ class ForYouViewModelTest { topics = listOf( FollowableTopic( topic = Topic( - id = 0, + id = "0", name = "Headlines", shortDescription = "", longDescription = "long description", @@ -794,7 +794,7 @@ class ForYouViewModelTest { ), FollowableTopic( topic = Topic( - id = 1, + id = "1", name = "UI", shortDescription = "", longDescription = "long description", @@ -805,7 +805,7 @@ class ForYouViewModelTest { ), FollowableTopic( topic = Topic( - id = 2, + id = "2", name = "Tools", shortDescription = "", longDescription = "long description", @@ -819,7 +819,7 @@ class ForYouViewModelTest { authors = listOf( FollowableAuthor( author = Author( - id = 0, + id = "0", name = "Android Dev", imageUrl = "", twitter = "", @@ -829,7 +829,7 @@ class ForYouViewModelTest { ), FollowableAuthor( author = Author( - id = 1, + id = "1", name = "Android Dev 2", imageUrl = "", twitter = "", @@ -839,7 +839,7 @@ class ForYouViewModelTest { ), FollowableAuthor( author = Author( - id = 2, + id = "2", name = "Android Dev 3", imageUrl = "", twitter = "", @@ -867,7 +867,7 @@ class ForYouViewModelTest { newsRepository.sendNewsResources(sampleNewsResources) awaitItem() - viewModel.updateAuthorSelection(1, isChecked = true) + viewModel.updateAuthorSelection("1", isChecked = true) viewModel.saveFollowedInterests() awaitItem() @@ -877,7 +877,7 @@ class ForYouViewModelTest { topics = listOf( FollowableTopic( topic = Topic( - id = 0, + id = "0", name = "Headlines", shortDescription = "", longDescription = "long description", @@ -888,7 +888,7 @@ class ForYouViewModelTest { ), FollowableTopic( topic = Topic( - id = 1, + id = "1", name = "UI", shortDescription = "", longDescription = "long description", @@ -899,7 +899,7 @@ class ForYouViewModelTest { ), FollowableTopic( topic = Topic( - id = 2, + id = "2", name = "Tools", shortDescription = "", longDescription = "long description", @@ -913,7 +913,7 @@ class ForYouViewModelTest { authors = listOf( FollowableAuthor( author = Author( - id = 0, + id = "0", name = "Android Dev", imageUrl = "", twitter = "", @@ -923,7 +923,7 @@ class ForYouViewModelTest { ), FollowableAuthor( author = Author( - id = 1, + id = "1", name = "Android Dev 2", imageUrl = "", twitter = "", @@ -933,7 +933,7 @@ class ForYouViewModelTest { ), FollowableAuthor( author = Author( - id = 2, + id = "2", name = "Android Dev 3", imageUrl = "", twitter = "", @@ -955,11 +955,11 @@ class ForYouViewModelTest { .test { awaitItem() topicsRepository.sendTopics(sampleTopics) - topicsRepository.setFollowedTopicIds(setOf(1)) + topicsRepository.setFollowedTopicIds(setOf("1")) authorsRepository.sendAuthors(sampleAuthors) - authorsRepository.setFollowedAuthorIds(setOf(1)) + authorsRepository.setFollowedAuthorIds(setOf("1")) newsRepository.sendNewsResources(sampleNewsResources) - viewModel.updateNewsResourceSaved(2, true) + viewModel.updateNewsResourceSaved("2", true) assertEquals( ForYouFeedUiState.PopulatedFeed.FeedWithoutTopicSelection( @@ -983,21 +983,21 @@ class ForYouViewModelTest { private val sampleAuthors = listOf( Author( - id = 0, + id = "0", name = "Android Dev", imageUrl = "", twitter = "", mediumPage = "" ), Author( - id = 1, + id = "1", name = "Android Dev 2", imageUrl = "", twitter = "", mediumPage = "" ), Author( - id = 2, + id = "2", name = "Android Dev 3", imageUrl = "", twitter = "", @@ -1007,7 +1007,7 @@ private val sampleAuthors = listOf( private val sampleTopics = listOf( Topic( - id = 0, + id = "0", name = "Headlines", shortDescription = "", longDescription = "long description", @@ -1015,7 +1015,7 @@ private val sampleTopics = listOf( imageUrl = "image URL", ), Topic( - id = 1, + id = "1", name = "UI", shortDescription = "", longDescription = "long description", @@ -1023,7 +1023,7 @@ private val sampleTopics = listOf( imageUrl = "image URL", ), Topic( - id = 2, + id = "2", name = "Tools", shortDescription = "", longDescription = "long description", @@ -1034,8 +1034,8 @@ private val sampleTopics = listOf( private val sampleNewsResources = listOf( NewsResource( - id = 1, - episodeId = 52, + id = "1", + episodeId = "52", title = "Thanks for helping us reach 1M YouTube Subscribers", content = "Thank you everyone for following the Now in Android series and everything the " + "Android Developers YouTube channel has to offer. During the Android Developer " + @@ -1047,7 +1047,7 @@ private val sampleNewsResources = listOf( type = Video, topics = listOf( Topic( - id = 0, + id = "0", name = "Headlines", shortDescription = "", longDescription = "long description", @@ -1057,7 +1057,7 @@ private val sampleNewsResources = listOf( ), authors = listOf( Author( - id = 0, + id = "0", name = "Android Dev", imageUrl = "", twitter = "", @@ -1066,8 +1066,8 @@ private val sampleNewsResources = listOf( ) ), NewsResource( - id = 2, - episodeId = 52, + id = "2", + episodeId = "52", title = "Transformations and customisations in the Paging Library", content = "A demonstration of different operations that can be performed with Paging. " + "Transformations like inserting separators, when to create a new pager, and " + @@ -1078,7 +1078,7 @@ private val sampleNewsResources = listOf( type = Video, topics = listOf( Topic( - id = 1, + id = "1", name = "UI", shortDescription = "", longDescription = "long description", @@ -1088,7 +1088,7 @@ private val sampleNewsResources = listOf( ), authors = listOf( Author( - id = 1, + id = "1", name = "Android Dev 2", imageUrl = "", twitter = "", @@ -1097,8 +1097,8 @@ private val sampleNewsResources = listOf( ) ), NewsResource( - id = 3, - episodeId = 52, + id = "3", + episodeId = "52", title = "Community tip on Paging", content = "Tips for using the Paging library from the developer community", url = "https://youtu.be/r5JgIyS3t3s", @@ -1107,7 +1107,7 @@ private val sampleNewsResources = listOf( type = Video, topics = listOf( Topic( - id = 1, + id = "1", name = "UI", shortDescription = "", longDescription = "long description", @@ -1117,7 +1117,7 @@ private val sampleNewsResources = listOf( ), authors = listOf( Author( - id = 1, + id = "1", name = "Android Dev 2", imageUrl = "", twitter = "", diff --git a/feature-topic/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/topic/TopicScreenTest.kt b/feature-topic/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/topic/TopicScreenTest.kt index 5d15903b3..4c12d0096 100644 --- a/feature-topic/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/topic/TopicScreenTest.kt +++ b/feature-topic/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/topic/TopicScreenTest.kt @@ -130,7 +130,7 @@ private const val TOPIC_DESC = "At vero eos et accusamus et iusto odio dignissim private val testTopics = listOf( FollowableTopic( Topic( - id = 0, + id = "0", name = TOPIC_1_NAME, shortDescription = "", longDescription = TOPIC_DESC, @@ -141,7 +141,7 @@ private val testTopics = listOf( ), FollowableTopic( Topic( - id = 1, + id = "1", name = TOPIC_2_NAME, shortDescription = "", longDescription = TOPIC_DESC, @@ -152,7 +152,7 @@ private val testTopics = listOf( ), FollowableTopic( Topic( - id = 2, + id = "2", name = TOPIC_3_NAME, shortDescription = "", longDescription = TOPIC_DESC, @@ -165,8 +165,8 @@ private val testTopics = listOf( private val sampleNewsResources = listOf( NewsResource( - id = 1, - episodeId = 52, + id = "1", + episodeId = "52", title = "Thanks for helping us reach 1M YouTube Subscribers", content = "Thank you everyone for following the Now in Android series and everything the " + "Android Developers YouTube channel has to offer. During the Android Developer " + @@ -178,7 +178,7 @@ private val sampleNewsResources = listOf( type = Video, topics = listOf( Topic( - id = 0, + id = "0", name = "Headlines", shortDescription = "", longDescription = TOPIC_DESC, diff --git a/feature-topic/src/main/java/com/google/samples/apps/nowinandroid/feature/topic/TopicViewModel.kt b/feature-topic/src/main/java/com/google/samples/apps/nowinandroid/feature/topic/TopicViewModel.kt index fef44cf44..e60eda9c1 100644 --- a/feature-topic/src/main/java/com/google/samples/apps/nowinandroid/feature/topic/TopicViewModel.kt +++ b/feature-topic/src/main/java/com/google/samples/apps/nowinandroid/feature/topic/TopicViewModel.kt @@ -42,10 +42,10 @@ class TopicViewModel @Inject constructor( newsRepository: NewsRepository ) : ViewModel() { - private val topicId: Int = checkNotNull(savedStateHandle[TopicDestinationsArgs.TOPIC_ID_ARG]) + private val topicId: String = checkNotNull(savedStateHandle[TopicDestinationsArgs.TOPIC_ID_ARG]) // Observe the followed topics, as they could change over time. - private val followedTopicIdsStream: Flow>> = + private val followedTopicIdsStream: Flow>> = topicsRepository.getFollowedTopicIdsStream().asResult() // Observe topic information diff --git a/feature-topic/src/test/java/com/google/samples/apps/nowinandroid/feature/topic/TopicViewModelTest.kt b/feature-topic/src/test/java/com/google/samples/apps/nowinandroid/feature/topic/TopicViewModelTest.kt index b9fec8ef2..bec7ed35c 100644 --- a/feature-topic/src/test/java/com/google/samples/apps/nowinandroid/feature/topic/TopicViewModelTest.kt +++ b/feature-topic/src/test/java/com/google/samples/apps/nowinandroid/feature/topic/TopicViewModelTest.kt @@ -137,7 +137,7 @@ private const val TOPIC_IMAGE_URL = "Image URL" private val testInputTopics = listOf( FollowableTopic( Topic( - id = 0, + id = "0", name = TOPIC_1_NAME, shortDescription = TOPIC_SHORT_DESC, longDescription = TOPIC_LONG_DESC, @@ -148,7 +148,7 @@ private val testInputTopics = listOf( ), FollowableTopic( Topic( - id = 1, + id = "1", name = TOPIC_2_NAME, shortDescription = TOPIC_SHORT_DESC, longDescription = TOPIC_LONG_DESC, @@ -159,7 +159,7 @@ private val testInputTopics = listOf( ), FollowableTopic( Topic( - id = 2, + id = "2", name = TOPIC_3_NAME, shortDescription = TOPIC_SHORT_DESC, longDescription = TOPIC_LONG_DESC, @@ -173,7 +173,7 @@ private val testInputTopics = listOf( private val testOutputTopics = listOf( FollowableTopic( Topic( - id = 0, + id = "0", name = TOPIC_1_NAME, shortDescription = TOPIC_SHORT_DESC, longDescription = TOPIC_LONG_DESC, @@ -184,7 +184,7 @@ private val testOutputTopics = listOf( ), FollowableTopic( Topic( - id = 1, + id = "1", name = TOPIC_2_NAME, shortDescription = TOPIC_SHORT_DESC, longDescription = TOPIC_LONG_DESC, @@ -195,7 +195,7 @@ private val testOutputTopics = listOf( ), FollowableTopic( Topic( - id = 2, + id = "2", name = TOPIC_3_NAME, shortDescription = TOPIC_SHORT_DESC, longDescription = TOPIC_LONG_DESC, @@ -208,8 +208,8 @@ private val testOutputTopics = listOf( private val sampleNewsResources = listOf( NewsResource( - id = 1, - episodeId = 52, + id = "1", + episodeId = "52", title = "Thanks for helping us reach 1M YouTube Subscribers", content = "Thank you everyone for following the Now in Android series and everything the " + "Android Developers YouTube channel has to offer. During the Android Developer " + @@ -221,7 +221,7 @@ private val sampleNewsResources = listOf( type = Video, topics = listOf( Topic( - id = 0, + id = "0", name = "Headlines", shortDescription = "", longDescription = "long description",