There is a Marionette.js view which acts as a login form. The following code sample shows the relevant code parts including an error I already fixed:
MyApp.module("User", function(User, App, Backbone, Marionette, $, _) {
User.LoginView = Marionette.ItemView.extend({
className: "reveal-modal",
template: "user/login",
ui: {
signInForm: "#signin-form"
},
events: {
"submit #signin-form": "onSignInFormSubmit"
},
onRender: function() {
var self = this;
var $el = this.$el;
// [...] Render schema
_.defer(function(){
$el.reveal({
closeOnBackgroundClick: false,
closed: function(){
self.close(); // <-- This is incorrect. Do not close the ItemView directly!
}
});
});
},
onSignInFormSubmit: function(event) {
event.preventDefault();
var errors = this.signInForm.validate();
var data = this.signInForm.getValue();
// [...] Notify that data has been submitted.
},
hideForm: function() {
this.$el.trigger("reveal:close");
}
});
});
I noticed a major mistake in my implementation. In the callback function closed
of Reveal I decided to close the ItemView directly which is wrong as you can read in the documentation of Marionette.js:
View implements a close method, which is called by the region managers automatically.
Bugfix: Instead close()
should be called on the region. I fixed this error.
Now I ask myself how can I actually write a test which covers the problem. I use Jasmine for testing. I noticed that the event handler onSignInFormSubmit
is no longer called after I have incorrectly closed the ItemView and try to re-submit the form.
Here is a first draft of the test which unfortunately does fail also with the bugfix:
it("should call the submit handler for the sign-in form", function() {
spyOn(userController.loginView, "onSignInFormSubmit");
spyOn(userController.loginView.signInForm, "validate").andCallFake(function(params) {
return null;
});
userController.loginView.hideForm();
userController.loginView.ui.signInForm.trigger("submit");
expect(userController.loginView.onSignInFormSubmit).toHaveBeenCalled();
});
Maybe one could also test if the event handler is registered such as:
expect(userController.loginView.events["submit #signin-form"]).toEqual("onSignInFormSubmit");