Compare commits

..

12 Commits

@ -51,7 +51,7 @@ android {
}
dependencies {
implementation("io.coil-kt:coil-compose:1.4.0")
implementation(libs.coil.compose.v140)
implementation(libs.bcrypt) // pour hacher les mdp
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.lifecycle.runtime.ktx)
@ -76,5 +76,9 @@ dependencies {
//ViewModel
implementation(libs.android.lifecycle.viewmodel)
implementation(libs.android.lifecycle.viewmodel.runtime.ktx)
//Retrofit
implementation(libs.retrofit)
implementation(libs.converter.gson)
implementation(libs.gson)
}

@ -1,6 +1,11 @@
package com.example.what_the_fantasy.data.model
import com.google.gson.annotations.SerializedName
data class Image(
@SerializedName("idImage")
val id: Int,
@SerializedName("imagePath")
val url: String
)

@ -1,16 +1,37 @@
package com.example.what_the_fantasy.data.model
import java.util.Date
import com.google.gson.annotations.SerializedName
data class Quote (
@SerializedName("id")
val id: Int,
@SerializedName("content")
val content: String,
@SerializedName("like")
var likes: Int,
@SerializedName("langage")
val language: SrcLanguage,
@SerializedName("character")
val character: String,
@SerializedName("titleSource")
val source: String,
@SerializedName("imagePath")
val imgUrl: String,
@SerializedName("type")
val type: SrcType ,
val date: Int
@SerializedName("dateSource")
val date: Int,
@SerializedName("isValide")
val isValide : Boolean = true
)

@ -1,6 +1,31 @@
package com.example.what_the_fantasy.data.model
import com.google.gson.*
import java.lang.reflect.Type
enum class SrcLanguage(val code:Int) {
vf(1),
vo(0);
companion object {
fun fromCode(code: Int): SrcLanguage? = values().find { it.code == code }
}
}
class LangAdapter : JsonSerializer<SrcLanguage>, JsonDeserializer<SrcLanguage> {
override fun serialize(
src: SrcLanguage?,
typeOfSrc: Type?,
context: JsonSerializationContext?
): JsonElement = JsonPrimitive(src?.code)
override fun deserialize(
json: JsonElement?,
typeOfT: Type?,
context: JsonDeserializationContext?
): SrcLanguage {
val code = json?.asInt
return SrcLanguage.fromCode(code ?: throw JsonParseException("Code null"))
?: throw JsonParseException("Unknown Status code: $code")
}
enum class SrcLanguage {
vf,
vo
}

@ -2,9 +2,50 @@ package com.example.what_the_fantasy.data.model
import androidx.compose.ui.res.stringResource
import com.example.what_the_fantasy.R
import com.google.gson.JsonDeserializationContext
import com.google.gson.JsonDeserializer
import com.google.gson.JsonElement
import com.google.gson.JsonParseException
import com.google.gson.JsonPrimitive
import com.google.gson.JsonSerializationContext
import com.google.gson.JsonSerializer
import java.lang.reflect.Type
enum class SrcType (val value: String) {
Movie("movie" ),
VideoGame("videoGame"),
Series("series"),
Series("series");
companion object {
fun fromCode(value: Int): SrcType? = SrcType.values().find {
if (value==0){
it.value == "movie"
}
else if (value==1){
it.value == "videoGame"
}
else{
it.value == "series"
}
}
}
}
class SrcTypeAdapter : JsonSerializer<SrcType>, JsonDeserializer<SrcType> {
override fun serialize(
src: SrcType?,
typeOfSrc: Type?,
context: JsonSerializationContext?
): JsonElement = JsonPrimitive(src?.value)
override fun deserialize(
json: JsonElement?,
typeOfT: Type?,
context: JsonDeserializationContext?
): SrcType {
val value = json?.asInt
return SrcType.fromCode(value ?: throw JsonParseException("Code null"))
?: throw JsonParseException("Unknown Status code: $value")
}
}

@ -1,11 +1,22 @@
package com.example.what_the_fantasy.data.model
import com.google.gson.annotations.SerializedName
class User(
@SerializedName("id")
val id:Int,
@SerializedName("pseudo")
var username:String,
@SerializedName("email")
var email:String,
@SerializedName("date")
var date:String,
@SerializedName("imageProfil")
val imgUrl: String,
@SerializedName("password")
var password: String,
@SerializedName("lang")
var langage : SrcLanguage
)

@ -0,0 +1,107 @@
package com.example.what_the_fantasy.data.retrofit
import com.example.what_the_fantasy.data.model.Image
import com.example.what_the_fantasy.data.model.LangAdapter
import com.example.what_the_fantasy.data.model.SrcTypeAdapter
import com.example.what_the_fantasy.data.model.Quote
import com.example.what_the_fantasy.data.model.SrcLanguage
import com.example.what_the_fantasy.data.model.SrcType
import com.example.what_the_fantasy.data.model.User
import com.example.what_the_fantasy.data.services.APIReponceList
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import retrofit2.Response
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.http.Body
import retrofit2.http.GET
import retrofit2.http.POST
import retrofit2.http.PUT
import retrofit2.http.Path
import retrofit2.http.Query
interface ApiService {
@GET("users/username")
suspend fun getUserByUsername(
@Query("username") username: String
): User
@GET("users/{id}")
suspend fun getUserById(
@Path("id") id: Int
): User
@GET("users/existusername")
suspend fun checkIfUsernameExists(
@Query("username") username: String
): Boolean
@GET("users/existemail")
suspend fun checkIfEmailExists(
@Query("email") email: String
): Boolean
@PUT("users")
suspend fun updateUsername(
@Query("id") id: Int,
@Body user: User // Envoie un objet `User` avec les nouvelles données
): Response<Unit>
@POST("users")
suspend fun addUser(
@Body newUser: User
): Response<Unit>
@GET("quote/dailyquote")
suspend fun getDailyQuote(
@Query("year") year: Int,
@Query("month") month: Int,
@Query("day") day: Int,
@Query("lang") lang: SrcLanguage
): Quote
@GET("quote/{id}")
suspend fun getQuoteById(
@Path("id")id : Int
):Quote
@GET("quote/all")
suspend fun getAllQuote(
@Query("index") index: Int,
@Query("count") count: Int
): APIReponceList<Quote>
@GET("image/all")
suspend fun getAllImages(
@Query("index") index: Int,
@Query("count") count: Int
): List<Image>
@GET("image/{id}")
suspend fun getImageById(
@Path("id") id: Int
): Image
}
object RetrofitInstance {
private const val BASE_URL = "https://codefirst.iut.uca.fr/containers/WhatTheFantasy-web-services/api/v1/"
private val gson: Gson = GsonBuilder()
.registerTypeAdapter(SrcLanguage::class.java, LangAdapter())
.registerTypeAdapter(SrcType::class.java, SrcTypeAdapter())
.create()
val api: ApiService by lazy {
Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.build()
.create(ApiService::class.java)
}
}

@ -0,0 +1,17 @@
package com.example.what_the_fantasy.data.services
import com.google.gson.annotations.SerializedName
data class APIReponceList<T> (
@SerializedName("totalCount")
val totalCount: Int,
@SerializedName("pageIndex")
val index: Int,
@SerializedName("countPerPage")
val count: Int,
@SerializedName("items")
val items: MutableList<T>,
)

@ -6,38 +6,41 @@ import com.example.what_the_fantasy.data.model.Quote
import com.example.what_the_fantasy.data.model.SrcLanguage
import com.example.what_the_fantasy.data.model.User
import com.example.what_the_fantasy.ui.states.AuthUserState
import com.example.what_the_fantasy.ui.viewModels.CurrentUserViewModel
import kotlinx.coroutines.flow.StateFlow
interface IServices {
fun validLogin(username : String,
suspend fun validLogin(username : String,
passwd : String,
navController: (Int) -> Unit,
initialierCurrentUser : (Int) ->Unit): Boolean
fun EditUsername(username : String, index : Int) : Boolean
fun EditEmail(email : String, index : Int) : Boolean
fun EditPasswd(passwd : String, index : Int)
fun EditImage(index : Int) : String
fun ChangeLangage(index : Int): SrcLanguage
initialierCurrentUser : (Int) ->Unit,
currentUserViewModel: CurrentUserViewModel
): Boolean
suspend fun EditUsername(username : String, index : Int, currentUserViewModel: CurrentUserViewModel) : Boolean
suspend fun EditEmail(email : String, index : Int,currentUserViewModel: CurrentUserViewModel) : Boolean
suspend fun EditPasswd(passwd : String, index : Int,currentUserViewModel : CurrentUserViewModel): Boolean
suspend fun EditImage(index : Int,currentUserViewModel : CurrentUserViewModel) : String
suspend fun ChangeLangage(index : Int, currentUserViewModel : CurrentUserViewModel): SrcLanguage
fun isUsernameExist(username : String) : Boolean
fun isEmailExist(email : String) : Boolean
fun AddFav(userId: Int, QuoteId : Int)
fun SupFav(userId: Int, QuoteId : Int)
fun AddComment(content : String)
fun CreateUser(username : String, email : String, passwd : String) : Boolean
suspend fun CreateUser(username : String, email : String, passwd : String) : Boolean
fun getFavorite(user: User): List<Quote>
fun getAllUsers(): List<User>
fun getComment(quoteId : Int) : List<Comment>
fun getUserById(id: Int): User?
suspend fun getUserById(id: Int): User?
fun getQuote( id : Int): Quote?
fun isFavorite(idQuote : Int, iduser: Int): Boolean
suspend fun isFavorite(idQuote : Int, iduser: Int): Boolean
fun getAllFavorite(): List<Favorite>
fun getAllQuote(): List<Quote>
fun getSomeQuotes(nb: Int, page: Int) : MutableList<Quote>
suspend fun getSomeQuotes(nb: Int, page: Int) : MutableList<Quote>
suspend fun getDalyQuote(langage : SrcLanguage) : Quote
fun search(type : String ,search:String ,indexCount: Int): List<Quote>
}

@ -1,89 +1,302 @@
package com.example.what_the_fantasy.data.services
import android.os.Build
import android.util.Log
import androidx.annotation.RequiresApi
import com.example.what_the_fantasy.data.local.ImageStub.allImages
import com.example.what_the_fantasy.data.model.Comment
import com.example.what_the_fantasy.data.model.Favorite
import com.example.what_the_fantasy.data.model.Quote
import com.example.what_the_fantasy.data.model.SrcLanguage
import com.example.what_the_fantasy.data.model.User
import com.example.what_the_fantasy.data.retrofit.RetrofitInstance
import com.example.what_the_fantasy.ui.viewModels.CurrentUserViewModel
import java.time.LocalDate
import java.util.Calendar
import java.util.Date
//import com.example.what_the_fantasy.data.model.Comment
//import com.example.what_the_fantasy.data.model.Favorite
//import com.example.what_the_fantasy.data.model.Quote
//import com.example.what_the_fantasy.data.model.User
////import com.example.what_the_fantasy.ui.navigations.Destination
//class ServicesAPI : IServices {
// override fun EditUsername(username: String, index : Int): Boolean {
// TODO("Not yet implemented")
// }
//
// override fun EditEmail(email: String, index : Int): Boolean {
// TODO("Not yet implemented")
// }
//
// override fun EditPasswd(passwd: String, index : Int) {
// TODO("Not yet implemented")
// }
//
// override fun EditImage(imageURL: String, index : Int) {
// TODO("Not yet implemented")
// }
//
// override fun ChangeLangage(user: User) {
// TODO("Not yet implemented")
// }
//
// override fun AddFav(userId: Int, QuoteId: Int) {
// TODO("Not yet implemented")
// }
//
// override fun SupFav(userId: Int, QuoteId: Int) {
// TODO("Not yet implemented")
// }
//
// override fun AddComment(content: String) {
// TODO("Not yet implemented")
// }
//
// override fun CreateUser(username: String, email: String, passwd: String, services: IServices) : Boolean {
// TODO("Not yet implemented")
// }
//
// override fun getFavorite(user: User): List<Quote> {
// TODO("Not yet implemented")
// }
//
// override fun SearchQuote(quote: String) {
// TODO("Not yet implemented")
// }
//
// override fun getQuote(id: Int): Quote? {
// TODO("Not yet implemented")
// }
//
// override fun isFavorite(id: Int, user: User): Boolean {
// TODO("Not yet implemented")
// }
//
// override fun getAllFavorite(): List<Favorite> {
// TODO("Not yet implemented")
// }
//
// override fun getAllQuote(): List<Quote> {
// TODO("Not yet implemented")
// }
//
// override fun getSomeQuotes(nb: Int, page: Int): MutableList<Quote> {
// TODO("Not yet implemented")
// }
//
// override fun getAllUsers(): List<User> {
// TODO("Not yet implemented")
// }
//
// override fun getComment(quoteId: Int): List<Comment> {
// TODO("Not yet implemented")
// }
//
// override fun getUserById(id: Int): User? {
// TODO("Not yet implemented")
// }
//
// override fun search(type : String ,search:String ,indexCount: Int): List<Quote>{
// TODO("Not yet implemented")
// }
//}
class ServicesAPI : IServices {
override suspend fun validLogin(
username: String,
passwd: String,
navController: (Int) -> Unit,
initialierCurrentUser: (Int) -> Unit,
currentUserViewModel: CurrentUserViewModel
): Boolean {
try {
val response = RetrofitInstance.api.getUserByUsername(username) // on récupère l'utilisateur
val hashedPasswordAPI = response.password // récupère le mot de passe de l'api
val index =response.id
//val hashPassWd = hashPassword(passwd)// hache mot de passe demandé
if (passwd == hashedPasswordAPI) { // on compare les deux mots de passe
navController(index)
initialierCurrentUser(index)
currentUserViewModel.setUser(response)
return true
}
else {
return false
}
} catch (e: Exception) {
return false
}
}
override suspend fun EditUsername(username: String, index: Int, currentUserViewModel: CurrentUserViewModel): Boolean {
try {
val userExistsResponse = RetrofitInstance.api.checkIfUsernameExists(username)
Log.d("EditUsername", "Username check: $username exists = $userExistsResponse")
if (userExistsResponse) {
Log.d("EditUsername", "Username $username already exists, cannot update.")
return false
}
val responseUser = RetrofitInstance.api.getUserById(index)
val updatedUser = User(
id = index,
username = username, // Nouveau nom d'utilisateur
email = responseUser.email,
password = responseUser.password,
imgUrl = responseUser.imgUrl,
langage = responseUser.langage,
date = responseUser.date
)
val response = RetrofitInstance.api.updateUsername(index, updatedUser)
if (response.isSuccessful) {
currentUserViewModel.setUser(updatedUser)
Log.d("EditUsername", "Username updated successfully.")
return true
} else {
Log.d("EditUsername", "Failed to update username, API response not successful.")
return false
}
} catch (e: Exception) {
e.printStackTrace()
Log.d("EditUsername", "Exception occurred: ${e.message}")
return false
}
}
override suspend fun EditEmail(email: String, index: Int,currentUserViewModel: CurrentUserViewModel): Boolean {
try {
val userExistsResponse = RetrofitInstance.api.checkIfEmailExists(email)
if (userExistsResponse) {
Log.d("EditEmail", "Exception occurred: The email alredy exist")
return false
}
val responseUser = RetrofitInstance.api.getUserById(index)
val updatedUser = User(
id = index,
username = responseUser.username,
email = email,// Nouvel email d'utilisateur
password = responseUser.password,
imgUrl = responseUser.imgUrl,
langage = responseUser.langage,
date = responseUser.date
)
val response = RetrofitInstance.api.updateUsername(index, updatedUser)
if (response.isSuccessful) {
currentUserViewModel.setUser(updatedUser)
return true
} else {
return false
}
} catch (e: Exception) {
e.printStackTrace()
Log.d("EditEmail", "Exception occurred: ${e.message}")
return false
}
}
override suspend fun EditPasswd(passwd: String, index: Int, currentUserViewModel: CurrentUserViewModel): Boolean {
try {
val responseUser = RetrofitInstance.api.getUserById(index)
val updatedUser = User(
id = index,
username = responseUser.username,
email = responseUser.username,
password = passwd,
//password = hashPassword(passwd),
imgUrl = responseUser.imgUrl,
langage = responseUser.langage,
date = responseUser.date
)
val response = RetrofitInstance.api.updateUsername(index, updatedUser)
if (response.isSuccessful) {
currentUserViewModel.setUser(updatedUser)
return true
} else {
return false
}
} catch (e: Exception) {
e.printStackTrace()
Log.d("EditPasswd", "Exception occurred: ${e.message}")
return false
}
}
override suspend fun EditImage(index: Int, currentUserViewModel : CurrentUserViewModel): String {
try {
val responseUser = RetrofitInstance.api.getUserById(index)
val updatedUser = User(
id = index,
username = responseUser.username,
email = responseUser.email,// Nouvel email d'utilisateur
password = responseUser.password,
imgUrl = randomImage(),
langage = responseUser.langage,
date = responseUser.date
)
val response = RetrofitInstance.api.updateUsername(index, updatedUser)
if (response.isSuccessful) {
currentUserViewModel.setUser(updatedUser)
return updatedUser.imgUrl
} else {
return responseUser.imgUrl
}
} catch (e: Exception) {
e.printStackTrace()
return ""
Log.d("EditEmail", "Exception occurred: ${e.message}")
}
}
override suspend fun ChangeLangage(index: Int, currentUserViewModel : CurrentUserViewModel): SrcLanguage {
val responseUser = RetrofitInstance.api.getUserById(index)
var langage : SrcLanguage
if(responseUser.langage == SrcLanguage.vf){
langage = SrcLanguage.vo
}
else{
langage = SrcLanguage.vf
}
val updatedUser = User(
id = index,
username = responseUser.username,
email = responseUser.email,
password = responseUser.password,
imgUrl = responseUser.imgUrl,
langage = langage,
date = responseUser.date
)
RetrofitInstance.api.updateUsername(index, updatedUser)
currentUserViewModel.setUser(updatedUser)
return langage
}
override fun isUsernameExist(username: String): Boolean {
TODO("Not yet implemented")
}
override fun isEmailExist(email: String): Boolean {
TODO("Not yet implemented")
}
override fun AddFav(userId: Int, QuoteId: Int) {
TODO("Not yet implemented")
}
override fun SupFav(userId: Int, QuoteId: Int) {
TODO("Not yet implemented")
}
override fun AddComment(content: String) {
TODO("Not yet implemented")
}
override suspend fun CreateUser(username: String, email: String, passwd: String): Boolean {
val today = Calendar.getInstance().time
val rep =RetrofitInstance.api.addUser( User(15,username,email,today.toString(),"img",passwd,SrcLanguage.vo))
Log.d("test",rep.toString())
if(rep.code() in 200..299) return true
return false
}
override fun getFavorite(user: User): List<Quote> {
TODO("Not yet implemented")
}
override fun getAllUsers(): List<User> {
TODO("Not yet implemented")
}
override fun getComment(quoteId: Int): List<Comment> {
TODO("Not yet implemented")
}
override suspend fun getUserById(id: Int): User {
return RetrofitInstance.api.getUserById(id)
}
override fun getQuote(id: Int): Quote? {
TODO("Not yet implemented")
}
override suspend fun isFavorite(idQuote: Int, iduser: Int): Boolean {
TODO("Not yet implemented")
}
override fun getAllFavorite(): List<Favorite> {
TODO("Not yet implemented")
}
override fun getAllQuote(): List<Quote> {
TODO("Not yet implemented")
}
override suspend fun getSomeQuotes(nb: Int, page: Int): MutableList<Quote> {
val result = RetrofitInstance.api.getAllQuote(page,nb)
return result.items
}
@RequiresApi(Build.VERSION_CODES.O)
override suspend fun getDalyQuote(langage : SrcLanguage): Quote {
val today = LocalDate.now()
return RetrofitInstance.api.getDailyQuote(today.year, today.monthValue, today.dayOfMonth, langage)
}
override fun search(type: String, search: String, indexCount: Int): List<Quote> {
TODO("Not yet implemented")
}
//-------------------------------------------------------
suspend fun randomImage() : String{
val imagesList = RetrofitInstance.api.getAllImages(0, 300)
val sizeList = imagesList.size
return RetrofitInstance.api.getImageById((0..sizeList).random()).url
}
}

@ -12,16 +12,19 @@ import com.example.what_the_fantasy.data.local.CommentStub.comments
import com.example.what_the_fantasy.data.model.Comment
import com.example.what_the_fantasy.data.model.Quote
import com.example.what_the_fantasy.data.model.SrcLanguage
import com.example.what_the_fantasy.ui.viewModels.CurrentUserViewModel
import java.time.LocalDate
class ServicesStub : IServices {
val logsUser = LogsUsers() //gestion des logs pour les utilisateurs
override fun validLogin(username : String,
override suspend fun validLogin(username : String,
passwd : String,
navController: (Int) -> Unit,
initialierCurrentUser : (Int) ->Unit): Boolean{
initialierCurrentUser : (Int) ->Unit,
currentUserViewModel: CurrentUserViewModel
): Boolean{
users.forEachIndexed { index, user ->
val hashPassWd = hashPassword(passwd)
@ -36,7 +39,7 @@ class ServicesStub : IServices {
}
override fun EditUsername(username: String, index : Int) : Boolean{
override suspend fun EditUsername(username: String, index : Int,currentUserViewModel: CurrentUserViewModel) : Boolean{
val user = getUserById(index)
if(!isUsernameExist(username)){
@ -49,7 +52,7 @@ class ServicesStub : IServices {
return false
}
override fun EditEmail(email: String,index : Int) : Boolean {
override suspend fun EditEmail(email: String, index : Int,currentUserViewModel: CurrentUserViewModel) : Boolean {
val user = getUserById(index)
if(!isEmailExist(email)){
@ -61,20 +64,20 @@ class ServicesStub : IServices {
return false
}
override fun EditPasswd(passwd: String,index : Int) {
override suspend fun EditPasswd(passwd: String, index: Int, currentUserViewModel: CurrentUserViewModel): Boolean {
val user = getUserById(index)
val passwordhash = hashPassword(passwd)
user?.password = passwordhash
return true
//Afficher tous les users en log
//logsUser.logDebugAllUsers(getAllUsers(), "PasswordUpdate")
}
override fun EditImage(index : Int) : String {
override suspend fun EditImage(index : Int,currentUserViewModel : CurrentUserViewModel) : String {
return randomImage()
}
override fun ChangeLangage(index : Int) : SrcLanguage{
override suspend fun ChangeLangage(index : Int,currentUserViewModel : CurrentUserViewModel) : SrcLanguage{
if(getAllUsers()[index].langage == SrcLanguage.vo){
getAllUsers()[index].langage = SrcLanguage.vf
}
@ -101,16 +104,14 @@ class ServicesStub : IServices {
}
override fun CreateUser(username: String, email: String, passwd: String) : Boolean {
override suspend fun CreateUser(username: String, email: String, passwd: String) : Boolean {
val date =dateDuJour()
val passwordhash = hashPassword(passwd)
val services = ServicesStub()
val userStub = services.getAllUsers()
val nbUser = userStub.size
if(username == "" || email == "" || passwd == ""){
return false
}
if(!isUsernameExist(username) && !isEmailExist(email)){
val user = User(nbUser,username, email, date,randomImage(), passwordhash, SrcLanguage.vo)
users.add(user)//ajout au stub
@ -133,7 +134,7 @@ class ServicesStub : IServices {
override fun getComment(quoteId: Int): List<Comment> = comments
override fun getUserById(id: Int): User? {
override suspend fun getUserById(id: Int): User? {
return (users.find { it.id == id })
}
@ -142,21 +143,23 @@ class ServicesStub : IServices {
return (quotes.find { it.id == id })
}
override fun getSomeQuotes(nb: Int, page: Int): MutableList<Quote> {
override suspend fun getSomeQuotes(nb: Int, page: Int): MutableList<Quote> {
var nbQuote = nb
var nbPage = page
if(nb < 0) nbQuote = 1
if(nbPage < 0) nbPage = 1
val fromIndex = (nbPage - 1) * nbQuote
val toIndex = minOf(nbPage * nbQuote, quotes.size)
val fromIndex = (page - 1) * nbQuote
val toIndex = minOf(page * nbQuote, quotes.size)
if (fromIndex >= quotes.size) return mutableListOf()
return quotes.subList(fromIndex, toIndex).toMutableList()
}
override fun isFavorite(idQuote: Int, idUser: Int): Boolean {
override suspend fun getDalyQuote(langage: SrcLanguage): Quote {
return quotes.first()
}
override suspend fun isFavorite(idQuote: Int, idUser: Int): Boolean {
val user = getUserById(idUser) ?: return false
val quote = getFavorite(user)
return quote.find{ it.id == idQuote } != null

@ -1,5 +1,6 @@
package com.example.what_the_fantasy.ui.navigations
import android.util.Log
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
@ -8,12 +9,14 @@ import androidx.compose.material3.Scaffold
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import androidx.navigation.toRoute
import com.example.what_the_fantasy.data.services.ServicesAPI
import com.example.what_the_fantasy.data.services.ServicesStub
import com.example.what_the_fantasy.ui.screens.*
import com.example.what_the_fantasy.ui.viewModels.AuthUserViewModel
@ -21,6 +24,7 @@ import com.example.what_the_fantasy.ui.viewModels.CurrentUserViewModel
import com.example.what_the_fantasy.ui.viewModels.QuoteInformationUserViewModel
import com.example.what_the_fantasy.ui.viewModels.SearchViewModel
import com.example.what_the_fantasy.ui.viewModels.SignInUserViewModel
import kotlinx.coroutines.launch
import kotlinx.serialization.Serializable
@Serializable
@ -70,7 +74,8 @@ data class RecapSubmit(val userIndex: Int,
@Composable
fun AppNavigator() {
val navController = rememberNavController()
val services = ServicesStub()
val servicesStub = ServicesStub()
val services = ServicesAPI()
//ViewModel pour l'authentification
val authUserVM : AuthUserViewModel = viewModel()
@ -100,6 +105,7 @@ fun AppNavigator() {
NavHost(navController, startDestination = Login) {
composable<Login> {
val coroutineScope = rememberCoroutineScope()
LoginPage(
navControllerSignUp = { navController.navigate(SignUp) },
navControllerProfil = { userIndex ->
@ -109,7 +115,12 @@ fun AppNavigator() {
},
authUserVM = authUserVM,
authState = authState,
initialierCurrentUser ={currentUserVM.initialiseCurrentUser(it)}
currentUserViewModel = currentUserVM,
initialierCurrentUser ={
coroutineScope.launch {
currentUserVM.initialiseCurrentUser(it)
}
}
)
}
@ -148,7 +159,7 @@ fun AppNavigator() {
)
},
navSearch = { navController.navigate(Search(currentUserState.id))},
services = services,
services = servicesStub,
currentUserVM = currentUserVM,
currentUserState = currentUserState,
)
@ -178,7 +189,7 @@ fun AppNavigator() {
navQuiz = { navController.navigate(QuizMenu(currentUserState.id)) },
navProfil = { navController.navigate(Profil(currentUserState.id)) },
navFavorite = { navController.navigate(Favorite(currentUserState.id)) },
service = services,
service = servicesStub,
currentUserVM = currentUserVM,
currentUserState = currentUserState,
navSearch = { navController.navigate(Search(currentUserState.id))},

@ -1,5 +1,7 @@
package com.example.what_the_fantasy.ui.screens
import android.annotation.SuppressLint
import android.util.Log
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
@ -19,14 +21,19 @@ import androidx.compose.ui.unit.sp
import com.example.what_the_fantasy.R
import com.example.what_the_fantasy.data.local.DailyQuoteStub
import com.example.what_the_fantasy.data.model.Quote
import com.example.what_the_fantasy.data.model.SrcLanguage
import com.example.what_the_fantasy.data.model.SrcType
import com.example.what_the_fantasy.data.services.IServices
import com.example.what_the_fantasy.ui.components.NavBar
import com.example.what_the_fantasy.ui.components.QuoteLittle
import com.example.what_the_fantasy.ui.states.CurrentUserState
import com.example.what_the_fantasy.ui.viewModels.CurrentUserViewModel
import com.example.what_the_fantasy.ui.theme.colorBackground
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
@SuppressLint("CoroutineCreationDuringComposition")
@Composable
fun AccueilPage(
navFavorite: () -> Unit,
@ -39,12 +46,13 @@ fun AccueilPage(
currentUserState : CurrentUserState,
) {
val dailyQuote = DailyQuoteStub.dailyQuote
//val dailyQuote = DailyQuoteStub.dailyQuote
val titleDalyQuote = stringResource(R.string.TitleHomeDailyQuote)
val titleSuggestion = stringResource(R.string.TitleHomeSuggestion)
val page = remember { mutableIntStateOf(1) }
val page = remember { mutableIntStateOf(0) }
val quotes = remember { mutableStateListOf<Quote>() }
val state = rememberLazyListState()
val layoutInfo = remember { derivedStateOf { state.layoutInfo } }
@ -53,6 +61,10 @@ fun AccueilPage(
val fullyVisibleItemsInfo = visibleItemsInfo.toMutableList()
val lastItem = if (fullyVisibleItemsInfo.isNotEmpty()) fullyVisibleItemsInfo.last() else null
val dailyQuote = remember { mutableStateOf(Quote(-1,"",0,SrcLanguage.vo,"","","",SrcType.Movie,0)) }
LaunchedEffect(true){
dailyQuote.value=services.getDalyQuote(currentUserState.langage)
}
LaunchedEffect(page.intValue) {
if (!isLoading.value) {
@ -87,8 +99,9 @@ fun AccueilPage(
.background(MaterialTheme.colorScheme.background)
) {
LazyColumn(modifier = Modifier.weight(1f), state = state) {
if(dailyQuote.value.id!=-1) {
item {
Column(Modifier.clickable { navQuote(dailyQuote.id) }) {
Column(Modifier.clickable { navQuote(dailyQuote.value.id) }) {
Text(
text = titleDalyQuote,
color = MaterialTheme.colorScheme.onBackground,
@ -98,9 +111,23 @@ fun AccueilPage(
.padding(16.dp),
textAlign = TextAlign.Center
)
QuoteLittle(dailyQuote)
QuoteLittle(dailyQuote.value)
}
}
}
else{
item {
Box(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
contentAlignment = Alignment.Center
) {
CircularProgressIndicator()
}
}
}
item {
Text(
text = titleSuggestion,
color = MaterialTheme.colorScheme.onBackground,

@ -33,9 +33,10 @@ fun FavoritePage(
currentUserVM : CurrentUserViewModel,
currentUserState : CurrentUserState,
) {
val user = services.getUserById(currentUserState.id) ?: return
val quotes = services.getFavorite(user)
//val user = services.getUserById(currentUserState.id) ?: return
//val quotes = services.getFavorite(user)
val titlePage = stringResource(R.string.TitleFavorite)
NavBar(onFavorite = true,
@ -65,12 +66,12 @@ fun FavoritePage(
textAlign = TextAlign.Center
)
}
items(quotes) { quote ->
Column(Modifier.clickable { navQuote(quote.id) }) {
QuoteLittle(quote)
Spacer(modifier = Modifier.height(16.dp))
}
}
// items(quotes) { quote ->
// Column(Modifier.clickable { navQuote(quote.id) }) {
// QuoteLittle(quote)
// Spacer(modifier = Modifier.height(16.dp))
// }
// }
}
}
}

@ -21,6 +21,7 @@ import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@ -44,12 +45,15 @@ import com.example.what_the_fantasy.data.services.hashPassword
import com.example.what_the_fantasy.ui.components.VisibleIconPasswordComponent
import com.example.what_the_fantasy.ui.states.AuthUserState
import com.example.what_the_fantasy.ui.viewModels.AuthUserViewModel
import com.example.what_the_fantasy.ui.viewModels.CurrentUserViewModel
import kotlinx.coroutines.launch
@Composable
fun LoginPage(navControllerSignUp: () -> Unit,
navControllerProfil: (Int) -> Unit,
authUserVM : AuthUserViewModel,
authState : AuthUserState,
currentUserViewModel : CurrentUserViewModel,
initialierCurrentUser : (Int) -> Unit) {
@ -77,7 +81,7 @@ fun LoginPage(navControllerSignUp: () -> Unit,
authUserVM.setUsername(it)
}, PassWdTextField(R.string.PasswdLogin, authState.password){
authUserVM.setPassword(it)
}, R.string.ButtonLogin,18,navControllerProfil){
}, R.string.ButtonLogin,18,currentUserViewModel,navControllerProfil){
initialierCurrentUser(it)
}
SpaceHeightComponent(16)
@ -136,12 +140,25 @@ fun PassWdTextField(textpasswdResId : Int, password : String, onValueChange: (St
@Composable
fun ConnexionButtonLogin(authUserVM : AuthUserViewModel, username : String, passwd : String, titleResId : Int, size : Int, navController: (Int) -> Unit, initialierCurrentUser : (Int) -> Unit){
fun ConnexionButtonLogin(authUserVM : AuthUserViewModel,
username : String,
passwd : String,
titleResId : Int,
size : Int,
currentUserViewModel: CurrentUserViewModel,
navController: (Int) -> Unit,
initialierCurrentUser : (Int) -> Unit){
val title = stringResource(id = titleResId)
var showError by remember { mutableStateOf(false) }
val coroutineScope = rememberCoroutineScope()
Button(
onClick = { showError = !authUserVM.validLogin(username, passwd, navController, initialierCurrentUser)
onClick = {
coroutineScope.launch {
val result = authUserVM.validLogin(username, passwd, navController, initialierCurrentUser, currentUserViewModel)
showError = !result
}
},
colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.background),
modifier = Modifier
.fillMaxWidth(),

@ -33,6 +33,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@ -57,6 +58,8 @@ import com.example.what_the_fantasy.ui.components.TitlePageComponent
import com.example.what_the_fantasy.ui.components.VisibleIconPasswordComponent
import com.example.what_the_fantasy.ui.states.CurrentUserState
import com.example.what_the_fantasy.ui.viewModels.CurrentUserViewModel
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
@Composable
fun ProfilPage(navFavorite: () -> Unit,
@ -129,13 +132,18 @@ fun ProfilPage(navFavorite: () -> Unit,
@Composable
fun ImageProfil(size :Int,index: Int, currentUserVM: CurrentUserViewModel, currentUserState: CurrentUserState){
val coroutineScope = rememberCoroutineScope()
AsyncImage(
model = currentUserState.imagePath,
contentDescription = "Photo de profil",
modifier = Modifier
.size(size.dp)
.clip(CircleShape)
.clickable{currentUserVM.editImage(index)}
.clickable{
coroutineScope.launch {
currentUserVM.editImage(index)
}
}
)
}
@ -145,14 +153,16 @@ fun EditEmail(emailState: String, index: Int, currentUserVM: CurrentUserViewMode
var originalEmail by remember { mutableStateOf(emailState) }
var isEditingEmail by remember { mutableStateOf(false) }
var emailError by remember { mutableStateOf(false) }
val coroutineScope = rememberCoroutineScope()
fun onDoneEditing() {
coroutineScope.launch {
if (email != originalEmail) {
isEditingEmail = !currentUserVM.editEmail(email, index)
} else {
isEditingEmail = false
}
}
}
if (isEditingEmail) {
EmailEditingField(
@ -235,14 +245,17 @@ fun EditUsername(usernameState: String, index: Int, currentUserVM: CurrentUserVi
var username by remember { mutableStateOf(usernameState) }
var originalUsername by remember { mutableStateOf(usernameState) }
var isEditingUsername by remember { mutableStateOf(false) }
val coroutineScope = rememberCoroutineScope()
fun onDoneEditing() {
coroutineScope.launch {
if (username != originalUsername) {
isEditingUsername = !currentUserVM.editUsername(username, index)
} else {
isEditingUsername = false
}
}
}
if (isEditingUsername) {
UsernameEditingField(
@ -312,13 +325,15 @@ fun EditPasswd(index: Int, currentUserVM: CurrentUserViewModel) {
var confirmPassword by remember { mutableStateOf("") }
var passwordVisible by remember { mutableStateOf(false) }
var passwordError by remember { mutableStateOf(false) }
val coroutineScope = rememberCoroutineScope()
// Fonction pour finaliser l'édition du mot de passe et appeler la méthode EditPasswd2
fun onDoneEditing() {
coroutineScope.launch {
// Appeler EditPasswd pour mettre à jour le mot de passe de l'utilisateur
currentUserVM.editPassword(newPassword, index)
isEditingPassword = false
}
}
if (isEditingPassword) {
PasswordEditingFields(
@ -480,10 +495,12 @@ fun ButtonUnLog(textResId : Int, size :Int, colorTexte : Color,colorButton : Col
@Composable
fun ButtonLanguage(textResId : Int, size :Int,colorTexte : Color, colorButton : Color, currentUserVM: CurrentUserViewModel, currentUserState : CurrentUserState){
val text = stringResource(id = textResId)
val coroutineScope = rememberCoroutineScope()
Button(
onClick = {
coroutineScope.launch {
currentUserVM.editLangue(currentUserState.id)
}
},
colors = ButtonDefaults.buttonColors(containerColor = colorButton),
modifier = Modifier.fillMaxWidth(),

@ -87,9 +87,9 @@ fun QuotePage(
val quote = service.getQuote(quoteId) ?: return
val context = LocalContext.current
val favorite by remember { mutableStateOf(service.isFavorite(
idQuote = quoteId,
iduser = currentUserState.id)) }
//val favorite by remember { mutableStateOf(service.isFavorite(
// idQuote = quoteId,
// iduser = currentUserState.id)) }
NavBar(
currentUserVM = currentUserVM,
@ -120,15 +120,15 @@ fun QuotePage(
)
Column {
FunctionalIcon(
isFavorite = favorite,
userId = currentUserState.id,
quoteId = quoteId,
context = context,
quoteInformationUserVM = quoteInformationUserVM,
quoteInformationUserState = quoteInformationUserState,
quote = quote
)
// FunctionalIcon(
// isFavorite = favorite,
// userId = currentUserState.id,
// quoteId = quoteId,
// context = context,
// quoteInformationUserVM = quoteInformationUserVM,
// quoteInformationUserState = quoteInformationUserState,
// quote = quote
// )
QuoteText(
text = '"' + quote.content + '"'
)

@ -26,6 +26,7 @@ import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@ -47,6 +48,7 @@ import com.example.what_the_fantasy.ui.components.ErrorMessageProfileComponent
import com.example.what_the_fantasy.ui.components.VisibleIconPasswordComponent
import com.example.what_the_fantasy.ui.states.SignInUserState
import com.example.what_the_fantasy.ui.viewModels.SignInUserViewModel
import kotlinx.coroutines.launch
@Composable
fun SignUpPage(navControllerLogin: () -> Unit, signInUserVM :SignInUserViewModel,signInState : SignInUserState) {
@ -91,7 +93,7 @@ fun SignUpPage(navControllerLogin: () -> Unit, signInUserVM :SignInUserViewModel
ConnexionButtonSign(R.string.ButtonSignUp,18, Color.White, Color.Black, signInState.username, signInState.email, signInState.password, signInState.confirmPassword, signInUserVM, navControllerLogin)
SpaceHeightComponent(16)
ReturnLogin(R.string.ButtonLogin,12, Color.White, navController = navControllerLogin)
ReturnLogin(R.string.ButtonLogin,12, MaterialTheme.colorScheme.onBackground, navController = navControllerLogin)
}
}
@ -219,8 +221,11 @@ fun ConnexionButtonSign(
val invalidRegex = """^[a-zA-Z0-9]*$""".toRegex()
val coroutineScope = rememberCoroutineScope()
Button(
onClick = {
coroutineScope.launch {
emailError = !isValidEmail(email)
passwordError = !arePasswordsMatching(password, confirmPassword)
usernameError = username.isBlank() && !username.matches(invalidRegex)
@ -232,6 +237,7 @@ fun ConnexionButtonSign(
navController() // retour à la page login
}
}
}
},
colors = ButtonDefaults.buttonColors(containerColor = colorButton),
modifier = Modifier.fillMaxWidth(),

@ -2,6 +2,7 @@ package com.example.what_the_fantasy.ui.viewModels
import android.util.Log
import androidx.lifecycle.ViewModel
import com.example.what_the_fantasy.data.services.ServicesAPI
import com.example.what_the_fantasy.data.services.ServicesStub
import com.example.what_the_fantasy.ui.states.AuthUserState
import kotlinx.coroutines.flow.MutableStateFlow
@ -10,7 +11,8 @@ import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
class AuthUserViewModel : ViewModel(){
private val services = ServicesStub() // faire repository qui gère les services Stub et API
//private val services = ServicesStub()
private val services = ServicesAPI() // faire repository qui gère les services Stub et API
private val _userState = MutableStateFlow(AuthUserState())
val userState : StateFlow<AuthUserState> = _userState.asStateFlow()
@ -24,7 +26,7 @@ class AuthUserViewModel : ViewModel(){
_userState.update { it.copy(password=password) }
}
fun validLogin(username : String, passwd : String, navController: (Int) -> Unit, initialierCurrentUser : (Int) -> Unit) : Boolean{
return services.validLogin(username,passwd, navController, initialierCurrentUser)
suspend fun validLogin(username : String, passwd : String, navController: (Int) -> Unit, initialierCurrentUser : (Int) -> Unit, currentUserViewModel: CurrentUserViewModel) : Boolean{
return services.validLogin(username,passwd, navController, initialierCurrentUser,currentUserViewModel)
}
}

@ -3,6 +3,8 @@ package com.example.what_the_fantasy.ui.viewModels
import android.util.Log
import androidx.lifecycle.ViewModel
import com.example.what_the_fantasy.data.model.SrcLanguage
import com.example.what_the_fantasy.data.model.User
import com.example.what_the_fantasy.data.services.ServicesAPI
import com.example.what_the_fantasy.data.services.ServicesStub
import com.example.what_the_fantasy.ui.states.CurrentUserState
import kotlinx.coroutines.flow.MutableStateFlow
@ -11,21 +13,31 @@ import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
class CurrentUserViewModel : ViewModel(){
private val services = ServicesStub() // faire repository qui gère les services Stub et API
//private val services = ServicesStub()
private val services = ServicesAPI() // faire repository qui gère les services Stub et API
private val _currentUserState = MutableStateFlow(CurrentUserState())
var currentUserState : StateFlow<CurrentUserState> = _currentUserState.asStateFlow()
fun initialiseCurrentUser(index : Int){
services.getUserById(index)?.let {
suspend fun initialiseCurrentUser(index : Int){
services.getUserById(index).let {
setId(it.id)
setUsername(it.username)
setEmail(it.email)
setPassword(it.password)
setLangue(it.langage)
setLangue(it.langage) // A rajouter quand on aura le langage
setImage(it.imgUrl)
}
}
fun setUser(user: User) {
_currentUserState.value = CurrentUserState(
id = user.id,
username = user.username,
email = user.email,
password = user.password,
imagePath = user.imgUrl,
)
}
fun clearCurrentUser(){
@ -59,36 +71,44 @@ class CurrentUserViewModel : ViewModel(){
fun editUsername(username : String, index : Int) : Boolean{
_currentUserState.update {it.copy(username = username)}
return services.EditUsername(username, index)
suspend fun editUsername(username: String, index: Int): Boolean {
if (!services.EditUsername(username, index, this)) {
_currentUserState.update {
it.copy(username = username)
}
return true
}
return false
}
suspend fun editEmail(email : String, index : Int) : Boolean{
fun editEmail(email : String, index : Int) : Boolean{
if(!services.EditEmail(email, index, this)){
_currentUserState.update {
it.copy(email = email)
}
return services.EditEmail(email, index)
return true
}
return false
}
fun editPassword(password : String, index : Int){
services.EditPasswd(password, index)
suspend fun editPassword(password : String, index : Int){
services.EditPasswd(password, index, this)
}
fun editLangue(index : Int){
val langage = services.ChangeLangage(index)
suspend fun editLangue(index : Int){
val langage = services.ChangeLangage(index, this)
_currentUserState.update {
it.copy(langage = langage)
}
}
fun editImage(index : Int){
val image = services.EditImage(index)
_currentUserState.update {
it.copy(imagePath = image)
}
suspend fun editImage(index : Int){
// _currentUserState.update {
// it.copy(imagePath = services.EditImage(index, this))
// }
}
}

@ -1,20 +1,23 @@
package com.example.what_the_fantasy.ui.viewModels
import androidx.lifecycle.ViewModel
import com.example.what_the_fantasy.data.services.ServicesAPI
import com.example.what_the_fantasy.data.services.ServicesStub
import com.example.what_the_fantasy.ui.states.SignInUserState
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
class SignInUserViewModel: ViewModel() {
private val services = ServicesStub() // faire repository qui gère les services Stub et API
private val services = ServicesAPI() // faire repository qui gère les services Stub et API
private val _userState = MutableStateFlow(SignInUserState())
val userState : StateFlow<SignInUserState> = _userState.asStateFlow()
fun createUser(username: String, email: String, passwd: String) : Boolean{
suspend fun createUser(username: String, email: String, passwd: String) : Boolean{
return services.CreateUser(username, email, passwd)
}
fun setUsername(username : String){

@ -4,24 +4,16 @@ import org.junit.Assert.assertEquals
import org.junit.Test
import com.example.what_the_fantasy.data.services.IServices
import com.example.what_the_fantasy.data.services.ServicesStub
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
class UnitTestQuote {
private val services : IServices = ServicesStub()
@Test
fun testGetQuote_OK(){
fun testGetQuote(){
val quote = services.getQuote(1)
assertEquals("All we have to decide is what to do with the time that is given us.",quote?.content)
}
@Test
fun testGetQuote_Fake(){
val quote = services.getQuote(-1)
assertEquals(null,quote?.content)
}
@Test
fun testGetSomeQuote_OK(){
val quote = services.getSomeQuotes(4,1)
@ -29,19 +21,13 @@ class UnitTestQuote {
}
@Test
fun testGetSomeQuoteIndexNegatif(){
fun testGetSomeQuoteNegatif(){
val quote = services.getSomeQuotes(-1,1)
assertEquals(1,quote.size)
}
@Test
fun testGetSomeQuotePageNegatif(){
val quote = services.getSomeQuotes(1,-1)
assertEquals(1,quote.size)
}
@Test
fun testGetSomeQuoteIndex0(){
fun testGetSomeQuote0(){
val quote = services.getSomeQuotes(0,1)
assertEquals(0,quote.size)
}
@ -140,22 +126,5 @@ class UnitTestQuote {
assertEquals(0,quote.size)
}
@Test
fun testIsFavorite_OK(){
assertTrue(services.isFavorite(1,10))
}
@Test
fun testIsFavorite_FakeQuote(){
assertFalse(services.isFavorite(-1,10))
}
@Test
fun testIsFavorite_FakeUser(){
assertFalse(services.isFavorite(1,-1))
}
}

@ -34,23 +34,6 @@ class UnitTestUser {
)
}
@Test
fun testCreateUserEmptyUsername(){
assertFalse(services.CreateUser("", "email", "passwd")
)
}
@Test
fun testCreateUserEmptyEmail(){
assertFalse(services.CreateUser("usernameEmptyEmail", "", "passwd")
)
}
@Test
fun testCreateUserEmptyPassword(){
assertFalse(services.CreateUser("usernameEmptyPassword", "email", "")
)
}
@Test
fun testUserEditUsername_OK(){
services.CreateUser("username4", "email4", "passwd")

@ -3,6 +3,9 @@ agp = "8.6.0"
bcrypt = "0.4"
coilCompose = "2.2.1"
coilComposeVersion = "1.4.0"
converterGson = "2.9.0"
gson = "2.10.1"
kotlin = "1.9.0"
coreKtx = "1.10.1"
junit = "4.13.2"
@ -15,12 +18,16 @@ navigationCompose = "2.8.6"
navigationCommonAndroid = "2.9.0-alpha05"
engageCore = "1.5.6"
lifecycle = "2.8.0"
retrofit = "2.9.0"
[libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
bcrypt = { module = "org.mindrot:jbcrypt", version.ref = "bcrypt" }
coil-compose = { module = "io.coil-kt:coil-compose", version.ref = "coilCompose" }
coil-compose-v140 = { module = "io.coil-kt:coil-compose", version.ref = "coilComposeVersion" }
converter-gson = { module = "com.squareup.retrofit2:converter-gson", version.ref = "converterGson" }
gson = { module = "com.google.code.gson:gson", version.ref = "gson" }
junit = { group = "junit", name = "junit", version.ref = "junit" }
androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
@ -40,6 +47,7 @@ engage-core = { group = "com.google.android.engage", name = "engage-core", versi
android-lifecycle-viewmodel ={ group = "androidx.lifecycle", name ="lifecycle-viewmodel-compose", version.ref ="lifecycle"}
android-lifecycle-viewmodel-runtime-ktx ={ group = "androidx.lifecycle", name ="lifecycle-viewmodel-ktx", version.ref ="lifecycle"}
retrofit = { module = "com.squareup.retrofit2:retrofit", version.ref = "retrofit" }
[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }

Loading…
Cancel
Save