Serenity-BDD jsonPath validation - jsonpath

I'm doing a serenity test and want to do some validation on json.
The json I got looks like
{
"devices": [
{
"deviceId": "0",
"deviceName": "Device-0",
"deviceStatus": "free",
"claimer": "-",
"claimedUntil": null
},
{
"deviceId": "1",
"deviceName": "Device-1",
"deviceStatus": "free",
"claimer": "-",
"claimedUntil": null
},
...
]
}
The order of the devices in this json is changing after I do some operations. I want to get a device by Id and want to validate the "claimer" and "deviceStatus".
My code look like:
#Then("see if device with id {string} is status {string}")
public void checkIfDeviceIsClaimed(String deviceId, String status) {
theActorInTheSpotlight().should(seeThatResponse("Get valid",
res -> res.statusCode(200)
.body("$.devices.?(#.deviceId == " + deviceId + ").claimer", equalTo(theActorInTheSpotlight().getName()))
.body("$.devices.?(#.deviceId == " + deviceId + ").deviceStatus", equalTo(status))));
}
And my error looks like
Step failed
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
Script1.groovy: 1: Unexpected input: 'restAssuredJsonRootObject.$.devices.[' # line 1, column 37.
restAssuredJsonRootObject.$.devices.[?(#.deviceId == 0)].claimer
^
Is there any possibility to change the JsonPath Lib or to achive the right behaviour?
Many thanks in advance

You can get result by using correct syntax.
.body("devices.find {it.deviceId == '" + deviceId + "'}.claimer", equalTo(theActorInTheSpotlight().getName()))
.body("devices.find {it.deviceId == '" + deviceId + "'}.deviceStatus", equalTo(status))));

Related

Firebase function transaction handle null value

I'm trying to use firebase function transaction, but as I see there is no official way to handle the first cached null value...
I'm trying to do the following:
var team = event.data.child('team').val();
var tip = event.data.child('tip').val();
console.log('tip: ' + tip + ' | team: ' +team)
const pathToValue = admin.database().ref('users/' + event.params.userId + '/coins');
const pathToTeamBetsValue = admin.database().ref('matches/' + event.params.matchId + '/opponents/' + team + "/bets");
return pathToValue.transaction(function (coins) {
if (coins) {
if (coins >= tip) {
pathToTeamBetsValue.transaction(function (teamBets) {
if (teamBets) {
teamBets = teamBets + tips;
return teamBets;
}
});
admin.database().ref('bets/' + event.params.matchId + '/' + event.params.userId + '/status').set('inProgress');
coins = coins - tip;
}
else {
console.warn(event.params.userId + " new bet on match " + event.params.matchId + " was not successfull! (not enough coin)")
//return coins;
}
}
return coins;
})
so far as you can see I get some value which what should be decreased from the user's coins... unfortunately till now I could only get the behaviour which sets null in the user's coin value.. please help

Range of all linkAttributed String in MutableAttributedString in swift

I have a mutableAttributedString in which few strings are linkAttributed,I want to find the Range of all link attributed string. How to do that in swift3 ?
When user start type # in textview i show list of few name. If user select any row then following method gets called.
func didSelectMemberId(_ model: BaseModel) {
var fullName = ""
if model.entityType == ReceiverType.Active.rawValue{
fullName = model.name
}else{
fullName = AtMention + model.name + " " + model.name2
}
let attributedString = NSMutableAttributedString(string:fullName, attributes:[NSFontAttributeName:(appNeedsAutoResize ? (UIUtils.getFontForApproprieteField(.headlineWithoutBold).font) : UIFont.systemFont(ofSize: 14))])
attributedString.addAttribute(NSLinkAttributeName, value: "connectmention://\(model.entityId.stringValue())", range: NSRange(location: 0, length: fullName.length))
attributedString.append(NSAttributedString(string: emptySpaceStringByUC, attributes:[NSFontAttributeName:(appNeedsAutoResize ? (UIUtils.getFontForApproprieteField(.headlineWithoutBold).font) : UIFont.systemFont(ofSize: 14))]))
self.composeBar.textView.textStorage.insert(attributedString, at:self.composeBar.textView.selectedRange.location)
}
self.composeBar.textView.selectedRange = NSMakeRange(self.composeBar.textView.selectedRange.location+fullName.length, 0 )
To get the link proprty I am using the following method
func getlinkActionRange(attributeString: NSAttributedString) -> [MentionStruct] {
var arrMentions = [MentionStruct]()
_ = attributeString.enumerateAttribute(NSLinkAttributeName, in: NSRange.init(location: 0, length: attributeString.length), options: [], using: { (value, range, stop) in
if let url = value {
let occurrence = (attributeString.string as NSString).substring(with:range)
arrMentions.append(MentionStruct(link: url as! String, text: occurrence, range: range))
}
})
return arrMentions
}
If user type anything after inserting that name , that type string also coming.

How to deserialize an array using c# dynamics?

I am trying to deserialize the following JSON to an array using C# dynamics:
[
{
"itemId":"15",
"quantity":101,
"eventTimestamp":"00000000-0000-0000-0000-000000000000",
"salesChannel":"1",
"unlimitedQuantity":false
},
{
"itemId":"15",
"quantity":101,
"eventTimestamp":"00000000-0000-0000-0000-000000000000",
"salesChannel":"2",
"unlimitedQuantity":false
}
]
I have already tried two different approaches, without success:
dynamic itemsBalance = JObject.Parse(content);
and
var itemBalanceType = new {
itemId = "", quantity = 0, eventTimestamp = "", salesChannel = ""
};
var itemsBalance = JsonConvert.DeserializeAnonymousType(content, itemBalanceType);
I am currently using C# dynamics with all other deserializations, and would not like to create classes for each response.
Is there any way to do this ?
Thanks
I found a solution:
JArray itemsBalance = JArray.Parse(content);
if (itemsBalance != null)
{
for (int i = 0; i < itemsBalance.Count; i++)
{
string itemBalanceJSON = itemsBalance[i].ToString();
dynamic itemBalance = JObject.Parse(itemBalanceJSON);
lbxResponse.Items.Add(itemBalance.itemId + " - " + itemBalance.salesChannel +": " + itemBalance.quantity.ToString());
}
}
Should there be any better, please let me know...
You could do it with less amount of code:
dynamic result = JsonConvert.Deserialize(content);
foreach(var entry in result)
{
lbxResponse.Items.Add(entry.itemId + " - " + entry.salesChannel + ": " + entry.quantity);
}

MVC ViewModel Custom Property not populating if null exists

I have a very simple viewmodel, based on a Customer domain model.
I'm adding one property to it: CustomerNameAddress which is made up of the CustomerName, Contact and Town of the domain model.
However, if any of CustomerName, Contact or Town are null - then CustomerNameAddress is also null.
Is there anyway of checking for null within my query below, and changing it to "", so that my viewmodel works correctly?
I had tried:
CustomerNameAddress = (p.CustomerName || "") + ", " + (p.Contact || "") + ", " + (p.Town || "")
... but VS advised Operator '||' cannot be applied to operands of type 'string' and 'string'
My controller code is below.
Thank you,
Mark
public JsonResult Lookup(string id)
{
string userName = null;
if (HttpContext.User.Identity.IsAuthenticated)
{
userName = HttpContext.User.Identity.Name;
}
var customers = from p in db.Customers
where p.UserName.Equals(userName)
select new CustomerLookupViewModel
{
CustomerId = p.CustomerId,
Email = p.Email,
CustomerNameAddress = p.CustomerName + ", " + p.Contact + ", " + p.Town
};
return Json(customers, JsonRequestBehavior.AllowGet);
}
UPDATE
I amended the code to:
But now get the error on p.Contact (underlined above) advising: Cannot implicitly convert type 'string' to 'bool'
However, my viewmodel clearly has Contact as a string:
public class CustomerLookupViewModel
{
public string CustomerNameAddress { get; set; }
public int CustomerId { get; set; }
[Required]
[Display(Name = "Customer Name")]
public string CustomerName { get; set; }
[Display(Name = "Customer Contact")]
public string Contact { get; set; }
2nd Update - now working
I updated the conditions to be enclosed in brackets, and it's now working:
CustomerNameAddress = ((p.CustomerName == null) ? "" : (p.CustomerName + ", ")) +
((p.Contact == null) ? "" : (p.Contact + ", ")) +
((p.Town == null) ? "" : (p.Town))
You can use condition operator ? :
CustomerNameAddress = (p.CustomerName == null || p.Contact == null || p.Town == null ) ? "" : p.CustomerName + ", " + p.Contact + ", " + p.Town
Query would be.
var customers = from p in db.Customers
where p.UserName.Equals(userName)
select new CustomerLookupViewModel
{
CustomerId = p.CustomerId,
Email = p.Email,
CustomerNameAddress = (p.CustomerName == null || p.Contact == null || p.Town == null ) ? "" : p.CustomerName + ", " + p.Contact + ", " + p.Town
};
Is there anyway of checking for null within my query below, and
changing it to "", so that my viewmodel works correctly?
something like this should do the trick
CustomerNameAddress =
(string.IsNullOrWhiteSpace(p.CustomerName) ? "" : (p.CustomerName + ", ")) +
(string.IsNullOrWhiteSpace(p.Contact) ? "" : (p.Contact + ", ")) +
(string.IsNullOrWhiteSpace(p.Town) ? "" : (p.Town + ", "))
You might want to create a procedure for that so you can reuse that simple logic.

queries in entity framework

i have to fetch those records where cityname like'zipcode' where zipcode is variable and apply conditions
var zipcd = (from u in db.ZipCodes1
where u.CityName.Contains(zipcode) && u.CityType == "D"
select u).ToList().Select(u => new Viewsearch
{
Zipcode = u.ZIPCode,
CityName = u.CityName,
stateabbr = u.StateAbbr
}).Distinct();
Viewsearch vs = (Viewsearch)zipcd;
if (zipcd.Count() > 1)
{
locations = "United States;" + vs.stateabbr + ";" + vs.CityName;
}
else if (locations == "")
{
locations = "United States;" + vs.stateabbr + ";" + vs.CityName;
}
else
{
locations = "United States;" + vs.stateabbr + ";" + vs.CityName + "," + locations;
}
if (zipcd.Count() > 3) is greater than 3
{
locations = locations.Replace(locations, "," + "<br>");
}
The problem is that you're casting an iterator to the type of a single element on the line
ViewSearch vs = (ViewSearch)zipcd.
If you want vs to be a single object, you must call First() or FirstOrDefault() on your collection:
ViewSearch vs = zipcd.First(); // Throws if there are no elements
ViewSearch vs = zipcd.FirstOrDefault(); // null if there are no elements
First of all I would suggest that you download and use the lovely LINQPad not only to run your LINQ queries first but also to learn from it (has a lot of samples that you can run right form there, no more config needed)
for your question:
var zipcd = (
from u in db.ZipCodes1
where u.CityName.Contains(zipcode) && u.CityType == "D"
select new Viewsearch
{
Zipcode = u.ZIPCode,
CityName = u.CityName,
stateabbr = u.StateAbbr
}).Distinct().ToList();
As you can see the query works:
Distinct at the end of your query uses IEqualityComparer, and I'm guessing you haven't defined one for Viewsearch. It would look something like this:
public class ViewsearchComparer : IEqualityComparer<Viewsearch>
{
public bool Equals(Viewsearch vs1, Viewsearch vs2)
{
// Implementation
}
public int GetHashCode(Viewsearch vs)
{
// Implementation
}
}
After you have that defined, you pass it into your distinct call:
.Select(u => new Viewsearch
{
Zipcode = u.ZIPCode,
CityName = u.CityName,
Stateabbr = u.StateAbbr
})
.Distinct(new ViewsearchComparer());

Resources