Skip to content

Commit

Permalink
chore: merge with main
Browse files Browse the repository at this point in the history
  • Loading branch information
ortolino committed May 29, 2024
2 parents a94f7bc + 2ab708c commit 7fca325
Show file tree
Hide file tree
Showing 27 changed files with 597 additions and 210 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -295,16 +295,17 @@ class EditReceiptScreenTest : TestCase(kaspressoBuilder = Kaspresso.Builder.with
every { UUID.randomUUID() } returns UUID.fromString("08a11dc8-975c-4da1-93a6-865c20c7adec")
}

private val viewModel =
ReceiptViewModel(
receiptUid = "08a11dc8-975c-4da1-93a6-865c20c7adec",
navActions = navActions,
receiptApi = receiptsAPI)
lateinit var viewModel: ReceiptViewModel

@Before
fun testSetup() {
CurrentUser.userUid = "testUser"
CurrentUser.associationUid = "testUser"
viewModel =
ReceiptViewModel(
receiptUid = "08a11dc8-975c-4da1-93a6-865c20c7adec",
navActions = navActions,
receiptApi = receiptsAPI)
composeTestRule.setContent { ReceiptScreen(viewModel = viewModel) }
}

Expand Down Expand Up @@ -337,4 +338,17 @@ class EditReceiptScreenTest : TestCase(kaspressoBuilder = Kaspresso.Builder.with
onNodeWithTag("errorMessage").assertIsDisplayed().assertTextContains("Error loading receipt")
}
}

@Test
fun receiptDeleteFail() {
every { receiptsAPI.deleteReceipt(any(), any(), any()) } answers
{
thirdArg<(Exception) -> Unit>().invoke(Exception("error"))
}
with(composeTestRule) {
onNodeWithTag("deleteButton").performScrollTo().performClick()
onNodeWithText("Failed to delete receipt", true).assertIsDisplayed()
onNodeWithText("Retry", true).performClick()
}
}
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,26 @@
package com.github.se.assocify.screens.profile

import androidx.compose.ui.test.assertCountEquals
import androidx.compose.ui.test.assertHasClickAction
import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onAllNodesWithTag
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.github.se.assocify.model.CurrentUser
import com.github.se.assocify.model.database.EventAPI
import com.github.se.assocify.model.entities.Event
import com.github.se.assocify.navigation.NavigationActions
import com.github.se.assocify.ui.screens.profile.events.ProfileEventsScreen
import com.github.se.assocify.ui.screens.profile.events.ProfileEventsViewModel
import com.kaspersky.components.composesupport.config.withComposeSupport
import com.kaspersky.kaspresso.kaspresso.Kaspresso
import com.kaspersky.kaspresso.testcases.api.testcase.TestCase
import io.mockk.every
import io.mockk.mockk
import java.time.OffsetDateTime
import org.junit.Before
import org.junit.Rule
import org.junit.Test
Expand All @@ -26,19 +34,41 @@ class ProfileEventsScreenTest :
private val navActions = mockk<NavigationActions>()
private var goBack = false

private val events =
listOf(
Event("1", "event1", "desc1", OffsetDateTime.MIN, OffsetDateTime.MAX, "", ""),
Event("2", "event2", "desc2", OffsetDateTime.MIN, OffsetDateTime.MAX, "", ""))

private val mockEventAPI =
mockk<EventAPI> {
every { getEvents(any(), any()) } answers
{
val onSuccess = firstArg<(List<Event>) -> Unit>()
onSuccess(events)
}
}

@Before
fun testSetup() {
CurrentUser.userUid = "1"
CurrentUser.associationUid = "asso"

every { navActions.back() } answers { goBack = true }

composeTestRule.setContent { ProfileEventsScreen(navActions = navActions) }
composeTestRule.setContent {
ProfileEventsScreen(navActions = navActions, ProfileEventsViewModel(mockEventAPI, navActions))
}
}

@Test
fun display() {
with(composeTestRule) { onNodeWithTag("ProfileEvents Screen").assertIsDisplayed() }
with(composeTestRule) {
onNodeWithTag("ProfileEvents Screen").assertIsDisplayed()
onNodeWithTag("addEventButton").assertIsDisplayed().assertHasClickAction()
events.forEach { onNodeWithText(it.name).assertIsDisplayed() }
onAllNodesWithTag("editEventButton").assertCountEquals(events.size)
onAllNodesWithTag("deleteEventButton").assertCountEquals(events.size)
}
}

@Test
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,33 @@
package com.github.se.assocify.screens.profile

import android.util.Log
import androidx.compose.ui.test.assertCountEquals
import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.hasTestTag
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onAllNodesWithTag
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick
import androidx.compose.ui.test.performScrollTo
import androidx.compose.ui.test.performScrollToNode
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.github.se.assocify.model.CurrentUser
import com.github.se.assocify.model.database.AssociationAPI
import com.github.se.assocify.model.entities.Association
import com.github.se.assocify.model.entities.AssociationMember
import com.github.se.assocify.model.entities.PermissionRole
import com.github.se.assocify.model.entities.RoleType
import com.github.se.assocify.model.entities.User
import com.github.se.assocify.navigation.NavigationActions
import com.github.se.assocify.ui.screens.profile.members.ProfileMembersScreen
import com.github.se.assocify.ui.screens.profile.members.ProfileMembersViewModel
import com.kaspersky.components.composesupport.config.withComposeSupport
import com.kaspersky.kaspresso.kaspresso.Kaspresso
import com.kaspersky.kaspresso.testcases.api.testcase.TestCase
import io.mockk.every
import io.mockk.mockk
import java.time.LocalDate
import org.junit.Before
import org.junit.Rule
import org.junit.Test
Expand All @@ -26,19 +41,73 @@ class ProfileMembersScreenTest :
private val navActions = mockk<NavigationActions>()
private var goBack = false

private val userList =
listOf(
User("1", "Sarah"),
User("2", "veryveryveryverylooooooooooooooooooooongnameeeeeeeeee"),
User("3", "Alice"),
User("4", "Bob"),
User("5", "Charlie"),
User("6", "David"),
User("7", "Eve"),
User("8", "Frank"),
User("9", "Grace"),
User("10", "Hank"),
User("11", "Ivy"),
)

private val applicantList = userList.take(2)

private val assoMembers: List<AssociationMember> =
userList.map {
AssociationMember(
it,
Association("a", "assoName", "", LocalDate.EPOCH),
PermissionRole("r", "a", RoleType.MEMBER))
}

private val associationAPI =
mockk<AssociationAPI> {
every { getApplicants(any(), any(), any()) } answers
{
secondArg<(List<User>) -> Unit>().invoke(applicantList)
}
every { getMembers(any(), any(), any()) } answers
{
secondArg<(List<AssociationMember>) -> Unit>().invoke(assoMembers)
}
}

@Before
fun testSetup() {
CurrentUser.userUid = "1"
CurrentUser.associationUid = "asso"

every { navActions.back() } answers { goBack = true }

composeTestRule.setContent { ProfileMembersScreen(navActions = navActions) }
composeTestRule.setContent {
ProfileMembersScreen(
navActions = navActions, ProfileMembersViewModel(navActions, associationAPI))
}
}

@Test
fun display() {
with(composeTestRule) { onNodeWithTag("Members Screen").assertIsDisplayed() }
with(composeTestRule) {
onNodeWithTag("Members Screen").assertIsDisplayed()

onNodeWithText("New requests").assertIsDisplayed()
applicantList.forEach { onNodeWithTag("applicantCard-${it.uid}").assertIsDisplayed() }
onAllNodesWithTag("rejectButton").assertCountEquals(applicantList.size)
onAllNodesWithTag("acceptButton").assertCountEquals(applicantList.size)

onNodeWithText("Current members").performScrollTo().assertIsDisplayed()
assoMembers.forEach {
Log.e("assoMembers", it.user.uid)
onNodeWithTag("membersScreen").performScrollToNode(hasTestTag("memberItem-${it.user.uid}"))
onNodeWithTag("memberItem-${it.user.uid}").assertIsDisplayed()
}
}
}

@Test
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
package com.github.se.assocify.screens.profile

import androidx.compose.ui.test.assertCountEquals
import androidx.compose.ui.test.assertHasClickAction
import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onAllNodesWithTag
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.github.se.assocify.model.CurrentUser
import com.github.se.assocify.model.database.AccountingCategoryAPI
import com.github.se.assocify.model.entities.AccountingCategory
import com.github.se.assocify.navigation.NavigationActions
import com.github.se.assocify.ui.screens.profile.treasuryTags.ProfileTreasuryTagsScreen
import com.github.se.assocify.ui.screens.profile.treasuryTags.ProfileTreasuryTagsViewModel
import com.kaspersky.components.composesupport.config.withComposeSupport
import com.kaspersky.kaspresso.kaspresso.Kaspresso
import com.kaspersky.kaspresso.testcases.api.testcase.TestCase
Expand All @@ -26,19 +33,40 @@ class ProfileTreasuryTagsScreenTest :
private val navActions = mockk<NavigationActions>()
private var goBack = false

private val accCats = listOf(AccountingCategory("1", "cat1"), AccountingCategory("2", "cat2"))

private val mockAccountingCategoryAPI =
mockk<AccountingCategoryAPI>() {
every { getCategories(any(), any(), any()) } answers
{
val onSuccess = secondArg<(List<AccountingCategory>) -> Unit>()
onSuccess(accCats)
}
}

@Before
fun testSetup() {
CurrentUser.userUid = "1"
CurrentUser.associationUid = "asso"

every { navActions.back() } answers { goBack = true }

composeTestRule.setContent { ProfileTreasuryTagsScreen(navActions = navActions) }
composeTestRule.setContent {
ProfileTreasuryTagsScreen(
navActions = navActions,
ProfileTreasuryTagsViewModel(mockAccountingCategoryAPI, navActions))
}
}

@Test
fun display() {
with(composeTestRule) { onNodeWithTag("TreasuryTags Screen").assertIsDisplayed() }
with(composeTestRule) {
onNodeWithTag("TreasuryTags Screen").assertIsDisplayed()
onNodeWithTag("addTagButton").assertIsDisplayed().assertHasClickAction()
accCats.forEach { onNodeWithText(it.name).assertIsDisplayed() }
onAllNodesWithTag("editTagButton").assertCountEquals(accCats.size)
onAllNodesWithTag("deleteTagButton").assertCountEquals(accCats.size)
}
}

@Test
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.github.se.assocify.model.database

import com.github.se.assocify.model.CurrentUser
import com.github.se.assocify.model.entities.Event
import io.github.jan.supabase.SupabaseClient
import io.github.jan.supabase.postgrest.postgrest
Expand All @@ -18,15 +19,19 @@ class EventAPI(db: SupabaseClient) : SupabaseApi() {
}

/**
* Updates the event cache with the events from the database
* Updates the event cache with the events from the current Association from the database
*
* @param onSuccess called on success with the list of events
* @param onFailure called on failure
*/
fun updateEventCache(onSuccess: (List<Event>) -> Unit, onFailure: (Exception) -> Unit) {
tryAsync(onFailure) {
val events =
postgrest.from(collectionName).select().decodeList<SupabaseEvent>().map { it.toEvent() }
postgrest
.from(collectionName)
.select { filter { SupabaseEvent::associationUID eq CurrentUser.associationUid } }
.decodeList<SupabaseEvent>()
.map { it.toEvent() }
eventCache = events
onSuccess(events)
}
Expand All @@ -51,7 +56,9 @@ class EventAPI(db: SupabaseClient) : SupabaseApi() {
startDate = event.startDate.toString(),
endDate = event.endDate.toString(),
guestsOrArtists = event.guestsOrArtists,
location = event.location))
location = event.location,
associationUID = CurrentUser.associationUid))

eventCache = eventCache?.plus(event)
onSuccess(event.uid)
}
Expand All @@ -68,7 +75,6 @@ class EventAPI(db: SupabaseClient) : SupabaseApi() {
onSuccess(eventCache!!)
return
}

updateEventCache(onSuccess, onFailure)
}

Expand Down Expand Up @@ -193,7 +199,8 @@ class EventAPI(db: SupabaseClient) : SupabaseApi() {
@SerialName("start_date") val startDate: String,
@SerialName("end_date") val endDate: String,
@SerialName("guests_or_artists") val guestsOrArtists: String,
val location: String
val location: String,
@SerialName("association_uid") val associationUID: String?
) {
fun toEvent() =
Event(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,12 @@ data class BalanceItem(
val date: LocalDate,
val assignee: String,
val status: Status,
)
) {
fun getAmount(tvaActive: Boolean): Int {
return if (tvaActive) this.amount + (this.amount * this.tva.rate / 100f).toInt()
else this.amount
}
}

/**
* Represents the TVA of a budget or balance item, these types are also represented in the database
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,13 @@ data class BudgetItem(
val description: String,
val subcategoryUID: String,
val year: Int
)
) {
fun getAmount(tvaActive: Boolean): Int {
return if (tvaActive) this.amount + (this.amount * this.tva.rate / 100f).toInt()
else this.amount
}

fun getFormattedDescription(): String {
return this.description.ifEmpty { "-" }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ fun NavGraphBuilder.mainNavGraph(
accountingCategoriesAPI,
accountingSubCategoryAPI)
eventGraph(navActions, eventAPI, taskAPI)
profileGraph(navActions, userAPI, associationAPI)
profileGraph(navActions, userAPI, associationAPI, accountingCategoriesAPI, eventAPI)
loginGraph(navActions, userAPI)
selectAssociationGraph(navActions, userAPI, associationAPI)
createAssociationGraph(navActions, userAPI, associationAPI)
Expand Down
Loading

0 comments on commit 7fca325

Please sign in to comment.