Im trying to validate the below json using Jsonpath. I am not able to validate any values after the "fieldMap". I get No JSON path error on everything that I tried. Please advise on how to validate the json string.
{
"Identifier": "ABC#SOMEYNC001#112#2018071900:00",
"someEventId": "Some001",
"Error": null,
"fieldMap": {
"responseKey [someType=APPLICANT, somebaseid=982465, somechildid=Some001]": {
"Gur.CalledFlag": "Y",
"Some.SomeField01": "null",
"Some.SomeField02": "null",
"Some.SomeField03": "null",
"Some.SomeField04": "null",
},
"responseKey [someType=APPLICANT, somebaseid=982455, somechildid=Some001]": {
"Gur.CalledFlag": "Y",
"Some.SomeField01": "null",
"Some.SomeField02": "null",
"Some.SomeField03": "null",
"Some.SomeField04": "null",
}
},
"someMap": {
"982465": {
"urlMap": "http://someurl.com"
},
"982455": {
"urlMap": "http://someurl.com"
}
}
}
And this is how I try to validate, in which I am failing.
this.mockMvc
.perform(get("/v1.0/someapi/ABC/{SomeEventId}",
"Some001",
.andExpect(status().isOk())
.andExpect(jsonPath("$.Identifier").value(notNullValue()))
.andExpect(jsonPath("$.someEventId").value("Some001")))
//.andDo(MockMvcResultHandlers.print())
.andExpect(jsonPath("Error").value(nullValue()));
//.andExpect(jsonPath("$.fieldMap").value(nullValue()))
//.andExpect(jsonPath("$..[Gur.CalledFlag]").value(nullValue()));
Im a novice in this, any help is greatly appreciated!
Related
This question already has answers here:
How to deep copy a map and then clear the original?
(6 answers)
Closed 4 years ago.
What am I trying to do?
Copy a "default" struct into a new one when needed, keeping all it's values.
Details
I am trying to copy a Chat struct:
type ChatData struct {
User map[string]map[string]string `json:"user"`
Chat map[string]string `json:"chat"`
}
type Chat struct {
Settings map[string]map[string]interface{} `json:"settings"`
Data ChatData `json:"data"`
}
I only need to do this when a new chat is introduced, and I check for membership in a map[string]Chat.
//data is a map[string]Chat
if _, exists := data[event.Chat]; !exists {
data[event.Chat] = data["default"]
}
The full default struct is:
{
"default": {
"settings": {
"eightball": {
"messages": [
"yes",
"no",
"maybe"
]
},
"main": {
"blacklistedCommands": [],
"blacklistedUsers": [],
"error": "there was an error - ",
"maxConsecutive": 5,
"permissions": "You don't have permissions for that command.",
"success": "The command was successful.",
"whitelistedCommands": [],
"whitelistedUsers": []
}
},
"data": {
"user": {
"default": {
"admin": "false",
"consecutiveCommands": "0",
"nickname": "",
"sentMessages": "0"
},
"total": {
"admin": "false",
"consecutiveCommands": "0",
"nickname": "",
"sentMessages": "0"
}
},
"chat": {
"commandSender": "",
"lastMessage": "",
"lastSender": "",
"lastTimestamp": "",
"wasCommand":""
}
}
}
}
What have I tried
data[event.Chat] = data["default"]
// causes a reference
data[event.Chat] = &data["default"]
// cannot use &data["default"] (type *Chat) as type Chat in assignment
data[event.Chat] = *data["default"]
// invalid indirect of data["default"] (type Chat)
Do I need to change my use of map[string]Chat to map[string]*Chat and go with the second option? Pointers and references are not my specialty, so help would be appreciated.
Edit
whoever thought I was copying a map, what are you smoking?
I have found in previous cases, that an easy (though not the most efficient) way to copy a complex structure is to Marshal it, and then Unmarshal it into a new variable. This can be done with a variety of encodings. Two easy ones (included in the stdlib) would be json and gob.
There are also plenty of libraries using reflection to achieve a similar goal: https://github.com/jinzhu/copier
But like I said, though not as efficient, this is easy to reason about and takes just a single, simple function to achieve. If performance matters you should prefer gob over json. If performance REALLY matters, then you should prefer another solution altogether.
If you know the data structure it is best for you to fully define your structs. It will be much easier to manage than complex maps and interfaces with reflection to cast data types. Here is a tool to help you convert JSON to Go structs. It isn't perfect and you have to confirm the data types. You may even want to rip out the internal structs and create types for them for readability and maintenance, but it will save you some time.
https://mholt.github.io/json-to-go/
package main
import (
"encoding/json"
"fmt"
"log"
)
var rawDataExample = []byte(`{
"default": {
"settings": {
"eightball": {
"messages": [
"yes",
"no",
"maybe"
]
},
"main": {
"blacklistedCommands": [],
"blacklistedUsers": [],
"error": "there was an error - ",
"maxConsecutive": 5,
"permissions": "You don't have permissions for that command.",
"success": "The command was successful.",
"whitelistedCommands": [],
"whitelistedUsers": []
}
},
"data": {
"user": {
"default": {
"admin": "false",
"consecutiveCommands": "0",
"nickname": "",
"sentMessages": "0"
},
"total": {
"admin": "false",
"consecutiveCommands": "0",
"nickname": "",
"sentMessages": "0"
}
},
"chat": {
"commandSender": "",
"lastMessage": "",
"lastSender": "",
"lastTimestamp": "",
"wasCommand":""
}
}
}
}
`)
type Settings struct {
Default struct {
Settings struct {
Eightball struct {
Messages []string `json:"messages"`
} `json:"eightball"`
Main struct {
BlacklistedCommands []string `json:"blacklistedCommands"`
BlacklistedUsers []string `json:"blacklistedUsers"`
Error string `json:"error"`
MaxConsecutive int `json:"maxConsecutive"`
Permissions string `json:"permissions"`
Success string `json:"success"`
WhitelistedCommands []string `json:"whitelistedCommands"`
WhitelistedUsers []string `json:"whitelistedUsers"`
} `json:"main"`
} `json:"settings"`
Data struct {
User struct {
Default struct {
Admin string `json:"admin"`
ConsecutiveCommands string `json:"consecutiveCommands"`
Nickname string `json:"nickname"`
SentMessages string `json:"sentMessages"`
} `json:"default"`
Total struct {
Admin string `json:"admin"`
ConsecutiveCommands string `json:"consecutiveCommands"`
Nickname string `json:"nickname"`
SentMessages string `json:"sentMessages"`
} `json:"total"`
} `json:"user"`
Chat struct {
CommandSender string `json:"commandSender"`
LastMessage string `json:"lastMessage"`
LastSender string `json:"lastSender"`
LastTimestamp string `json:"lastTimestamp"`
WasCommand string `json:"wasCommand"`
} `json:"chat"`
} `json:"data"`
} `json:"default"`
}
type Data struct {
Events map[string]Settings
}
func main() {
var settings Settings
err := json.Unmarshal(rawDataExample, &settings)
if err != nil {
log.Fatal(err)
}
event := "foo"
d := Data{
Events: make(map[string]Settings),
}
if _, ok := d.Events[event]; !ok {
// event doesn't exist
// add it
d.Events[event] = settings
fmt.Println("event added")
}
if _, ok := d.Events[event]; !ok {
// event exist, this will never be happen
// sanity check
fmt.Println("this will never be printed")
}
fmt.Printf("%+v\n", d)
}
Super simple fix, just wanted to get some input before I did it. Changed the map[string]Chat > map[string]*Chat and made a new *Chat, then copied the data.
data[event.Chat] = &Chat{}
*data[event.Chat] = *data["default"]
I can successfully use PactDslJsonArray.arrayMaxLike(3,3) to create a pact that validates a maximum of 3 items returned.
"body": [
{
"firstName": "first",
"lastName": "last",
"city": "test",
},
{
"firstName": "first",
"lastName": "last",
"city": "test",
},
{
"firstName": "first",
"lastName": "last",
"city": "test",
}
]
"body": {
"$": {
"matchers": [
{
"match": "type",
"max": 3
}
]
...
However, I would like to reuse the body from another request without the need to specify the attributes again.
DslPart body = new PactDslJsonBody()
.stringType("firstName","first")
.stringType("lastName","last")
.stringType("city", "test")
What I'm looking for is something like :
PactDslJsonArray.arrayMaxLike(3,3).template(body)
instead of
PactDslJsonArray.arrayMaxLike(3,3)
.stringType("firstName","first")
.stringType("lastName","last")
.stringType("city", "test")
Thanks
Dan
The point of the DSL is to do validations of the Pact interactions in code. Using a template kinda goes against that concept. What I would recommend is that if you have the same interactions in multiple places, then adding a shared function to add said interaction would be the best way to do so. For example:
private void personalDetailInteraction(DslPart part) {
return part.stringType("firstName","first")
.stringType("lastName","last")
.stringType("city", "test");
}
private void yourTest() {
personalDetailInteraction(
PactDslJsonArray.arrayMaxLike(3,3)
)
.stringType("blarg", "weee")
...
}
If it needs to be shared across different classes, create a InteractionUtils class that can be shared across. This is the best way to do it in my opinion because the compiler makes sure no mistakes are made while creating the interactions, which is kind of the point of the whole framework; to reduce human error.
I am trying to filter the data coming back from FindAll cause I only want data from a certain provider
// Data coming back from API
{
"-KDinaItb7lkHpai-DlG": {
"email": "johns#test.com",
"name": "John Smith",
"notes": "John is a great employee and is the best",
"phone": "215-543-9830",
"provider": "-KDhzbilOvv7Evuc5S_X"
},
"-KDjS0cCxFWQctcwXg0V": {
"email": "amanda#test.com",
"name": "Amanda Harrington",
"notes": "Amanda is a great employee",
"phone": "215-543-9830",
"provider": "-KDiokWebdhTNKTORWwn"
},
"-KDyf7pU_PyxRQSgFB59": {
"email": "lguy#test.com",
"name": "Larry Guy",
"notes": "He is a funny guy",
"phone": "702-454-2397",
"provider": "-KDhzbilOvv7Evuc5S_X"
}
}
// In the route
let providerId = model.get('provider').get('id');
this.store.findAll('employee').then(function(results) {
let prov = results.filterBy('provider', providerId);
console.log(prov);
});
When the console log happens and it returns an empty array. I think its because of the ID and its not looking at the nested object. Anyone got any thoughts?
Ok so your hash looks quite odd. Property name shouldn't be some generated hash.
code should be something like that.
I assume you have 1 wrapper object on index 0 within an array.
var filteredEmployees_promise = this.store.findAll('employee').then(function(results) {
var filteredResults = [];
Object.keys(Results[0]).forEach(key => {
var filteredObj = Results[0][key][providerId];
if(Ember.isPresent(filteredObj) {
filteredResults.pushObject(filteredObj)
}
});
return filteredResults;
});
And later
filterEmployees_promise.then(employees => { // Custom stuff })
I am trying to follow the datatable example for Ajax data source (objects) found here. I am using asp.net and have the following handler which receives my data, processes it and provides the response.
public class UsersHandler : IHttpHandler
{
private const string JsHeader = #"{{""data"" {0}}}";
public void ProcessRequest(HttpContext context)
{
IEnumerable<SystemUser> data = SystemUserLogic.LoadAllSystemUsers();
List<SimpleUser> userlist = new List<SimpleUser>();
foreach (SystemUser su in data)
{
SimpleUser simple = new SimpleUser();
simple.Id = su.Id;
simple.FullName = su.NameFirst;
simple.Email = "example#email.co.uk";
userlist.Add(simple);
}
string json = JsonConvert.SerializeObject(userlist, Formatting.Indented);
context.Response.ContentType = "text/plain";
context.Response.ContentEncoding = Encoding.UTF8;
context.Response.Cache.SetNoStore();
context.Response.Expires = -1;
context.Response.Write(String.Format(JsHeader, json));
}
which deliveries the correct response when I catch it in the browser and look at the data via the network traffic. My aspx page contains the following.
$('#table_id').DataTable({
"ajax": '/Handlers_New/UsersHandler.ashx',
"columns": [
{ "data": "Id" },
{ "data": "FullName" },
{ "data": "Email" },
{ "data": "KeyResource" }
]
});
However when the page loads, I am getting this error:
DataTables warning: table id=table_id - Invalid JSON response. For more information about this error, please see http://datatables.net/tn/1
The outputted data looks like this,
{"data" [
{
"Id": 1,
"FullName": "Admin",
"Email": "example#email.co.uk",
"KeyResource": false
},
{
"Id": 2,
"FullName": "Jon",
"Email": "example#email.co.uk",
"KeyResource": false
},
{
"Id": 3,
"FullName": "Stephen",
"Email": "example#email.co.uk",
"KeyResource": false
}, etc.....
Please tell me why I am getting this error. Should I be manipulating the json object differently, or am I missing something with the Jquery datatables?
I have managed to fix my issue amazingly due to jsonlint. I ran my code through that and it turns out I was missing a ':' in my jsHeader. So what I had was:
private const string JsHeader = #"{{""data"" {0}}}";
and what I have now which now works is:
private const string JsHeader = #"{{""data"": {0}}}";
Hope this helps any one else encountering a similar issue.
I was making a function to convert all dates in an object to strings and when I used the following function I got a error in FF "too much recursion". (It also fails in IE and chrome)
function datesToString(obj) {
if (obj instanceof Object) {
if (obj instanceof Date) {
obj = "this part does not matter";
} else {
for (var key in obj) { obj[key] = datesToString(obj[key]); }
}
}
return obj;
}
but when I changed it to use typeof it worked fine?
function datesToString(obj) {
if (obj && typeof obj == "object") {
if (obj instanceof Date) {
obj = "this part does not matter";
} else {
for (var key in obj) { obj[key] = datesToString(obj[key]); }
}
}
return obj;
}
It should be the same amount of recursion. Am I missing something? Why am I getting an error with the first example but not the second?
Update:
here is an example of the object I was using (in json form)
Contact = {
"LContactID": "00000000-0000-0000-0000-000000000000",
"CellPhone": "",
"HomePhone": "4564564560",
"OtherPhone": "",
"BirthDate": new Date(-62135575200000),
"SSN": "456456456",
"HowToContact": 1,
"ContactType": 3,
"Address1": "123 test",
"Address2": "apt. 1",
"City": "Valparaiso",
"State": "IN",
"Zip": "46383",
"FullAddress": "123 test, apt. 1",
"BuilderID": "",
"FullAddressWithCityState": "123 test\r\napt. 1\r\nValparaiso, IN 46383",
"WorkHours": "9-5",
"ContactTime": "",
"ContactMethod": "???",
"IsMilitaryOrSelfEmployed": false,
"AlternateContactName": "",
"AlternateContactPhone": "",
"ContactID": "00000000-0000-0000-0000-000000000000",
"Password": null,
"FirstName": "updatetest",
"MiddleName": null,
"LastName": "test_",
"Suffix": null,
"EmailAddress": null,
"EmailAddressAlternate": null,
"WorkPhone": "6546546540",
"WorkPhoneExt": null,
"CreatedOn": new Date(1263597309000),
"CreatedOnOverride": new Date(-62135575200000),
"ModifiedOn": new Date(1264014749000),
"SCRep": "",
"HBCRep": "",
"PPPRep": "",
"DPSRep": "",
"DRSRep": "",
"RDRep": "",
"OwnerID": "00000000-0000-0000-0000-000000000000",
"FullName": "updatetest test_",
"ImportID": 0,
"IncludeEmail": false,
"PreferredLanguage": 1,
"CarbonCopyList": [],
"HearAboutUs": 5,
"HearAboutUsOther": "",
"init": function() { },
"update": function() { },
"load": function() { }
}
It looks like when I remove the method parameters (init,update and load) it works with the instanceof example.
UPDATE: This is a ASP.Net ScriptManager problem it turns out. Sorry for not including the fact that I was working with an ASP.Net website.The ASP.Net ScriptManager prototypes methods to Function which causes an infinity loop when doing a recursive for in loop on a function.
(First, let me say that I tried your code on FF 3.5.7 and it didn't run into an infinite recursion. maybe you used a different input example?)
Anyway, to answer your questions:
(a) Why do you get an infinite recursion? Because an object may refer to itself. If o.f==o then calling your function on o will fire a subsequent call on o.f which is actually o and so on...
(b) Why the difference between the two versions? obj instanceof Object checks if obj is an instance of Object or an instance of a subclass thereof. Given that every Javascript object inherits from Object then this condition is trivially true, and is thus meaningless. Net result is that the first if always succeeds. On the other hand typeof obj == "object" checks that obj is an instance of Object. This may be false, for example, if obj is an instance of String (at which case typeof obj yields String). Hence, the difference.