tidepool-org/blip — pull request #25 by nicolashery (2014-03-06 15:59:51+00:00)
Title: Test different app behaviors with mock parameters via query strings

I'm going to merge this later in the day if that's all right, but I wanted to show it as a PR to explain a bit what I've added, and what it allows for Blip developers.

Front-end Blip developers spend a lot of time (I know I do!), working solely on UI behaviors (ex: I click this button I'm taken to this screen, etc.), and not worrying (yet) about talking to an external API (the Tidepool platform).

**Mock services**, which we introduced in the first version of Blip, using **mock data**, already help a lot with this. Refreshing the browser and rendering the app is fast, because the app makes no external calls.

But when working on a piece of UI, there's a lot of scenarios I want to take into account, for example:

- What happens if this API call returns an empty list, and what do I show on the screen?
- What does the user see while the app is waiting for the data to return from the server?
- Etc.

Also, mocking authentication with "demo/demo" as credentials is all fine and fun, but I may not want to have to type that in the login screen every time I hit refresh.

So before, I would "hack" the mock services' code, commenting out this line, adding a line here to return an empty list directly, adding a line there to authenticate automatically, etc. It works, but it's not great, and I run the risk of checking in these "hacks". Plus, I'm not really able to re-use these "alternate scenarios" in my automated end-to-end tests.

Enter **mock parameters**, via query strings. The way they work is pretty simple, so I'll just illustrate with an example. Let's say I'm working on the "patients" page (and of course I have the app running in "mock mode"). The screen looks like this:

![screen shot 2014-03-06 at 4 42 10 pm](https://f.cloud.github.com/assets/1306536/2346788/f74b59de-a545-11e3-931e-1a89f97379e0.png)

Now, if enter the following URL, I can work on what happens when the user has no shared patients:

```
http://localhost:3000/?auth.skip&api.patient.getall.empty#/patients
```

![screen shot 2014-03-06 at 4 43 31 pm](https://f.cloud.github.com/assets/1306536/2346799/2f59dcba-a546-11e3-8081-6906ba3b4c0a.png)

With this other URL, I can work on what the app shows while the patient list is being fetched from the server:

```
http://localhost:3000/?auth.skip&api.patient.getall.delay=2000#/patients
```

![screen shot 2014-03-06 at 4 45 19 pm](https://f.cloud.github.com/assets/1306536/2346836/9025e32c-a546-11e3-865f-ca114c4f8c27.png)

Etc. You get the idea :)

What's more, I can actually use this in my "end-to-end tests" (or "feature/acceptance tests"). Since, in these tests the app is pre-built and loaded fully into a browser (that I'm driving automatically with Selenium), I can't use fixtures or mocks directly in my tests (like I would in unit tests for instance).

Since I can define alternate behaviors with a simple URL query strings, I can write end-to-end tests like this:

```javascript
it('should show shared patients', function(done) {
openAppToPatients()
.then(function() {
expect('.js-patients-shared .js-patient')
.dom.to.have.count(3);
done();
});
});

it('should show message if user has no shared patients', function(done) {
openAppToPatients({
'api.patient.getall.empty': true
})
.then(function() {
expect('.js-patients-shared-empty').dom.to.be.visible();
done();
});
});

function openAppToPatients(qs) {
return openAppTo('/patients', _.assign({
'auth.skip': true
}, qs));
}
```

Nice!

Now of course, keep in mind that these "end-to-end tests" are just a quick check that things haven't broken at a high level. They by no means replace testing the app manually, and testing it against a real API with real data. :)

That's it! I've added details on these new **mock parameters** in the README. I hope as people work on Blip they will find them as useful as I do.

PS: @ianjorgensen I wanted to thank you for giving me (without knowing) the inspiration for this :) You used query strings in your first demo to load it with certain parameters, and I found that very clever!