Conversation
package.json
Outdated
| "@loopback/rest": "^0.19.2", | ||
| "@loopback/openapi-v3": "^0.12.2" | ||
| "@types/bcrypt": "^2.0.0", | ||
| "bcrypt": "^3.0.0", |
There was a problem hiding this comment.
Please use https://github.com/dcodeIO/bcrypt.js instead.
There was a problem hiding this comment.
Any reason for using that modules over the one I'm using?
There was a problem hiding this comment.
bcrypt is a binary add-on and it requires compilation.
There was a problem hiding this comment.
And we don't want that? CI was failing before because I was running install with --ignore-scripts. The JS version is about 30% slower according to their own docs.
There was a problem hiding this comment.
Plain JS module is much more desirable for an example app. It will remove a lot of support issues in the future.
package.json
Outdated
| "@loopback/repository": "^0.14.2", | ||
| "@loopback/rest": "^0.19.2", | ||
| "@loopback/openapi-v3": "^0.12.2" | ||
| "@types/bcrypt": "^2.0.0", |
src/controllers/user.controller.ts
Outdated
| } | ||
|
|
||
| // Validate Password Length | ||
| if (obj.password.length < 8) { |
There was a problem hiding this comment.
Is this a temporary solution to the fact that we are not supporting authentication atm? I would have assumed that the password at the framework level would have been hashed
There was a problem hiding this comment.
We don't have a default User model like we did in LB3 which is where these checks / hashing would've been implemented. So for now people would have the flexibility to implement User how they want.
| import {createClientForHandler, supertest} from '@loopback/testlab'; | ||
| import {RestServer} from '@loopback/rest'; | ||
| import {ShoppingApplication} from '../'; | ||
| import {ShoppingApplication} from '../..'; |
There was a problem hiding this comment.
This is probably a good reminder for us to change the template generated by our app generator so that this file lives in the acceptance folder
| .send(user) | ||
| .expect(200) | ||
| // tslint:disable-next-line:no-any | ||
| .expect(function(res: any) { |
There was a problem hiding this comment.
it's not all that important, but we can use the supertest's promise support here:
const response = await client.post('/users').send(user).expect(200);
// assertions
src/datasources/db.datasource.ts
Outdated
| @@ -0,0 +1,14 @@ | |||
| import {inject} from '@loopback/core'; | |||
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
|
|
||
| if [ $TASK = "test" ]; then | ||
| echo "TASK => MONGODB STARTUP DELAY" | ||
| sleep 10 |
There was a problem hiding this comment.
Can we have a check for mongodb service / process here instead of using sleep?
There was a problem hiding this comment.
We would have to check and sleep / something if the service isn't up and ready yet anyways. This is the fix recommended by Travis themselves, documented here: https://docs.travis-ci.com/user/database-setup/#mongodb-does-not-immediately-accept-connections
bin/setup.sh
Outdated
| @@ -0,0 +1,3 @@ | |||
| docker rm -f mongodb_c | |||
There was a problem hiding this comment.
Can we have a variable to represent the name of the container? Feel free to ignore as this can be done later if need be.
src/controllers/user.controller.ts
Outdated
| ) {} | ||
|
|
||
| @post('/users') | ||
| async create(@requestBody() obj: User): Promise<User> { |
There was a problem hiding this comment.
nitpick: I suggest we rename obj to userObj or user or something along those lines
There was a problem hiding this comment.
That's the default we generate using the lb4 controller command but a good call. Will update.
src/controllers/user.controller.ts
Outdated
| @get('/users/{id}') | ||
| async findById(@param.path.string('id') id: string): Promise<User> { | ||
| const user = await this.userRepository.findById(id); | ||
| delete user.password; |
There was a problem hiding this comment.
I wonder if juggler can take care of this for us using some sort of flag.
shimks
left a comment
There was a problem hiding this comment.
In this PR, do we want to have a separate datasource and docker configured for just testing? I'd imagine we don't want to run any tests on potentially existing data
| .expect(415); | ||
| }); | ||
|
|
||
| it('returns a user with given id when POST /user/{id} is invoked', async () => { |
| }); | ||
|
|
||
| it('returns a user with given id when POST /user/{id} is invoked', async () => { | ||
| const userWithId = Object.assign({}, user, {id: userId}); |
There was a problem hiding this comment.
Instead of setting userId in a separate test, I think it's better for the user to be created in the test (through the repository), set the userId, and then call the endpoint. This allows tests to not be dependent upon each other.
Also, the created user instances need to be deleted after each tests
Signed-off-by: virkt25 <taranveer@virk.cc>
Signed-off-by: virkt25 <taranveer@virk.cc>
|
|
||
| // Save & Return Result | ||
| const savedUser = await this.userRepository.create(user); | ||
| delete savedUser.password; |
There was a problem hiding this comment.
While this is good enough for the initial implementation, it is also very brittle. We should find a more robust way how to allow models to hide certain properties from toJSON output.
In the past, I had very good experience with moving the password to a different model (table/collection) and use hasMany relation. As a nice side effect, by keeping a hash of all previous passwords, we can easily implement a password policy like "cannot reuse the same password".
| @get('/users/{id}') | ||
| async findById(@param.path.string('id') id: string): Promise<User> { | ||
| const user = await this.userRepository.findById(id, { | ||
| fields: {password: false}, |
| import {createClientForHandler, supertest} from '@loopback/testlab'; | ||
| import {RestServer} from '@loopback/rest'; | ||
| import {ShoppingApplication} from '../'; | ||
| import {ShoppingApplication} from '../..'; |
| let client: supertest.SuperTest<supertest.Test>; | ||
| const userRepo = new UserRepository(new UserDataSource()); | ||
|
|
||
| const user = { |
There was a problem hiding this comment.
I'd prefer us to follow our own best practices, see Use data builders.
implements the remainder of loopbackio/loopback-next#1480