Commit 47b8f79a authored by GitLab Bot's avatar GitLab Bot

Add latest changes from gitlab-org/gitlab@master

parent 52fe64b7
...@@ -480,6 +480,13 @@ Please view this file on the master branch, on stable branches it's out of date. ...@@ -480,6 +480,13 @@ Please view this file on the master branch, on stable branches it's out of date.
- Fixes style-lint errors and warnings for EE builds.scss file. - Fixes style-lint errors and warnings for EE builds.scss file.
## 12.2.11
### Fixed (1 change)
- Backport the new reliable fetcher. !21198
## 12.2.8 ## 12.2.8
### Fixed (1 change) ### Fixed (1 change)
...@@ -830,6 +837,7 @@ Please view this file on the master branch, on stable branches it's out of date. ...@@ -830,6 +837,7 @@ Please view this file on the master branch, on stable branches it's out of date.
## 12.0.10 ## 12.0.10
- No changes.
### Fixed (1 change) ### Fixed (1 change)
- Backport the new reliable fetcher to 12.0.9. !20532 - Backport the new reliable fetcher to 12.0.9. !20532
......
...@@ -20,7 +20,7 @@ export const discardAllChanges = ({ state, commit, dispatch }) => { ...@@ -20,7 +20,7 @@ export const discardAllChanges = ({ state, commit, dispatch }) => {
commit(types.DISCARD_FILE_CHANGES, file.path); commit(types.DISCARD_FILE_CHANGES, file.path);
if (file.tempFile) { if (file.tempFile) {
dispatch('closeFile', file.path); dispatch('closeFile', file);
} }
}); });
......
...@@ -193,23 +193,10 @@ export default { ...@@ -193,23 +193,10 @@ export default {
this.stopPolling(); this.stopPolling();
this.saveNote(noteData) this.saveNote(noteData)
.then(res => { .then(() => {
this.enableButton(); this.enableButton();
this.restartPolling(); this.restartPolling();
if (res.errors) {
if (res.errors.commands_only) {
this.discard(); this.discard();
} else {
Flash(
__('Something went wrong while adding your comment. Please try again.'),
'alert',
this.$refs.commentForm,
);
}
} else {
this.discard();
}
if (withIssueAction) { if (withIssueAction) {
this.toggleIssueState(); this.toggleIssueState();
......
...@@ -198,16 +198,16 @@ export default { ...@@ -198,16 +198,16 @@ export default {
data: postData, data: postData,
}; };
this.isReplying = false;
this.saveNote(replyData) this.saveNote(replyData)
.then(() => { .then(res => {
if (res.hasFlash !== true) {
this.isReplying = false;
clearDraft(this.autosaveKey); clearDraft(this.autosaveKey);
}
callback(); callback();
}) })
.catch(err => { .catch(err => {
this.removePlaceholderNotes(); this.removePlaceholderNotes();
this.isReplying = true;
this.$nextTick(() => {
const msg = __( const msg = __(
'Your comment could not be submitted! Please check your network connection and try again.', 'Your comment could not be submitted! Please check your network connection and try again.',
); );
...@@ -215,7 +215,6 @@ export default { ...@@ -215,7 +215,6 @@ export default {
this.$refs.noteForm.note = noteText; this.$refs.noteForm.note = noteText;
callback(err); callback(err);
}); });
});
}, },
jumpToNextDiscussion() { jumpToNextDiscussion() {
const nextId = this.nextUnresolvedDiscussionId( const nextId = this.nextUnresolvedDiscussionId(
......
...@@ -14,7 +14,7 @@ import sidebarTimeTrackingEventHub from '../../sidebar/event_hub'; ...@@ -14,7 +14,7 @@ import sidebarTimeTrackingEventHub from '../../sidebar/event_hub';
import { isInViewport, scrollToElement, isInMRPage } from '../../lib/utils/common_utils'; import { isInViewport, scrollToElement, isInMRPage } from '../../lib/utils/common_utils';
import { mergeUrlParams } from '../../lib/utils/url_utility'; import { mergeUrlParams } from '../../lib/utils/url_utility';
import mrWidgetEventHub from '../../vue_merge_request_widget/event_hub'; import mrWidgetEventHub from '../../vue_merge_request_widget/event_hub';
import { __ } from '~/locale'; import { __, sprintf } from '~/locale';
import Api from '~/api'; import Api from '~/api';
let eTagPoll; let eTagPoll;
...@@ -252,29 +252,22 @@ export const saveNote = ({ commit, dispatch }, noteData) => { ...@@ -252,29 +252,22 @@ export const saveNote = ({ commit, dispatch }, noteData) => {
} }
} }
const processErrors = res => { const processQuickActions = res => {
const { errors } = res; const { errors: { commands_only: message } = { commands_only: null } } = res;
if (!errors || !Object.keys(errors).length) {
return res;
}
/* /*
The following reply means that quick actions have been successfully applied: The following reply means that quick actions have been successfully applied:
{"commands_changes":{},"valid":false,"errors":{"commands_only":["Commands applied"]}} {"commands_changes":{},"valid":false,"errors":{"commands_only":["Commands applied"]}}
*/ */
if (hasQuickActions) { if (hasQuickActions && message) {
eTagPoll.makeRequest(); eTagPoll.makeRequest();
$('.js-gfm-input').trigger('clear-commands-cache.atwho'); $('.js-gfm-input').trigger('clear-commands-cache.atwho');
const { commands_only: message } = errors;
Flash(message || __('Commands applied'), 'notice', noteData.flashContainer); Flash(message || __('Commands applied'), 'notice', noteData.flashContainer);
return res;
} }
throw new Error(__('Failed to save comment!')); return res;
}; };
const processEmojiAward = res => { const processEmojiAward = res => {
...@@ -321,11 +314,33 @@ export const saveNote = ({ commit, dispatch }, noteData) => { ...@@ -321,11 +314,33 @@ export const saveNote = ({ commit, dispatch }, noteData) => {
return res; return res;
}; };
const processErrors = error => {
if (error.response) {
const {
response: { data = {} },
} = error;
const { errors = {} } = data;
const { base = [] } = errors;
// we handle only errors.base for now
if (base.length > 0) {
const errorMsg = sprintf(__('Your comment could not be submitted because %{error}'), {
error: base[0].toLowerCase(),
});
Flash(errorMsg, 'alert', noteData.flashContainer);
return { ...data, hasFlash: true };
}
}
throw error;
};
return dispatch(methodToDispatch, postData, { root: true }) return dispatch(methodToDispatch, postData, { root: true })
.then(processErrors) .then(processQuickActions)
.then(processEmojiAward) .then(processEmojiAward)
.then(processTimeTracking) .then(processTimeTracking)
.then(removePlaceholder); .then(removePlaceholder)
.catch(processErrors);
}; };
const pollSuccessCallBack = (resp, commit, state, getters, dispatch) => { const pollSuccessCallBack = (resp, commit, state, getters, dispatch) => {
......
...@@ -11,7 +11,7 @@ module Notes ...@@ -11,7 +11,7 @@ module Notes
unless discussion && can?(current_user, :create_note, discussion.noteable) unless discussion && can?(current_user, :create_note, discussion.noteable)
note = Note.new note = Note.new
note.errors.add(:base, 'Discussion to reply to cannot be found') note.errors.add(:base, _('Discussion to reply to cannot be found'))
return note return note
end end
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
module Notes module Notes
class CreateService < ::Notes::BaseService class CreateService < ::Notes::BaseService
# rubocop:disable Metrics/CyclomaticComplexity
def execute def execute
merge_request_diff_head_sha = params.delete(:merge_request_diff_head_sha) merge_request_diff_head_sha = params.delete(:merge_request_diff_head_sha)
...@@ -9,7 +10,9 @@ module Notes ...@@ -9,7 +10,9 @@ module Notes
# n+1: https://gitlab.com/gitlab-org/gitlab-foss/issues/37440 # n+1: https://gitlab.com/gitlab-org/gitlab-foss/issues/37440
note_valid = Gitlab::GitalyClient.allow_n_plus_1_calls do note_valid = Gitlab::GitalyClient.allow_n_plus_1_calls do
note.valid? # We may set errors manually in Notes::BuildService for this reason
# we also need to check for already existing errors.
note.errors.empty? && note.valid?
end end
return note unless note_valid return note unless note_valid
...@@ -67,6 +70,7 @@ module Notes ...@@ -67,6 +70,7 @@ module Notes
note note
end end
# rubocop:enable Metrics/CyclomaticComplexity
private private
......
---
title: Display a better message when starting a discussion on a deleted comment
merge_request: 20031
author: Jacopo Beschi @jacopo-beschi
type: changed
---
title: "Web IDE: Fix the console error that happens when discarding a newly added/uploaded file."
merge_request: 21537
author:
type: fixed
...@@ -23,3 +23,7 @@ Your feature flag can now be: ...@@ -23,3 +23,7 @@ Your feature flag can now be:
- [Deleting a feature flag](../../api/features.md#delete-a-feature) - [Deleting a feature flag](../../api/features.md#delete-a-feature)
- [Manage feature flags](../feature_flags/process.md) - [Manage feature flags](../feature_flags/process.md)
- [Feature flags API](../../api/features.md) - [Feature flags API](../../api/features.md)
## Running tests locally
This can be done as outlined by the [frontend testing guide](../testing_guide/frontend_testing.md#running-frontend-tests).
...@@ -552,6 +552,7 @@ For running the frontend tests, you need the following commands: ...@@ -552,6 +552,7 @@ For running the frontend tests, you need the following commands:
- `rake frontend:fixtures` (re-)generates [fixtures](#frontend-test-fixtures). - `rake frontend:fixtures` (re-)generates [fixtures](#frontend-test-fixtures).
- `yarn test` executes the tests. - `yarn test` executes the tests.
- `yarn jest` executes only the Jest tests.
As long as the fixtures don't change, `yarn test` is sufficient (and saves you some time). As long as the fixtures don't change, `yarn test` is sufficient (and saves you some time).
...@@ -593,6 +594,24 @@ glob otherwise your shell may split it into multiple arguments: ...@@ -593,6 +594,24 @@ glob otherwise your shell may split it into multiple arguments:
yarn karma -f 'spec/javascripts/ide/**/file_spec.js' yarn karma -f 'spec/javascripts/ide/**/file_spec.js'
``` ```
It is also possible to target individual Jest / RSpec tests:
```bash
# Run specific jest file
yarn jest ./path/to/local_spec.js
# Run specific jest folder
yarn jest ./path/to/folder/
# Run all jest files which path contain term
yarn jest term
```
```bash
# Run specific rspec file
rspec ./path/to/local_spec.rb
# Run specific block within rspec file
rspec ./path/to/local_spec.rb:15
```
## Frontend test fixtures ## Frontend test fixtures
Code that is added to HAML templates (in `app/views/`) or makes Ajax requests to the backend has tests that require HTML or JSON from the backend. Code that is added to HAML templates (in `app/views/`) or makes Ajax requests to the backend has tests that require HTML or JSON from the backend.
......
...@@ -5,14 +5,24 @@ module Gitlab ...@@ -5,14 +5,24 @@ module Gitlab
module Helm module Helm
module ClientCommand module ClientCommand
def init_command def init_command
if local_tiller_enabled?
<<~HEREDOC.chomp
export HELM_HOST="localhost:44134"
tiller -listen ${HELM_HOST} -alsologtostderr &
helm init --client-only
HEREDOC
else
# Here we are always upgrading to the latest version of Tiller when # Here we are always upgrading to the latest version of Tiller when
# installing an app. We ensure the helm version stored in the # installing an app. We ensure the helm version stored in the
# database is correct by also updating this after transition to # database is correct by also updating this after transition to
# :installed,:updated in Clusters::Concerns::ApplicationStatus # :installed,:updated in Clusters::Concerns::ApplicationStatus
'helm init --upgrade' 'helm init --upgrade'
end end
end
def wait_for_tiller_command def wait_for_tiller_command
return if local_tiller_enabled?
helm_check = ['helm', 'version', *optional_tls_flags].shelljoin helm_check = ['helm', 'version', *optional_tls_flags].shelljoin
# This is necessary to give Tiller time to restart after upgrade. # This is necessary to give Tiller time to restart after upgrade.
# Ideally we'd be able to use --wait but cannot because of # Ideally we'd be able to use --wait but cannot because of
...@@ -25,6 +35,14 @@ module Gitlab ...@@ -25,6 +35,14 @@ module Gitlab
['helm', 'repo', 'add', name, repository].shelljoin if repository ['helm', 'repo', 'add', name, repository].shelljoin if repository
end end
private
def tls_flags_if_remote_tiller
return [] if local_tiller_enabled?
optional_tls_flags
end
def optional_tls_flags def optional_tls_flags
return [] unless files.key?(:'ca.pem') return [] unless files.key?(:'ca.pem')
...@@ -35,6 +53,10 @@ module Gitlab ...@@ -35,6 +53,10 @@ module Gitlab
'--tls-key', "#{files_dir}/key.pem" '--tls-key', "#{files_dir}/key.pem"
] ]
end end
def local_tiller_enabled?
Feature.enabled?(:managed_apps_local_tiller)
end
end end
end end
end end
......
...@@ -39,7 +39,7 @@ module Gitlab ...@@ -39,7 +39,7 @@ module Gitlab
private private
def delete_command def delete_command
command = ['helm', 'delete', '--purge', name] + optional_tls_flags command = ['helm', 'delete', '--purge', name] + tls_flags_if_remote_tiller
command.shelljoin command.shelljoin
end end
......
...@@ -49,7 +49,7 @@ module Gitlab ...@@ -49,7 +49,7 @@ module Gitlab
command = ['helm', 'upgrade', name, chart] + command = ['helm', 'upgrade', name, chart] +
install_flag + install_flag +
reset_values_flag + reset_values_flag +
optional_tls_flags + tls_flags_if_remote_tiller +
optional_version_flag + optional_version_flag +
rbac_create_flag + rbac_create_flag +
namespace_flag + namespace_flag +
......
...@@ -6078,6 +6078,9 @@ msgstr "" ...@@ -6078,6 +6078,9 @@ msgstr ""
msgid "Discussion" msgid "Discussion"
msgstr "" msgstr ""
msgid "Discussion to reply to cannot be found"
msgstr ""
msgid "Disk Usage" msgid "Disk Usage"
msgstr "" msgstr ""
...@@ -7395,9 +7398,6 @@ msgstr "" ...@@ -7395,9 +7398,6 @@ msgstr ""
msgid "Failed to reset key. Please try again." msgid "Failed to reset key. Please try again."
msgstr "" msgstr ""
msgid "Failed to save comment!"
msgstr ""
msgid "Failed to save merge conflicts resolutions. Please try again!" msgid "Failed to save merge conflicts resolutions. Please try again!"
msgstr "" msgstr ""
...@@ -16399,9 +16399,6 @@ msgstr "" ...@@ -16399,9 +16399,6 @@ msgstr ""
msgid "Something went wrong while adding your award. Please try again." msgid "Something went wrong while adding your award. Please try again."
msgstr "" msgstr ""
msgid "Something went wrong while adding your comment. Please try again."
msgstr ""
msgid "Something went wrong while applying the suggestion. Please try again." msgid "Something went wrong while applying the suggestion. Please try again."
msgstr "" msgstr ""
...@@ -20647,6 +20644,9 @@ msgstr "" ...@@ -20647,6 +20644,9 @@ msgstr ""
msgid "Your changes have been successfully committed." msgid "Your changes have been successfully committed."
msgstr "" msgstr ""
msgid "Your comment could not be submitted because %{error}"
msgstr ""
msgid "Your comment could not be submitted! Please check your network connection and try again." msgid "Your comment could not be submitted! Please check your network connection and try again."
msgstr "" msgstr ""
......
...@@ -91,24 +91,22 @@ module QA ...@@ -91,24 +91,22 @@ module QA
end end
def merge_immediately def merge_immediately
wait(reload: false, max: 60) do wait(reload: false) do
has_merge_options? finished_loading?
end end
if has_merge_options? if has_merge_options?
if has_no_element? :merge_immediately_option
retry_until do retry_until do
click_element :merge_moment_dropdown click_element :merge_moment_dropdown
has_element? :merge_immediately_option has_element? :merge_immediately_option
end end
end
click_element :merge_immediately_option click_element :merge_immediately_option
else else
click_element :merge_button click_element :merge_button
end end
wait(reload: false, max: 60) do wait(reload: false) do
merged? merged?
end end
end end
......
...@@ -95,6 +95,24 @@ describe 'Merge request > User posts notes', :js do ...@@ -95,6 +95,24 @@ describe 'Merge request > User posts notes', :js do
end end
end end
describe 'reply on a deleted conversation' do
before do
visit project_merge_request_path(project, merge_request)
end
it 'shows an error message' do
find('.js-reply-button').click
note.delete
page.within('.discussion-reply-holder') do
fill_in 'note[note]', with: 'A reply'
click_button 'Comment'
wait_for_requests
expect(page).to have_content('Your comment could not be submitted because discussion to reply to cannot be found')
end
end
end
describe 'when previewing a note' do describe 'when previewing a note' do
it 'shows the toolbar buttons when editing a note' do it 'shows the toolbar buttons when editing a note' do
page.within('.js-main-target-form') do page.within('.js-main-target-form') do
......
...@@ -145,8 +145,7 @@ describe('DiffsStoreActions', () => { ...@@ -145,8 +145,7 @@ describe('DiffsStoreActions', () => {
}); });
describe('fetchDiffFilesBatch', () => { describe('fetchDiffFilesBatch', () => {
// eslint-disable-next-line jasmine/no-focused-tests it('should fetch batch diff files', done => {
fit('should fetch batch diff files', done => {
const endpointBatch = '/fetch/diffs_batch'; const endpointBatch = '/fetch/diffs_batch';
const batch1 = `${endpointBatch}?per_page=${DIFFS_PER_PAGE}`; const batch1 = `${endpointBatch}?per_page=${DIFFS_PER_PAGE}`;
const batch2 = `${endpointBatch}?per_page=${DIFFS_PER_PAGE}&page=2`; const batch2 = `${endpointBatch}?per_page=${DIFFS_PER_PAGE}&page=2`;
......
...@@ -12,6 +12,7 @@ import actions, { ...@@ -12,6 +12,7 @@ import actions, {
renameEntry, renameEntry,
getBranchData, getBranchData,
createTempEntry, createTempEntry,
discardAllChanges,
} from '~/ide/stores/actions'; } from '~/ide/stores/actions';
import axios from '~/lib/utils/axios_utils'; import axios from '~/lib/utils/axios_utils';
import { createStore } from '~/ide/stores'; import { createStore } from '~/ide/stores';
...@@ -60,8 +61,9 @@ describe('Multi-file store actions', () => { ...@@ -60,8 +61,9 @@ describe('Multi-file store actions', () => {
}); });
describe('discardAllChanges', () => { describe('discardAllChanges', () => {
let f;
beforeEach(() => { beforeEach(() => {
const f = file('discardAll'); f = file('discardAll');
f.changed = true; f.changed = true;
store.state.openFiles.push(f); store.state.openFiles.push(f);
...@@ -89,6 +91,27 @@ describe('Multi-file store actions', () => { ...@@ -89,6 +91,27 @@ describe('Multi-file store actions', () => {
.then(done) .then(done)
.catch(done.fail); .catch(done.fail);
}); });
it('closes the temp file if it was open', done => {
f.tempFile = true;
testAction(
discardAllChanges,
undefined,
store.state,
[
{ type: types.DISCARD_FILE_CHANGES, payload: 'discardAll' },
{ type: types.REMOVE_ALL_CHANGES_FILES },
],
[
{
type: 'closeFile',
payload: jasmine.objectContaining({ path: 'discardAll' }),
},
],
done,
);
});
}); });
describe('closeAllFiles', () => { describe('closeAllFiles', () => {
......
...@@ -751,29 +751,59 @@ describe('Actions Notes Store', () => { ...@@ -751,29 +751,59 @@ describe('Actions Notes Store', () => {
}); });
describe('saveNote', () => { describe('saveNote', () => {
const payload = { endpoint: TEST_HOST, data: { 'note[note]': 'some text' } }; const flashContainer = {};
const payload = { endpoint: TEST_HOST, data: { 'note[note]': 'some text' }, flashContainer };
describe('if response contains errors', () => { describe('if response contains errors', () => {
const res = { errors: { something: ['went wrong'] } }; const res = { errors: { something: ['went wrong'] } };
const error = { message: 'Unprocessable entity', response: { data: res } };
it('throws an error', done => { it('throws an error', done => {
actions actions
.saveNote( .saveNote(
{ {
commit() {}, commit() {},
dispatch: () => Promise.resolve(res), dispatch: () => Promise.reject(error),
}, },
payload, payload,
) )
.then(() => done.fail('Expected error to be thrown!')) .then(() => done.fail('Expected error to be thrown!'))
.catch(error => { .catch(err => {
expect(error.message).toBe('Failed to save comment!'); expect(err).toBe(error);
expect(flashSpy).not.toHaveBeenCalled();
}) })
.then(done) .then(done)
.catch(done.fail); .catch(done.fail);
}); });
}); });
describe('if response contains errors.base', () => {
const res = { errors: { base: ['something went wrong'] } };
const error = { message: 'Unprocessable entity', response: { data: res } };
it('sets flash alert using errors.base message', done => {
actions
.saveNote(
{
commit() {},
dispatch: () => Promise.reject(error),
},
{ ...payload, flashContainer },
)
.then(resp => {
expect(resp.hasFlash).toBe(true);
expect(flashSpy).toHaveBeenCalledWith(
'Your comment could not be submitted because something went wrong',
'alert',
flashContainer,
);
})
.catch(() => done.fail('Expected success response!'))
.then(done)
.catch(done.fail);
});
});
describe('if response contains no errors', () => { describe('if response contains no errors', () => {
const res = { valid: true }; const res = { valid: true };
...@@ -788,6 +818,7 @@ describe('Actions Notes Store', () => { ...@@ -788,6 +818,7 @@ describe('Actions Notes Store', () => {
) )
.then(data => { .then(data => {
expect(data).toBe(res); expect(data).toBe(res);
expect(flashSpy).not.toHaveBeenCalled();
}) })
.then(done) .then(done)
.catch(done.fail); .catch(done.fail);
......
...@@ -10,6 +10,22 @@ describe Gitlab::Kubernetes::Helm::DeleteCommand do ...@@ -10,6 +10,22 @@ describe Gitlab::Kubernetes::Helm::DeleteCommand do
subject { delete_command } subject { delete_command }
it_behaves_like 'helm commands' do
let(:commands) do
<<~EOS
export HELM_HOST="localhost:44134"
tiller -listen ${HELM_HOST} -alsologtostderr &
helm init --client-only
helm delete --purge app-name
EOS
end
end
context 'tillerless feature disabled' do
before do
stub_feature_flags(managed_apps_local_tiller: false)
end
it_behaves_like 'helm commands' do it_behaves_like 'helm commands' do
let(:commands) do let(:commands) do
<<~EOS <<~EOS
...@@ -20,6 +36,9 @@ describe Gitlab::Kubernetes::Helm::DeleteCommand do ...@@ -20,6 +36,9 @@ describe Gitlab::Kubernetes::Helm::DeleteCommand do
end end
end end
context 'when there is a ca.pem file' do
let(:files) { { 'ca.pem': 'some file content' } }
let(:tls_flags) do let(:tls_flags) do
<<~EOS.squish <<~EOS.squish
--tls --tls
...@@ -29,9 +48,6 @@ describe Gitlab::Kubernetes::Helm::DeleteCommand do ...@@ -29,9 +48,6 @@ describe Gitlab::Kubernetes::Helm::DeleteCommand do
EOS EOS
end end
context 'when there is a ca.pem file' do
let(:files) { { 'ca.pem': 'some file content' } }
it_behaves_like 'helm commands' do it_behaves_like 'helm commands' do
let(:commands) do let(:commands) do
<<~EOS <<~EOS
...@@ -49,6 +65,7 @@ describe Gitlab::Kubernetes::Helm::DeleteCommand do ...@@ -49,6 +65,7 @@ describe Gitlab::Kubernetes::Helm::DeleteCommand do
end end
end end
end end
end
describe '#pod_resource' do describe '#pod_resource' do
subject { delete_command.pod_resource } subject { delete_command.pod_resource }
......
...@@ -23,6 +23,38 @@ describe Gitlab::Kubernetes::Helm::InstallCommand do ...@@ -23,6 +23,38 @@ describe Gitlab::Kubernetes::Helm::InstallCommand do
) )
end end
subject { install_command }
it_behaves_like 'helm commands' do
let(:commands) do
<<~EOS
export HELM_HOST="localhost:44134"
tiller -listen ${HELM_HOST} -alsologtostderr &
helm init --client-only
helm repo add app-name https://repository.example.com
helm repo update
#{helm_install_comand}
EOS
end
let(:helm_install_comand) do
<<~EOS.squish
helm upgrade app-name chart-name
--install
--reset-values
--version 1.2.3
--set rbac.create\\=false,rbac.enabled\\=false
--namespace gitlab-managed-apps
-f /data/helm/app-name/config/values.yaml
EOS
end
end
context 'tillerless feature disabled' do
before do
stub_feature_flags(managed_apps_local_tiller: false)
end
let(:tls_flags) do let(:tls_flags) do
<<~EOS.squish <<~EOS.squish
--tls --tls
...@@ -32,8 +64,6 @@ describe Gitlab::Kubernetes::Helm::InstallCommand do ...@@ -32,8 +64,6 @@ describe Gitlab::Kubernetes::Helm::InstallCommand do
EOS EOS
end end
subject { install_command }
it_behaves_like 'helm commands' do it_behaves_like 'helm commands' do
let(:commands) do let(:commands) do
<<~EOS <<~EOS
...@@ -58,6 +88,7 @@ describe Gitlab::Kubernetes::Helm::InstallCommand do ...@@ -58,6 +88,7 @@ describe Gitlab::Kubernetes::Helm::InstallCommand do
EOS EOS
end end
end end
end
context 'when rbac is true' do context 'when rbac is true' do
let(:rbac) { true } let(:rbac) { true }
...@@ -65,8 +96,9 @@ describe Gitlab::Kubernetes::Helm::InstallCommand do ...@@ -65,8 +96,9 @@ describe Gitlab::Kubernetes::Helm::InstallCommand do
it_behaves_like 'helm commands' do it_behaves_like 'helm commands' do
let(:commands) do let(:commands) do
<<~EOS <<~EOS
helm init --upgrade export HELM_HOST="localhost:44134"
for i in $(seq 1 30); do helm version #{tls_flags} && s=0 && break || s=$?; sleep 1s; echo \"Retrying ($i)...\"; done; (exit $s) tiller -listen ${HELM_HOST} -alsologtostderr &
helm init --client-only
helm repo add app-name https://repository.example.com helm repo add app-name https://repository.example.com
helm repo update helm repo update
#{helm_install_command} #{helm_install_command}
...@@ -78,7 +110,6 @@ describe Gitlab::Kubernetes::Helm::InstallCommand do ...@@ -78,7 +110,6 @@ describe Gitlab::Kubernetes::Helm::InstallCommand do
helm upgrade app-name chart-name helm upgrade app-name chart-name
--install --install
--reset-values --reset-values
#{tls_flags}
--version 1.2.3 --version 1.2.3
--set rbac.create\\=true,rbac.enabled\\=true --set rbac.create\\=true,rbac.enabled\\=true
--namespace gitlab-managed-apps --namespace gitlab-managed-apps
...@@ -94,8 +125,9 @@ describe Gitlab::Kubernetes::Helm::InstallCommand do ...@@ -94,8 +125,9 @@ describe Gitlab::Kubernetes::Helm::InstallCommand do
it_behaves_like 'helm commands' do it_behaves_like 'helm commands' do
let(:commands) do let(:commands) do
<<~EOS <<~EOS
helm init --upgrade export HELM_HOST="localhost:44134"
for i in $(seq 1 30); do helm version #{tls_flags} && s=0 && break || s=$?; sleep 1s; echo \"Retrying ($i)...\"; done; (exit $s) tiller -listen ${HELM_HOST} -alsologtostderr &
helm init --client-only
helm repo add app-name https://repository.example.com helm repo add app-name https://repository.example.com
helm repo update helm repo update
/bin/date /bin/date
...@@ -109,7 +141,6 @@ describe Gitlab::Kubernetes::Helm::InstallCommand do ...@@ -109,7 +141,6 @@ describe Gitlab::Kubernetes::Helm::InstallCommand do
helm upgrade app-name chart-name helm upgrade app-name chart-name
--install --install
--reset-values --reset-values
#{tls_flags}
--version 1.2.3 --version 1.2.3
--set rbac.create\\=false,rbac.enabled\\=false --set rbac.create\\=false,rbac.enabled\\=false
--namespace gitlab-managed-apps --namespace gitlab-managed-apps
...@@ -125,8 +156,9 @@ describe Gitlab::Kubernetes::Helm::InstallCommand do ...@@ -125,8 +156,9 @@ describe Gitlab::Kubernetes::Helm::InstallCommand do
it_behaves_like 'helm commands' do it_behaves_like 'helm commands' do
let(:commands) do let(:commands) do
<<~EOS <<~EOS
helm init --upgrade export HELM_HOST="localhost:44134"
for i in $(seq 1 30); do helm version #{tls_flags} && s=0 && break || s=$?; sleep 1s; echo \"Retrying ($i)...\"; done; (exit $s) tiller -listen ${HELM_HOST} -alsologtostderr &
helm init --client-only
helm repo add app-name https://repository.example.com helm repo add app-name https://repository.example.com
helm repo update helm repo update
#{helm_install_command} #{helm_install_command}
...@@ -140,7 +172,6 @@ describe Gitlab::Kubernetes::Helm::InstallCommand do ...@@ -140,7 +172,6 @@ describe Gitlab::Kubernetes::Helm::InstallCommand do
helm upgrade app-name chart-name helm upgrade app-name chart-name
--install --install
--reset-values --reset-values
#{tls_flags}
--version 1.2.3 --version 1.2.3
--set rbac.create\\=false,rbac.enabled\\=false --set rbac.create\\=false,rbac.enabled\\=false
--namespace gitlab-managed-apps --namespace gitlab-managed-apps
...@@ -156,8 +187,9 @@ describe Gitlab::Kubernetes::Helm::InstallCommand do ...@@ -156,8 +187,9 @@ describe Gitlab::Kubernetes::Helm::InstallCommand do
it_behaves_like 'helm commands' do it_behaves_like 'helm commands' do
let(:commands) do let(:commands) do
<<~EOS <<~EOS
helm init --upgrade export HELM_HOST="localhost:44134"
for i in $(seq 1 30); do helm version && s=0 && break || s=$?; sleep 1s; echo \"Retrying ($i)...\"; done; (exit $s) tiller -listen ${HELM_HOST} -alsologtostderr &
helm init --client-only
helm repo add app-name https://repository.example.com helm repo add app-name https://repository.example.com
helm repo update helm repo update
#{helm_install_command} #{helm_install_command}
...@@ -184,8 +216,9 @@ describe Gitlab::Kubernetes::Helm::InstallCommand do ...@@ -184,8 +216,9 @@ describe Gitlab::Kubernetes::Helm::InstallCommand do
it_behaves_like 'helm commands' do it_behaves_like 'helm commands' do
let(:commands) do let(:commands) do
<<~EOS <<~EOS
helm init --upgrade export HELM_HOST="localhost:44134"
for i in $(seq 1 30); do helm version #{tls_flags} && s=0 && break || s=$?; sleep 1s; echo \"Retrying ($i)...\"; done; (exit $s) tiller -listen ${HELM_HOST} -alsologtostderr &
helm init --client-only
helm repo add app-name https://repository.example.com helm repo add app-name https://repository.example.com
helm repo update helm repo update
#{helm_install_command} #{helm_install_command}
...@@ -197,7 +230,6 @@ describe Gitlab::Kubernetes::Helm::InstallCommand do ...@@ -197,7 +230,6 @@ describe Gitlab::Kubernetes::Helm::InstallCommand do
helm upgrade app-name chart-name helm upgrade app-name chart-name
--install --install
--reset-values --reset-values
#{tls_flags}
--set rbac.create\\=false,rbac.enabled\\=false --set rbac.create\\=false,rbac.enabled\\=false
--namespace gitlab-managed-apps --namespace gitlab-managed-apps
-f /data/helm/app-name/config/values.yaml -f /data/helm/app-name/config/values.yaml
......
...@@ -382,6 +382,19 @@ describe Notes::CreateService do ...@@ -382,6 +382,19 @@ describe Notes::CreateService do
end.to change { existing_note.type }.from(nil).to('DiscussionNote') end.to change { existing_note.type }.from(nil).to('DiscussionNote')
.and change { existing_note.updated_at } .and change { existing_note.updated_at }
end end
context 'discussion to reply cannot be found' do
before do
existing_note.delete
end
it 'returns an note with errors' do
note = subject
expect(note.errors).not_to be_empty
expect(note.errors[:base]).to eq(['Discussion to reply to cannot be found'])
end
end
end end
describe "usage counter" do describe "usage counter" do
......
...@@ -26,6 +26,7 @@ end ...@@ -26,6 +26,7 @@ end
RSpec.shared_examples 'a Note mutation when there are active record validation errors' do |model: Note| RSpec.shared_examples 'a Note mutation when there are active record validation errors' do |model: Note|
before do before do
expect_next_instance_of(model) do |note| expect_next_instance_of(model) do |note|
allow(note).to receive_message_chain(:errors, :empty?).and_return(true)
expect(note).to receive(:valid?).at_least(:once).and_return(false) expect(note).to receive(:valid?).at_least(:once).and_return(false)
expect(note).to receive_message_chain( expect(note).to receive_message_chain(
:errors, :errors,
......
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