Error responses

Loading "Error Responses"
Right now, we are sending the exact successful JSON response that the getAuthToken() expects. That allows us to reproduce and test the happy path behavior.
But there are more behaviors that we intended for this function, and they happen to concern themselves with error handling.
First, there's the logic that throws an error if the server responds with a 401 response (i.e. we are sending invalid user credentials and the authorization fails):
if (response.status === 401) {
  throw new Error('Authentication failed: invalid credentials')
}
Then, there's another check for generic response errors as well:
if (!response.ok) {
  throw new Error('Authentication failed: network error')
}
Let's model both of these scenarios in tests with MSW!
The request handlers we write in handlers.ts are meant to describe the happy path behaviors. In order to test our error handling, we will use a feature called runtime request handlers.
In simple terms, a runtime request handler is a request handler you can add in individual tests. It extends your network description and allows you to add new network behaviors to your happy paths defined in handlers.ts.
Runtime handlers can be added using the server.use() function:
import { http } from 'msw'
import { setupServer } from 'msw/node'

const server = setupServer(
  // This is a happy path handler.
  http.get('http://localhost/resource', () => {
    return Response.json({ response: 'happy' })
  }),
)
server.listen()

await fetch('http://localhost/resource').then((response) => response.json())
// {"response":"happy"}

server.use(
  // This is a runtime handler override. It has the same
  // predicate (request path) as the happy path handler
  // but returns a different mocked response.
  http.get('http://localhost/resource', () => {
    return Response.json({ response: 'override' })
  }),
)

await fetch('http://localhost/resource').then((response) => response.json())
// {"response":"override"}
Above is an example of adding a runtime handler for the GET http://localhost/resource endpoint. Notice how the response to the fetch() call changes based on whether the request was made before or after the runtime handler was added.
๐Ÿ‘จโ€๐Ÿ’ผ It's time you learned to use the power of runtime handlers! Rewrite the test to add new test cases for the error handling logic of the getAuthToken() function.
To achieve that, you'd have to reuse the server from both for the setup file and the test.
๐Ÿจ Move handlers.ts to ./mocks so it becomes ./mocks/handler.ts.
๐Ÿจ Move the server setup from to the new mocks/node.ts module.
import { setupServer } from 'msw/node'
import { handlers } from './handlers.js'

const server = setupServer(...handlers)
import { server } from './mocks/node.js'

beforeAll(() => {
  server.listen({
    onUnhandledRequest: 'error',
  })
})

afterEach(() => {
  server.resetHandlers()
})

afterAll(() => {
  server.close()
})
๐Ÿจ Then, head to the file and complete the new test cases. Verify your solution by running npm test.

Access Denied

You must login or register for the workshop to view the diff.

Check out this video to see how the diff tab works.