Repository: honojs/hono
File: src/middleware/ip-restriction/index.test.ts (TypeScript)

Code before:
      { denyList: ['0.0.0.0'] },
      () => new Response('error')
    )(new Context(new HonoRequest(new Request('http://localhost/'))), async () => void 0)
    expect(res).toBeTruthy()
    if (res) {
      expect(await res.text()).toBe('error')
    }
  })
})

describe('isMatchForRule', () => {
  it('CIDR Notation', () => {
    expect(isMatchForRule({ addr: '192.168.2.0', type: 'IPv4' }, '192.168.2.0/24')).toBeTruthy()
    expect(isMatchForRule({ addr: '192.168.2.1', type: 'IPv4' }, '192.168.2.0/24')).toBeTruthy()

    expect(isMatchForRule({ addr: '::0', type: 'IPv6' }, '::0/1')).toBeTruthy()
  })
  it('Static Rules', () => {
    expect(isMatchForRule({ addr: '192.168.2.1', type: 'IPv4' }, '192.168.2.1')).toBeTruthy()
    expect(isMatchForRule({ addr: '1234::5678', type: 'IPv6' }, '1234::5678')).toBeTruthy()
  })
  it('Function Rules', () => {
    expect(isMatchForRule({ addr: '0.0.0.0', type: 'IPv4' }, () => true)).toBeTruthy()
    expect(isMatchForRule({ addr: '0.0.0.0', type: 'IPv4' }, () => false)).toBeFalsy()

    const randIP = Math.random().toString()
    isMatchForRule({ addr: randIP, type: 'IPv4' }, (ip) => {
      expect(randIP).toBe(ip.addr)
      return false
    })
  })
})


Review comment (bug):
`Math.random` should not be used in tests.
This includes a possibility that the test will fail randomly.
I don't see any reason to use it, at least not here.

Code after:
      { denyList: ['0.0.0.0'] },
      () => new Response('error')
    )(new Context(new Request('http://localhost/')), async () => void 0)
    expect(res).toBeTruthy()
    if (res) {
      expect(await res.text()).toBe('error')
    }
  })
})

describe('isMatchForRule', () => {
  const isMatch = async (info: { addr: string; type: AddressType }, rule: IPRestrictionRule) => {
    const middleware = ipRestriction(
      () => ({
        remote: {
          address: info.addr,
          addressType: info.type,
        },
      }),
      {
        allowList: [rule],
      }
    )
    try {
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      await middleware(undefined as any, () => Promise.resolve())
    } catch (e) {
      return false
    }
    return true
  }

  it('star', async () => {
    expect(await isMatch({ addr: '192.168.2.0', type: 'IPv4' }, '*')).toBeTruthy()
    expect(await isMatch({ addr: '192.168.2.1', type: 'IPv4' }, '*')).toBeTruthy()
    expect(await isMatch({ addr: '::0', type: 'IPv6' }, '*')).toBeTruthy()
  })
  it('CIDR Notation', async () => {
    expect(await isMatch({ addr: '192.168.2.0', type: 'IPv4' }, '192.168.2.0/24')).toBeTruthy()
    expect(await isMatch({ addr: '192.168.2.1', type: 'IPv4' }, '192.168.2.0/24')).toBeTruthy()
    expect(await isMatch({ addr: '192.168.2.1', type: 'IPv4' }, '192.168.2.1/32')).toBeTruthy()
    expect(await isMatch({ addr: '192.168.2.1', type: 'IPv4' }, '192.168.2.2/32')).toBeFalsy()

    expect(await isMatch({ addr: '::0', type: 'IPv6' }, '::0/1')).toBeTruthy()
  })
  it('Static Rules', async () => {
    expect(await isMatch({ addr: '192.168.2.1', type: 'IPv4' }, '192.168.2.1')).toBeTruthy()
    expect(await isMatch({ addr: '1234::5678', type: 'IPv6' }, '1234::5678')).toBeTruthy()
  })
  it('Function Rules', async () => {
    expect(await isMatch({ addr: '0.0.0.0', type: 'IPv4' }, () => true)).toBeTruthy()