How to pass an object as parameter in unit test? (laravel) - php

I have a data object below that I tried to test using postman. I just don't know how to make this possible also in laravel's unit testing. I have visited this link but it doesn't helped in my case.
{
"user_id": 1,
"name": "juan",
"address": [
"state": "Auckland",
"country": "New Zealand",
],
"school": [
{
"school_name": "Kristin School",
"year": 2016
},
{
"school_name": "ACG Parnell College",
"year": 2018
},
],
// and more...
}
How can we pass such an object above in unit testing? Is there any way to achieve this?
$response = $this->post('/logbooks/user', ['Authorization': 'Bearer' + $token]);

First to know that such tests are not a "unit test" type.
Note that the code will run and you should be alert to changes that running the code may entail (updating data in the database, contacting external providers).
Of course, all of this can be mocked, and it is recommended that you read about it carefully.
class FooTest extends TestCase {
public function testBar()
{
$response = $this->post('/api/v1/yourapi',
[
"user_id" => 1,
"name" => "juan",
"address" => [
"state" => "Auckland",
"country" => "New Zealand"
],
"school" => [
[
"school_name" => "Kristin School",
"year" => 2016
],
[
"school_name" => "ACG Parnell College",
"year" => 2018
]
]
]);
$response->assertStatus(200);
$response->assertJsonStructure([...]);
$response->assert....();
}
}
As I wrote in the comment below, the JSON you attached was invalid.
You treated the array as an object, adding unnecessary commas.
It is recommended to use an array that the IDE knows to recognize

As you can find in the Laravel docs for HTTP tests, you can send a php array as follows:
$payload = [
"user_id" => 1,
"name" => "juan",
"address" => [
"state" => "Auckland",
"country" => "New Zealand",
],
];
$response = $this->postJson(
'/logbooks/user', $payload, ['Authorization': 'Bearer' + $token]
);
It takes your php $payload array and encodes it as JSON and sends it.
If you have an object you can cast it with $myArray = (array) $myObject.

Related

How to use Google Cloud Healthcare API HttpBody class?

I'm having a hard time using a method setData() of the HttpBody class. I'm passing the parameter to the method as an object, but I recieve an error message.
How do I pass the parameter:
public function create(string $resource, $body)
{
$client = $this->googleClient();
$service = new CloudHealthcare($client);
$parent = "projects/my_project_id/locations/my_location/datasets/my_dataset/fhirStores/repository";
$httpBody = new HttpBody();
$httpBody->setContentType('application/fhir+json;charset=utf-8');
$httpBody->setData([
"resourceType" => "Patient",
"id" => "23434",
"meta" => [
"versionId" => "12",
"lastUpdated" => "2014-08-18T15:43:30Z"
],
"text" => [
"status" => "generated",
"div" => "<!-- Snipped for Brevity -->"
],
"extension" => [
[
"url" => "http://example.org/consent#trials",
"valueCode" => "renal"
]
],
"identifier" => [
[
"use" => "usual",
"label" => "MRN",
"system" => "http://www.goodhealth.org/identifiers/mrn",
"value" => "123456"
]
],
"name" => [
[
"family" => [
"Levin"
],
"given" => [
"Henry"
],
"suffix" => [
"The 7th"
]
]
],
"gender" => [
"text" => "Male"
],
"birthDate" => "1932-09-24",
"active" => true
]);
$data = $service->projects_locations_datasets_fhirStores_fhir->create($parent, $resource, $httpBody);
return $data;
}
Following the error message I get.
The error says I didn't pass the resourceType field, but it was passed:
Google\Service\Exception: {
"issue": [
{
"code": "structure",
"details": {
"text": "unparseable_resource"
},
"diagnostics": "missing required field \"resourceType\"",
"expression": [
""
],
"severity": "error"
}
],
"resourceType": "OperationOutcome"
} in file /usr/share/nginx/vendor/google/apiclient/src/Http/REST.php on line 128
How should I pass the parameter to receive the success message?
Tkanks!
I haven't tried the PHP client libraries specifically, but for most languages you don't want to use the HttpBody class - it's an indication that the method accepts something in the body of the request that is just text from the perspective of the method signature. I would try passing the JSON string directly.

Symfony - deep cloning functional test

I am trying to write I functional test for my deep cloning entity method __clone() on my Symfony project, which is defined in my method class..
I am new at writing tests and I can not find any source where I can get an info about this specific operation. This is what I got so far:
public function testDuplicate()
{
$userInProgress = $this->fixtureLoader->getReferenceRepository()->getReference(UserFixtures::USER_1);
$data = [
"name" => "John Doe"
];
$expected = [
"name" => "John Doe",
"status" => "IN_PROGRESS",
"assignee" => [
"uuid" => "4e7c77d5-8e36-4319-b250-050d241621dc",
]
"archived" => FALSE
];
$client->request('POST',
self::API_URL . self::USER_ENDPOINT . 'copy/' . $userInProgress->getId(),
[],
[],
[
'CONTENT_TYPE' => 'application/ld+json',
'HTTP_ACCEPT' => 'application/ld+json'
],
json_encode($data)
);
//assert
$this->assertEquals(200, $client->getResponse()->getStatusCode());
$response = $client->getResponse()->getContent();
$this->assertArraySubset($expected, json_decode($response, true));
}
This will run my test but I am not sure if it will actually test if deep cloning is set as it should?
Can anybody help?

How to create this JSON in PHP?

Sorry for the bad title, but I don't know how to create following JSON in PHP:
{
"id":"1",
"method":"getData",
"params":{
"options":{
"element":{
"id":"1a_ext",
"type":1,
"keyType":"externalkey"
},
"moreInfo":true,
"userFields":[
"id",
"name",
"longname",
"externalkey"
]
}
},
"jsonrpc":"2.0"
}
I don't know to do the part after "params" (how do I "put" options "into" params) - for the other parts I know what I have to do:
public static function getData(){
$json = array(
"id" => self::id(),
"method" => "getData",
"params" => array(
"id" => self::$userid,
"type" => self::$type
),
"jsonrpc" => "2.0"
);
$json = json_encode($json, true);
return self::request($json);
}
I would really appreciate your help, thanks!
You directly can assign to the params keys like
$json['params']['options'] = $your_options;
Full version of your code as an example
public static function getData(){
$json = array(
"id" => self::id(),
"method" => "getData",
"params" => array(
"id" => self::$userid,
"type" => self::$type
),
"jsonrpc" => "2.0"
);
# add something to param index
$json['params']['options'] = $your_options;
$json = json_encode($json, true);
return self::request($json);
}
You can create the this in array format in PHP and then JSON encode:
$arr = [
'id' => 1,
'method' => 'getData',
'params' => [
'options' => [
'element' => [
'id' => '1a_ext',
'type' => 1,
'keyType' => 'externalKey'
],
'moreInfo' => true,
'userFields' => [
'id',
'name',
'longname',
'externalKey'
]
]
],
'jsonrpc' => '2.0'
];
$json = json_encode($arr);
Instead of spoonfeeding, i would like to help related, Whenever if you find difficulties to create an array representation of a JSON then you should use var_export(array, true) the second parameter must be true to return the variable representation instead of outputting it
<?php
$json_str = '{
"id": "1",
"method": "getData",
"params": {
"options": {
"element": {"id": "1a_ext", "type": 1, "keyType": "externalkey"},
"moreInfo": true,
"userFields": ["id", "name", "longname", "externalkey"]
}
},
"jsonrpc": "2.0"
}';
$json_arr = var_export(json_decode($json_str, true), true);
print_r($json_arr);
check the output here https://paiza.io/projects/eUZZDsTsSFSM4m9WMl05Ow
$json_arr is an array representation for your JSON, now you can dynamic the array values

In my discord webhook, I am getting the error: {"embeds": ["0"]}

I am making a discord webhook for logging something, I have done it with the help of a template (I'm not good at php) and I keep getting the error: {"embeds": ["0"]}
I have already tried researching it, I haven't gotten back anything helpful. Mind the messiness I did this to test.
Here is my code:
<?php
$url = "https://discordapp.com/api/webhooks/xxx"; // Censored for privacy
$hookObject = json_encode([
"username" => "Promotion Logs",
"avatar_url" => "https://cdn.discordapp.com/icons/472520717515096078/60cc7dd2864c95a749516d1213359b67.png",
"tts" => false,
"embeds" => [
[
"title" => "Promotion Logs",
"type" => "rich",
"description" => "",
"url" => "http://police.riverside-roleplay.com/promologs.php",
"color" => hexdec( "0099ff" ),
"fields" => [
[
"name" => "Name",
"value" => "dd",
"inline" => false
],
[
"name" => "Rank",
"value" => "$rank",
"inline" => true
],
[
"name" => "Their name",
"value" => "dd",
"inline" => true
],
[
"name" => "Old rank",
"value" => "dd",
"inline" => true
],
[
"name" => "New rank",
"value" => "dd",
"inline" => true
],
[
"name" => "Reason",
"value" => "dd",
"inline" => true
],
[
"name" => "Date",
"value" => "dd",
"inline" => true
],
]
]
]
], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE );
$ch = curl_init();
curl_setopt_array( $ch, [
CURLOPT_URL => $url,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $hookObject,
CURLOPT_HTTPHEADER => [
"Length" => strlen( $hookObject ),
"Content-Type" => "application/json"
]
]);
$response = curl_exec( $ch );
curl_close( $ch );
?>
Here is the template I was using:
<?php
// Replace the URL with your own webhook url
$url = "https://discordapp.com/api/webhooks/0000000/ABCDEFGH....";
$hookObject = json_encode([
/*
* The general "message" shown above your embeds
*/
"content" => "A message will go here",
/*
* The username shown in the message
*/
"username" => "MyUsername",
/*
* The image location for the senders image
*/
"avatar_url" => "https://pbs.twimg.com/profile_images/972154872261853184/RnOg6UyU_400x400.jpg",
/*
* Whether or not to read the message in Text-to-speech
*/
"tts" => false,
/*
* File contents to send to upload a file
*/
// "file" => "",
/*
* An array of Embeds
*/
"embeds" => [
/*
* Our first embed
*/
[
// Set the title for your embed
"title" => "Google.com",
// The type of your embed, will ALWAYS be "rich"
"type" => "rich",
// A description for your embed
"description" => "",
// The URL of where your title will be a link to
"url" => "https://www.google.com/",
/* A timestamp to be displayed below the embed, IE for when an an article was posted
* This must be formatted as ISO8601
*/
"timestamp" => "2018-03-10T19:15:45-05:00",
// The integer color to be used on the left side of the embed
"color" => hexdec( "FFFFFF" ),
// Footer object
"footer" => [
"text" => "Google TM",
"icon_url" => "https://pbs.twimg.com/profile_images/972154872261853184/RnOg6UyU_400x400.jpg"
],
// Image object
"image" => [
"url" => "https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png"
],
// Thumbnail object
"thumbnail" => [
"url" => "https://pbs.twimg.com/profile_images/972154872261853184/RnOg6UyU_400x400.jpg"
],
// Author object
"author" => [
"name" => "Alphabet",
"url" => "https://www.abc.xyz"
],
// Field array of objects
"fields" => [
// Field 1
[
"name" => "Data A",
"value" => "Value A",
"inline" => false
],
// Field 2
[
"name" => "Data B",
"value" => "Value B",
"inline" => true
],
// Field 3
[
"name" => "Data C",
"value" => "Value C",
"inline" => true
]
]
]
]
], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE );
$ch = curl_init();
curl_setopt_array( $ch, [
CURLOPT_URL => $url,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $hookObject,
CURLOPT_HTTPHEADER => [
"Length" => strlen( $hookObject ),
"Content-Type" => "application/json"
]
]);
$response = curl_exec( $ch );
curl_close( $ch );
?>
My expected results is to make an embed with the fields I have setup. I had this before then I implemented it to a different page and changed a few things, then it was broken. Actual results is the error {"embeds": ["0"]}
The main problem with your code appear to be that $rank is undefined, as in there's no value in it, so "value" => "$rank", is causing the problem as Discord is expecting a value in it.
Using the code you wrote (and substituting webhook link with functioning link for testing) initially gave a different error:
{"message": "Cannot send an empty message", "code": 50006}
That could be fixed by changing this bit:
CURLOPT_HTTPHEADER => [
"Length" => strlen( $hookObject ),
"Content-Type" => "application/json"
]
into this:
CURLOPT_HTTPHEADER => [
"Length" => strlen( $hookObject ),
"Content-Type: application/json"
]
After that bit had been changed, it now indeed gave out the error {"embeds": ["0"]} as you described. After I define some value for $rank at top, your code works again. So the actual problem is really that the value is undefined.
See full file comparison between your original code and the edited code on my Gist:
https://gist.github.com/mnh48/a707aec600ac74f4e5d50875fcab5d7c
I put 34.2 as example $rank = 34.2;, and the result:
For anyone else coming from search engine
I initially got the same error and I had found the reason, but the reason on my side is different from what OP encountered.
Whenever anyone get this response from Discord webhook:
{"embeds": ["0"]}
It can mean two different thing:
There is invalid field being sent in the body
The limit has been exceeded for certain element
For the first case, it can be:
formatting error:
wrong format in timestamp, it must be in ISO8601 format
wrong format in color, it must be in decimal, anything else are not accepted (yes, even colour name string like "red" are not accepted, convert them to decimal -- red is 16711680, you can use site like SpyColor to check the decimal value)
wrong format in icon_url, avatar_url, or url, all of them must be in http://, https://, (additionally for url that expects image, it can be attachment:// so long the image file is also attached to the request)
invalid value:
using unexpected values, like passing string instead of boolean for inline (there's two strings accepted, probably for compatibility reason: "true" and "false", but any other strings are not accepted, and it's expecting boolean)
empty or null value, if you want it to be empty then don't include it in the first place, or use _ _ as the value
undefined value, check that all variables are actually defined
For the second case, the limit is as follows:
The limit for embed titles are 256 characters
The limit for embed descriptions are 2048 characters
Each field's name is limited to 256 characters
Each field's value is limited to 1024 characters
The limit for footer text is 2048 characters
The limit for author name is 256 characters
There can be 25 fields maximum per message
There can be 10 embeds maximum per message
Total characters overall must not exceed 6000 characters
In my case, it was the latter. I set my email client to send the content of the email as Discord Webhook in embeds > fields > value, and it was passing the whole long email message. The value field has maximum character limit of 1024 but my email content message had 1565 characters.
For anyone else coming across this from google:
Response from API:
{"embeds": ["0"]}
The issue for me was that I was using a float number vars in my JSON.
Wrong json:
{
"allowed_mentions": {
"parse": [
"everyone"
]
},
"embeds": [
{
"author": {
"name": "Name"
},
"title": "Title",
"color": "51281",
"fields": [
{
"name": "Label",
"value": 648.2,
"inline": true
}
]
}
]
}
Right json
{
"allowed_mentions": {
"parse": [
"everyone"
]
},
"embeds": [
{
"author": {
"name": "Name"
},
"title": "Title",
"color": "51281",
"fields": [
{
"name": "Label",
"value": 648,
"inline": true
}
]
}
]
}
I was getting the same error and the problem for me was using env vars in my JSON.
You'll get an error back if url fields aren't valid urls.
e.g "url":"$SOME_VAR"
I believe that this can also happen with other types too!
For anyone coming from Google, I got the same error when the url parameter was invalid.
I had the url as file:///Users/myUser/Downloads/test.html while I was testing and it didn't work. Seems only valid URLs are accepted for webhooks, which makes sense.

Google Analtyics not registering transactions when using Measurment protocol

I try to send http request to track eCommerce.
I got response http_code=200 but, I can't see any event or transaction.
Code:
$fields_string = '';
$fields = array(
'v' => 1,
'tid' => "UA-xxxxxx-1",
'cid' => $userid,
't' => 'transaction',
'ti' => $transaction_id,
'tr' => $Transaction_revenue,
'ts' => $Transaction_shipping,
'tt' => $tax,
'cu' =>'EUR'
);
Hit:
v=1&t=event&tid=UA-xxxxxx-1&cid=555&uid=123&ti=21&tr=20&tt=5&ts=2&pa=purchase&ec=Checkout&ea=Purchase
what could be the problem?
Thanks a lot.
What makes you think its not working. I ran your hit against debug collect to verify it. Looks good to me.
https://www.google-analytics.com/debug/collect?v=1&t=event&tid=UA-3731463-1&cid=555&uid=123&ti=21&tr=20&tt=5&ts=2&pa=purchase&ec=Checkout&ea=Purchase
{
"hitParsingResult": [ {
"valid": true,
"parserMessage": [ ],
"hit": "/debug/collect?v=1\u0026t=event\u0026tid=UA-3731463-1\u0026cid=555\u0026uid=123\u0026ti=21\u0026tr=20\u0026tt=5\u0026ts=2\u0026pa=purchase\u0026ec=Checkout\u0026ea=Purchase"
} ],
"parserMessage": [ {
"messageType": "INFO",
"description": "Found 1 hit in the request."
} ]
}
Did you check the real time reports have you double checked your Tid?
https://www.google-analytics.com/debug/collect?v=1&tid=UA-3731463-1&cid=123&t=transaction&ti=124&tr=1&ts=1&tt=1&cu=EUR
{
"hitParsingResult": [ {
"valid": true,
"parserMessage": [ ],
"hit": "/debug/collect?v=1\u0026tid=UA-3731463-1\u0026cid=123\u0026t=transaction\u0026ti=124\u0026tr=1\u0026ts=1\u0026tt=1\u0026cu=EUR"
} ],
"parserMessage": [ {
"messageType": "INFO",
"description": "Found 1 hit in the request."
} ]
}
Could also be something with the values you are sending in the second one.
Apparently I cloud not send transaction because my IP was blocked.

Categories