Laravel AssertJsonCount on a nested array - json

How can I call assertJsonCount using an indexed, nested array?
In my test, the following JSON is returned:
[[{"sku":"P09250"},{"sku":"P03293"}]]
But attempting to use assertJsonCount returns the following error:
$response->assertJsonCount(2);
// Failed asserting that actual size 1 matches expected size 2.

This may or may not be specific to Laravel. Although a Laravel helper is involved, this issue may occur elsewhere.
assertJsonCount utilises the PHPUnit function PHPUnit::assertCount which uses a laravel helper data_get, which has the following signature:
/**
* Get an item from an array or object using "dot" notation.
*
* #param mixed $target
* #param string|array|int $key
* #param mixed $default
* #return mixed
*/
function data_get($target, $key, $default = null)
{
if (is_null($key)) {
return $target;
}
...
We can see that the JSON returned is a nested array, so logically we should pass in a key of 0.
$response->assertJsonCount($expectedProducts->count(), '0');
However this will be ignored as assertCount function checks if a key has been passed using is_null.
To overcome this, we can count all children of 0:
$response->assertJsonCount($expectedProducts->count(), '0.*');
This will produce the desired result.

Related

phpunit test methods that take data from db

in my app I have a special class to work with DB.
And I have methods that SELECT data from BD and return the result as an array. But when I try to cover this methods with PHPUnit, I always have NULL in return.
here is my piece of code
public function getData($id) {
$selectQuery = $dataBase->query('SELECT * FROM table WHERE id = :id');
$selectQery->bindInt(':id', $id);
$selectQuery->execute();
$result = $selectQuery->toArray();
return $result;
}
before getting result I can see with debuger that SQL query is ok, ID is binded and the method has to return an array. and it returns if to run the method in my app. But the test gives NULL result.
How can I cover this method with tests and make sure that it returns a correct array of data?

Returning all items /whats-new API call

We are using self-hosted ActiveCollab v5.13.60 and I'm trying to generate a list of completed projects and tasks given a specific date. I've been toying with /whats-new/daily/ API request since it also gives a related object so I can pull in the project/task name easily.
From what I can tell the request only returns the last 50 items, if there are more than 50 items, then additional requests can be made with a ?page=X parameter.
Is there a way this request can return an un-paginated list, or all items for a given day?
Thanks!
Unfortunately not, you have to keep requesting the next page until there is nothing returned and then combine all of the results.
Within our in-house application, we have the following function (in PHP)
/**
* Get pages of data with passed url
* #param [string] $url The api endpoint
* #return [array] All your data
*/
function getPagedData($url) {
// Get all the projects in active collab
$page = 1;
$paged_records = array();
$paged_records_results = $this->activeCollabClient->get($url . '?page=' . $page)->getJson();
$paged_records = array_merge($paged_records, $paged_records_results);
// Loop through pages
while ($paged_records_results = $this->activeCollabClient->get($url . '?page=' . ++$page)->getJson()) {
$paged_records = array_merge($paged_records, $paged_records_results);
}
return $paged_records;
}
It can then be called, passing the URL. In your case it could be used like:
getPagedData('whats-news/daily');
You will then get an array returned with all of the information contained.

yii2 App Starting With An Error

I am experiencing a strange error when I start my Yii2 app! Please need your help on this. Here is the what I get:
PHP Warning – yii\base\ErrorException
mb_strlen() expects parameter 1 to be string, array given
1. in /var/www/yii2/basic/vendor/yiisoft/yii2/helpers/BaseStringHelper.php at line 31
22232425262728293031323334353637383940
{
/**
* Returns the number of bytes in the given string.
* This method ensures the string is treated as a byte array by using `mb_strlen()`.
* #param string $string the string being measured for length
* #return integer the number of bytes in the given string.
*/
public static function byteLength($string)
{
return mb_strlen($string, '8bit');
}
/**
* Returns the portion of string specified by the start and length parameters.
* This method ensures the string is treated as a byte array by using `mb_substr()`.
* #param string $string the input string. Must be one character or longer.
* #param integer $start the starting position
* #param integer $length the desired portion length. If not specified or `null`, there will be
* no limit on length i.e. the output will be until the end of the strin
I happened an the same error message copying an external component in my project in my case I solved the problem by running
composer update

where_in codeigniter error if array is empty

I'm using Codeigniter 2. I'm trying to make a mysql query using Active Record. The problem is I got error when array passed to where_in is empty. I'm asking if there any way to ignore where_in condition if the array is empty
This the condition example :
$this->db->where_in('p.brand_id', $brands);
And this is the error I got :
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ') AND p.brand_id IN ()
Just don't call where_in() if the array is empty.
if(is_array($brands) && count($brands) > 0){
$this->db->where_in('p.brand_id', $brands);
}
I changed in Active Record (DB_active_rec.php class) and I Added this code to Ignore where_in condition if values array's empty. So it's works now for me.
The code I added is between //#begin and //#end
/**
* Where_in
*
* Called by where_in, where_in_or, where_not_in, where_not_in_or
*
* #param string The field to search
* #param array The values searched on
* #param boolean If the statement would be IN or NOT IN
* #param string
* #return object
*/
protected function _where_in($key = NULL, $values = NULL, $not = FALSE, $type = 'AND ')
{
if ($key === NULL OR $values === NULL)
{
return;
}
//#begin
// Ignore where_in condition if values array's empty
if(is_array($values) && empty($values))
{
return $this;
}
//#end
// More method stuff

In AS3, how to check if two JSON objects are equal?

Title pretty much says it. I have two JSON objects and I want to know if they are equal (have all the same property values).
I could stringify them both, but I'm not sure if two equal objects will always produce the same output:
E.g:
{
"firstName": "John",
"lastName": "Smith",
"age": 25,
"favoriteColors": ["blue", "green", "red"]
}
Is a different string from:
{
"age": 25,
"lastName": "Smith",
"firstName": "John",
"favoriteColors": ["blue", "green", "red"]
}
But as objects they have identical properties.
There is a method for this in the Flex SDK. It is in the class ObjectUtil. Here is the description from the source :
/**
* Compares the Objects and returns an integer value
* indicating if the first item is less than greater than or equal to
* the second item.
* This method will recursively compare properties on nested objects and
* will return as soon as a non-zero result is found.
* By default this method will recurse to the deepest level of any property.
* To change the depth for comparison specify a non-negative value for
* the depth parameter.
* #param a Object.
* #param b Object.
* #param depth Indicates how many levels should be
* recursed when performing the comparison.
* Set this value to 0 for a shallow comparison of only the primitive
* representation of each property.
* For example:
* var a:Object = {name:"Bob", info:[1,2,3]};
* var b:Object = {name:"Alice", info:[5,6,7]};
* var c:int = ObjectUtil.compare(a, b, 0);In the above example the complex properties of a and
* b will be flattened by a call to toString()
* when doing the comparison.
* In this case the info property will be turned into a string
* when performing the comparison.
* #return Return 0 if a and b are null, NaN, or equal.
* Return 1 if a is null or greater than b.
* Return -1 if b is null or greater than a.
* #langversion 3.0
* #playerversion Flash 9
* #playerversion AIR 1.1
* #productversion Flex 3
*/
public static function compare (a:Object, b:Object, depth:int=-1) : int;
If you don't want the whole SDK maybe you can just get this function/class and use that source.
You can see the source here. Most of the work is done in the function internalCompare.
Edit: Barış' answer is the best option, as it's tried and tested. Just in case this comes in handy for someone though:
Given that JSON values are limited to a small set of simple types, it should be possible to recurse through the properties fairly easily. Something along these lines works with your example:
private function areEqual(a:Object, b:Object):Boolean {
if (a === null || a is Number || a is Boolean || a is String) {
// Compare primitive values.
return a === b;
} else {
var p:*;
for (p in a) {
// Check if a and b have different values for p.
if (!areEqual(a[p], b[p])) {
return false;
}
}
for (p in b) {
// Check if b has a value which a does not.
if (!a[p]) {
return false;
}
}
return true;
}
return false;
}
Maybe you can convert the two objects to string then compare them
function compareJSON(a:Object, b:Object):Boolean
{
return JSON.stringify(a)===JSON.stringify(b);
}