mirror of
https://github.com/anyproto/anytype-kotlin.git
synced 2025-06-08 05:47:05 +09:00
DROID-69 Tech | Feature | Add feature toggles and make logs more concise (#2699)
This commit is contained in:
parent
72fa7d39f2
commit
29347ffb4a
33 changed files with 330 additions and 117 deletions
|
@ -13,6 +13,12 @@ apikeyProperties.load(new FileInputStream(apikeyPropertiesFile))
|
|||
|
||||
def useReleaseKeystore = rootProject.file("scripts/release/app-release.jks").exists()
|
||||
|
||||
def localProperties = new Properties()
|
||||
localProperties.with {
|
||||
def lp = "local.properties"
|
||||
if (new File(lp).exists()) it.load(new FileInputStream(lp))
|
||||
}
|
||||
|
||||
android {
|
||||
def config = rootProject.ext
|
||||
|
||||
|
@ -27,6 +33,11 @@ android {
|
|||
versionName getBuildVersionName()
|
||||
testInstrumentationRunner config.test_runner
|
||||
buildConfigField "boolean", "USE_NEW_WINDOW_INSET_API", "true"
|
||||
buildConfigField "boolean", "LOG_FROM_MW_LIBRARY", localProperties.getProperty("LOG_FROM_MW_LIBRARY", "false")
|
||||
buildConfigField "boolean", "LOG_MW_INTERACTION", localProperties.getProperty("LOG_MW_INTERACTION", "false")
|
||||
buildConfigField "boolean", "LOG_DASHBOARD_REDUCER", localProperties.getProperty("LOG_DASHBOARD_REDUCER", "false")
|
||||
buildConfigField "boolean", "LOG_EDITOR_VIEWMODEL_EVENTS", localProperties.getProperty("LOG_EDITOR_VIEWMODEL_EVENTS", "false")
|
||||
buildConfigField "boolean", "LOG_EDITOR_CONTROL_PANEL", localProperties.getProperty("LOG_EDITOR_CONTROL_PANEL", "false")
|
||||
}
|
||||
|
||||
packagingOptions {
|
||||
|
@ -69,9 +80,9 @@ android {
|
|||
buildConfigField("String", "AMPLITUDE_KEY", apikeyProperties['amplitude.debug'])
|
||||
//signingConfig signingConfigs.debug
|
||||
firebaseAppDistribution {
|
||||
artifactType="AAB"
|
||||
groups="anytype-q&a, product-review, nightly"
|
||||
serviceCredentialsFile="$rootDir/scripts/distribution/anytype-debug-service-account-key.json"
|
||||
artifactType = "AAB"
|
||||
groups = "anytype-q&a, product-review, nightly"
|
||||
serviceCredentialsFile = "$rootDir/scripts/distribution/anytype-debug-service-account-key.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
package com.anytypeio.anytype.app
|
||||
|
||||
import com.anytypeio.anytype.BuildConfig
|
||||
import com.anytypeio.anytype.core_utils.tools.FeatureToggles
|
||||
import javax.inject.Inject
|
||||
|
||||
class DefaultFeatureToggles @Inject constructor() : FeatureToggles {
|
||||
|
||||
override val isLogFromMiddlewareLibrary =
|
||||
BuildConfig.LOG_FROM_MW_LIBRARY && BuildConfig.DEBUG
|
||||
|
||||
override val isLogMiddlewareInteraction =
|
||||
BuildConfig.LOG_MW_INTERACTION && BuildConfig.DEBUG
|
||||
|
||||
override val isLogDashboardReducer =
|
||||
BuildConfig.LOG_DASHBOARD_REDUCER && BuildConfig.DEBUG
|
||||
|
||||
override val isLogEditorViewModelEvents =
|
||||
BuildConfig.LOG_EDITOR_VIEWMODEL_EVENTS && BuildConfig.DEBUG
|
||||
|
||||
override val isLogEditorControlPanelMachine =
|
||||
BuildConfig.LOG_EDITOR_CONTROL_PANEL && BuildConfig.DEBUG
|
||||
|
||||
}
|
|
@ -2,6 +2,7 @@ package com.anytypeio.anytype.di.feature
|
|||
|
||||
import com.anytypeio.anytype.analytics.base.Analytics
|
||||
import com.anytypeio.anytype.core_utils.di.scope.PerScreen
|
||||
import com.anytypeio.anytype.core_utils.tools.FeatureToggles
|
||||
import com.anytypeio.anytype.domain.`object`.ObjectTypesProvider
|
||||
import com.anytypeio.anytype.domain.auth.interactor.GetProfile
|
||||
import com.anytypeio.anytype.domain.auth.repo.AuthRepository
|
||||
|
@ -76,7 +77,8 @@ object HomeDashboardModule {
|
|||
objectSearchSubscriptionContainer: ObjectSearchSubscriptionContainer,
|
||||
cancelSearchSubscription: CancelSearchSubscription,
|
||||
objectStore: ObjectStore,
|
||||
createNewObject: CreateNewObject
|
||||
createNewObject: CreateNewObject,
|
||||
featureToggles: FeatureToggles
|
||||
): HomeDashboardViewModelFactory = HomeDashboardViewModelFactory(
|
||||
getProfile = getProfile,
|
||||
openDashboard = openDashboard,
|
||||
|
@ -94,7 +96,8 @@ object HomeDashboardModule {
|
|||
objectSearchSubscriptionContainer = objectSearchSubscriptionContainer,
|
||||
cancelSearchSubscription = cancelSearchSubscription,
|
||||
objectStore = objectStore,
|
||||
createNewObject = createNewObject
|
||||
createNewObject = createNewObject,
|
||||
featureToggles = featureToggles
|
||||
)
|
||||
|
||||
@JvmStatic
|
||||
|
|
|
@ -7,6 +7,7 @@ import com.anytypeio.anytype.core_models.Id
|
|||
import com.anytypeio.anytype.core_models.ObjectType
|
||||
import com.anytypeio.anytype.core_models.Payload
|
||||
import com.anytypeio.anytype.core_utils.di.scope.PerScreen
|
||||
import com.anytypeio.anytype.core_utils.tools.FeatureToggles
|
||||
import com.anytypeio.anytype.di.feature.cover.UnsplashSubComponent
|
||||
import com.anytypeio.anytype.di.feature.relations.RelationAddToObjectSubComponent
|
||||
import com.anytypeio.anytype.di.feature.relations.RelationCreateFromScratchForObjectBlockSubComponent
|
||||
|
@ -223,7 +224,8 @@ object EditorSessionModule {
|
|||
setDocImageIcon: SetDocumentImageIcon,
|
||||
editorTemplateDelegate: EditorTemplateDelegate,
|
||||
createNewObject: CreateNewObject,
|
||||
objectToSet: ConvertObjectToSet
|
||||
objectToSet: ConvertObjectToSet,
|
||||
featureToggles: FeatureToggles
|
||||
): EditorViewModelFactory = EditorViewModelFactory(
|
||||
openPage = openPage,
|
||||
closeObject = closePage,
|
||||
|
@ -255,7 +257,8 @@ object EditorSessionModule {
|
|||
setDocImageIcon = setDocImageIcon,
|
||||
editorTemplateDelegate = editorTemplateDelegate,
|
||||
createNewObject = createNewObject,
|
||||
objectToSet = objectToSet
|
||||
objectToSet = objectToSet,
|
||||
featureToggles = featureToggles
|
||||
)
|
||||
|
||||
@JvmStatic
|
||||
|
|
|
@ -5,6 +5,9 @@ import android.content.SharedPreferences
|
|||
import androidx.security.crypto.EncryptedSharedPreferences
|
||||
import androidx.security.crypto.MasterKeys
|
||||
import com.anytypeio.anytype.app.DefaultAppActionManager
|
||||
import com.anytypeio.anytype.core_utils.tools.DefaultUrlValidator
|
||||
import com.anytypeio.anytype.core_utils.tools.FeatureToggles
|
||||
import com.anytypeio.anytype.core_utils.tools.UrlValidator
|
||||
import com.anytypeio.anytype.data.auth.config.DefaultFeaturesConfigProvider
|
||||
import com.anytypeio.anytype.data.auth.repo.AuthCache
|
||||
import com.anytypeio.anytype.data.auth.repo.AuthCacheDataStore
|
||||
|
@ -40,18 +43,21 @@ import com.anytypeio.anytype.middleware.auth.AuthMiddleware
|
|||
import com.anytypeio.anytype.middleware.block.BlockMiddleware
|
||||
import com.anytypeio.anytype.middleware.interactor.Middleware
|
||||
import com.anytypeio.anytype.middleware.interactor.MiddlewareFactory
|
||||
import com.anytypeio.anytype.middleware.interactor.MiddlewareProtobufLogger
|
||||
import com.anytypeio.anytype.middleware.interactor.ProtobufConverterProvider
|
||||
import com.anytypeio.anytype.middleware.service.MiddlewareService
|
||||
import com.anytypeio.anytype.middleware.service.MiddlewareServiceImplementation
|
||||
import com.anytypeio.anytype.persistence.db.AnytypeDatabase
|
||||
import com.anytypeio.anytype.persistence.repo.DefaultAuthCache
|
||||
import com.anytypeio.anytype.persistence.repo.DefaultDebugSettingsCache
|
||||
import com.anytypeio.anytype.persistence.repo.DefaultUserSettingsCache
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import javax.inject.Named
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Module
|
||||
@Module(includes = [DataModule.Bindings::class])
|
||||
object DataModule {
|
||||
|
||||
@JvmStatic
|
||||
|
@ -219,19 +225,15 @@ object DataModule {
|
|||
@Singleton
|
||||
fun provideMiddleware(
|
||||
service: MiddlewareService,
|
||||
factory: MiddlewareFactory
|
||||
): Middleware = Middleware(service, factory)
|
||||
factory: MiddlewareFactory,
|
||||
logger: MiddlewareProtobufLogger
|
||||
): Middleware = Middleware(service, factory, logger)
|
||||
|
||||
@JvmStatic
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideMiddlewareFactory(): MiddlewareFactory = MiddlewareFactory()
|
||||
|
||||
@JvmStatic
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideMiddlewareService(): MiddlewareService = MiddlewareServiceImplementation()
|
||||
|
||||
@JvmStatic
|
||||
@Provides
|
||||
@Singleton
|
||||
|
@ -282,15 +284,17 @@ object DataModule {
|
|||
): UnsplashRepository = UnsplashDataRepository(
|
||||
remote = remote
|
||||
)
|
||||
|
||||
@JvmStatic
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideUnsplashRemote(
|
||||
service: MiddlewareService
|
||||
): UnsplashRemote = UnsplashMiddleware(
|
||||
service = service
|
||||
)
|
||||
|
||||
//endregion
|
||||
|
||||
@Module
|
||||
interface Bindings {
|
||||
|
||||
@Binds
|
||||
@Singleton
|
||||
fun bindUnsplashRemote(middleware: UnsplashMiddleware): UnsplashRemote
|
||||
|
||||
@Binds
|
||||
@Singleton
|
||||
fun bindMiddlewareService(middleware: MiddlewareServiceImplementation): MiddlewareService
|
||||
}
|
||||
}
|
|
@ -14,11 +14,12 @@ import com.anytypeio.anytype.domain.search.SubscriptionEventChannel
|
|||
import com.anytypeio.anytype.domain.status.ThreadStatusChannel
|
||||
import com.anytypeio.anytype.middleware.EventProxy
|
||||
import com.anytypeio.anytype.middleware.interactor.*
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Module
|
||||
@Module(includes = [EventModule.Bindings::class])
|
||||
object EventModule {
|
||||
|
||||
@JvmStatic
|
||||
|
@ -88,13 +89,6 @@ object EventModule {
|
|||
events = proxy
|
||||
)
|
||||
|
||||
@JvmStatic
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideEventProxy(): EventProxy {
|
||||
return EventHandler()
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@Provides
|
||||
@Singleton
|
||||
|
@ -115,4 +109,12 @@ object EventModule {
|
|||
fun provideSubscriptionEventRemoteChannel(
|
||||
proxy: EventProxy
|
||||
): SubscriptionEventRemoteChannel = MiddlewareSubscriptionEventChannel(events = proxy)
|
||||
|
||||
@Module
|
||||
interface Bindings {
|
||||
|
||||
@Binds
|
||||
@Singleton
|
||||
fun bindEventProxy(handler: EventHandler): EventProxy
|
||||
}
|
||||
}
|
|
@ -1,14 +1,19 @@
|
|||
package com.anytypeio.anytype.di.main
|
||||
|
||||
import com.anytypeio.anytype.app.DefaultFeatureToggles
|
||||
import com.anytypeio.anytype.core_utils.tools.DefaultUrlValidator
|
||||
import com.anytypeio.anytype.core_utils.tools.FeatureToggles
|
||||
import com.anytypeio.anytype.core_utils.tools.UrlValidator
|
||||
import com.anytypeio.anytype.domain.config.Gateway
|
||||
import com.anytypeio.anytype.domain.misc.UrlBuilder
|
||||
import com.anytypeio.anytype.middleware.interactor.MiddlewareProtobufLogger
|
||||
import com.anytypeio.anytype.middleware.interactor.ProtobufConverterProvider
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Module
|
||||
@Module(includes = [UtilModule.Bindings::class])
|
||||
object UtilModule {
|
||||
|
||||
@JvmStatic
|
||||
|
@ -16,8 +21,24 @@ object UtilModule {
|
|||
@Singleton
|
||||
fun provideUrlBuilder(gateway: Gateway): UrlBuilder = UrlBuilder(gateway)
|
||||
|
||||
@JvmStatic
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideUrlValidator() : UrlValidator = DefaultUrlValidator()
|
||||
|
||||
@Module
|
||||
interface Bindings {
|
||||
|
||||
@Binds
|
||||
@Singleton
|
||||
fun bindUrlValidator(applicator: DefaultUrlValidator): UrlValidator
|
||||
|
||||
@Binds
|
||||
@Singleton
|
||||
fun bindFeatureToggles(applicator: DefaultFeatureToggles): FeatureToggles
|
||||
|
||||
@Binds
|
||||
@Singleton
|
||||
fun bindMiddlewareProtobufLogger(logger: MiddlewareProtobufLogger.Impl): MiddlewareProtobufLogger
|
||||
|
||||
@Binds
|
||||
@Singleton
|
||||
fun bindProtobufConverterProvider(provider: ProtobufConverterProvider.Impl): ProtobufConverterProvider
|
||||
}
|
||||
}
|
|
@ -39,6 +39,7 @@ dependencies {
|
|||
implementation applicationDependencies.kotlin
|
||||
implementation applicationDependencies.coroutinesAndroid
|
||||
implementation applicationDependencies.dagger
|
||||
implementation applicationDependencies.gson
|
||||
|
||||
implementation applicationDependencies.timber
|
||||
implementation applicationDependencies.crashlytics
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
package com.anytypeio.anytype.core_utils.tools
|
||||
|
||||
interface FeatureToggles {
|
||||
|
||||
val isLogFromMiddlewareLibrary: Boolean
|
||||
|
||||
val isLogMiddlewareInteraction: Boolean
|
||||
|
||||
val isLogDashboardReducer: Boolean
|
||||
|
||||
val isLogEditorViewModelEvents: Boolean
|
||||
|
||||
val isLogEditorControlPanelMachine: Boolean
|
||||
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package com.anytypeio.anytype.core_utils.tools
|
||||
|
||||
import android.graphics.Color
|
||||
import com.google.gson.GsonBuilder
|
||||
|
||||
fun String.randomColor(): Int {
|
||||
var hash = 0
|
||||
|
@ -9,4 +10,14 @@ fun String.randomColor(): Int {
|
|||
}
|
||||
val h = (hash % 360).toFloat()
|
||||
return Color.HSVToColor(floatArrayOf(h, 0.5f, 0.9f))
|
||||
}
|
||||
|
||||
private val gson by lazy { GsonBuilder().setPrettyPrinting().create() }
|
||||
|
||||
fun Any.toPrettyString(): String {
|
||||
return try {
|
||||
gson.toJson(this)
|
||||
} catch (e: Exception) {
|
||||
this.toString()
|
||||
}
|
||||
}
|
|
@ -1,12 +1,13 @@
|
|||
package com.anytypeio.anytype.core_utils.tools
|
||||
|
||||
import android.util.Patterns
|
||||
import javax.inject.Inject
|
||||
|
||||
interface UrlValidator {
|
||||
fun isValid(url: String) : Boolean
|
||||
}
|
||||
|
||||
class DefaultUrlValidator: UrlValidator {
|
||||
class DefaultUrlValidator @Inject constructor(): UrlValidator {
|
||||
override fun isValid(url: String): Boolean {
|
||||
return Patterns.WEB_URL.matcher(url).matches()
|
||||
}
|
||||
|
|
|
@ -35,7 +35,8 @@ ext {
|
|||
javaxInject_version = '1'
|
||||
retrofit_version = '2.3.0'
|
||||
okhttp_logging_interceptor_version = '3.8.1'
|
||||
gson_version = '2.8.6'
|
||||
gson_version = '2.10'
|
||||
gson_wire_version = '4.4.3'
|
||||
better_link_method_version = '2.2.0'
|
||||
table_view_version = '0.8.9.4'
|
||||
pickt_version = "2.0.2"
|
||||
|
@ -118,6 +119,7 @@ ext {
|
|||
javaxAnnotation: "javax.annotation:jsr250-api:$javaxAnnotations_version",
|
||||
javaxInject: "javax.inject:javax.inject:$javaxInject_version",
|
||||
gson: "com.google.code.gson:gson:$gson_version",
|
||||
gsonWire: "com.squareup.wire:wire-gson-support:$gson_wire_version",
|
||||
retrofit: "com.squareup.retrofit2:converter-gson:$retrofit_version",
|
||||
okhttpLoggingInterceptor: "com.squareup.okhttp3:logging-interceptor:$okhttp_logging_interceptor_version",
|
||||
timber: "com.jakewharton.timber:timber:$timber_version",
|
||||
|
@ -177,6 +179,7 @@ ext {
|
|||
|
||||
protobuf = [
|
||||
protobufJava: "com.google.protobuf:protobuf-java:$protobuf_java_version",
|
||||
protobufJavaUtil: "com.google.protobuf:protobuf-java-util:$protobuf_java_version",
|
||||
protoc: "com.google.protobuf:protoc:$protoc_version",
|
||||
wireRuntime: "com.squareup.wire:wire-runtime:$wire_version"
|
||||
]
|
||||
|
|
|
@ -27,6 +27,7 @@ dependencies {
|
|||
implementation project(':core-models')
|
||||
implementation project(':protocol')
|
||||
implementation project(':data')
|
||||
implementation project(':core-utils')
|
||||
|
||||
def applicationDependencies = rootProject.ext.mainApplication
|
||||
def anytypeDependencies = rootProject.ext.anytype
|
||||
|
@ -35,6 +36,9 @@ dependencies {
|
|||
implementation applicationDependencies.kotlin
|
||||
implementation applicationDependencies.timber
|
||||
implementation applicationDependencies.coroutinesAndroid
|
||||
implementation applicationDependencies.gsonWire
|
||||
implementation applicationDependencies.gson
|
||||
implementation applicationDependencies.javaxInject
|
||||
implementation anytypeDependencies.middleware
|
||||
|
||||
testImplementation project(":test:utils")
|
||||
|
|
|
@ -6,27 +6,28 @@ import com.anytypeio.anytype.core_models.Hash
|
|||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.core_models.UnsplashImage
|
||||
import com.anytypeio.anytype.data.auth.repo.unsplash.UnsplashRemote
|
||||
import com.anytypeio.anytype.middleware.log.logRequest
|
||||
import com.anytypeio.anytype.middleware.log.logResponse
|
||||
import com.anytypeio.anytype.middleware.interactor.MiddlewareProtobufLogger
|
||||
import com.anytypeio.anytype.middleware.mappers.core
|
||||
import com.anytypeio.anytype.middleware.service.MiddlewareService
|
||||
import javax.inject.Inject
|
||||
|
||||
class UnsplashMiddleware(
|
||||
private val service: MiddlewareService
|
||||
class UnsplashMiddleware @Inject constructor(
|
||||
private val service: MiddlewareService,
|
||||
private val logger: MiddlewareProtobufLogger
|
||||
) : UnsplashRemote {
|
||||
|
||||
override fun search(query: String, limit: Int): List<UnsplashImage> {
|
||||
val request = Search.Request(
|
||||
query = query,
|
||||
limit = limit
|
||||
).also { it.logRequest() }
|
||||
val response = service.unsplashSearch(request = request).also { it.logResponse() }
|
||||
).also { logger.logRequest(it) }
|
||||
val response = service.unsplashSearch(request = request).also { logger.logResponse(it) }
|
||||
return response.pictures.map { p -> p.core() }
|
||||
}
|
||||
|
||||
override fun download(id: Id): Hash {
|
||||
val request = Download.Request(pictureId = id).also { it.logRequest() }
|
||||
val response = service.unsplashDownload(request = request).also { it.logResponse() }
|
||||
val request = Download.Request(pictureId = id).also { logger.logRequest(it) }
|
||||
val response = service.unsplashDownload(request = request).also { logger.logResponse(it) }
|
||||
return response.hash
|
||||
}
|
||||
}
|
|
@ -9,11 +9,13 @@ import kotlinx.coroutines.flow.MutableSharedFlow
|
|||
import service.Service.setEventHandlerMobile
|
||||
import timber.log.Timber
|
||||
import java.io.IOException
|
||||
import javax.inject.Inject
|
||||
|
||||
class EventHandler(
|
||||
private val scope: CoroutineScope = GlobalScope
|
||||
class EventHandler @Inject constructor(
|
||||
private val logger: MiddlewareProtobufLogger
|
||||
) : EventProxy {
|
||||
|
||||
private val scope: CoroutineScope = GlobalScope
|
||||
private val channel = MutableSharedFlow<Event>(0, 1)
|
||||
|
||||
init {
|
||||
|
@ -38,10 +40,7 @@ class EventHandler(
|
|||
}
|
||||
|
||||
private fun logEvent(event: Event) {
|
||||
if (BuildConfig.DEBUG) {
|
||||
val message = "[" + "\n" + event::class.java.name + ":" + "\n" + event.toString() + "\n" + "]"
|
||||
Timber.d(message)
|
||||
}
|
||||
logger.logEvent(event)
|
||||
}
|
||||
|
||||
override fun flow(): Flow<Event> = channel
|
||||
|
|
|
@ -39,11 +39,11 @@ import com.anytypeio.anytype.middleware.mappers.toMiddlewareModel
|
|||
import com.anytypeio.anytype.middleware.mappers.toPayload
|
||||
import com.anytypeio.anytype.middleware.model.CreateWalletResponse
|
||||
import com.anytypeio.anytype.middleware.service.MiddlewareService
|
||||
import timber.log.Timber
|
||||
|
||||
class Middleware(
|
||||
private val service: MiddlewareService,
|
||||
private val factory: MiddlewareFactory
|
||||
private val factory: MiddlewareFactory,
|
||||
private val logger: MiddlewareProtobufLogger,
|
||||
) {
|
||||
|
||||
@Throws(Exception::class)
|
||||
|
@ -1957,12 +1957,10 @@ class Middleware(
|
|||
}
|
||||
|
||||
private fun logRequest(any: Any) {
|
||||
val message = "===> " + any::class.java.canonicalName + ":" + "\n" + any.toString()
|
||||
Timber.d(message)
|
||||
logger.logRequest(any)
|
||||
}
|
||||
|
||||
private fun logResponse(any: Any) {
|
||||
val message = "<=== " + any::class.java.canonicalName + ":" + "\n" + any.toString()
|
||||
Timber.d(message)
|
||||
logger.logResponse(any)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package com.anytypeio.anytype.middleware.interactor
|
||||
|
||||
import com.anytypeio.anytype.core_utils.tools.FeatureToggles
|
||||
import com.google.gson.Gson
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
interface MiddlewareProtobufLogger {
|
||||
|
||||
fun logRequest(any: Any)
|
||||
|
||||
fun logResponse(any: Any)
|
||||
|
||||
fun logEvent(any: Any)
|
||||
|
||||
class Impl @Inject constructor(
|
||||
private val protobufConverter: ProtobufConverterProvider,
|
||||
private val featureToggles: FeatureToggles
|
||||
) : MiddlewareProtobufLogger {
|
||||
|
||||
override fun logRequest(any: Any) {
|
||||
if (featureToggles.isLogMiddlewareInteraction) {
|
||||
Timber.d("request -> ${any.toLogMessage()}")
|
||||
}
|
||||
}
|
||||
|
||||
override fun logResponse(any: Any) {
|
||||
if (featureToggles.isLogMiddlewareInteraction) {
|
||||
Timber.d("response -> ${any.toLogMessage()}")
|
||||
}
|
||||
}
|
||||
|
||||
override fun logEvent(any: Any) {
|
||||
if (featureToggles.isLogMiddlewareInteraction) {
|
||||
Timber.d("event -> ${any.toLogMessage()}")
|
||||
}
|
||||
}
|
||||
|
||||
private fun Any.toLogMessage(): String {
|
||||
return "${this::class.java.canonicalName}:\n${
|
||||
protobufConverter.provideConverter().toJson(this)
|
||||
}"
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package com.anytypeio.anytype.middleware.interactor
|
||||
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.GsonBuilder
|
||||
import com.squareup.wire.WireTypeAdapterFactory
|
||||
import javax.inject.Inject
|
||||
|
||||
interface ProtobufConverterProvider {
|
||||
|
||||
fun provideConverter(): Gson
|
||||
|
||||
class Impl @Inject constructor() : ProtobufConverterProvider {
|
||||
private val provider = GsonBuilder()
|
||||
.registerTypeAdapterFactory(WireTypeAdapterFactory())
|
||||
.setPrettyPrinting()
|
||||
.create()
|
||||
|
||||
override fun provideConverter(): Gson {
|
||||
return provider
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
package com.anytypeio.anytype.middleware.log
|
||||
|
||||
import timber.log.Timber
|
||||
|
||||
fun Any.logResponse() {
|
||||
val message = "===> " + this::class.java.canonicalName + ":" + "\n" + this.toString()
|
||||
Timber.d(message)
|
||||
}
|
||||
|
||||
fun Any.logRequest() {
|
||||
val message = "<=== " + this::class.java.canonicalName + ":" + "\n" + this.toString()
|
||||
Timber.d(message)
|
||||
}
|
|
@ -3,12 +3,22 @@ package com.anytypeio.anytype.middleware.service
|
|||
import anytype.Rpc
|
||||
import com.anytypeio.anytype.core_models.exceptions.AccountIsDeletedException
|
||||
import com.anytypeio.anytype.core_models.exceptions.CreateAccountException
|
||||
import com.anytypeio.anytype.core_utils.tools.FeatureToggles
|
||||
import com.anytypeio.anytype.data.auth.exception.BackwardCompatilityNotSupportedException
|
||||
import com.anytypeio.anytype.data.auth.exception.NotFoundObjectException
|
||||
import com.anytypeio.anytype.data.auth.exception.UndoRedoExhaustedException
|
||||
import service.Service
|
||||
import javax.inject.Inject
|
||||
|
||||
class MiddlewareServiceImplementation : MiddlewareService {
|
||||
class MiddlewareServiceImplementation @Inject constructor(
|
||||
featureToggles: FeatureToggles
|
||||
) : MiddlewareService {
|
||||
|
||||
init {
|
||||
if (!featureToggles.isLogFromMiddlewareLibrary) {
|
||||
Service.setEnv("ANYTYPE_LOG_LEVEL", "*=fatal;anytype*=error")
|
||||
}
|
||||
}
|
||||
|
||||
override fun accountCreate(request: Rpc.Account.Create.Request): Rpc.Account.Create.Response {
|
||||
val encoded = Service.accountCreate(Rpc.Account.Create.Request.ADAPTER.encode(request))
|
||||
|
@ -655,7 +665,8 @@ class MiddlewareServiceImplementation : MiddlewareService {
|
|||
}
|
||||
|
||||
override fun objectCreateBookmark(request: Rpc.Object.CreateBookmark.Request): Rpc.Object.CreateBookmark.Response {
|
||||
val encoded = Service.objectCreateBookmark(Rpc.Object.CreateBookmark.Request.ADAPTER.encode(request))
|
||||
val encoded =
|
||||
Service.objectCreateBookmark(Rpc.Object.CreateBookmark.Request.ADAPTER.encode(request))
|
||||
val response = Rpc.Object.CreateBookmark.Response.ADAPTER.decode(encoded)
|
||||
val error = response.error
|
||||
if (error != null && error.code != Rpc.Object.CreateBookmark.Response.Error.Code.NULL) {
|
||||
|
@ -666,7 +677,8 @@ class MiddlewareServiceImplementation : MiddlewareService {
|
|||
}
|
||||
|
||||
override fun objectBookmarkFetch(request: Rpc.Object.BookmarkFetch.Request): Rpc.Object.BookmarkFetch.Response {
|
||||
val encoded = Service.objectBookmarkFetch(Rpc.Object.BookmarkFetch.Request.ADAPTER.encode(request))
|
||||
val encoded =
|
||||
Service.objectBookmarkFetch(Rpc.Object.BookmarkFetch.Request.ADAPTER.encode(request))
|
||||
val response = Rpc.Object.BookmarkFetch.Response.ADAPTER.decode(encoded)
|
||||
val error = response.error
|
||||
if (error != null && error.code != Rpc.Object.BookmarkFetch.Response.Error.Code.NULL) {
|
||||
|
@ -1119,7 +1131,11 @@ class MiddlewareServiceImplementation : MiddlewareService {
|
|||
|
||||
override fun blockDataViewSetSource(request: Rpc.BlockDataview.SetSource.Request): Rpc.BlockDataview.SetSource.Response {
|
||||
val encoded =
|
||||
Service.blockDataviewSetSource(Rpc.BlockDataview.SetSource.Request.ADAPTER.encode(request))
|
||||
Service.blockDataviewSetSource(
|
||||
Rpc.BlockDataview.SetSource.Request.ADAPTER.encode(
|
||||
request
|
||||
)
|
||||
)
|
||||
val response = Rpc.BlockDataview.SetSource.Response.ADAPTER.decode(encoded)
|
||||
val error = response.error
|
||||
if (error != null && error.code != Rpc.BlockDataview.SetSource.Response.Error.Code.NULL) {
|
||||
|
|
|
@ -17,6 +17,7 @@ import org.mockito.Mock
|
|||
import org.mockito.MockitoAnnotations
|
||||
import org.mockito.kotlin.any
|
||||
import org.mockito.kotlin.doReturn
|
||||
import org.mockito.kotlin.mock
|
||||
import org.mockito.kotlin.stub
|
||||
import org.mockito.kotlin.times
|
||||
import org.mockito.kotlin.verify
|
||||
|
@ -42,7 +43,7 @@ class MiddlewareTest {
|
|||
@Before
|
||||
fun setup() {
|
||||
MockitoAnnotations.openMocks(this)
|
||||
middleware = Middleware(service, factory)
|
||||
middleware = Middleware(service, factory, mock())
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -7,6 +7,8 @@ import com.anytypeio.anytype.core_models.ext.amend
|
|||
import com.anytypeio.anytype.core_models.ext.getChildrenIdsList
|
||||
import com.anytypeio.anytype.core_models.ext.set
|
||||
import com.anytypeio.anytype.core_models.ext.unset
|
||||
import com.anytypeio.anytype.core_utils.tools.FeatureToggles
|
||||
import com.anytypeio.anytype.core_utils.tools.toPrettyString
|
||||
import com.anytypeio.anytype.domain.misc.UrlBuilder
|
||||
import com.anytypeio.anytype.presentation.common.StateReducer
|
||||
import com.anytypeio.anytype.presentation.dashboard.HomeDashboardStateMachine.Event
|
||||
|
@ -34,7 +36,7 @@ sealed class HomeDashboardStateMachine {
|
|||
|
||||
class Interactor(
|
||||
private val scope: CoroutineScope,
|
||||
private val reducer: Reducer = Reducer(),
|
||||
private val reducer: Reducer,
|
||||
private val channel: Channel<List<Event>> = Channel(),
|
||||
private val events: Flow<List<Event>> = channel.consumeAsFlow()
|
||||
) {
|
||||
|
@ -116,13 +118,19 @@ sealed class HomeDashboardStateMachine {
|
|||
object OnFinishedCreatingPage : Event()
|
||||
}
|
||||
|
||||
class Reducer : StateReducer<State, List<Event>> {
|
||||
class Reducer(private val featureToggles: FeatureToggles) : StateReducer<State, List<Event>> {
|
||||
|
||||
override val function: suspend (State, List<Event>) -> State
|
||||
get() = { state, events ->
|
||||
Timber.d("REDUCE, STATE:$state, EVENT:$events")
|
||||
if (featureToggles.isLogDashboardReducer) {
|
||||
Timber.d("REDUCE, STATE:$state, EVENT:${events.toPrettyString()}")
|
||||
}
|
||||
|
||||
val update = reduce(state, events)
|
||||
Timber.d("REDUCE, UPDATED STATE:$update")
|
||||
|
||||
if (featureToggles.isLogDashboardReducer) {
|
||||
Timber.d("REDUCE, UPDATED STATE:${update.toPrettyString()}")
|
||||
}
|
||||
update
|
||||
}
|
||||
|
||||
|
@ -148,9 +156,9 @@ sealed class HomeDashboardStateMachine {
|
|||
is Event.OnShowDashboard -> {
|
||||
|
||||
val new = event.blocks.toDashboardViews(
|
||||
details = event.details,
|
||||
builder = event.builder,
|
||||
objectTypes = event.objectTypes
|
||||
details = event.details,
|
||||
builder = event.builder,
|
||||
objectTypes = event.objectTypes
|
||||
)
|
||||
|
||||
val childrenIdsList = event.blocks.getChildrenIdsList(parent = event.context)
|
||||
|
|
|
@ -22,6 +22,7 @@ import com.anytypeio.anytype.core_models.Position
|
|||
import com.anytypeio.anytype.core_models.Relations
|
||||
import com.anytypeio.anytype.core_utils.common.EventWrapper
|
||||
import com.anytypeio.anytype.core_utils.ext.withLatestFrom
|
||||
import com.anytypeio.anytype.core_utils.tools.FeatureToggles
|
||||
import com.anytypeio.anytype.core_utils.ui.ViewState
|
||||
import com.anytypeio.anytype.core_utils.ui.ViewStateViewModel
|
||||
import com.anytypeio.anytype.domain.auth.interactor.GetProfile
|
||||
|
@ -41,6 +42,7 @@ import com.anytypeio.anytype.domain.search.CancelSearchSubscription
|
|||
import com.anytypeio.anytype.domain.search.ObjectSearchSubscriptionContainer
|
||||
import com.anytypeio.anytype.presentation.BuildConfig
|
||||
import com.anytypeio.anytype.presentation.dashboard.HomeDashboardStateMachine.Interactor
|
||||
import com.anytypeio.anytype.presentation.dashboard.HomeDashboardStateMachine.Reducer
|
||||
import com.anytypeio.anytype.presentation.dashboard.HomeDashboardStateMachine.State
|
||||
import com.anytypeio.anytype.presentation.extension.sendAnalyticsRemoveObjects
|
||||
import com.anytypeio.anytype.presentation.extension.sendAnalyticsRestoreFromBin
|
||||
|
@ -84,7 +86,8 @@ class HomeDashboardViewModel(
|
|||
private val objectSearchSubscriptionContainer: ObjectSearchSubscriptionContainer,
|
||||
private val cancelSearchSubscription: CancelSearchSubscription,
|
||||
private val objectStore: ObjectStore,
|
||||
private val createNewObject: CreateNewObject
|
||||
private val createNewObject: CreateNewObject,
|
||||
featureToggles: FeatureToggles
|
||||
) : ViewStateViewModel<State>(),
|
||||
HomeDashboardEventConverter by eventConverter,
|
||||
SupportNavigation<EventWrapper<AppNavigation.Command>> {
|
||||
|
@ -93,7 +96,7 @@ class HomeDashboardViewModel(
|
|||
|
||||
val toasts = MutableSharedFlow<String>()
|
||||
|
||||
private val machine = Interactor(scope = viewModelScope)
|
||||
private val machine = Interactor(scope = viewModelScope, reducer = Reducer(featureToggles))
|
||||
|
||||
private val movementChannel = Channel<Movement>()
|
||||
private val movementChanges = movementChannel.consumeAsFlow()
|
||||
|
|
|
@ -3,6 +3,7 @@ package com.anytypeio.anytype.presentation.dashboard
|
|||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import com.anytypeio.anytype.analytics.base.Analytics
|
||||
import com.anytypeio.anytype.core_utils.tools.FeatureToggles
|
||||
import com.anytypeio.anytype.domain.auth.interactor.GetProfile
|
||||
import com.anytypeio.anytype.domain.block.interactor.Move
|
||||
import com.anytypeio.anytype.domain.config.GetConfig
|
||||
|
@ -36,7 +37,8 @@ class HomeDashboardViewModelFactory(
|
|||
private val objectSearchSubscriptionContainer: ObjectSearchSubscriptionContainer,
|
||||
private val cancelSearchSubscription: CancelSearchSubscription,
|
||||
private val objectStore: ObjectStore,
|
||||
private val createNewObject: CreateNewObject
|
||||
private val createNewObject: CreateNewObject,
|
||||
private val featureToggles: FeatureToggles
|
||||
) : ViewModelProvider.Factory {
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
|
@ -58,7 +60,8 @@ class HomeDashboardViewModelFactory(
|
|||
objectSearchSubscriptionContainer = objectSearchSubscriptionContainer,
|
||||
cancelSearchSubscription = cancelSearchSubscription,
|
||||
objectStore = objectStore,
|
||||
createNewObject = createNewObject
|
||||
createNewObject = createNewObject,
|
||||
featureToggles = featureToggles
|
||||
) as T
|
||||
}
|
||||
}
|
|
@ -4,6 +4,8 @@ import com.anytypeio.anytype.core_models.Block
|
|||
import com.anytypeio.anytype.core_models.Block.Content.Text.Style
|
||||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.core_models.TextBlock
|
||||
import com.anytypeio.anytype.core_utils.tools.FeatureToggles
|
||||
import com.anytypeio.anytype.core_utils.tools.toPrettyString
|
||||
import com.anytypeio.anytype.presentation.common.StateReducer
|
||||
import com.anytypeio.anytype.presentation.editor.ControlPanelMachine.Event
|
||||
import com.anytypeio.anytype.presentation.editor.ControlPanelMachine.Interactor
|
||||
|
@ -42,10 +44,10 @@ sealed class ControlPanelMachine {
|
|||
* @property scope coroutine scope (state machine runs inside this scope)
|
||||
*/
|
||||
class Interactor(
|
||||
private val scope: CoroutineScope
|
||||
private val scope: CoroutineScope,
|
||||
private val reducer: Reducer
|
||||
) : ControlPanelMachine() {
|
||||
|
||||
private val reducer: Reducer = Reducer()
|
||||
val channel: Channel<Event> = Channel()
|
||||
private val events: Flow<Event> = channel.consumeAsFlow()
|
||||
|
||||
|
@ -232,7 +234,8 @@ sealed class ControlPanelMachine {
|
|||
/**
|
||||
* Concrete reducer implementation that holds all the logic related to control panels.
|
||||
*/
|
||||
class Reducer : StateReducer<ControlPanelState, Event> {
|
||||
class Reducer(private val featureToggles: FeatureToggles) :
|
||||
StateReducer<ControlPanelState, Event> {
|
||||
|
||||
override val function: suspend (ControlPanelState, Event) -> ControlPanelState
|
||||
get() = { state, event ->
|
||||
|
@ -938,19 +941,21 @@ sealed class ControlPanelMachine {
|
|||
}
|
||||
|
||||
private fun logState(text: String, state: ControlPanelState) {
|
||||
Timber.i(
|
||||
"REDUCER, $text STATE:${
|
||||
state
|
||||
}"
|
||||
)
|
||||
if (featureToggles.isLogEditorControlPanelMachine) {
|
||||
Timber.i(
|
||||
"REDUCER, $text STATE:${state.toPrettyString()}"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun logEvent(event: Event) {
|
||||
Timber.i(
|
||||
"REDUCER, EVENT:${
|
||||
event::class.qualifiedName?.substringAfter("Event.")
|
||||
}"
|
||||
)
|
||||
if (featureToggles.isLogEditorControlPanelMachine) {
|
||||
Timber.i(
|
||||
"REDUCER, EVENT:${
|
||||
event::class.qualifiedName?.substringAfter("Event.")
|
||||
}"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,6 +6,7 @@ import com.anytypeio.anytype.core_models.Id
|
|||
import com.anytypeio.anytype.core_models.Relations
|
||||
import com.anytypeio.anytype.core_models.ext.content
|
||||
import com.anytypeio.anytype.core_utils.ext.replace
|
||||
import com.anytypeio.anytype.core_utils.tools.toPrettyString
|
||||
import com.anytypeio.anytype.presentation.common.StateReducer
|
||||
import timber.log.Timber
|
||||
|
||||
|
@ -142,7 +143,9 @@ class DocumentExternalEventReducer : StateReducer<List<Block>, Event> {
|
|||
target = { block -> block.id == event.id }
|
||||
)
|
||||
|
||||
else -> state.also { Timber.d("Ignoring event: $event") }
|
||||
else -> state.also {
|
||||
Timber.d("Ignoring event: ${event::class.java.canonicalName}:\n${event.toPrettyString()}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -88,6 +88,8 @@ import com.anytypeio.anytype.presentation.editor.editor.Orchestrator
|
|||
import com.anytypeio.anytype.presentation.editor.editor.Proxy
|
||||
import com.anytypeio.anytype.presentation.editor.editor.SideEffect
|
||||
import com.anytypeio.anytype.core_models.ThemeColor
|
||||
import com.anytypeio.anytype.core_utils.tools.FeatureToggles
|
||||
import com.anytypeio.anytype.core_utils.tools.toPrettyString
|
||||
import com.anytypeio.anytype.domain.`object`.ConvertObjectToSet
|
||||
import com.anytypeio.anytype.presentation.editor.editor.ViewState
|
||||
import com.anytypeio.anytype.presentation.editor.editor.actions.ActionItemType
|
||||
|
@ -249,7 +251,8 @@ class EditorViewModel(
|
|||
private val setDocImageIcon: SetDocumentImageIcon,
|
||||
private val templateDelegate: EditorTemplateDelegate,
|
||||
private val createNewObject: CreateNewObject,
|
||||
private val objectToSet: ConvertObjectToSet
|
||||
private val objectToSet: ConvertObjectToSet,
|
||||
private val featureToggles: FeatureToggles
|
||||
) : ViewStateViewModel<ViewState>(),
|
||||
PickerListener,
|
||||
SupportNavigation<EventWrapper<AppNavigation.Command>>,
|
||||
|
@ -295,7 +298,10 @@ class EditorViewModel(
|
|||
|
||||
val footers = MutableStateFlow<EditorFooter>(EditorFooter.None)
|
||||
|
||||
private val controlPanelInteractor = Interactor(viewModelScope)
|
||||
private val controlPanelInteractor = Interactor(
|
||||
viewModelScope,
|
||||
reducer = ControlPanelMachine.Reducer(featureToggles)
|
||||
)
|
||||
val controlPanelViewState = MutableLiveData<ControlPanelState>()
|
||||
|
||||
/**
|
||||
|
@ -496,9 +502,9 @@ class EditorViewModel(
|
|||
}
|
||||
|
||||
private suspend fun processEvents(events: List<Event>): List<Flag> {
|
||||
if (BuildConfig.DEBUG) {
|
||||
Timber.d("Blocks before handling events: $blocks")
|
||||
Timber.d("Events: $events")
|
||||
if (featureToggles.isLogEditorViewModelEvents) {
|
||||
Timber.d("Blocks before handling events: ${blocks.toPrettyString()}")
|
||||
Timber.d("Events: ${events.toPrettyString()}")
|
||||
}
|
||||
events.forEach { event ->
|
||||
when (event) {
|
||||
|
@ -522,8 +528,8 @@ class EditorViewModel(
|
|||
}
|
||||
orchestrator.stores.document.update(reduce(blocks, event))
|
||||
}
|
||||
if (BuildConfig.DEBUG) {
|
||||
Timber.d("Blocks after handling events: $blocks")
|
||||
if (featureToggles.isLogEditorViewModelEvents) {
|
||||
Timber.d("Blocks after handling events: ${blocks.toPrettyString()}")
|
||||
}
|
||||
return events.flags(context)
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import com.anytypeio.anytype.analytics.base.Analytics
|
|||
import com.anytypeio.anytype.core_models.Block
|
||||
import com.anytypeio.anytype.core_models.Event
|
||||
import com.anytypeio.anytype.core_models.Payload
|
||||
import com.anytypeio.anytype.core_utils.tools.FeatureToggles
|
||||
import com.anytypeio.anytype.domain.`object`.ConvertObjectToSet
|
||||
import com.anytypeio.anytype.domain.`object`.ObjectTypesProvider
|
||||
import com.anytypeio.anytype.domain.`object`.UpdateDetail
|
||||
|
@ -69,7 +70,8 @@ open class EditorViewModelFactory(
|
|||
private val setDocImageIcon: SetDocumentImageIcon,
|
||||
private val editorTemplateDelegate: EditorTemplateDelegate,
|
||||
private val createNewObject: CreateNewObject,
|
||||
private val objectToSet: ConvertObjectToSet
|
||||
private val objectToSet: ConvertObjectToSet,
|
||||
private val featureToggles: FeatureToggles
|
||||
) : ViewModelProvider.Factory {
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
|
@ -105,7 +107,8 @@ open class EditorViewModelFactory(
|
|||
setDocImageIcon = setDocImageIcon,
|
||||
templateDelegate = editorTemplateDelegate,
|
||||
createNewObject = createNewObject,
|
||||
objectToSet = objectToSet
|
||||
objectToSet = objectToSet,
|
||||
featureToggles = featureToggles
|
||||
) as T
|
||||
}
|
||||
}
|
|
@ -40,6 +40,7 @@ import org.mockito.Mock
|
|||
import org.mockito.kotlin.any
|
||||
import org.mockito.kotlin.doAnswer
|
||||
import org.mockito.kotlin.doReturn
|
||||
import org.mockito.kotlin.mock
|
||||
import org.mockito.kotlin.stub
|
||||
|
||||
open class DashboardTestSetup {
|
||||
|
@ -147,7 +148,8 @@ open class DashboardTestSetup {
|
|||
main = coroutineTestRule.testDispatcher
|
||||
)
|
||||
),
|
||||
createNewObject = createNewObject
|
||||
createNewObject = createNewObject,
|
||||
featureToggles = mock()
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -51,6 +51,7 @@ import org.mockito.kotlin.atLeast
|
|||
import org.mockito.kotlin.doAnswer
|
||||
import org.mockito.kotlin.doReturn
|
||||
import org.mockito.kotlin.eq
|
||||
import org.mockito.kotlin.mock
|
||||
import org.mockito.kotlin.stub
|
||||
import org.mockito.kotlin.times
|
||||
import org.mockito.kotlin.verify
|
||||
|
@ -152,7 +153,8 @@ class HomeDashboardViewModelTest {
|
|||
cancelSearchSubscription = cancelSearchSubscription,
|
||||
objectStore = objectStore,
|
||||
objectSearchSubscriptionContainer = objectSearchSubscriptionContainer,
|
||||
createNewObject = createNewObject
|
||||
createNewObject = createNewObject,
|
||||
featureToggles = mock()
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ import org.junit.Rule
|
|||
import org.junit.Test
|
||||
import org.mockito.Mock
|
||||
import org.mockito.MockitoAnnotations
|
||||
import org.mockito.kotlin.mock
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
|
||||
|
@ -28,7 +29,7 @@ class ControlPanelStateReducerTest {
|
|||
lateinit var gateway: Gateway
|
||||
lateinit var urlBuilder: UrlBuilder
|
||||
|
||||
private val reducer = ControlPanelMachine.Reducer()
|
||||
private val reducer = ControlPanelMachine.Reducer(mock())
|
||||
|
||||
val paragraph = Block(
|
||||
id = MockDataFactory.randomUuid(),
|
||||
|
|
|
@ -137,6 +137,7 @@ import org.mockito.kotlin.doAnswer
|
|||
import org.mockito.kotlin.doReturn
|
||||
import org.mockito.kotlin.doThrow
|
||||
import org.mockito.kotlin.eq
|
||||
import org.mockito.kotlin.mock
|
||||
import org.mockito.kotlin.never
|
||||
import org.mockito.kotlin.stub
|
||||
import org.mockito.kotlin.times
|
||||
|
@ -4018,7 +4019,8 @@ open class EditorViewModelTest {
|
|||
setDocImageIcon = setDocImageIcon,
|
||||
templateDelegate = editorTemplateDelegate,
|
||||
createNewObject = createNewObject,
|
||||
objectToSet = objectToSet
|
||||
objectToSet = objectToSet,
|
||||
featureToggles = mock()
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -93,6 +93,7 @@ import org.mockito.Mock
|
|||
import org.mockito.kotlin.any
|
||||
import org.mockito.kotlin.doAnswer
|
||||
import org.mockito.kotlin.doReturn
|
||||
import org.mockito.kotlin.mock
|
||||
import org.mockito.kotlin.stub
|
||||
|
||||
open class EditorPresentationTestSetup {
|
||||
|
@ -376,7 +377,8 @@ open class EditorPresentationTestSetup {
|
|||
setDocImageIcon = setDocImageIcon,
|
||||
templateDelegate = editorTemplateDelegate,
|
||||
createNewObject = createNewObject,
|
||||
objectToSet = objectToSet
|
||||
objectToSet = objectToSet,
|
||||
featureToggles = mock()
|
||||
)
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue