Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
677f084
Refactor: extract filtering component
Autek Dec 11, 2024
2687c15
Fix/Feat: UI fix and added filtering tabs to SearchOnBoarding.kt
Autek Dec 12, 2024
7fa722a
Merge remote-tracking branch 'origin' into feature/quickFixFinder-scr…
Autek Dec 12, 2024
897ce03
Feat: all the UI implemented in the QuickFixFinder.kt screen
Autek Dec 12, 2024
2272ac7
Style: package directives updated in search package and cleanup
Autek Dec 12, 2024
0c57667
Fix: adapt tests to work with refactored SearchWorkerResult.kt
Autek Dec 13, 2024
88546c7
Merge remote-tracking branch 'origin' into feature/quickFixFinder-scr…
Autek Dec 13, 2024
f437f78
Fix: update of tests to match refactoring of SearchWorkerResult.kt
Autek Dec 14, 2024
ab48b64
Test: add tests to reach 80% coverage
Autek Dec 14, 2024
42e7825
Merge remote-tracking branch 'origin' into feature/quickFixFinder-scr…
Autek Dec 14, 2024
de5971d
Style: cleanup
Autek Dec 14, 2024
513da1f
Test: add tests for coverage
Autek Dec 14, 2024
9ac23d0
Merge remote-tracking branch 'origin' into feature/quickFixFinder-scr…
Autek Dec 18, 2024
761f367
Merge: merge finished and tests compiling
Autek Dec 19, 2024
1c03423
Fix: update tests for two files.
Autek Dec 19, 2024
5e5ba70
Fix: all tests fixed and passing
Autek Dec 19, 2024
4d07d58
Fix: most tests passing
Autek Dec 19, 2024
27cbb35
Fix: all tests passing
Autek Dec 20, 2024
f6471d9
Merge remote-tracking branch 'origin' into feature/quickFixFinder-scr…
Autek Dec 20, 2024
f6ff04a
Fix: implemented requested changes in PR review
Autek Dec 20, 2024
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
Original file line number Diff line number Diff line change
@@ -1,148 +1,116 @@
package com.arygm.quickfix.ui.search

import android.graphics.Bitmap
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.unit.dp
import com.arygm.quickfix.model.account.Account
import com.arygm.quickfix.model.account.AccountRepositoryFirestore
import com.arygm.quickfix.model.account.AccountViewModel
import com.arygm.quickfix.model.category.CategoryRepositoryFirestore
import com.arygm.quickfix.model.category.CategoryViewModel
import com.arygm.quickfix.model.profile.ProfileRepository
import com.arygm.quickfix.model.profile.ProfileViewModel
import com.arygm.quickfix.model.locations.Location
import com.arygm.quickfix.model.profile.WorkerProfile
import com.arygm.quickfix.model.profile.WorkerProfileRepositoryFirestore
import com.arygm.quickfix.model.search.SearchViewModel
import com.arygm.quickfix.ui.navigation.NavigationActions
import com.arygm.quickfix.ui.uiMode.appContentUI.userModeUI.search.ProfileResults
import com.google.firebase.Timestamp
import io.mockk.every
import io.mockk.invoke
import io.mockk.mockk
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.mockito.Mockito.mock

class ProfileResultsTest {

private lateinit var navigationActions: NavigationActions
private lateinit var workerProfileRepo: WorkerProfileRepositoryFirestore
private lateinit var accountRepositoryFirestore: AccountRepositoryFirestore
private lateinit var categoryRepo: CategoryRepositoryFirestore
private lateinit var searchViewModel: SearchViewModel
private lateinit var accountViewModel: AccountViewModel
private lateinit var categoryViewModel: CategoryViewModel
private lateinit var navigationActionsRoot: NavigationActions
private lateinit var workerRepository: ProfileRepository
private lateinit var workerViewModel: ProfileViewModel

@get:Rule val composeTestRule = createComposeRule()

private lateinit var accountViewModel: AccountViewModel
private lateinit var searchViewModel: SearchViewModel

@Before
fun setup() {
navigationActions = mock(NavigationActions::class.java)
navigationActionsRoot = mock(NavigationActions::class.java)
workerProfileRepo = mockk(relaxed = true)
categoryRepo = mockk(relaxed = true)
accountRepositoryFirestore = mock(AccountRepositoryFirestore::class.java)
searchViewModel = SearchViewModel(workerProfileRepo)
categoryViewModel = CategoryViewModel(categoryRepo)
accountViewModel = mockk(relaxed = true)
searchViewModel = mockk(relaxed = true)

workerViewModel = mockk(relaxed = true)

// Mock fetchProfileImageAsBitmap
every { workerViewModel.fetchProfileImageAsBitmap(any(), any(), any()) } answers
{
val onSuccess = arg<(Bitmap) -> Unit>(1)
// Provide a dummy bitmap here (e.g. a solid color bitmap or decode from resources)
val dummyBitmap = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888)
onSuccess(dummyBitmap) // Simulate success callback
}

// Mock fetchBannerImageAsBitmap
every { workerViewModel.fetchBannerImageAsBitmap(any(), any(), any()) } answers
{
val onSuccess = arg<(Bitmap) -> Unit>(1)
// Provide another dummy bitmap
val dummyBitmap = Bitmap.createBitmap(20, 20, Bitmap.Config.ARGB_8888)
onSuccess(dummyBitmap) // Simulate success callback
}
}
// Mock calculateDistance to return a fixed distance
every { searchViewModel.calculateDistance(any(), any(), any(), any()) } returns 10.0

@Test
fun profileContent_displaysWorkerProfiles() {
// Set up test data
val testProfiles =
listOf(
WorkerProfile(
uid = "worker0",
fieldOfWork = "Plumbing",
rating = 3.5,
reviews = ArrayDeque(),
location = null, // Simplify for the test
price = 49.0,
),
WorkerProfile(
uid = "worker1",
fieldOfWork = "Electrical",
rating = 3.0,
reviews = ArrayDeque(),
location = null,
price = 59.0,
))

// Mock the AccountViewModel to return sample account data
// Mock AccountViewModel fetchUserAccount
every { accountViewModel.fetchUserAccount(any(), captureLambda()) } answers
{
val uid = firstArg<String>()
Comment on lines -77 to 40
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why was this test removed ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this test was not removed but updated to match the update of the ProfileResults composable. It was replaced by a new test that is testing exactly the same thing

val account =
val lambda = secondArg<(Account?) -> Unit>()
lambda(
when (uid) {
"worker0" ->
Account(
uid = "worker0",
firstName = "John",
lastName = "Doe",
email = "",
Timestamp.now())
birthDate = Timestamp.now())
"worker1" ->
Account(
uid = "worker1",
firstName = "Jane",
lastName = "Smith",
email = "",
Timestamp.now())
birthDate = Timestamp.now())
else -> null
}
lambda<(Account?) -> Unit>().invoke(account)
})
}
}

@Test
fun profileResults_displaysWorkerProfiles_correctly() {
// Test data: profiles, images, and location
val testProfiles =
listOf(
WorkerProfile(
uid = "worker0",
displayName = "John Doe",
fieldOfWork = "Plumbing",
reviews = ArrayDeque(listOf()),
location = Location(40.0, 70.0),
price = 49.0),
WorkerProfile(
uid = "worker1",
displayName = "Jane Smith",
fieldOfWork = "Electrical",
reviews = ArrayDeque(listOf()),
location = Location(41.0, 71.0),
price = 59.0))

val dummyBitmap = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888)
val profileImagesMap = mapOf("worker0" to dummyBitmap, "worker1" to dummyBitmap)
val bannerImagesMap = mapOf("worker0" to dummyBitmap, "worker1" to dummyBitmap)
val baseLocation = Location(0.0, 0.0)

// Set the content with ProfileContent composable
// Set the ProfileResults composable
composeTestRule.setContent {
ProfileResults(
profiles = testProfiles,
listState = rememberLazyListState(),
searchViewModel = searchViewModel,
accountViewModel = accountViewModel,
heightRatio = 1.0f,
workerViewModel = workerViewModel,
onBookClick = { _, _ -> })
onBookClick = { _, _, _, _ -> },
profileImagesMap = profileImagesMap,
bannerImagesMap = bannerImagesMap,
baseLocation = baseLocation,
screenHeight = 1000.dp)
}

// Allow coroutines to complete
composeTestRule.waitForIdle()

// Verify that the profile items are displayed correctly
composeTestRule.onNodeWithTag("worker_profile_result_0").assertIsDisplayed()
// Verify first profile
composeTestRule.onNodeWithTag("worker_profile_result0").assertIsDisplayed()
composeTestRule.onNodeWithText("John Doe").assertIsDisplayed()
composeTestRule.onNodeWithText("Plumbing").assertIsDisplayed()
composeTestRule.onNodeWithText("49.0").assertIsDisplayed()

composeTestRule.onNodeWithTag("worker_profile_result_1").assertIsDisplayed()
// Verify second profile
composeTestRule.onNodeWithTag("worker_profile_result1").assertIsDisplayed()
composeTestRule.onNodeWithText("Jane Smith").assertIsDisplayed()
composeTestRule.onNodeWithText("Electrical").assertIsDisplayed()
composeTestRule.onNodeWithText("59.0").assertIsDisplayed()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,20 @@ import androidx.datastore.preferences.core.Preferences
import com.arygm.quickfix.model.account.AccountViewModel
import com.arygm.quickfix.model.category.CategoryRepositoryFirestore
import com.arygm.quickfix.model.category.CategoryViewModel
import com.arygm.quickfix.model.locations.Location
import com.arygm.quickfix.model.offline.small.PreferencesRepository
import com.arygm.quickfix.model.offline.small.PreferencesViewModel
import com.arygm.quickfix.model.profile.Profile
import com.arygm.quickfix.model.profile.ProfileRepository
import com.arygm.quickfix.model.profile.ProfileViewModel
import com.arygm.quickfix.model.profile.UserProfile
import com.arygm.quickfix.model.profile.WorkerProfileRepositoryFirestore
import com.arygm.quickfix.model.quickfix.QuickFixViewModel
import com.arygm.quickfix.model.search.AnnouncementRepository
import com.arygm.quickfix.model.search.AnnouncementViewModel
import com.arygm.quickfix.model.search.SearchViewModel
import com.arygm.quickfix.ui.navigation.NavigationActions
import com.arygm.quickfix.ui.uiMode.appContentUI.userModeUI.search.QuickFixFinderScreen
import io.mockk.mockk
import kotlinx.coroutines.flow.MutableStateFlow
import org.junit.Before
Expand All @@ -37,6 +41,7 @@ class QuickFixFinderScreenTest {
private lateinit var profileViewModel: ProfileViewModel
private lateinit var announcementViewModel: AnnouncementViewModel
private lateinit var workerProfileRepo: WorkerProfileRepositoryFirestore
private lateinit var userProfileRepositoryFirestore: ProfileRepository
private lateinit var categoryRepo: CategoryRepositoryFirestore
private lateinit var searchViewModel: SearchViewModel
private lateinit var accountViewModel: AccountViewModel
Expand All @@ -51,6 +56,8 @@ class QuickFixFinderScreenTest {
navigationActions = mock(NavigationActions::class.java)
navigationActionsRoot = mock(NavigationActions::class.java)

userProfileRepositoryFirestore = mock(ProfileRepository::class.java)

preferencesRepository = mock(PreferencesRepository::class.java)
announcementRepository = mock(AnnouncementRepository::class.java)
userProfileRepository = mock(ProfileRepository::class.java)
Expand All @@ -64,7 +71,26 @@ class QuickFixFinderScreenTest {
announcementViewModel =
AnnouncementViewModel(announcementRepository, preferencesRepository, userProfileRepository)

profileViewModel = mock(ProfileViewModel::class.java)
org.mockito.kotlin
.doAnswer { invocation ->
val uid = invocation.arguments[0] as String
val onSuccess = invocation.arguments[1] as (Profile?) -> Unit
val onFailure = invocation.arguments[2] as (Exception) -> Unit

// Return a user profile with a "Home" location
val testUserProfile =
UserProfile(
locations = listOf(Location(latitude = 40.0, longitude = -74.0, name = "Home")),
announcements = emptyList(),
uid = uid)
onSuccess(testUserProfile)
null
}
.`when`(userProfileRepositoryFirestore)
.getProfileById(anyString(), org.mockito.kotlin.any(), org.mockito.kotlin.any())

profileViewModel = ProfileViewModel(userProfileRepositoryFirestore)
workerViewModel = mockk(relaxed = true)

workerProfileRepo = mockk(relaxed = true)
categoryRepo = mockk(relaxed = true)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package com.arygm.quickfix.ui.search

import android.graphics.Bitmap
import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.unit.dp
import com.arygm.quickfix.R
import com.arygm.quickfix.ui.uiMode.appContentUI.userModeUI.search.QuickFixSlidingWindowWorker
import org.junit.Rule
import org.junit.Test
Expand Down Expand Up @@ -37,11 +37,11 @@ class QuickFixSlidingWindowWorkerTest {
QuickFixSlidingWindowWorker(
isVisible = true,
onDismiss = { /* No-op */},
bannerImage = R.drawable.moroccan_flag,
profilePicture = R.drawable.placeholder_worker,
bannerImage = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888),
profilePicture = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888),
initialSaved = false,
workerCategory = "Painter",
workerAddress = "123 Main Street",
selectedCityName = "123 Main Street",
description = "Sample description for the worker.",
includedServices = includedServices,
addonServices = addonServices,
Expand Down Expand Up @@ -92,11 +92,11 @@ class QuickFixSlidingWindowWorkerTest {
QuickFixSlidingWindowWorker(
isVisible = true,
onDismiss = { /* No-op */},
bannerImage = R.drawable.moroccan_flag,
profilePicture = R.drawable.placeholder_worker,
bannerImage = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888),
profilePicture = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888),
initialSaved = false,
workerCategory = "Painter",
workerAddress = "123 Main Street",
selectedCityName = "123 Main Street",
description = "Sample description for the worker.",
includedServices = includedServices,
addonServices = addOnServices,
Expand Down Expand Up @@ -155,11 +155,11 @@ class QuickFixSlidingWindowWorkerTest {
QuickFixSlidingWindowWorker(
isVisible = true,
onDismiss = { /* No-op */},
bannerImage = R.drawable.moroccan_flag,
profilePicture = R.drawable.placeholder_worker,
bannerImage = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888),
profilePicture = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888),
initialSaved = false,
workerCategory = "Painter",
workerAddress = "123 Main Street",
selectedCityName = "123 Main Street",
description = "Sample description for the worker.",
includedServices = includedServices,
addonServices = addOnServices,
Expand Down
Loading
Loading