Commit d805d0a4 authored by Tomislav Nikić's avatar Tomislav Nikić Committed by Andrejs Cunskis

Basic setup for contract testing

This commit contains a basic consumer side test setup.
It is still a draft but sets up the needed folder structure.
parent 0d75bf91
......@@ -9,3 +9,4 @@
/sitespeed-result/
/fixtures/**/*.graphql
spec/fixtures/**/*.graphql
**/contracts/consumer/
......@@ -35,6 +35,8 @@ gem 'confiner', '~> 0.2'
gem 'chemlab', '~> 0.9'
gem 'chemlab-library-www-gitlab-com', '~> 0.1'
gem "pact", "~> 1.12"
gem 'deprecation_toolkit', '~> 1.5.1', require: false
group :development do
......
......@@ -28,6 +28,7 @@ GEM
require_all (>= 2, < 4)
uuid (>= 2.3, < 3)
ast (2.4.2)
awesome_print (1.9.2)
binding_ninja (0.2.3)
builder (3.2.4)
byebug (9.1.0)
......@@ -91,6 +92,8 @@ GEM
ffi-compiler (1.0.1)
ffi (>= 1.0.0)
rake
filelock (1.1.1)
find_a_port (1.0.1)
fog-core (2.1.0)
builder
excon (~> 0.58)
......@@ -173,6 +176,7 @@ GEM
concurrent-ruby (~> 1.0)
ice_nine (0.11.2)
influxdb-client (1.17.0)
json (2.6.1)
jwt (2.3.0)
knapsack (4.0.0)
rake
......@@ -205,6 +209,29 @@ GEM
sawyer (~> 0.8.0, >= 0.5.3)
oj (3.13.11)
os (1.1.4)
pact (1.59.0)
pact-mock_service (~> 3.0, >= 3.3.1)
pact-support (~> 1.15)
rack-test (>= 0.6.3, < 2.0.0)
rspec (~> 3.0)
term-ansicolor (~> 1.0)
thor (>= 0.20, < 2.0)
webrick (~> 1.3)
pact-mock_service (3.6.2)
filelock (~> 1.1)
find_a_port (~> 1.0.1)
json
pact-support (~> 1.12, >= 1.12.0)
rack (~> 2.0)
rspec (>= 2.14)
term-ansicolor (~> 1.0)
thor (>= 0.19, < 2.0)
webrick (~> 1.3)
pact-support (1.15.1)
awesome_print (~> 1.1)
randexp (~> 0.1.7)
rspec (>= 2.14)
term-ansicolor (~> 1.0)
parallel (1.19.2)
parallel_tests (2.29.0)
parallel
......@@ -228,6 +255,7 @@ GEM
rack (>= 1.0, < 3)
rainbow (3.0.0)
rake (13.0.6)
randexp (0.1.7)
regexp_parser (2.1.1)
representable (3.1.1)
declarative (< 0.1.0)
......@@ -282,12 +310,18 @@ GEM
jwt (>= 1.5, < 3.0)
multi_json (~> 1.10)
slack-notifier (2.4.0)
sync (0.5.0)
systemu (2.6.5)
table_print (1.5.7)
term-ansicolor (1.7.1)
tins (~> 1.0)
terminal-table (3.0.2)
unicode-display_width (>= 1.1.1, < 3)
thor (1.2.1)
thread_safe (0.3.6)
timecop (0.9.1)
tins (1.31.0)
sync
trailblazer-option (0.1.2)
tzinfo (2.0.4)
concurrent-ruby (~> 1.0)
......@@ -337,6 +371,7 @@ DEPENDENCIES
influxdb-client (~> 1.17)
knapsack (~> 4.0)
octokit (~> 4.21)
pact (~> 1.12)
parallel (~> 1.19)
parallel_tests (~> 2.29)
pry-byebug (~> 3.5.1)
......
#!/usr/bin/env ruby
# frozen_string_literal: true
require 'rake'
host = ARGV.shift
ENV['CONTRACT_HOST'] ||= host
list = []
loop do
keyword = ARGV.shift
case keyword
when '--mr'
ENV['CONTRACT_MR'] ||= ARGV.shift
list.push 'test:merge_request'
else
break
end
end
app = Rake.application
Dir.chdir('contracts/provider') do
app.init
app.add_import 'Rakefile'
app.load_rakefile
list.each do |element|
app[element].invoke
end
end
logs/
consumer/node_modules
'use strict';
const axios = require('axios');
exports.getMetadata = (endpoint) => {
const url = endpoint.url;
return axios
.request({
method: 'GET',
baseURL: url,
url: '/diffs_metadata.json',
headers: { Accept: '*/*' },
})
.then((response) => response.data);
};
exports.getDiscussions = (endpoint) => {
const url = endpoint.url;
return axios
.request({
method: 'GET',
baseURL: url,
url: '/discussions.json',
headers: { Accept: '*/*' },
})
.then((response) => response.data);
};
exports.getDiffs = (endpoint) => {
const url = endpoint.url;
return axios
.request({
method: 'GET',
baseURL: url,
url: '/diffs_batch.json?page=0',
headers: { Accept: '*/*' },
})
.then((response) => response.data);
};
'use strict';
const { Matchers } = require('@pact-foundation/pact');
const body = {
diff_files: Matchers.eachLike({
content_sha: Matchers.string('b0c94059db75b2473d616d4b1fde1a77533355a3'),
submodule: Matchers.boolean(false),
edit_path: Matchers.string('/gitlab-qa-bot/...'),
ide_edit_path: Matchers.string('/gitlab-qa-bot/...'),
old_path_html: Matchers.string('Gemfile'),
new_path_html: Matchers.string('Gemfile'),
blob: {
id: Matchers.string('855071bb3928d140764885964f7be1bb3e582495'),
path: Matchers.string('Gemfile'),
name: Matchers.string('Gemfile'),
mode: Matchers.string('1234567'),
readable_text: Matchers.boolean(true),
icon: Matchers.string('doc-text'),
},
can_modify_blob: Matchers.boolean(false),
file_identifier_hash: Matchers.string('67d82b8716a5b6c52c7abf0b2cd99c7594ed3587'),
file_hash: Matchers.string('67d82b8716a5b6c52c7abf0b2cd99c7594ed3587'),
file_path: Matchers.string('Gemfile'),
old_path: Matchers.string('Gemfile'),
new_path: Matchers.string('Gemfile'),
new_file: Matchers.boolean(false),
renamed_file: Matchers.boolean(false),
deleted_file: Matchers.boolean(false),
diff_refs: {
base_sha: Matchers.string('67d82b8716a5b6c52c7abf0b2cd99c7594ed3587'),
start_sha: Matchers.string('67d82b8716a5b6c52c7abf0b2cd99c7594ed3587'),
head_sha: Matchers.string('67d82b8716a5b6c52c7abf0b2cd99c7594ed3587'),
},
mode_changed: Matchers.boolean(false),
a_mode: Matchers.string('123456'),
b_mode: Matchers.string('123456'),
viewer: {
name: Matchers.string('text'),
collapsed: Matchers.boolean(false),
},
old_size: Matchers.integer(2288),
new_size: Matchers.integer(2288),
added_lines: Matchers.integer(1),
removed_lines: Matchers.integer(1),
load_collapsed_diff_url: Matchers.string('/gitlab-qa-bot/...'),
view_path: Matchers.string('/gitlab-qa-bot/...'),
context_lines_path: Matchers.string('/gitlab-qa-bot/...'),
highlighted_diff_lines: Matchers.eachLike({
// The following values can also be null which is not supported
//line_code: Matchers.string('de3150c01c3a946a6168173c4116741379fe3579_1_1'),
//old_line: Matchers.integer(1),
//new_line: Matchers.integer(1),
text: Matchers.string('source'),
rich_text: Matchers.string('<span></span>'),
can_receive_suggestion: Matchers.boolean(true),
}),
is_fully_expanded: Matchers.boolean(false),
}),
pagination: {
total_pages: Matchers.integer(1),
},
};
const Diffs = {
body: Matchers.extractPayload(body),
success: {
status: 200,
headers: {
'Content-Type': 'application/json; charset=utf-8',
},
body: body,
},
request: {
uponReceiving: 'a request for diff lines',
withRequest: {
method: 'GET',
path: '/diffs_batch.json',
headers: {
Accept: '*/*',
},
query: 'page=0',
},
},
};
exports.Diffs = Diffs;
'use strict';
const { Matchers } = require('@pact-foundation/pact');
const body = Matchers.eachLike({
id: Matchers.string('fd73763cbcbf7b29eb8765d969a38f7d735e222a'),
reply_id: Matchers.string('fd73763cbcbf7b29eb8765d969a38f7d735e222a'),
project_id: Matchers.integer(6954442),
confidential: Matchers.boolean(false),
diff_discussion: Matchers.boolean(false),
expanded: Matchers.boolean(false),
for_commit: Matchers.boolean(false),
individual_note: Matchers.boolean(true),
resolvable: Matchers.boolean(false),
resolved_by_push: Matchers.boolean(false),
notes: Matchers.eachLike({
id: Matchers.string('76489845'),
author: {
id: Matchers.integer(1675733),
username: Matchers.string('gitlab-qa-bot'),
name: Matchers.string('gitlab-qa-bot'),
state: Matchers.string('active'),
avatar_url: Matchers.string(
'https://secure.gravatar.com/avatar/8355ad0f2761367fae6b9c4fe80994b9?s=80&d=identicon',
),
show_status: Matchers.boolean(false),
path: Matchers.string('/gitlab-qa-bot'),
},
created_at: Matchers.iso8601DateTimeWithMillis('2022-02-22T07:06:55.038Z'),
updated_at: Matchers.iso8601DateTimeWithMillis('2022-02-22T07:06:55.038Z'),
system: Matchers.boolean(false),
noteable_id: Matchers.integer(8333422),
noteable_type: Matchers.string('MergeRequest'),
resolvable: Matchers.boolean(false),
resolved: Matchers.boolean(true),
confidential: Matchers.boolean(false),
noteable_iid: Matchers.integer(1),
note: Matchers.string('This is a test comment'),
note_html: Matchers.string(
'<p data-sourcepos="1:1-1:22" dir="auto">This is a test comment</p>',
),
current_user: {
can_edit: Matchers.boolean(true),
can_award_emoji: Matchers.boolean(true),
can_resolve: Matchers.boolean(false),
can_resolve_discussion: Matchers.boolean(false),
},
is_noteable_author: Matchers.boolean(true),
discussion_id: Matchers.string('fd73763cbcbf7b29eb8765d969a38f7d735e222a'),
emoji_awardable: Matchers.boolean(true),
report_abuse_path: Matchers.string('/gitlab-qa-bot/...'),
noteable_note_url: Matchers.string('https://staging.gitlab.com/gitlab-qa-bot/...'),
cached_markdown_version: Matchers.integer(1900552),
human_access: Matchers.string('Maintainer'),
is_contributor: Matchers.boolean(false),
project_name: Matchers.string('contract-testing'),
path: Matchers.string('/gitlab-qa-bot/...'),
}),
resolved: Matchers.boolean(true),
});
const Discussions = {
body: Matchers.extractPayload(body),
success: {
status: 200,
headers: {
'Content-Type': 'application/json; charset=utf-8',
},
body: body,
},
request: {
uponReceiving: 'a request for discussions',
withRequest: {
method: 'GET',
path: '/discussions.json',
headers: {
Accept: '*/*',
},
},
},
};
exports.Discussions = Discussions;
'use strict';
const { Matchers } = require('@pact-foundation/pact');
const body = {
real_size: Matchers.string('1'),
size: Matchers.integer(1),
branch_name: Matchers.string('testing-branch-1'),
source_branch_exists: Matchers.boolean(true),
target_branch_name: Matchers.string('master'),
merge_request_diff: {
created_at: Matchers.iso8601DateTimeWithMillis('2022-02-17T11:47:08.804Z'),
commits_count: Matchers.integer(1),
latest: Matchers.boolean(true),
short_commit_sha: Matchers.string('aee1ffec'),
base_version_path: Matchers.string(
'/gitlab-qa-bot/contract-testing/-/merge_requests/1/diffs?diff_id=10581773',
),
head_version_path: Matchers.string(
'/gitlab-qa-bot/contract-testing/-/merge_requests/1/diffs?diff_head=true',
),
version_path: Matchers.string(
'/gitlab-qa-bot/contract-testing/-/merge_requests/1/diffs?diff_id=10581773',
),
compare_path: Matchers.string(
'/gitlab-qa-bot/contract-testing/-/merge_requests/1/diffs?diff_id=10581773&start_sha=aee1ffec2299c0cfb17c8821e931339b73a3759f',
),
},
latest_diff: Matchers.boolean(true),
latest_version_path: Matchers.string('/gitlab-qa-bot/contract-testing/-/merge_requests/1/diffs'),
added_lines: Matchers.integer(1),
removed_lines: Matchers.integer(1),
render_overflow_warning: Matchers.boolean(false),
email_patch_path: Matchers.string('/gitlab-qa-bot/contract-testing/-/merge_requests/1.patch'),
plain_diff_path: Matchers.string('/gitlab-qa-bot/contract-testing/-/merge_requests/1.diff'),
merge_request_diffs: Matchers.eachLike({
commits_count: Matchers.integer(1),
latest: Matchers.boolean(true),
short_commit_sha: Matchers.string('aee1ffec'),
base_version_path: Matchers.string(
'/gitlab-qa-bot/contract-testing/-/merge_requests/1/diffs?diff_id=10581773',
),
head_version_path: Matchers.string(
'/gitlab-qa-bot/contract-testing/-/merge_requests/1/diffs?diff_head=true',
),
version_path: Matchers.string(
'/gitlab-qa-bot/contract-testing/-/merge_requests/1/diffs?diff_id=10581773',
),
compare_path: Matchers.string(
'/gitlab-qa-bot/contract-testing/-/merge_requests/1/diffs?diff_id=10581773&start_sha=aee1ffec2299c0cfb17c8821e931339b73a3759f',
),
}),
definition_path_prefix: Matchers.string(
'/gitlab-qa-bot/contract-testing/-/blob/aee1ffec2299c0cfb17c8821e931339b73a3759f',
),
diff_files: Matchers.eachLike({
added_lines: Matchers.integer(1),
removed_lines: Matchers.integer(1),
new_path: Matchers.string('Gemfile'),
old_path: Matchers.string('Gemfile'),
new_file: Matchers.boolean(false),
deleted_file: Matchers.boolean(false),
submodule: Matchers.boolean(false),
file_identifier_hash: Matchers.string('67d82b8716a5b6c52c7abf0b2cd99c7594ed3587'),
file_hash: Matchers.string('de3150c01c3a946a6168173c4116741379fe3579'),
}),
has_conflicts: Matchers.boolean(false),
can_merge: Matchers.boolean(false),
project_path: Matchers.string('gitlab-qa-bot/contract-testing'),
project_name: Matchers.string('contract-testing'),
};
const Metadata = {
body: Matchers.extractPayload(body),
success: {
status: 200,
headers: {
'Content-Type': 'application/json; charset=utf-8',
},
body: body,
},
request: {
uponReceiving: 'a request for Metadata',
withRequest: {
method: 'GET',
path: '/diffs_metadata.json',
headers: {
Accept: '*/*',
},
},
},
};
exports.Metadata = Metadata;
{
"name": "consumer",
"version": "1.0.0",
"description": "consumer side contract testing",
"license": "MIT",
"repository": "https://gitlab.com/gitlab-org/gitlab.git",
"dependencies": {
"@pact-foundation/pact": "^9.17.2",
"axios": "^0.26.0",
"jest": "^27.5.1",
"jest-pact": "^0.9.1",
"prettier": "^2.5.1"
},
"scripts": {
"test": "jest specs/ --runInBand"
}
}
'use strict';
const { pactWith } = require('jest-pact');
const { Diffs } = require('../fixtures/diffs.fixture');
const { getDiffs } = require('../endpoints/merge_request');
pactWith(
{
consumer: 'Merge Request Page',
provider: 'Merge Request Diffs Endpoint',
log: '../logs/consumer.log',
dir: '../contracts',
},
(provider) => {
describe('Diffs Endpoint', () => {
beforeEach(() => {
const interaction = {
...Diffs.request,
willRespondWith: Diffs.success,
};
return provider.addInteraction(interaction);
});
it('return a successful body', () => {
return getDiffs({
url: provider.mockService.baseUrl,
}).then((diffs) => {
expect(diffs).toEqual(Diffs.body);
});
});
});
},
);
'use strict';
const { pactWith } = require('jest-pact');
const { Discussions } = require('../fixtures/discussions.fixture');
const { getDiscussions } = require('../endpoints/merge_request');
pactWith(
{
consumer: 'Merge Request Page',
provider: 'Merge Request Discussions Endpoint',
log: '../logs/consumer.log',
dir: '../contracts',
},
(provider) => {
describe('Discussions Endpoint', () => {
beforeEach(() => {
const interaction = {
...Discussions.request,
willRespondWith: Discussions.success,
};
return provider.addInteraction(interaction);
});
it('return a successful body', () => {
return getDiscussions({
url: provider.mockService.baseUrl,
}).then((discussions) => {
expect(discussions).toEqual(Discussions.body);
});
});
});
},
);
'use strict';
const { pactWith } = require('jest-pact');
const { Metadata } = require('../fixtures/metadata.fixture');
const { getMetadata } = require('../endpoints/merge_request');
pactWith(
{
consumer: 'Merge Request Page',
provider: 'Merge Request Metadata Endpoint',
log: '../logs/consumer.log',
dir: '../contracts',
},
(provider) => {
describe('Metadata Endpoint', () => {
beforeEach(() => {
const interaction = {
...Metadata.request,
willRespondWith: Metadata.success,
};
return provider.addInteraction(interaction);
});
it('return a successful body', () => {
return getMetadata({
url: provider.mockService.baseUrl,
}).then((metadata) => {
expect(metadata).toEqual(Metadata.body);
});
});
});
},
);
{
"consumer": {
"name": "Merge Request Page"
},
"provider": {
"name": "Merge Request Diffs Endpoint"
},
"interactions": [
{
"description": "a request for diff lines",
"request": {
"method": "GET",
"path": "/diffs_batch.json",
"query": "page=0",
"headers": {
"Accept": "*/*"
}
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json; charset=utf-8"
},
"body": {
"diff_files": [
{
"content_sha": "b0c94059db75b2473d616d4b1fde1a77533355a3",
"submodule": false,
"edit_path": "/gitlab-qa-bot/...",
"ide_edit_path": "/gitlab-qa-bot/...",
"old_path_html": "Gemfile",
"new_path_html": "Gemfile",
"blob": {
"id": "855071bb3928d140764885964f7be1bb3e582495",
"path": "Gemfile",
"name": "Gemfile",
"mode": "1234567",
"readable_text": true,
"icon": "doc-text"
},
"can_modify_blob": false,
"file_identifier_hash": "67d82b8716a5b6c52c7abf0b2cd99c7594ed3587",
"file_hash": "67d82b8716a5b6c52c7abf0b2cd99c7594ed3587",
"file_path": "Gemfile",
"old_path": "Gemfile",
"new_path": "Gemfile",
"new_file": false,
"renamed_file": false,
"deleted_file": false,
"diff_refs": {
"base_sha": "67d82b8716a5b6c52c7abf0b2cd99c7594ed3587",
"start_sha": "67d82b8716a5b6c52c7abf0b2cd99c7594ed3587",
"head_sha": "67d82b8716a5b6c52c7abf0b2cd99c7594ed3587"
},
"mode_changed": false,
"a_mode": "123456",
"b_mode": "123456",
"viewer": {
"name": "text",
"collapsed": false
},
"old_size": 2288,
"new_size": 2288,
"added_lines": 1,
"removed_lines": 1,
"load_collapsed_diff_url": "/gitlab-qa-bot/...",
"view_path": "/gitlab-qa-bot/...",
"context_lines_path": "/gitlab-qa-bot/...",
"highlighted_diff_lines": [
{
"text": "source",
"rich_text": "<span></span>",
"can_receive_suggestion": true
}
],
"is_fully_expanded": false
}
],
"pagination": {
"total_pages": 1
}
},
"matchingRules": {
"$.body.diff_files": {
"min": 1
},
"$.body.diff_files[*].*": {
"match": "type"
},
"$.body.diff_files[*].content_sha": {
"match": "type"
},
"$.body.diff_files[*].submodule": {
"match": "type"
},
"$.body.diff_files[*].edit_path": {
"match": "type"
},
"$.body.diff_files[*].ide_edit_path": {
"match": "type"
},
"$.body.diff_files[*].old_path_html": {
"match": "type"
},
"$.body.diff_files[*].new_path_html": {
"match": "type"
},
"$.body.diff_files[*].blob.id": {
"match": "type"
},
"$.body.diff_files[*].blob.path": {
"match": "type"
},
"$.body.diff_files[*].blob.name": {
"match": "type"
},
"$.body.diff_files[*].blob.mode": {
"match": "type"
},
"$.body.diff_files[*].blob.readable_text": {
"match": "type"
},
"$.body.diff_files[*].blob.icon": {
"match": "type"
},
"$.body.diff_files[*].can_modify_blob": {
"match": "type"
},
"$.body.diff_files[*].file_identifier_hash": {
"match": "type"
},
"$.body.diff_files[*].file_hash": {
"match": "type"
},
"$.body.diff_files[*].file_path": {
"match": "type"
},
"$.body.diff_files[*].old_path": {
"match": "type"
},
"$.body.diff_files[*].new_path": {
"match": "type"
},
"$.body.diff_files[*].new_file": {
"match": "type"
},
"$.body.diff_files[*].renamed_file": {
"match": "type"
},
"$.body.diff_files[*].deleted_file": {
"match": "type"
},
"$.body.diff_files[*].diff_refs.base_sha": {
"match": "type"
},
"$.body.diff_files[*].diff_refs.start_sha": {
"match": "type"
},
"$.body.diff_files[*].diff_refs.head_sha": {
"match": "type"
},
"$.body.diff_files[*].mode_changed": {
"match": "type"
},
"$.body.diff_files[*].a_mode": {
"match": "type"
},
"$.body.diff_files[*].b_mode": {
"match": "type"
},
"$.body.diff_files[*].viewer.name": {
"match": "type"
},
"$.body.diff_files[*].viewer.collapsed": {
"match": "type"
},
"$.body.diff_files[*].old_size": {
"match": "type"
},
"$.body.diff_files[*].new_size": {
"match": "type"
},
"$.body.diff_files[*].added_lines": {
"match": "type"
},
"$.body.diff_files[*].removed_lines": {
"match": "type"
},
"$.body.diff_files[*].load_collapsed_diff_url": {
"match": "type"
},
"$.body.diff_files[*].view_path": {
"match": "type"
},
"$.body.diff_files[*].context_lines_path": {
"match": "type"
},
"$.body.diff_files[*].highlighted_diff_lines": {
"min": 1
},
"$.body.diff_files[*].highlighted_diff_lines[*].*": {
"match": "type"
},
"$.body.diff_files[*].highlighted_diff_lines[*].text": {
"match": "type"
},
"$.body.diff_files[*].highlighted_diff_lines[*].rich_text": {
"match": "type"
},
"$.body.diff_files[*].highlighted_diff_lines[*].can_receive_suggestion": {
"match": "type"
},
"$.body.diff_files[*].is_fully_expanded": {
"match": "type"
},
"$.body.pagination.total_pages": {
"match": "type"
}
}
}
}
],
"metadata": {
"pactSpecification": {
"version": "2.0.0"
}
}
}
\ No newline at end of file
{
"consumer": {
"name": "Merge Request Page"
},
"provider": {
"name": "Merge Request Discussions Endpoint"
},
"interactions": [
{
"description": "a request for discussions",
"request": {
"method": "GET",
"path": "/discussions.json",
"headers": {
"Accept": "*/*"
}
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json; charset=utf-8"
},
"body": [
{
"id": "fd73763cbcbf7b29eb8765d969a38f7d735e222a",
"reply_id": "fd73763cbcbf7b29eb8765d969a38f7d735e222a",
"project_id": 6954442,
"confidential": false,
"diff_discussion": false,
"expanded": false,
"for_commit": false,
"individual_note": true,
"resolvable": false,
"resolved_by_push": false,
"notes": [
{
"id": "76489845",
"author": {
"id": 1675733,
"username": "gitlab-qa-bot",
"name": "gitlab-qa-bot",
"state": "active",
"avatar_url": "https://secure.gravatar.com/avatar/8355ad0f2761367fae6b9c4fe80994b9?s=80&d=identicon",
"show_status": false,
"path": "/gitlab-qa-bot"
},
"created_at": "2022-02-22T07:06:55.038Z",
"updated_at": "2022-02-22T07:06:55.038Z",
"system": false,
"noteable_id": 8333422,
"noteable_type": "MergeRequest",
"resolvable": false,
"resolved": true,
"confidential": false,
"noteable_iid": 1,
"note": "This is a test comment",
"note_html": "<p data-sourcepos=\"1:1-1:22\" dir=\"auto\">This is a test comment</p>",
"current_user": {
"can_edit": true,
"can_award_emoji": true,
"can_resolve": false,
"can_resolve_discussion": false
},
"is_noteable_author": true,
"discussion_id": "fd73763cbcbf7b29eb8765d969a38f7d735e222a",
"emoji_awardable": true,
"report_abuse_path": "/gitlab-qa-bot/...",
"noteable_note_url": "https://staging.gitlab.com/gitlab-qa-bot/...",
"cached_markdown_version": 1900552,
"human_access": "Maintainer",
"is_contributor": false,
"project_name": "contract-testing",
"path": "/gitlab-qa-bot/..."
}
],
"resolved": true
}
],
"matchingRules": {
"$.body": {
"min": 1
},
"$.body[*].*": {
"match": "type"
},
"$.body[*].id": {
"match": "type"
},
"$.body[*].reply_id": {
"match": "type"
},
"$.body[*].project_id": {
"match": "type"
},
"$.body[*].confidential": {
"match": "type"
},
"$.body[*].diff_discussion": {
"match": "type"
},
"$.body[*].expanded": {
"match": "type"
},
"$.body[*].for_commit": {
"match": "type"
},
"$.body[*].individual_note": {
"match": "type"
},
"$.body[*].resolvable": {
"match": "type"
},
"$.body[*].resolved_by_push": {
"match": "type"
},
"$.body[*].notes": {
"min": 1
},
"$.body[*].notes[*].*": {
"match": "type"
},
"$.body[*].notes[*].id": {
"match": "type"
},
"$.body[*].notes[*].author.id": {
"match": "type"
},
"$.body[*].notes[*].author.username": {
"match": "type"
},
"$.body[*].notes[*].author.name": {
"match": "type"
},
"$.body[*].notes[*].author.state": {
"match": "type"
},
"$.body[*].notes[*].author.avatar_url": {
"match": "type"
},
"$.body[*].notes[*].author.show_status": {
"match": "type"
},
"$.body[*].notes[*].author.path": {
"match": "type"
},
"$.body[*].notes[*].created_at": {
"match": "regex",
"regex": "^\\d{4}-[01]\\d-[0-3]\\dT[0-2]\\d:[0-5]\\d:[0-5]\\d\\.\\d+([+-][0-2]\\d(:?[0-5]\\d)?|Z)$"
},
"$.body[*].notes[*].updated_at": {
"match": "regex",
"regex": "^\\d{4}-[01]\\d-[0-3]\\dT[0-2]\\d:[0-5]\\d:[0-5]\\d\\.\\d+([+-][0-2]\\d(:?[0-5]\\d)?|Z)$"
},
"$.body[*].notes[*].system": {
"match": "type"
},
"$.body[*].notes[*].noteable_id": {
"match": "type"
},
"$.body[*].notes[*].noteable_type": {
"match": "type"
},
"$.body[*].notes[*].resolvable": {
"match": "type"
},
"$.body[*].notes[*].resolved": {
"match": "type"
},
"$.body[*].notes[*].confidential": {
"match": "type"
},
"$.body[*].notes[*].noteable_iid": {
"match": "type"
},
"$.body[*].notes[*].note": {
"match": "type"
},
"$.body[*].notes[*].note_html": {
"match": "type"
},
"$.body[*].notes[*].current_user.can_edit": {
"match": "type"
},
"$.body[*].notes[*].current_user.can_award_emoji": {
"match": "type"
},
"$.body[*].notes[*].current_user.can_resolve": {
"match": "type"
},
"$.body[*].notes[*].current_user.can_resolve_discussion": {
"match": "type"
},
"$.body[*].notes[*].is_noteable_author": {
"match": "type"
},
"$.body[*].notes[*].discussion_id": {
"match": "type"
},
"$.body[*].notes[*].emoji_awardable": {
"match": "type"
},
"$.body[*].notes[*].report_abuse_path": {
"match": "type"
},
"$.body[*].notes[*].noteable_note_url": {
"match": "type"
},
"$.body[*].notes[*].cached_markdown_version": {
"match": "type"
},
"$.body[*].notes[*].human_access": {
"match": "type"
},
"$.body[*].notes[*].is_contributor": {
"match": "type"
},
"$.body[*].notes[*].project_name": {
"match": "type"
},
"$.body[*].notes[*].path": {
"match": "type"
},
"$.body[*].resolved": {
"match": "type"
}
}
}
}
],
"metadata": {
"pactSpecification": {
"version": "2.0.0"
}
}
}
\ No newline at end of file
{
"consumer": {
"name": "Merge Request Page"
},
"provider": {
"name": "Merge Request Metadata Endpoint"
},
"interactions": [
{
"description": "a request for Metadata",
"request": {
"method": "GET",
"path": "/diffs_metadata.json",
"headers": {
"Accept": "*/*"
}
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json; charset=utf-8"
},
"body": {
"real_size": "1",
"size": 1,
"branch_name": "testing-branch-1",
"source_branch_exists": true,
"target_branch_name": "master",
"merge_request_diff": {
"created_at": "2022-02-17T11:47:08.804Z",
"commits_count": 1,
"latest": true,
"short_commit_sha": "aee1ffec",
"base_version_path": "/gitlab-qa-bot/contract-testing/-/merge_requests/1/diffs?diff_id=10581773",
"head_version_path": "/gitlab-qa-bot/contract-testing/-/merge_requests/1/diffs?diff_head=true",
"version_path": "/gitlab-qa-bot/contract-testing/-/merge_requests/1/diffs?diff_id=10581773",
"compare_path": "/gitlab-qa-bot/contract-testing/-/merge_requests/1/diffs?diff_id=10581773&start_sha=aee1ffec2299c0cfb17c8821e931339b73a3759f"
},
"latest_diff": true,
"latest_version_path": "/gitlab-qa-bot/contract-testing/-/merge_requests/1/diffs",
"added_lines": 1,
"removed_lines": 1,
"render_overflow_warning": false,
"email_patch_path": "/gitlab-qa-bot/contract-testing/-/merge_requests/1.patch",
"plain_diff_path": "/gitlab-qa-bot/contract-testing/-/merge_requests/1.diff",
"merge_request_diffs": [
{
"commits_count": 1,
"latest": true,
"short_commit_sha": "aee1ffec",
"base_version_path": "/gitlab-qa-bot/contract-testing/-/merge_requests/1/diffs?diff_id=10581773",
"head_version_path": "/gitlab-qa-bot/contract-testing/-/merge_requests/1/diffs?diff_head=true",
"version_path": "/gitlab-qa-bot/contract-testing/-/merge_requests/1/diffs?diff_id=10581773",
"compare_path": "/gitlab-qa-bot/contract-testing/-/merge_requests/1/diffs?diff_id=10581773&start_sha=aee1ffec2299c0cfb17c8821e931339b73a3759f"
}
],
"definition_path_prefix": "/gitlab-qa-bot/contract-testing/-/blob/aee1ffec2299c0cfb17c8821e931339b73a3759f",
"diff_files": [
{
"added_lines": 1,
"removed_lines": 1,
"new_path": "Gemfile",
"old_path": "Gemfile",
"new_file": false,
"deleted_file": false,
"submodule": false,
"file_identifier_hash": "67d82b8716a5b6c52c7abf0b2cd99c7594ed3587",
"file_hash": "de3150c01c3a946a6168173c4116741379fe3579"
}
],
"has_conflicts": false,
"can_merge": false,
"project_path": "gitlab-qa-bot/contract-testing",
"project_name": "contract-testing"
},
"matchingRules": {
"$.body.real_size": {
"match": "type"
},
"$.body.size": {
"match": "type"
},
"$.body.branch_name": {
"match": "type"
},
"$.body.source_branch_exists": {
"match": "type"
},
"$.body.target_branch_name": {
"match": "type"
},
"$.body.merge_request_diff.created_at": {
"match": "regex",
"regex": "^\\d{4}-[01]\\d-[0-3]\\dT[0-2]\\d:[0-5]\\d:[0-5]\\d\\.\\d+([+-][0-2]\\d(:?[0-5]\\d)?|Z)$"
},
"$.body.merge_request_diff.commits_count": {
"match": "type"
},
"$.body.merge_request_diff.latest": {
"match": "type"
},
"$.body.merge_request_diff.short_commit_sha": {
"match": "type"
},
"$.body.merge_request_diff.base_version_path": {
"match": "type"
},
"$.body.merge_request_diff.head_version_path": {
"match": "type"
},
"$.body.merge_request_diff.version_path": {
"match": "type"
},
"$.body.merge_request_diff.compare_path": {
"match": "type"
},
"$.body.latest_diff": {
"match": "type"
},
"$.body.latest_version_path": {
"match": "type"
},
"$.body.added_lines": {
"match": "type"
},
"$.body.removed_lines": {
"match": "type"
},
"$.body.render_overflow_warning": {
"match": "type"
},
"$.body.email_patch_path": {
"match": "type"
},
"$.body.plain_diff_path": {
"match": "type"
},
"$.body.merge_request_diffs": {
"min": 1
},
"$.body.merge_request_diffs[*].*": {
"match": "type"
},
"$.body.merge_request_diffs[*].commits_count": {
"match": "type"
},
"$.body.merge_request_diffs[*].latest": {
"match": "type"
},
"$.body.merge_request_diffs[*].short_commit_sha": {
"match": "type"
},
"$.body.merge_request_diffs[*].base_version_path": {
"match": "type"
},
"$.body.merge_request_diffs[*].head_version_path": {
"match": "type"
},
"$.body.merge_request_diffs[*].version_path": {
"match": "type"
},
"$.body.merge_request_diffs[*].compare_path": {
"match": "type"
},
"$.body.definition_path_prefix": {
"match": "type"
},
"$.body.diff_files": {
"min": 1
},
"$.body.diff_files[*].*": {
"match": "type"
},
"$.body.diff_files[*].added_lines": {
"match": "type"
},
"$.body.diff_files[*].removed_lines": {
"match": "type"
},
"$.body.diff_files[*].new_path": {
"match": "type"
},
"$.body.diff_files[*].old_path": {
"match": "type"
},
"$.body.diff_files[*].new_file": {
"match": "type"
},
"$.body.diff_files[*].deleted_file": {
"match": "type"
},
"$.body.diff_files[*].submodule": {
"match": "type"
},
"$.body.diff_files[*].file_identifier_hash": {
"match": "type"
},
"$.body.diff_files[*].file_hash": {
"match": "type"
},
"$.body.has_conflicts": {
"match": "type"
},
"$.body.can_merge": {
"match": "type"
},
"$.body.project_path": {
"match": "type"
},
"$.body.project_name": {
"match": "type"
}
}
}
}
],
"metadata": {
"pactSpecification": {
"version": "2.0.0"
}
}
}
\ No newline at end of file
# frozen_string_literal: true
require 'pact/tasks/verification_task'
Pact::VerificationTask.new(:metadata) do |pact|
pact.uri '../contracts/merge_request_page-merge_request_metadata_endpoint.json', pact_helper: './spec/metadata_helper.rb'
end
Pact::VerificationTask.new(:discussions) do |pact|
pact.uri '../contracts/merge_request_page-merge_request_discussions_endpoint.json', pact_helper: './spec/discussions_helper.rb'
end
Pact::VerificationTask.new(:diffs) do |pact|
pact.uri '../contracts/merge_request_page-merge_request_diffs_endpoint.json', pact_helper: './spec/diffs_helper.rb'
end
task 'test:merge_request' => ['pact:verify:metadata', 'pact:verify:discussions', 'pact:verify:diffs']
# frozen_string_literal: true
require 'faraday'
module Environments
class Base
attr_writer :base_url, :merge_request
def call(env)
@payload
end
def http(endpoint)
Faraday.default_adapter = :net_http
response = Faraday.get(@base_url + endpoint)
@payload = [response.status, response.headers, [response.body]]
self
end
def merge_request(endpoint)
if endpoint.include? '.json'
http(@merge_request + endpoint)
end
end
end
end
# frozen_string_literal: true
require_relative './base'
module Environments
class Local < Base
def initialize
@base_url = ENV['CONTRACT_HOST']
@merge_request = ENV['CONTRACT_MR']
end
end
end
# frozen_string_literal: true
require_relative '../environments/local'
module DiffsHelper
local = Environments::Local.new
Pact.service_provider "Merge Request Diffs Endpoint" do
app { local.merge_request('/diffs_batch.json?page=0') }
honours_pact_with 'Merge Request Page' do
pact_uri '../contracts/merge_request_page-merge_request_diffs_endpoint.json'
end
end
end
# frozen_string_literal: true
require_relative '../environments/local'
module DiscussionsHelper
local = Environments::Local.new
Pact.service_provider "Merge Request Discussions Endpoint" do
app { local.merge_request('/discussions.json') }
honours_pact_with 'Merge Request Page' do
pact_uri '../contracts/merge_request_page-merge_request_discussions_endpoint.json'
end
end
end
# frozen_string_literal: true
require_relative '../environments/local'
module MetadataHelper
local = Environments::Local.new
Pact.service_provider "Merge Request Metadata Endpoint" do
app { local.merge_request('/diffs_metadata.json') }
honours_pact_with 'Merge Request Page' do
pact_uri '../contracts/merge_request_page-merge_request_metadata_endpoint.json'
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment