@mswjs/interceptors
Version:
Low-level HTTP/HTTPS/XHR/fetch request interception library.
265 lines (217 loc) • 6.83 kB
text/typescript
/**
* @vitest-environment node
*/
import { Socket } from 'node:net'
import { vi, it, expect } from 'vitest'
import { MockSocket } from './MockSocket'
it(`keeps the socket connecting until it's destroyed`, () => {
const socket = new MockSocket({
write: vi.fn(),
read: vi.fn(),
})
expect(socket.connecting).toBe(true)
socket.destroy()
expect(socket.connecting).toBe(false)
})
it('calls the "write" on "socket.write()"', () => {
const writeCallback = vi.fn()
const socket = new MockSocket({
write: writeCallback,
read: vi.fn(),
})
socket.write()
expect(writeCallback).toHaveBeenCalledWith(undefined, undefined, undefined)
})
it('calls the "write" on "socket.write(chunk)"', () => {
const writeCallback = vi.fn()
const socket = new MockSocket({
write: writeCallback,
read: vi.fn(),
})
socket.write('hello')
expect(writeCallback).toHaveBeenCalledWith('hello', undefined, undefined)
})
it('calls the "write" on "socket.write(chunk, encoding)"', () => {
const writeCallback = vi.fn()
const socket = new MockSocket({
write: writeCallback,
read: vi.fn(),
})
socket.write('hello', 'utf8')
expect(writeCallback).toHaveBeenCalledWith('hello', 'utf8', undefined)
})
it('calls the "write" on "socket.write(chunk, encoding, callback)"', () => {
const writeCallback = vi.fn()
const socket = new MockSocket({
write: writeCallback,
read: vi.fn(),
})
const callback = vi.fn()
socket.write('hello', 'utf8', callback)
expect(writeCallback).toHaveBeenCalledWith('hello', 'utf8', callback)
})
it('calls the "write" on "socket.end()"', () => {
const writeCallback = vi.fn()
const socket = new MockSocket({
write: writeCallback,
read: vi.fn(),
})
socket.end()
expect(writeCallback).toHaveBeenCalledWith(undefined, undefined, undefined)
})
it('calls the "write" on "socket.end(chunk)"', () => {
const writeCallback = vi.fn()
const socket = new MockSocket({
write: writeCallback,
read: vi.fn(),
})
socket.end('final')
expect(writeCallback).toHaveBeenCalledWith('final', undefined, undefined)
})
it('calls the "write" on "socket.end(chunk, encoding)"', () => {
const writeCallback = vi.fn()
const socket = new MockSocket({
write: writeCallback,
read: vi.fn(),
})
socket.end('final', 'utf8')
expect(writeCallback).toHaveBeenCalledWith('final', 'utf8', undefined)
})
it('calls the "write" on "socket.end(chunk, encoding, callback)"', () => {
const writeCallback = vi.fn()
const socket = new MockSocket({
write: writeCallback,
read: vi.fn(),
})
const callback = vi.fn()
socket.end('final', 'utf8', callback)
expect(writeCallback).toHaveBeenCalledWith('final', 'utf8', callback)
})
it('calls the "write" on "socket.end()" without any arguments', () => {
const writeCallback = vi.fn()
const socket = new MockSocket({
write: writeCallback,
read: vi.fn(),
})
socket.end()
expect(writeCallback).toHaveBeenCalledWith(undefined, undefined, undefined)
})
it('emits "finished" on .end() without any arguments', async () => {
const finishListener = vi.fn()
const socket = new MockSocket({
write: vi.fn(),
read: vi.fn(),
})
socket.on('finish', finishListener)
socket.end()
await vi.waitFor(() => {
expect(finishListener).toHaveBeenCalledTimes(1)
})
})
it('calls the "read" on "socket.read(chunk)"', () => {
const readCallback = vi.fn()
const socket = new MockSocket({
write: vi.fn(),
read: readCallback,
})
socket.push('hello')
expect(readCallback).toHaveBeenCalledWith('hello', undefined)
})
it('calls the "read" on "socket.read(chunk, encoding)"', () => {
const readCallback = vi.fn()
const socket = new MockSocket({
write: vi.fn(),
read: readCallback,
})
socket.push('world', 'utf8')
expect(readCallback).toHaveBeenCalledWith('world', 'utf8')
})
it('calls the "read" on "socket.read(null)"', () => {
const readCallback = vi.fn()
const socket = new MockSocket({
write: vi.fn(),
read: readCallback,
})
socket.push(null)
expect(readCallback).toHaveBeenCalledWith(null, undefined)
})
it('updates the writable state on "socket.end()"', async () => {
const finishListener = vi.fn()
const endListener = vi.fn()
const socket = new MockSocket({
write: vi.fn(),
read: vi.fn(),
})
socket.on('finish', finishListener)
socket.on('end', endListener)
expect(socket.writable).toBe(true)
expect(socket.writableEnded).toBe(false)
expect(socket.writableFinished).toBe(false)
socket.write('hello')
// Finish the writable stream.
socket.end()
expect(socket.writable).toBe(false)
expect(socket.writableEnded).toBe(true)
// The "finish" event is emitted when writable is done.
// I.e. "socket.end()" is called.
await vi.waitFor(() => {
expect(finishListener).toHaveBeenCalledTimes(1)
})
expect(socket.writableFinished).toBe(true)
})
it('updates the readable state on "socket.push(null)"', async () => {
const endListener = vi.fn()
const socket = new MockSocket({
write: vi.fn(),
read: vi.fn(),
})
socket.on('end', endListener)
expect(socket.readable).toBe(true)
expect(socket.readableEnded).toBe(false)
socket.push('hello')
socket.push(null)
expect(socket.readable).toBe(true)
expect(socket.readableEnded).toBe(false)
// Read the data to free the buffer and
// make Socket emit "end".
socket.read()
await vi.waitFor(() => {
expect(endListener).toHaveBeenCalledTimes(1)
})
expect(socket.readable).toBe(false)
expect(socket.readableEnded).toBe(true)
})
it('updates the readable/writable state on "socket.destroy()"', async () => {
const finishListener = vi.fn()
const endListener = vi.fn()
const closeListener = vi.fn()
const socket = new MockSocket({
write: vi.fn(),
read: vi.fn(),
})
socket.on('finish', finishListener)
socket.on('end', endListener)
socket.on('close', closeListener)
expect(socket.writable).toBe(true)
expect(socket.writableEnded).toBe(false)
expect(socket.writableFinished).toBe(false)
expect(socket.readable).toBe(true)
socket.destroy()
expect(socket.writable).toBe(false)
// The ".end()" wasn't called.
expect(socket.writableEnded).toBe(false)
expect(socket.writableFinished).toBe(false)
expect(socket.readable).toBe(false)
await vi.waitFor(() => {
expect(closeListener).toHaveBeenCalledTimes(1)
})
// Neither "finish" nor "end" events are emitted
// when you destroy the stream. If you want those,
// call ".end()", then destroy the stream.
expect(finishListener).not.toHaveBeenCalled()
expect(endListener).not.toHaveBeenCalled()
expect(socket.writableFinished).toBe(false)
// The "end" event was never emitted so "readableEnded"
// remains false.
expect(socket.readableEnded).toBe(false)
})