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

feat: add ktolinter and detekt #37

Merged
merged 1 commit into from
May 18, 2023
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
9 changes: 2 additions & 7 deletions .github/workflows/testandlint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,6 @@ jobs:
java-version: 11
- name: Unit tests
run: bash ./gradlew test --stacktrace
- name: Unit tests results
uses: actions/upload-artifact@v1
with:
name: unit-tests-results
path: app/build/reports/tests/testDebugUnitTest/index.html

lint:
name: Lint Check
Expand All @@ -45,8 +40,8 @@ jobs:
java-version: 11
- name: Make gradlew executable
run: chmod +x ./gradlew
- name: Lint debug flavor
run: ./gradlew lint --stacktrace
- name: Lint Checks
run: ./gradlew detektAll lintKotlin lint
- name: Lint results
uses: yutailang0119/action-android-lint@v2
with:
Expand Down
11 changes: 7 additions & 4 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import com.loodos.buildsrc.getDateTime

// TODO: Remove once https://youtrack.jetbrains.com/issue/KTIJ-19369 is fixed
@Suppress("DSL_SCOPE_VIOLATION")
plugins {
id("com.android.application")
kotlin("android")
id("kotlin-kapt")
id("dagger.hilt.android.plugin")
kotlin("kapt")
alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.android)
alias(libs.plugins.dagger.hilt)
alias(libs.plugins.kotlinter)
}

android {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
package com.loodos.samplecomposeandroid

import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4

import androidx.test.platform.app.InstrumentationRegistry
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith

import org.junit.Assert.*

/**
* Instrumented test, which will execute on an Android device.
*
Expand All @@ -21,4 +19,4 @@ class ExampleInstrumentedTest {
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("com.loodos.samplecomposeandroid", appContext.packageName)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ class MainAppStateTest {
// Subject under test.
private lateinit var state: MainAppState


@Test
fun mainAppState_currentDestination() = runTest {
var currentDestination: String? = null
Expand All @@ -46,7 +45,7 @@ class MainAppStateTest {
MainAppState(
navController = navController,
networkMonitor = networkMonitor,
coroutineScope = backgroundScope
coroutineScope = backgroundScope,
)
}

Expand All @@ -63,15 +62,14 @@ class MainAppStateTest {
assertEquals("b", currentDestination)
}


@Test
fun mainAppState_stateIsOfflineWhenNetworkMonitorIsOffline() =
runTest(UnconfinedTestDispatcher()) {
composeTestRule.setContent {
state = MainAppState(
navController = NavHostController(LocalContext.current),
networkMonitor = networkMonitor,
coroutineScope = backgroundScope
coroutineScope = backgroundScope,
)
}
backgroundScope.launch { state.isOffline.collect() }
Expand All @@ -86,7 +84,7 @@ class MainAppStateTest {
state = MainAppState(
navController = NavHostController(LocalContext.current),
networkMonitor = networkMonitor,
coroutineScope = backgroundScope
coroutineScope = backgroundScope,
)
}
backgroundScope.launch { state.isOffline.collect() }
Expand All @@ -109,4 +107,4 @@ private fun rememberTestNavController(): TestNavHostController {
}
}
return navController
}
}
2 changes: 1 addition & 1 deletion app/src/main/java/com/loodos/MainApplication.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ import dagger.hilt.android.HiltAndroidApp
* Created by mertcantoptas on 07.03.2023
*/
@HiltAndroidApp
class MainApplication :Application() {}
class MainApplication : Application()
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,3 @@ abstract class BaseViewModel<State : IViewState> : ViewModel() {
_uiState.update { currentState.reduce() }
}
}


Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@ import dagger.hilt.components.SingletonComponent
interface DataModule {
@Binds
fun bindsNetworkMonitor(
networkMonitor: ConnectivityManagerNetworkMonitor
networkMonitor: ConnectivityManagerNetworkMonitor,
): NetworkMonitor
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@ interface LoginModule {

@Binds
fun bindAuthRepository(repositoryImpl: AuthenticationRepositoryImpl): AuthenticationRepository
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ import javax.inject.Singleton
@Module
@InstallIn(SingletonComponent::class)
object RemoteDataModule {

private const val CHUCKER_MAX_CONTENT_LENGTH = 250_000L

@Provides
@Singleton
fun provideRetrofit(
Expand Down Expand Up @@ -52,6 +55,7 @@ object RemoteDataModule {
fun provideHttpLoggingInterceptor(): HttpLoggingInterceptor = HttpLoggingInterceptor().apply {
setLevel(HttpLoggingInterceptor.Level.BODY)
}

@Singleton
@Provides
fun provideGsonConverterFactory(): GsonConverterFactory {
Expand All @@ -64,9 +68,8 @@ object RemoteDataModule {
@ApplicationContext context: Context,
chuckerCollector: ChuckerCollector,
): ChuckerInterceptor {

return ChuckerInterceptor.Builder(context).collector(chuckerCollector)
.maxContentLength(250_000L)
.maxContentLength(CHUCKER_MAX_CONTENT_LENGTH)
.redactHeaders("Content-Type", "application/json")
.alwaysReadResponseBody(true).build()
}
Expand All @@ -79,13 +82,12 @@ object RemoteDataModule {
// Toggles visibility of the push notification
showNotification = true,
// Allows to customize the retention period of collected data
retentionPeriod = RetentionManager.Period.ONE_HOUR
retentionPeriod = RetentionManager.Period.ONE_HOUR,
)


@Provides
@Singleton
fun provideLoginService(retrofit: Retrofit): AuthenticationService {
return retrofit.create(AuthenticationService::class.java)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ data class LoginBody(
@SerializedName("username")
val username: String,
@SerializedName("password")
val password: String
)
val password: String,
)
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ package com.loodos.samplecomposeandroid.core.data.model.login
* Created by mertcantoptas on 13.04.2023
*/
data class LoginResponse(
val token: String
val token: String,
)
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package com.loodos.samplecomposeandroid.core.data.remote.api

import com.loodos.samplecomposeandroid.core.data.model.login.LoginBody
import com.loodos.samplecomposeandroid.core.data.model.login.LoginResponse
import retrofit2.Response
import retrofit2.http.Body
import retrofit2.http.POST

Expand All @@ -13,6 +12,6 @@ import retrofit2.http.POST
interface AuthenticationService {
@POST("auth/login")
suspend fun login(
@Body requestBody: LoginBody
@Body requestBody: LoginBody,
): LoginResponse
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
package com.loodos.samplecomposeandroid.core.data.remote.source

import com.loodos.samplecomposeandroid.core.data.model.login.LoginResponse
import kotlinx.coroutines.flow.Flow

/**
* Created by mertcantoptas on 13.04.2023
*/
interface AuthenticationRemoteDataSource {
suspend fun login(username: String, password: String): Result<LoginResponse>
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
package com.loodos.samplecomposeandroid.core.data.repository

import com.loodos.samplecomposeandroid.core.data.model.login.LoginResponse
import kotlinx.coroutines.flow.Flow

/**
* Created by mertcantoptas on 13.04.2023
*/
interface AuthenticationRepository {
suspend fun login(username: String, password: String): Result<LoginResponse>
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,13 @@ package com.loodos.samplecomposeandroid.core.data.repository

import com.loodos.samplecomposeandroid.core.data.model.login.LoginResponse
import com.loodos.samplecomposeandroid.core.data.remote.source.AuthenticationRemoteDataSource
import kotlinx.coroutines.flow.Flow
import javax.inject.Inject

class AuthenticationRepositoryImpl @Inject constructor(
private val authenticationRemoteDataSource: AuthenticationRemoteDataSource
private val authenticationRemoteDataSource: AuthenticationRemoteDataSource,
) : AuthenticationRepository {

override suspend fun login(username: String, password: String): Result<LoginResponse> {
return authenticationRemoteDataSource.login(username, password)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ package com.loodos.samplecomposeandroid.core.domain
class UsernameRequiredException : Exception()
class PasswordRequiredException : Exception()
class UsernameLengthException : Exception()
class PasswordLengthException : Exception()
class PasswordLengthException : Exception()
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ data class LoginResult(
val token: String = "",
)

fun LoginResponse.toModel() : LoginResult {
fun LoginResponse.toModel(): LoginResult {
return LoginResult(this.token)
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ import kotlinx.coroutines.flow.flow
import javax.inject.Inject

class LoginUseCase @Inject constructor(
private val authenticationRepository: AuthenticationRepository
private val authenticationRepository: AuthenticationRepository,
) {
operator fun invoke(username: String, password: String) : Flow<LoginResult> {
operator fun invoke(username: String, password: String): Flow<LoginResult> {
return flow {
val result = authenticationRepository.login(username, password)
(result.getOrNull() ?: throw Exception("error message")).also {
(result.getOrNull() ?: throw IllegalArgumentException("error message")).also {
emit(it.toModel())
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,22 @@ import javax.inject.Inject
* Created by mertcantoptas on 12.05.2023
*/

private const val MinUsernameLength = 6
private const val MinPasswordLength = 6

class ValidateAuthUseCase @Inject constructor() {
operator fun invoke(username: String, password: String): Flow<Resource<Unit>> {
return flow {
if (username.isEmpty()) {
throw UsernameRequiredException()
}
if (username.length < 6) {
if (username.length < MinUsernameLength) {
throw UsernameLengthException()
}
if (password.isEmpty()) {
throw PasswordRequiredException()
}
if (password.length < 6) {
if (password.length < MinPasswordLength) {
throw PasswordLengthException()
}
emit(Unit)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import javax.inject.Inject
*/

class ConnectivityManagerNetworkMonitor @Inject constructor(
@ApplicationContext private val context: Context
@ApplicationContext private val context: Context,
) : NetworkMonitor {
override val isOnline: Flow<Boolean> = callbackFlow {
val connectivityManager = context.getSystemService<ConnectivityManager>()
Expand All @@ -35,7 +35,7 @@ class ConnectivityManagerNetworkMonitor @Inject constructor(

override fun onCapabilitiesChanged(
network: Network,
networkCapabilities: NetworkCapabilities
networkCapabilities: NetworkCapabilities,
) {
channel.trySend(connectivityManager.isCurrentlyConnected())
}
Expand All @@ -45,7 +45,7 @@ class ConnectivityManagerNetworkMonitor @Inject constructor(
NetworkRequest.Builder()
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.build(),
callback
callback,
)

channel.trySend(connectivityManager.isCurrentlyConnected())
Expand Down
Loading