Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature [Event Creation/Edition] Add possibility to add types to events #318

Merged
merged 26 commits into from
Dec 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
1674c96
Merge branch 'main' of github.com:SwEnt-Group13/Unio
AlouchLaBouche Dec 11, 2024
0739098
Merge branch 'fix/navigation-welcome'
AlouchLaBouche Dec 12, 2024
af13f83
Merge branch 'main' of github.com:SwEnt-Group13/Unio
AlouchLaBouche Dec 12, 2024
b7ca7cd
Merge branch 'main' of github.com:SwEnt-Group13/Unio
AlouchLaBouche Dec 13, 2024
58e19d5
Merge branch 'main' of github.com:SwEnt-Group13/Unio
AlouchLaBouche Dec 13, 2024
75795da
Merge branch 'main' of github.com:SwEnt-Group13/Unio
AlouchLaBouche Dec 17, 2024
304fec1
feat(Events): Add new event types
AlouchLaBouche Dec 18, 2024
ac14557
feat(Users): Add new user interests to match event types
AlouchLaBouche Dec 18, 2024
7750877
feat(Event): Add new translations for new event types
AlouchLaBouche Dec 18, 2024
2900916
feat(Event): Add new colors for new event types
AlouchLaBouche Dec 18, 2024
b25bcc0
feat(Event): Add Other event type as a default
AlouchLaBouche Dec 18, 2024
6dc8567
feat(EventType): Add EventTypeOverlay skeleton
AlouchLaBouche Dec 18, 2024
6965fd7
Merge branch 'feature/event_types' of github.com:SwEnt-Group13/Unio i…
AlouchLaBouche Dec 18, 2024
e735a1d
chore(EventTypeOverlay): Add necessary test tags
AlouchLaBouche Dec 18, 2024
df1a23f
feat(EventCreation): Add functional types selector overlay
AlouchLaBouche Dec 18, 2024
499acbf
refactor(EventEditComposable): Make association Chip generic
AlouchLaBouche Dec 18, 2024
0844fe1
refactor(EventCreation/Edition): Use the new generic chip composable
AlouchLaBouche Dec 18, 2024
3424e52
chore(TestTage/Strings): Add corresponding test tags and strings
AlouchLaBouche Dec 18, 2024
646db53
feat(EventTypeOverlay): Make sure that max event types is 3
AlouchLaBouche Dec 18, 2024
fe53358
style(All): ktfmt
AlouchLaBouche Dec 18, 2024
23f73b2
test(EventCreation/Edition): Add corresponding tests
AlouchLaBouche Dec 18, 2024
092df88
chore(EventEditComponents): Add necessary test tags
AlouchLaBouche Dec 18, 2024
c6da95e
style(All): ktfmt
AlouchLaBouche Dec 18, 2024
0ef79da
Merge main into feature/event-types 18/12 19h18
AlouchLaBouche Dec 18, 2024
9fb4296
fix(UnitTests): Add default list (empty) for types field
AlouchLaBouche Dec 18, 2024
57605b7
fix(EventTypeOverlay): remove unnecessary print
AlouchLaBouche Dec 18, 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
Expand Up @@ -17,7 +17,6 @@ import com.android.unio.mocks.user.MockUser
import com.android.unio.model.association.AssociationRepositoryFirestore
import com.android.unio.model.event.Event
import com.android.unio.model.event.EventRepositoryFirestore
import com.android.unio.model.event.EventType
import com.android.unio.model.event.EventUserPictureRepositoryFirestore
import com.android.unio.model.event.EventViewModel
import com.android.unio.model.image.ImageRepositoryFirebaseStorage
Expand Down Expand Up @@ -142,7 +141,7 @@ class EventCardTest : TearDown() {
composeTestRule
.onNodeWithTag(EventCardTestTags.EVENT_MAIN_TYPE, useUnmergedTree = true)
.assertExists()
.assertTextEquals(EventType.TRIP.text)
.assertTextEquals("Trip")

composeTestRule
.onNodeWithTag(EventCardTestTags.EVENT_LOCATION, useUnmergedTree = true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.android.unio.components.event

import androidx.compose.ui.test.assert
import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.assertIsNotEnabled
import androidx.compose.ui.test.assertTextEquals
import androidx.compose.ui.test.hasText
import androidx.compose.ui.test.isDisplayed
Expand Down Expand Up @@ -32,6 +33,8 @@ import com.android.unio.model.search.SearchViewModel
import com.android.unio.model.strings.TextLengthSamples
import com.android.unio.model.strings.test_tags.event.EventCreationOverlayTestTags
import com.android.unio.model.strings.test_tags.event.EventCreationTestTags
import com.android.unio.model.strings.test_tags.event.EventDetailsTestTags
import com.android.unio.model.strings.test_tags.event.EventTypeOverlayTestTags
import com.android.unio.model.usecase.FollowUseCaseFirestore
import com.android.unio.model.usecase.SaveUseCaseFirestore
import com.android.unio.ui.event.EventCreationScreen
Expand Down Expand Up @@ -283,6 +286,77 @@ class EventCreationTest : TearDown() {
composeTestRule.onNodeWithTag(EventCreationTestTags.DESCRIPTION).performTextClearance()
}

@Test
fun testCorrectlyAddEvenTypes() {
nominatimLocationSearchViewModel =
NominatimLocationSearchViewModel(nominatimLocationRepositoryWithoutFunctionality)
composeTestRule.setContent {
EventCreationScreen(
navigationAction,
searchViewModel,
associationViewModel,
eventViewModel,
nominatimLocationSearchViewModel)
}

composeTestRule.onNodeWithTag(EventCreationTestTags.EVENT_TYPE).performScrollTo().performClick()

composeTestRule.onNodeWithTag(EventTypeOverlayTestTags.CARD).assertExists()

composeTestRule
.onNodeWithTag(EventTypeOverlayTestTags.CLICKABLE_ROW + "FESTIVAL")
.performScrollTo()
.performClick()
composeTestRule
.onNodeWithTag(EventTypeOverlayTestTags.CLICKABLE_ROW + "APERITIF")
.performScrollTo()
.performClick()

composeTestRule.onNodeWithTag(EventTypeOverlayTestTags.SAVE_BUTTON).performClick()

composeTestRule.onNodeWithTag(EventCreationTestTags.SCREEN).assertIsDisplayed()

composeTestRule.onNodeWithTag(EventDetailsTestTags.CHIPS + "Festival").assertExists()
composeTestRule.onNodeWithTag(EventDetailsTestTags.CHIPS + "Aperitif").assertExists()
}

@Test
fun testNotPossibleToAddMoreThan3EventTypes() {
nominatimLocationSearchViewModel =
NominatimLocationSearchViewModel(nominatimLocationRepositoryWithoutFunctionality)
composeTestRule.setContent {
EventCreationScreen(
navigationAction,
searchViewModel,
associationViewModel,
eventViewModel,
nominatimLocationSearchViewModel)
}

composeTestRule.onNodeWithTag(EventCreationTestTags.EVENT_TYPE).performScrollTo().performClick()

composeTestRule.onNodeWithTag(EventTypeOverlayTestTags.CARD).assertExists()

composeTestRule
.onNodeWithTag(EventTypeOverlayTestTags.CLICKABLE_ROW + "FESTIVAL")
.performScrollTo()
.performClick()
composeTestRule
.onNodeWithTag(EventTypeOverlayTestTags.CLICKABLE_ROW + "APERITIF")
.performScrollTo()
.performClick()
composeTestRule
.onNodeWithTag(EventTypeOverlayTestTags.CLICKABLE_ROW + "JAM")
.performScrollTo()
.performClick()
composeTestRule
.onNodeWithTag(EventTypeOverlayTestTags.CLICKABLE_ROW + "TRIP")
.performScrollTo()
.performClick()

composeTestRule.onNodeWithTag(EventTypeOverlayTestTags.SAVE_BUTTON).assertIsNotEnabled()
}

@Test
fun testClearButtonFunctionality() {
nominatimLocationSearchViewModel =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ import com.android.unio.model.map.nominatim.NominatimLocationRepository
import com.android.unio.model.map.nominatim.NominatimLocationSearchViewModel
import com.android.unio.model.search.SearchRepository
import com.android.unio.model.search.SearchViewModel
import com.android.unio.model.strings.test_tags.event.EventDetailsTestTags
import com.android.unio.model.strings.test_tags.event.EventEditTestTags
import com.android.unio.model.strings.test_tags.event.EventTypeOverlayTestTags
import com.android.unio.model.usecase.FollowUseCaseFirestore
import com.android.unio.model.usecase.SaveUseCaseFirestore
import com.android.unio.ui.event.EventEditScreen
Expand Down Expand Up @@ -231,6 +233,73 @@ class EventEditTests : TearDown() {
composeTestRule.waitForIdle()
}

@Test
fun testCorrectlyAddEvenTypes() {
nominatimLocationSearchViewModel =
NominatimLocationSearchViewModel(nominatimLocationRepositoryWithoutFunctionality)
composeTestRule.setContent {
EventEditScreen(
navigationAction,
searchViewModel,
associationViewModel,
eventViewModel,
nominatimLocationSearchViewModel)
}

composeTestRule.onNodeWithTag(EventEditTestTags.EVENT_TYPE).performScrollTo().performClick()

composeTestRule.onNodeWithTag(EventTypeOverlayTestTags.CARD).assertExists()

composeTestRule
.onNodeWithTag(EventTypeOverlayTestTags.CLICKABLE_ROW + "FESTIVAL")
.performScrollTo()
.performClick()
composeTestRule
.onNodeWithTag(EventTypeOverlayTestTags.CLICKABLE_ROW + "APERITIF")
.performScrollTo()
.performClick()

composeTestRule.onNodeWithTag(EventTypeOverlayTestTags.SAVE_BUTTON).performClick()

composeTestRule.onNodeWithTag(EventEditTestTags.SCREEN).assertIsDisplayed()

composeTestRule.onNodeWithTag(EventDetailsTestTags.CHIPS + "Festival").assertExists()
composeTestRule.onNodeWithTag(EventDetailsTestTags.CHIPS + "Aperitif").assertExists()
}

@Test
fun testNotPossibleToAddMoreThan3EventTypes() {
nominatimLocationSearchViewModel =
NominatimLocationSearchViewModel(nominatimLocationRepositoryWithoutFunctionality)
composeTestRule.setContent {
EventEditScreen(
navigationAction,
searchViewModel,
associationViewModel,
eventViewModel,
nominatimLocationSearchViewModel)
}

composeTestRule.onNodeWithTag(EventEditTestTags.EVENT_TYPE).performScrollTo().performClick()

composeTestRule.onNodeWithTag(EventTypeOverlayTestTags.CARD).assertExists()

composeTestRule
.onNodeWithTag(EventTypeOverlayTestTags.CLICKABLE_ROW + "LAN")
.performScrollTo()
.performClick()
composeTestRule
.onNodeWithTag(EventTypeOverlayTestTags.CLICKABLE_ROW + "FOOD_DISTRIBUTION")
.performScrollTo()
.performClick()
composeTestRule
.onNodeWithTag(EventTypeOverlayTestTags.CLICKABLE_ROW + "MANIFESTATION")
.performScrollTo()
.performClick()

composeTestRule.onNodeWithTag(EventTypeOverlayTestTags.SAVE_BUTTON).assertIsNotEnabled()
}

@Test
fun testDeleteButtonWorksCorrectly() {
nominatimLocationSearchViewModel =
Expand Down
48 changes: 30 additions & 18 deletions app/src/main/java/com/android/unio/model/event/Event.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,12 @@ import androidx.appsearch.annotation.Document.Namespace
import androidx.appsearch.annotation.Document.StringProperty
import androidx.appsearch.app.AppSearchSchema.StringPropertyConfig
import androidx.compose.ui.graphics.Color
import com.android.unio.R
import com.android.unio.model.association.Association
import com.android.unio.model.firestore.ReferenceList
import com.android.unio.model.firestore.UniquelyIdentifiable
import com.android.unio.model.map.Location
import com.android.unio.ui.theme.eventTypeAperitif
import com.android.unio.ui.theme.eventTypeFestival
import com.android.unio.ui.theme.eventTypeJam
import com.android.unio.ui.theme.eventTypeNetworking
import com.android.unio.ui.theme.eventTypeNightParty
import com.android.unio.ui.theme.eventTypeOther
import com.android.unio.ui.theme.eventTypeSport
import com.android.unio.ui.theme.eventTypeTrip
import com.android.unio.ui.theme.EventColors
import com.google.firebase.Timestamp
import java.util.Date

Expand Down Expand Up @@ -53,7 +47,7 @@ data class Event(
val startDate: Timestamp = Timestamp(Date()),
val endDate: Timestamp = Timestamp(Date()),
val location: Location = Location(),
val types: List<EventType> = mutableListOf(EventType.OTHER),
val types: List<EventType>,
val maxNumberOfPlaces: Int = -1,
val numberOfSaved: Int = 0,
val eventPictures: ReferenceList<EventUserPicture>,
Expand Down Expand Up @@ -81,15 +75,33 @@ data class Event(
* @property color event type color
* @property text event type text
*/
enum class EventType(val color: Color, val text: String) {
FESTIVAL(eventTypeFestival, "festival"),
APERITIF(eventTypeAperitif, "aperitif"),
NIGHT_PARTY(eventTypeNightParty, "night party"),
JAM(eventTypeJam, "jam"),
NETWORKING(eventTypeNetworking, "networking"),
SPORT(eventTypeSport, "sport"),
TRIP(eventTypeTrip, "trip"),
OTHER(eventTypeOther, "other")
enum class EventType(val color: Color, val text: Int) {
FESTIVAL(EventColors.Festival, R.string.event_type_festival), // + Music and Festivals
APERITIF(EventColors.Aperitif, R.string.event_type_aperitif), // + Food and Apéro
NIGHT_PARTY(EventColors.NightParty, R.string.event_type_night_party), // + Music and Festivals
JAM(EventColors.Jam, R.string.event_type_jam), // + Music and Art
NETWORKING(EventColors.Networking, R.string.event_type_networking), // + Apéro and Networking
SPORT_TOURNAMENT(EventColors.SportTournament, R.string.event_type_sport_tournament), // + Sports
SPORT_DISCOVERY(
EventColors.SportDiscovery, R.string.event_type_sport_discovery), // + Sports, Socialising
TRIP(EventColors.Trip, R.string.event_type_trip), // + Travel, Culture
LAN(EventColors.Lan, R.string.event_type_lan), // + Gaming
FILM_PROJECTION(
EventColors.FilmProjection, R.string.event_type_film_projection), // + Art, Culture
FOREIGN_CULTURE_DISCOVERY(
EventColors.ForeignCultureDiscovery,
R.string.event_type_foreign_culture_discovery), // + Culture, Literature
TECH_PRESENTATION(
EventColors.TechPresentation, R.string.event_type_tech_presentation), // + Tech, Science
SCIENCE_FARE(EventColors.ScienceFare, R.string.event_type_science_fare), // + Science, Tech
FOOD_DISTRIBUTION(EventColors.FoodDistribution, R.string.event_type_food_distribuition), // + Food
ART_CONVENTION(
EventColors.ArtConvention, R.string.event_type_art_convention), // + Art, Literature
MANIFESTATION(
EventColors.Manifestation, R.string.event_type_manifestation), // + Culture, Socialising
BOARD_GAMES(EventColors.BoardGames, R.string.event_type_board_games), // + Gaming, Socialising
GROUP_STUDY(EventColors.GroupStudy, R.string.event_type_group_study), // + Science, Tech
OTHER(EventColors.Other, R.string.event_type_other)
Comment on lines +78 to +104
Copy link
Collaborator

Choose a reason for hiding this comment

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

Great work on extracting these strings, it's much appreciated

Copy link
Collaborator

Choose a reason for hiding this comment

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

Also, for my own understanding, what do the comments indicate ? Is it the associated user interests ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I need to remove them, but yes it is the "potential matches" with the user interests that can be used with the custom recommendation system

}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ object EventCreationTestTags {
const val EVENT_SHORT_DESCRIPTION_CLEAR_BUTTON = "eventCreationShortDescriptionClearButton"
const val COAUTHORS = "eventCreationCoauthors"
const val TAGGED_ASSOCIATIONS = "eventCreationTaggedAssociations"
const val EVENT_TYPE = "eventCreationEventType"
const val DESCRIPTION = "eventCreationDescription"
const val LOCATION = "eventCreationLocation"
const val SAVE_BUTTON = "eventCreationSaveButton"
Expand Down Expand Up @@ -63,6 +64,7 @@ object EventEditTestTags {
const val SHORT_DESCRIPTION_CLEAR_BUTTON = "eventEditShortDescriptionClearButton"
const val COAUTHORS = "eventEditCoauthors"
const val TAGGED_ASSOCIATIONS = "eventEditTaggedAssociations"
const val EVENT_TYPE = "eventEditEventType"
const val DESCRIPTION = "eventEditDescription"
const val LOCATION = "eventEditLocation"
const val LOCATION_SUGGESTION_ITEM = "eventCreationSuggestionItem: "
Expand Down Expand Up @@ -118,4 +120,18 @@ object EventDetailsTestTags {
const val EVENT_PICTURES_ARROW_LEFT = "picturesArrowLeft"
const val EVENT_PICTURES_ARROW_RIGHT = "picturesArrowRight"
const val PICTURE_FULL_SCREEN = "pictureFullScreen"
const val CHIPS = "eventChips"
}

object EventTypeOverlayTestTags {
const val CARD = "eventOverlayCard"
const val COLUMN = "eventOverlayColumn"
const val TITLE_TEXT = "eventOverlayTitleText"
const val SUBTITLE_TEXT = "eventOverlaySubtitleText"
const val DIVIDER = "eventOverlayDivider"
const val CANCEL_BUTTON = "eventOverlayCancelButton"
const val SAVE_BUTTON = "eventOverlaySaveButton"
const val CLICKABLE_ROW = "eventOverlayClickableRow"
const val TEXT = "eventOverlayRowText"
const val CHECK_BOX = "eventOverlayRowCheckBox"
}
3 changes: 3 additions & 0 deletions app/src/main/java/com/android/unio/model/user/User.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ enum class Interest(val title: Int) {
FOOD(R.string.interest_food),
GAMING(R.string.interest_gaming),
FESTIVALS(R.string.interest_festivals),
APEROS(R.string.interest_apero),
NETWORKING(R.string.interest_networking),
CULTURE(R.string.interest_culture)
}

enum class Social(val title: String, val icon: Int, val url: String) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,11 @@ import androidx.compose.ui.platform.testTag
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.PopupProperties
import com.android.unio.R
import com.android.unio.model.association.Association
import com.android.unio.model.map.Location
import com.android.unio.model.map.nominatim.NominatimLocationSearchViewModel
import com.android.unio.model.strings.FormatStrings.DAY_MONTH_YEAR_FORMAT
import com.android.unio.model.strings.FormatStrings.HOUR_MINUTE_FORMAT
import com.android.unio.model.strings.test_tags.event.EventDetailsTestTags
import com.android.unio.ui.image.AsyncImageWrapper
import com.android.unio.ui.utils.ToastUtils
import com.google.firebase.Timestamp
Expand Down Expand Up @@ -172,24 +172,26 @@ fun NominatimLocationPicker(
}

/**
* Composable for the association chips that show the selected associations.
* Composable for the different chips used that must be displayed in a flowRow
*
* @param associations List<Pair<Association, MutableState<Boolean>>> : List of associations and
* their selected state.
* @param items a generic list of items that can have their elements selected or not
*/
@OptIn(ExperimentalLayoutApi::class)
@Composable
fun AssociationChips(
associations: List<Pair<Association, MutableState<Boolean>>>,
fun <T> Chips(
items: List<Pair<T, MutableState<Boolean>>>,
getName: (T) -> String,
) {
Comment on lines -182 to 184
Copy link
Collaborator

Choose a reason for hiding this comment

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

Very clever use of genericity, well done 🚀

val context = LocalContext.current

FlowRow {
associations.forEach { (association, selected) ->
items.forEach { (item, selected) ->
if (selected.value) {
InputChip(
label = { Text(association.name) },
label = { Text(getName(item)) },
onClick = {},
selected = selected.value,
modifier = Modifier.testTag(EventDetailsTestTags.CHIPS + getName(item)),
avatar = {
Icon(
Icons.Default.Close,
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/java/com/android/unio/ui/event/EventCard.kt
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ fun EventCardScaffold(
.background(addAlphaToColor(type.color, 200))
.wrapContentWidth()) {
Text(
text = type.text,
text = context.getString(type.text),
modifier =
Modifier.padding(horizontal = 4.dp, vertical = 4.dp)
.testTag(EventCardTestTags.EVENT_MAIN_TYPE),
Expand Down
Loading
Loading