will be discussed here
# pactflow
i
will be discussed here
To help answer this, we’d need a reproducible example (a pact file and OAS)
A screenshot of the UI in PactFlow would also be ideal.
Also, move this thread to #CLS16AVEE if you don’t mind, as it’s not related to the Pact Broker (the open source derivative of PactFlow)
@Matt (pactflow.io / pact-js / pact-go) here is the screenshots:
m
It doesn't look like your pact request has an expected body in it. I see matchers (which aren't used in BDCT) If the path and response code matches your OAD then it would be compatible
(I can't see the relevant endpoint tho in those screenshots)
i
I see matchers (which aren't used in BDCT)
is ther any specific matcher for BDCT? here is the actual implementation :
Copy code
public function testAll()
    {
        $servicesPath = '/api/internal/services';

        $config = (new MockServerEnvConfig())
            ->setConsumer($this->pactConsumerName)
            ->setPactSpecificationVersion('4.0')
            ->setProvider(self::PROVIDER_NAME)
            ->setPactDir(__DIR__ . '/pacts');

        $interaction = new InteractionBuilder($config);
        $interaction
            ->given('OfferService list is not empty')
            ->uponReceiving('json-array with OfferService objects')
            ->with(
                (new ConsumerRequest())
                ->setMethod('GET')
                ->setPath($servicesPath)
                ->addHeader('Authorization', new Regex('^Bearer\\s.+'))
            )
            ->willRespondWith(
                (new ProviderResponse())
                ->setStatus(200)
                ->setHeaders([
                    'Content-Type' => new Regex('application/json(;\\s?charset=.*)?')
                ])
                ->setBody(
                    [
                        "items" => [
                            ["id" => "17575ed0-9533-4000-a967-9011ffc6ff94", "name" => "Curb", "isActive" => true],
                            ["id" => "df9095b8-63af-4e5c-8e52-c6e9bd1c8c78", "name" => "Premise", "isActive" => true],
                        ],
                        "totalCount" => 2,
                    ]
                )
            );

        $response = HttpClient::create()->request('GET', $config->getBaseUri() . $servicesPath, ['auth_bearer' => 'CthulhuFhtagn']);

        $this->assertSame(200, $response->getStatusCode());

        $body = $response->toArray();
        $this->assertIsArray($body);
        $this->assertArrayHasKey('items', $body);
        $this->assertIsArray($body['items']);
        $this->assertNotEmpty($body['items']);
        $item = $body['items'][0];
        $this->assertArrayHasKey('id', $item);
        $this->assertNotEmpty($item['id']);
        $this->assertIsString($item['id']);
        $this->assertTrue(Uuid::isValid($item['id']));
        $this->assertArrayHasKey('name', $item);
        $this->assertNotEmpty($item['name']);
        $this->assertIsString($item['name']);
        $this->assertArrayHasKey('isActive', $item);
        $this->assertNotEmpty($item['isActive']);
        $this->assertIsBool($item['isActive']);
        $this->assertArrayHasKey('totalCount', $body);
        $this->assertIsInt($body['totalCount']);
        $this->assertEquals(count($body['items']), $body['totalCount']);

        $verified = $interaction->verify();
        $this->assertTrue($verified, 'Pact verification failed.');

        // Add matching rules manually
        $pactPath = __DIR__ . '/pacts/' . $this->pactConsumerName . '-' . self::PROVIDER_NAME . '.json';
        $pact = json_decode(file_get_contents($pactPath), true);

        $pact['interactions'][0]['response']['body'] = $pact['interactions'][0]['response']['body']['content'];
        $pact['interactions'][0]['response']['matchingRules'] = [
            'header' => [
                'Content-Type' => [
                    'matchers' => [[
                        'match' => 'regex',
                        'regex' => 'application/json(;\\s?charset=.*)?',
                    ]],
                    'combine' => 'AND',
                ],
            ],
            'body' => [
                '$.items' => [
                    'matchers' => [['match' => 'type', 'min' => 1]],
                ],
                '$.items[*].id' => [
                    'matchers' => [
                        ['match' => 'type'],
                        ['match' => 'notEmpty'],
                        ['match' => 'regex', 'regex' => '^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$'],
                    ],
                ],
                '$.items[*].name' => [
                    'matchers' => [['match' => 'type'], ['match' => 'notEmpty']],
                ],
                '$.items[*].isActive' => [
                    'matchers' => [['match' => 'type']],
                ],
                '$.totalCount' => [
                    'matchers' => [['match' => 'type']], 
                    ['match' => 'notEmpty'],
                ],
            ],
        ];

        $uploadResult = $this->pactFlowService->uploadContract($this->pactConsumerName, self::PROVIDER_NAME,
                        $this->version, $this->branch, json_encode($pact));
        $this->assertTrue($uploadResult);

    }
are those matchers correct?
m
I’m not sure if this is just a demo, but there is a lot wrong with that pact test. 1. You’re not using your API client, but a general one:
Copy code
$response = HttpClient::create()->request('GET', $config->getBaseUri() . $servicesPath, ['auth_bearer' => 'CthulhuFhtagn']);
This means See also this best practice guide. 2.
// Add matching rules manually
Why are you manually adding matchers? This is a super advanced case that basically nobody should be doing (the only case I can really think of is if there is a bug in Pact, or you are not using Pact to generate the contract in the first place). 3. As noted above, matchers are not relevant for BDCT anyway. In BDCT, the request/response body is compared against the OAD schema. The “matchers” here are essentially the OAD schema. 4. The assertions aren’t testing your API client, they’re checking the mock server did it’s job. This is only testing Pact, which isn’t useful i.e.
Copy code
$body = $response->toArray();
        $this->assertIsArray($body);
        $this->assertArrayHasKey('items', $body);
        $this->assertIsArray($body['items']);
        $this->assertNotEmpty($body['items']);
        $item = $body['items'][0];
...
Just asserts that the mock server returned what you told it to. 5. Uploading the contract within the unit test isn’t good practice You should use a separate CI step to do this
i
@Matt (pactflow.io / pact-js / pact-go) thanks for all suggestion. we'll review our code again