Back to Repositories

Testing Multipart Form Data Construction in Kong/insomnia

This test suite validates the buildMultipart function in Kong/insomnia, which handles multipart form data construction for HTTP requests. The tests verify correct boundary handling, content-type processing, and file uploads in multipart form submissions.

Test Coverage Overview

The test suite provides comprehensive coverage of multipart form data building functionality.

Key areas tested include:
  • Simple form data with text fields
  • Multiline content with custom content-types
  • File upload handling
  • Edge cases with empty or missing field values
Integration points cover file system operations and content-type handling.

Implementation Analysis

The testing approach uses Jest’s describe/it pattern for structured test organization. Tests validate the buildMultipart function’s output against expected multipart form structures, including boundary formatting, content disposition headers, and proper line endings.

Technical patterns include:
  • Async/await for file operations
  • Boundary string validation
  • Content length verification
  • File content comparison

Technical Details

Testing tools and configuration:
  • Vitest as the test runner
  • Node.js fs module for file operations
  • Path module for file path handling
  • DEFAULT_BOUNDARY constant for multipart separation
  • UTF-8 encoding for content verification

Best Practices Demonstrated

The test suite exemplifies several testing best practices for multipart form handling.

Notable practices include:
  • Isolated test cases for specific functionality
  • Comprehensive edge case coverage
  • Consistent assertion patterns
  • Clear test case descriptions
  • Proper cleanup of test files

kong/insomnia

packages/insomnia/src/network/__tests__/multipart.test.ts

            
import fs from 'fs';
import path from 'path';
import { describe, expect, it } from 'vitest';

import { buildMultipart, DEFAULT_BOUNDARY } from '../../main/network/multipart';

describe('buildMultipart()', () => {

  it('builds a simple request', async () => {
    const { filePath, boundary, contentLength } = await buildMultipart([
      {
        name: 'foo',
        value: 'bar',
      },
      {
        name: 'multi-line',
        value: 'Hello\nWorld!',
      },
    ]);
    expect(boundary).toBe(DEFAULT_BOUNDARY);
    expect(contentLength).toBe(189);
    expect(fs.readFileSync(filePath, 'utf8')).toBe(
      [
        `--${boundary}`,
        'Content-Disposition: form-data; name="foo"',
        '',
        'bar',
        `--${boundary}`,
        'Content-Disposition: form-data; name="multi-line"',
        '',
        'Hello\nWorld!',
        `--${boundary}--`,
        '',
      ].join('\r\n'),
    );
  });

  it('builds a multiline request with content-type', async () => {
    const { filePath, boundary, contentLength } = await buildMultipart([
      {
        name: 'foo',
        value: 'bar',
      },
      {
        name: 'json',
        value: '{"hello": "world"}',
        multiline: 'application/json',
      },
      {
        name: 'text',
        value: 'text',
        multiline: true,
      },
    ]);
    expect(boundary).toBe(DEFAULT_BOUNDARY);
    expect(contentLength).toBe(297);
    expect(fs.readFileSync(filePath, 'utf8')).toBe(
      [
        `--${boundary}`,
        'Content-Disposition: form-data; name="foo"',
        '',
        'bar',
        `--${boundary}`,
        'Content-Disposition: form-data; name="json"',
        'Content-Type: application/json',
        '',
        '{"hello": "world"}',
        `--${boundary}`,
        'Content-Disposition: form-data; name="text"',
        '',
        'text',
        `--${boundary}--`,
        '',
      ].join('\r\n'),
    );
  });

  it('builds with file', async () => {
    const fileName = path.resolve(path.join(__dirname, './testfile.txt'));
    const { filePath, boundary, contentLength } = await buildMultipart([
      {
        name: 'foo',
        value: 'bar',
      },
      {
        name: 'file',
        type: 'file',
        fileName: fileName,
      },
      {
        name: 'baz',
        value: 'qux',
      },
    ]);
    expect(boundary).toBe(DEFAULT_BOUNDARY);
    expect(contentLength).toBe(322);
    expect(fs.readFileSync(filePath, 'utf8')).toBe(
      [
        `--${boundary}`,
        'Content-Disposition: form-data; name="foo"',
        '',
        'bar',
        `--${boundary}`,
        'Content-Disposition: form-data; name="file"; filename="testfile.txt"',
        'Content-Type: text/plain',
        '',
        'Hello World!\n\nHow are you?',
        `--${boundary}`,
        'Content-Disposition: form-data; name="baz"',
        '',
        'qux',
        `--${boundary}--`,
        '',
      ].join('\r\n'),
    );
  });

  it('skips entries with no name or value', async () => {
    const { filePath, boundary, contentLength } = await buildMultipart([
      {
        value: 'bar',
      },
      {
        name: 'foo',
      },
      {
        name: '',
        value: '',
      },
      {
        name: '',
        type: 'file',
        fileName: '',
      },
    ]);
    expect(boundary).toBe(DEFAULT_BOUNDARY);
    expect(contentLength).toBe(167);
    expect(fs.readFileSync(filePath, 'utf8')).toBe(
      [
        `--${boundary}`,
        'Content-Disposition: form-data; name=""',
        '',
        'bar',
        `--${boundary}`,
        'Content-Disposition: form-data; name="foo"',
        '',
        '',
        `--${boundary}--`,
        '',
      ].join('\r\n'),
    );
  });
});