Born to Test?

There are those random times where you find a bug and think, “Damn, I was born to test!” The other day I found a bug where this was the case – quite literally…

At Mimeo.com, we have a set of internal web apps written in ASP.NET MVC that are used by folks on the production floor to manage load and capacity for our presses. There were some new features added to the tool, and the devs asked me to take a look at the user stories and make sure things were in order. Now, I don’t normally test this tool. The devs have a really good battery of unit tests and are extremely diligent of testing the tool themselves. So I figured that I’ll just spend an hour or two doing some exploratory testing to dot the t’s and cross the i’s. And then I found a bug.

In one particular area of the app, the View grabs your domain account and passes it off to a Controller. So when I started to test out one of the newly added features, I kept getting a partially rendered page. This happened across all browsers I tested against. Now I’m thinking to myself, with all the unit tests and manual/exploratory tests the devs do themselves, how the hell did they let this through? Now I had the IE Dev Tools open already (as I usually do when exploratory testing a site), so I figured I should take a network trace and see if anything pops up. Here’s what I found:

image

It’s interesting that I’m getting a 400 response. Very odd. So, let’s talk to the devs. Neither of the two devs, Chris and Phil, could repro this issue. “Works fine for me!” Of course it does. L We took a closer look. My domain account is DOMAIN\nshenoy. But this is coming through as DOMAIN%0Ashenoy. When the developers looked at their resource request, Chris got “DOMAINchris” and Phil got “DOMAINphil”. Here’s the JavaScript code in the Index.cshtml that grabs the domain account:

 
var initParameters = {
    ...
    userName: “@User.Identity.Name” 
    ...
}; 

And here’s the script that actually uses this value:

 
my.getPressesUrl = function(userName) {
    return my.pressesUrl + “/” + encodeURIComponent(userName);
}

Hmm, so there’s a call to encodeURIComponent(). If we type “encodeURIComponent(DOMAIN\nshenoy)” into the console, sure enough we get DOMAIN%0Ashenoy. So it looks like it’s encoding the “\n” into an ASCII newline. And what’s happening for Chris and Phil? Seems that encodeURIComponent() is simply stripping out that backslash. Whoa.

Lesson 1: when dealing with domain accounts, be sure to replace to “\” with “\\” to properly escape it.

Cool, so I went ahead and just did a quick and dirty fix to the code like the following:

 
userName: ‘@User.Identity.Name.Replace(“\\”, “\\\\”)’

And this worked. The call to encodeURIComponent() now returned “DOMAIN%5Cnshenoy”. Yay? No. Because NOW I started to get a 404. What the what?! Here’s what the request looks like now in the network profiler:

image

This looks right to me. The username is correctly escaped, so we should be good to go right? Well, no. Obviously. So why isn’t this route resolving? The backslash is a special character and needs to be treated differently. To work around this issue of query strings containing special characters, we need to supply the “id=”. Changing the function like so made things work:

my.getPressesUrl = function(userName) {
    return my.pressesUrl + “/?id=” + encodeURIComponent(userName);
}

This could have been solved other ways (i.e. make a custom resolver in the RouteConfig.cs), but this works too.

Lesson 2: when naming your children, try to make their names interesting for testing purposes.

If my name wasn’t Nithin, I wouldn’t I have found this bug (thanks mom and dad!). Though I guess if I was a \timothy or \robert, it may have also resulted in interesting test cases. 😉

But seriously, pay attention to strings containing special characters. And also use the tools available to you. Simply watching network traffic in the dev tools while testing gave a wealth of information for why this strange behavior was happening in the first place.


Special thanks to @drub0y for reviewing this post.

Advertisements
This entry was posted in testing, Work and tagged , , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s