Chaining Chaplin.js Controller beforeAction behavior with Promises

Lately for work I’ve been doing a lot of work with Chaplin.js, a framework built on Backbone.js for client-side JavaScript “single page” applications. It’s pretty neat, but that’s not what I want to write about.

We have a (possibly over-) complicated structure where most of our application has 2 layers of inheritance beyond the framework: our generic “web” package that provides certain shared functionality across multiple applications, the application-specific  ”base” package, and the actual application architecture.

One example of this is our controller layers, where the “web” package provides “requires login” behavior, then the application “base” which provides role-based restrictions on the various application controllers and actions.

IMPORTANT: SPA security is a farce! Because all javascript is sent to the browser, a nefarious end user *could* reverse-engineer the security and get to things you don’t want them to see. You must pair this with server-side restrictions

Whew, now that’s over, I wanted to show how I used promises to chain functionality between the “requires login” controller, through the “check for role” controller, to the actual application controller. This is my interpretation of “the Chaplin way” as evidenced here.

Ok, so first thing we need is our “requires login” controller:

So we have a beforeAction()  that uses jQuery’s Deferred interface to “defer” this functionality. Our checkLogin()  method creates a deferred object, then resolves it or rejects it based on whether we have a user object in  Chaplin.mediator .

Next up we have our “check role” controller that, well, checks the user object for a given role. The trick here is that we ONLY want to do this if  RequireLoginController  has passed successfully.

So we’re using the deferred interface to run beforeAction()  on  RequireLoginController  first. Assuming this passes, we then use the deferred interface again to check our role.

As some final sugar, we’re using deferred always() to ensure that we compose our navigation whether we’re going to the error page or the actual requested page.

This is how I hacked this together. I’d love to hear your thoughts!

Time flies… how to manage it better

Another year or two goes by, and I’ve done nothing with this blog. It’s not that I’ve done nothing in the last 2 years, but apparently I’m horrible at blogging. Since my last post in November of 2011 I’ve become a vegan, bought an airplane (1956 Cessna 172), switched jobs a handful of times, got a Rhodesian Ridgeback puppy, my band has put out an album, and I’ve been generally enjoying life. More about those later…

So, here’s a quick micro-post about a tool/technique I’ve been using to combat my ADD and Get Things Done: it’s called the Pomodoro Technique.

The basic premise is that you break your day up into 25 minute chunks separated with 5 minute breaks. A “pomodoro” (the Italian word for “tomato”; the author’s timer was shaped like one) is an indivisible time period that you either complete or restart depending on the amount of distraction you cannot avoid. I suggest looking into it if you’re ever feeling particularly distracted. Along with advice from The 4-Hour Workweek and Getting Things Done, The Pomodoro Technique makes the bulk of my productivity strategy.

Mail.app vs Sparrow.app: Gmail client showdown!

I’ve never been too excited about OS X’s Mail for GMail as I use tags extensively for GTD (based on this) and Mail seemed so… Outlook. My main reason for this is that Mail uses folders to represent tags, forcing me to choose just one tag instead of a Reference, Project, Context and Action. Overall, Google spends lots of time fine-tuning their web interface for GMail, and I’ve been pretty happy.

Then I came across an interesting OS X client for GMail: Sparrow.app.  Sparrow aims to be lightweight but have the “right” features, integrates with things like Growl seamlessly, and allows me to monitor and quickly “do, delegate, delay or delete” things that hit my inbox. I’ve liked it so much that I ended up buying it from the App Store.

It’s not without it’s faults, and after reading Alan Hogan’s article about the improvements to Mail in Lion, I may play around with Mail again. I’m not sure that I can get over the tags-are-folders nature of Mail, but it’s good to see there are options.

Really Easy RESTful Servers Using the Limonade Micro-framework

I just wrote a blog article for my company’s website based on work I did with the Limonade micro-framework. Check it out:

http://www.newsignature.com/blog/2011/08/09/easy-rest-servers-with-microframework/

Rails 3 & freezing gems

I learned an important lesson today. The quick summary is “bundler makes freezing gems unnecessary, use ‘bundle install –deployment‘”. But for those who like a good, geeky story:

I’ve been updating/upgrading/refactoring a Rails 2 project as a Rails 3 project. We’d used the method described here to ensure that developer, testing & production environments would be synched with regards to gems, particularly Rails itself.

Rails 3 introduces the use of bundler, a sweet gem management tool. In a googling of “rails 3 freeze gems” I came across a post on Stack Overflow describing a bundle option to set the BUNDLE_PATH variable.  I ran it and voila: all my gems were in the vendor/gems folder.  Seemed to do the trick.

When trying in vain to get the app building in Hudson, I came to realize that the –path option had not worked.  Instead, using ‘bundle install –deployment’ on the hudson machine (vs sending it all the gems as part of a Git checkout) was the REAL trick.

The moral of the story: don’t believe everything you read on the internet and RTFM.

ActiveResource, FakeWeb & Regex Mojo (authenticated edition)

Have a web service which needs requires authentication, but you’re testing a completely different part of the application?  Again, FakeWeb & Regex help you out here.  If you’re testing a model extended from ActiveResource by using FakeWeb, the url will look something like this: 

1
http://user:[email protected]/someService

To mock the request, use a regular expression like so:

1
FakeWeb.register_uri :get, %r|http:(.*)example.com/someService|, :body => 'foo'

Now you don’t have to worry about how you are authenticated. Of course you could use a more advanced regular expression, but we’re not testing that ActiveResource knows how to authenticate with a source, right?

More FakeWeb & RegExp mojo (anchors edition)

I’ve been using a lot of FakeWeb + Rspec for creating ActiveResource models BDD-style without hitting my RESTful source.  I keep on figuring out little things with FakeWeb that I feel like I should share.

When you register uri’s with FakeWeb, and you’re using regular expressions, you might be building layers of access like this:

All good, right? No. When you try to get comments, FakeWeb will give you an error:

Fear not, fair citizen. Regular Expressions Anchors to the rescue. See, FakeWeb is using the first registered uri regexp to match all calls past

1
http://example.com/posts

so your comments url is already matched. By using the ^ (pattern start) and $ (pattern stop) anchors, you can be a little more precise in your matching. Observe:

Tune in later for more: authentication edition.

HAML/SASS and the Holy Grail

I’ve been using HAML and SASS a lot lately because it’s kind of the best thing since sliced bread and ZenCode.  I’ve also been using Mathew James Taylor‘s no-quirks-mode 3 column holy grail layout because: why re-invent the wheel (or in this case the Rube Goldberg Machine that is column layout in CSS).

Matthew’s code says it’s free to use (thanks, Matthew!), so I’m doing my OSS-part by providing you HAML/SASS versions of the layout:

3 Column HAML:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
!!! 5
%html
  %head
  %body
    #header
    #colmask.three-column
      #colmid
        #colright
          #col1wrap
            #col1pad
              #col1
                -# Main content goes here
          #col2
            -# Left column here
          #col3
            -# Right column here
      #footer

3 Column SASS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
$left_col_width: 170px
$right_col_width: 170px

$padding: 15px

#colmask.three-column
  position: relative
  clear: both
  float: left
  width: 100%
  overflow: hidden
  #colmid
    float: left
    width: 200%
    position: relative
    left: ($left_col_width + $padding + $padding)
  #colright
    float: left
    width: 100%
    position: relative
    left: 50%
    margin-left: -1 * ($left_col_width + $padding + $padding + $right_col_width + $padding + $padding)
  #col1wrap
    float: right
    width: 50%
    position: relative
    right: 100%
  #col1pad
    margin: 0 $padding 0 ($left_col_width + $padding + $padding + $right_col_width + $padding + $padding)
    overflow: hidden
  #col1
    width: 100%
    overflow: hidden
  #col2
    float: left
    width: $left_col_width
    position: relative
    margin-left: -50%
    left: 215px
    overflow: hidden
  #col3
    float: left
    width: $right_col_width
    position: relative
    left: 15px
    overflow: hidden

As a bonus: his 2 column layout

2-column HAML:

1
2
3
4
5
6
7
8
9
10
11
12
13
!!! 5
%html
  %head
  %body
    #header
    .colmask.leftmenu
      .colright
        .col1wrap
          .col1
            -# Main body goes here
        .col2
          -# Left Column goes here
      #footer

2-column SASS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
>$left_col_width: 10em
$padding: 1em

$left_col_top_padding: $padding
$left_col_left_padding: $padding
$left_col_right_padding: $padding

$right_col_top_padding: $padding
$right_col_left_padding: $padding
$right_col_right_padding: $padding

// Header styles
#header
  clear: both
  float: left
  width: 100%

.colmask
  position: relative
  clear: both
  float: left
  width: 100%
  overflow: hidden

  // 2 column left menu settings
.leftmenu
  .colright
    float: left
    width: 200%
    position: relative
    left: $left_col_width+$left_col_left_padding+$right_col_left_padding
  .col1wrap
    float: right
    width: 50%
    position: relative
    right: $left_col_width+$left_col_right_padding+$right_col_right_padding
    padding-bottom: 1em
  .col1
    margin: $right_col_top_padding $right_col_right_padding 0 $left_col_width+$left_col_left_padding+$left_col_right_padding+$right_col_left_padding
    position: relative
    right: 100%
    overflow: hidden
  .col2
    float: left
    width: $left_col_width
    position: relative
    right: $left_col_width+$left_col_left_padding

  // Footer styles
#footer
  clear: both
  float: left
  width: 100%

Enjoy

MVC & BDD or “How I learned to stop worrying and love the test”

For a long time now, I’ve known I needed to get better at testing. Not smoke testing, but real unit testing, test driven development (TDD), or better yet behavior driven development (BDD).  I’d read papers, API’s and even wrote some after-the-fact unit tests for a CakePHP project.  It always seamed overly laborious and time consuming.

My second-most recent project at work is a fairly complex/robust Ruby on Rails application which consumes and provides a front-end for our REST services.  Under the gun to get features out quickly, we skipped over BDD and went right for a system of “live prototyping”. Devoid of tests, this app quickly became a game of Jenga where fixing one thing jeopardized the functionality of another. Implementing Cucumber tests after the fact stopped some of the bleeding, but I was finally starting to see the light.

Which brings me to my most current project. Also a Ruby on Rails application, I had the chance to do ground-up development so I decided to do it right.  At the suggestion of a co-worker who knows better, I replaced Rails’ default testing framework with RSpec for true BDD. The going has been slow, but here’s what I’ve found:

  1. By starting with behavior I’ve stuck to the “fat model, skinny controller” model where most of my functionality is in the model. It’s easier to test functionality on a model and then string the resulting data together in the controller.
  2. After the initial delays from learning rspec and getting the initial models and model tests written, the views come together really quickly
  3. I often re-factor my methods several times durring my initial writing. Using Autotest not only checks that I update all affected code, but I start anticipating where I need to update much faster than if I were doing it solo.

I hope someone comes across this article and it provides the final push to get on board with BDD. I truly believe that in the last month of development I’ve improved my MVC development skills as much as I have over the past 3 years. It’s provided a lot of “a ha” moments, and I’m writing better code.

RSpec, FakeWeb, Regexp; a gotcha

In my effort to be a better BDD/TDD (Behavior-Driven and Test-Driven Development) Developer, I’ve been diving into writing apps using RSpec for testing.  The nature of my work has me writing test where, in a non-automated-test environment, I would be using web services (SOAP and/or REST) to get and post data.  Now, obviously I don’t want to use a live web services to do this, so enter FakeWeb. I won’t go into the details of what FakeWeb is other than it allows me to fake responses to a given HTTP call.

So, I think I’m pretty slick, having found this nifty tool, but I keep getting schooled when I try to use a regular expression to register an HTTP query string like such:

1
2
3
4
5
FakeWeb.register_uri(
:get, %r|http:\/\/example\.com\/search\.html\?query=.*&collection=.*|,
:body => file )

My thought is that this will return 'file' every time I request something like:[cc]http://example.com/search.html?query=foo&collection=bar

. I’d be wrong.

After much monkey-patching-as-debugging of FakeWeb, I find out that when Ruby parses an incoming URI, it’s broken into parts such as protocol, host, path and query (there are more, but you get my point). When FakeWeb tries to match the incoming URI against my regular expression above, it key-sorts the query, so

1
http://example.com/search.html?query=foo&collection=bar
1
becomes http://example.com/search.html?collection=bar&query=foo

and FakeWeb throws it out as an unregistered URI. Fun!

Simply re-arranging the regular expression in the register call makes it all happy.

1
2
3
4
FakeWeb.register_uri(
:get,
%r|http:\/\/example\.com\/search\.html\?collection=.*&query=.*|,
:body => file )