Using Meteor Methods but still getting error - javascript

I'm using Meteor methods to avoid updating the database on the client-side but still getting this error:
Uncaught Error: Not permitted. Untrusted code may only remove documents by ID. [403]
I didn't notice it affecting the application until configuring Facebook and Twitter login for the accounts-ui package. Again, the only database operations I'm performing on the client-side are finds.
if(Meteor.isClient) {
$scope.deleteTask = function(task) {
$meteor.call("deleteTask", task._id);
};
}
if(Meteor.isServer) {
Meteor.methods({
deleteTask: function (taskId) {
var task = Tasks.findOne(taskId);
if (task.owner !== Meteor.userId()) {
alert("Only a tasks owner may delete the task.")
throw new Meteor.Error("not-authorized");
}
else {
Tasks.remove(taskId);
}
}
});
}
EDIT: I should mention that the application still works fine on localhost even though that error appears, but does not work (and still shows that error) when I deploy it to one of meteor's test servers.

You are running the code on the client. You have two choices to immediately solve the problem:
Place the method definition in a file under the /server directory in your app.
Wrap the method definition inside of an if (Meteor.isServer) {} block.
The actual error is happening because the method is running on the client (see above) and updating a collection with a non-id-based selector. For example:
Posts.update({awesome: false}, {...});
Whereas on the client you can only make updates like:
Posts.update(postId, {...});
If you prefer to keep latency compensation and write a client stub you can, but you'll need to modify your update as seen in the second example above.
Suggested reading: Structuring your application.

Found that it was coming from my accounts-ui configurations in a totally different file!

Related

Protractor failure and browser handling on data driven approach

We are developing data driven protractor framework (jasmine), I need help in handling certain failure scenario.
I will be iterating same test with different data set, my Page module will handle the all verification.
If any it blocks fails, I want to run the certain function to clear cookies, capture session details and re-start the browser (I do have all the functions )
but ,
I am not sure how to get the it block failure and trigger the specific function, also I want to make sure next loop iteration is triggered.
browser.restart() - never worked in data driven in before or after all .....
If am running this data driven in parallel (we can run same test in parallel browser, but we can't distribute each data in to multiple browser), is there any way to distribute?
var dData = requireFile('testData/data.json');
using(dData,async function(data, description) {
describe( scenario 1++ , function() {
it('Load URL' , async function() { })
it('validate Page1' , async function() { xxxxx })
it('validate Page2' , async function() { xxxxx })
it('validate Page3' , async function() { xxxxx })
}) }
If I understood everything right, you have like 3 questions. I'll answer only the first, general one - how to handle results of each it block
It sounds like for what you are trying to implement you should use advantage of custom reporter in jasmine
More precisely, what you want to do is to:
create a module with custom reporter
register it in your config. This would be a good place to think ahead of time if there are any parameters that you want to pass to the reporter
there are different hooks: jasmine-started, suite-started (describe), spec-started (it), suite-done, jasmine-done. Not sure if you all of them, but one particular for sure: spec-done. This should be a function that will be called after each it block. It will be taking spec object as a parameter. You can explore it on your own, but what you'll need from it is status property (spec.status). It's value can be 'passed', 'failed' and I believe others. So your logic will be like
if (spec.status === 'passed') {
// ...
} else if (spec.status === 'failed') {
// ...
} else {
// ...
}

Yeoman - Delaying logging until after task completion

I'm getting frustrated with part of a Yeoman Generator I'm building. As it's my first, I have no doubt I'm missing something obvious, but here it goes.
Simply put, I'm trying to log a message, Do Thingsā„¢ and then log another message only when those things have been done.
Here's the method:
repos: function () {
var self = this;
this.log(highlightColour('Pulling down the repositories'));
// Skeleton
this.remote('user', 'skeleton', 'master', function(err, remote) {
if (!err) {
remote.bulkDirectory('.', self.destinationRoot());
} else {
self.log('\n');
self.log(alertColour('Failed to pull down Skeleton'));
repoErr = true;
}
});
//
// Three more near identical remote() tasks
//
if (!repoErr) {
self.log(successColour('Success!'));
self.log('\n');
} else {
self.log(alertColour('One or more repositories failed to download!'));
}
},
Each of the individual remote() tasks are working fine, but I get both the first and last self.log() messages before the file copying happens. It seems trivial, but I simply want the success message to come after everything has been completed.
For example, in the terminal I see:
Pulling down the repositories
Success!
file copying results
It should be:
Pulling down the repositories
file copying results
Success!
I thought it could be something to do with using this.async() with done() at the end of each remote() task, and I tried that, but whenever I do, none of the code fires at all.
I've even tried breaking everything (including the messages) into separate methods, but still no luck.
Such a simple goal, but I'm out of ideas! I'd be grateful for your help!
EDIT: In case you're wondering, I know the messages are coming first because any alerts regarding file conflicts are coming after the messages :)
This is not an issue related to Yeoman. You have asynchronous code, but you're handling it as if it was synchronous.
In the example you posted here, just do the logging as part of this.remote callback:
repos: function () {
var self = this;
this.log(highlightColour('Pulling down the repositories'));
// Skeleton
this.remote('user', 'skeleton', 'master', function(err, remote) {
if (!err) {
remote.bulkDirectory('.', self.destinationRoot());
self.log(successColour('Success!'));
self.log('\n');
} else {
self.log('\n');
self.log(alertColour('Failed to pull down Skeleton'));
self.log(alertColour('One or more repositories failed to download!'));
}
});
},
Maybe your actual use case is more complex; in this case you can use a module like async (or any other alternative) to handle more complex async flow. Either way, Yeoman doesn't provide helpers to handle asynchronous code as this is the bread and butter of Node.js.

Deps autorun in Meteor JS

Decided to test out Meteor JS today to see if I would be interested in building my next project with it and decided to start out with the Deps library.
To get something up extremely quick to test this feature out, I am using the 500px API to simulate changes. After reading through the docs quickly, I thought I would have a working example of it on my local box.
The function seems to only autorun once which is not how it is suppose to be working based on my initial understanding of this feature in Meteor.
Any advice would be greatly appreciated. Thanks in advance.
if (Meteor.isClient) {
var Api500px = {
dep: new Deps.Dependency,
get: function () {
this.dep.depend();
return Session.get('photos');
},
set: function (res) {
Session.set('photos', res.data.photos);
this.dep.changed();
}
};
Deps.autorun(function () {
Api500px.get();
Meteor.call('fetchPhotos', function (err, res) {
if (!err) Api500px.set(res);
else console.log(err);
});
});
Template.photos.photos = function () {
return Api500px.get();
};
}
if (Meteor.isServer) {
Meteor.methods({
fetchPhotos: function () {
var url = 'https://api.500px.com/v1/photos';
return HTTP.call('GET', url, {
params: {
consumer_key: 'my_consumer_key_here',
feature: 'fresh_today',
image_size: 2,
rpp: 24
}
});
}
});
}
Welcome to Meteor! A couple of things to point out before the actual answer...
Session variables have reactivity built in, so you don't need to use the Deps package to add Deps.Dependency properties when you're using them. This isn't to suggest you shouldn't roll your own reactive objects like this, but if you do so then its get and set functions should return and update a normal javascript property of the object (like value, for example), rather than a Session variable, with the reactivity being provided by the depend and changed methods of the dep property. The alternative would be to just use the Session variables directly and not bother with the Api500px object at all.
It's not clear to me what you're trying to achieve reactively here - apologies if it should be. Are you intending to repeatedly run fetchPhotos in an infinite loop, such that every time a result is returned the function gets called again? If so, it's really not the best way to do things - it would be much better to subscribe to a server publication (using Meteor.subscribe and Meteor.publish), get this publication function to run the API call with whatever the required regularity, and then publish the results to the client. That would dramatically reduce client-server communication with the same net result.
Having said all that, why would it only be running once? The two possible explanations that spring to mind would be that an error is being returned (and thus Api500px.set is never called), or the fact that a Session.set call doesn't actually fire a dependency changed event if the new value is the same as the existing value. However, in the latter case I would still expect your function to run repeatedly as you have your own depend and changed structure surrounding the Session variable, which does not implement that self-limiting logic, so having Api500px.get in the autorun should mean that it reruns when Api500px.set returns even if the Session.set inside it isn't actually doing anything. If it's not the former diagnosis then I'd just log everything in sight and the answer should present itself.

How can i use sinon to stub functions for neo4j Thingdom module

I am having some issues writing some unit tests where i would like to stub out the functionality of the neo4j Thingdom module.
After a few hours of failed attempts i have been searching around the web and the only point of reference i found was a sample project which used to sinon.createStubInstance(neo4j.GraphDatabase); to stub out the entire object. For me, and becuase this seemed to a be a throw away project i wanted a more fine grained approach so i can test that for instance as the Thingdom API outlines when saving a node you create it (non persisted) persist it and then you can index it if you wish which are three calls and could be outlined in multiple specific tests, which i am not sure can be achieved with the createStubInstance setup (i.e. found out if a function was called once).
Example "create node" function (this is just to illustrate the function, i am trying to build it out using the tests)
User.create = function(data, next){
var node = db.createNode(data);
node.save(function(err, node){
next(null,node);
});
};
I am able to stub functions of the top level object (neo4j.GraphDatabase) so this works:
it('should create a node for persistence', function(){
var stub = sinon.stub(neo4j.GraphDatabase.prototype, 'createNode');
User.create({}, res);
stub.calledOnce.should.be.ok;
stub.restore();
});
The issue comes with the next set of test i wish to run which tests if the call to persist the node to the database is called (the node,save) method:
I am not sure if this is possible or it can be achieved but i have tried several variations of the stub and non seem to work (on neo4j.Node, neo4j.Node.prototype) and they all come back with varying errors such as can't wrap undefined etc. and this is probably due to the createNode function generating the node and not my code directly.
Is there something i am glaringly doing wrong, am i missing the trick or can you just not do this? if not what are the best tactics to deal with stuff like this?
A possible solution is to return a stubbed or mocked object, giving you control on what happens after the node is created:
it('should create a node for persistence and call save', function () {
var stubbedNode = {
save: sinon.stub().yields(undefined, stubbedNode)
};
var stub = sinon.stub(neo4j.GraphDatabase.prototype, 'createNode').returns(stubbedNode);
User.create({}, res);
stub.calledOnce.should.be.ok;
stub.restore();
stubbedNode.save.calledOnce.should.be.ok;
});
We couldn't do it directly, the way the module is setup it doesn't work to well with Sinon. What we are doing is simply abstracting the module away and wrapping it in a simple facade/adapter which we are able to stub on our unit tests.
As we are not doing anything bar calling the neo4j module in that class we are integration (and will validate when regression testing) testing that part to make sure we are hitting the neo4j database.

Why can't I extend everyone's pocket in nowjs?

I'm trying to provide functions in everyone's pocket of nowjs. I'd like to do so by _.extending everyone's pocket, i.e. everyone.now. For some reason which I cannot understand, _.extend fails to properly provide the function at the client side.
This is my current code:
var _ = require("underscore"),
everyone = require("nowjs").initialize(app);
everyone.now.foo = function() {};
_.extend(everyone.now, {
bar: function() {}
});
console.log(everyone.now.foo); // [Function]
console.log(everyone.now.bar); // undefined
On both the server and client sides, I can do now.foo() just fine. On the other hand, now.bar() fails because now.bar is not defined. This is the case on both the client and server sides. I tried to check for existence at the server side, as shown above on the last line. However, this line logs undefined.
Underscore's extend function (obviously) does work on other objects so I guess it has something to do with the "magical namespace" that nowjs uses.
How come extending doesn't work with everyone.now and how can I get it to work?
Edit 2: I digged some more into proxies. It seems like setting a property on a proxy by passing a variable as its name does not work. I removed my first edit because this testcase is more narrowed down.
Why is this not working? Is this a bug? (Most of the times I ask this myself I know it isn't, but this is really making me clueless...)
var proxy = Proxy.create({
get: function(pr, name) {
console.log("get called");
return null;
},
set: function(pr, name, value) {
console.log("set called");
}
});
var key = "foo";
proxy["foo"] = "bar";
proxy[ key ] = "bar";
proxy["foo"];
proxy[ key ];
Log result:
set called
get called
get called
Apparently, proxy[ key ] = "bar"; does not cause set to be called on the proxy. Why is that?
They posted a blog entry on the NowJS website on how to use node-proxy on Windows, instead of the native V8 implementation using the --harmony_proxies flag.
It appeared that the V8 version that Node currently uses contains several bugs with regard to proxies, which were causing the weird behaviour as outlined in the question. node-proxy, however, is a module that enables proxies (the core of the "magical namespace" of NowJS) without those bugs. (The bugs are fixed in a newer version of V8 as well, but that would require a custom build of Node.)
I just couldn't figure out how to build node-proxy on Windows (it's a .node addon; not a pure JavaScript one). In the above blog post they distributed the compiled module, and everything now works like a charm.
To fix:
Download the compiled module
Extract the folder to the node_modules folder and rename it to now
Don't run Node with the proxy flag
Edit: Node 0.7.0 uses V8 3.8.6 which also solves this issue. Just run with the --harmony flag and remove the reference to node-proxy.

Categories

Resources