Skip to content

Commit

Permalink
Merge pull request #481 from nimblehq/release/3.21.0
Browse files Browse the repository at this point in the history
[Release] 3.21.0
  • Loading branch information
ryan-conway authored Jul 3, 2023
2 parents e552114 + 4b47ad3 commit 70d21ad
Show file tree
Hide file tree
Showing 19 changed files with 177 additions and 94 deletions.
2 changes: 1 addition & 1 deletion .cicdtemplate/.github/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ The `.github` contains all the required setup for Github Action to trigger. Simp
Here are the current Secrets we need to add to the Project Settings - Secret:

- `FIREBASE_APP_ID_STAGING` - your application id on Firebase.
- `FIREBASE_TOKEN` - your Firebase access/refresh token. Follow this [Guideline](https://firebase.google.com/docs/cli#cli-ci-systems) to get one for your project.
- `FIREBASE_SERVICE_ACCOUNT_CREDENTIAL_FILE_CONTENT` - your Firebase service account credential file. Follow this [Guideline](https://github.com/wzieba/Firebase-Distribution-Github-Action/wiki/FIREBASE_TOKEN-migration#guide-2---the-same-but-with-screenshots) to get one for your project.
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ jobs:
uses: wzieba/Firebase-Distribution-Github-Action@v1
with:
appId: ${{secrets.FIREBASE_APP_ID_STAGING}}
token: ${{secrets.FIREBASE_TOKEN}}
serviceCredentialsFileContent: ${{ secrets.FIREBASE_SERVICE_ACCOUNT_CREDENTIAL_FILE_CONTENT }}
groups: testers
file: app/build/outputs/apk/staging/debug/app-staging-debug.apk

Expand All @@ -74,6 +74,6 @@ jobs:
uses: wzieba/Firebase-Distribution-Github-Action@v1
with:
appId: ${{secrets.FIREBASE_APP_ID_PRODUCTION}}
token: ${{secrets.FIREBASE_TOKEN}}
serviceCredentialsFileContent: ${{ secrets.FIREBASE_SERVICE_ACCOUNT_CREDENTIAL_FILE_CONTENT }}
groups: testers
file: app/build/outputs/apk/production/debug/app-production-debug.apk
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,14 @@ A collection of our Android templates:
package-name= New package name (i.e., com.example.package)
app-name= New app name (i.e., MyApp, "My App", "my-app")
template= Template (i.e., xml, compose)
force= Force project creation even if the script fails (default: false)
destination= Set the output location where the project should be generated (i.e., /Users/johndoe/documents/projectfolder)
```

Examples:
`kscript new_project.kts package-name=co.myxmlproject.example app-name="My XML Project" template=xml`
`kscript scripts/new_project.kts package-name=co.myxmlproject.example app-name="My XML Project" template=xml`
`kscript new_project.kts package-name=co.myxmlproject.example app-name="My XML Project" template=xml destination=/Users/johndoe/documents/projectfolder`

4. Update `android_version_code` and `android_version_name` in `template/build.gradle`

Expand Down
8 changes: 4 additions & 4 deletions RxJavaTemplate[DEPRECATED]/fastlane/script/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def sanity_check
errors = []
errors << verify_slack_config unless verify_slack_config.nil?
errors << verify_workspace_config unless verify_workspace_config.nil?
errors << verify_firebase_token unless verify_firebase_token.nil?
errors << verify_service_account unless verify_service_account.nil?
throw errors unless errors.empty?
end

Expand All @@ -55,9 +55,9 @@ def verify_workspace_config
'Missing env.WORKSPACE, please set it accordingly and retry'
end

def verify_firebase_token
return unless ENV['FIREBASE_TOKEN'].nil?
def verify_service_account
return unless ENV['FIREBASE_SERVICE_ACCOUNT_CREDENTIAL_FILE_CONTENT'].nil?

'Missing env.FIREBASE_TOKEN for Firebase, please set it accordingly and retry'
'Missing env.FIREBASE_SERVICE_ACCOUNT_CREDENTIAL_FILE_CONTENT for Firebase App Distribution, please set it accordingly and retry'
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,10 @@ class HomeScreenTest {
every { mockIsFirstTimeLaunchPreferencesUseCase() } returns flowOf(false)

viewModel = HomeViewModel(
TestDispatchersProvider,
mockGetModelsUseCase,
mockIsFirstTimeLaunchPreferencesUseCase,
mockUpdateFirstTimeLaunchPreferencesUseCase
mockUpdateFirstTimeLaunchPreferencesUseCase,
TestDispatchersProvider
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,20 @@ import androidx.annotation.StringRes
import androidx.compose.material.Text
import androidx.compose.material.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import co.nimblehq.sample.compose.R
import co.nimblehq.sample.compose.ui.theme.AppTheme.colors
import co.nimblehq.sample.compose.ui.theme.ComposeTheme

@Composable
fun AppBar(@StringRes title: Int) {
fun AppBar(
@StringRes title: Int,
modifier: Modifier = Modifier,
) {
TopAppBar(
modifier = modifier,
title = { Text(text = stringResource(title)) },
backgroundColor = colors.topAppBarBackground
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ fun HomeScreen(

LaunchedEffect(isFirstTimeLaunch) {
if (isFirstTimeLaunch) {
context.showToast("This is the first time launch")
context.showToast(context.getString(R.string.message_first_time_launch))
viewModel.onFirstTimeLaunch()
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ import javax.inject.Inject

@HiltViewModel
class HomeViewModel @Inject constructor(
dispatchersProvider: DispatchersProvider,
getModelsUseCase: GetModelsUseCase,
isFirstTimeLaunchPreferencesUseCase: IsFirstTimeLaunchPreferencesUseCase,
updateFirstTimeLaunchPreferencesUseCase: UpdateFirstTimeLaunchPreferencesUseCase,
private val updateFirstTimeLaunchPreferencesUseCase: UpdateFirstTimeLaunchPreferencesUseCase,
private val dispatchersProvider: DispatchersProvider,
) : BaseViewModel() {

private val _uiModels = MutableStateFlow<List<UiModel>>(emptyList())
Expand All @@ -38,15 +38,19 @@ class HomeViewModel @Inject constructor(
.catch { e -> _error.emit(e) }
.launchIn(viewModelScope)

launch(dispatchersProvider.io) {
val isFirstTimeLaunch = isFirstTimeLaunchPreferencesUseCase()
.catch { e -> _error.emit(e) }
.first()

_isFirstTimeLaunch.emit(isFirstTimeLaunch)
if (isFirstTimeLaunch) {
updateFirstTimeLaunchPreferencesUseCase(false)
isFirstTimeLaunchPreferencesUseCase()
.onEach { isFirstTimeLaunch ->
_isFirstTimeLaunch.emit(isFirstTimeLaunch)
}
.flowOn(dispatchersProvider.io)
.catch { e -> _error.emit(e) }
.launchIn(viewModelScope)
}

fun onFirstTimeLaunch() {
launch(dispatchersProvider.io) {
updateFirstTimeLaunchPreferencesUseCase(false)
_isFirstTimeLaunch.emit(false)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@ import co.nimblehq.sample.compose.ui.theme.AppTheme.dimensions
fun Item(
uiModel: UiModel,
onClick: (UiModel) -> Unit,
onLongClick: (UiModel) -> Unit
onLongClick: (UiModel) -> Unit,
modifier: Modifier = Modifier,
) {
var expanded by remember { mutableStateOf(false) }

Box(
modifier = Modifier
modifier = modifier
.fillMaxWidth()
.combinedClickable(
onClick = { onClick(uiModel) },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material.Divider
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import co.nimblehq.sample.compose.model.UiModel
import co.nimblehq.sample.compose.ui.theme.ComposeTheme
Expand All @@ -12,9 +13,10 @@ import co.nimblehq.sample.compose.ui.theme.ComposeTheme
fun ItemList(
uiModels: List<UiModel>,
onItemClick: (UiModel) -> Unit,
onItemLongClick: (UiModel) -> Unit
onItemLongClick: (UiModel) -> Unit,
modifier: Modifier = Modifier,
) {
LazyColumn {
LazyColumn(modifier) {
items(uiModels) { uiModel ->
Item(
uiModel = uiModel,
Expand Down
2 changes: 2 additions & 0 deletions sample-compose/app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,6 @@
<string name="third_title_bar">Third</string>
<string name="third_data_title">Data: %s</string>
<string name="third_edit_menu_title">Edit</string>

<string name="message_first_time_launch">This is the first time launch</string>
</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ import co.nimblehq.sample.compose.ui.screens.BaseScreenTest
import co.nimblehq.sample.compose.ui.screens.MainActivity
import co.nimblehq.sample.compose.ui.theme.ComposeTheme
import io.kotest.matchers.shouldBe
import io.mockk.every
import io.mockk.mockk
import io.mockk.*
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.test.*
Expand Down Expand Up @@ -54,6 +53,29 @@ class HomeScreenTest : BaseScreenTest() {
listOf(Model(1), Model(2), Model(3))
)
every { mockIsFirstTimeLaunchPreferencesUseCase() } returns flowOf(false)
coEvery { mockUpdateFirstTimeLaunchPreferencesUseCase(any()) } just Runs
}

@Test
fun `When entering the Home screen for the first time, it shows a toast confirming that`() {
every { mockIsFirstTimeLaunchPreferencesUseCase() } returns flowOf(true)

initComposable {
composeRule.waitForIdle()
advanceUntilIdle()

ShadowToast.showedToast(activity.getString(R.string.message_first_time_launch)) shouldBe true
}
}

@Test
fun `When entering the Home screen NOT for the first time, it doesn't show the toast confirming that`() {
initComposable {
composeRule.waitForIdle()
advanceUntilIdle()

ShadowToast.showedToast(activity.getString(R.string.message_first_time_launch)) shouldBe false
}
}

@Test
Expand Down Expand Up @@ -106,10 +128,10 @@ class HomeScreenTest : BaseScreenTest() {

private fun initViewModel() {
viewModel = HomeViewModel(
coroutinesRule.testDispatcherProvider,
mockGetModelsUseCase,
mockIsFirstTimeLaunchPreferencesUseCase,
mockUpdateFirstTimeLaunchPreferencesUseCase
mockUpdateFirstTimeLaunchPreferencesUseCase,
coroutinesRule.testDispatcherProvider
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,9 @@ import co.nimblehq.sample.compose.test.CoroutineTestRule
import co.nimblehq.sample.compose.ui.AppDestination
import co.nimblehq.sample.compose.util.DispatchersProvider
import io.kotest.matchers.shouldBe
import io.mockk.every
import io.mockk.mockk
import io.mockk.*
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.test.*
import org.junit.*

Expand All @@ -29,11 +27,13 @@ class HomeViewModelTest {
private lateinit var viewModel: HomeViewModel

private val models = listOf(Model(1), Model(2), Model(3))
private val isFirstTimeLaunch = false

@Before
fun setUp() {
every { mockGetModelsUseCase() } returns flowOf(models)
every { mockIsFirstTimeLaunchPreferencesUseCase() } returns flowOf(false)
every { mockIsFirstTimeLaunchPreferencesUseCase() } returns flowOf(isFirstTimeLaunch)
coEvery { mockUpdateFirstTimeLaunchPreferencesUseCase(any()) } just Runs

initViewModel()
}
Expand Down Expand Up @@ -78,12 +78,44 @@ class HomeViewModelTest {
}
}

@Test
fun `When initializing the ViewModel, it emits whether the app is launched for the first time accordingly`() =
runTest {
viewModel.isFirstTimeLaunch.first() shouldBe isFirstTimeLaunch
}

@Test
fun `When initializing the ViewModel and isFirstTimeLaunchPreferencesUseCase returns error, it shows the corresponding error`() =
runTest {
val error = Exception()
every { mockIsFirstTimeLaunchPreferencesUseCase() } returns flow { throw error }

initViewModel(dispatchers = CoroutineTestRule(StandardTestDispatcher()).testDispatcherProvider)

viewModel.error.test {
advanceUntilIdle()

expectMostRecentItem() shouldBe error
}
}

@Test
fun `When launching the app for the first time, it executes the use case and emits value accordingly`() =
runTest {
viewModel.onFirstTimeLaunch()

coVerify(exactly = 1) {
mockUpdateFirstTimeLaunchPreferencesUseCase(false)
}
viewModel.isFirstTimeLaunch.first() shouldBe false
}

private fun initViewModel(dispatchers: DispatchersProvider = coroutinesRule.testDispatcherProvider) {
viewModel = HomeViewModel(
dispatchers,
mockGetModelsUseCase,
mockIsFirstTimeLaunchPreferencesUseCase,
mockUpdateFirstTimeLaunchPreferencesUseCase
mockUpdateFirstTimeLaunchPreferencesUseCase,
dispatchers
)
}
}
35 changes: 9 additions & 26 deletions sample-compose/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -67,45 +67,28 @@ detekt {
koverMerged {
enable()

val generatedFiles = setOf(
"*.R.class",
"*.R\$*.class",
"*.*\$ViewBinder*.*",
"*.*\$InjectAdapter*.*",
"*.*Injector*.*",
val excludedFiles = listOf(
"*.BuildConfig.*",
"*.BuildConfig",
"*.Manifest*.*",
"*.*_ViewBinding*.*",
"*.*Adapter*.*",
"*.*Test*.*",
// Enum
"*.*\$Creator*",
// Nav Component
"*.*_Factory*",
"*.*FragmentArgs*",
"*.*FragmentDirections*",
"*.FragmentNavArgsLazy.kt",
"*.*Fragment*navArgs*",
"*.*ModuleDeps*.*",
"*.*NavGraphDirections*",
// DI
"*.di.*",
// Hilt
"*.*_ComponentTreeDeps*",
"*.*_HiltComponents*",
"*.*_HiltModules*",
"*.*_MembersInjector*",
"*.Hilt_*"
)

val excludedPackages = setOf(
"com.bumptech.glide.*",
"*.*_Factory*",
"*.Hilt_*",
"dagger.hilt.internal.*",
"hilt_aggregated_deps.*",
"co.nimblehq.sample.compose.databinding.*",
"co.nimblehq.sample.compose.di.*"
// Jetpack Compose
"*.ComposableSingletons*",
"*.*\$*Preview\$*",
"*.ui.preview.*",
)

val excludedFiles = generatedFiles + excludedPackages
filters {
classes {
excludes += excludedFiles
Expand Down
2 changes: 1 addition & 1 deletion sample-compose/buildSrc/src/main/java/Versions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ object Versions {
const val ANDROID_TARGET_SDK_VERSION = 33

const val ANDROID_VERSION_CODE = 1
const val ANDROID_VERSION_NAME = "3.20.0"
const val ANDROID_VERSION_NAME = "3.21.0"

// Dependencies (Alphabet sorted)
const val ACCOMPANIST_PERMISSIONS_VERSION = "0.30.1"
Expand Down
2 changes: 1 addition & 1 deletion sample-xml/buildSrc/src/main/java/Versions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ object Versions {
const val ANDROID_TARGET_SDK_VERSION = 33

const val ANDROID_VERSION_CODE = 1
const val ANDROID_VERSION_NAME = "3.20.0"
const val ANDROID_VERSION_NAME = "3.21.0"

// Dependencies (Alphabet sorted)
const val ANDROID_COMMON_KTX_VERSION = "0.1.1"
Expand Down
Loading

0 comments on commit 70d21ad

Please sign in to comment.