mirror of
				https://github.com/KokaKiwi/BarInsta
				synced 2025-11-04 13:35:36 +00:00 
			
		
		
		
	Update ProfileFragmentViewModel
This commit is contained in:
		
							parent
							
								
									b1628492f5
								
							
						
					
					
						commit
						1ebf7a2e4b
					
				@ -192,6 +192,7 @@ dependencies {
 | 
				
			|||||||
    // Lifecycle
 | 
					    // Lifecycle
 | 
				
			||||||
    implementation "androidx.lifecycle:lifecycle-extensions:2.2.0"
 | 
					    implementation "androidx.lifecycle:lifecycle-extensions:2.2.0"
 | 
				
			||||||
    implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1"
 | 
					    implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1"
 | 
				
			||||||
 | 
					    implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.3.1"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Room
 | 
					    // Room
 | 
				
			||||||
    def room_version = "2.3.0"
 | 
					    def room_version = "2.3.0"
 | 
				
			||||||
@ -244,6 +245,7 @@ dependencies {
 | 
				
			|||||||
    testImplementation "androidx.test:core-ktx:1.3.0"
 | 
					    testImplementation "androidx.test:core-ktx:1.3.0"
 | 
				
			||||||
    testImplementation "androidx.arch.core:core-testing:2.1.0"
 | 
					    testImplementation "androidx.arch.core:core-testing:2.1.0"
 | 
				
			||||||
    testImplementation "org.robolectric:robolectric:4.5.1"
 | 
					    testImplementation "org.robolectric:robolectric:4.5.1"
 | 
				
			||||||
 | 
					    testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.5.0'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    androidTestImplementation 'org.junit.jupiter:junit-jupiter:5.7.2'
 | 
					    androidTestImplementation 'org.junit.jupiter:junit-jupiter:5.7.2'
 | 
				
			||||||
    androidTestImplementation 'androidx.test:core:1.3.0'
 | 
					    androidTestImplementation 'androidx.test:core:1.3.0'
 | 
				
			||||||
 | 
				
			|||||||
@ -6,11 +6,12 @@ import androidx.savedstate.SavedStateRegistryOwner
 | 
				
			|||||||
import awais.instagrabber.db.repositories.AccountRepository
 | 
					import awais.instagrabber.db.repositories.AccountRepository
 | 
				
			||||||
import awais.instagrabber.db.repositories.FavoriteRepository
 | 
					import awais.instagrabber.db.repositories.FavoriteRepository
 | 
				
			||||||
import awais.instagrabber.managers.DirectMessagesManager
 | 
					import awais.instagrabber.managers.DirectMessagesManager
 | 
				
			||||||
import awais.instagrabber.models.enums.BroadcastItemType
 | 
					 | 
				
			||||||
import awais.instagrabber.models.Resource
 | 
					import awais.instagrabber.models.Resource
 | 
				
			||||||
import awais.instagrabber.repositories.responses.User
 | 
					import awais.instagrabber.repositories.responses.User
 | 
				
			||||||
import awais.instagrabber.repositories.responses.directmessages.RankedRecipient
 | 
					import awais.instagrabber.repositories.responses.directmessages.RankedRecipient
 | 
				
			||||||
import awais.instagrabber.webservices.*
 | 
					import awais.instagrabber.webservices.*
 | 
				
			||||||
 | 
					import kotlinx.coroutines.CoroutineDispatcher
 | 
				
			||||||
 | 
					import kotlinx.coroutines.Dispatchers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ProfileFragmentViewModel(
 | 
					class ProfileFragmentViewModel(
 | 
				
			||||||
    state: SavedStateHandle,
 | 
					    state: SavedStateHandle,
 | 
				
			||||||
@ -21,12 +22,61 @@ class ProfileFragmentViewModel(
 | 
				
			|||||||
    graphQLRepository: GraphQLRepository,
 | 
					    graphQLRepository: GraphQLRepository,
 | 
				
			||||||
    accountRepository: AccountRepository,
 | 
					    accountRepository: AccountRepository,
 | 
				
			||||||
    favoriteRepository: FavoriteRepository,
 | 
					    favoriteRepository: FavoriteRepository,
 | 
				
			||||||
 | 
					    ioDispatcher: CoroutineDispatcher,
 | 
				
			||||||
) : ViewModel() {
 | 
					) : ViewModel() {
 | 
				
			||||||
    private val _profile = MutableLiveData<Resource<User?>>(Resource.loading(null))
 | 
					    private val _currentUser = MutableLiveData<Resource<User?>>(Resource.loading(null))
 | 
				
			||||||
    private val _isLoggedIn = MutableLiveData(false)
 | 
					 | 
				
			||||||
    private var messageManager: DirectMessagesManager? = null
 | 
					    private var messageManager: DirectMessagesManager? = null
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    val profile: LiveData<Resource<User?>> = _profile
 | 
					    val currentUser: LiveData<Resource<User?>> = _currentUser
 | 
				
			||||||
 | 
					    val isLoggedIn: LiveData<Boolean> = currentUser.map { it.data != null }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private val currentUserAndStateUsernameLiveData: LiveData<Pair<Resource<User?>, Resource<String?>>> =
 | 
				
			||||||
 | 
					        object : MediatorLiveData<Pair<Resource<User?>, Resource<String?>>>() {
 | 
				
			||||||
 | 
					            var user: Resource<User?> = Resource.loading(null)
 | 
				
			||||||
 | 
					            var stateUsername: Resource<String?> = Resource.loading(null)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            init {
 | 
				
			||||||
 | 
					                addSource(currentUser) { currentUser ->
 | 
				
			||||||
 | 
					                    this.user = currentUser
 | 
				
			||||||
 | 
					                    value = currentUser to stateUsername
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                addSource(state.getLiveData<String?>("username")) { username ->
 | 
				
			||||||
 | 
					                    this.stateUsername = Resource.success(username)
 | 
				
			||||||
 | 
					                    value = user to this.stateUsername
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                // trigger currentUserAndStateUsernameLiveData switch map with a state username success resource
 | 
				
			||||||
 | 
					                if (!state.contains("username")) {
 | 
				
			||||||
 | 
					                    this.stateUsername = Resource.success(null)
 | 
				
			||||||
 | 
					                    value = user to this.stateUsername
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    val profile: LiveData<Resource<User?>> = currentUserAndStateUsernameLiveData.switchMap {
 | 
				
			||||||
 | 
					        val (userResource, stateUsernameResource) = it
 | 
				
			||||||
 | 
					        liveData<Resource<User?>>(context = viewModelScope.coroutineContext + ioDispatcher) {
 | 
				
			||||||
 | 
					            if (userResource.status == Resource.Status.LOADING || stateUsernameResource.status == Resource.Status.LOADING) {
 | 
				
			||||||
 | 
					                emit(Resource.loading(null))
 | 
				
			||||||
 | 
					                return@liveData
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            val user = userResource.data
 | 
				
			||||||
 | 
					            val stateUsername = stateUsernameResource.data
 | 
				
			||||||
 | 
					            if (stateUsername.isNullOrBlank()) {
 | 
				
			||||||
 | 
					                emit(Resource.success(user))
 | 
				
			||||||
 | 
					                return@liveData
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                val fetchedUser = if (user != null) {
 | 
				
			||||||
 | 
					                    userRepository.getUsernameInfo(stateUsername) // logged in
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    graphQLRepository.fetchUser(stateUsername) // anonymous
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                emit(Resource.success(fetchedUser))
 | 
				
			||||||
 | 
					            } catch (e: Exception) {
 | 
				
			||||||
 | 
					                emit(Resource.error(e.message, null))
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Username of profile without '`@`'
 | 
					     * Username of profile without '`@`'
 | 
				
			||||||
@ -37,30 +87,12 @@ class ProfileFragmentViewModel(
 | 
				
			|||||||
            Resource.Status.SUCCESS -> it.data?.username ?: ""
 | 
					            Resource.Status.SUCCESS -> it.data?.username ?: ""
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    val isLoggedIn: LiveData<Boolean> = _isLoggedIn
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    var currentUser: Resource<User?>? = null
 | 
					 | 
				
			||||||
        set(value) {
 | 
					 | 
				
			||||||
            _isLoggedIn.postValue(value?.data != null)
 | 
					 | 
				
			||||||
            // if no profile, and value is valid, set it as profile
 | 
					 | 
				
			||||||
            val profileValue = profile.value
 | 
					 | 
				
			||||||
            if (
 | 
					 | 
				
			||||||
                profileValue?.status != Resource.Status.LOADING
 | 
					 | 
				
			||||||
                && profileValue?.data == null
 | 
					 | 
				
			||||||
                && value?.status == Resource.Status.SUCCESS
 | 
					 | 
				
			||||||
                && value.data != null
 | 
					 | 
				
			||||||
            ) {
 | 
					 | 
				
			||||||
                _profile.postValue(Resource.success(value.data))
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            field = value
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    init {
 | 
					    init {
 | 
				
			||||||
        // Log.d(TAG, "${state.keys()} $userRepository $friendshipRepository $storiesRepository $mediaRepository")
 | 
					        // Log.d(TAG, "${state.keys()} $userRepository $friendshipRepository $storiesRepository $mediaRepository")
 | 
				
			||||||
        val usernameFromState = state.get<String?>("username")
 | 
					    }
 | 
				
			||||||
        if (usernameFromState.isNullOrBlank()) {
 | 
					
 | 
				
			||||||
            _profile.postValue(Resource.success(null))
 | 
					    fun setCurrentUser(currentUser: Resource<User?>) {
 | 
				
			||||||
        }
 | 
					        _currentUser.postValue(currentUser)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fun shareDm(result: RankedRecipient) {
 | 
					    fun shareDm(result: RankedRecipient) {
 | 
				
			||||||
@ -104,6 +136,7 @@ class ProfileFragmentViewModelFactory(
 | 
				
			|||||||
            graphQLRepository,
 | 
					            graphQLRepository,
 | 
				
			||||||
            accountRepository,
 | 
					            accountRepository,
 | 
				
			||||||
            favoriteRepository,
 | 
					            favoriteRepository,
 | 
				
			||||||
 | 
					            Dispatchers.IO,
 | 
				
			||||||
        ) as T
 | 
					        ) as T
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -12,7 +12,7 @@ import org.json.JSONObject
 | 
				
			|||||||
import java.util.*
 | 
					import java.util.*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class GraphQLRepository(private val service: GraphQLService) {
 | 
					open class GraphQLRepository(private val service: GraphQLService) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // TODO convert string response to a response class
 | 
					    // TODO convert string response to a response class
 | 
				
			||||||
    private suspend fun fetch(
 | 
					    private suspend fun fetch(
 | 
				
			||||||
@ -176,7 +176,7 @@ class GraphQLRepository(private val service: GraphQLService) {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // TODO convert string response to a response class
 | 
					    // TODO convert string response to a response class
 | 
				
			||||||
    suspend fun fetchUser(
 | 
					    open suspend fun fetchUser(
 | 
				
			||||||
        username: String,
 | 
					        username: String,
 | 
				
			||||||
    ): User {
 | 
					    ): User {
 | 
				
			||||||
        val response = service.getUser(username)
 | 
					        val response = service.getUser(username)
 | 
				
			||||||
 | 
				
			|||||||
@ -0,0 +1,84 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (C) 2019 Google LLC
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * 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
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *      http://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 awais.instagrabber
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import kotlinx.coroutines.Dispatchers
 | 
				
			||||||
 | 
					import kotlinx.coroutines.ExperimentalCoroutinesApi
 | 
				
			||||||
 | 
					import kotlinx.coroutines.test.TestCoroutineDispatcher
 | 
				
			||||||
 | 
					import kotlinx.coroutines.test.TestCoroutineScope
 | 
				
			||||||
 | 
					import kotlinx.coroutines.test.resetMain
 | 
				
			||||||
 | 
					import kotlinx.coroutines.test.setMain
 | 
				
			||||||
 | 
					import org.junit.rules.TestWatcher
 | 
				
			||||||
 | 
					import org.junit.runner.Description
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * MainCoroutineRule installs a TestCoroutineDispatcher for Disptachers.Main.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Since it extends TestCoroutineScope, you can directly launch coroutines on the MainCoroutineRule
 | 
				
			||||||
 | 
					 * as a [CoroutineScope]:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * ```
 | 
				
			||||||
 | 
					 * mainCoroutineRule.launch { aTestCoroutine() }
 | 
				
			||||||
 | 
					 * ```
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * All coroutines started on [MainCoroutineScopeRule] must complete (including timeouts) before the test
 | 
				
			||||||
 | 
					 * finishes, or it will throw an exception.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * When using MainCoroutineRule you should always invoke runBlockingTest on it to avoid creating two
 | 
				
			||||||
 | 
					 * instances of [TestCoroutineDispatcher] or [TestCoroutineScope] in your test:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * ```
 | 
				
			||||||
 | 
					 * @Test
 | 
				
			||||||
 | 
					 * fun usingRunBlockingTest() = mainCoroutineRule.runBlockingTest {
 | 
				
			||||||
 | 
					 *     aTestCoroutine()
 | 
				
			||||||
 | 
					 * }
 | 
				
			||||||
 | 
					 * ```
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You may call [DelayController] methods on [MainCoroutineScopeRule] and they will control the
 | 
				
			||||||
 | 
					 * virtual-clock.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * ```
 | 
				
			||||||
 | 
					 * mainCoroutineRule.pauseDispatcher()
 | 
				
			||||||
 | 
					 * // do some coroutines
 | 
				
			||||||
 | 
					 * mainCoroutineRule.advanceUntilIdle() // run all pending coroutines until the dispatcher is idle
 | 
				
			||||||
 | 
					 * ```
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * By default, [MainCoroutineScopeRule] will be in a *resumed* state.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @param dispatcher if provided, this [TestCoroutineDispatcher] will be used.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					@ExperimentalCoroutinesApi
 | 
				
			||||||
 | 
					class MainCoroutineScopeRule(val dispatcher: TestCoroutineDispatcher = TestCoroutineDispatcher()) :
 | 
				
			||||||
 | 
					    TestWatcher(),
 | 
				
			||||||
 | 
					    TestCoroutineScope by TestCoroutineScope(dispatcher) {
 | 
				
			||||||
 | 
					    override fun starting(description: Description?) {
 | 
				
			||||||
 | 
					        super.starting(description)
 | 
				
			||||||
 | 
					        // If your codebase allows the injection of other dispatchers like
 | 
				
			||||||
 | 
					        // Dispatchers.Default and Dispatchers.IO, consider injecting all of them here
 | 
				
			||||||
 | 
					        // and renaming this class to `CoroutineScopeRule`
 | 
				
			||||||
 | 
					        //
 | 
				
			||||||
 | 
					        // All injected dispatchers in a test should point to a single instance of
 | 
				
			||||||
 | 
					        // TestCoroutineDispatcher.
 | 
				
			||||||
 | 
					        Dispatchers.setMain(dispatcher)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun finished(description: Description?) {
 | 
				
			||||||
 | 
					        super.finished(description)
 | 
				
			||||||
 | 
					        cleanupTestCoroutines()
 | 
				
			||||||
 | 
					        Dispatchers.resetMain()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -3,6 +3,7 @@ package awais.instagrabber.viewmodels
 | 
				
			|||||||
import androidx.arch.core.executor.testing.InstantTaskExecutorRule
 | 
					import androidx.arch.core.executor.testing.InstantTaskExecutorRule
 | 
				
			||||||
import androidx.lifecycle.SavedStateHandle
 | 
					import androidx.lifecycle.SavedStateHandle
 | 
				
			||||||
import androidx.test.ext.junit.runners.AndroidJUnit4
 | 
					import androidx.test.ext.junit.runners.AndroidJUnit4
 | 
				
			||||||
 | 
					import awais.instagrabber.MainCoroutineScopeRule
 | 
				
			||||||
import awais.instagrabber.common.*
 | 
					import awais.instagrabber.common.*
 | 
				
			||||||
import awais.instagrabber.db.datasources.AccountDataSource
 | 
					import awais.instagrabber.db.datasources.AccountDataSource
 | 
				
			||||||
import awais.instagrabber.db.datasources.FavoriteDataSource
 | 
					import awais.instagrabber.db.datasources.FavoriteDataSource
 | 
				
			||||||
@ -12,6 +13,7 @@ import awais.instagrabber.getOrAwaitValue
 | 
				
			|||||||
import awais.instagrabber.models.Resource
 | 
					import awais.instagrabber.models.Resource
 | 
				
			||||||
import awais.instagrabber.repositories.responses.User
 | 
					import awais.instagrabber.repositories.responses.User
 | 
				
			||||||
import awais.instagrabber.webservices.*
 | 
					import awais.instagrabber.webservices.*
 | 
				
			||||||
 | 
					import kotlinx.coroutines.ExperimentalCoroutinesApi
 | 
				
			||||||
import org.junit.Rule
 | 
					import org.junit.Rule
 | 
				
			||||||
import org.junit.Test
 | 
					import org.junit.Test
 | 
				
			||||||
import org.junit.jupiter.api.Assertions.assertEquals
 | 
					import org.junit.jupiter.api.Assertions.assertEquals
 | 
				
			||||||
@ -21,12 +23,22 @@ import org.junit.runner.RunWith
 | 
				
			|||||||
@RunWith(AndroidJUnit4::class)
 | 
					@RunWith(AndroidJUnit4::class)
 | 
				
			||||||
internal class ProfileFragmentViewModelTest {
 | 
					internal class ProfileFragmentViewModelTest {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private val testPublicUser = User(
 | 
				
			||||||
 | 
					        pk = 100,
 | 
				
			||||||
 | 
					        username = "test",
 | 
				
			||||||
 | 
					        fullName = "Test user"
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @get:Rule
 | 
					    @get:Rule
 | 
				
			||||||
    var instantExecutorRule = InstantTaskExecutorRule()
 | 
					    var instantExecutorRule = InstantTaskExecutorRule()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @ExperimentalCoroutinesApi
 | 
				
			||||||
 | 
					    @get:Rule
 | 
				
			||||||
 | 
					    val coroutineScope = MainCoroutineScopeRule()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @ExperimentalCoroutinesApi
 | 
				
			||||||
    @Test
 | 
					    @Test
 | 
				
			||||||
    fun testNoUsernameNoCurrentUser() {
 | 
					    fun testNoUsernameNoCurrentUser() {
 | 
				
			||||||
        val accountDataSource = AccountDataSource(AccountDaoAdapter())
 | 
					 | 
				
			||||||
        val viewModel = ProfileFragmentViewModel(
 | 
					        val viewModel = ProfileFragmentViewModel(
 | 
				
			||||||
            SavedStateHandle(),
 | 
					            SavedStateHandle(),
 | 
				
			||||||
            UserRepository(UserServiceAdapter()),
 | 
					            UserRepository(UserServiceAdapter()),
 | 
				
			||||||
@ -34,46 +46,75 @@ internal class ProfileFragmentViewModelTest {
 | 
				
			|||||||
            StoriesRepository(StoriesServiceAdapter()),
 | 
					            StoriesRepository(StoriesServiceAdapter()),
 | 
				
			||||||
            MediaRepository(MediaServiceAdapter()),
 | 
					            MediaRepository(MediaServiceAdapter()),
 | 
				
			||||||
            GraphQLRepository(GraphQLServiceAdapter()),
 | 
					            GraphQLRepository(GraphQLServiceAdapter()),
 | 
				
			||||||
            AccountRepository(accountDataSource),
 | 
					            AccountRepository(AccountDataSource(AccountDaoAdapter())),
 | 
				
			||||||
            FavoriteRepository(FavoriteDataSource(FavoriteDaoAdapter()))
 | 
					            FavoriteRepository(FavoriteDataSource(FavoriteDaoAdapter())),
 | 
				
			||||||
 | 
					            coroutineScope.dispatcher,
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        assertEquals(false, viewModel.isLoggedIn.getOrAwaitValue())
 | 
					        assertEquals(false, viewModel.isLoggedIn.getOrAwaitValue())
 | 
				
			||||||
 | 
					        viewModel.setCurrentUser(Resource.success(null))
 | 
				
			||||||
        assertNull(viewModel.profile.getOrAwaitValue().data)
 | 
					        assertNull(viewModel.profile.getOrAwaitValue().data)
 | 
				
			||||||
        assertEquals("", viewModel.username.getOrAwaitValue())
 | 
					        assertEquals("", viewModel.username.getOrAwaitValue())
 | 
				
			||||||
        viewModel.currentUser = Resource.success(null)
 | 
					        viewModel.setCurrentUser(Resource.success(null))
 | 
				
			||||||
        assertEquals(false, viewModel.isLoggedIn.getOrAwaitValue())
 | 
					        assertEquals(false, viewModel.isLoggedIn.getOrAwaitValue())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @ExperimentalCoroutinesApi
 | 
				
			||||||
    @Test
 | 
					    @Test
 | 
				
			||||||
    fun testNoUsernameWithCurrentUser() {
 | 
					    fun testNoUsernameWithCurrentUser() {
 | 
				
			||||||
        // val state = SavedStateHandle(
 | 
					 | 
				
			||||||
        //     mutableMapOf<String, Any?>(
 | 
					 | 
				
			||||||
        //         "username" to "test"
 | 
					 | 
				
			||||||
        //     )
 | 
					 | 
				
			||||||
        // )
 | 
					 | 
				
			||||||
        val userRepository = UserRepository(UserServiceAdapter())
 | 
					 | 
				
			||||||
        val friendshipRepository = FriendshipRepository(FriendshipServiceAdapter())
 | 
					 | 
				
			||||||
        val storiesRepository = StoriesRepository(StoriesServiceAdapter())
 | 
					 | 
				
			||||||
        val mediaRepository = MediaRepository(MediaServiceAdapter())
 | 
					 | 
				
			||||||
        val graphQLRepository = GraphQLRepository(GraphQLServiceAdapter())
 | 
					 | 
				
			||||||
        val accountDataSource = AccountDataSource(AccountDaoAdapter())
 | 
					 | 
				
			||||||
        val accountRepository = AccountRepository(accountDataSource)
 | 
					 | 
				
			||||||
        val favoriteRepository = FavoriteRepository(FavoriteDataSource(FavoriteDaoAdapter()))
 | 
					 | 
				
			||||||
        val viewModel = ProfileFragmentViewModel(
 | 
					        val viewModel = ProfileFragmentViewModel(
 | 
				
			||||||
            SavedStateHandle(),
 | 
					            SavedStateHandle(),
 | 
				
			||||||
            userRepository,
 | 
					            UserRepository(UserServiceAdapter()),
 | 
				
			||||||
            friendshipRepository,
 | 
					            FriendshipRepository(FriendshipServiceAdapter()),
 | 
				
			||||||
            storiesRepository,
 | 
					            StoriesRepository(StoriesServiceAdapter()),
 | 
				
			||||||
            mediaRepository,
 | 
					            MediaRepository(MediaServiceAdapter()),
 | 
				
			||||||
            graphQLRepository,
 | 
					            GraphQLRepository(GraphQLServiceAdapter()),
 | 
				
			||||||
            accountRepository,
 | 
					            AccountRepository(AccountDataSource(AccountDaoAdapter())),
 | 
				
			||||||
            favoriteRepository
 | 
					            FavoriteRepository(FavoriteDataSource(FavoriteDaoAdapter())),
 | 
				
			||||||
 | 
					            coroutineScope.dispatcher,
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        assertEquals(false, viewModel.isLoggedIn.getOrAwaitValue())
 | 
					        assertEquals(false, viewModel.isLoggedIn.getOrAwaitValue())
 | 
				
			||||||
        assertNull(viewModel.profile.getOrAwaitValue().data)
 | 
					        assertNull(viewModel.profile.getOrAwaitValue().data)
 | 
				
			||||||
        val user = User()
 | 
					        val user = User()
 | 
				
			||||||
        viewModel.currentUser = Resource.success(user)
 | 
					        viewModel.setCurrentUser(Resource.success(user))
 | 
				
			||||||
        assertEquals(true, viewModel.isLoggedIn.getOrAwaitValue())
 | 
					        assertEquals(true, viewModel.isLoggedIn.getOrAwaitValue())
 | 
				
			||||||
        assertEquals(user, viewModel.profile.getOrAwaitValue().data)
 | 
					        var profile = viewModel.profile.getOrAwaitValue()
 | 
				
			||||||
 | 
					        while (profile.status == Resource.Status.LOADING) {
 | 
				
			||||||
 | 
					            profile = viewModel.profile.getOrAwaitValue()
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        assertEquals(user, profile.data)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @ExperimentalCoroutinesApi
 | 
				
			||||||
 | 
					    @Test
 | 
				
			||||||
 | 
					    fun testPublicUsernameWithNoCurrentUser() {
 | 
				
			||||||
 | 
					        // username without `@`
 | 
				
			||||||
 | 
					        val state = SavedStateHandle(
 | 
				
			||||||
 | 
					            mutableMapOf<String, Any?>(
 | 
				
			||||||
 | 
					                "username" to testPublicUser.username
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        val graphQLRepository = object : GraphQLRepository(GraphQLServiceAdapter()) {
 | 
				
			||||||
 | 
					            override suspend fun fetchUser(username: String): User {
 | 
				
			||||||
 | 
					                return testPublicUser
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        val viewModel = ProfileFragmentViewModel(
 | 
				
			||||||
 | 
					            state,
 | 
				
			||||||
 | 
					            UserRepository(UserServiceAdapter()),
 | 
				
			||||||
 | 
					            FriendshipRepository(FriendshipServiceAdapter()),
 | 
				
			||||||
 | 
					            StoriesRepository(StoriesServiceAdapter()),
 | 
				
			||||||
 | 
					            MediaRepository(MediaServiceAdapter()),
 | 
				
			||||||
 | 
					            graphQLRepository,
 | 
				
			||||||
 | 
					            AccountRepository(AccountDataSource(AccountDaoAdapter())),
 | 
				
			||||||
 | 
					            FavoriteRepository(FavoriteDataSource(FavoriteDaoAdapter())),
 | 
				
			||||||
 | 
					            coroutineScope.dispatcher,
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        viewModel.setCurrentUser(Resource.success(null))
 | 
				
			||||||
 | 
					        assertEquals(false, viewModel.isLoggedIn.getOrAwaitValue())
 | 
				
			||||||
 | 
					        var profile = viewModel.profile.getOrAwaitValue()
 | 
				
			||||||
 | 
					        while (profile.status == Resource.Status.LOADING) {
 | 
				
			||||||
 | 
					            profile = viewModel.profile.getOrAwaitValue()
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        assertEquals(testPublicUser, profile.data)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user