Skip to content

Instantly share code, notes, and snippets.

View bethesque's full-sized avatar
💭
Intermittently coding

Beth Skurrie bethesque

💭
Intermittently coding
View GitHub Profile
@bethesque
bethesque / a_readme.md
Last active October 21, 2023 16:03
Using Pact with non-HTTP services

When you declare a request and response using the traditional Pact DSL, ("uponReceiving" and "willRespondWith") you're building a structure that has three purposes -

  1. it provides the concrete example request and response used in the tests
  2. it specifies the contents of the contract which...
  3. defines how to validate the the actual request/response against the expected request/response

The three different uses of this structure are hidden from you when using HTTP Pact because the mock service handles numbers 1 & 2 in the consumer tests, and the verification task handles number 3 for you in the provider tests. When using Pact in a non-HTTP scenario, there is no nice neat protocol layer to inject the code to do this for you, so you have to explicitly do each step.

The file expected_data_from_collector.rb declares an object graph using the Pact DSL. This is going to be used to create the concrete example and the contract. This could be declared inline, but for easier maintenance, and to allow the contr

@bethesque
bethesque / index.md
Last active October 31, 2022 18:10
Using pact with providers that have their own providers

Eg. A -> B -> C

A more find grained view of this intergration might go:

|------------------A Codebase------------------||------------------B Codebase------------------||--------C Codebase---...
 A UI -> A Controller -> B Service -> B Client -> B API -> B Controller -> CService -> CClient -> C API etc...  
                                           |---A/B pact------------------------?
 |---A/B pact------------------------------------?
@bethesque
bethesque / index.js
Created March 31, 2022 06:02
Example of how to use Cypress and Pact together using a shared fixture
// in cypress support
const Matchers = require('@pact-foundation/pact-web').Matchers
// turn a pact definition into a cypress mock
// TODO headers, and allow safe overriding of generated fields
const toCypressInteraction = (interaction) => {
return {
method: interaction.withRequest.method,
url: Matchers.extractPayload(interaction.withRequest.path),
@bethesque
bethesque / index.md
Last active June 24, 2021 23:57
Problem solving checklist

Strategies

  • Form a mental model of the process taking place. Write it down in words or draw a diagram. Validate that each step in your model is accurate, not just the one you think is failing.
  • Another way to approach the above point - think of all the things that affect the running code, and work out which are the most likely to have an effect. Don't rule out the unexpected ones though. Think how you could test your understanding of, or rule out a problem with, each of the aspects.
    • your code (and different versions thereof)
    • other libraries (and different versions thereof)
    • application server (and different versions thereof)
    • language interpreter, compiler and/or virtual machine (and different versions thereof)
    • properties files
  • environment variables
Current definition of WIP:
No successful verifications exist for the pact content by a provider version with the specified tag.
main ref1, basePact
create branchA refA, basePact+integrationA
create branchB refB, basePact+integrationB
main provider build runs, configured to verify main pacts, and WIP pacts.
basePact (explicit), basePact+integrationA (wip), basePact+integrationB (wip) all verified successfully
basePact+integrationA and basePact+integrationB no longer WIP
@bethesque
bethesque / authorizer.js
Created February 25, 2020 03:48
API Gateway custom auth
const accountId = process.env.ACCOUNT_ID;
const region = process.env.REGION;
const basicAuthUsername = process.env.BASIC_AUTH_USERNAME;
const basicAuthPassword = process.env.BASIC_AUTH_PASSWORD;
const validateAuth = authorizationHeader => {
if (!authorizationHeader) return false;
const encodedCreds = authorizationHeader.split(" ")[1];
const plainCreds = new Buffer(encodedCreds, "base64").toString().split(":");
@bethesque
bethesque / dynamic-left-outer-join.rb
Last active December 20, 2019 01:21
Trying to achieve a dynamically filtered left outer join AND eager loading
require 'spec_helper'
require 'sequel'
DATABASE = Sequel::Model.db
DATABASE.drop_table(:orders) rescue nil
DATABASE.drop_table(:order_lines) rescue nil
DATABASE.drop_table(:customers) rescue nil
DATABASE.create_table(:customers) do
@bethesque
bethesque / test.rb
Last active August 14, 2019 04:23
synchronous message
some_provider.given("a thing", "foo" => "bar")
.and("another thing", "blah" => "blah")
.upon_receiving("some message")
.with(
contents: {"the" => "contents"},
metadata: {"some" => "info"})
.will_respond_with(
contents: {"the" => "response"},
metadata: {"some" => "other info"}
)
@bethesque
bethesque / migrate.rb
Last active November 26, 2018 00:53
Migrate pacts from one pact broker to another
# Note: this does not migrate the tags
require 'faraday'
require 'json'
source_host = 'http://some-pact-broker'
destination_host = 'http://localhost:9292'
latest_pacts_response = JSON.parse(Faraday.get("#{source_host}/pacts/latest").body)
pact_hrefs = latest_pacts_response['pacts'].collect{ | pact | pact['_links']['self'][1]['href'] }
@bethesque
bethesque / 1.sh
Last active July 10, 2018 06:56
HTTP requests to ruby mock server
You will need ruby or the standalone mock service to run these examples.
$ gem install pact-mock_service