Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Behat Api Platform Bundle Laravel Package

boulzy/behat-api-platform-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation Add the bundle via Composer in your Symfony/Laravel (via Symfony bridge) project:

    composer require boulzy/behat-api-platform-bundle
    

    Register the bundle in config/bundles.php (Symfony) or config/app.php (Laravel via Symfony bridge):

    return [
        // ...
        Boulzy\BehatApiPlatformBundle\BoulzyBehatApiPlatformBundle::class => ['all' => true],
    ];
    
  2. Configure Behat Update behat.yml to include the bundle’s extensions:

    default:
      extensions:
        - Boulzy\BehatApiPlatformBundle\Behat\ApiPlatformExtension
        - Behat\MinkExtension:
            base_url: 'http://api.test'  # Your API Platform endpoint
    
  3. First Test Case Create a feature file (e.g., features/api/authentication.feature) and use the bundle’s custom steps:

    Feature: API Authentication
      Scenario: Successful login
        Given I am authenticated as a user with email "test@example.com" and password "password"
        When I request "POST" to "/api/login_check"
        Then the response status code should be 200
    
  4. Key Directories

    • src/Behat/ApiPlatformContext.php: Default context class (extend for custom logic).
    • config/packages/boulzy_behat_api_platform.yaml: Bundle configuration (if needed).

Implementation Patterns

Workflows

  1. Authentication Handling

    • Use Given I am authenticated as a user with ... to auto-generate JWT/Bearer tokens.
    • Example:
      Given I am authenticated as a user with:
        | email       | password  |
        | test@example.com | password |
      
    • Tokens are stored in Mink’s session for subsequent requests.
  2. API Requests

    • Leverage Mink’s When I request steps with API Platform’s routes:
      When I request "GET" to "/api/users/1"
      
    • Use custom steps for complex payloads:
      When I send a POST request to "/api/users" with:
        | name  | email               |
        | John  | john@example.com    |
      
  3. Response Validation

    • Validate status codes, headers, and JSON payloads:
      Then the response status code should be 201
      And the response should contain JSON:
        """
        {
          "id": 1,
          "name": "John"
        }
        """
      
    • Use Then the response should match schema for JSON Schema validation.
  4. Data Fixtures

    • Load fixtures before scenarios using Given steps:
      Given there is a user with:
        | email       | password  | roles       |
        | admin@example.com | secret | ROLE_ADMIN |
      
  5. Integration with API Platform

    • Test serialization/deserialization by sending malformed data:
      When I send a POST request to "/api/users" with invalid JSON
      Then the response status code should be 400
      

Integration Tips

  • Symfony UX Turbo/Stimulus: Mock Turbo-driven API calls by intercepting fetch requests in Behat.
  • API Platform Filters: Test filter operations (e.g., ?where[name]=John):
    When I request "GET" to "/api/users?where[name]=John"
    
  • Custom Contexts: Extend ApiPlatformContext to add domain-specific steps:
    // src/Behat/CustomContext.php
    use Boulzy\BehatApiPlatformBundle\Behat\ApiPlatformContext;
    
    class CustomContext extends ApiPlatformContext {
        public function assertUserHasRole($userId, $role) {
            // Custom logic
        }
    }
    
    Register in behat.yml:
    extensions:
      - Behat\MinkExtension:
          goutte_driver:
            custom_context: App\Behat\CustomContext
    

Gotchas and Tips

Pitfalls

  1. Token Expiry

    • JWT tokens may expire during long-running scenarios. Use Given I refresh my authentication token or configure shorter expiry in config/packages/security.yaml for tests:
      lexik_jwt_authentication:
          token_ttl: 3600  # 1 hour (reduce for tests)
      
  2. Mink Session Management

    • Mink’s session is shared across scenarios. Clear it between unrelated tests:
      Given I clear the Mink session
      
    • Or use @BeforeScenario hooks in a context to reset state.
  3. API Platform Version Mismatch

    • The bundle assumes API Platform’s default configurations (e.g., api_platform.core.serializer).
    • Override serializers/deserializers in config/packages/api_platform.yaml if needed:
      api_platform:
          formats:
              jsonld:
                  mime_types: ['application/ld+json']
      
  4. CORS Issues

    • Behat runs in a separate process. Ensure your API allows requests from localhost or configure CORS in config/packages/nelmio_cors.yaml:
      nelmio_cors:
          defaults:
              allow_origin: ['*']
      
  5. Database Transactions

    • Use Doctrine’s transactions to avoid test pollution:
      Given the database is in a transaction
      
    • Requires doctrine/doctrine-bundle and behat/mink-doctrine-extension.

Debugging Tips

  • Enable Mink Debugging Add to behat.yml:

    extensions:
        Behat\MinkExtension:
            base_url: 'http://api.test'
            goutte_driver:
                options:
                    debug: true
    

    Check logs in var/log/test.log for failed requests.

  • Inspect Raw Responses Use custom steps to dump responses:

    // In a context
    public function dumpResponse() {
        $response = $this->getSession()->getResponse();
        file_put_contents('response.json', $response->getContent());
    }
    

    Then call in Gherkin:

    When I dump the response
    
  • Network Tab Emulation Use mink-debug-extension to simulate browser dev tools:

    composer require --dev behat/mink-debug-extension
    

Extension Points

  1. Custom Steps Extend ApiPlatformContext to add domain logic:

    public function assertUserExists($email) {
        $client = static::createClient();
        $response = $client->request('GET', '/api/users?email='.$email);
        Assert::jsonContains($response->getContent(), ['email' => $email]);
    }
    
  2. Hooks for Setup/Teardown Use @BeforeScenario/@AfterScenario in contexts to manage state:

    use Behat\Behat\Hook\Scope\ScenarioScope;
    
    /**
     * @BeforeScenario
     */
    public function gatherContexts(ScenarioScope $scope) {
        $this->user = User::factory()->create();
    }
    
  3. Mock External Services Use HttpClient in contexts to mock API calls:

    public function mockPaymentService() {
        $this->client->addMockResponse(
            new Response(200, [], json_encode(['success' => true]))
        );
    }
    
  4. Parallel Testing Configure Behat’s parallel runner to avoid session conflicts:

    ./vendor/bin/behat --tags=~@wip --parallel=4
    

    Ensure your API can handle concurrent requests (e.g., with Puma/Unicorn).

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
cocosmos/filament-sticky-save-bar
patrickbussmann/oauth2-apple
3brs/enterprise-security-bundle
anousss007/vigilance
supportpal/eloquent-model
ardenexal/fhir-models
laravel-at/laravel-image-sanitize
romalytar/yammi-audit-log-laravel
ardenexal/fhir-validation
arshaviras/weather-widget
laravel-chronicle/core
sunchayn/nimbus
daikazu/eloquent-salesforce-objects
unseen-codes/chat
romalytar/yammi-jobs-monitoring-laravel
kisame76/filament-db-table-state
nqxcode/laravel-lucene-search
dpfx/laravel-livewire-wizards
workos/workos-php-laravel
sofa/laravel-global-scope