I am looking at some older Postman test scripts, and since I don't have much experience, I need help understanding this a bit better.
The following are in the test scripts
//schema validation
const schema201PostSuccess = pm.collectionVariables.get("schema201PostSuccess");
const schema400BmcIdFail = pm.collectionVariables.get("schema400BmcIdFail");
const schema401Unauthorized = pm.collectionVariables.get("schema401Unauthorized");
const schema400BadRequest = pm.collectionVariables.get("schema400BadRequest");
const schema404InsufficientPermission = pm.collectionVariables.get("schema404InsufficientPermission");
const schema500InternalServerError = pm.collectionVariables.get("schema500InternalServerError");
pm.test("Wishlist Record Created Schema Validated", function() {
pm.response.to.have.jsonSchema(schema201PostSuccess);
});
pm.test("Incorrect bmc_id Schema Validated", function() {
pm.response.to.have.jsonSchema(schema400BmcIdFail);
});
pm.test("Unauthorized Schema Validated", function() {
pm.response.to.have.jsonSchema(schema401Unauthorized);
});
pm.test("400 Bad Request - Schema Validated", function() {
pm.response.to.have.jsonSchema(schema400BadRequest);
});
pm.test("404 Insufficient Permission - Schema Validated", function() {
pm.response.to.have.jsonSchema(schema404InsufficientPermission);
});
pm.test("500 Internal Server Error - Schema Validated", function() {
pm.response.to.have.jsonSchema(schema500InternalServerError);
});
Now, I'd like to put the tests into an if-else statement so rather than a bunch of fails and one pass, it just shows the correct result with the proper schema validated.
Here's how it currently looks Postman Test Result Screenshot
You can do something like this.
let status = pm.response.code;
if(status === 201){
pm.test("Wishlist Record Created Schema Validated", function() {
pm.response.to.have.jsonSchema(schema201PostSuccess);
});
} else if (status === 400) {
pm.test("Incorrect bmc_id Schema Validated", function() {
pm.response.to.have.jsonSchema(schema400BmcIdFail);
});
...
}
Related
Hi I am new to AWS dynamdoDB and mocha chai unit testing.
I wanted to create a node js unit testing with mocha and chai.
In my test.js i need to get expected outcome from AWS dynamoDB. However i not sure how to do it.
in my test.js
var assert = require('chai').assert;
describle('querying items from dynamodb', function(){
it('find date in Month collection', function(){
//not sure how should i put my inputs in here.
});
})
Do you have any articles or resources that I should read on?
If you want to make actual calls to AWS DynamoDB, a simple way to do it would be the following (based on documentation found for DynamoDB and DynamoDB.DocumentClient):
const assert = require('chai').assert;
const AWS = require('aws-sdk');
describe('querying items from dynamodb', function(){
it('find date in Month collection', function(done){
var params = {
TableName : <TEST_TABLE_NAME>,
Key: {
<PRIMARY_KEY>: <TEST_KEY_VALUE>
}
};
var expectedDate = <EXPECTED_VALUE>;
var documentClient = new AWS.DynamoDB.DocumentClient({apiVersion: '2012-08-10'});
documentClient.get(params, function(err, data) {
assert.strictEqual(data.Item.Date, expectedDate);
done();
});
});
});
BUT BUYER BEWARE! This will make calls to your actual DynamoDB and AWS may charge you money! To avoid this, mocking is highly recommended. Mocking calls to your DynamoDB can be done with the following code (based on documentation found on github, npmjs.com, and npmdoc.github.io):
const assert = require('chai').assert;
const AWS = require('aws-sdk');
const MOCK = require('aws-sdk-mock');
describe('querying items from dynamodb', function(){
before(() => {
// set up a mock call to DynamoDB
MOCK.mock('DynamoDB.DocumentClient', 'get', (params, callback) => {
console.log('Let us not call AWS DynamoDB and say we did.');
// return fake data
let fakeData = {
Item: {
Date: <FAKE_DATE>
}
};
return callback(null, fakeData);
});
});
after(() => {
// restore normal function
MOCK.restore('DynamoDB.DocumentClient');
});
it('find date in Month collection', function(done){
// set up the call like it's real
var params = {
TableName : <TEST_TABLE_NAME>,
Key: {
<PRIMARY_KEY>: <TEST_KEY_VALUE>
}
};
var expectedDate = <EXPECTED_VALUE>;
var documentClient = new AWS.DynamoDB.DocumentClient({apiVersion: '2012-08-10'});
documentClient.get(params, function(err, data) {
// data should be the fake object that should match
assert.strictEqual(data.Item.Date, expectedDate);
done();
});
});
});
I am new to building websites and all I want to do at this stage is to use local JSON file to retrive data instead of mirage provided in ember tutorial. you have mirage/config.js like this:
export default function() {
this.namespace = '/api';
let rentals = [{
//JSON
}];
this.get('/rentals', function(db, request) {
if(request.queryParams.area !== undefined) {
let filteredRentals = rentals.filter(function(i) {
return i.attributes.area.toLowerCase().indexOf(request.queryParams.area.toLowerCase()) !== -1;
});
return { data: filteredRentals };
} else {
return { data: rentals };
}
});
// Find and return the provided rental from our rental list above
this.get('/rentals/:id', function (db, request) {
return { data: rentals.find((rental) => request.params.id === rental.id) };
});
}
This article shows part of the solution but I don't know where it's supposed to be written. Any help would be much appreciated.
There are a few different options for stubbing some data without using mirage. The clearest and easiest is fetch.
Put your json file in the public folder, let's call it something.json. Then, use fetch to get the data (this is the model hook of a route):
model() {
return fetch('something.json')
.then(function(res) {
return res.json()
})
}
This answer applies from at least 1.13 onward (and possibly earlier). It was written as of 3.1.
I'm loading a route. Its model hook loads some models. Some are fetch from ember store and some are promises requested through AJAX:
model: function () {
return Em.RSVP.hash({
//the server data might not be loaded if user is offline (application runs using appcache, but it's nice to have)
someServerData: App.DataService.get(),
users: this.store.find('user')
});
}
The App.DataService.get() is defined as:
get: function () {
return new Ember.RSVP.Promise(function(resolve, reject) {
//ajax request here
});
}
Obviously if the request is rejected, the flow is interrupted and I cannot display the page at all.
Is there a way to overcome this?
Ember.RSVP.hashSettled is exactly meant for this purpose.
From tildeio/rsvp.js Github repository:
hashSettled() work exactly like hash(), except that it fulfill with a hash of the constituent promises' result states. Each state object will either indicate fulfillment or rejection, and provide the corresponding value or reason. The states will take one of the following formats:
{ state: 'fulfilled', value: value }
or
{ state: 'rejected', reason: reason }
Here is an example for using it (working JS Bin example):
App.IndexRoute = Ember.Route.extend({
fallbackValues: {
firstProperty: null,
secondProperty: null
},
model: function() {
var fallbackValues = this.get('fallbackValues');
return new Ember.RSVP.Promise(function(resolve, reject) {
Ember.RSVP.hashSettled({
firstProperty: Ember.RSVP.Promise.resolve('Resolved data despite error'),
secondProperty: (function() {
var doomedToBeRejected = $.Deferred();
doomedToBeRejected.reject({
error: 'some error message'
});
return doomedToBeRejected.promise();
})()
}).then(function(result) {
var objectToResolve = {};
Ember.keys(result).forEach(function(key) {
objectToResolve[key] = result[key].state === 'fulfilled' ? result[key].value : fallbackValues[key];
});
resolve(objectToResolve);
}).catch(function(error) {
reject(error);
});
});
}
});
fallbackValues can be useful for managing resolved hash's properties' fallback values without using conditions inside the promise function.
Taking into account that Ember.RSVP.hashSettled is not available in my Ember version. I come up with the following solution:
model: function(params) {
var self = this;
return new Em.RSVP.Promise(function(resolve, reject){
// get data from server
App.DataService.get().then(function(serverData) { //if server responds set it to the promise
resolve({
serverData: serverData,
users: self.store.find('user')
});
}, function(reason){ //if not ignore it, and send the rest of the data
resolve({
users: self.store.find('user')
});
});
});
}
I'm setting up unit tests on my Sails application's models, controllers and services.
I stumbled upon a confusing issue, while testing my User model. Excerpt of User.js:
module.exports = {
attributes: {
username: {
type: 'string',
required: true
},
[... other attributes...] ,
isAdmin: {
type: 'boolean',
defaultsTo: false
},
toJSON: function() {
var obj = this.toObject();
// Don't send back the isAdmin attribute
delete obj.isAdmin;
delete obj.updatedAt;
return obj;
}
}
}
Following is my test.js, meant to be run with mocha. Note that I turned on the pluralize flag in blueprints config. Also, I use sails-ember-blueprints, in order to have Ember Data-compliant blueprints. So my request has to look like {user: {...}}.
// Require app factory
var Sails = require('sails/lib/app');
var assert = require('assert');
var request = require('supertest');
// Instantiate the Sails app instance we'll be using
var app = Sails();
var User;
before(function(done) {
// Lift Sails and store the app reference
app.lift({
globals: true,
// load almost everything but policies
loadHooks: ['moduleloader', 'userconfig', 'orm', 'http', 'controllers', 'services', 'request', 'responses', 'blueprints'],
}, function() {
User = app.models.user;
console.log('Sails lifted!');
done();
});
});
// After Function
after(function(done) {
app.lower(done);
});
describe.only('User', function() {
describe('.update()', function() {
it('should modify isAdmin attribute', function (done) {
User.findOneByUsername('skippy').exec(function(err, user) {
if(err) throw new Error('User not found');
user.isAdmin = false;
request(app.hooks.http.app)
.put('/users/' + user.id)
.send({user:user})
.expect(200)
.expect('Content-Type', /json/)
.end(function() {
User.findOneByUsername('skippy').exec(function(err, user) {
assert.equal(user.isAdmin, false);
done();
});
});
});
});
});
});
Before I set up a policy that will prevent write access on User.isAdmin, I expect my user.isAdmin attribute to be updated by this request.
Before running the test, my user's isAdmin flag is set to true. Running the test shows the flag isn't updated:
1) User .update() should modify isAdmin attribute:
Uncaught AssertionError: true == false
This is even more puzzling since the following QUnit test, run on client side, does update the isAdmin attribute, though it cannot tell if it was updated, since I remove isAdmin from the payload in User.toJSON().
var user;
module( "user", {
setup: function( assert ) {
stop(2000);
// Authenticate with user skippy
$.post('/auth/local', {identifier: 'skippy', password: 'Guru-Meditation!!'}, function (data) {
user = data.user;
}).always(QUnit.start);
}
, teardown: function( assert ) {
$.get('/logout', function(data) {
});
}
});
asyncTest("PUT /users with isAdmin attribute should modify it in the db and return the user", function () {
stop(1000);
user.isAdmin = true;
$.ajax({
url: '/users/' + user.id,
type: 'put',
data: {user: user},
success: function (data) {
console.log(data);
// I can not test isAdmin value here
equal(data.user.firstName, user.firstName, "first name should not be modified");
start();
},
error: function (reason) {
equal(typeof reason, 'object', 'reason for failure should be an object');
start();
}
});
});
In the mongoDB console:
> db.user.find({username: 'skippy'});
{ "_id" : ObjectId("541d9b451043c7f1d1fd565a"), "isAdmin" : false, ..., "username" : "skippy" }
Yet even more puzzling, is that commenting out delete obj.isAdmin in User.toJSON() makes the mocha test pass!
So, I wonder:
Is the toJSON() method on Waterline models only used for output filtering? Or does it have an effect on write operations such as update().
Might this issue be related to supertest? Since the jQuery.ajax() in my QUnit test does modify the isAdmin flag, it is quite strange that the supertest request does not.
Any suggestion really appreciated.
I'm trying to execute a promise inside Ember.RSVP.all
App.Foo = Ember.Object.create({
bar: function() {
var configuration = ajaxPromise("/api/configuration/", "GET");
Ember.RSVP.all([configuration]).then(function(response) {
//do something with the response in here
});
}
});
But because my integration test mocks the xhr w/out a run loop the test fails with the expected error "You have turned on testing mode, which disabled the run-loop' autorun"
So I wrapped the RSVP with a simple ember.run like so
App.Foo = Ember.Object.create({
bar: function() {
var configuration = ajaxPromise("/api/configuration/", "GET");
Ember.run(function() {
Ember.RSVP.all([configuration]).then(function(response) {
//do something with the response in here
});
});
}
});
But I still get the error for some odd reason. Note -if I run later it's fine (this won't work though as I need to exec the async code for this test to work correctly)
App.Foo = Ember.Object.create({
bar: function() {
var configuration = ajaxPromise("/api/configuration/", "GET");
Ember.run.later(function() {
Ember.RSVP.all([configuration]).then(function(response) {
//do something with the response in here
});
});
}
});
Here is my ajaxPromise implementation -fyi
var ajaxPromise = function(url, type, hash) {
return new Ember.RSVP.Promise(function(resolve, reject) {
hash = hash || {};
hash.url = url;
hash.type = type;
hash.dataType = 'json';
hash.success = function(json) {
Ember.run(null, resolve, json);
};
hash.error = function(json) {
Ember.run(null, reject, json);
};
$.ajax(hash);
});
}
How can I wrap the Ember.RVSP inside my ember run w/out it throwing this error?
Update
here is my test setup (including my helper)
document.write('<div id="ember-testing-container"><div id="wrap"></div></div>');
App.setupForTesting();
App.injectTestHelpers();
test("test this async stuff works", function() {
visit("/").then(function() {
equal(1, 1, "omg");
});
});
The only part I've left out is that I'm using jquery-mockjax so no run loop wraps the xhr mock (and in part that's why I like this library, it fails a test when I don't wrap async code with a run loop as the core team suggests)
This may have to do with how your tests are being run, so if you can provide the test, it will be helpful
I also noticed:
It turns out I believe you are also being (or will be soon) trolled by jQuery's jQXHR object being a malformed promise, the fulfills with itself for 0 reason, and enforcing its own nextTurn on you. Which is causing the autorun. This will only happen in the error scenario.
In ember data we sort this out, by stripping the then off the jQXHR object
see:
https://github.com/emberjs/data/blob/4bca3d7e86043c7c5c4a854052a99dc2b4089be7/packages/ember-data/lib/adapters/rest_adapter.js#L539-L541
I suspect the following will clear this up.
var ajaxPromise = function(url, type, hash) {
return new Ember.RSVP.Promise(function(resolve, reject) {
hash = hash || {};
hash.url = url;
hash.type = type;
hash.dataType = 'json';
hash.success = function(json) {
Ember.run(null, resolve, json);
};
hash.error = function(json) {
if (json && json.then) { json.then = null } // this line
Ember.run(null, reject, json);
};
$.ajax(hash);
});
}
This is rather unfortunate, and various separate concepts and ideas are coming together to cause you pain. We hope to (very shortly) land Ember.ajax which normalizes all these crazy away.
Also feel free to checkout how ember-data is going this: https://github.com/emberjs/data/blob/4bca3d7e86043c7c5c4a854052a99dc2b4089be7/packages/ember-data/lib/adapters/rest_adapter.js#L570-L586
I feel your pain on this Toran, I'm sure it's what Stefan's stated, we had to 1 off mockjax to get our tests to work with it.
https://github.com/kingpin2k/jquery-mockjax/commit/ccd8df8ed7f64672f35490752b95e527c09931b5
// jQuery < 1.4 doesn't have onreadystate change for xhr
if ($.isFunction(onReady)) {
if (mockHandler.isTimeout) {
this.status = -1;
}
Em.run(function () {
onReady.call(self, mockHandler.isTimeout ? 'timeout' : undefined);
});
} else if (mockHandler.isTimeout) {
// Fix for 1.3.2 timeout to keep success from firing.
this.status = -1;
}