Commit cf3477d2 authored by Phil Hughes's avatar Phil Hughes Committed by Mayra Cabrera

Move core merge request widget state into GraphQL

This moves the main core merge request widget state into
GraphQL.
This is part of a bigger effort to eventually have the
whole merge request widget in GraphQL.

Note: This is behind a feature flag for now.

Closes https://gitlab.com/gitlab-org/gitlab/-/issues/235717
parent f174031b
...@@ -55,13 +55,15 @@ export default { ...@@ -55,13 +55,15 @@ export default {
}, },
methods: { methods: {
removeWipMutation() { removeWipMutation() {
const { mergeRequestQueryVariables } = this;
this.isMakingRequest = true; this.isMakingRequest = true;
this.$apollo this.$apollo
.mutate({ .mutate({
mutation: removeWipMutation, mutation: removeWipMutation,
variables: { variables: {
...this.mergeRequestQueryVariables, ...mergeRequestQueryVariables,
wip: false, wip: false,
}, },
update( update(
...@@ -83,14 +85,14 @@ export default { ...@@ -83,14 +85,14 @@ export default {
const data = store.readQuery({ const data = store.readQuery({
query: getStateQuery, query: getStateQuery,
variables: this.mergeRequestQueryVariables, variables: mergeRequestQueryVariables,
}); });
data.project.mergeRequest.workInProgress = workInProgress; data.project.mergeRequest.workInProgress = workInProgress;
data.project.mergeRequest.title = title; data.project.mergeRequest.title = title;
store.writeQuery({ store.writeQuery({
query: getStateQuery, query: getStateQuery,
data, data,
variables: this.mergeRequestQueryVariables, variables: mergeRequestQueryVariables,
}); });
}, },
optimisticResponse: { optimisticResponse: {
......
...@@ -96,12 +96,11 @@ export default { ...@@ -96,12 +96,11 @@ export default {
variables() { variables() {
return this.mergeRequestQueryVariables; return this.mergeRequestQueryVariables;
}, },
result({ result({ data: { project } }) {
data: { if (project) {
project: { mergeRequest }, this.mr.setGraphqlData(project);
}, this.loading = false;
}) { }
this.mr.setGraphqlData(mergeRequest);
}, },
}, },
}, },
...@@ -120,9 +119,17 @@ export default { ...@@ -120,9 +119,17 @@ export default {
mr: store, mr: store,
state: store && store.state, state: store && store.state,
service: store && this.createService(store), service: store && this.createService(store),
loading: true,
}; };
}, },
computed: { computed: {
isLoaded() {
if (window.gon?.features?.mergeRequestWidgetGraphql) {
return !this.loading;
}
return this.mr;
},
shouldRenderApprovals() { shouldRenderApprovals() {
return this.mr.state !== 'nothingToMerge'; return this.mr.state !== 'nothingToMerge';
}, },
...@@ -409,7 +416,7 @@ export default { ...@@ -409,7 +416,7 @@ export default {
}; };
</script> </script>
<template> <template>
<div v-if="mr" class="mr-state-widget gl-mt-3"> <div v-if="isLoaded" class="mr-state-widget gl-mt-3">
<mr-widget-header :mr="mr" /> <mr-widget-header :mr="mr" />
<mr-widget-suggest-pipeline <mr-widget-suggest-pipeline
v-if="shouldSuggestPipelines" v-if="shouldSuggestPipelines"
......
query getState($projectPath: ID!, $iid: String!) { query getState($projectPath: ID!, $iid: String!) {
project(fullPath: $projectPath) { project(fullPath: $projectPath) {
archived
onlyAllowMergeIfPipelineSucceeds
mergeRequest(iid: $iid) { mergeRequest(iid: $iid) {
title autoMergeEnabled
commitCount
conflicts
diffHeadSha
mergeError
mergeStatus
mergeableDiscussionsState
pipelines(first: 1) {
nodes {
status
}
}
shouldBeRebased
sourceBranchExists
targetBranchExists
userPermissions {
canMerge
}
workInProgress workInProgress
} }
} }
......
...@@ -43,12 +43,10 @@ export default class MergeRequestStore { ...@@ -43,12 +43,10 @@ export default class MergeRequestStore {
this.conflictsDocsPath = data.conflicts_docs_path; this.conflictsDocsPath = data.conflicts_docs_path;
this.mergeRequestPipelinesHelpPath = data.merge_request_pipelines_docs_path; this.mergeRequestPipelinesHelpPath = data.merge_request_pipelines_docs_path;
this.mergeTrainWhenPipelineSucceedsDocsPath = data.merge_train_when_pipeline_succeeds_docs_path; this.mergeTrainWhenPipelineSucceedsDocsPath = data.merge_train_when_pipeline_succeeds_docs_path;
this.mergeStatus = data.merge_status;
this.commitMessage = data.default_merge_commit_message; this.commitMessage = data.default_merge_commit_message;
this.shortMergeCommitSha = data.short_merged_commit_sha; this.shortMergeCommitSha = data.short_merged_commit_sha;
this.mergeCommitSha = data.merged_commit_sha; this.mergeCommitSha = data.merged_commit_sha;
this.commitMessageWithDescription = data.default_merge_commit_message_with_description; this.commitMessageWithDescription = data.default_merge_commit_message_with_description;
this.commitsCount = data.commits_count;
this.divergedCommitsCount = data.diverged_commits_count; this.divergedCommitsCount = data.diverged_commits_count;
this.pipeline = data.pipeline || {}; this.pipeline = data.pipeline || {};
this.pipelineCoverageDelta = data.pipeline_coverage_delta; this.pipelineCoverageDelta = data.pipeline_coverage_delta;
...@@ -61,9 +59,6 @@ export default class MergeRequestStore { ...@@ -61,9 +59,6 @@ export default class MergeRequestStore {
this.rebaseInProgress = data.rebase_in_progress; this.rebaseInProgress = data.rebase_in_progress;
this.mergeRequestDiffsPath = data.diffs_path; this.mergeRequestDiffsPath = data.diffs_path;
this.approvalsWidgetType = data.approvals_widget_type; this.approvalsWidgetType = data.approvals_widget_type;
this.projectArchived = data.project_archived;
this.branchMissing = data.branch_missing;
this.hasConflicts = data.has_conflicts;
if (data.issues_links) { if (data.issues_links) {
const links = data.issues_links; const links = data.issues_links;
...@@ -81,25 +76,18 @@ export default class MergeRequestStore { ...@@ -81,25 +76,18 @@ export default class MergeRequestStore {
this.setToAutoMergeBy = MergeRequestStore.formatUserObject(data.merge_user || {}); this.setToAutoMergeBy = MergeRequestStore.formatUserObject(data.merge_user || {});
this.mergeUserId = data.merge_user_id; this.mergeUserId = data.merge_user_id;
this.currentUserId = gon.current_user_id; this.currentUserId = gon.current_user_id;
this.mergeError = data.merge_error;
this.sourceBranchRemoved = !data.source_branch_exists; this.sourceBranchRemoved = !data.source_branch_exists;
this.shouldRemoveSourceBranch = data.remove_source_branch || false; this.shouldRemoveSourceBranch = data.remove_source_branch || false;
this.onlyAllowMergeIfPipelineSucceeds = data.only_allow_merge_if_pipeline_succeeds || false;
this.autoMergeEnabled = Boolean(data.auto_merge_enabled);
this.autoMergeStrategy = data.auto_merge_strategy; this.autoMergeStrategy = data.auto_merge_strategy;
this.availableAutoMergeStrategies = data.available_auto_merge_strategies; this.availableAutoMergeStrategies = data.available_auto_merge_strategies;
this.preferredAutoMergeStrategy = MergeRequestStore.getPreferredAutoMergeStrategy( this.preferredAutoMergeStrategy = MergeRequestStore.getPreferredAutoMergeStrategy(
this.availableAutoMergeStrategies, this.availableAutoMergeStrategies,
); );
this.ffOnlyEnabled = data.ff_only_enabled; this.ffOnlyEnabled = data.ff_only_enabled;
this.shouldBeRebased = Boolean(data.should_be_rebased);
this.isRemovingSourceBranch = this.isRemovingSourceBranch || false; this.isRemovingSourceBranch = this.isRemovingSourceBranch || false;
this.mergeRequestState = data.state; this.mergeRequestState = data.state;
this.isOpen = this.mergeRequestState === 'opened'; this.isOpen = this.mergeRequestState === 'opened';
this.hasMergeableDiscussionsState = data.mergeable_discussions_state === false;
this.isSHAMismatch = this.sha !== data.diff_head_sha;
this.latestSHA = data.diff_head_sha; this.latestSHA = data.diff_head_sha;
this.canBeMerged = data.can_be_merged || false;
this.isMergeAllowed = data.mergeable || false; this.isMergeAllowed = data.mergeable || false;
this.mergeOngoing = data.merge_ongoing; this.mergeOngoing = data.merge_ongoing;
this.allowCollaboration = data.allow_collaboration; this.allowCollaboration = data.allow_collaboration;
...@@ -109,7 +97,6 @@ export default class MergeRequestStore { ...@@ -109,7 +97,6 @@ export default class MergeRequestStore {
// CI related // CI related
this.hasCI = data.has_ci; this.hasCI = data.has_ci;
this.ciStatus = data.ci_status; this.ciStatus = data.ci_status;
this.isPipelineFailed = this.ciStatus === 'failed' || this.ciStatus === 'canceled';
this.isPipelinePassing = this.isPipelinePassing =
this.ciStatus === 'success' || this.ciStatus === 'success-with-warnings'; this.ciStatus === 'success' || this.ciStatus === 'success-with-warnings';
this.isPipelineSkipped = this.ciStatus === 'skipped'; this.isPipelineSkipped = this.ciStatus === 'skipped';
...@@ -134,11 +121,24 @@ export default class MergeRequestStore { ...@@ -134,11 +121,24 @@ export default class MergeRequestStore {
this.removeWIPPath = data.remove_wip_path; this.removeWIPPath = data.remove_wip_path;
this.createIssueToResolveDiscussionsPath = data.create_issue_to_resolve_discussions_path; this.createIssueToResolveDiscussionsPath = data.create_issue_to_resolve_discussions_path;
this.mergePath = data.merge_path; this.mergePath = data.merge_path;
this.canMerge = Boolean(data.merge_path);
this.mergeCommitPath = data.merged_commit_path; this.mergeCommitPath = data.merged_commit_path;
this.canPushToSourceBranch = data.can_push_to_source_branch; this.canPushToSourceBranch = data.can_push_to_source_branch;
if (data.work_in_progress !== undefined) { if (!window.gon?.features?.mergeRequestWidgetGraphql) {
this.autoMergeEnabled = Boolean(data.auto_merge_enabled);
this.canBeMerged = data.can_be_merged || false;
this.canMerge = Boolean(data.merge_path);
this.commitsCount = data.commits_count;
this.branchMissing = data.branch_missing;
this.hasConflicts = data.has_conflicts;
this.hasMergeableDiscussionsState = data.mergeable_discussions_state === false;
this.isPipelineFailed = this.ciStatus === 'failed' || this.ciStatus === 'canceled';
this.mergeError = data.merge_error;
this.mergeStatus = data.merge_status;
this.onlyAllowMergeIfPipelineSucceeds = data.only_allow_merge_if_pipeline_succeeds || false;
this.projectArchived = data.project_archived;
this.isSHAMismatch = this.sha !== data.diff_head_sha;
this.shouldBeRebased = Boolean(data.should_be_rebased);
this.workInProgress = data.work_in_progress; this.workInProgress = data.work_in_progress;
} }
...@@ -155,8 +155,27 @@ export default class MergeRequestStore { ...@@ -155,8 +155,27 @@ export default class MergeRequestStore {
this.setState(); this.setState();
} }
setGraphqlData(data) { setGraphqlData(project) {
this.workInProgress = data.workInProgress; const { mergeRequest } = project;
const pipeline = mergeRequest.pipelines?.nodes?.[0];
this.projectArchived = project.archived;
this.onlyAllowMergeIfPipelineSucceeds = project.onlyAllowMergeIfPipelineSucceeds;
this.autoMergeEnabled = mergeRequest.autoMergeEnabled;
this.canBeMerged = mergeRequest.mergeStatus === 'can_be_merged';
this.canMerge = mergeRequest.userPermissions.canMerge;
this.ciStatus = pipeline?.status.toLowerCase();
this.commitsCount = mergeRequest.commitCount;
this.branchMissing = !mergeRequest.sourceBranchExists || !mergeRequest.targetBranchExists;
this.hasConflicts = mergeRequest.conflicts;
this.hasMergeableDiscussionsState = mergeRequest.mergeableDiscussionsState === false;
this.mergeError = mergeRequest.mergeError;
this.mergeStatus = mergeRequest.mergeStatus;
this.isPipelineFailed = this.ciStatus === 'failed' || this.ciStatus === 'canceled';
this.isSHAMismatch = this.sha !== mergeRequest.diffHeadSha;
this.shouldBeRebased = mergeRequest.shouldBeRebased;
this.workInProgress = mergeRequest.workInProgress;
this.setState(); this.setState();
} }
......
...@@ -7,6 +7,8 @@ module Resolvers ...@@ -7,6 +7,8 @@ module Resolvers
alias_method :merge_request, :object alias_method :merge_request, :object
def resolve(**args) def resolve(**args)
return unless project
resolve_pipelines(project, args) resolve_pipelines(project, args)
.merge(merge_request.all_pipelines) .merge(merge_request.all_pipelines)
end end
......
...@@ -80,7 +80,7 @@ module Types ...@@ -80,7 +80,7 @@ module Types
description: 'Error message due to a merge error' description: 'Error message due to a merge error'
field :allow_collaboration, GraphQL::BOOLEAN_TYPE, null: true, field :allow_collaboration, GraphQL::BOOLEAN_TYPE, null: true,
description: 'Indicates if members of the target project can push to the fork' description: 'Indicates if members of the target project can push to the fork'
field :should_be_rebased, GraphQL::BOOLEAN_TYPE, method: :should_be_rebased?, null: false, field :should_be_rebased, GraphQL::BOOLEAN_TYPE, method: :should_be_rebased?, null: false, calls_gitaly: true,
description: 'Indicates if the merge request will be rebased' description: 'Indicates if the merge request will be rebased'
field :rebase_commit_sha, GraphQL::STRING_TYPE, null: true, field :rebase_commit_sha, GraphQL::STRING_TYPE, null: true,
description: 'Rebase commit SHA of the merge request' description: 'Rebase commit SHA of the merge request'
...@@ -113,6 +113,7 @@ module Types ...@@ -113,6 +113,7 @@ module Types
field :head_pipeline, Types::Ci::PipelineType, null: true, method: :actual_head_pipeline, field :head_pipeline, Types::Ci::PipelineType, null: true, method: :actual_head_pipeline,
description: 'The pipeline running on the branch HEAD of the merge request' description: 'The pipeline running on the branch HEAD of the merge request'
field :pipelines, Types::Ci::PipelineType.connection_type, field :pipelines, Types::Ci::PipelineType.connection_type,
null: true,
description: 'Pipelines for the merge request', description: 'Pipelines for the merge request',
resolver: Resolvers::MergeRequestPipelinesResolver resolver: Resolvers::MergeRequestPipelinesResolver
...@@ -146,6 +147,10 @@ module Types ...@@ -146,6 +147,10 @@ module Types
description: Types::TaskCompletionStatus.description description: Types::TaskCompletionStatus.description
field :commit_count, GraphQL::INT_TYPE, null: true, field :commit_count, GraphQL::INT_TYPE, null: true,
description: 'Number of commits in the merge request' description: 'Number of commits in the merge request'
field :conflicts, GraphQL::BOOLEAN_TYPE, null: false, method: :cannot_be_merged?,
description: 'Indicates if the merge request has conflicts'
field :auto_merge_enabled, GraphQL::BOOLEAN_TYPE, null: false,
description: 'Indicates if auto merge is enabled for the merge request'
def diff_stats(path: nil) def diff_stats(path: nil)
stats = Array.wrap(object.diff_stats&.to_a) stats = Array.wrap(object.diff_stats&.to_a)
......
...@@ -18,6 +18,10 @@ module Types ...@@ -18,6 +18,10 @@ module Types
PERMISSION_FIELDS.each do |field_name| PERMISSION_FIELDS.each do |field_name|
permission_field field_name, method: :"can_#{field_name}?", calls_gitaly: true permission_field field_name, method: :"can_#{field_name}?", calls_gitaly: true
end end
permission_field :can_merge, calls_gitaly: true, resolve: -> (object, args, context) do
object.can_be_merged_by?(context[:current_user])
end
end end
end end
end end
...@@ -9272,11 +9272,21 @@ type MergeRequest implements CurrentUserTodos & Noteable { ...@@ -9272,11 +9272,21 @@ type MergeRequest implements CurrentUserTodos & Noteable {
""" """
author: User author: User
"""
Indicates if auto merge is enabled for the merge request
"""
autoMergeEnabled: Boolean!
""" """
Number of commits in the merge request Number of commits in the merge request
""" """
commitCount: Int commitCount: Int
"""
Indicates if the merge request has conflicts
"""
conflicts: Boolean!
""" """
Timestamp of when the merge request was created Timestamp of when the merge request was created
""" """
...@@ -9570,7 +9580,7 @@ type MergeRequest implements CurrentUserTodos & Noteable { ...@@ -9570,7 +9580,7 @@ type MergeRequest implements CurrentUserTodos & Noteable {
Filter pipelines by their status Filter pipelines by their status
""" """
status: PipelineStatusEnum status: PipelineStatusEnum
): PipelineConnection! ): PipelineConnection
""" """
Alias for target_project Alias for target_project
...@@ -9827,6 +9837,11 @@ type MergeRequestPermissions { ...@@ -9827,6 +9837,11 @@ type MergeRequestPermissions {
""" """
adminMergeRequest: Boolean! adminMergeRequest: Boolean!
"""
Indicates the user can perform `can_merge` on this resource
"""
canMerge: Boolean!
""" """
Indicates the user can perform `cherry_pick_on_current_merge_request` on this resource Indicates the user can perform `cherry_pick_on_current_merge_request` on this resource
""" """
......
...@@ -25712,6 +25712,24 @@ ...@@ -25712,6 +25712,24 @@
"isDeprecated": false, "isDeprecated": false,
"deprecationReason": null "deprecationReason": null
}, },
{
"name": "autoMergeEnabled",
"description": "Indicates if auto merge is enabled for the merge request",
"args": [
],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "Boolean",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{ {
"name": "commitCount", "name": "commitCount",
"description": "Number of commits in the merge request", "description": "Number of commits in the merge request",
...@@ -25726,6 +25744,24 @@ ...@@ -25726,6 +25744,24 @@
"isDeprecated": false, "isDeprecated": false,
"deprecationReason": null "deprecationReason": null
}, },
{
"name": "conflicts",
"description": "Indicates if the merge request has conflicts",
"args": [
],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "Boolean",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{ {
"name": "createdAt", "name": "createdAt",
"description": "Timestamp of when the merge request was created", "description": "Timestamp of when the merge request was created",
...@@ -26466,13 +26502,9 @@ ...@@ -26466,13 +26502,9 @@
} }
], ],
"type": { "type": {
"kind": "NON_NULL", "kind": "OBJECT",
"name": null, "name": "PipelineConnection",
"ofType": { "ofType": null
"kind": "OBJECT",
"name": "PipelineConnection",
"ofType": null
}
}, },
"isDeprecated": false, "isDeprecated": false,
"deprecationReason": null "deprecationReason": null
...@@ -27304,6 +27336,24 @@ ...@@ -27304,6 +27336,24 @@
"isDeprecated": false, "isDeprecated": false,
"deprecationReason": null "deprecationReason": null
}, },
{
"name": "canMerge",
"description": "Indicates the user can perform `can_merge` on this resource",
"args": [
],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "Boolean",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{ {
"name": "cherryPickOnCurrentMergeRequest", "name": "cherryPickOnCurrentMergeRequest",
"description": "Indicates the user can perform `cherry_pick_on_current_merge_request` on this resource", "description": "Indicates the user can perform `cherry_pick_on_current_merge_request` on this resource",
...@@ -1385,7 +1385,9 @@ Autogenerated return type of MarkAsSpamSnippet ...@@ -1385,7 +1385,9 @@ Autogenerated return type of MarkAsSpamSnippet
| `allowCollaboration` | Boolean | Indicates if members of the target project can push to the fork | | `allowCollaboration` | Boolean | Indicates if members of the target project can push to the fork |
| `approved` | Boolean! | Indicates if the merge request has all the required approvals. Returns true if no required approvals are configured. | | `approved` | Boolean! | Indicates if the merge request has all the required approvals. Returns true if no required approvals are configured. |
| `author` | User | User who created this merge request | | `author` | User | User who created this merge request |
| `autoMergeEnabled` | Boolean! | Indicates if auto merge is enabled for the merge request |
| `commitCount` | Int | Number of commits in the merge request | | `commitCount` | Int | Number of commits in the merge request |
| `conflicts` | Boolean! | Indicates if the merge request has conflicts |
| `createdAt` | Time! | Timestamp of when the merge request was created | | `createdAt` | Time! | Timestamp of when the merge request was created |
| `defaultMergeCommitMessage` | String | Default merge commit message of the merge request | | `defaultMergeCommitMessage` | String | Default merge commit message of the merge request |
| `description` | String | Description of the merge request (Markdown rendered as HTML for caching) | | `description` | String | Description of the merge request (Markdown rendered as HTML for caching) |
...@@ -1456,6 +1458,7 @@ Check permissions for the current user on a merge request ...@@ -1456,6 +1458,7 @@ Check permissions for the current user on a merge request
| Name | Type | Description | | Name | Type | Description |
| --- | ---- | ---------- | | --- | ---- | ---------- |
| `adminMergeRequest` | Boolean! | Indicates the user can perform `admin_merge_request` on this resource | | `adminMergeRequest` | Boolean! | Indicates the user can perform `admin_merge_request` on this resource |
| `canMerge` | Boolean! | Indicates the user can perform `can_merge` on this resource |
| `cherryPickOnCurrentMergeRequest` | Boolean! | Indicates the user can perform `cherry_pick_on_current_merge_request` on this resource | | `cherryPickOnCurrentMergeRequest` | Boolean! | Indicates the user can perform `cherry_pick_on_current_merge_request` on this resource |
| `createNote` | Boolean! | Indicates the user can perform `create_note` on this resource | | `createNote` | Boolean! | Indicates the user can perform `create_note` on this resource |
| `pushToSourceBranch` | Boolean! | Indicates the user can perform `push_to_source_branch` on this resource | | `pushToSourceBranch` | Boolean! | Indicates the user can perform `push_to_source_branch` on this resource |
......
...@@ -234,7 +234,7 @@ export default { ...@@ -234,7 +234,7 @@ export default {
}; };
</script> </script>
<template> <template>
<div v-if="mr" class="mr-state-widget gl-mt-3"> <div v-if="isLoaded" class="mr-state-widget gl-mt-3">
<mr-widget-header :mr="mr" /> <mr-widget-header :mr="mr" />
<mr-widget-suggest-pipeline <mr-widget-suggest-pipeline
v-if="shouldSuggestPipelines" v-if="shouldSuggestPipelines"
......
...@@ -110,6 +110,7 @@ describe('ee merge request widget options', () => { ...@@ -110,6 +110,7 @@ describe('ee merge request widget options', () => {
mock.onGet(VULNERABILITY_FEEDBACK_ENDPOINT).reply(200, []); mock.onGet(VULNERABILITY_FEEDBACK_ENDPOINT).reply(200, []);
vm = mountComponent(Component, { mrData: gl.mrWidgetData }); vm = mountComponent(Component, { mrData: gl.mrWidgetData });
vm.loading = false;
expect( expect(
findSecurityWidget() findSecurityWidget()
......
...@@ -29,4 +29,11 @@ RSpec.describe Resolvers::MergeRequestPipelinesResolver do ...@@ -29,4 +29,11 @@ RSpec.describe Resolvers::MergeRequestPipelinesResolver do
it 'resolves only MRs for the passed merge request' do it 'resolves only MRs for the passed merge request' do
expect(resolve_pipelines).to contain_exactly(pipeline) expect(resolve_pipelines).to contain_exactly(pipeline)
end end
describe 'with archived project' do
let(:archived_project) { create(:project, :archived) }
let(:merge_request) { create(:merge_request, source_project: archived_project) }
it { expect(resolve_pipelines).not_to contain_exactly(pipeline) }
end
end end
...@@ -27,6 +27,7 @@ RSpec.describe GitlabSchema.types['MergeRequest'] do ...@@ -27,6 +27,7 @@ RSpec.describe GitlabSchema.types['MergeRequest'] do
upvotes downvotes head_pipeline pipelines task_completion_status upvotes downvotes head_pipeline pipelines task_completion_status
milestone assignees participants subscribed labels discussion_locked time_estimate milestone assignees participants subscribed labels discussion_locked time_estimate
total_time_spent reference author merged_at commit_count current_user_todos total_time_spent reference author merged_at commit_count current_user_todos
conflicts auto_merge_enabled
] ]
if Gitlab.ee? if Gitlab.ee?
......
...@@ -7,7 +7,8 @@ RSpec.describe Types::PermissionTypes::MergeRequest do ...@@ -7,7 +7,8 @@ RSpec.describe Types::PermissionTypes::MergeRequest do
expected_permissions = [ expected_permissions = [
:read_merge_request, :admin_merge_request, :update_merge_request, :read_merge_request, :admin_merge_request, :update_merge_request,
:create_note, :push_to_source_branch, :remove_source_branch, :create_note, :push_to_source_branch, :remove_source_branch,
:cherry_pick_on_current_merge_request, :revert_on_current_merge_request :cherry_pick_on_current_merge_request, :revert_on_current_merge_request,
:can_merge
] ]
expect(described_class).to have_graphql_fields(expected_permissions) expect(described_class).to have_graphql_fields(expected_permissions)
......
...@@ -124,7 +124,8 @@ RSpec.describe 'getting merge request information nested in a project' do ...@@ -124,7 +124,8 @@ RSpec.describe 'getting merge request information nested in a project' do
'removeSourceBranch' => false, 'removeSourceBranch' => false,
'cherryPickOnCurrentMergeRequest' => false, 'cherryPickOnCurrentMergeRequest' => false,
'revertOnCurrentMergeRequest' => false, 'revertOnCurrentMergeRequest' => false,
'updateMergeRequest' => false 'updateMergeRequest' => false,
'canMerge' => false
} }
post_graphql(query, current_user: current_user) post_graphql(query, current_user: current_user)
......
...@@ -204,6 +204,10 @@ RSpec.configure do |config| ...@@ -204,6 +204,10 @@ RSpec.configure do |config|
# unified diff lines works as expected # unified diff lines works as expected
stub_feature_flags(unified_diff_lines: false) stub_feature_flags(unified_diff_lines: false)
# Merge request widget GraphQL requests are disabled in the tests
# for now whilst we migrate as much as we can over the GraphQL
stub_feature_flags(merge_request_widget_graphql: false)
enable_rugged = example.metadata[:enable_rugged].present? enable_rugged = example.metadata[:enable_rugged].present?
# Disable Rugged features by default # Disable Rugged features by default
......
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