Sort news resources by descending publish date, add NewsResourceDao tests

Change-Id: Ib783ed1f4e0ce83c5add82e561f50f89de4faac9
pull/2/head
Adetunji Dahunsi 3 years ago committed by Don Turner
parent a89b435e37
commit a2aa29ef9d

@ -34,6 +34,8 @@ android {
ksp { ksp {
arg("room.schemaLocation", "$projectDir/schemas") arg("room.schemaLocation", "$projectDir/schemas")
} }
testInstrumentationRunner "com.google.samples.apps.nowinandroid.core.testing.NiaTestRunner"
} }
compileOptions { compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8 sourceCompatibility JavaVersion.VERSION_1_8
@ -56,4 +58,15 @@ dependencies {
implementation libs.hilt.android implementation libs.hilt.android
kapt libs.hilt.compiler kapt libs.hilt.compiler
androidTestImplementation project(':core-testing')
// androidx.test is forcing JUnit, 4.12. This forces it to use 4.13
configurations.configureEach {
resolutionStrategy {
force libs.junit4
// Temporary workaround for https://issuetracker.google.com/174733673
force 'org.objenesis:objenesis:2.6'
}
}
} }

@ -0,0 +1,184 @@
/*
* 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.database.dao
import android.content.Context
import androidx.room.Room
import androidx.test.core.app.ApplicationProvider
import com.google.samples.apps.nowinandroid.core.database.NiADatabase
import com.google.samples.apps.nowinandroid.core.database.model.NewsResourceEntity
import com.google.samples.apps.nowinandroid.core.database.model.NewsResourceTopicCrossRef
import com.google.samples.apps.nowinandroid.core.database.model.TopicEntity
import com.google.samples.apps.nowinandroid.core.database.model.asExternalModel
import com.google.samples.apps.nowinandroid.core.database.model.episodeEntityShell
import com.google.samples.apps.nowinandroid.core.model.data.NewsResourceType
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.test.runTest
import kotlinx.datetime.Instant
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Test
class NewsResourceDaoTest {
private lateinit var newsResourceDao: NewsResourceDao
private lateinit var episodeDao: EpisodeDao
private lateinit var topicDao: TopicDao
private lateinit var db: NiADatabase
@Before
fun createDb() {
val context = ApplicationProvider.getApplicationContext<Context>()
db = Room.inMemoryDatabaseBuilder(
context,
NiADatabase::class.java
).build()
newsResourceDao = db.newsResourceDao()
episodeDao = db.episodeDao()
topicDao = db.topicDao()
}
@Test
fun newsResourceDao_fetches_items_by_descending_publish_date() = runTest {
val newsResourceEntities = listOf(
testNewsResource(
id = 0,
millisSinceEpoch = 0,
),
testNewsResource(
id = 1,
millisSinceEpoch = 3,
),
testNewsResource(
id = 2,
millisSinceEpoch = 1,
),
testNewsResource(
id = 3,
millisSinceEpoch = 2,
),
)
val episodeEntityShells = newsResourceEntities
.map(NewsResourceEntity::episodeEntityShell)
.distinct()
episodeDao.saveEpisodeEntities(
episodeEntityShells
)
newsResourceDao.saveNewsResourceEntities(
newsResourceEntities
)
val savedNewsResourceEntities = newsResourceDao.getNewsResourcesStream()
.first()
assertEquals(
listOf(3L, 2L, 1L, 0L),
savedNewsResourceEntities.map {
it.asExternalModel().publishDate.toEpochMilliseconds()
}
)
}
@Test
fun newsResourceDao_filters_items_by_topic_ids_by_descending_publish_date() = runTest {
val topicEntities = listOf(
testTopicEntity(
id = 1,
name = "1"
),
testTopicEntity(
id = 2,
name = "2"
),
)
val newsResourceEntities = listOf(
testNewsResource(
id = 0,
millisSinceEpoch = 0,
),
testNewsResource(
id = 1,
millisSinceEpoch = 3,
),
testNewsResource(
id = 2,
millisSinceEpoch = 1,
),
testNewsResource(
id = 3,
millisSinceEpoch = 2,
),
)
val episodeEntityShells = newsResourceEntities
.map(NewsResourceEntity::episodeEntityShell)
.distinct()
val newsResourceTopicCrossRefEntities = topicEntities.mapIndexed { index, topicEntity ->
NewsResourceTopicCrossRef(
newsResourceId = index,
topicId = topicEntity.id
)
}
topicDao.saveTopics(
topicEntities
)
episodeDao.saveEpisodeEntities(
episodeEntityShells
)
newsResourceDao.saveNewsResourceEntities(
newsResourceEntities
)
newsResourceDao.saveTopicCrossRefEntities(
newsResourceTopicCrossRefEntities
)
val filteredNewsResources = newsResourceDao.getNewsResourcesStream(
filterTopicIds = topicEntities
.map(TopicEntity::id)
.toSet()
).first()
assertEquals(
listOf(1, 0),
filteredNewsResources.map { it.entity.id }
)
}
}
private fun testTopicEntity(
id: Int = 0,
name: String
) = TopicEntity(
id = id,
name = name,
description = "",
)
private fun testNewsResource(
id: Int = 0,
millisSinceEpoch: Long = 0
) = NewsResourceEntity(
id = id,
episodeId = 0,
title = "",
content = "",
url = "",
headerImageUrl = "",
publishDate = Instant.fromEpochMilliseconds(millisSinceEpoch),
type = NewsResourceType.DAC,
)

@ -33,21 +33,21 @@ import kotlinx.coroutines.flow.Flow
interface NewsResourceDao { interface NewsResourceDao {
@Query( @Query(
value = """ value = """
SELECT * FROM news_resources SELECT * FROM news_resources
ORDER BY publish_date ORDER BY publish_date DESC
""" """
) )
fun getNewsResourcesStream(): Flow<List<PopulatedNewsResource>> fun getNewsResourcesStream(): Flow<List<PopulatedNewsResource>>
@Query( @Query(
value = """ value = """
SELECT * FROM news_resources SELECT * FROM news_resources
WHERE id in WHERE id in
( (
SELECT news_resource_id FROM news_resources_topics SELECT news_resource_id FROM news_resources_topics
WHERE topic_id IN (:filterTopicIds) WHERE topic_id IN (:filterTopicIds)
) )
ORDER BY publish_date ORDER BY publish_date DESC
""" """
) )
fun getNewsResourcesStream(filterTopicIds: Set<Int>): Flow<List<PopulatedNewsResource>> fun getNewsResourcesStream(filterTopicIds: Set<Int>): Flow<List<PopulatedNewsResource>>

Loading…
Cancel
Save