markdown 挑战19:测试Auth

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了markdown 挑战19:测试Auth相关的知识,希望对你有一定的参考价值。

# Challenge - Create User Tests

In this challenge you will create integration tests to verify User endpoints including `/login`. And you will update the integration tests for endpoints protected by JWT.

## Create a User tests

Create a `/test/users.test.js` file and copy in the starter from this [gist](https://gist.github.com/cklanac/2e82a1a8e151c79779293a3615877fcc)

The setup and Mocha hooks have been completed for you. And note the use of `describe.only` which tells Mocha run this suite of tests and skip the others. You'll tackle the other tests later. 

Your challenge is to complete the User tests and assertions based on the `describe` and `it` blocks in the file. Again you can use the [Node JWT Auth](https://github.com/Thinkful-Ed/node-jwt-auth) as a guide.

# Challenge - Testing JWTs and Protected Endpoints

Next, update integration tests to support to test JWT authorization. As you proceed, you should refer to [Node JWT Auth](https://github.com/Thinkful-Ed/node-jwt-auth) as a guide.

## Access Protected Endpoint

Chia-Http makes accessing endpoints protected by JWTs is relatively easy. Simply create a valid JWT using the site's `JWT_SECRET` and add it as a Bearer token to each request. But there's a wrinkle, the resources (eg. notes, folders and tags) belong to an specifec individual so the JWT must be created using the seed data. And the tests must be updated to check for the specific user's resources.

We'll tackle this challenge in 2 steps. First, configure the tests to generate a valid JWT and use it to test an endpoint. Second, update the tests to verify the data based on the user.

### Create a JWT in `beforeEach`

Starting with `/test/folders.test.js` update the `beforeEach` as follows.

Insert the users and folders into the database. Then capture the users and extract the first user and create a valid JWT.

```js
  // Define a token and user so it is accessible in the tests
  let token; 
  let user;

  beforeEach(function () {
    return Promise.all([
      User.insertMany(seedUsers),
      Folder.insertMany(seedFolders),
      Folder.createIndexes()
    ])
      .then(([users]) => {
        user = users[0];
        token = jwt.sign({ user }, JWT_SECRET, { subject: user.username });
      });
  });
```

> Note, the example above assumes the passwords in the seed data have been hashed. 

### Add JWT to request header

Before attempting to add the JWT to your requests you should update your test suite so only one test is executed. This allows you to focus on one test at a time. In the example below we are focusing on the `GET /api/folders`. Add `.only` or `.skip` to the `describe` and it `blocks` as needed.

Now we need to add the JWT to the `Authorization` header as a Bearer token. Luckily, the Chai-HTTP `.set()` method makes this easy. Below is a generic example

```js
  chai.request(app)
    .get('/api/protected')
    .set('Authorization', `Bearer ${token}`)
    .then(() => {
      /*...*/
    });
```

Add the Authorization header with the Bearer token to the `/api/folders/` test as shown below.

```js
  describe.only('GET /api/folders', function () {
    it('should return the correct number of folders', function () {
      const dbPromise = Folder.find();
      const apiPromise = chai.request(app)
        .get('/api/folders')
        .set('Authorization', `Bearer ${token}`); // <<== Add this

      return Promise.all([dbPromise, apiPromise])
        .then(([data, res]) => {
          expect(res).to.have.status(200);
          expect(res).to.be.json;
          expect(res.body).to.be.a('array');
          expect(res.body).to.have.length(data.length);
        });
    });
```

Now when you run the test, you should no longer get an Unauthorized error, but the test will not pass. Comment-out the `expect(res.body).to.have.length(data.length)` assertion and run it again.

Let's fix the length issue now.

### Update tests to expect specific user content

The test did not pass because the `/api/folders/` endpoint returns results for a specific user. But the database cross-check is still selecting **all** folders. You need to update the `Folder.find()` to include the User id like so:

```js
  Folder.find({ userId: user.id })
```

The complete test will look like this:

```js
  it('should return the correct number of folders', function () {
    const dbPromise = Folder.find({ userId: user.id });
    const apiPromise = chai.request(app)
      .get('/api/folders')
      .set('Authorization', `Bearer ${token}`);

    return Promise.all([dbPromise, apiPromise])
      .then(([data, res]) => {
        expect(res).to.have.status(200);
        expect(res).to.be.json;
        expect(res.body).to.be.a('array');
        expect(res.body).to.have.length(data.length);
      });
  });
```

Let's try another one. The next test verifies that the response contains the correct keys. The updated endpoint now returns the `userId` in addition to the `id` and `name`. Update your test with the Authorization header, add a filter to the database query and update the assertion as shown below.

```js
  it('should return a list with the correct right fields', function () {
    const dbPromise = Folder.find({ userId: user.id }); // <<== Add filter on User Id
    const apiPromise = chai.request(app)
      .get('/api/folders')
      .set('Authorization', `Bearer ${token}`); // <<== Add Authorization header

    return Promise.all([dbPromise, apiPromise])
      .then(([data, res]) => {
        expect(res).to.have.status(200);
        expect(res).to.be.json;
        expect(res.body).to.be.a('array');
        res.body.forEach(function (item) {
          expect(item).to.be.a('object');
          expect(item).to.have.keys('id', 'name', 'userId', 'createdAt', 'updatedAt');  // <<== Update assertion
        });
      });
  });
```

Your challenge!

Update the rest of the Folder tests **and** then apply your learning to the Tag and Note tests.

## Deploy the app

If time allows, you should push your changes to GitHub and verify your tests pass on Travis CI and are deployed to Heroku.

以上是关于markdown 挑战19:测试Auth的主要内容,如果未能解决你的问题,请参考以下文章

markdown 挑战10:Knex JS测试

markdown 挑战20测试JWT

markdown 挑战13:猫鼬测试

markdown 挑战05:使用摩卡柴进行测试

吴恩达-医学图像人工智能专项课程-第一课第一周19-20节

markdown Auth0笔记