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
path: root/spec
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-04-09 00:09:50 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-04-09 00:09:50 +0300
commit76358aee81a471a5e71eaf3e8c2d91b7c9a0a5a9 (patch)
treedf9ba3dcc09eb404de31e0d79cb8f0b77812e655 /spec
parent80e9fdc9682cfbcfb9202a2733605a6a6bd23f05 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/frontend/custom_metrics/components/custom_metrics_form_fields_spec.js334
-rw-r--r--spec/frontend/custom_metrics/components/custom_metrics_form_spec.js48
-rw-r--r--spec/frontend/monitoring/store/actions_spec.js9
-rw-r--r--spec/frontend/reports/accessibility_report/components/accessibility_issue_body_spec.js112
-rw-r--r--spec/lib/gitlab/import_export/project/tree_restorer_spec.rb22
-rw-r--r--spec/lib/gitlab/import_export/project/tree_saver_spec.rb15
-rw-r--r--spec/requests/api/internal/base_spec.rb82
7 files changed, 519 insertions, 103 deletions
diff --git a/spec/frontend/custom_metrics/components/custom_metrics_form_fields_spec.js b/spec/frontend/custom_metrics/components/custom_metrics_form_fields_spec.js
new file mode 100644
index 00000000000..61cbef0c557
--- /dev/null
+++ b/spec/frontend/custom_metrics/components/custom_metrics_form_fields_spec.js
@@ -0,0 +1,334 @@
+import { mount } from '@vue/test-utils';
+import MockAdapter from 'axios-mock-adapter';
+import { TEST_HOST } from 'helpers/test_constants';
+import waitForPromises from 'helpers/wait_for_promises';
+import CustomMetricsFormFields from '~/custom_metrics/components/custom_metrics_form_fields.vue';
+import axios from '~/lib/utils/axios_utils';
+
+const { CancelToken } = axios;
+
+describe('custom metrics form fields component', () => {
+ let component;
+ let mockAxios;
+
+ const getNamedInput = name => component.element.querySelector(`input[name="${name}"]`);
+ const validateQueryPath = `${TEST_HOST}/mock/path`;
+ const validQueryResponse = { data: { success: true, query: { valid: true, error: '' } } };
+ const csrfToken = 'mockToken';
+ const formOperation = 'post';
+ const debouncedValidateQueryMock = jest.fn();
+ const makeFormData = (data = {}) => ({
+ formData: {
+ title: '',
+ yLabel: '',
+ query: '',
+ unit: '',
+ group: '',
+ legend: '',
+ ...data,
+ },
+ });
+ const mountComponent = (props, methods = {}) => {
+ component = mount(CustomMetricsFormFields, {
+ propsData: {
+ formOperation,
+ validateQueryPath,
+ ...props,
+ },
+ csrfToken,
+ methods,
+ });
+ };
+
+ beforeEach(() => {
+ mockAxios = new MockAdapter(axios);
+ mockAxios.onPost(validateQueryPath).reply(validQueryResponse);
+ });
+
+ afterEach(() => {
+ component.destroy();
+ mockAxios.restore();
+ });
+
+ it('checks form validity', done => {
+ mountComponent({
+ metricPersisted: true,
+ ...makeFormData({
+ title: 'title',
+ yLabel: 'yLabel',
+ unit: 'unit',
+ group: 'group',
+ }),
+ });
+
+ component.vm.$nextTick(() => {
+ expect(component.vm.formIsValid).toBe(false);
+ done();
+ });
+ });
+
+ describe('hidden inputs', () => {
+ beforeEach(() => {
+ mountComponent();
+ });
+
+ it('specifies form operation _method', () => {
+ expect(getNamedInput('_method', 'input').value).toBe('post');
+ });
+
+ it('specifies authenticity token', () => {
+ expect(getNamedInput('authenticity_token', 'input').value).toBe(csrfToken);
+ });
+ });
+
+ describe('name input', () => {
+ const name = 'prometheus_metric[title]';
+
+ it('is empty by default', () => {
+ mountComponent();
+
+ expect(getNamedInput(name).value).toBe('');
+ });
+
+ it('receives a persisted value', () => {
+ const title = 'mockTitle';
+ mountComponent(makeFormData({ title }));
+
+ expect(getNamedInput(name).value).toBe(title);
+ });
+ });
+
+ describe('group input', () => {
+ it('has a default value', () => {
+ mountComponent();
+
+ expect(getNamedInput('prometheus_metric[group]', 'glformradiogroup-stub').value).toBe(
+ 'business',
+ );
+ });
+ });
+
+ describe('query input', () => {
+ const queryInputName = 'prometheus_metric[query]';
+ beforeEach(() => {
+ mockAxios.onPost(validateQueryPath).reply(validQueryResponse);
+ });
+
+ it('is empty by default', () => {
+ mountComponent();
+
+ expect(getNamedInput(queryInputName).value).toBe('');
+ });
+
+ it('receives and validates a persisted value', () => {
+ const query = 'persistedQuery';
+ const axiosPost = jest.spyOn(axios, 'post');
+ const source = CancelToken.source();
+ mountComponent({ metricPersisted: true, ...makeFormData({ query }) });
+
+ expect(axiosPost).toHaveBeenCalledWith(
+ validateQueryPath,
+ { query },
+ { cancelToken: source.token },
+ );
+ expect(getNamedInput(queryInputName).value).toBe(query);
+ jest.runAllTimers();
+ });
+
+ it('checks validity on user input', () => {
+ const query = 'changedQuery';
+ mountComponent(
+ {},
+ {
+ debouncedValidateQuery: debouncedValidateQueryMock,
+ },
+ );
+ const queryInput = component.find(`input[name="${queryInputName}"]`);
+ queryInput.setValue(query);
+ queryInput.trigger('input');
+
+ expect(debouncedValidateQueryMock).toHaveBeenCalledWith(query);
+ });
+
+ describe('when query validation is in flight', () => {
+ beforeEach(() => {
+ jest.useFakeTimers();
+ mountComponent(
+ { metricPersisted: true, ...makeFormData({ query: 'validQuery' }) },
+ {
+ requestValidation: jest.fn().mockImplementation(
+ () =>
+ new Promise(resolve =>
+ setTimeout(() => {
+ resolve(validQueryResponse);
+ }, 4000),
+ ),
+ ),
+ },
+ );
+ });
+
+ afterEach(() => {
+ jest.clearAllTimers();
+ });
+
+ it('expect queryValidateInFlight is in flight', done => {
+ const queryInput = component.find(`input[name="${queryInputName}"]`);
+ queryInput.setValue('query');
+ queryInput.trigger('input');
+
+ component.vm.$nextTick(() => {
+ expect(component.vm.queryValidateInFlight).toBe(true);
+ jest.runOnlyPendingTimers();
+ waitForPromises()
+ .then(() => {
+ component.vm.$nextTick(() => {
+ expect(component.vm.queryValidateInFlight).toBe(false);
+ expect(component.vm.queryIsValid).toBe(true);
+ done();
+ });
+ })
+ .catch(done.fail);
+ });
+ });
+
+ it('expect loading message to display', done => {
+ const queryInput = component.find(`input[name="${queryInputName}"]`);
+ queryInput.setValue('query');
+ queryInput.trigger('input');
+ component.vm.$nextTick(() => {
+ expect(component.text()).toContain('Validating query');
+ jest.runOnlyPendingTimers();
+ done();
+ });
+ });
+
+ it('expect loading message to disappear', done => {
+ const queryInput = component.find(`input[name="${queryInputName}"]`);
+ queryInput.setValue('query');
+ queryInput.trigger('input');
+ component.vm.$nextTick(() => {
+ jest.runOnlyPendingTimers();
+ waitForPromises()
+ .then(() => {
+ component.vm.$nextTick(() => {
+ expect(component.vm.queryValidateInFlight).toBe(false);
+ expect(component.vm.queryIsValid).toBe(true);
+ expect(component.vm.errorMessage).toBe('');
+ done();
+ });
+ })
+ .catch(done.fail);
+ });
+ });
+ });
+
+ describe('when query is invalid', () => {
+ const errorMessage = 'mockErrorMessage';
+ const invalidQueryResponse = {
+ data: { success: true, query: { valid: false, error: errorMessage } },
+ };
+
+ beforeEach(() => {
+ mountComponent(
+ { metricPersisted: true, ...makeFormData({ query: 'invalidQuery' }) },
+ {
+ requestValidation: jest
+ .fn()
+ .mockImplementation(() => Promise.resolve(invalidQueryResponse)),
+ },
+ );
+ });
+
+ it('sets queryIsValid to false', done => {
+ component.vm.$nextTick(() => {
+ expect(component.vm.queryValidateInFlight).toBe(false);
+ expect(component.vm.queryIsValid).toBe(false);
+ done();
+ });
+ });
+
+ it('shows invalid query message', done => {
+ component.vm.$nextTick(() => {
+ expect(component.text()).toContain(errorMessage);
+ done();
+ });
+ });
+ });
+
+ describe('when query is valid', () => {
+ beforeEach(() => {
+ mountComponent(
+ { metricPersisted: true, ...makeFormData({ query: 'validQuery' }) },
+ {
+ requestValidation: jest
+ .fn()
+ .mockImplementation(() => Promise.resolve(validQueryResponse)),
+ },
+ );
+ });
+
+ it('sets queryIsValid to true when query is valid', done => {
+ component.vm.$nextTick(() => {
+ expect(component.vm.queryIsValid).toBe(true);
+ done();
+ });
+ });
+
+ it('shows valid query message', () => {
+ expect(component.text()).toContain('PromQL query is valid');
+ });
+ });
+ });
+
+ describe('yLabel input', () => {
+ const name = 'prometheus_metric[y_label]';
+
+ it('is empty by default', () => {
+ mountComponent();
+
+ expect(getNamedInput(name).value).toBe('');
+ });
+
+ it('receives a persisted value', () => {
+ const yLabel = 'mockYLabel';
+ mountComponent(makeFormData({ yLabel }));
+
+ expect(getNamedInput(name).value).toBe(yLabel);
+ });
+ });
+
+ describe('unit input', () => {
+ const name = 'prometheus_metric[unit]';
+
+ it('is empty by default', () => {
+ mountComponent();
+
+ expect(getNamedInput(name).value).toBe('');
+ });
+
+ it('receives a persisted value', () => {
+ const unit = 'mockUnit';
+ mountComponent(makeFormData({ unit }));
+
+ expect(getNamedInput(name).value).toBe(unit);
+ });
+ });
+
+ describe('legend input', () => {
+ const name = 'prometheus_metric[legend]';
+
+ it('is empty by default', () => {
+ mountComponent();
+
+ expect(getNamedInput(name).value).toBe('');
+ });
+
+ it('receives a persisted value', () => {
+ const legend = 'mockLegend';
+ mountComponent(makeFormData({ legend }));
+
+ expect(getNamedInput(name).value).toBe(legend);
+ });
+ });
+});
diff --git a/spec/frontend/custom_metrics/components/custom_metrics_form_spec.js b/spec/frontend/custom_metrics/components/custom_metrics_form_spec.js
new file mode 100644
index 00000000000..384d6699150
--- /dev/null
+++ b/spec/frontend/custom_metrics/components/custom_metrics_form_spec.js
@@ -0,0 +1,48 @@
+import { shallowMount } from '@vue/test-utils';
+import CustomMetricsForm from '~/custom_metrics/components/custom_metrics_form.vue';
+
+describe('CustomMetricsForm', () => {
+ let wrapper;
+
+ function mountComponent({
+ metricPersisted = false,
+ formData = {
+ title: '',
+ query: '',
+ yLabel: '',
+ unit: '',
+ group: '',
+ legend: '',
+ },
+ }) {
+ wrapper = shallowMount(CustomMetricsForm, {
+ propsData: {
+ customMetricsPath: '',
+ editProjectServicePath: '',
+ metricPersisted,
+ validateQueryPath: '',
+ formData,
+ },
+ });
+ }
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ describe('Computed', () => {
+ it('Form button and title text indicate the custom metric is being edited', () => {
+ mountComponent({ metricPersisted: true });
+
+ expect(wrapper.vm.saveButtonText).toBe('Save Changes');
+ expect(wrapper.vm.titleText).toBe('Edit metric');
+ });
+
+ it('Form button and title text indicate the custom metric is being created', () => {
+ mountComponent({ metricPersisted: false });
+
+ expect(wrapper.vm.saveButtonText).toBe('Create metric');
+ expect(wrapper.vm.titleText).toBe('New metric');
+ });
+ });
+});
diff --git a/spec/frontend/monitoring/store/actions_spec.js b/spec/frontend/monitoring/store/actions_spec.js
index 7c559aed2c5..b37c10791bf 100644
--- a/spec/frontend/monitoring/store/actions_spec.js
+++ b/spec/frontend/monitoring/store/actions_spec.js
@@ -6,6 +6,7 @@ import statusCodes from '~/lib/utils/http_status';
import * as commonUtils from '~/lib/utils/common_utils';
import createFlash from '~/flash';
import { defaultTimeRange } from '~/vue_shared/constants';
+import { ENVIRONMENT_AVAILABLE_STATE } from '~/monitoring/constants';
import store from '~/monitoring/stores';
import * as types from '~/monitoring/stores/mutation_types';
@@ -157,17 +158,21 @@ describe('Monitoring store actions', () => {
variables: {
projectPath: state.projectPath,
search: searchTerm,
+ states: [ENVIRONMENT_AVAILABLE_STATE],
},
};
state.environmentsSearchTerm = searchTerm;
- mockMutate.mockReturnValue(Promise.resolve());
+ mockMutate.mockResolvedValue({});
return testAction(
fetchEnvironmentsData,
null,
state,
[],
- [{ type: 'requestEnvironmentsData' }, { type: 'receiveEnvironmentsDataFailure' }],
+ [
+ { type: 'requestEnvironmentsData' },
+ { type: 'receiveEnvironmentsDataSuccess', payload: [] },
+ ],
() => {
expect(mockMutate).toHaveBeenCalledWith(mutationVariables);
},
diff --git a/spec/frontend/reports/accessibility_report/components/accessibility_issue_body_spec.js b/spec/frontend/reports/accessibility_report/components/accessibility_issue_body_spec.js
new file mode 100644
index 00000000000..794deca42ac
--- /dev/null
+++ b/spec/frontend/reports/accessibility_report/components/accessibility_issue_body_spec.js
@@ -0,0 +1,112 @@
+import { shallowMount } from '@vue/test-utils';
+import AccessibilityIssueBody from '~/reports/accessibility_report/components/accessibility_issue_body.vue';
+
+const issue = {
+ name:
+ 'The accessibility scanning found 2 errors of the following type: WCAG2AA.Principle4.Guideline4_1.4_1_2.H91.A.NoContent',
+ code: 'WCAG2AA.Principle4.Guideline4_1.4_1_2.H91.A.NoContent',
+ message: 'This element has insufficient contrast at this conformance level.',
+ status: 'failed',
+ className: 'spec.test_spec',
+ learnMoreUrl: 'https://www.w3.org/TR/WCAG20-TECHS/H91.html',
+};
+
+describe('CustomMetricsForm', () => {
+ let wrapper;
+
+ const mountComponent = ({ name, code, message, status, className }, isNew = false) => {
+ wrapper = shallowMount(AccessibilityIssueBody, {
+ propsData: {
+ issue: {
+ name,
+ code,
+ message,
+ status,
+ className,
+ },
+ isNew,
+ },
+ });
+ };
+
+ const findIsNewBadge = () => wrapper.find({ ref: 'accessibility-issue-is-new-badge' });
+
+ beforeEach(() => {
+ mountComponent(issue);
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
+ });
+
+ it('Displays the issue message', () => {
+ const description = wrapper.find({ ref: 'accessibility-issue-description' }).text();
+
+ expect(description).toContain(`Message: ${issue.message}`);
+ });
+
+ describe('When an issue code is present', () => {
+ it('Creates the correct URL for learning more about the issue code', () => {
+ const learnMoreUrl = wrapper
+ .find({ ref: 'accessibility-issue-learn-more' })
+ .attributes('href');
+
+ expect(learnMoreUrl).toEqual(issue.learnMoreUrl);
+ });
+ });
+
+ describe('When an issue code is not present', () => {
+ beforeEach(() => {
+ mountComponent({
+ ...issue,
+ code: undefined,
+ });
+ });
+
+ it('Creates a URL leading to the overview documentation page', () => {
+ const learnMoreUrl = wrapper
+ .find({ ref: 'accessibility-issue-learn-more' })
+ .attributes('href');
+
+ expect(learnMoreUrl).toEqual('https://www.w3.org/TR/WCAG20-TECHS/Overview.html');
+ });
+ });
+
+ describe('When an issue code does not contain the TECHS code', () => {
+ beforeEach(() => {
+ mountComponent({
+ ...issue,
+ code: 'WCAG2AA.Principle4.Guideline4_1.4_1_2',
+ });
+ });
+
+ it('Creates a URL leading to the overview documentation page', () => {
+ const learnMoreUrl = wrapper
+ .find({ ref: 'accessibility-issue-learn-more' })
+ .attributes('href');
+
+ expect(learnMoreUrl).toEqual('https://www.w3.org/TR/WCAG20-TECHS/Overview.html');
+ });
+ });
+
+ describe('When issue is new', () => {
+ beforeEach(() => {
+ mountComponent(issue, true);
+ });
+
+ it('Renders the new badge', () => {
+ expect(findIsNewBadge().exists()).toEqual(true);
+ });
+ });
+
+ describe('When issue is not new', () => {
+ beforeEach(() => {
+ mountComponent(issue, false);
+ });
+
+ it('Does not render the new badge', () => {
+ expect(findIsNewBadge().exists()).toEqual(false);
+ });
+ });
+});
diff --git a/spec/lib/gitlab/import_export/project/tree_restorer_spec.rb b/spec/lib/gitlab/import_export/project/tree_restorer_spec.rb
index 96aed774cfc..c8229eeee94 100644
--- a/spec/lib/gitlab/import_export/project/tree_restorer_spec.rb
+++ b/spec/lib/gitlab/import_export/project/tree_restorer_spec.rb
@@ -11,7 +11,7 @@ describe Gitlab::ImportExport::Project::TreeRestorer do
let(:shared) { project.import_export_shared }
- RSpec.shared_examples 'project tree restorer work properly' do |reader|
+ RSpec.shared_examples 'project tree restorer work properly' do |reader, ndjson_enabled|
describe 'restore project tree' do
before_all do
# Using an admin for import, so we can check assignment of existing members
@@ -25,6 +25,9 @@ describe Gitlab::ImportExport::Project::TreeRestorer do
@project = create(:project, :builds_enabled, :issues_disabled, name: 'project', path: 'project')
@shared = @project.import_export_shared
+ allow(Feature).to receive(:enabled?).and_call_original
+ stub_feature_flags(project_import_ndjson: ndjson_enabled)
+
setup_import_export_config('complex')
setup_reader(reader)
@@ -999,23 +1002,12 @@ describe Gitlab::ImportExport::Project::TreeRestorer do
end
context 'enable ndjson import' do
- before_all do
- # Test suite `restore project tree` run `project_tree_restorer.restore` in `before_all`.
- # `Enable all features by default for testing` happens in `before(:each)`
- # So it requires manually enable feature flag to allow ndjson_reader
- Feature.enable(:project_import_ndjson)
- end
-
- it_behaves_like 'project tree restorer work properly', :legacy_reader
+ it_behaves_like 'project tree restorer work properly', :legacy_reader, true
- it_behaves_like 'project tree restorer work properly', :ndjson_reader
+ it_behaves_like 'project tree restorer work properly', :ndjson_reader, true
end
context 'disable ndjson import' do
- before do
- stub_feature_flags(project_import_ndjson: false)
- end
-
- it_behaves_like 'project tree restorer work properly', :legacy_reader
+ it_behaves_like 'project tree restorer work properly', :legacy_reader, false
end
end
diff --git a/spec/lib/gitlab/import_export/project/tree_saver_spec.rb b/spec/lib/gitlab/import_export/project/tree_saver_spec.rb
index d859af5df02..ded57b1d576 100644
--- a/spec/lib/gitlab/import_export/project/tree_saver_spec.rb
+++ b/spec/lib/gitlab/import_export/project/tree_saver_spec.rb
@@ -16,7 +16,6 @@ describe Gitlab::ImportExport::Project::TreeSaver do
let_it_be(:group) { create(:group) }
let_it_be(:project) { setup_project }
let_it_be(:shared) { project.import_export_shared }
- let_it_be(:project_tree_saver ) { described_class.new(project: project, current_user: user, shared: shared) }
let(:relation_name) { :projects }
@@ -29,9 +28,17 @@ describe Gitlab::ImportExport::Project::TreeSaver do
end
before_all do
- Feature.enable(:project_export_as_ndjson) if ndjson_enabled
- project.add_maintainer(user)
- project_tree_saver.save
+ RSpec::Mocks.with_temporary_scope do
+ allow(Feature).to receive(:enabled?).and_call_original
+ stub_feature_flags(project_export_as_ndjson: ndjson_enabled)
+
+ project.add_maintainer(user)
+
+ stub_feature_flags(project_export_as_ndjson: ndjson_enabled)
+ project_tree_saver = described_class.new(project: project, current_user: user, shared: shared)
+
+ project_tree_saver.save
+ end
end
after :all do
diff --git a/spec/requests/api/internal/base_spec.rb b/spec/requests/api/internal/base_spec.rb
index f84336b64c2..0629d51154b 100644
--- a/spec/requests/api/internal/base_spec.rb
+++ b/spec/requests/api/internal/base_spec.rb
@@ -882,88 +882,6 @@ describe API::Internal::Base do
end
end
- # TODO: Uncomment when the end-point is reenabled
- # describe 'POST /notify_post_receive' do
- # let(:valid_params) do
- # { project: project.repository.path, secret_token: secret_token }
- # end
- #
- # let(:valid_wiki_params) do
- # { project: project.wiki.repository.path, secret_token: secret_token }
- # end
- #
- # before do
- # allow(Gitlab.config.gitaly).to receive(:enabled).and_return(true)
- # end
- #
- # it "calls the Gitaly client with the project's repository" do
- # expect(Gitlab::GitalyClient::NotificationService).
- # to receive(:new).with(gitlab_git_repository_with(path: project.repository.path)).
- # and_call_original
- # expect_any_instance_of(Gitlab::GitalyClient::NotificationService).
- # to receive(:post_receive)
- #
- # post api("/internal/notify_post_receive"), valid_params
- #
- # expect(response).to have_gitlab_http_status(:ok)
- # end
- #
- # it "calls the Gitaly client with the wiki's repository if it's a wiki" do
- # expect(Gitlab::GitalyClient::NotificationService).
- # to receive(:new).with(gitlab_git_repository_with(path: project.wiki.repository.path)).
- # and_call_original
- # expect_any_instance_of(Gitlab::GitalyClient::NotificationService).
- # to receive(:post_receive)
- #
- # post api("/internal/notify_post_receive"), valid_wiki_params
- #
- # expect(response).to have_gitlab_http_status(:ok)
- # end
- #
- # it "returns 500 if the gitaly call fails" do
- # expect_any_instance_of(Gitlab::GitalyClient::NotificationService).
- # to receive(:post_receive).and_raise(GRPC::Unavailable)
- #
- # post api("/internal/notify_post_receive"), valid_params
- #
- # expect(response).to have_gitlab_http_status(:internal_server_error)
- # end
- #
- # context 'with a gl_repository parameter' do
- # let(:valid_params) do
- # { gl_repository: "project-#{project.id}", secret_token: secret_token }
- # end
- #
- # let(:valid_wiki_params) do
- # { gl_repository: "wiki-#{project.id}", secret_token: secret_token }
- # end
- #
- # it "calls the Gitaly client with the project's repository" do
- # expect(Gitlab::GitalyClient::NotificationService).
- # to receive(:new).with(gitlab_git_repository_with(path: project.repository.path)).
- # and_call_original
- # expect_any_instance_of(Gitlab::GitalyClient::NotificationService).
- # to receive(:post_receive)
- #
- # post api("/internal/notify_post_receive"), valid_params
- #
- # expect(response).to have_gitlab_http_status(:ok)
- # end
- #
- # it "calls the Gitaly client with the wiki's repository if it's a wiki" do
- # expect(Gitlab::GitalyClient::NotificationService).
- # to receive(:new).with(gitlab_git_repository_with(path: project.wiki.repository.path)).
- # and_call_original
- # expect_any_instance_of(Gitlab::GitalyClient::NotificationService).
- # to receive(:post_receive)
- #
- # post api("/internal/notify_post_receive"), valid_wiki_params
- #
- # expect(response).to have_gitlab_http_status(:ok)
- # end
- # end
- # end
-
describe 'POST /internal/post_receive', :clean_gitlab_redis_shared_state do
let(:identifier) { 'key-123' }
let(:branch_name) { 'feature' }