Nextjs Api Tester

Test and validate Next.js API routes with comprehensive test scenarios

Commandnextjs vercelMIT1 source files

Before you use this component

This is a third-party source bundle, not an installation into your account. UI Discovery has checked the available redistribution license evidence; runtime behavior has not been tested. Review all files, use a disposable project first, and do not enable scripts or hooks until you understand their permissions.

Some integrations require separately installed software, API keys or paid services. Credentials and subscriptions are not included. These are Claude Code resources; other clients may require adaptation.

Extract the ZIP into a temporary folder, inspect its entry file and supporting resources, then follow the original instructions. Do not overwrite an existing project configuration blindly. Keep the bundled license and attribution notices.

Source publisher
Claude Code Templates
Creator supplied by source
Not listed in source
Pinned source version
a344359459263d73d8948651c789244093c02e4e
License evidence
LICENSE

Source preview

cli-tool/components/commands/nextjs-vercel/nextjs-api-tester.md

---
allowed-tools: Read, Write, Edit, Bash
argument-hint: [route-path] [--method=GET] [--data='{}'] [--headers='{}']
description: Test and validate Next.js API routes with comprehensive test scenarios
---

## Next.js API Route Tester

**API Route**: $ARGUMENTS

## Current Project Analysis

### API Routes Detection
- App Router API: @app/api/
- Pages Router API: @pages/api/
- API configuration: @next.config.js
- Environment variables: @.env.local

### Project Context
- Next.js version: !`grep '"next"' package.json | head -1`
- TypeScript config: @tsconfig.json (if exists)
- Testing framework: @jest.config.js or @vitest.config.js (if exists)

## API Route Analysis

### Route Discovery
Based on the provided route path, analyze:
- **Route File**: Locate the actual route file
- **HTTP Methods**: Supported methods (GET, POST, PUT, DELETE, PATCH)
- **Route Parameters**: Dynamic segments and query parameters
- **Middleware**: Applied middleware functions
- **Authentication**: Required authentication/authorization

### Route Implementation Review
- Route handler implementation: @app/api/[route-path]/route.ts or @pages/api/[route-path].ts
- Type definitions: @types/ or inline types
- Validation schemas: @lib/validations/ or inline validation
- Database models: @lib/models/ or @models/

## Test Generation Strategy

### 1. Basic Functionality Tests
```javascript
// Basic API route test template
describe('API Route: /api/[route-path]', () => {
  describe('GET requests', () => {
    test('should return 200 for valid request', async () => {
      const response = await fetch('/api/[route-path]');
      expect(response.status).toBe(200);
    });

    test('should return valid JSON response', async () => {
      const response = await fetch('/api/[route-path]');
      const data = await response.json();
      expect(data).toBeDefined();
      expect(typeof data).toBe('object');
    });
  });

  describe('POST requests', () => {
    test('should create resource with valid data', async () => {
      const testData = { name: 'Test', email: 'test@example.com' };
      const response = await fetch('/api/[route-path]', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(testData)
      });
      
      expect(response.status).toBe(201);
      const result = await response.json();
      expect(result.name).toBe(testData.name);
    });

    test('should reject invalid data', async () => {
      const invalidData = { invalid: 'field' };
      const response = await fetch('/api/[route-path]', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(invalidData)
      });
      
      expect(response.status).toBe(400);
    });
  });
});
```

### 2. Authentication Tests
```javascript
describe('Authentication', () => {
  test('should require authentication for protected routes', async () => {
    const response = await fetch('/api/protected-route');
    expect(response.status).toBe(401);
  });

  test('should allow authenticated requests', async () => {
    const token = 'valid-jwt-token';
    const response = await fetch('/api/protected-route', {
      headers: { 'Authorization': `Bearer ${token}` }
    });
    expect(response.status).not.toBe(401);
  });

  test('should validate JWT token format', async () => {
    const invalidToken = 'invalid-token';
    const response = await fetch('/api/protected-route', {
      headers: { 'Authorization': `Bearer ${invalidToken}` }
    });
    expect(response.status).toBe(403);
  });
});
```

### 3. Input Validation Tests
```javascript
describe('Input Validation', () => {
  const validationTests = [
    { field: 'email', invalid: 'not-an-email', valid: 'test@example.com' },
    { field: 'phone', invalid: '123', valid: '+1234567890' },
    { field: 'age', invalid: -1, valid: 25 },
    { field: 'name', invalid: '', valid: 'John Doe' }
  ];

  validationTests.forEach(({ field, invalid, valid }) => {
    test(`should validate ${field} field`, async () => {
      const invalidData = { [field]: invalid };
      const validData = { [field]: valid };

      // Test invalid data
      const invalidResponse = await fetch('/api/[route-path]', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(invalidData)
      });
      expect(invalidResponse.status).toBe(400);

      // Test valid data
      const validResponse = await fetch('/api/[route-path]', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(validData)
      });
      expect(validResponse.status).not.toBe(400);
    });
  });
});
```

### 4. Error Handling Tests
```javascript
describe('Error Handling', () => {
  test('should handle malformed JSON', async () => {
    const response = await fetch('/api/[route-path]', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: 'invalid-json'
    });
    expect(response.status).toBe(400);
  });

  test('should handle missing Content-Type header', async () => {
    const response = await fetch('/api/[route-path]', {
      method: 'POST',
      body: JSON.stringify({ test: 'data' })
    });
    expect(response.status).toBe(400);
  });

  test('should handle request timeout', async () => {
    // Mock slow endpoint
    jest.setTimeout(5000);
    const response = await fetch('/api/slow-endpoint');
    // Test appropriate timeout handling
  }, 5000);

  test('should handle database connection errors', async () => {
    // Mock database failure
    const mockDbError = jest.spyOn(db, 'connect').mockRejectedValue(new Error('DB Error'));
    
    const response = await fetch('/api/[route-path]');
    expect(response.status).toBe(500);
    
    mockDbError.mockRestore();
  });
});
```

### 5. Performance Tests
```javascript
describe('Performance', () => {
  test('should respond within acceptable time', async () => {
    const startTime = Date.now();
    const response = await fetch('/api/[route-path]');
    const endTime = Date.now();
    
    expect(response.status).toBe(200);
    expect(endTime - startTime).toBeLessThan(1000); // 1 second
  });

  test('should handle concurrent requests', async () => {
    const promises = Array.from({ length: 10 }, () =>
      fetch('/api/[route-path]')
    );
    
    const responses = await Promise.all(promises);
    responses.forEach(response => {
      expect(response.status).toBe(200);
    });
  });

  test('should implement rate limiting', async () => {
    const requests = Array.from({ length: 100 }, () =>
      fetch('/api/[route-path]')
    );
    
    const responses = await Promise.all(requests);
    const rateLimitedResponses = responses.filter(r => r.status === 429);
    expect(rateLimitedResponses.length).toBeGreaterThan(0);
  });
});
```

## Manual Testing Commands

### cURL Commands Generation
```bash
# GET request
curl -X GET "http://localhost:3000/api/[route-path]" \
  -H "Accept: application/json"

# POST request with data
curl -X POST "http://localhost:3000/api/[route-path]" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{"key": "value"}'

# Authenticated request
curl -X GET "http://localhost:3000/api/protected-route" \
  -H "Authorization: Bearer YOUR_TOKEN_HERE" \
  -H "Accept: application/json"

# Upload file
curl -X POST "http://localhost:3000/api/upload" \
  -H "Authorization: Bearer YOUR_TOKEN_HERE" \
  -F "file=@path/to/file.jpg"
```

### HTTPie Commands
```bash
# GET request
http GET localhost:3000/api/[route-path]

# POST request with JSON
http POST localhost:3000/api/[route-path] key=value

# Authenticated request
http GET localhost:3000/api/protected-route Authorization:"Bearer TOKEN"

# Custom headers
http GET localhost:3000/api/[route-path] X-Custom-Header:value
```

## Interactive Testing Tools

### Postman Collection Generation
```json
{
  "info": {
    "name": "Next.js API Tests",
    "description": "Generated API tests for [route-path]"
  },
  "item": [
    {
      "name": "GET [route-path]",
      "request": {
        "method": "GET",
        "header": [],
        "url": {
          "raw": "{{baseUrl}}/api/[route-path]",
          "host": ["{{baseUrl}}"],
          "path": ["api", "[route-path]"]
        }
      }
    },
    {
      "name": "POST [route-path]",
      "request": {
        "method": "POST",
        "header": [
          {
            "key": "Content-Type",
            "value": "application/json"
          }
        ],
        "body": {
          "mode": "raw",
          "raw": "{\n  \"key\": \"value\"\n}"
        },
        "url": {
          "raw": "{{baseUrl}}/api/[route-path]",
          "host": ["{{baseUrl}}"],
          "path": ["api", "[route-path]"]
        }
      }
    }
  ]
}
```

### Thunder Client Collection
```json
{
  "client": "Thunder Client",
  "collectionName": "Next.js API Tests",
  "dateExported": "2024-01-01",
  "version": "1.1",
  "folders": [],
  "requests": [
    {
      "name": "Test API Route",
      "url": "localhost:3000/api/[route-path]",
      "method": "GET",
      "headers": [
        {
          "name": "Accept",
          "value": "application/json"
        }
      ]
    }
  ]
}
```

## Test Data Management

### Test Fixtures
```typescript
// test/fixtures/apiTestData.ts
export const validUserData = {
  name: 'John Doe',
  email: 'john@example.com',
  age: 30,
  role: 'user'
};

export const invalidUserData = {
  name: '',
  email: 'invalid-email',
  age: -1,
  role: 'invalid-role'
};

export const testHeaders = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'User-Agent': 'API-Test-Suite/1.0'
};
```

### Mock Data Generation
```typescript
// test/utils/mockData.ts
export function generateMockUser() {
  return {
    id: Math.random().toString(36).substr(2, 9),
    name: `User ${Math.floor(Math.random() * 1000)}`,
    email: `user${Date.now()}@example.com`,
    createdAt: new Date().toISOString()
  };
}

export function generateBulkTestData(count: number) {
  return Array.from({ length: count }, generateMockUser);
}
```

## Test Environment Setup

### Jest Configuration
```javascript
// jest.config.js for API testing
module.exports = {
  testEnvironment: 'node',
  setupFilesAfterEnv: ['<rootDir>/test/setup.js'],
  testMatch: ['**/__tests__/**/*.test.js', '**/?(*.)+(spec|test).js'],
  collectCoverageFrom: [
    'pages/api/**/*.{js,ts}',
    'app/api/**/*.{js,ts}',
    '!**/*.d.ts',
  ],
  coverageThreshold: {
    global: {
      branches: 70,
      functions: 70,
      lines: 70,
      statements: 70
    }
  }
};
```

### Test Setup
```javascript
// test/setup.js
import { createMocks } from 'node-mocks-http';
import { testDb } from './testDatabase';

// Global test setup
beforeAll(async () => {
  // Setup test database
  await testDb.connect();
});

afterAll(async () => {
  // Cleanup test database
  await testDb.disconnect();
});

beforeEach(async () => {
  // Reset database state
  await testDb.reset();
});

// Helper function for API testing
global.createAPITest = (handler) => {
  return (method, url, options = {}) => {
    const { req, res } = createMocks({
      method,
      url,
      ...options
    });
    return handler(req, res);
  };
};
```

## Automated Testing Integration

### GitHub Actions Workflow
```yaml
name: API Tests
on: [push, pull_request]

jobs:
  test-api:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: '18'
      - run: npm ci
      - run: npm run test:api
      - name: Upload coverage
        uses: codecov/codecov-action@v3
```

### Continuous Testing
```bash
# Watch mode for development
npm run test:api -- --watch

# Coverage reporting
npm run test:api -- --coverage

# Specific route testing
npm run test:api -- --testNamePattern="api/users"
```

## Test Results Analysis

Generate comprehensive test report including:
1. **Test Coverage**: Line, branch, function coverage percentages
2. **Performance Metrics**: Response times, throughput
3. **Security Analysis**: Authentication, authorization, input validation
4. **Error Handling**: Exception scenarios and error responses
5. **Compatibility**: Cross-environment testing results

Provide actionable recommendations for improving API reliability, performance, and security.

Preview capped at 60,000 characters. Download the bundle for every original file and notice.

Read the redistribution license
MIT License

Copyright (c) 2025 Daniel (San) Ávila

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

Bundle SHA-256: 16a77ff3b02c73c0b0f229389294b2d9c4490c452dad4ccf77854f73f6d969aa. Files are served as downloads and are never executed by this page.