Skip to content
This repository has been archived by the owner on Jun 5, 2023. It is now read-only.

Feature/recipe permission wrapper #323

Merged
merged 9 commits into from
May 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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 @@ -48,7 +48,7 @@ class PermissionManagerTest {
}

composeTestRule.onNodeWithText("Request permissions").assertExists()
composeTestRule.onNodeWithText("The following permissions are important: TestPermission1, TestPermission2. Please grant all of them for the app to function properly.").assertExists()
composeTestRule.onNodeWithText("The following permissions are important: Testpermission1, Testpermission2. Please grant all of them for the app to function properly.").assertExists()
}

@Test
Expand Down Expand Up @@ -112,7 +112,7 @@ class PermissionManagerTest {
}
}

val expectedText = "The following permissions will grant a better experience in the app: camera, location."
val expectedText = "The following permissions will grant a better experience in the app: Camera, Location."
composeTestRule.onNodeWithText(expectedText).assertIsDisplayed()
}

Expand All @@ -128,7 +128,7 @@ class PermissionManagerTest {
}
}

val expectedText = "The following permissions are important: camera, location. Please grant all of them for the app to function properly."
val expectedText = "The following permissions are important: Camera, Location. Please grant all of them for the app to function properly."
composeTestRule.onNodeWithText(expectedText).assertIsDisplayed()
}

Expand All @@ -144,7 +144,7 @@ class PermissionManagerTest {
}
}

val expectedText = "The location permission will grant a better experience in the app"
val expectedText = "The Location permission will grant a better experience in the app"
composeTestRule.onNodeWithText(expectedText).assertIsDisplayed()
}

Expand All @@ -160,7 +160,7 @@ class PermissionManagerTest {
}
}

val expectedText = "The camera permission is important. Please grant it for the app to function properly."
val expectedText = "The Camera permission is important. Please grant it for the app to function properly."
composeTestRule.onNodeWithText(expectedText).assertIsDisplayed()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,6 @@ class TestMapPermissionWrapper {
)
}

composeTestRule.onNodeWithText("The location permission will grant a better experience in the app").assertIsDisplayed()
composeTestRule.onNodeWithText("The Location permission will grant a better experience in the app").assertIsDisplayed()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package ch.epfl.sdp.cook4me.ui.recipe

import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performScrollTo
import androidx.test.ext.junit.runners.AndroidJUnit4
import ch.epfl.sdp.cook4me.TestPermissionStatusProvider
import ch.epfl.sdp.cook4me.persistence.repository.RecipeRepository
import io.mockk.mockk
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith

@RunWith(AndroidJUnit4::class)
class CreateRecipePermissionWrapperTest {
@get:Rule
val composeTestRule = createComposeRule()

private val mockRecipeRepository = mockk<RecipeRepository>(relaxed = true)

@Test
fun assertCreateRecipeIsDisplayedWhenCameraIsEnabled() {
val permissionStatusProvider = TestPermissionStatusProvider(mapOf("camera" to Pair(true, false)))
composeTestRule.setContent {
CreateRecipePermissionWrapper(
permissionStatusProvider = permissionStatusProvider,
repository = mockRecipeRepository
)
}
composeTestRule.onNodeWithText(text = "Recipe name").performScrollTo().assertIsDisplayed()
}

@Test
fun assertCreateRecipeIsNotDisplayedWhenCameraIsNotEnabled() {
val permissionStatusProvider = TestPermissionStatusProvider(mapOf("camera" to Pair(false, false)))
composeTestRule.setContent {
CreateRecipePermissionWrapper(
permissionStatusProvider = permissionStatusProvider,
repository = mockRecipeRepository
)
}
composeTestRule.onNodeWithText("The Camera permission will grant a better experience in the app")
.assertIsDisplayed()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class CreateTupperwarePermissionWrapperTest {
CreateTupperwarePermissionWrapper(permissionStatusProvider = permissionStatusProvider, {}, {})
}

composeTestRule.onNodeWithText("The camera permission will grant a better experience in the app")
composeTestRule.onNodeWithText("The Camera permission will grant a better experience in the app")
.assertIsDisplayed()
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
package ch.epfl.sdp.cook4me.permissions

import android.content.Context
import androidx.compose.foundation.layout.Column
import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
Expand Down Expand Up @@ -32,18 +29,15 @@ class PermissionManager(
if (permissionsRequested) {
permissionStatusProvider.RequestAllPermissions()
}
Column {
Text(
getPermissionText(
context,
permissionStatusProvider.getRevokedPermissions(),
permissionStatusProvider.shouldShowRationale()
)
)
Button(onClick = { permissionsRequested = true }) {
Text("Request permissions")
}
}
val permissionText = getPermissionText(
context,
permissionStatusProvider.getRevokedPermissions(),
permissionStatusProvider.shouldShowRationale()
)
PermissionRequesterScreen(
permissionText = permissionText,
onClick = { permissionsRequested = true }
)
}
}

Expand All @@ -60,16 +54,18 @@ class PermissionManager(
val permissionCount = permissions.size
if (permissionCount == 0) return ""

val formattedPermissions = permissions.map { formatPermission(it) }

val permissionText = if (permissionCount == 1) {
String.format(permissionMessageSingular, permissions[0])
String.format(permissionMessageSingular, formattedPermissions[0])
} else {
String.format(permissionMessagePlural, permissions.joinToString())
String.format(permissionMessagePlural, formattedPermissions.joinToString())
}

val permissionRecommendationText = if (permissionCount == 1) {
String.format(permissionMessageSingularRecommendation, permissions[0])
String.format(permissionMessageSingularRecommendation, formattedPermissions[0])
} else {
String.format(permissionMessagePluralRecommendation, permissions.joinToString())
String.format(permissionMessagePluralRecommendation, formattedPermissions.joinToString())
}

return if (shouldShowRationale) {
Expand All @@ -78,4 +74,9 @@ class PermissionManager(
permissionRecommendationText
}
}

private fun formatPermission(permission: String): String {
val reformatted = permission.split(".").last().replace("_", " ").lowercase()
return reformatted.replaceFirstChar { char -> if (char.isLowerCase()) char.uppercase() else char.toString() }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package ch.epfl.sdp.cook4me.permissions

import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.Button
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import ch.epfl.sdp.cook4me.R

@Composable
fun PermissionRequesterScreen(permissionText: String, onClick: () -> Unit) {
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Image(
painterResource(id = R.mipmap.ic_launcher_foreground),
contentDescription = "App Logo",
modifier = Modifier
.size(200.dp) // Increased size
.clip(CircleShape) // Makes image circular
)

Spacer(modifier = Modifier.height(24.dp))

Text(
text = permissionText,
style = MaterialTheme.typography.body1,
textAlign = TextAlign.Center,
modifier = Modifier.padding(horizontal = 16.dp)
)

Spacer(modifier = Modifier.height(24.dp))

Button(
onClick = { onClick() },
modifier = Modifier.padding(horizontal = 16.dp)
) {
Text(text = stringResource(R.string.request_permissions))
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import ch.epfl.sdp.cook4me.ui.chat.ChannelScreen
import ch.epfl.sdp.cook4me.ui.event.details.DetailedEventScreen
import ch.epfl.sdp.cook4me.ui.event.form.CreateEventScreen
import ch.epfl.sdp.cook4me.ui.map.MapPermissionWrapper
import ch.epfl.sdp.cook4me.ui.recipe.CreateRecipeScreen
import ch.epfl.sdp.cook4me.ui.recipe.CreateRecipePermissionWrapper
import ch.epfl.sdp.cook4me.ui.recipe.feed.RecipeFeed
import ch.epfl.sdp.cook4me.ui.tupperware.form.CreateTupperwarePermissionWrapper
import ch.epfl.sdp.cook4me.ui.tupperware.swipe.TupperwareSwipeScreen
Expand Down Expand Up @@ -102,7 +102,8 @@ fun Cook4MeNavHost(
)
}
composable(route = Screen.CreateRecipeScreen.name) {
CreateRecipeScreen(
CreateRecipePermissionWrapper(
permissionStatusProvider = permissionProvider,
onSuccessfulSubmit = { navController.navigateUp() },
onCancelClick = { navController.navigateUp() }
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package ch.epfl.sdp.cook4me.ui.recipe

import androidx.compose.runtime.Composable
import ch.epfl.sdp.cook4me.permissions.PermissionManager
import ch.epfl.sdp.cook4me.permissions.PermissionStatusProvider
import ch.epfl.sdp.cook4me.persistence.repository.RecipeRepository

@Composable
fun CreateRecipePermissionWrapper(
permissionStatusProvider: PermissionStatusProvider,
repository: RecipeRepository = RecipeRepository(),
onCancelClick: () -> Unit = {},
onSuccessfulSubmit: () -> Unit = {}
) {
val permissionManager = PermissionManager(permissionStatusProvider)
permissionManager.WithPermission {
CreateRecipeScreen(
repository = repository,
onCancelClick = onCancelClick,
onSuccessfulSubmit = onSuccessfulSubmit
)
}
}
1 change: 1 addition & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@
<string name="permission_message_plural">The following permissions are important: %1\$s. Please grant all of them for the app to function properly.</string>
<string name="permission_message_singular_recommendation">The %1\$s permission will grant a better experience in the app</string>
<string name="permission_message_plural_recommendation">The following permissions will grant a better experience in the app: %1\$s.</string>
<string name="request_permissions">Request permissions</string>

<!-- Chat -->
<string name="Too_many_connection_error_title">Connection Error</string>
Expand Down