I am a beginner javascript developer. My first unit test code failed and I want to resolve the problem.
The message error is Warned [web-server]: 404: /cash register/product?
ERROR: 'Error: NOT FOUND
My unit test code is :
describe("SaveCashregister:", function(done){
beforeEach(bard.asyncModule('app'));
describe("#Product", function(){
it("Add a new Product to the cashregisterDb database", function(done){
bard.inject(this, '$controller', '$log', '$q', '$rootScope', 'dataservice');
dataservice
.getProducts()
.then(function(data) {
expect(data).to.have.length(1);
})
.then(done,done);
});
});
});
The getProducts method, I want to test is :
function getProducts()
{
// http://www.breezejs.com/sites/all/apidocs/classes/EntityManager.html
var query = breeze.EntityQuery
.from('produit');
//var prodType = manager.getEntityType('Product');
var products = manager.getEntities('Produit');
return products.length ?
util.$q.when(products) :
manager.executeQuery(query)
.then(function(data){
logger.log(" codeBar: " + data.results[0].codebar);
isReady = true;
return data.results;})
.catch(queryFailed);
}
Did you try changing
var products = manager.getEntities('Produit');
to
var products = manager.getEntities('Product');
(I would have rather put a response like this into a comment but my rep isn't high enough.)
If that doesn't fix it can you provide more of the stack-trace?
Related
hi I try to save in cookies after a web response. Here is my code
angular.module('myApp').controller('SignInController',['WebService',function(WebService, $cookies){
this.formData = {};
this.signIn = function(formData){
WebService.login(formData).then(function successCallback(data){
//console.log("Success callback:"+JSON.stringify(data));
var response = data.data;
var message = response['message'];
if (message == 'Success') {
$cookies.put("id", response['id']);
$cookies.put("number", response['number']);
}else{
}
console.log('Message:'+message+" id:"+ $cookies.get('id'));
},function errorCallback(error){
console.log("Error"+JSON.stringify(error));
});
this.formData = {};
};
}]);
i have included ngCookies as module while creating main angular module. What I'm doing wrong here? Anyone show me correct way. Thank you.
array containing all string of all arguments is good approach to handle dependency injection (DI) after your code is minified.
angularJs use Named_parameter in DI, you can understand how DI works by this blog post.
when you minified you angularJs file, ($http, $scope) converted to (a, b) and DI can't understand them.
$inject is my recommended way to handle this situation. its looks clean. (personal opinion, can be vary).
and try to write code which easily maintainable.
var app = angular.module('myApp', []);
SignInController.$inject = ['WebService', '$cookies'];
app.controller('SignInCtrl', SignInController);
function SignInController(WebService, $cookies){
this.formData = {};
this.signIn = signIn;
function signIn(formData) {
WebService.login(formData)
.then(successCallback, errorCallback);
function errorCallback(error){
console.log("Error"+JSON.stringify(error));
}
function successCallback(data){
var response = data.data;
var message = response['message'];
if (message == 'Success') {
$cookies.put("id", response['id']);
$cookies.put("number", response['number']);
}
}
this.formData = {};
};
I'm trying to read the following fields (LocationID ..) that I can see in the console when I wrote
console.log($scope.businessInformation);
Console photo capture
Can you help me please?
Thanks
Script.js
app.controller('ProfileController', ['$scope', function($scope) {
$scope.dropLink = '1';
$scope.dropContentLink = '1';
}]);
app.factory('infoService', ['$resource', function($resource){
return $resource('/api/business-information/:id');
}]);
app.controller('BusinessInfoController', ['$scope', 'infoService', function($scope, infoService) {
$scope.isActive = 1;
$scope.is_active_label = 'Active';
$scope.getInfo = function() {
$scope.businessInformation = infoService.query({id: $scope.businessInformation.industryID});
console.log($scope.businessInformation);
};
$scope.updateLabel = function(){
if($scope.isActive === 1){
$scope.is_active_label = 'Active';
}else {
$scope.is_active_label = 'Not Active';
}
};
}]);
routes/api.js
router.route('/business-information/:id')
.get(function(req, res){
conn.query('CALL Inductry_Location_Get(?)', [req.params.id],function(err,info){
if(err) res.send(err);
console.log('Data received from Db:\n');
console.log(info[0]);
return res.send(info);
});
}) ;
module.exports = router;
$resource is awesome because when you call an action like query, the object you receive back will be auto populated as soon as the promise resolves. The problem here is you try to log it right after calling it before the promise gets resolved.
If you want to use it from your controller, you can add your code to the promise which is a property $promise
$scope.getInfo = function() {
$scope.businessInformation = infoService.query({
id: $scope.businessInformation.industryID
});
$scope.businessInformation.$promise.then(function(data) {
// Access data parameter or
console.log(data);
// Use $scope.businessInformation directly since its populated at this point
console.log($scope.businessInformation);
});
};
If you are wanting to use it on your view, you can use the $resolved parameter to know if the data is ready yet.
<div ng-show="businessInformation.$resolved">{{ businessInformation }}</div>
I also want to point out an oddity which is you using $scope.businessInformation before the query is even run. You pass $scope.businessInformation.industryId into the query params.
I've been trying to write some unit tests for my services which use AngularFire to communicate with Firebase inside an Angular website.
I'm new to AngularJS and so I feel like I'm missing something obvious but couldn't find any great examples online (at least not that spoke to my limited knowledge).
I found some limited docs on MockFirebase https://github.com/katowulf/mockfirebase/tree/master/tutorials and that showed how to pretty much mock out the data so I did that.
For further examples of mockfirebase I looked at the angular fire's unit tests https://github.com/firebase/angularfire/tree/master/tests/unit but that didn't seem to show me the right way.
Here is my service --
app.service('Subscription', function ($firebase, FIREBASE_URL, $q) {
var ref;
var Subcription = {
ref: function () {
if (!ref) ref = new Firebase(FIREBASE_URL + "/subscriptions");
return ref;
},
validateSubscription: function(userId){
var defer = $q.defer();
$firebase(Subcription.ref().child(userId))
.$asObject()
.$loaded()
.then(function (subscription) {
defer.resolve(subscription.valid === true);
});
return defer.promise;
},
recordSubscription: function(userId){
return Subcription.ref().$set(userId, {valid: true});
}
};
return Subcription;
});
Here is the spec file --
describe('Service: subscription', function () {
// load the service's module
beforeEach(module('clientApp'));
// instantiate service
var subscription;
var scope;
beforeEach(inject(function (_Subscription_, $rootScope) {
MockFirebase.override();
subscription = _Subscription_;
scope = $rootScope.$new();
}));
it('allows access when the user id is in the subscription list', function () {
subscription.ref().push({'fakeUser': {valid: true}});
subscription.ref().flush();
var handler = jasmine.createSpy('success');
subscription.validateSubscription('fakeUser').then(handler);
scope.$digest();
expect(handler).toHaveBeenCalledWith(true);
});
});
It seems like the problem is that the promise never gets resolved inside of $asobject.$loaded because that angularfire part isn't happening.
I get the following as a result of the test: 'Expected spy success to have been called with [ true ] but it was never called.'
I am writing tests for a controller. One method calls a method in a service, which utilises a promise. In my test, I have mocked the service, and (I think) correctly mocked the promise. I have been following this blog entry: http://codingsmackdown.tv/blog/2012/12/28/mocking-promises-in-unit-tests/.
Here is the test code:
describe('Controller: ResultsController', function () {
'use strict';
var ctrl;
var ResultsServiceMock;
var RouteServiceMock;
var $scope;
var mockResults;
var mockPromise;
var q;
var deferred;
beforeEach(module('waApp'));
beforeEach(function() {
ResultsServiceMock = {
get: function(query) {
deferred = q.defer();
return deferred.promise;
}
};
RouteServiceMock = {
getParams: function() {
}
};
});
beforeEach(inject(function(
$rootScope,
$controller,
$q
) {
$scope = $rootScope.$new();
q = $q;
ctrl = $controller('ResultsController', {
$scope: $scope,
results: ResultsServiceMock,
route: RouteServiceMock
});
}));
it('Should simulate requesting results from the api', function() {
spyOn(ResultsServiceMock, 'get').andCallThrough();
spyOn(RouteServiceMock, 'getParams').andReturn({input:'hamburger'});
$scope.getResults({input:'hamburger'}); // TODO give params. try query()
deferred.resolve();
$scope.$root.$digest();
expect($scope.getResults).toHaveBeenCalled();
});
});
However, when I run the tests, I get the following error:
Chrome 35.0 (Mac) Controller: ResultsController Should simulate requesting results from the api FAILED
TypeError: Cannot read property 'resolve' of undefined
at null.<anonymous> (/Users/maryc/wa/app/results/results-controller_test.js:70:17)
Chrome 35.0 (Mac): Executed 14 of 14 (1 FAILED) (0.313 secs / 0.093 secs)
I don't understand where this error is coming from; is it because the spy call on ResultsServiceMock is not working? Any help would be appreciated.
The function getResults is as follows:
$scope.getResults = function(params) {¬
$scope.$emit('startGetResults');¬
$scope.loading = true;¬
$scope.podRequestStatus.init = false;¬
$scope.podRequestStatus = {¬
async: {}¬
};¬
var didyoumeans;¬
if(params.didyoumeans) {¬
didyoumeans = params.didyoumeans;¬
delete params.didyoumeans;¬
}¬
ResultsService.get(params).success(function(result) {¬
$scope.$emit('getResultsSuccess');¬
if(!_.isUndefined(didyoumeans)) {¬
$scope.results.queryresult.didyoumeans = didyoumeans;¬
} else if(!_.isUndefined(result.queryresult.didyoumeans)) {¬
if (!_.isArray(result.queryresult.didyoumeans)){¬
result.queryresult.didyoumeans = [result.queryresult.didyoumeans];¬
}¬
$scope.getResults({input: result.queryresult.didyoumeans[0].val, didyoumeans: result.queryresul t.didyoumeans});¬
return;¬
}¬
$scope.loading = false;¬
$scope.podRequestStatus.init = true;¬
if(result.queryresult.success === false) { //TODO is this result.results.queryresult.success??¬
if(result.queryresult.error !== false) {¬
$log.error('Results error', 'code: ' + result.queryresult.error.code, 'msg: ' + result.quer yresult.error.msg);¬
switch (result.queryresult.error.code){¬
case '3000':¬
$location.url('/blockedip');¬
break;¬
}¬
return;¬
}¬
if($scope.results.queryresult.examplepage && $scope.results.queryresult.examplepage.category) { ¬
$scope.examples();¬
}¬
// convert tips to an array if we have a single item¬
if($scope.results.queryresult.tips && !_.isArray($scope.results.queryresult.tips)){¬
$scope.results.queryresult.tips = [$scope.results.queryresult.tips];¬
}¬
$log.error('Results error');¬
return;¬
}¬
$scope.results.queryresult.pods = _.map($scope.results.queryresult.pods, function(pod) {¬
pod.priority = PodService.priority.initial;¬
return pod;¬
});¬
if ($scope.results.queryresult.sources && _.where($scope.results.queryresult.sources, {'text':'Fina ncial data'})) {¬
$scope.$emit('financialData', true);¬
} else {¬
$scope.$emit('financialData', false);¬
}¬ ¬
$scope.asyncPods(PodService.priority.async, 'async');¬
$scope.recalculate();¬
$scope.related();¬
}).error(function() {¬
$log.error('error occurred during ResultsService.get call in ResultsController');¬
});¬
};¬
The functions asyncPods, recalculate and related are three other methods within the ResultsController.
Edited: Having fixed the first error, I now get the following error when running the tests:
Chrome 35.0 (Mac) Controller: ResultsController Should simulate requesting results from the api FAILED
TypeError: undefined is not a function
at Scope.$scope.getResults (/Users/maryc/wa/.tmp_test/results-controller.js:222:36)
at null.<anonymous> (/Users/maryc/wa/app/results/results-controller_test.js:67:16)
This error comes from the line at the beginning of getResults() which calls ResultsService.get(). This seems to imply that my promise is either not being resolved, or the call $scope.getResults() is somehow failing?
The code for the .get() function of ResultsService is:
get: function(query) {¬
this.reset();¬
return ApiService.get({¬
params: UtilService.merge(query, {¬
async: true,¬
scantimeout: 1,¬
formattimeout: 8,¬
parsetimeout: 5,¬
format: 'image,plaintext,imagemap',¬
banners: 'true'¬
}),¬
timeout: abort.promise,¬
type: 'init',¬
cache: UserService.user.cacheResults¬
}).success(function(data){results.queryresult = data.queryresult;});¬
},¬
I'm wondering now if the problem is that .get itself contains a promise?
From the information you have included so far, this is my guess of what might cause the problem.
In your $scope.getResults() method, you call the get() method of ResultsService, so it seems like a name of the service is ResultsService.
But in the unit testing, you pass the ResultsServiceMock as results:
ctrl = $controller('ResultsController', {
$scope: $scope,
results: ResultsServiceMock,
route: RouteServiceMock
});
It should be ResultsService instead like this:
ctrl = $controller('ResultsController', {
$scope: $scope,
ResultsService: ResultsServiceMock,
RouteService: RouteServiceMock
});
After this change, you might encounter another problems, but it should take you pass the error:
TypeError: Cannot read property 'resolve' of undefined
Hope this helps.
New to AngularJS and I guess I don't understand how to call one Promise method from another with the same factory. Every time my code gets to the $http.get within processPerson, I get a Function Expected error in IE, or an Object is not a Function error in Chrome. I've tried reorganizing code many times, multiple factories, etc, and generally get the same error. The only time I can get this to work is if I combine the functions where the processPerson function is embedded within the success of the getPersonnel.
Code:
(function(){
var app = angular.module('hrSite', ['personnel']);
app.controller('PersonnelController', function($scope, personnelFactory){
var personnelPromise = personnelFactory.getPersonnel();
personnelPromise.then(function(personnel){
var perDefs = new Array();
$.each(personnel.data.value, function( i, person ){
var perDef = personnelFactory.processPerson(person);
perDefs.push(perDef);
});
$q.all(perDefs).then(function(){
$scope.personnel = personnel.data.value;
});
});
});
})();
(function(){
var personnelModule = angular.module('personnel', []);
personnelModule.factory('personnelFactory', function($http, $q) {
var getPersonnel = function(){
return $http.get("/sites/Development/_api/web/lists/getbytitle('Personnel')/items");
};
var processPerson = function(person){
var deferred = $q.defer();
$http.get("/sites/Development/_api/web/lists/getbytitle('Personnel Skills')/items?$select=*,Skill/Id,Skill/Title&$filter=PersonId eq '"+person.Id+"'&$expand=Skill").then(function(skills){
person.Skills = skills.data.value;
person.SkillsId = [];
$.each(skills.data.value, function( j, skill ){
person.SkillsId.push(skill.Id);
});
deferred.resolve();
});
return deferred.promise();
};
return {getPersonnel: getPersonnel,
processPerson: processPerson}
});
})();
Nevermind - I figured it out. I was migrating code from a jQuery project and in jQuery, you return a promise like this:
return deferred.promise();
Since Angular has its own deferred feature, $q, I began using that, without realizing that the notation to return a promise was slightly different:
return deferred.promise;
No () in that, which was really screwing things up. Now everything seems to be working fine.