I am new to Rest Assured and I don't understand what kind of name is it expected. I am trying to deserialize response
Here is a test itself
import io.restassured.RestAssured.given
import io.restassured.builder.RequestSpecBuilder
import io.restassured.http.ContentType
import io.restassured.specification.RequestSpecification
import org.junit.Test
import pojos.UserData
class RestTest {
private var requestSpec: RequestSpecification = RequestSpecBuilder()
.setBaseUri("https://reqres.in")
.setContentType(ContentType.JSON)
.setBasePath("/api/users/")
.addQueryParam("page", 2)
.build()
#Test
fun getUsers() {
var response =
given().spec(requestSpec)
.`when`().get()
.then().extract().body().`as`(UserData.class)
}}
And here is pojo class
package pojos
import lombok.Builder
import lombok.Data
#Data
#Builder
class UserData {
var id: Int = 0
var email: String? = null
var first_name: String? = null
var last_name: String? = null
var avatar: String? = null
}
Screenshot
Related
I get below error while trying to access refferences from my Resources.kt file
.
Below shows my full code on LoginViewModel.kt
package lk.ac.kln.mit.stu.mobileapplicationdevelopment.viewmodel
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.bumptech.glide.load.engine.Resource
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.auth.FirebaseUser
import com.google.firebase.firestore.auth.User
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.launch
import javax.inject.Inject
#HiltViewModel
class LoginViewModel #Inject constructor(
private val firebaseAuth: FirebaseAuth
): ViewModel() {
private val _login = MutableSharedFlow<Resource<FirebaseUser>>()
// MutableSharedFlow<Resource<FirebaseUser>>()
val login = _login.asSharedFlow()
fun login(email: String, password: String){
viewModelScope.launch {
_login.emit(Resource.Loading())
}
firebaseAuth.signInWithEmailAndPassword(
email,password
).addOnSuccessListener {
viewModelScope.launch {
it.user?.let {
_login.emit(Resource.Success(it))
}
}
}.addOnFailureListener {
viewModelScope.launch {
_login.emit(Resource.Error(it.message.toString()))
}
}
}
}
Below shows the Resource.kt file
package lk.ac.kln.mit.stu.mobileapplicationdevelopment.util
sealed class Resource<T>(
val data: T? = null,
val message: String? = null
){
class Success<T>(data:T):Resource<T>(data)
class Error<T>(message:String):Resource<T>(message = message)
class Loading <T>: Resource<T>()
class Unspecified <T>: Resource<T>()
}
I have tried to implement using the same way I did for other view models.
I did the same approach to access same variables on RegisterViewModel.kt and it works without any error. Below is the code for that functioning view model
package lk.ac.kln.mit.stu.mobileapplicationdevelopment.viewmodel
import androidx.lifecycle.ViewModel
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.auth.FirebaseUser
import com.google.firebase.firestore.FirebaseFirestore
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.receiveAsFlow
import kotlinx.coroutines.runBlocking
import lk.ac.kln.mit.stu.mobileapplicationdevelopment.data.User
import lk.ac.kln.mit.stu.mobileapplicationdevelopment.util.*
import lk.ac.kln.mit.stu.mobileapplicationdevelopment.util.Constants.USER_COLLECTION
import javax.inject.Inject
#HiltViewModel
class RegisterViewModel #Inject constructor(
private val firebaseAuth : FirebaseAuth,
private val db: FirebaseFirestore
) : ViewModel() {
private val _register = MutableStateFlow<Resource<User>>(Resource.Unspecified())
val register : Flow<Resource<User>> = _register
private val _validation = Channel<RegisterFieldsState>()
val validation =_validation.receiveAsFlow()
fun createAccountWithEmailAndPassword(user: User, password: String) {
if (checkValidation(user, password)){
runBlocking {
_register.emit(Resource.Loading())
}
firebaseAuth.createUserWithEmailAndPassword(user.email, password)
.addOnSuccessListener {
it.user?.let {
saveUserInfo(it.uid, user)
// _register.value = Resource.Success(it)
}
}
.addOnFailureListener {
_register.value = Resource.Error(it.message.toString())
}
} else
{
val registerFieldsState = RegisterFieldsState(
validateEmail(user.email), validatePassword(password)
)
runBlocking {
_validation.send(registerFieldsState)
}
}
}
private fun saveUserInfo(userUid: String, user: User) {
db.collection(USER_COLLECTION)
.document(userUid)
.set(user)
.addOnSuccessListener {
_register.value = Resource.Success(user)
}
.addOnFailureListener {
_register.value = Resource.Error(it.message.toString())
}
}
private fun checkValidation(
user: User,
password: String
) : Boolean {
val emailValidation = validateEmail(user.email)
val passwordValidation = validatePassword(password)
val shouldRegister =
emailValidation is RegisterValidation.Success && passwordValidation is RegisterValidation.Success
return shouldRegister
}
}
Can someone help me with solving above issue please.Why it gives an error when trying to call Resource.Loading() from LoginViewModel.kt?
Please check import class in LoginViewModel, You are importing
import com.bumptech.glide.load.engine.Resource
It should be from this package lk.ac.kln.mit.stu.mobileapplicationdevelopment.util
When calling the getUser function, I make an HTTP request that retrieves information about a user.
If the user does not exist I get the error:
io.ktor.client.features.ClientRequestException: Client request(https://api.intra.chocolat.fr/v2/users/fff) invalid: 404 Not Found. Text: "{}"
I am unable to catch the error, and to continue the execution of the program.
package com.ksainthi.swifty.api
import android.util.Log
import androidx.annotation.Keep
import io.ktor.client.*
import io.ktor.client.call.*
import io.ktor.client.features.*
import io.ktor.client.features.json.*
import io.ktor.client.features.json.serializer.*
import io.ktor.client.features.observer.*
import io.ktor.client.request.*
import io.ktor.client.statement.*
import io.ktor.http.*
import kotlinx.serialization.*
class Api42Service {
#Keep
#Serializable
data class Token(
#SerialName("access_token") val accessToken: String,
#SerialName("token_type") val tokenType: String,
#SerialName("expires_in") val expiresIn: Int,
#SerialName("scope") val scope: String,
#SerialName("created_at") val createdAt: Int
)
#Keep
#Serializable
data class User(
#SerialName("id") val id: Int,
#SerialName("email") val email: String,
#SerialName("login") val login: String? = null,
#SerialName("first_name") val firstName: String? = null,
#SerialName("last_name") val lastName: String? = null,
)
private var accessToken: String? = null
private var client: HttpClient = HttpClient() {
install(JsonFeature) {
serializer = KotlinxSerializer(kotlinx.serialization.json.Json {
prettyPrint = true
isLenient = true
ignoreUnknownKeys = true
})
}
}
private val API_URL: String = "https://api.intra.chocolat.fr"
private val API_SECRET: String =
"<secret>"
private val API_UID: String =
"<api_uid>"
suspend fun requestAPI(
requestMethod: HttpMethod,
path: String,
params: MutableMap<String, String>?
): HttpResponse {
val urlString = API_URL
.plus(path)
return client.request(urlString) {
method = requestMethod
params?.forEach { (key, value) ->
parameter(key, value)
}
headers {
accessToken?.let {
println(it)
append(HttpHeaders.Authorization, "Bearer $it")
}
}
}
}
suspend fun getToken(): Token {
val params: MutableMap<String, String> = HashMap()
params["grant_type"] = "client_credentials";
params["client_secret"] = API_SECRET;
params["client_id"] = API_UID;
val response = requestAPI(HttpMethod.Post, "/oauth/token", params);
val token: Token = response.receive()
accessToken = token.accessToken
return token
}
suspend fun getUser(login: String): User? {
try {
val response = requestAPI(HttpMethod.Get, "/v2/users/$login", null);
val user: User = response.receive()
return user
} catch (cause: io.ktor.client.features.ClientRequestException) {
Log.d("wtf", "Catch your error here")
}
return null
}
}
Using the sample below (based on this source but with some changes), if the property #Id is named "id", the Neo4J (latest version) does not recognizes the attribute when the load is executed. But if I named it to any other name, such as "myId", the method works. Please, does anyone know why?
My code:
package sample
import org.neo4j.ogm.annotation.Id
import org.neo4j.ogm.annotation.NodeEntity
import org.neo4j.ogm.annotation.Relationship
import org.neo4j.ogm.config.Configuration
import org.neo4j.ogm.session.SessionFactory
#NodeEntity
data class Actor(
#Id
var id: Long?,
var name:String
) {
constructor() : this(-1, "")
#Relationship(type = "ACTS_IN", direction = "OUTGOING")
var movies = mutableSetOf<Movie>()
fun actsIn(movie: Movie) {
movies.add(movie)
movie.actors.add(this)
}
}
#NodeEntity
data class Movie(
#Id
var id: Long?,
var title:String,
var released:Int
) {
constructor() : this(-1L, "", -1)
#Relationship(type = "ACTS_IN", direction = "INCOMING")
var actors = mutableSetOf<Actor>()
}
class Sample {
private val uri = "bolt://localhost:7687"
val configuration = Configuration.Builder()
.uri(uri)
//.credentials("neo4j", "test")
.build()
val sessionFactory = SessionFactory(configuration, "sample")
fun save() {
val pack = SessionFactory::class.java.name
val l = java.util.logging.Logger.getLogger(pack)
l.setLevel(java.util.logging.Level.ALL)
val session = sessionFactory.openSession()
val develsAdvocate = Movie(1, "The Devil’s Advocate", 1997)
val theMatrix = Movie(2, "The Matrix", 1999)
val act = Actor(1, "Carrie-Anne Moss")
act.actsIn(theMatrix)
val keanu = Actor(2, "Keanu Reeves")
keanu.actsIn(theMatrix)
keanu.actsIn(develsAdvocate)
session.save(develsAdvocate)
session.save(theMatrix)
session.clear()
// ** Only works if the entity has a attribute #Id with name different as "id"
val theMatrixReloaded = session.load(Movie::class.java, theMatrix.id, 2)
println("Found ${theMatrixReloaded.title}")
for (actor in theMatrixReloaded.actors) {
println("Actor ${actor.name} acted in ${actor.movies.joinToString { it.title }}")
}
sessionFactory.close()
}
}
fun main(args: Array<String>) {
val neoInstance = Sample()
neoInstance.save()
}
I am having difficulties retrieving the information correctly from Firebase Firestore for my Recycler Adapter. I am not sure what I might be doing wrong but I used a Document Reference to get the required field but now it seems to just copy the same thing over and over, I want it to display each created users profile and display it on my RecyclerAdapter but am not sure what I should do and have tried different methods but get a
"No setter/field error" on my Model Class "Users".
This is my Firebase Schema
This is what it is outputting
This is what I have my code as so far
[Update]
This is what I have imported
import Models.User
import android.content.Intent
import android.content.res.Configuration
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.ActionBarDrawerToggle
import androidx.appcompat.widget.Toolbar
import androidx.core.view.GravityCompat
import androidx.drawerlayout.widget.DrawerLayout
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.firebase.ui.firestore.FirestoreRecyclerAdapter
import com.firebase.ui.firestore.FirestoreRecyclerOptions
import com.google.android.material.navigation.NavigationView
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.firestore.*
import com.squareup.picasso.Picasso
import de.hdodenhof.circleimageview.CircleImageView
import kotlinx.android.synthetic.main.all_nearby_users.*
import kotlinx.android.synthetic.main.toolbar_layout.*
Oncreate
auth = FirebaseAuth.getInstance()
val customUserId = auth.currentUser!!.uid
val db = FirebaseFirestore.getInstance()
val userRef = db.collection("sUsers").document(customUserId)
val userQuery = db.collection("sUsers").orderBy("Full Name", Query.Direction.DESCENDING).limit(10)
//User List Layout
all_users_nearby_list.layoutManager = LinearLayoutManager(this)
//Firestore
val firestoreRecyclerOptions: FirestoreRecyclerOptions<Users> = FirestoreRecyclerOptions.Builder<Users>()
.setQuery(userQuery, Users::class.java)
.build()
adapter = UserFirestoreRecyclerAdapter(firestoreRecyclerOptions)
all_users_nearby_list.adapter = adapter
Firestore Recycler Adapter
private inner class UserFirestoreRecyclerAdapter internal constructor
(firestoreRecyclerOptions: FirestoreRecyclerOptions<Users>): FirestoreRecyclerAdapter<Users, UserViewHolder>(firestoreRecyclerOptions) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UserViewHolder {
val userView = LayoutInflater.from(parent.context)
.inflate(R.layout.display_users_profile, parent, false)
return UserViewHolder(userView)
}
override fun onBindViewHolder(holder: UserViewHolder, position: Int, model: Users) {
holder.setFullname(model.fullname)
holder.setProfileimage(model.profileImage)
}
}
UserViewHolder
private inner class UserViewHolder internal constructor (private val pView: View) : RecyclerView.ViewHolder(pView) {
internal fun setFullname(fullname: String) {
val username = pView.findViewById<TextView>(R.id.usernameTextView)
val db = FirebaseFirestore.getInstance()
val docRef = db.collection("sUsers").document(auth.currentUser!!.uid)
docRef.get()
.addOnSuccessListener { document ->
if (document != null) {
Log.d("HomeActivity", "DocumentSnapshot data: ${document.data}")
username.text = document.getString("Full Name")
} else {
Log.d("HomeActivity", "No such document")
}
}
.addOnFailureListener { exception ->
Log.d("HomeActivity", "get failed with ", exception)
}
username.text = fullname
Log.d("HomeActivity", "Current Data: " + fullname)
}
internal fun setProfileimage(profileImage: String) {
val userProfileImage = pView.findViewById<CircleImageView>(R.id.profileUserImage)
Picasso.get().load(profileImage).into(userProfileImage)
}
}
Model Class
package Models
class Users(
var fullname: String= "",
var profileImage: String= "",
var uid: String? = "",
var haircut: Boolean? = null,
var waxing: Boolean? = null,
var nails: Boolean? = null,
var profileRatingBar: Float? = 1.0f
)
My onStart and onStop
override fun onStart() {
super.onStart()
adapter!!.startListening()
}
override fun onStop() {
super.onStop()
if (adapter != null) {
adapter!!.stopListening()
}
}
This is how I would write your RecyclerView. Key points:
Don't make a 2nd FireStore query inside the ViewHolder
Your Firestore schema must exactly match your model
Use lifecycle owner instead of onStart/onStop
Firebase UI doesn't capture the uid; so do this manually (see apply)
ViewHolder must "hold" the views as fields (to avoid calling find every time)
Model represents 1 object, so I name it "User" not "Users"
Set layoutManager in XML to reduce boilerplate in onCreate
Layout XML
<androidx.recyclerview.widget.RecyclerView
...
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:itemCount="5"
tools:listitem="#layout/display_users_profile"
... />
Activity onCreate
val query = FirebaseFirestore.getInstance()
.collection("sUsers") // Why not "users" ?
.orderBy("fullname", Query.Direction.DESCENDING)
.limit(10)
val options = FirestoreRecyclerOptions.Builder<User>()
.setLifeCycleOwner(this)
.setQuery(query) { it.toObject(User::class.java)!!.apply { uid = it.id } }
.build()
all_users_nearby_list.adapter = UserFirestoreRecyclerAdapter(options)
Adapter
internal class UserFirestoreRecyclerAdapter(options: FirestoreRecyclerOptions<User>) :
FirestoreRecyclerAdapter<User, UserViewHolder>(options) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
LayoutInflater.from(parent.context)
.inflate(R.layout.display_users_profile, parent, false)
.let { UserViewHolder(it) }
override fun onBindViewHolder(holder: UserViewHolder, position: Int, model: Users) =
holder.bind(model)
}
ViewHolder
internal class UserViewHolder(itemView: View) :
RecyclerView.ViewHolder(itemView) {
// Hold view refs
private val usernameTextView: TextView = itemView.userNameTextView
private val profileUserImage: ImageView = itemView.profileUserImage
internal fun bind(model: User) {
model.apply {
usernameTextView.text = fullname
Picasso.get().load(profileImage).into(profileUserImage)
}
}
}
Model
// Set sensible defaults here (or null if no sensible default)
data class User(
var uid: String = "",
var fullname: String= "",
var profileImage: String= "",
var haircut: Boolean = false,
var waxing: Boolean = false,
var nails: Boolean = false,
var profileRatingBar: Float? = null
)
I am following TornadoFX Guide from here, trying to run the sample wizard:
Wizard
and have implemented additional class Customer as follows, which is not running:
package com.example.demo.app
import javafx.beans.property.SimpleIntegerProperty
import javafx.beans.property.SimpleObjectProperty
import javafx.beans.property.SimpleStringProperty
import java.time.LocalDate
import java.time.Period
import tornadofx.*
class Customer(name: String, zip: Int, city: String, type: String) {
val zipProperty = SimpleIntegerProperty(zip)
var zip by zipProperty
val nameProperty = SimpleStringProperty(name)
var name by nameProperty
val cityProperty = SimpleStringProperty(city)
var city by cityProperty
val typeProperty = SimpleStringProperty(type)
var type by typeProperty
}
How can I add Customer.Type as referenced here, these classes are taken from the Guide:
package com.example.demo.view
import com.example.demo.app.Customer
import com.example.demo.app.CustomerModel
import tornadofx.*
class CustomerWizard : Wizard() {
val customer: CustomerModel by inject()
override val canGoNext = currentPageComplete
override val canFinish = allPagesComplete
init {
add(BasicData::class)
add(AddressInput::class)
}
}
class BasicData : View("Basic Data") {
val customer: CustomerModel by inject()
override val complete = customer.valid(customer.name)
override val root = form {
fieldset(title) {
field("Type") {
combobox(customer.type, Customer.Type.values().toList()) //Customer.Type, what is it?
}
field("Name") {
textfield(customer.name).required()
}
}
}
}
class AddressInput : View("Address") {
val customer: CustomerModel by inject()
override val complete = customer.valid(customer.zip, customer.city)
override val root = form {
fieldset(title) {
field("Zip/City") {
textfield(customer.zip) {
prefColumnCount = 5
required()
}
textfield(customer.city).required()
}
}
}
}
Error is as follows, leaving me to wonder what Type is? Enum, Class, ...? Error:(26, 50) Kotlin: Unresolved reference: Type
In the example above, Type is an enum, defined inside the Customer class, for example like this:
class Customer(name: String, zip: Int, city: String, type: Customer.Type) {
enum class Type {
Private, Company
}
val zipProperty = SimpleIntegerProperty(zip)
var zip by zipProperty
val nameProperty = SimpleStringProperty(name)
var name by nameProperty
val cityProperty = SimpleStringProperty(city)
var city by cityProperty
val typeProperty = SimpleObjectProperty<Type>(type)
var type by typeProperty
}
Note that typeProperty was changed to SimpleObjectProperty<Type> as well.