Rspec & Real World Testing
July 10th, 2008
Rspec is a tasty testing suite for Rails. It’s stubbing can be enhanced by using Mocha, a stubbing framework. There is a spattering of documentation to get you started, but a few controller level items were challenging to test:
- Included modules
- Filtered parameters
- Before filters
- Response codes
- Facebook redirects
And I had to pick up a few model testing tricks too:
- Association testing
- ActionMailer testing
Let’s look at some good approaches for each of these.
Read the rest of this entryMooTools and Rails CSRF Protection
June 25th, 2008
“Cross site request forgery” is also known as CSRF, XSRF or just request forgery (more at wikipedia and sans.org). It’s a method of attack toward web applications- Rails 2.0 introduced a defence and Rails 2.1 enabled that defence by default. Call form_for…
1 |
<% form_for @friend, :action => 'create' do |f| %> |
and Rails spits out more than just the form, it also generates a secret authenticity_token:
1 2 3 4 |
<form action="/friends" method="post"> <div style="margin:0;padding:0"> <input name="authenticity_token" type="hidden" value="e8c827c47577e013cc4c06a99cab63da95b71915" /> </div> |
AJAX submission of this particular form will include the authenticity token. So here’s the rub: what if the form is generated by something else?
1 |
new Element('form', { 'action': '/friends'}); |
Or what if there is no form?!
1 |
new Request.Json( ... ).post(); |
In these cases Rails would raise an ActionController::InvalidAuthenticityToken exception. To avoid an exception the CSRF check can be altogether disabled for a controller:
1 |
skip_before_filter :verify_authenticity_token
|
Of course this is a compromise between convenience and security. For those who want security and AJAXy goodness (well, with MooTools at least), there is a better way.
Using AuthenticityToken with MooTools
MooTools has a wonderful object oriented codebase. First Rails needs to pass the authenticity_token into Javascript, then we can use the inheritance from MooTools to pass the authenticity_token with every request.
The authenticity_token can be passed in the header of the Rails application layout. It’s just one line:
1 |
<%= javascript_tag "const AUTH_TOKEN = #{form_authenticity_token.inspect};" if protect_against_forgery? %> |
And now pass that token with every POST request (GET requests don’t check CSRF):
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 |
// Include authenticity_token in Request.JSON fires // // move the send function Request.prototype._send = Request.prototype.send Request.implement({ auth_token: function(){ return AUTH_TOKEN; }, // This is more verbose than is ideal, but I don't see a better place // to hook this functionality in send: function(options){ var type = $type(options); if (type == 'string' || type == 'element') options = {data: options}; var old = this.options; options = $extend({data: old.data, url: old.url, method: old.method}, options); switch ($type(options.data)){ case 'element': options.data = $(options.data).toQueryString(); break; case 'object': case 'hash': options.data = Hash.toQueryString(options.data); } // If this isn't a get request add the authenticity_token if (options.method != 'get' || options.method != 'GET') options.data = options.data+'&authenticity_token='+this.auth_token(); // Call the original send this._send(options) } }); |
Look at that, now every AJAX call from MooTools will attach our CSRF. All the ease of normal javascript, all the security of the native Rails defences.
The Joy of Tables On Cows
June 20th, 2008
On June 12th MooTools 1.2 was released, to great rejoicing. It’s a release that really sets MooTools apart with better Fx, more browser compatibility effort, and a jaw dropping element storage feature. That means it’s time to update the table sort script I’ve blogged here before (The Joy of a Minimal, Complete Javascript Table Sort and The Joy of an Optimized, Complete Javascript Table Sort). This release does more than just port, and also adds a few features:
- Sorts more out of the box:
- strings
- numbers
- decimal currency (12.34, 4.50)
- dates (YYYY-MM-DD, YYYY-M-D)
- relative dates (1 day ago, 38 years ago)
- disk memory (1.75 MB, 34 KB, 8 TB)
- Passes the matcher into the conversion_function for re-use.
- Classes set for forward and reverse sorting th tags.
- A “don’t sort” class.
- It’s on github!
- Integration with the brand new pagination library.
Oh yeah, and that. There’s now a pagination library supporting all the same things like expanding rows. It’ll do multiple pagination link areas and drop offset and cut-off numbers into the DOM. Let’s take a look.
Read the rest of this entrySomeone At Mozilla Is Getting Too Cute
June 18th, 2008
Ok, so I load up Firefox 3 and go to change some settings, you know, try reverting all the tweaks I’ve made to Firefox 2. I enter the incantation “about:config” into the URL bar and get this:
![What Warranty?]](http://madhatted.com/assets/2008/6/18/what_warranty.jpg)
What? Void my warranty? I get a warranty with this open source software? That’s a new one to me.

Oh wait, yeah, I don’t. Please Mozilla, stick with the warnings about understanding the settings and don’t use inappropriate legalese. The whole “void your warranty” phrase is the fear-mongering motto of anti reverse engineering corporates everywhere. Firefox is open source, it should embrace everything the opposite, encourage me to explore and experiement.
To top it off, making me click on I’ll be careful, I promise! is just a little too cute and condescending. I’m feeling a lack of UI polish so far in Firefox 3. I’ll cover a few other things after I organize my thoughts, but this was just too good to wait on.
Missing Mephisto Upgrade Guide: 0.7.3 to 0.8
April 25th, 2008
My Mephisto install was 0.7.3- 0.8 doesn’t have any huge feature changes but there are some bugfixes and small enhancements, as well as a performance boost (speed, memory use) from using rails 2.0. My install was from a tarball, and I don’t want to move my production server to a git checkout (yet?). Like other Mephisto users I’ve got theme customizations and maybe even some things in the public directory.
I need to upgrade, not reinstall. The Mephisto folks didn’t write a real upgrade guide, but this is Rails and it’s not too hard to figure out. Almost any rails app could be updated this way:
- Back Everything Up
- Create & Apply A Patch
- Stop Your Server & Clean Up
- Patch Code & Migrate The Database
- Crack Open A Beer
Keep Google Happy: SEO For Online Stores
April 24th, 2008
As a side project I’ve helped some friends launch Liquidware, a simple storefront for their Arduino modules and other open/hobby hardware. They created a decent amount of buzz about their launch by saving up a bunch of content and pushing it out the same weekend. Blog posts, video, images, all that good stuff:
That was good noise, and it got them enough traffic to sell out of a few stocked items (woohoo!). But after the launch bubble a steady stream of sales needs to come from Google. I’ve been experimenting with the SEO on Liquidware’s site and learned a few smart tricks for your next storefront.
Read the rest of this entryDancing Tags
February 21st, 2008
So just two days ago Obama swept Hawaii for his 10th Democratic primary win in a row. Barack in particular has been beat up for lacking real content in his message, though I personally think his actions have spoken loudly (he taught constitutional law, supported Net-neutrality, and helped push the ethics reform bill). Using tag clouds for visualizing messages has been done before, with pretty interesting results
That example was nice for a snapshot of each candidate, but I’m looking to dig into the data for a single candidate a little more. I want to compare tag clouds for Obama to see how his message has changed over time.
Read the rest of this entryThe Joy of an Optimized, Complete Javascript Table Sort
January 16th, 2008
When you’re done poking through this, check out the final version of this script at The Joy of Cows On Tables
A few days ago we walked through writing our own mootools-based table sort in the Joy of a Minimal, Complete Javascript Table Sort. A poster going by “hello there” raised a good point about performance:
“would be nice to see the example with several hundred rows - performance in sorting is a huge issue, and looking at the zillions of libraries out there… many of them konk out completely, taking 5 seconds to sort a table with 1,000 rows.”
Right. Javascript should be used to enhance a user’s experience. 5 seconds of wait times for a table sort is completely asinine. Let’s look at some quick ways to optimize our code, and uncover a slick way to double the speed of our sorting.
Read the rest of this entryThe Joy of a Minimal, Complete Javascript Table Sort
January 11th, 2008
When you’re done poking through this, take a peek at how you can double the speed of this script in The Joy of an Optimized, Complete Javascript Table Sort, and then check out the final version of it at The Joy of Cows On Tables
Ah table sorting. There are few problems that have been solved as many times as you have been. Unfortunately, some of the nicest solutions, such as mootable, are also pretty overbearing. Check out this feature list:
- Total re-styling of your table.
- Editable table cells.
- Loading table contents from JSON.
- Loading table contents from JSON over XHR.
- Server-side sorting using the above.
- Client-side sorting.
- Re-ordering of columns, column options.
- Nice fade effects.
- Event hooks.
Whoa, too much. Over at ICA we needed something way more lightweight. I was pretty much looking for this:
- Client-side sort of various formats (like mm/dd/yy).
- Zebra or striped tables.
- Support sorting with hidden rows on the table.
- Be fairly fast.
- Use mootools (which we already use).
- Use a table already on the DOM.
Let’s take a look at how to make a javascript table sort that follows best practices, is relatively minimal, and fast. Nothing here is completely new stuff, but hopefully walking through it will help you write a better table sort next time you need just a table sort, and not all the overhead of a library. I’ll be using mootools sort of aggressively, but the core ideas and practices here are portable to any environment.
Here we go!
Read the rest of this entryMaking More of Ferret Queries
June 4th, 2007
Oh Ferret, how lovely your speed, how confusing your documentation. Maybe we’ll go over that in another post, but for now, let’s see how we can make Ferret a bit kinder to normal users by better understanding their queries.
Over at FindYourDoc we’re searching not only a large number of records, but a large variety of fields. When we get a query such as:
Doctor in Nashville TN
You and I know the user has given us a lot to go on, but Ferret doesn’t. When humans look at that query we pull out a human understanding.
- Doctor - a type of care provider
- in - a throwaway word
- Nashville - a city
- TN - a state
So if I were a programmer (imagine that), I would form the same query using Ferret’s query syntax:
type:Doctor city:Nashville state:TN
Well great, but our visitors are not programmers, they’re grandmothers and dog trainers, patients and college students. Let’s look at that query again, and see how we could break it down:
- Doctor & TN - These are phrase that look for a match in specific sets.
- Nashville - matches data in a very large set.
- in - throwaway word.
So let’s see how the raw query might be moved closer to my programmers query.
Read the rest of this entryYes, geocode, but save your caches
May 31st, 2007
Geocoding is like a spicy pepper, it provides an impressive kick, but should normally be sprinkled in moderation. Now that rails has GeoKit, it’s even super-easy to do.
Once you fight your way through the API-only documentation.
But lucky you, we’re going to walk through a basic GeoKit set up modeled after what we used over at FindYourDoc (we launch next week-ish):
- Install GeoKit
- Find out where a visitor is from and stuff it in a cookie
- Test our geocoding (‘cause duh, you’re testing, right?)
- Use javascript to put it somewhere
At the end of this you’ll be customizing pages for visitors based on their location, but without killing off your action_caches. Won’t that be a ball?
Read the rest of this entry