I have a meteor method that's supposed to handle file/image uploads by passing a cdn key, which is just a string.
For latency compensation though, I want to add the actual image blob to LocalMongo, that way I can add an image preview.
This is a problem since I want to just pass a string key to my server method, while I want to pass a file blob to my client method stub. Does Meteor support this? I don't want to pass the image blob to my server (as doing so would serialize the blob/make the call costly).
A solution I'm thinking of is to just define two Meteor methods with different names, the first one being for the client and the other for the server, and just calling them both with the proper parameters. Is this the proper way to do this in Meteor?
EDIT: My solution above doesn't actually work because Meteor realizes there is no method on the server (and nukes the local changes of my client method)
Just a suggestion, you can save the file blob in a Session variable and access in the method when the method stub is called from client, like this,
Meteor.methods({
'yourMethod': function (key) {
if (Meteor.isClient) {
var fileBlob = Session.get('my-file-blob'); //set this variable just before calling this method. And don't forget to remove it when template is destroyed.
} else {
}
}
});
Like I said, I didn't test it but just a suggestion. Hope it helps.
Related
I would like to stub a Meteor method in Cucumber (using Velocity) so that when the Scenario runs and a button is clicked, I do not want it to send an email like it normally would.
My fixtures file in /tests/cucumber/fixtures/fixture.js contains a Meteor.method with the same name as a Meteor.method in the actual app. Of course, this prevents Meteor from running because Method names need to be unique.
I did notice the stubMethod() function here: https://meteor-testing.readme.io/docs/velocity-helpers, but this is marked as a Jasmine-only function.
How can I stub a Meteor method in Cucumber? Thanks.
Firstly you can use xolvio:email-stub to stub Email. If you look through the source code you can see how the stub is built. Note that the docs on GH are a bit out of date, the method names are wrong. You can get the right ones from the code.
My application has two databases with exactly the same schema. Basically, I need to change the DbContext based on what data I'm accessing. Two countries are in one Db and 4 countries in the other. I want the client to decide which context is being used. I tried changing my BreezeWebApiConfig file so that the route looks like this:
GlobalConfiguration.Configuration.Routes.MapHttpRoute(
name: "BreezeApi",
routeTemplate: "breeze/{dbName}/{controller}/{action}/{id}",
defaults: new {id=RouteParameter.Optional,dbName="db1"}
);
I added the string to the controller actions:
[HttpGet]
public string Metadata(string dbName="")
{
return _contextProvider.Metadata();
}
And changed the entityManager service Name.
Now when the client spins up, it accesses the corrent metadata action and I get a message:
Error: Metadata query failed for: /breeze/clienthistory/kenya/Metadata. Unable to either parse or import metadata: Type .... already exists in this MetadataStore
When I go to the metadata url from the browser, I get the correct metadata (exactly the same as when I remove the {dbName} segment from the route). If I remove the {dbName} segment from the route I get no error and everything works fine
(I have not started implementing the multiple contexts yet -- I am just trying to make the additional segment work).
Thanks.
I think the problem is that your Breeze client is issuing two separate requests for the same metadata, once under each of the two "serviceNames". Breeze tries to blend them both into the same EntityManager.metadataStore ... and can't because that would mean duplication of EntityType names.
One approach that should work is to begin your application by fetching the metadata immediately upon app start and then adding all the associated "DataServiceNames" to the MetadataStore.
Try something along these lines (pseudo-code):
var manager;
var store = new breeze.MetadataStore();
return store.fetchMetadata(serviceName1)
.then(gotMetadata)
.catch(handleFail);
function gotMetadata() {
// register the existing metadata with each of the other service names
store.addDataService(new breeze.DataService(serviceName2));
... more services as needed ...
manager = new breeze.EntityManager({
dataService: store.getDataService(serviceName1), // service to start
metadataStore: store
});
return true; // return something
}
Alternative
Other approaches to consider don't involve 'db' placeholder in the base URL nor any toying with the Web API routes. Let's assume you stay vanilla in that respect with your basic service name
var serviceName = '/breeze/clienthistory/';
..
For example, you could add an optional parameter to your routes (let's call it db) as needed via a withParameters clause.
Here is a query:
return new breeze.EntityQuery.from('Clients')
.where(...)
.withParameters({db: database1}); // database1 == 'kenya'
.using(manager).execute()
.then(success).catch(failed);
which produces a URL like:
/breeze/clienthistory/Clients/?$filter=...&db=kenya
It makes an implicit first-time-only metadata request that resolves to:
/breeze/clienthistory/Metadata
Your server-side Web API query methods can expect db as an optional parameter:
[HttpGet]
public string Metadata(string db="")
{
... do what is right ...
}
Saves?
I assume that you also want to identify the target database when you save. There are lots of ways you can include that in the save request
in a custom HTTP header via a custom AJAX adapter (you could do this for queries too)
in a query string parameter or hash segment on the saveChanges POST request URL (again via a custom AJAX adapter).
in the tag property of the saveOptions object (easily accessed by the server implementation of SaveChanges)
in the resourceName property of the saveOptions object (see "named save")
You'll want to explore this variety of options on your own to find the best choice for you.
Wondering if there was a way to get a list of the current Meteor.methods that have been registered.
for example if a post method is registered like so:
Meteor.methods({
post: function() {
//code
}
});
Is there a way to access a list of these methods? Ideally it would be via a method but if it was stored in an accessible variable like Meteor.__methods that would work as well.
I've combed through the documentation and the Meteor global in the browser but did no find anything useful. Any Ideas?
After Digging more on the Server side of meteor, it appears that the methods are stored in an array Meteor.default_server.method_handlers which is accessible on the server but not on the client.
Only way to expose it client side seems to be registering a method server side and then returning a list of the keys.
On the client you can do:
Meteor.connection._methodHandlers
It gives you a dictionary of function names to functions.
I'm testing the controllers using the crawler, but when I'm posting a form that doesn't generate any errors, it save the form in the database.
How can I prevent him to do so without changing the controller, and without testing something else.
Is there best practice about this kinds of test ?
I tried the rollback, but in the ControllerTest there is no more active transactions
You need to write your own test client class extending Symfony\Bundle\FrameworkBundle\Client.
It's because default client doesn't share connection object between requests (so you can't use transactions outside test client). If you extend test client you can handle transaction by your own.
In your client class you need make static connection object, and override method doRequest() to avoid creating new connection object every time but use our static one instead.
It's well described here:
http://alexandre-salome.fr/blog/Symfony2-Isolation-Of-Tests
When you have your own doRequest method all you need is handle transaction, so you wrap handle() method with begin and rollback. Your doRequest method could look sth like that:
protected function doRequest($request)
{
// here you need create your static connection object if it's doesn't exist yet
// and put it into service container as 'doctrine.dbal.default_connection'
(...)
self::$connection->beginTransaction();
$response = $this->kernel->handle($request);
self::$connection->rollback();
(...)
return $response
}
You can read the documentation of PHPUnit for database testing
http://www.phpunit.de/manual/3.6/en/database.html
You will need setup your database and teardown the changes you made.
If you think that the above is too complicated maybe you are interested in make a mockup of your database layer
http://www.phpunit.de/manual/3.6/en/test-doubles.html
Mockup is create a custom object based in the original object where put your own test controls. Probably in this case you are interested in mockup the Entity Manager of Doctrine
I'm using HTTPService with a POST operation to submit a Base64 encoded file (taken from bitmap data within the app) but I could really do with getting some idea of the progress of the POST operation (e.g. like the FileReference.upload()).
I don't think this is possible, but it would be awesome if it is (via any means, I'm willing to change my setup to get this).
Do not use HTTPService. Use URLRequest, URLLoader, and URLVariables.
If your using an HTTPService tag, get ride of it and replace it with a Script tag filled with something like ...
private function forYou() : void{
var req : URLRequest = new URLRequest("PUT YOUR URL HERE")
var loader : URLLoader = new URLLoader();
var params : URLVariables = new URLVariables();
params.WHATEVER = WHATEVER YOU WANT IT TO BE;
req.data = params;
req.method = URLRequestMethod.POST;
loader.addEventListener(ProgressEvent.PROGRESS, YOUR LISTENER FUNCTION NAME);
loader.load(req);
}
Assign this function name to the creationComplete attribute of the root tag.
If your not using an HTTPService tag, just get ride of the HTTPService object in your actionscript and use the above code.
This worked well for me to consume a REST web service:
http://code.google.com/p/as3httpclient/wiki/Links
Example
This isn't possible with HTTPService. Its only events are result, fault, and invoke (other than the non-relevant inherited events of activate and deactivate).
To get progress information on an upload process, the server would have to provide the information, which would require a means of communication between the server and the client during the operation, which isn't there for a regular HTTP POST operation.
One option might be to create an object on the server that would be instantiated whenever the server began receiving POST data from your client. It would then keep track of the progress and expose that data to the rest of your server-side application. Your client could then initiate a polling system that would request the value of that particular variable.
Seems like kind of a far-fetched option, though...