Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge upstream #55

Merged
merged 13 commits into from
Mar 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
Thanks for submitting a pull request. Please include the following information.
_Thanks for submitting a pull request. Please include the following information._

**What I have done and why**
Include a summary of what your pull request contains, and why you have made these changes.

_Include a summary of what your pull request contains, and why you have made these changes._

Fixes #<issue_number_goes_here>

**How I'm testing it**

_Choose at least one:_
- Unit tests
- UI tests
- Screenshot tests
- N/A _(provide justification)_

**Do tests pass?**
- [ ] Run local tests on `DemoDebug` variant: `./gradlew testDemoDebug`
- [ ] Check formatting: `./gradlew --init-script gradle/init.gradle.kts spotlessApply`
Expand Down
2 changes: 1 addition & 1 deletion app-nia-catalog/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ android {
// To publish on the Play store a private signing key is required, but to allow anyone
// who clones the code to sign and run the release variant, use the debug signing key.
// TODO: Abstract the signing configuration to a separate file to avoid hardcoding this.
signingConfig = signingConfigs.getByName("debug")
signingConfig = signingConfigs.named("debug").get()
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ android {
// To publish on the Play store a private signing key is required, but to allow anyone
// who clones the code to sign and run the release variant, use the debug signing key.
// TODO: Abstract the signing configuration to a separate file to avoid hardcoding this.
signingConfig = signingConfigs.getByName("debug")
signingConfig = signingConfigs.named("debug").get()
// Ensure Baseline Profile is fresh for release builds.
baselineProfile.automaticGenerationDuringBuild = true
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/

import androidx.room.gradle.RoomExtension
import com.google.devtools.ksp.gradle.KspExtension
import com.google.samples.apps.nowinandroid.libs
import org.gradle.api.Plugin
import org.gradle.api.Project
Expand All @@ -28,6 +29,10 @@ class AndroidRoomConventionPlugin : Plugin<Project> {
pluginManager.apply("androidx.room")
pluginManager.apply("com.google.devtools.ksp")

extensions.configure<KspExtension> {
arg("room.generateKotlin", "true")
}

extensions.configure<RoomExtension> {
// The schemas directory contains a schema file for each version of the Room database.
// This is required to enable Room auto migrations.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,16 @@
* limitations under the License.
*/

package com.google.samples.apps.nowinandroid.core.database
package com.google.samples.apps.nowinandroid.core.database.di

import android.content.Context
import androidx.sqlite.db.SupportSQLiteDatabase
import app.cash.sqldelight.async.coroutines.synchronous
import app.cash.sqldelight.db.QueryResult
import app.cash.sqldelight.db.QueryResult.AsyncValue
import app.cash.sqldelight.db.SqlDriver
import app.cash.sqldelight.db.SqlSchema
import app.cash.sqldelight.driver.android.AndroidSqliteDriver
import app.cash.sqldelight.driver.android.AndroidSqliteDriver.Callback
import me.tatarka.inject.annotations.Component
import me.tatarka.inject.annotations.Provides

Expand All @@ -31,18 +32,18 @@ internal actual abstract class DriverModule(private val context: Context) {

@Provides
actual suspend fun provideDbDriver(
schema: SqlSchema<QueryResult.AsyncValue<Unit>>,
schema: SqlSchema<AsyncValue<Unit>>,
): SqlDriver {
val synchronousSchema = schema.synchronous()
return AndroidSqliteDriver(
schema = synchronousSchema,
context = context,
name = "nia-database.db",
callback = object : AndroidSqliteDriver.Callback(synchronousSchema) {
callback = object : Callback(synchronousSchema) {
override fun onOpen(db: SupportSQLiteDatabase) {
db.setForeignKeyConstraintsEnabled(true)
}
},
)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2022 The Android Open Source Project
* Copyright 2024 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.
Expand All @@ -14,9 +14,10 @@
* limitations under the License.
*/

package com.google.samples.apps.nowinandroid.core.database
package com.google.samples.apps.nowinandroid.core.database.di

import app.cash.sqldelight.db.SqlDriver
import com.google.samples.apps.nowinandroid.core.database.NiaDatabase
import com.google.samples.apps.nowinandroid.core.database.dao.NewsResourceDao
import com.google.samples.apps.nowinandroid.core.database.dao.NewsResourceFtsDao
import com.google.samples.apps.nowinandroid.core.database.dao.RecentSearchQueryDao
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,16 @@
* limitations under the License.
*/

package com.google.samples.apps.nowinandroid.core.database
package com.google.samples.apps.nowinandroid.core.database.di

import app.cash.sqldelight.db.QueryResult
import app.cash.sqldelight.db.QueryResult.AsyncValue
import app.cash.sqldelight.db.SqlDriver
import app.cash.sqldelight.db.SqlSchema
import me.tatarka.inject.annotations.Provides

internal expect abstract class DriverModule {
@Provides
suspend fun provideDbDriver(
schema: SqlSchema<QueryResult.AsyncValue<Unit>>,
schema: SqlSchema<AsyncValue<Unit>>,
): SqlDriver
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@
* limitations under the License.
*/

package com.google.samples.apps.nowinandroid.core.database
package com.google.samples.apps.nowinandroid.core.database.di

import app.cash.sqldelight.db.QueryResult
import app.cash.sqldelight.db.QueryResult.AsyncValue
import app.cash.sqldelight.db.SqlDriver
import app.cash.sqldelight.db.SqlSchema
import app.cash.sqldelight.driver.jdbc.sqlite.JdbcSqliteDriver
import app.cash.sqldelight.driver.jdbc.sqlite.JdbcSqliteDriver.Companion
import me.tatarka.inject.annotations.Component
import me.tatarka.inject.annotations.Provides
import java.util.Properties
Expand All @@ -28,12 +29,12 @@ import java.util.Properties
internal actual abstract class DriverModule {
@Provides
actual suspend fun provideDbDriver(
schema: SqlSchema<QueryResult.AsyncValue<Unit>>,
schema: SqlSchema<AsyncValue<Unit>>,
): SqlDriver {
return JdbcSqliteDriver(
url = JdbcSqliteDriver.IN_MEMORY,
properties = Properties().apply { put("foreign_keys", "true") },
)
.also { schema.create(it).await() }
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,15 @@
* limitations under the License.
*/

package com.google.samples.apps.nowinandroid.core.database
package com.google.samples.apps.nowinandroid.core.database.di

import app.cash.sqldelight.async.coroutines.synchronous
import app.cash.sqldelight.db.QueryResult
import app.cash.sqldelight.db.QueryResult.AsyncValue
import app.cash.sqldelight.db.SqlDriver
import app.cash.sqldelight.db.SqlSchema
import app.cash.sqldelight.driver.native.NativeSqliteDriver
import co.touchlab.sqliter.DatabaseConfiguration
import co.touchlab.sqliter.DatabaseConfiguration.Extended
import me.tatarka.inject.annotations.Component
import me.tatarka.inject.annotations.Provides

Expand All @@ -30,17 +31,17 @@ internal actual abstract class DriverModule {

@Provides
actual suspend fun provideDbDriver(
schema: SqlSchema<QueryResult.AsyncValue<Unit>>,
schema: SqlSchema<AsyncValue<Unit>>,
): SqlDriver {
val synchronousSchema = schema.synchronous()
return NativeSqliteDriver(
schema = synchronousSchema,
name = "nia-database.db",
onConfiguration = { config: DatabaseConfiguration ->
config.copy(
extendedConfig = DatabaseConfiguration.Extended(foreignKeyConstraints = true),
extendedConfig = Extended(foreignKeyConstraints = true),
)
},
)
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ import com.google.samples.apps.nowinandroid.core.analytics.AnalyticsEvent
import com.google.samples.apps.nowinandroid.core.analytics.AnalyticsEvent.Param
import com.google.samples.apps.nowinandroid.core.analytics.AnalyticsHelper
import com.google.samples.apps.nowinandroid.core.data.repository.RecentSearchRepository
import com.google.samples.apps.nowinandroid.core.data.repository.SearchContentsRepository
import com.google.samples.apps.nowinandroid.core.data.repository.UserDataRepository
import com.google.samples.apps.nowinandroid.core.domain.GetRecentSearchQueriesUseCase
import com.google.samples.apps.nowinandroid.core.domain.GetSearchContentsCountUseCase
import com.google.samples.apps.nowinandroid.core.domain.GetSearchContentsUseCase
import com.google.samples.apps.nowinandroid.core.model.data.UserSearchResult
import dagger.hilt.android.lifecycle.HiltViewModel
Expand All @@ -42,8 +42,8 @@ import javax.inject.Inject
@HiltViewModel
class SearchViewModel @Inject constructor(
getSearchContentsUseCase: GetSearchContentsUseCase,
getSearchContentsCountUseCase: GetSearchContentsCountUseCase,
recentSearchQueriesUseCase: GetRecentSearchQueriesUseCase,
private val searchContentsRepository: SearchContentsRepository,
private val recentSearchRepository: RecentSearchRepository,
private val userDataRepository: UserDataRepository,
private val savedStateHandle: SavedStateHandle,
Expand All @@ -53,7 +53,7 @@ class SearchViewModel @Inject constructor(
val searchQuery = savedStateHandle.getStateFlow(key = SEARCH_QUERY, initialValue = "")

val searchResultUiState: StateFlow<SearchResultUiState> =
getSearchContentsCountUseCase()
searchContentsRepository.getSearchContentsCount()
.flatMapLatest { totalCount ->
if (totalCount < SEARCH_MIN_FTS_ENTITY_COUNT) {
flowOf(SearchResultUiState.SearchNotReady)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ package com.google.samples.apps.nowinandroid.feature.search
import androidx.lifecycle.SavedStateHandle
import com.google.samples.apps.nowinandroid.core.analytics.NoOpAnalyticsHelper
import com.google.samples.apps.nowinandroid.core.domain.GetRecentSearchQueriesUseCase
import com.google.samples.apps.nowinandroid.core.domain.GetSearchContentsCountUseCase
import com.google.samples.apps.nowinandroid.core.domain.GetSearchContentsUseCase
import com.google.samples.apps.nowinandroid.core.testing.data.newsResourcesTestData
import com.google.samples.apps.nowinandroid.core.testing.data.topicsTestData
Expand Down Expand Up @@ -60,16 +59,15 @@ class SearchViewModelTest {
)
private val recentSearchRepository = TestRecentSearchRepository()
private val getRecentQueryUseCase = GetRecentSearchQueriesUseCase(recentSearchRepository)
private val getSearchContentsCountUseCase = GetSearchContentsCountUseCase(searchContentsRepository)

private lateinit var viewModel: SearchViewModel

@Before
fun setup() {
viewModel = SearchViewModel(
getSearchContentsUseCase = getSearchContentsUseCase,
getSearchContentsCountUseCase = getSearchContentsCountUseCase,
recentSearchQueriesUseCase = getRecentQueryUseCase,
searchContentsRepository = searchContentsRepository,
savedStateHandle = SavedStateHandle(),
recentSearchRepository = recentSearchRepository,
userDataRepository = userDataRepository,
Expand All @@ -87,7 +85,8 @@ class SearchViewModelTest {
fun stateIsEmptyQuery_withEmptySearchQuery() = runTest {
searchContentsRepository.addNewsResources(newsResourcesTestData)
searchContentsRepository.addTopics(topicsTestData)
val collectJob = launch(UnconfinedTestDispatcher()) { viewModel.searchResultUiState.collect() }
val collectJob =
launch(UnconfinedTestDispatcher()) { viewModel.searchResultUiState.collect() }

viewModel.onSearchQueryChanged("")

Expand All @@ -98,7 +97,8 @@ class SearchViewModelTest {

@Test
fun emptyResultIsReturned_withNotMatchingQuery() = runTest {
val collectJob = launch(UnconfinedTestDispatcher()) { viewModel.searchResultUiState.collect() }
val collectJob =
launch(UnconfinedTestDispatcher()) { viewModel.searchResultUiState.collect() }

viewModel.onSearchQueryChanged("XXX")
searchContentsRepository.addNewsResources(newsResourcesTestData)
Expand All @@ -112,7 +112,8 @@ class SearchViewModelTest {

@Test
fun recentSearches_verifyUiStateIsSuccess() = runTest {
val collectJob = launch(UnconfinedTestDispatcher()) { viewModel.recentSearchQueriesUiState.collect() }
val collectJob =
launch(UnconfinedTestDispatcher()) { viewModel.recentSearchQueriesUiState.collect() }
viewModel.onSearchTriggered("kotlin")

val result = viewModel.recentSearchQueriesUiState.value
Expand All @@ -123,7 +124,8 @@ class SearchViewModelTest {

@Test
fun searchNotReady_withNoFtsTableEntity() = runTest {
val collectJob = launch(UnconfinedTestDispatcher()) { viewModel.searchResultUiState.collect() }
val collectJob =
launch(UnconfinedTestDispatcher()) { viewModel.searchResultUiState.collect() }

viewModel.onSearchQueryChanged("")

Expand Down
Loading