jsonPath: how confirm the data returned is just one element? and when it is not an array - jsonpath

I am working with:
Spring MVC
Spring MVC Testing
Assuming that a #Controller working with #ResponseBody returns a set of domain objects represented in JSON format and through print() method I can confirm the following:
Body = [ {
"id" : "88",
"nombre" : "Manuel",
"apellido" : "Jordan",
"fecha" : 1449370807750
}, {
"id" : "87",
"nombre" : "Leonardo",
"apellido" : "Jordan",
"fecha" : 1449370807750
}, {
...
}, {
...
}, {
...
} ]
Observe that content is an array.
Through Spring MVC Testing and with hamcrest I have the following:
resultActions.andExpect(jsonPath('$').exists())
.andExpect(jsonPath('$').isArray())
.andExpect(jsonPath('$',hasSize(5)))
…
Until here all work fine.
But assuming the #Controller returns just one element (One Domain Object) and again through the print() method I can see the following:
Body = {
"id" : "100",
"nombre" : "Jesús Você",
"apellido" : "Mão Nuñez",
"fecha" : 1449372342312
}
Observe it is not an array
I have currently the following:
resultActions.andExpect(jsonPath('$').exists())
//.andExpect(jsonPath('$').isArray()) <--- fails
.andExpect(jsonPath('$.*', hasSize(4) ))
How I can confirm the data returned is just one element?
It when is not an array.
I mean, I want have the same approach/behaviour about the following from XML
<persona>
<id>100</id>
<nombre>Jesús Você</nombre>
<apellido>"Mão Nuñez"</apellido>
<fecha>2015-12-05T22:00:07.756-05:00</fecha>
</persona>
Through
resultActions.andExpect(xpath("persona").exists())
.andExpect(xpath("persona").nodeCount(1))
Practically, what is the equivalent of xpath("persona").nodeCount(1) to jsonPath?
Thanks

Related

React Native Firebase, equalTo() is being aplied wrong?

I have this database:
{
"interpreters" : [ null, {
"InterpreterID" : "1",
"Name" : "Pedro",
"languages" : [ "portuguese", "russian", "english", "german" ],
"latitude" : 37.633,
"latitudeDelta" : 0.0143,
"longitude" : -122.345,
"longitudeDelta" : 0.0134
}, {
"InterpreterID" : "2",
"Name" : "Paulo",
"languages" : [ "english", "portuguese" ],
"latitude" : 37.554,
"latitudeDelta" : 0.0143,
"longitude" : -122.245,
"longitudeDelta" : 0.0134
} ]
}
And I'm trying to get only interpreters that match with the language I want. For example, get only interpreters
that speak russian.
I'm doing like this:
database()
.ref()
.child('interpreters')
.orderByChild('languages')
.equalTo('russian')
.on('value', snapshot => {
setInterpreters(snapshot.val())
console.log(snapshot.val())
});
But it returns 'null'.
If I look for orderByChild('Name').equalTo('Pedro') then return Pedros data.
Maybe it's because languages is an array but I'm not sure how to get data from it and couldn't find how to do it.
The forEach method simple didn’t work without any error. The code ran fine but I couldn’t display anything.
I'm following firebase documentation and seems that there is nothing different.
What should I do ?
Thank you in advance.
Firebase doesn't natively support arrays, well it does in form of objects. An array that you send as
["Portuguese", "Russian"]
is converted to
{0: "Portuguese", 1: "Russian"}
Hence your queries don't work as expected. Firebase doesn't support querying inner values of arrays
The workaround
Firebase recommends changing your data to:
{
"portugese": true,
"russian": true
}
and then query as
.orderByChild('languages/portuguese')
.equalTo(true)

Query to json firebase object or redux state

I'm building my first web app with React, Redux and Firebase, it's about registering the assistance of students (alumnos) to lessons (clases). I've the following database structure (the same in Redux state, this.props).
"clases" : {
"-LpQkLyGXEd-Up8hExTx" : {
"alumnos" : [ "-LpKkSh0E5jiuM0JCCpS", "-LpQi33M-0OSS4Jvup8k" ],
"fechaClase" : "20-09-2019",
"profesor" : "Nacho",
"tema" : "Misión"
},
"-LpQmExVsWtW1uPHLK52" : {
"alumnos" : [ "-LpJvbXb2FjgZvvBv3ei", "-LpKkSh0E5jiuM0JCCpS", "-LpQi33M-0OSS4Jvup8k", "-LpQiDGlRWITax2t6U2A" ],
"fechaClase" : "22-09-2019",
"profesor" : "Nacho",
"tema" : "Bautismo"
},
"-LpQqZ_uWu8HxROagVjN" : {
"alumnos" : [ "-LpKkSh0E5jiuM0JCCpS", "-LpQi33M-0OSS4Jvup8k", "-LpQiPCS2cIK7opMNqyH" ],
"fechaClase" : "21-09-2019",
"profesor" : "Manzo, Ignacio",
"tema" : "Bautismo"
}
I want to select a student (alumno), and know which lessons have made. Do I have to make a double map to the object? Can you give some help?
This is the deployed app https://metanoia-ic.herokuapp.com/
This is my github repository: https://github.com/tonicanada/metanoia
Thanks!
I would use Object.keys to be able to use filter and include Array.prototype methods. Asuming that clases is the object containing all the state, I would do something like this:
const studentId = this.props.studentId; // or any other value
const clasesPerStudent = Object.keys(clases).filter(clase =>
clases[clase].alumnos.includes(studentId)
);

Decent data structure for Firebase messaging?

I'm trying to get started with Firebase and I just want to make sure that this data structure is optimized for Firebase.
The conversation object/tree/whatever looks like this:
conversations: {
"-JRHTHaKuITFIhnj02kE": {
user_one_id: "054bd9ea-5e05-442b-a03d-4ff8e763030b",
user_two_id: "0b1b89b7-2580-4d39-ae6e-22ba6773e004",
user_one_name: "Christina",
user_two_name: "Conor",
user_one_typing: false,
user_two_typing: false,
last_message_text: "Hey girl, what are you doing?",
last_message_type: "TEXT",
last_message_date: 0
}
}
and the messages object looks like so:
messages: {
"-JRHTHaKuITFIhnj02kE": {
conversation: "-JRHTHaKuITFIhnj02kE",
sender: "054bd9ea-5e05-442b-a03d-4ff8e763030b",
message: "Hey girl, what are you doing?",
message_type: "TEXT",
message_date: 0
}
}
Is storing the name relative to the user in the conversation object needed, or can I easily look up the name of the user by the users UID on the fly? Other than the name question, is this good? I don't want to get started with a really bad data structure.
Note: Yes, i know the UID for the conversation & message are the same, I got tired of making up variables.
I usually model the data that I need to show in a single screen in a single location in the database. That makes it possible to retrieve that data with a single read/listener.
Following that train of thought it makes sense to keep the user name in the conversation node. In fact, I usually keep the username in each message node too. The latter prevents the need for a lookup, although in this case I might be expanding the data model a bit far for the sake of keep the code as simple as possible.
For the naming of the chat: if this is a fairly standard chat app, then user may expect to have a persistent 1:1 chat with each other, so that every time you and I chat, we end up in the same room. A good approach for accomplishing that in the data model, can be found in this answer: Best way to manage Chat channels in Firebase
I don't think you structured it right. You should bare in mind "What if" complete analysis.
Though, I would recommend structuring it this way (I made it up for fun, not really tested in-terms of performance when getting a huge traffic. but you can always do denormalization to increase performance when needed):
{
"conversation-messages" : {
"--JpntMPN_iPC3pKDUX9Z" : {
"-Jpnjg_7eom7pMG6LDe1" : {
"message" : "hey! Who are you?",
"timestamp" : 1432165992987,
"type" : "text",
"userId" : "user:-Jpnjcdp6YXM0auS1BAT"
},
"-JpnjibdwWpf1k-zS3SD" : {
"message" : "Arya Stark. You?",
"timestamp" : 1432166001453,
"type" : "text",
"userId" : "user:-OuJffgdYY0jshTFD"
},
"-JpnkqRjkz5oT9sTrKYU" : {
"message" : "no one. a man has no name.",
"timestamp" : 1432166295571,
"type" : "text",
"userId" : "user:-Jpnjcdp6YXM0auS1BAT"
}
}
},
"conversations-metadata" : { // to show the conversation list from all users for each user
"-JpntMPN_iPC3pKDUX9Z" : {
"id": "-JpntMPN_iPC3pKDUX9Z",
"date":995043959933,
"lastMsg": "no one. a man has no name.",
"messages_id": "-JpntMPN_iPC3pKDUX9Z"
}
},
"users" : {
"user:-Jpnjcdp6YXM0auS1BAT" : {
"id" : "user:-Jpnjcdp6YXM0auS1BAT",
"name" : "many-faced foo",
"ProfileImg" : "...."
"conversations":{
"user:-Yabba_Dabba_Doo" : {
"conversation_id": "-JpntMPN_iPC3pKDUX9Z",
"read" : false
}
}
},
"user:-Yabba_Dabba_Doo" : {
"id" : "user:-Yabba_Dabba_Doo",
"name" : "Arya Stark",
"ProfileImg" : "...."
"conversations":{
"user:-Jpnjcdp6YXM0auS1BAT" : {
"conversation_id": "-JpntMPN_iPC3pKDUX9Z",
"read" : true
}
}
}
}
}

Querying nested values with Q4 2015 version 1.1.3

Based on Tom's answer to this question, I'm getting the following error when trying to query a nested field on a collection.
I'm trying to get a single user object with personalityExams.id.extId = 24232. I'd like to know the best way to query this, and how to form an index rule for it.
Here is what the user looks like in firebase
{
"users": {
"93306b91-d5ba-4e06-838c-0ab85fd58783": {
"createdOn" : 1451495976870,
"email" : "iyad.bitar#gmail.com",
"firstName" : "Iyad",
"lastModifiedOn" : 1451590413654,
"lastName" : "Bitar",
"mobile" : "34234333",
"provider" : "password",
"userType" : "JS",
"personalityExams": [
{
"extId": "24232",
"skills": ["teaching"]
}
]
}
In my javascript, I'm trying to get it like so:
(new Firebase("https://hirely-dev.firebaseio.com/users")).orderByValue("personalityExams/extId").equalTo("24232").on("value", function(snapshot) {user1 = snapshot.val();});
Error:
Uncaught Error: Query.orderByValue failed: Was called with 1 argument. Expects none.
at Error (native)
at x (http://localhost:7200/lib/firebase/firebase.js:20:1074)
at U.g.Fg (http://localhost:7200/lib/firebase/firebase.js:233:343)
at <anonymous>:2:59
at Object.InjectedScript._evaluateOn (<anonymous>:875:140)
at Object.InjectedScript._evaluateAndWrap (<anonymous>:808:34)
at Object.InjectedScript.evaluate (<anonymous>:664:21)

How do you get a list of all developers and apps for an API in Apigee?

Say you have exposed an API Product in Apigee. You would like to get a list of all the developers and their apps that have registered for the API Product.
There is a call to return those, documented here:
http://apigee.com/docs/api/get-list-keys-apps-developers-or-companies-api-product
But the IDs it returns appear to be useless. If you try developers, for instance:
https://api.enterprise.apigee.com/v1/organizations/YOUR-ORG/apiproducts/YOUR-PRODUCT?query=list&entity=developers
you get back a list of IDs. But to find which developer a given ID relates to is impossible, as the call to get a developer:
http://apigee.com/docs/api/get-developer
only accepts an email address.
How can I get a list of all the developers and their apps registered for a given API product?
The Apps a developer has is nested in each developer:
https://api.enterprise.apigee.com/v1/o/{your org}/developers
will return a list of developers like this:
["email#domain.com", "email2#domain2.com"]
Then you have to loop through each developer to get a list of their apps:
https://api.enterprise.apigee.com/v1/o/{your org}/developers/tesla#weathersample.com
Which gives you a bunch of meta data including apps:
{
"apps" : [ "weather" ],
"companies" : [ ],
"email" : "tesla#weathersample.com",
"developerId" : "Hk5mmLw9kKIM95qF",
"firstName" : "Nikolai",
"lastName" : "Tesla",
"userName" : "Nikolai",
"organizationName" : "jokeindex",
"status" : "active",
"attributes" : [ ],
"createdAt" : 1357858239543,
"createdBy" : "noreply_admin#apigee.com",
"lastModifiedAt" : 1357858239543,
"lastModifiedBy" : "noreply_admin#apigee.com"
}
Finally, if you look at each app you can see the products associated with that developer app:
https://api.enterprise.apigee.com/v1/o/{your org}/developers/tesla#weathersample.com/apps/weather
Gets you this detail:
{
"accessType" : "read",
"appFamily" : "default",
"appId" : "030fdcea-cf97-40b1-96df-12084aea513c",
"attributes" : [ {
"name" : "Developer",
"value" : "tesla#weathersample.com"
}, {
"name" : "DisplayName",
"value" : "Weather"
}, {
"name" : "Notes",
"value" : "not yet"
}, {
"name" : "lastModifier",
"value" : ""
} ],
"callbackUrl" : "http://example.com/callback",
"createdAt" : 1363578857830,
"createdBy" : "adminui#apigee.com",
"credentials" : [ {
"apiProducts" : [ {
"apiproduct" : "weather",
"status" : "approved"
} ],
"attributes" : [ ],
"consumerKey" : "{key}",
"consumerSecret" : "{key}",
"expiresAt" : -1,
"scopes" : [ ],
"status" : "approved"
} ],
"developerId" : "Hk5mmLw9kKIM95qF",
"lastModifiedAt" : 1386042817268,
"lastModifiedBy" : "michael.bissell#apigee.com",
"name" : "weather",
"scopes" : [ ],
"status" : "approved"
}
Take a look at the Org Snapshot Tool on git if you want to interrogate the entire org with one script:
https://github.com/apigee/api-platform-samples/tree/master/tools
This will interrogate every developer and every app and put it into a nice tree structure in your file system for future reference.

Resources