-
Notifications
You must be signed in to change notification settings - Fork 9
Best practice for hapi route testing #214
Comments
Are your routes inheriting some default authentication strategy from their connection configuration? I can't tell exactly what your reduced server will be missing, nor what the intended benefits of testing the reduced server are. But I do have an initial impression/thought. Since you can mock credentials easily, this seems like a good excuse to keep the authentication config present, since the strategies are so easy to bypass. One reason to keep authentication enabled on each route during testing is that scope and entity-type are still validated whether or not you bypass the strategies. Authentication state is still managed too– if any of your request lifecycle hooks care about |
Thanks for the quick response! Yes, that's true, I only bypass the authentication-strategy, which is the same for every route ('hapi-auth-jwt2'). Sorry for confusing the terms logic and strategy. As the authentication-strategy is tested on its own, it should be safe to bypass it for the route-tests, I guess. (Right?) The intended benefits are more focused and better readable tests. At the moment my tests look like this: suite('/images/', function () {
...
test('POST-request with valid data', function (done) {
// add test user to database
addUser()
.then((user) => {
// authenticate user by creating a valid JSON Web Token
return authenticate(user);
})
.then((user) => {
const request = {
method: 'POST',
url: '/images/',
headers: {
'Cookie': user.jwtCookie, // apply JWT as cookie
},
payload: {
'metaData': {
'title': 'Test Title',
'location': 'Rome',
},
},
};
return server.injectThen(request);
})
.then((response) => {
// do assertions on response
...
done();
})
.catch(done);
});
...
});
Another benefit is, that the server-initialization might be faster, if I only add the necessary routes. But maybe its better to take the middle by only adding the auth-strategy and the route-plugin to test? What about the collision of routes? Does hapi detect possible collisions on server start? |
What you're saying sounds right to me– if you're testing your auth strategy on its own, then it's fairly safe to bypass that auth strategy in other tests by setting I don't know of any way for routes to collide– though not often stated, it is a top priority of hapi's to avoid route collision. The router (hapijs/call) would throw an error as soon as a conflicting route is added. |
So far I organized every main-resource as plugin. E.g. one plugin for the resource But it's good to know about this collision-feature, thanks for the hint! And thank you very much for clearing things up, Devin! |
Cheers! :) |
Hello, I'm doing something very similar to what it is being done here. I also start a minimal server with hawk as authentication strategy. I'm injecting the credentials in the request that I'm injecting to the server, as it is described here. I'm not the author of the endpoint that I'm testing, so I'm not sure about the motivations behind this, but the end point depends on the existence of an artifact property inside the credentials. It makes this check if (typeof request.auth.artifacts !== 'undefined') {
id = request.auth.artifacts.id;
} Such artifact seems to be injected in the validation process of happi. Could someone tell me if this is a bad practice (for me it looks like) and if not, how can I simulate such thing? |
@danielo515 |
Dear @devinivy, Regards |
By the way, could you provide an example? Is just an artifacts property like a do for the credentials? Or is something else? |
server.inject({/* ... */, credentials: {}, artifacts: {} }, (res) => {/* ... */}) The |
Hello @devinivy your suggestion worked like a charm. Thank you very much. |
I recently switched from express to hapi to develop a REST API and so far it feels like a really good decision. Especially the testing with
lab
andserver.inject
is a pleasure.Before, with express, I wrapped the whole application with
chai-http
and tested all api endpoints with actual http-requests. With hapi I'm doing it similarly: I require the server-file and after the composition of the whole server with all its routes and plugins, I do the tests withserver.inject
, which is much more comfortable than doing "real" http-requests. So with every test, authentication logic is tested as well as possible collisions with other routes, which seems to be a good idea.But now I realized, that
server.inject
can even bypass authentication-logic by simply setting thecredentials
option. So I'm very tempted to compose a highly reduced server for every endpoint-test-suite, that only contains the route(-plugin), that I want to test. But I'm too much a hapi-beginner to foresee, if this will lead to reliable test results.What's your opinion on this? I would love to see some best practice on api-route testing.
The text was updated successfully, but these errors were encountered: