Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wrong history of request when use an interceptor to re-send request with changed config #348

Open
eagleliang opened this issue Oct 8, 2022 · 0 comments

Comments

@eagleliang
Copy link

versions:

  • node: 16.14.0
  • adios-mock-adapter: 1.21.2

The history of request's config seems to be overwrite if it belongs to the same request.

Here is the demo code: I create a axios instance which will update the request's headers if server's response's data said statusCode is 401 (NOTE: not http status code), and re-send the request with the updated config.

The expectation is the first request header should not as same as the second. But the assertion always failed ( For reading convenience, I put the failed assertion at the end of the test case)

------------ netadapter.ts ----------------

import axios, {AxiosRequestHeaders} from "axios";

export class NetAdapter {
    #accessToken: string | undefined = undefined
    #instance = axios.create({
        baseURL: 'http://192.168.1.1'
    })

    constructor() {
        this.#instance.interceptors.response.use(async (res) => {
            const originalConfig = res.config

            if (res.status === 200 && res.data?.statusCode === 401) {
                if (originalConfig.headers) {
                    originalConfig.headers = {
                        ...originalConfig.headers,
                        accessToken: '123456',
                    }
                } else {
                    originalConfig.headers = {
                        accessToken: '123456'
                    }
                }

                return await this.#instance.request(originalConfig)
            }
            return res
        })
    }

    async call(api: string) {
        const headers: AxiosRequestHeaders = this.#accessToken ? {accessToken: this.#accessToken} : {}
        return await this.#instance.post(api, {}, {headers: headers})
    }

    setToken(token: string) {
        this.#accessToken = token
    }
}

-------------------- the test suits ---------------------

import {NetAdapter} from "../src/netadapter";
import MockAdapter from "axios-mock-adapter";
import axios from "axios";
import exp from "constants";

let adapter!: NetAdapter;
let mockAxios!: MockAdapter;

beforeAll(() => {
    mockAxios = new MockAdapter(axios, {delayResponse: 200})
})

beforeEach(() => {
    mockAxios.reset()
    adapter = new NetAdapter()
})

describe('axios mock test', () => {
    test('auto add token', async () => {
        const expectUrl = '/abc'
        mockAxios.onPost().replyOnce(200, {statusCode: 401}).onPost().replyOnce(200)

        const res = await adapter.call(expectUrl)
        expect(mockAxios.history.post.length).toBe(2)
        expect(mockAxios.history.post[0].url).toContain(expectUrl)
        expect(mockAxios.history.post[1].url).toContain(expectUrl)
        expect(mockAxios.history.post[1]?.headers?.accessToken).toEqual('123456')
        expect(mockAxios.history.post[0]?.headers?.accessToken).toBeUndefined()
    })

    test('auto update token', async () => {
        const expectUrl = '/abc'
        mockAxios.onPost().replyOnce(200, {statusCode: 401}).onPost().replyOnce(200)
        adapter.setToken('666')

        const res = await adapter.call(expectUrl)
        expect(mockAxios.history.post.length).toBe(2)
        expect(mockAxios.history.post[0].url).toContain(expectUrl)
        expect(mockAxios.history.post[1].url).toContain(expectUrl)
        expect(mockAxios.history.post[1]?.headers?.accessToken).toEqual('123456')
        expect(mockAxios.history.post[0]?.headers?.accessToken).toEqual('666')
    })

    test('manual set token and send request instead of automation', async () => {
        const expectUrl = '/abc'
        const expectToken = 'fff'

        mockAxios.onPost().reply(200)
        await adapter.call(expectUrl)
        adapter.setToken(expectToken)
        const res = await adapter.call(expectUrl)

        expect(mockAxios.history.post.length).toBe(2)
        expect(mockAxios.history.post[0]?.headers?.accessToken).toBeUndefined()
        expect(mockAxios.history.post[0].url).toContain(expectUrl)
        expect(mockAxios.history.post[1]?.headers?.accessToken).toEqual(expectToken)
        expect(mockAxios.history.post[1].url).toContain(expectUrl)
    })
})

-------------- the test results -------------------

  FAIL  test/NetAdapter.test.ts
  axios mock test
    ✕ auto add token (423 ms)
    ✕ auto update token (414 ms)
    ✓ manual set token and send request instead of automation (417 ms)

  ● axios mock test › auto add token

    expect(received).toBeUndefined()

    Received: "123456"

      26 |         expect(mockAxios.history.post[1].url).toContain(expectUrl)
      27 |         expect(mockAxios.history.post[1]?.headers?.accessToken).toEqual('123456')
    > 28 |         expect(mockAxios.history.post[0]?.headers?.accessToken).toBeUndefined()
         |                                                                 ^
      29 |     })
      30 |
      31 |     test('auto update token', async () => {

      at test/NetAdapter.test.ts:28:65
      at fulfilled (test/NetAdapter.test.ts:5:58)

  ● axios mock test › auto update token

    expect(received).toEqual(expected) // deep equality

    Expected: "666"
    Received: "123456"

      39 |         expect(mockAxios.history.post[1].url).toContain(expectUrl)
      40 |         expect(mockAxios.history.post[1]?.headers?.accessToken).toEqual('123456')
    > 41 |         expect(mockAxios.history.post[0]?.headers?.accessToken).toEqual('666')
         |                                                                 ^
      42 |     })
      43 |
      44 |     test('manual set token and send request instead of automation', async () => {

      at test/NetAdapter.test.ts:41:65
      at fulfilled (test/NetAdapter.test.ts:5:58)

Test Suites: 1 failed, 1 total
Tests:       2 failed, 1 passed, 3 total
Snapshots:   0 total
Time:        5.753 s
Ran all test suites.
error Command failed with exit code 1.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant