I have the following karma test. But I get the error "EXPECTED: {"data":{"form_field_17":"None Required","title":"Mr","firstName":"John","lastName":"Doe","email":"john#gmail.com","mobile":"1114269874","registration":"123","form_field_15":"Test","pref_date":"2016-08-30T02:13:00.000Z"},"formId":4}
GOT: {"data":"{\"form_field_17\":\"None Required\",\"title\":\"Mr\",\"firstName\":\"John\",\"lastName\":\"Doe\",\"email\":\"john#gmail.com\",\"mobile\":\"1114269874\",\"registration\":\"123\",\"form_field_15\":\"Test\",\"pref_date\":\"30/08/2016 12:13 PM\"}","formId":4}
Why does my JSON object have backslashes and my pref_date has changed format?
describe('when submitting a form', function () {
it('should be successful', function () {
var d = {
form_field_17: "None Required",
title: "Mr",
firstName: "John",
lastName: "Doe",
email: "john#gmail.com",
mobile: "1114269874",
registration: "123",
form_field_15: "Test",
pref_date: "2016-08-30T02:13:00.000Z"
};
$httpBackend.expect('POST', '/DynamicForm/SubmitForm/', { data: d, formId: 4})
.respond(200, "[{ success : 'true', data : 'true' }]");
DynamicFormFactory.SubmitForm(d, 4)
.then(function (data) {
expect(data.success).toBeTruthy();
});
$httpBackend.flush();
$httpBackend.verifyNoOutstandingExpectation();
$httpBackend.verifyNoOutstandingRequest();
});
});
Related
I am trying to test an action in a React project with redux.
The test i am trying to do using Mocha,Enzyme is for a DELETE_USER action which is dispatched first on pressing a delete button and onSuccess of the action another action LOAD_ALL_USERS is dispatched which performs a get request.
Following is the code for test i tried , which gives the error as in the topic:
it('should call the /users endpoint with a user ID', (done) => {
const deleteUserResponse = {userId: 1337};
const mapActions = (actions) => ({
deleteActions: filterForAction(actions, 'DELETE_USER'),
loadAllUserActions: filterForAction(
actions,
'LOAD_ALL_USERS'
)
});
const loadAllUsersResponse =
[
{
id: 1337,
email: 'testuser9#some-company.com',
firstName: 'John',
lastName: 'Doe',
active: false
},
{
id: 1338,
email: 'adamsmith#mail.com',
firstName: 'Adam',
lastName: 'Smith',
active: true
}
];
const sampleApiSearchParams = {
locale: 'en-GB',
pageSize: 10,
sortBy: 'userId',
sortDirection: 'desc',
location: 'Zurich'
};
const sampleReactTableSearchParams = {
filtered: [
{id: 'userId', value: '1id'},
{id: 'userFirstName', value: 'fname'},
{id: 'userLastName', value: 'lname'},
{id: 'userEmail', value: 'maill'}
],
sorted: [{id: 'userId', desc: true}],
pageSize: 10
};
const scope = nock('http://localhost')
.delete('users/1337')
.reply(200, deleteUserResponse)
.get(uri=>uri.includes('users'),{...sampleApiSearchParams})
.reply(200, loadAllUsersResponse);
const store = mockStore(
{
stringResources: {
'deleteuser.confirm.title': 'User Delete Confirm',
'deleteuser.confirm.description':
'Are you sure you want to delete the user?',
'deleteuser.notification.message.success':
'is successfully deleted.'
},
userManagement: {
table: {
searchParams: sampleReactTableSearchParams
}
}
});
const actual = actions.deleteUser(1337)
store.dispatch(actual);
setTimeout(() => {
scope.done();
const {deleteActions, loadAllUsersActions} = mapActions(store.getActions());
expect(
deleteActions[1].meta['redux-pack/LIFECYCLE']
).toBe('success');
expect(deleteActions[1].payload).toEqual(
deleteUserResponse
);
//expect(loadAllUsersActions[1].payload).toEqual(loadAllUsersResponse);
done();
}, 50);
});
});
If i comment the 'scope.done()' the test passes, but http.get request is not getting called so the 'loadAllUsersActions' is undefined. How can i solve this , what is that i am doing wrong ?
Thanks in advance.
This is my api:
exports.getService = function(req, res) {
var limit = 10; // number of records per page
var offset = 0;
Service.findAndCountAll({
raw: true,
where: {
shop: req.user.shop
}
}).then((data) => {
var page = req.params.page; // page number
var pages = Math.ceil(data.count / limit);
offset = limit * (page - 1);
Service.findAll({
// raw: true,
limit: limit,
offset: offset,
$sort: {
id: 1
},
where: {
shop: req.user.shop
},
include: [{
model: Categoryservice,
attributes: ['id'],
include: [{
model: Category,
attributes: ['id', 'name'],
}]
}],
}).then(function (services) {
var services=JSON.parse(JSON. stringify(services));
console.log('=====stringify==========>>',services);
var arr = services.categoryservices.map(item => item.category.id)
services.cats = arr;
delete services.categoryservices;
console.log('only for the testing========>',services);
res.status(200).json({
'result': services,
'count': data.count,
'pages': pages
});
});
}).catch(function(error) {
res.status(500).send('Internal Server Error');
});
};
I am using map in last then fuction ,
It contains a error map undefined in the server..
I want want a out like below given json using the map fuction.
Actually i need this out put:
{
"id": 2,
"service": "mobile",
"min": "20",
"per": "10",
"tax": "1",
"cats": [
1,
2
]
}
my JSON. stringify(services) out put is:
=====stringify==========>> [ { id: 2,
username: null,
name: null,
image: null,
service: 'mobile',
shop: '$2a$10$NWpbmgtzQAxRZ1ugvdC7LOlorBU36xoGHm1L.k.KmFqDO/7oSmBLu',
min: '20',
per: '10',
tax: '1',
activity: null,
createdAt: '2018-03-14T07:30:57.000Z',
updatedAt: '2018-03-14T07:30:57.000Z',
categoryservices: [ [Object], [Object] ] },
{ id: 1,
username: 'sam',
name: 'New Service',
image: '/images/uploads/22-Feb-2018/f96334384cd78754454c5e4e05e20fc0-dragon_pattern_red_black_9666_1920x1080.jpg',
service: 'battery',
shop: '$2a$10$NWpbmgtzQAxRZ1ugvdC7LOlorBU36xoGHm1L.k.KmFqDO/7oSmBLu',
min: '5',
per: '1',
tax: '1',
activity: '2018-03-14T06:01:36.000Z',
createdAt: '2018-03-14T06:01:36.000Z',
updatedAt: '2018-03-14T06:01:36.000Z',
categoryservices: [] } ]
I was beginner of using map function,
so,I am confused in map ,
so please give any solution to this problem.
You are stringifying your array that comes back. You can't do that if you plan to use .map on it. Remove that code and try again.
.then(function (services) {
var arr = services.categoryservices.map(item => item.category.id)
services.cats = arr;
delete services.categoryservices;
console.log('only for the testing========>',services);
res.status(200).json({
'result': services,
'count': data.count,
'pages': pages
});
});
I think we are missing something because the output you pasted doesn't have the category.id attribute that you are returning from the item passed in to map. Is that what you are trying to target? That's off topic, but this code may not work for what you are trying to achieve but will run the map though.
Looks like services is an array, based on the console.log. If you want the id's of all categories, you can do
let categoryIds = [];
categoryIds = services.reduce((categoryIds, service) => {
let ids = service.categoryservices.map(category => category.id);
for(let id of ids) {
if(categoryIds.indexOf(id) === -1) {
categoryIds.push(id)
}
}
return categoryIds;
}, categoryIds);
If you want to have category ids as cats in each service, you can do,
var services=JSON.parse(JSON. stringify(services));
services.forEach(service) => {
service.cats = service.categoryservices.map(category => category.id);
delete service.categoryservices;
});
res.status(200).json({
'result': services,
'count': data.count,
'pages': pages
});
Hope this helps!
Following are the steps for authentication flow:
User does the registeration by entering his details and he will be
sent an OTP to his mail.
At this time user details stored to
mongoDB.
Usually after validation of OTP, a user can login to
application. But in my case before validating OTP, user can login to
application.
How to solve this please help me. Some of my code shown below.
model.js
var UserSchema = new Schema({
name: String,
email: {type: String, required: true, select: true},
mobile: {type: String, required: true, select: true},
password: {type: String, required: true, select: true},
});
controller.js
vm.submitPost = function(userData){
$http({
url: 'http://192.168.2.8:7200/api/pages/auth/register',
method: 'POST',
data: userData
}).then(function(res) {
if(res.data.success){
$location.path('/pages/auth/otp');
} else {
alert('Please fill all credentials');
}
}, function(error) {
alert(error.data);
});
};
node.js
router.post('/pages/auth/register',function(req, res, next){
var user = new User({
name: req.body.username,
email: req.body.email,
password: req.body.password,
mobile: req.body.mobile,
});
var secret = "mysecretkey";
var code = otp.generate(secret);
var insertOtp = function(db, callback) {
db.collection('otp').createIndex( { "createdAt": 1 }, { expireAfterSeconds: 10 } );
db.collection('otp').insertOne( {
"createdAt": new Date(),
"generatedOtp": code,
"logEvent": 2,
"logMessage": "Success!"
}, function(err, result) {
assert.equal(err, null);
callback(result);
});
};
MongoClient.connect(config.database, function(err, db) {
assert.equal(null, err);
insertOtp(db, function(err,docs) {
db.close();
});
});
var mailOptions={
to : req.body.email,
subject : 'OTP',
text : "Your One-Time Password is "+code
}
transport.sendMail(mailOptions, function(error, response){
if(error){
console.log(error);
res.end("error");
}else{
res.end("sent");
}
});
user.save(function(err){
if(err){
res.send(err);
return;
}
res.json({
success:true,
message: 'User has been created!'
});
});
});
add active attribute to your schema with default value false when user has validated through OTP, then set this attribute to true and allow user to login if this attribute is true.
var UserSchema = new Schema({
name: String,
email: {type: String, required: true, select: true},
mobile: {type: String, required: true, select: true},
password: {type: String, required: true, select: true},
active:{ type: 'Boolean',
default: false}
});
Simply Put:
Can I match mock-$httpBackend data from $resource service in a jasmine unit test? How would I do it?
What I Want:
When I Jasmine-test my backend services with $httpBackend and the $http service, I can do this:
it("should return movie search data from the title", function() {
var movieData = { title: "The Phantom Menace", description: "A movie.";
var response = [];
$httpBackend.when('GET', 'http://www.omdbapi.com/?v=1&s=the%20phantom%20menace')
.respond(200, movieData);
moviesService.search('the phantom menace')
.then(function onSuccess(data) {
response = data;
});
$httpBackend.flush();
expect(response.data).toEqual(movieData);
}); // end it
I have all of The Phantom Menace's information stored in movieData. This test passes because it compares the data that is received from the mock backend to what it should be (movieData).
What I Am Getting:
When I Jasmine-test my backend services with $httpBackend and the $resource service, things are different.
it("retrieves a bunch objects", function() {
var result = {}, testArray = [];
var dataToCheck = [
{ id: 1, "des": "This is one."},
{ id: 2, "des": "This is two."},
{ id: 3, "des": "This is three."}
];
$httpBackend.whenGET('movies/api')
.respond(dataToCheck);
MovieResource.query().$promise.then(function (data) {
result = data;
});
$httpBackend.flush();
angular.forEach(result, function (resource) {
testArray.push(resource);
})
expect(testArray).toEqual(dataToCheck);
}); // end it
Karma tells me:
Expected [ Resource({ id: 1, des: 'This is one.' }), Resource({ id: 2,
des: 'This is two.' }), Resource({ id: 3, des: 'This is three.' }) ]
to equal [ Object({ id: 1, des: 'This is one.' }), Object({ id: 2,
des: 'This is two.' }), Object({ id: 3, des: 'This is three.' }) ].
So, instead of "Objects" they are "Resources."
I appreciate ANY guidance you can give me.
You will need to do something like this
expect(testArray[0].id).toEqual(dataToCheck[0].id);
expect(testArray[1].id).toEqual(dataToCheck[1].id);
expect(testArray[0].des).toEqual(datatoCheck[0].des);
Reference:
http://accraze.info/testing-angular-services-using-jasmine/
i cant get and ID from my json api, how can i do that? I am doing like $scope.info.id in my delete function but id doesnt work like that.
Here is my delete function
app.controller('InventoryCtrl', function($scope, $http, Inventory, $location) {
//getting the objects from Inventory
$scope.info = Inventory.query();
$scope.deleteInv = function () {
Inventory.drop({id: $scope.info.id}, function() {
$location.path('/');
});
};
});
here is my factory
app.factory('Inventory', function($resource, $http) {
return $resource('http://localhost/api/v1/inventory/:id', {id: "#id"},
{
drop: {
method: 'DELETE',
params: {id: "#id"}
}
}
);
});
And here is my api
{
meta: {
limit: 20,
next: null,
offset: 0,
previous: null,
total_count: 3
},
objects: [
{
category: {},
count: 1,
created: "2014-02-28T11:54:02.831409",
description: "dasdasdasdsa",
id: 20,
location: "asd",
name: "adas11",
resource_uri: "/api/v1/inventory/20",
status: "sad"
},
{
category: {},
count: 1,
created: "2014-02-28T11:54:03.708003",
description: "dasdasdasdsa",
id: 21,
location: "asd",
name: "adas11",
resource_uri: "/api/v1/inventory/21",
status: "sad"
},
]
}
I don't think you should call "drop" function. Instead you should call the 'delete' function which you specified in your factory.
$scope.deleteInv = function () {
Inventory.delete({id: $scope.info.id}, function() {
$location.path('/');
});