Back to Repositories

Testing cURL Command Parsing Implementation in Insomnia

This test suite validates the cURL command parsing functionality in Insomnia, focusing on data flag handling and header processing. It ensures accurate conversion of various cURL command formats into Insomnia’s internal request structure.

Test Coverage Overview

The test suite provides comprehensive coverage of cURL command parsing, specifically focusing on data flags (-d, –data, –data-ascii, –data-binary, –data-raw, –data-urlencode) and header flags (-H). It tests key functionality including parameter parsing, URI encoding, file uploads, and multiple parameter handling.

  • Data flag variations and their parsing
  • Header processing with different formats
  • URL-encoded content handling
  • File upload syntax validation

Implementation Analysis

The testing approach uses Jest’s parameterized testing with it.each() to systematically verify different input combinations. The implementation follows a data-driven testing pattern, where each test case defines input flags, values, and expected output structures.

  • Parameterized test structure for extensive coverage
  • Input/output mapping verification
  • Edge case handling for special characters

Technical Details

The test suite utilizes:

  • Vitest for test execution
  • shell-quote for command parsing
  • TypeScript for type safety
  • Parameter interface for data structure definition
  • convert() function for cURL command processing

Best Practices Demonstrated

The test suite exemplifies several testing best practices including systematic test organization, comprehensive edge case coverage, and clear test case documentation. Each test case is well-structured with explicit input/output expectations.

  • Organized test grouping using describe blocks
  • Consistent test case formatting
  • Comprehensive parameter validation
  • Clear test case documentation

kong/insomnia

packages/insomnia/src/utils/importers/importers/curl.test.ts

            
import { quote } from 'shell-quote';
import { describe, expect, it } from 'vitest';

import { Parameter } from '../entities';
import { convert } from './curl';

describe('curl', () => {
  describe('cURL --data flags', () => {
    it.each([
      // -d
      { flag: '-d', inputs: ['key=value'], expected: [{ name: 'key', value: 'value' }] },
      { flag: '-d', inputs: ['value'], expected: [{ name: '', value: 'value' }] },
      { flag: '-d', inputs: ['@filename'], expected: [{ name: '', fileName: 'filename', type: 'file' }] },
      {
        flag: '-d',
        inputs: ['first=1', 'second=2', 'third'],
        expected: [{ name: 'first', value: '1' }, {
          name: 'second',
          value: '2',
        }, { name: '', value: 'third' }],
      },
      {
        flag: '-d',
        inputs: ['first=1&second=2'],
        expected: [{ name: 'first', value: '1' }, { name: 'second', value: '2' }],
      },
      { flag: '-d', inputs: ['%3D'], expected: [{ name: '', value: '=' }] },
      { flag: '--d', inputs: ['%3D=%3D'], expected: [{ name: '=', value: '=' }] },

      // --data
      { flag: '--data', inputs: ['key=value'], expected: [{ name: 'key', value: 'value' }] },
      { flag: '--data', inputs: ['value'], expected: [{ name: '', value: 'value' }] },
      { flag: '--data', inputs: ['@filename'], expected: [{ name: '', fileName: 'filename' }] },
      {
        flag: '--data',
        inputs: ['first=1', 'second=2', 'third'],
        expected: [{ name: 'first', value: '1' }, {
          name: 'second',
          value: '2',
        }, { name: '', value: 'third' }],
      },
      {
        flag: '--data',
        inputs: ['first=1&second=2'],
        expected: [{ name: 'first', value: '1' }, { name: 'second', value: '2' }],
      },
      { flag: '--data', inputs: ['%3D'], expected: [{ name: '', value: '=' }] },
      { flag: '--data', inputs: ['%3D=%3D'], expected: [{ name: '=', value: '=' }] },

      // --data-ascii
      { flag: '--data-ascii', inputs: ['key=value'], expected: [{ name: 'key', value: 'value' }] },
      { flag: '--data-ascii', inputs: ['value'], expected: [{ name: '', value: 'value' }] },
      { flag: '--data-ascii', inputs: ['@filename'], expected: [{ name: '', fileName: 'filename', type: 'file' }] },
      {
        flag: '--data-ascii',
        inputs: ['first=1', 'second=2', 'third'],
        expected: [{ name: 'first', value: '1' }, {
          name: 'second',
          value: '2',
        }, { name: '', value: 'third' }],
      },
      {
        flag: '--data-ascii',
        inputs: ['first=1&second=2'],
        expected: [{ name: 'first', value: '1' }, { name: 'second', value: '2' }],
      },

      // --data-binary
      { flag: '--data-binary', inputs: ['key=value'], expected: [{ name: 'key', value: 'value' }] },
      { flag: '--data-binary', inputs: ['value'], expected: [{ name: '', value: 'value' }] },
      { flag: '--data-binary', inputs: ['@filename'], expected: [{ name: '', fileName: 'filename', type: 'file' }] },
      {
        flag: '--data-binary',
        inputs: ['first=1', 'second=2', 'third'],
        expected: [{ name: 'first', value: '1' }, {
          name: 'second',
          value: '2',
        }, { name: '', value: 'third' }],
      },
      {
        flag: '--data-binary',
        inputs: ['first=1&second=2'],
        expected: [{ name: 'first', value: '1' }, { name: 'second', value: '2' }],
      },

      // --data-raw
      { flag: '--data-raw', inputs: ['@filename'], expected: [{ name: '', value: '@filename' }] },
      { flag: '--data-raw', inputs: ['key=value'], expected: [{ name: 'key', value: 'value' }] },
      {
        flag: '--data-raw',
        inputs: ['first=1', 'second=2', 'third'],
        expected: [{ name: 'first', value: '1' }, {
          name: 'second',
          value: '2',
        }, { name: '', value: 'third' }],
      },
      {
        flag: '--data-raw',
        inputs: ['first=1&second=2'],
        expected: [{ name: 'first', value: '1' }, { name: 'second', value: '2' }],
      },

      // --data-urlencode
      { flag: '--data-urlencode', inputs: ['key=value'], expected: [{ name: 'key', value: 'value' }] },
      {
        flag: '--data-urlencode',
        inputs: ['key@filename'],
        expected: [{ name: 'key', fileName: 'filename', type: 'file' }],
      },
      {
        flag: '--data-urlencode',
        inputs: ['first=1', 'second=2', 'third'],
        expected: [{ name: 'first', value: '1' }, {
          name: 'second',
          value: '2',
        }, { name: '', value: 'third' }],
      },
      {
        flag: '--data-urlencode',
        inputs: ['first=1&second=2'],
        expected: [{ name: 'first', value: '1' }, { name: 'second', value: '2' }],
      },
      { flag: '--data-urlencode', inputs: ['=value'], expected: [{ name: '', value: 'value' }] },

      // --data-urlencode URI encoding
      { flag: '--data-urlencode', inputs: ['a='], expected: [{ name: 'a', value: '' }] },
      { flag: '--data-urlencode', inputs: [' '], expected: [{ name: '', value: ' ' }] },
      { flag: '--data-urlencode', inputs: ['<'], expected: [{ name: '', value: '<' }] },
      { flag: '--data-urlencode', inputs: ['>'], expected: [{ name: '', value: '>' }] },
      { flag: '--data-urlencode', inputs: ['?'], expected: [{ name: '', value: '?' }] },
      { flag: '--data-urlencode', inputs: ['['], expected: [{ name: '', value: '[' }] },
      { flag: '--data-urlencode', inputs: [']'], expected: [{ name: '', value: ']' }] },
      { flag: '--data-urlencode', inputs: ['|'], expected: [{ name: '', value: '|' }] },
      { flag: '--data-urlencode', inputs: ['^'], expected: [{ name: '', value: '^' }] },
      { flag: '--data-urlencode', inputs: ['"'], expected: [{ name: '', value: '"' }] },
      { flag: '--data-urlencode', inputs: ['='], expected: [{ name: '', value: '' }] },
      { flag: '--data-urlencode', inputs: ['%3D'], expected: [{ name: '', value: '%3D' }] },
    ])('handles %p correctly', async ({
      flag,
      inputs,
      expected,
    }: { flag: string; inputs: string[]; expected: Parameter[] }) => {
      const flaggedInputs = inputs.map(input => `${flag} ${quote([input])}`).join(' ');
      const rawData = `curl -X POST https://example.com 
      -H 'Content-Type: application/x-www-form-urlencoded'
      ${flaggedInputs}
      `;

      expect(convert(rawData)).toMatchObject([{
        body: {
          params: expected,
        },
      }]);
    });
  });
  describe('cURL -H flags', () => {
    it.each([
      { flag: '-H', inputs: ['X-Host: example.com'], expected: [{ name: 'X-Host', value: 'example.com' }] },
      { flag: '-H', inputs: ['X-Host:example.com'], expected: [{ name: 'X-Host', value: 'example.com' }] },
      { flag: '-H', inputs: ['Content-Type:application/x-www-form-urlencoded'], expected: [{ name: 'Content-Type', value: 'application/x-www-form-urlencoded' }] },
      { flag: '   -H', inputs: ['Content-Type:application/x-www-form-urlencoded'], expected: [{ name: 'Content-Type', value: 'application/x-www-form-urlencoded' }] },
      { flag: ' -H', inputs: ['Content-Type:application/x-www-form-urlencoded'], expected: [{ name: 'Content-Type', value: 'application/x-www-form-urlencoded' }] },
    ])('handles %p correctly', async ({
      flag,
      inputs,
      expected,
    }: { flag: string; inputs: string[]; expected: Parameter[] }) => {
      const flaggedInputs = inputs.map(input => `${flag} ${quote([input])}`).join(' ');
      const rawData = `curl https://example.com ${flaggedInputs}`;
      expect(convert(rawData)).toMatchObject([{
        headers: expected,
      }]);
    });
  });
});