Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-06-07 12:09:00 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-06-07 12:09:00 +0300
commitbdd03bc52aee1c3f37e25ae9b1fc8a27885b7428 (patch)
treee409a6e1f76d9dc69c5413a06e9b4c4b3f74fef7 /spec/contracts
parentbed53d96d214fd96ea688d3e86e53457ce50043e (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/contracts')
-rw-r--r--spec/contracts/.gitignore2
-rw-r--r--spec/contracts/consumer/.node-version1
-rw-r--r--spec/contracts/consumer/endpoints/merge_requests.js42
-rw-r--r--spec/contracts/consumer/fixtures/diffs.fixture.js89
-rw-r--r--spec/contracts/consumer/fixtures/discussions.fixture.js85
-rw-r--r--spec/contracts/consumer/fixtures/metadata.fixture.js96
-rw-r--r--spec/contracts/consumer/package.json17
-rw-r--r--spec/contracts/consumer/specs/diffs.spec.js36
-rw-r--r--spec/contracts/consumer/specs/discussions.spec.js36
-rw-r--r--spec/contracts/consumer/specs/metadata.spec.js36
-rw-r--r--spec/contracts/contracts/merge_request_page-merge_request_diffs_endpoint.json229
-rw-r--r--spec/contracts/contracts/merge_request_page-merge_request_discussions_endpoint.json236
-rw-r--r--spec/contracts/contracts/merge_request_page-merge_request_metadata_endpoint.json223
-rw-r--r--spec/contracts/provider/environments/test.rb15
-rw-r--r--spec/contracts/provider/helpers/users_helper.rb7
-rw-r--r--spec/contracts/provider/spec_helper.rb39
-rw-r--r--spec/contracts/provider/specs/diffs_helper.rb16
-rw-r--r--spec/contracts/provider/specs/discussions_helper.rb16
-rw-r--r--spec/contracts/provider/specs/metadata_helper.rb16
-rw-r--r--spec/contracts/provider/states/diffs_state.rb18
-rw-r--r--spec/contracts/provider/states/discussions_state.rb17
-rw-r--r--spec/contracts/provider/states/metadata_state.rb18
22 files changed, 1290 insertions, 0 deletions
diff --git a/spec/contracts/.gitignore b/spec/contracts/.gitignore
new file mode 100644
index 00000000000..cb89d4102d3
--- /dev/null
+++ b/spec/contracts/.gitignore
@@ -0,0 +1,2 @@
+logs/
+consumer/node_modules
diff --git a/spec/contracts/consumer/.node-version b/spec/contracts/consumer/.node-version
new file mode 100644
index 00000000000..18711d290ea
--- /dev/null
+++ b/spec/contracts/consumer/.node-version
@@ -0,0 +1 @@
+14.17.5
diff --git a/spec/contracts/consumer/endpoints/merge_requests.js b/spec/contracts/consumer/endpoints/merge_requests.js
new file mode 100644
index 00000000000..04e66c57dc9
--- /dev/null
+++ b/spec/contracts/consumer/endpoints/merge_requests.js
@@ -0,0 +1,42 @@
+'use strict';
+
+const axios = require('axios');
+
+exports.getMetadata = (endpoint) => {
+ const url = endpoint.url;
+
+ return axios
+ .request({
+ method: 'GET',
+ baseURL: url,
+ url: '/gitlab-org/gitlab-qa/-/merge_requests/1/diffs_metadata.json',
+ headers: { Accept: '*/*' },
+ })
+ .then((response) => response.data);
+};
+
+exports.getDiscussions = (endpoint) => {
+ const url = endpoint.url;
+
+ return axios
+ .request({
+ method: 'GET',
+ baseURL: url,
+ url: '/gitlab-org/gitlab-qa/-/merge_requests/1/discussions.json',
+ headers: { Accept: '*/*' },
+ })
+ .then((response) => response.data);
+};
+
+exports.getDiffs = (endpoint) => {
+ const url = endpoint.url;
+
+ return axios
+ .request({
+ method: 'GET',
+ baseURL: url,
+ url: '/gitlab-org/gitlab-qa/-/merge_requests/1/diffs_batch.json?page=0',
+ headers: { Accept: '*/*' },
+ })
+ .then((response) => response.data);
+};
diff --git a/spec/contracts/consumer/fixtures/diffs.fixture.js b/spec/contracts/consumer/fixtures/diffs.fixture.js
new file mode 100644
index 00000000000..7dbe825b093
--- /dev/null
+++ b/spec/contracts/consumer/fixtures/diffs.fixture.js
@@ -0,0 +1,89 @@
+'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: '/gitlab-org/gitlab-qa/-/merge_requests/1/diffs_batch.json',
+ headers: {
+ Accept: '*/*',
+ },
+ query: 'page=0',
+ },
+ },
+};
+
+exports.Diffs = Diffs;
diff --git a/spec/contracts/consumer/fixtures/discussions.fixture.js b/spec/contracts/consumer/fixtures/discussions.fixture.js
new file mode 100644
index 00000000000..c28b9bdd505
--- /dev/null
+++ b/spec/contracts/consumer/fixtures/discussions.fixture.js
@@ -0,0 +1,85 @@
+'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: '/gitlab-org/gitlab-qa/-/merge_requests/1/discussions.json',
+ headers: {
+ Accept: '*/*',
+ },
+ },
+ },
+};
+
+exports.Discussions = Discussions;
diff --git a/spec/contracts/consumer/fixtures/metadata.fixture.js b/spec/contracts/consumer/fixtures/metadata.fixture.js
new file mode 100644
index 00000000000..3fca6cf9181
--- /dev/null
+++ b/spec/contracts/consumer/fixtures/metadata.fixture.js
@@ -0,0 +1,96 @@
+'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: '/gitlab-org/gitlab-qa/-/merge_requests/1/diffs_metadata.json',
+ headers: {
+ Accept: '*/*',
+ },
+ },
+ },
+};
+
+exports.Metadata = Metadata;
diff --git a/spec/contracts/consumer/package.json b/spec/contracts/consumer/package.json
new file mode 100644
index 00000000000..6a427ff8a7b
--- /dev/null
+++ b/spec/contracts/consumer/package.json
@@ -0,0 +1,17 @@
+{
+ "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 --runInBand"
+ }
+}
diff --git a/spec/contracts/consumer/specs/diffs.spec.js b/spec/contracts/consumer/specs/diffs.spec.js
new file mode 100644
index 00000000000..b812461cb69
--- /dev/null
+++ b/spec/contracts/consumer/specs/diffs.spec.js
@@ -0,0 +1,36 @@
+'use strict';
+
+const { pactWith } = require('jest-pact');
+
+const { Diffs } = require('../fixtures/diffs.fixture');
+const { getDiffs } = require('../endpoints/merge_requests');
+
+pactWith(
+ {
+ consumer: 'Merge Request Page',
+ provider: 'Merge Request Diffs Endpoint',
+ log: '../logs/consumer.log',
+ dir: '../contracts',
+ },
+
+ (provider) => {
+ describe('Diffs Endpoint', () => {
+ beforeEach(() => {
+ const interaction = {
+ state: 'a merge request with diffs exists',
+ ...Diffs.request,
+ willRespondWith: Diffs.success,
+ };
+ provider.addInteraction(interaction);
+ });
+
+ it('return a successful body', () => {
+ return getDiffs({
+ url: provider.mockService.baseUrl,
+ }).then((diffs) => {
+ expect(diffs).toEqual(Diffs.body);
+ });
+ });
+ });
+ },
+);
diff --git a/spec/contracts/consumer/specs/discussions.spec.js b/spec/contracts/consumer/specs/discussions.spec.js
new file mode 100644
index 00000000000..304c240f7d3
--- /dev/null
+++ b/spec/contracts/consumer/specs/discussions.spec.js
@@ -0,0 +1,36 @@
+'use strict';
+
+const { pactWith } = require('jest-pact');
+
+const { Discussions } = require('../fixtures/discussions.fixture');
+const { getDiscussions } = require('../endpoints/merge_requests');
+
+pactWith(
+ {
+ consumer: 'Merge Request Page',
+ provider: 'Merge Request Discussions Endpoint',
+ log: '../logs/consumer.log',
+ dir: '../contracts',
+ },
+
+ (provider) => {
+ describe('Discussions Endpoint', () => {
+ beforeEach(() => {
+ const interaction = {
+ state: 'a merge request with discussions exists',
+ ...Discussions.request,
+ willRespondWith: Discussions.success,
+ };
+ provider.addInteraction(interaction);
+ });
+
+ it('return a successful body', () => {
+ return getDiscussions({
+ url: provider.mockService.baseUrl,
+ }).then((discussions) => {
+ expect(discussions).toEqual(Discussions.body);
+ });
+ });
+ });
+ },
+);
diff --git a/spec/contracts/consumer/specs/metadata.spec.js b/spec/contracts/consumer/specs/metadata.spec.js
new file mode 100644
index 00000000000..c49d4c354b1
--- /dev/null
+++ b/spec/contracts/consumer/specs/metadata.spec.js
@@ -0,0 +1,36 @@
+'use strict';
+
+const { pactWith } = require('jest-pact');
+
+const { Metadata } = require('../fixtures/metadata.fixture');
+const { getMetadata } = require('../endpoints/merge_requests');
+
+pactWith(
+ {
+ consumer: 'Merge Request Page',
+ provider: 'Merge Request Metadata Endpoint',
+ log: '../logs/consumer.log',
+ dir: '../contracts',
+ },
+
+ (provider) => {
+ describe('Metadata Endpoint', () => {
+ beforeEach(() => {
+ const interaction = {
+ state: 'a merge request exists',
+ ...Metadata.request,
+ willRespondWith: Metadata.success,
+ };
+ provider.addInteraction(interaction);
+ });
+
+ it('return a successful body', () => {
+ return getMetadata({
+ url: provider.mockService.baseUrl,
+ }).then((metadata) => {
+ expect(metadata).toEqual(Metadata.body);
+ });
+ });
+ });
+ },
+);
diff --git a/spec/contracts/contracts/merge_request_page-merge_request_diffs_endpoint.json b/spec/contracts/contracts/merge_request_page-merge_request_diffs_endpoint.json
new file mode 100644
index 00000000000..2f097d8eb24
--- /dev/null
+++ b/spec/contracts/contracts/merge_request_page-merge_request_diffs_endpoint.json
@@ -0,0 +1,229 @@
+{
+ "consumer": {
+ "name": "Merge Request Page"
+ },
+ "provider": {
+ "name": "Merge Request Diffs Endpoint"
+ },
+ "interactions": [
+ {
+ "description": "a request for diff lines",
+ "providerState": "a merge request with diffs exists",
+ "request": {
+ "method": "GET",
+ "path": "/gitlab-org/gitlab-qa/-/merge_requests/1/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"
+ }
+ }
+}
diff --git a/spec/contracts/contracts/merge_request_page-merge_request_discussions_endpoint.json b/spec/contracts/contracts/merge_request_page-merge_request_discussions_endpoint.json
new file mode 100644
index 00000000000..819d95276b3
--- /dev/null
+++ b/spec/contracts/contracts/merge_request_page-merge_request_discussions_endpoint.json
@@ -0,0 +1,236 @@
+{
+ "consumer": {
+ "name": "Merge Request Page"
+ },
+ "provider": {
+ "name": "Merge Request Discussions Endpoint"
+ },
+ "interactions": [
+ {
+ "description": "a request for discussions",
+ "providerState": "a merge request with discussions exists",
+ "request": {
+ "method": "GET",
+ "path": "/gitlab-org/gitlab-qa/-/merge_requests/1/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"
+ }
+ }
+}
diff --git a/spec/contracts/contracts/merge_request_page-merge_request_metadata_endpoint.json b/spec/contracts/contracts/merge_request_page-merge_request_metadata_endpoint.json
new file mode 100644
index 00000000000..eb22b7d2e3c
--- /dev/null
+++ b/spec/contracts/contracts/merge_request_page-merge_request_metadata_endpoint.json
@@ -0,0 +1,223 @@
+{
+ "consumer": {
+ "name": "Merge Request Page"
+ },
+ "provider": {
+ "name": "Merge Request Metadata Endpoint"
+ },
+ "interactions": [
+ {
+ "description": "a request for Metadata",
+ "providerState": "a merge request exists",
+ "request": {
+ "method": "GET",
+ "path": "/gitlab-org/gitlab-qa/-/merge_requests/1/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"
+ }
+ }
+}
diff --git a/spec/contracts/provider/environments/test.rb b/spec/contracts/provider/environments/test.rb
new file mode 100644
index 00000000000..6efb19508d8
--- /dev/null
+++ b/spec/contracts/provider/environments/test.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+module Provider
+ module Environments
+ class Test
+ def self.app
+ Rack::Builder.app do
+ map "/" do
+ run Gitlab::Application
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/spec/contracts/provider/helpers/users_helper.rb b/spec/contracts/provider/helpers/users_helper.rb
new file mode 100644
index 00000000000..1982bd9cfd2
--- /dev/null
+++ b/spec/contracts/provider/helpers/users_helper.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+module Provider
+ module UsersHelper
+ CONTRACT_USER_NAME = "Contract Test User"
+ end
+end
diff --git a/spec/contracts/provider/spec_helper.rb b/spec/contracts/provider/spec_helper.rb
new file mode 100644
index 00000000000..6009d6524e1
--- /dev/null
+++ b/spec/contracts/provider/spec_helper.rb
@@ -0,0 +1,39 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require 'zeitwerk'
+require_relative 'helpers/users_helper'
+
+RSpec.configure do |config|
+ config.include Devise::Test::IntegrationHelpers
+ config.include FactoryBot::Syntax::Methods
+
+ config.before do
+ user = create(:user, name: Provider::UsersHelper::CONTRACT_USER_NAME).tap do |user|
+ user.current_sign_in_at = Time.current
+ end
+
+ sign_in user
+ end
+end
+
+Pact.configure do |config|
+ config.include FactoryBot::Syntax::Methods
+end
+
+module SpecHelper
+ require_relative '../../../config/bundler_setup'
+ Bundler.require(:default)
+
+ root = File.expand_path('../', __dir__)
+
+ loader = Zeitwerk::Loader.new
+ loader.push_dir(root)
+
+ loader.ignore("#{root}/consumer")
+ loader.ignore("#{root}/contracts")
+
+ loader.collapse("#{root}/provider/spec")
+
+ loader.setup
+end
diff --git a/spec/contracts/provider/specs/diffs_helper.rb b/spec/contracts/provider/specs/diffs_helper.rb
new file mode 100644
index 00000000000..24bdd00dbae
--- /dev/null
+++ b/spec/contracts/provider/specs/diffs_helper.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+require_relative '../spec_helper'
+require_relative '../states/diffs_state'
+
+module Provider
+ module DiffsHelper
+ Pact.service_provider "Merge Request Diffs Endpoint" do
+ app { Environments::Test.app }
+
+ honours_pact_with 'Merge Request Page' do
+ pact_uri '../contracts/merge_request_page-merge_request_diffs_endpoint.json'
+ end
+ end
+ end
+end
diff --git a/spec/contracts/provider/specs/discussions_helper.rb b/spec/contracts/provider/specs/discussions_helper.rb
new file mode 100644
index 00000000000..135ccf48276
--- /dev/null
+++ b/spec/contracts/provider/specs/discussions_helper.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+require_relative '../spec_helper'
+require_relative '../states/discussions_state'
+
+module Provider
+ module DiscussionsHelper
+ Pact.service_provider "Merge Request Discussions Endpoint" do
+ app { Environments::Test.app }
+
+ honours_pact_with 'Merge Request Page' do
+ pact_uri '../contracts/merge_request_page-merge_request_discussions_endpoint.json'
+ end
+ end
+ end
+end
diff --git a/spec/contracts/provider/specs/metadata_helper.rb b/spec/contracts/provider/specs/metadata_helper.rb
new file mode 100644
index 00000000000..e73b993a31a
--- /dev/null
+++ b/spec/contracts/provider/specs/metadata_helper.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+require_relative '../spec_helper'
+require_relative '../states/metadata_state'
+
+module Provider
+ module MetadataHelper
+ Pact.service_provider "Merge Request Metadata Endpoint" do
+ app { Environments::Test.app }
+
+ honours_pact_with 'Merge Request Page' do
+ pact_uri '../contracts/merge_request_page-merge_request_metadata_endpoint.json'
+ end
+ end
+ end
+end
diff --git a/spec/contracts/provider/states/diffs_state.rb b/spec/contracts/provider/states/diffs_state.rb
new file mode 100644
index 00000000000..d959cde5f5e
--- /dev/null
+++ b/spec/contracts/provider/states/diffs_state.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+Pact.provider_states_for "Merge Request Page" do
+ provider_state "a merge request with diffs exists" do
+ set_up do
+ user = User.find_by(name: Provider::UsersHelper::CONTRACT_USER_NAME)
+ namespace = create(:namespace, name: 'gitlab-org')
+ project = create(:project, :custom_repo, name: 'gitlab-qa', namespace: namespace, files: {})
+
+ project.add_maintainer(user)
+
+ merge_request = create(:merge_request_with_multiple_diffs, source_project: project)
+ merge_request_diff = create(:merge_request_diff, merge_request: merge_request)
+
+ create(:merge_request_diff_file, :new_file, merge_request_diff: merge_request_diff)
+ end
+ end
+end
diff --git a/spec/contracts/provider/states/discussions_state.rb b/spec/contracts/provider/states/discussions_state.rb
new file mode 100644
index 00000000000..ddbcf80f2c8
--- /dev/null
+++ b/spec/contracts/provider/states/discussions_state.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+Pact.provider_states_for "Merge Request Page" do
+ provider_state "a merge request with discussions exists" do
+ set_up do
+ user = User.find_by(name: Provider::UsersHelper::CONTRACT_USER_NAME)
+ namespace = create(:namespace, name: 'gitlab-org')
+ project = create(:project, name: 'gitlab-qa', namespace: namespace)
+
+ project.add_maintainer(user)
+
+ merge_request = create(:merge_request_with_diffs, source_project: project, author: user)
+
+ create(:discussion_note_on_merge_request, noteable: merge_request, project: project, author: user)
+ end
+ end
+end
diff --git a/spec/contracts/provider/states/metadata_state.rb b/spec/contracts/provider/states/metadata_state.rb
new file mode 100644
index 00000000000..59b290ce2fe
--- /dev/null
+++ b/spec/contracts/provider/states/metadata_state.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+Pact.provider_states_for "Merge Request Page" do
+ provider_state "a merge request exists" do
+ set_up do
+ user = User.find_by(name: Provider::UsersHelper::CONTRACT_USER_NAME)
+ namespace = create(:namespace, name: 'gitlab-org')
+ project = create(:project, :custom_repo, name: 'gitlab-qa', namespace: namespace, files: {})
+
+ project.add_maintainer(user)
+
+ merge_request = create(:merge_request, source_project: project)
+ merge_request_diff = create(:merge_request_diff, merge_request: merge_request)
+
+ create(:merge_request_diff_file, :new_file, merge_request_diff: merge_request_diff)
+ end
+ end
+end