I'm creating API test which checks that the response contains specific key "textId" in structure:
it('TC-4 /rest/passwords/ should change "password"', function() {
return chai.request(serverurl)
.post('/rest/passwords/')
.set('Content-Type', 'application/json')
.set('Accept', 'text/html')
.set('X-Api-Key', global.apikey)
.set('Cookie', global.cookie)
.send({password: "password"})
.then(function(res) {
res.should.have.status(200);
res.should.be.json;
console.log('TC-4 /rest/passwords/: %j\n', res.body);
res.body.should.have.all.keys(['textId']);
});
});
response is following:
[{"textId":"PasswordNeedsAtLeastOneDigit","parameters":{}},{"textId":"PasswordNeedsAtLeastOneUpperCaseCharacter","parameters":{}}]
I tried:
res.body.should.have.property('textId');
res.body.should.have.nested.property('textId');
res.body.should.have.all.keys(['textId']);
res.body.should.have.all.nested.keys(['textId']);
none of them works
It's a bit late but for any future viewers, you need something like this:
res.body.should.have.property('data').that.includes.all.keys(['status', 'id', 'name', 'email',
'bio', 'image', 'email_verified', 'role', 'isActive', 'isDeleted', 'createdAt', 'updatedAt', 'token']);
Related
///<reference types = "cypress"/>
describe('API Test Suite', ()=>{
it('Send GET Request',()=>{
cy.request('http://ptsv2.com/t/fu807-1554722621/post').then((res)=>{
expect(res.body).has.property('username', 'automate')
})
})
})
I'm trying to validate username field but its throwing error
expected '{\r\n "username": "automate",\r\n "password": "everything",\r\n "targetUrl": "http://ptsv2.com/t/7ty82-1554722743/post"\r\n}' to have property 'username'
SAMPLE RESULT on POSTMAN:
{
"username": "automate",
"password": "everything",
"targetUrl": "http://ptsv2.com/t/7ty82-1554722743/post"
}
The body property needs parsing - true, but there are less hacky ways of doing it
cy.request('GET', 'http://ptsv2.com/t/fu807-1554722621/post')
.its('body')
.then(JSON.parse)
.should('have.property', 'username', 'automate')
or
cy.request('GET', 'http://ptsv2.com/t/fu807-1554722621/post')
.then(res => JSON.parse(res.body))
.should('have.property', 'username', 'automate')
You can do something like this:
///<reference types = "cypress"/>
describe('API Test Suite', () => {
it('Send GET Request', () => {
cy.request('GET', 'http://ptsv2.com/t/fu807-1554722621/post').then(
(res) => {
const user = 'automate'
cy.wrap(res.body).should('contain', `"username": "${user}"`)
}
)
})
})
On, digging deeper into your response body, I could see that there are empty spaces and because of which it was failing. So before asserting you have to remove the empty spacing and then apply the has.property assertion.
///<reference types = "cypress"/>
describe('API Test Suite', () => {
it('Send GET Request', () => {
cy.request('GET', 'http://ptsv2.com/t/fu807-1554722621/post').then(
(res) => {
expect(JSON.parse(JSON.stringify(JSON.parse(res.body)))).has.property(
'username',
'automate'
)
}
)
})
})
cy.request yields the response as an object so you can access it using .its()
cy.request('your-request-url')
.its('response.body')
.should('have.property', 'username','automate')
Alternatively, you can use cy-spok to check for properties and values in a more readable code format.
const 'spoke = require('cy-spok')
// in your test
cy.request('your-request-url')
.its('response.body')
.should(spok({
username: 'automated',
password: 'everything',
//other props
})
)
I want to check if my response object contains mentioned properties using chai should assertion.
Below is my code snippet:
chai.request(app)
.post('/api/signup')
.send(
data
)
.then(function (response) {
response.should.have.status(200);
response.body.should.have.property('active', 'mobileNumber', 'countryCode', 'username', 'email', 'id', 'createdAt', 'updatedAt', 'location');
done();
})
.catch(function (error) {
done(error);
})
But I am getting below error:
Found how to achieve it using mocha chai-should,
Function name is .should.have.keys()
Just pass the properties to this function and it will check they should be present in the object you are testing.
bellow is the code
response.body.should.have.keys('active', 'mobileNumber', 'countryCode', 'username', 'email', 'id', 'organisationId', 'createdAt', 'updatedAt', 'location');
If you're exclusively utilising Chai (in Postman, for example), the following string of functions will successfully aid you:
response.body.to.include.all.keys("active", "mobileNumber");
The full list of API's (including an example of the above) can be found here.
I was wondering how to return correctly an HTML template (SEO friendly) from an ajax call.
In my app, I use 2 differents ways to return response:
For simple template:
public function ajaxCallAction() {
//.....
$response = array(
"code" => 202,
"success" => true,
"simpleData" => $simpleData
);
return new JsonResponse($response);
}
And in the JS I do something like:
$("div#target").click(function(event) {
$.ajax({
type: "POST",
success: function(response) {
if(response.code === 202 && response.success) {
$("div#box").append(response.simpleData);
}
}
});
});
For complexe template (more than 20 lines and various var):
public function ajaxCallAction() {
//...
$listOfObjects = $repo->findAll();
$viewsDatas = [
'listOfObjects' => $listOfObjects,
//....other vars
];
return $this->render('myAppBundle:template:complexTemplate.html.twig', $viewsDatas);
//in complexTemplate.html.twig, I loop on listOfObjects for example...
}
And for this kind of call, the JS looks like:
$("div#target").click(function(event) {
$.ajax({
type: "POST",
success: function(response) {
$("div#box").append(response);
}
});
});
All those methods are working, but with the second one, we dont have status code (does it matter?) and I know that returning directly formated html template can be heavy (according to for example this topic Why is it a bad practice to return generated HTML instead of JSON? Or is it?).
How are you guys doing ajax calls? What are the best practices here?
In my apps, I typically use something like that:
$response = array(
"code" => 200,
"response" => $this->render('yourTemplate.html.twig')->getContent() );
Hope this help!
Edit
To return your response, you should use JsonResponseas explained in docs: http://symfony.com/doc/current/components/http_foundation.html#creating-a-json-response
Simply use that:
return new JsonResponse($response);
Try with "renderView" ;)
return $this->json([
'html' => $this->renderView('template.html.twig', []),
]);
I'm trying to integrate Twitter Typeahead into my Laravel (4.2.11) project (with Bootstrap 2.3.2).
I have results being returned as JSON (checked with Fiddler), but a single "undefined" is always displayed instead.
If I enter a search query that doesn't return any results, the "No Results" is displayed correctly.
//Simple query in Laravel
Route::get('/sidebar/clients/{q}', function($q)
{
$companies = DB::table('ViewCompanies')->select(array('CompanyID', 'FullCompanyName'))
->where('FullCompanyName', 'like', '%'. $q .'%')->get();
return Response::json(array('companies' => $companies));
});
//Javascript in page
var clients = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('FullCompayName'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
remote: {
url: '/sidebar/clients/%QUERY',
filter: function (parsedResponse) {
// parsedResponse is the array returned from your backend
console.log(parsedResponse);
return parsedResponse;
}
}
});
clients.initialize();
$('#clients .typeahead').typeahead({
hint: true,
highlight: true,
minLength: 3,
},
{
name: 'clients',
valueKey: 'CompanyID',
displayKey: 'FullCompanyName',
source: clients.ttAdapter(),
templates: {
empty: [
'<div class="tt-empty-message">',
'No Results',
'</div>'
],
header: '<h3 class="tt-tag-heading tt-tag-heading2">Matched Companies</h3>'
}
});
My console log using the above code:
what is the output of the parsedResponse you are logging? I think DB::table returns an object, not an array. Try to replace the response like this:
return Response::json(array('companies' => $companies->toArray()));
Then log the results and format them in the "filter" function in the Bloodhound object.
Hope it helps!
Thanks to Eduardo for giving me the idea of needing to parse my JSON into a JS array.
Doing a search revealed these two questions:
Twitter Typeahead.js Bloodhound remote returns undefined
Converting JSON Object into Javascript array
from which I was able to devise my one-line solution (full remove filter show):
filter: function (parsedResponse) {
console.log(parsedResponse);
var parsedResponse = $.map(parsedResponse, function(el) { return el; });
return parsedResponse;
}
I wanna get JSON from the server.And here is the django server view function:
def showChart(request):
data = [{"id":1, "name":"Tom", "email":"a#a.com"}, {"id":2, "name":"Bosh", "email":"c#c.com"}]
return HttpResponse(json.dumps(data), mimetype="application/json");
Obviously, showChart() will return a json.
My frontend extjs4 code:
Ext.onReady(function() {
Ext.define('ProductionInfo', {
extend: 'Ext.data.Model',
fields: ['email', 'id', 'name']
});
var store_new = Ext.create('Ext.data.Store', {
model: 'ProductionInfo',
proxy: {
type: 'ajax',
url : 'http://localhost:8000/production_data',
reader: {
type: 'json'
}
}
});
store_new.load();
alert(store_new.getCount());
});
But the alert dialog shows '0', while the right answer is '2'. So why I can't get JSON from server? (I can get the right JSON through a GET request in Chorme and Firefox)
You could check my sample: https://github.com/lucassus/extjs4-account-manager
It's rails application but json mechanism is very similar.
Basically you have to define a model with valid proxy: https://github.com/lucassus/extjs4-account-manager/blob/master/app/assets/javascripts/app/model/User.js
and a store which will have model attribute: https://github.com/lucassus/extjs4-account-manager/blob/master/app/assets/javascripts/app/store/Users.js