Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
3acaaf7231
commit
0978fc4c40
|
@ -3,7 +3,7 @@ import { EditorContent as TiptapEditorContent } from '@tiptap/vue-2';
|
|||
import { __ } from '~/locale';
|
||||
import { VARIANT_DANGER } from '~/flash';
|
||||
import { createContentEditor } from '../services/create_content_editor';
|
||||
import { ALERT_EVENT } from '../constants';
|
||||
import { ALERT_EVENT, TIPTAP_AUTOFOCUS_OPTIONS } from '../constants';
|
||||
import ContentEditorAlert from './content_editor_alert.vue';
|
||||
import ContentEditorProvider from './content_editor_provider.vue';
|
||||
import EditorStateObserver from './editor_state_observer.vue';
|
||||
|
@ -51,6 +51,12 @@ export default {
|
|||
required: false,
|
||||
default: '',
|
||||
},
|
||||
autofocus: {
|
||||
type: [String, Boolean],
|
||||
required: false,
|
||||
default: false,
|
||||
validator: (autofocus) => TIPTAP_AUTOFOCUS_OPTIONS.includes(autofocus),
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -67,7 +73,7 @@ export default {
|
|||
},
|
||||
},
|
||||
created() {
|
||||
const { renderMarkdown, uploadsPath, extensions, serializerConfig } = this;
|
||||
const { renderMarkdown, uploadsPath, extensions, serializerConfig, autofocus } = this;
|
||||
|
||||
// This is a non-reactive attribute intentionally since this is a complex object.
|
||||
this.contentEditor = createContentEditor({
|
||||
|
@ -75,6 +81,9 @@ export default {
|
|||
uploadsPath,
|
||||
extensions,
|
||||
serializerConfig,
|
||||
tiptapOptions: {
|
||||
autofocus,
|
||||
},
|
||||
});
|
||||
},
|
||||
mounted() {
|
||||
|
|
|
@ -66,3 +66,5 @@ export const SAFE_VIDEO_EXT = ['mp4', 'm4v', 'mov', 'webm', 'ogv'];
|
|||
export const SAFE_AUDIO_EXT = ['mp3', 'oga', 'ogg', 'spx', 'wav'];
|
||||
|
||||
export const DIAGRAM_LANGUAGES = ['plantuml', 'mermaid'];
|
||||
|
||||
export const TIPTAP_AUTOFOCUS_OPTIONS = [true, false, 'start', 'end', 'all'];
|
||||
|
|
|
@ -299,7 +299,7 @@ export default {
|
|||
:uploads-path="pageInfo.uploadsPath"
|
||||
:enable-content-editor="isMarkdownFormat"
|
||||
:enable-preview="isMarkdownFormat"
|
||||
:autofocus="pageInfo.persisted"
|
||||
:init-on-autofocus="pageInfo.persisted"
|
||||
:form-field-placeholder="$options.i18n.content.placeholder"
|
||||
:form-field-aria-label="$options.i18n.content.label"
|
||||
form-field-id="wiki_content"
|
||||
|
|
|
@ -31,7 +31,8 @@ export default {
|
|||
},
|
||||
uploadsPath: {
|
||||
type: String,
|
||||
required: true,
|
||||
required: false,
|
||||
default: () => window.uploads_path,
|
||||
},
|
||||
enableContentEditor: {
|
||||
type: Boolean,
|
||||
|
@ -56,11 +57,6 @@ export default {
|
|||
required: false,
|
||||
default: true,
|
||||
},
|
||||
autofocus: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
formFieldPlaceholder: {
|
||||
type: String,
|
||||
required: false,
|
||||
|
@ -71,17 +67,30 @@ export default {
|
|||
required: false,
|
||||
default: '',
|
||||
},
|
||||
initOnAutofocus: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
editingMode: EDITING_MODE_MARKDOWN_FIELD,
|
||||
switchEditingControlEnabled: true,
|
||||
autofocus: this.initOnAutofocus,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
isContentEditorActive() {
|
||||
return this.enableContentEditor && this.editingMode === EDITING_MODE_CONTENT_EDITOR;
|
||||
},
|
||||
contentEditorAutofocus() {
|
||||
// Match textarea focus behavior
|
||||
return this.autofocus ? 'end' : false;
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.autofocusTextarea(this.editingMode);
|
||||
},
|
||||
methods: {
|
||||
updateMarkdownFromContentEditor({ markdown }) {
|
||||
|
@ -99,9 +108,25 @@ export default {
|
|||
renderMarkdown(markdown) {
|
||||
return axios.post(this.renderMarkdownPath, { text: markdown }).then(({ data }) => data.body);
|
||||
},
|
||||
onEditingModeChange(editingMode) {
|
||||
this.notifyEditingModeChange(editingMode);
|
||||
this.enableAutofocus(editingMode);
|
||||
},
|
||||
onEditingModeRestored(editingMode) {
|
||||
this.notifyEditingModeChange(editingMode);
|
||||
},
|
||||
notifyEditingModeChange(editingMode) {
|
||||
this.$emit(editingMode);
|
||||
},
|
||||
enableAutofocus(editingMode) {
|
||||
this.autofocus = true;
|
||||
this.autofocusTextarea(editingMode);
|
||||
},
|
||||
autofocusTextarea(editingMode) {
|
||||
if (this.autofocus && editingMode === EDITING_MODE_MARKDOWN_FIELD) {
|
||||
this.$refs.textarea.focus();
|
||||
}
|
||||
},
|
||||
},
|
||||
switchEditingControlOptions: [
|
||||
{ text: __('Source'), value: EDITING_MODE_MARKDOWN_FIELD },
|
||||
|
@ -119,13 +144,13 @@ export default {
|
|||
class="gl-display-flex"
|
||||
:options="$options.switchEditingControlOptions"
|
||||
:disabled="!enableContentEditor || !switchEditingControlEnabled"
|
||||
@change="notifyEditingModeChange"
|
||||
@change="onEditingModeChange"
|
||||
/>
|
||||
</div>
|
||||
<local-storage-sync
|
||||
v-model="editingMode"
|
||||
storage-key="gl-wiki-content-editor-enabled"
|
||||
@input="notifyEditingModeChange"
|
||||
@input="onEditingModeRestored"
|
||||
/>
|
||||
<markdown-field
|
||||
v-if="!isContentEditorActive"
|
||||
|
@ -148,7 +173,6 @@ export default {
|
|||
dir="auto"
|
||||
data-supports-quick-actions="false"
|
||||
data-qa-selector="markdown_editor_form_field"
|
||||
:autofocus="autofocus"
|
||||
:aria-label="formFieldAriaLabel"
|
||||
:placeholder="formFieldPlaceholder"
|
||||
@input="updateMarkdownFromMarkdownField"
|
||||
|
@ -161,6 +185,7 @@ export default {
|
|||
:render-markdown="renderMarkdown"
|
||||
:uploads-path="uploadsPath"
|
||||
:markdown="value"
|
||||
:autofocus="contentEditorAutofocus"
|
||||
@change="updateMarkdownFromContentEditor"
|
||||
@loading="disableSwitchEditingControl"
|
||||
@loadingSuccess="enableSwitchEditingControl"
|
||||
|
|
|
@ -856,7 +856,6 @@ module Ci
|
|||
variables.append(key: 'CI_COMMIT_REF_NAME', value: source_ref)
|
||||
variables.append(key: 'CI_COMMIT_REF_SLUG', value: source_ref_slug)
|
||||
variables.append(key: 'CI_COMMIT_BRANCH', value: ref) if branch?
|
||||
variables.append(key: 'CI_COMMIT_TAG', value: ref) if tag?
|
||||
variables.append(key: 'CI_COMMIT_MESSAGE', value: git_commit_message.to_s)
|
||||
variables.append(key: 'CI_COMMIT_TITLE', value: git_commit_full_title.to_s)
|
||||
variables.append(key: 'CI_COMMIT_DESCRIPTION', value: git_commit_description.to_s)
|
||||
|
@ -869,7 +868,8 @@ module Ci
|
|||
variables.append(key: 'CI_BUILD_BEFORE_SHA', value: before_sha)
|
||||
variables.append(key: 'CI_BUILD_REF_NAME', value: source_ref)
|
||||
variables.append(key: 'CI_BUILD_REF_SLUG', value: source_ref_slug)
|
||||
variables.append(key: 'CI_BUILD_TAG', value: ref) if tag?
|
||||
|
||||
variables.concat(predefined_commit_tag_variables)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -894,6 +894,20 @@ module Ci
|
|||
end
|
||||
end
|
||||
|
||||
def predefined_commit_tag_variables
|
||||
strong_memoize(:predefined_commit_ref_variables) do
|
||||
Gitlab::Ci::Variables::Collection.new.tap do |variables|
|
||||
next variables unless tag?
|
||||
|
||||
variables.append(key: 'CI_COMMIT_TAG', value: ref)
|
||||
variables.append(key: 'CI_COMMIT_TAG_MESSAGE', value: project.repository.find_tag(ref).message)
|
||||
|
||||
# legacy variable
|
||||
variables.append(key: 'CI_BUILD_TAG', value: ref)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def queued_duration
|
||||
return unless started_at
|
||||
|
||||
|
|
|
@ -77,7 +77,7 @@
|
|||
= _("The maximum file size in megabytes for individual job artifacts.")
|
||||
= link_to sprite_icon('question-o'), help_page_path('user/admin_area/settings/continuous_integration', anchor: 'maximum-artifacts-size'), target: '_blank', rel: 'noopener noreferrer'
|
||||
|
||||
= f.submit _('Save changes'), class: "btn gl-button btn-confirm"
|
||||
= f.submit _('Save changes'), pajamas_button: true
|
||||
|
||||
%hr
|
||||
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
- return unless custom_attributes.present?
|
||||
|
||||
.card
|
||||
.card-header
|
||||
= render Pajamas::CardComponent.new(body_options: { class: 'gl-py-0' }) do |c|
|
||||
- c.header do
|
||||
= link_to(_('Custom Attributes'), help_page_path('api/custom_attributes.md'))
|
||||
%ul.content-list
|
||||
- custom_attributes.each do |custom_attribute|
|
||||
%li
|
||||
%span.light
|
||||
= custom_attribute.key
|
||||
%strong
|
||||
= custom_attribute.value
|
||||
- c.body do
|
||||
%ul.content-list
|
||||
- custom_attributes.each do |custom_attribute|
|
||||
%li
|
||||
%span.light
|
||||
= custom_attribute.key
|
||||
%strong
|
||||
= custom_attribute.value
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class FinalizeTaskSystemNoteRenaming < Gitlab::Database::Migration[2.0]
|
||||
disable_ddl_transaction!
|
||||
|
||||
restrict_gitlab_migration gitlab_schema: :gitlab_main
|
||||
|
||||
MIGRATION = 'RenameTaskSystemNoteToChecklistItem'
|
||||
|
||||
def up
|
||||
ensure_batched_background_migration_is_finished(
|
||||
job_class_name: MIGRATION,
|
||||
table_name: :system_note_metadata,
|
||||
column_name: :id,
|
||||
job_arguments: []
|
||||
)
|
||||
end
|
||||
|
||||
def down
|
||||
# noop
|
||||
end
|
||||
end
|
|
@ -0,0 +1,15 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class RemoveTaskSystemNoteRenameTempIndex < Gitlab::Database::Migration[2.0]
|
||||
disable_ddl_transaction!
|
||||
|
||||
INDEX_NAME = 'tmp_index_system_note_metadata_on_id_where_task'
|
||||
|
||||
def up
|
||||
remove_concurrent_index_by_name :system_note_metadata, INDEX_NAME
|
||||
end
|
||||
|
||||
def down
|
||||
add_concurrent_index :system_note_metadata, [:id, :action], where: "action = 'task'", name: INDEX_NAME
|
||||
end
|
||||
end
|
|
@ -0,0 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class RemoveTraceColumnFromCiBuilds < Gitlab::Database::Migration[2.0]
|
||||
enable_lock_retries!
|
||||
|
||||
def change
|
||||
remove_column :ci_builds, :trace, :text
|
||||
end
|
||||
end
|
|
@ -0,0 +1 @@
|
|||
e683bd10619f9ceee2a5d330ca4d6b9d396ad8934095b707a0eec5d49cdaf2be
|
|
@ -0,0 +1 @@
|
|||
6a4677165bca249c369214aee9fae331fde4dc716544bac93c06f0ee33222455
|
|
@ -0,0 +1 @@
|
|||
6ce159118651ec93989e8f111528ad2134e46f359c483b60239290d677f9f4f4
|
|
@ -12601,7 +12601,6 @@ CREATE TABLE ci_build_trace_metadata (
|
|||
CREATE TABLE ci_builds (
|
||||
status character varying,
|
||||
finished_at timestamp without time zone,
|
||||
trace text,
|
||||
created_at timestamp without time zone,
|
||||
updated_at timestamp without time zone,
|
||||
started_at timestamp without time zone,
|
||||
|
@ -30910,8 +30909,6 @@ CREATE INDEX tmp_index_project_statistics_cont_registry_size ON project_statisti
|
|||
|
||||
CREATE INDEX tmp_index_system_note_metadata_on_attention_request_actions ON system_note_metadata USING btree (id) WHERE ((action)::text = ANY ((ARRAY['attention_requested'::character varying, 'attention_request_removed'::character varying])::text[]));
|
||||
|
||||
CREATE INDEX tmp_index_system_note_metadata_on_id_where_task ON system_note_metadata USING btree (id, action) WHERE ((action)::text = 'task'::text);
|
||||
|
||||
CREATE INDEX tmp_index_vulnerability_occurrences_on_id_and_scanner_id ON vulnerability_occurrences USING btree (id, scanner_id) WHERE (report_type = ANY (ARRAY[7, 99]));
|
||||
|
||||
CREATE UNIQUE INDEX uniq_pkgs_deb_grp_architectures_on_distribution_id_and_name ON packages_debian_group_architectures USING btree (distribution_id, name);
|
||||
|
|
|
@ -27,8 +27,9 @@ Features behind flags can be gradually rolled out, typically:
|
|||
1. The feature flag is removed.
|
||||
|
||||
These features can be enabled and disabled to allow or prevent users from using
|
||||
them. It can be done by GitLab administrators with access to GitLab Rails
|
||||
console.
|
||||
them. It can be done by GitLab administrators with access to the
|
||||
[Rails console](#how-to-enable-and-disable-features-behind-flags) or the
|
||||
[Feature flags API](../api/features.md).
|
||||
|
||||
When you disable a feature flag, the feature is hidden from users and all of the functionality is turned off.
|
||||
For example, data is not recorded and services do not run.
|
||||
|
|
|
@ -22,7 +22,8 @@ a database schema.
|
|||
Adding a `:migration` tag to a test signature enables some custom RSpec
|
||||
`before` and `after` hooks in our
|
||||
[`spec/support/migration.rb`](https://gitlab.com/gitlab-org/gitlab/-/blob/f81fa6ab1dd788b70ef44b85aaba1f31ffafae7d/spec/support/migration.rb)
|
||||
to run.
|
||||
to run. If performing a migration against a database schema other than
|
||||
`:gitlab_main` (for example `:gitlab_ci`), then you must specify it as well: `migration: :gitlab_ci`. See [spec/migrations/change_public_projects_cost_factor_spec.rb](https://gitlab.com/gitlab-org/gitlab/blob/master/spec/migrations/change_public_projects_cost_factor_spec.rb#L6-6) for an example.
|
||||
|
||||
A `before` hook reverts all migrations to the point that a migration
|
||||
under test is not yet migrated.
|
||||
|
|
|
@ -19,14 +19,14 @@ Group push rules allow group maintainers to set
|
|||
|
||||
In GitLab 15.4 and later, to configure push rules for a group:
|
||||
|
||||
1. On the left sidebar, select **Push rules**.
|
||||
1. On the left sidebar, select **Settings > Repository**.
|
||||
1. Expand the **Pre-defined push rules** section.
|
||||
1. Select the settings you want.
|
||||
1. Select **Save Push Rules**.
|
||||
|
||||
In GitLab 15.3 and earlier, to configure push rules for a group:
|
||||
|
||||
1. On the left sidebar, select **Settings > Repository** page.
|
||||
1. Expand the **Pre-defined push rules** section.
|
||||
1. On the left sidebar, select **Push rules**.
|
||||
1. Select the settings you want.
|
||||
1. Select **Save Push Rules**.
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ module Gitlab
|
|||
end
|
||||
|
||||
def id_for_already_imported_cache(note)
|
||||
note.id
|
||||
note[:id]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -27,7 +27,7 @@ module Gitlab
|
|||
end
|
||||
|
||||
def id_for_already_imported_cache(event)
|
||||
event.id
|
||||
event[:id]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -33,7 +33,7 @@ module Gitlab
|
|||
end
|
||||
|
||||
def id_for_already_imported_cache(issue)
|
||||
issue.number
|
||||
issue[:number]
|
||||
end
|
||||
|
||||
def collection_options
|
||||
|
|
|
@ -22,7 +22,7 @@ module Gitlab
|
|||
end
|
||||
|
||||
def already_imported?(label)
|
||||
existing_labels.include?(label.name)
|
||||
existing_labels.include?(label[:name])
|
||||
end
|
||||
|
||||
def build_labels_cache
|
||||
|
@ -33,8 +33,8 @@ module Gitlab
|
|||
time = Time.zone.now
|
||||
|
||||
{
|
||||
title: label.name,
|
||||
color: '#' + label.color,
|
||||
title: label[:name],
|
||||
color: '#' + label[:color],
|
||||
project_id: project.id,
|
||||
type: 'ProjectLabel',
|
||||
created_at: time,
|
||||
|
|
|
@ -22,7 +22,7 @@ module Gitlab
|
|||
end
|
||||
|
||||
def already_imported?(milestone)
|
||||
existing_milestones.include?(milestone.number)
|
||||
existing_milestones.include?(milestone[:number])
|
||||
end
|
||||
|
||||
def build_milestones_cache
|
||||
|
@ -31,19 +31,19 @@ module Gitlab
|
|||
|
||||
def build(milestone)
|
||||
{
|
||||
iid: milestone.number,
|
||||
title: milestone.title,
|
||||
description: milestone.description,
|
||||
iid: milestone[:number],
|
||||
title: milestone[:title],
|
||||
description: milestone[:description],
|
||||
project_id: project.id,
|
||||
state: state_for(milestone),
|
||||
due_date: milestone.due_on&.to_date,
|
||||
created_at: milestone.created_at,
|
||||
updated_at: milestone.updated_at
|
||||
due_date: milestone[:due_on]&.to_date,
|
||||
created_at: milestone[:created_at],
|
||||
updated_at: milestone[:updated_at]
|
||||
}
|
||||
end
|
||||
|
||||
def state_for(milestone)
|
||||
milestone.state == 'open' ? :active : :closed
|
||||
milestone[:state] == 'open' ? :active : :closed
|
||||
end
|
||||
|
||||
def each_milestone
|
||||
|
|
|
@ -27,7 +27,7 @@ module Gitlab
|
|||
end
|
||||
|
||||
def id_for_already_imported_cache(note)
|
||||
note.id
|
||||
note[:id]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -19,7 +19,7 @@ module Gitlab
|
|||
end
|
||||
|
||||
def id_for_already_imported_cache(pr)
|
||||
pr.number
|
||||
pr[:number]
|
||||
end
|
||||
|
||||
def object_type
|
||||
|
@ -55,11 +55,11 @@ module Gitlab
|
|||
def update_repository?(pr)
|
||||
last_update = project.last_repository_updated_at || project.created_at
|
||||
|
||||
return false if pr.updated_at < last_update
|
||||
return false if pr[:updated_at] < last_update
|
||||
|
||||
# PRs may be updated without there actually being new commits, thus we
|
||||
# check to make sure we only re-fetch if truly necessary.
|
||||
!(commit_exists?(pr.head.sha) && commit_exists?(pr.base.sha))
|
||||
!(commit_exists?(pr.dig(:head, :sha)) && commit_exists?(pr.dig(:base, :sha)))
|
||||
end
|
||||
|
||||
def commit_exists?(sha)
|
||||
|
|
|
@ -34,7 +34,7 @@ module Gitlab
|
|||
end
|
||||
|
||||
def id_for_already_imported_cache(review)
|
||||
review.id
|
||||
review[:id]
|
||||
end
|
||||
|
||||
# The worker can be interrupted, by rate limit for instance,
|
||||
|
@ -52,7 +52,7 @@ module Gitlab
|
|||
|
||||
Gitlab::GithubImport::ObjectCounter.increment(project, object_type, :fetched)
|
||||
|
||||
review.merge_request_id = merge_request.id
|
||||
review[:merge_request_id] = merge_request.id
|
||||
yield(review)
|
||||
|
||||
mark_as_imported(review)
|
||||
|
|
|
@ -21,21 +21,21 @@ module Gitlab
|
|||
end
|
||||
|
||||
def already_imported?(release)
|
||||
existing_tags.include?(release.tag_name) || release.tag_name.nil?
|
||||
existing_tags.include?(release[:tag_name]) || release[:tag_name].nil?
|
||||
end
|
||||
|
||||
def build(release)
|
||||
existing_tags.add(release.tag_name)
|
||||
existing_tags.add(release[:tag_name])
|
||||
|
||||
{
|
||||
name: release.name,
|
||||
tag: release.tag_name,
|
||||
name: release[:name],
|
||||
tag: release[:tag_name],
|
||||
author_id: fetch_author_id(release),
|
||||
description: description_for(release),
|
||||
created_at: release.created_at,
|
||||
updated_at: release.created_at,
|
||||
created_at: release[:created_at],
|
||||
updated_at: release[:created_at],
|
||||
# Draft releases will have a null published_at
|
||||
released_at: release.published_at || Time.current,
|
||||
released_at: release[:published_at] || Time.current,
|
||||
project_id: project.id
|
||||
}
|
||||
end
|
||||
|
@ -45,7 +45,7 @@ module Gitlab
|
|||
end
|
||||
|
||||
def description_for(release)
|
||||
release.body.presence || "Release for tag #{release.tag_name}"
|
||||
release[:body].presence || "Release for tag #{release[:tag_name]}"
|
||||
end
|
||||
|
||||
def object_type
|
||||
|
|
|
@ -28,7 +28,7 @@ module Gitlab
|
|||
Gitlab::GithubImport::ObjectCounter.increment(project, object_type, :fetched)
|
||||
|
||||
pull_request = parent_record.is_a? MergeRequest
|
||||
associated.issue = { 'number' => parent_record.iid, 'pull_request' => pull_request }
|
||||
associated[:issue] = { 'number' => parent_record.iid, 'pull_request' => pull_request }
|
||||
yield(associated)
|
||||
|
||||
mark_as_imported(associated)
|
||||
|
@ -78,7 +78,7 @@ module Gitlab
|
|||
end
|
||||
|
||||
def id_for_already_imported_cache(event)
|
||||
event.id
|
||||
event[:id]
|
||||
end
|
||||
|
||||
def collection_options
|
||||
|
@ -87,9 +87,9 @@ module Gitlab
|
|||
|
||||
# Cross-referenced events on Github doesn't have id.
|
||||
def compose_associated_id!(issuable, event)
|
||||
return if event.event != 'cross-referenced'
|
||||
return if event[:event] != 'cross-referenced'
|
||||
|
||||
event.id = "cross-reference##{issuable.iid}-in-#{event.source.issue.id}"
|
||||
event[:id] = "cross-reference##{issuable.iid}-in-#{event.dig(:source, :issue, :id)}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -21,31 +21,31 @@ module Gitlab
|
|||
#
|
||||
# note - An instance of `Sawyer::Resource` containing the note details.
|
||||
def self.from_api_response(note, additional_data = {})
|
||||
matches = note.html_url.match(NOTEABLE_ID_REGEX)
|
||||
matches = note[:html_url].match(NOTEABLE_ID_REGEX)
|
||||
|
||||
unless matches
|
||||
raise(
|
||||
ArgumentError,
|
||||
"The note URL #{note.html_url.inspect} is not supported"
|
||||
"The note URL #{note[:html_url].inspect} is not supported"
|
||||
)
|
||||
end
|
||||
|
||||
user = Representation::User.from_api_response(note.user) if note.user
|
||||
user = Representation::User.from_api_response(note[:user]) if note[:user]
|
||||
hash = {
|
||||
noteable_id: matches[:iid].to_i,
|
||||
file_path: note.path,
|
||||
commit_id: note.commit_id,
|
||||
original_commit_id: note.original_commit_id,
|
||||
diff_hunk: note.diff_hunk,
|
||||
file_path: note[:path],
|
||||
commit_id: note[:commit_id],
|
||||
original_commit_id: note[:original_commit_id],
|
||||
diff_hunk: note[:diff_hunk],
|
||||
author: user,
|
||||
note: note.body,
|
||||
created_at: note.created_at,
|
||||
updated_at: note.updated_at,
|
||||
note_id: note.id,
|
||||
end_line: note.line,
|
||||
start_line: note.start_line,
|
||||
side: note.side,
|
||||
in_reply_to_id: note.in_reply_to_id
|
||||
note: note[:body],
|
||||
created_at: note[:created_at],
|
||||
updated_at: note[:updated_at],
|
||||
note_id: note[:id],
|
||||
end_line: note[:line],
|
||||
start_line: note[:start_line],
|
||||
side: note[:side],
|
||||
in_reply_to_id: note[:in_reply_to_id]
|
||||
}
|
||||
|
||||
new(hash)
|
||||
|
|
|
@ -19,24 +19,24 @@ module Gitlab
|
|||
# details.
|
||||
def self.from_api_response(issue, additional_data = {})
|
||||
user =
|
||||
if issue.user
|
||||
Representation::User.from_api_response(issue.user)
|
||||
if issue[:user]
|
||||
Representation::User.from_api_response(issue[:user])
|
||||
end
|
||||
|
||||
hash = {
|
||||
iid: issue.number,
|
||||
title: issue.title,
|
||||
description: issue.body,
|
||||
milestone_number: issue.milestone&.number,
|
||||
state: issue.state == 'open' ? :opened : :closed,
|
||||
assignees: issue.assignees.map do |u|
|
||||
iid: issue[:number],
|
||||
title: issue[:title],
|
||||
description: issue[:body],
|
||||
milestone_number: issue.dig(:milestone, :number),
|
||||
state: issue[:state] == 'open' ? :opened : :closed,
|
||||
assignees: issue[:assignees].map do |u|
|
||||
Representation::User.from_api_response(u)
|
||||
end,
|
||||
label_names: issue.labels.map(&:name),
|
||||
label_names: issue[:labels].map { _1[:name] },
|
||||
author: user,
|
||||
created_at: issue.created_at,
|
||||
updated_at: issue.updated_at,
|
||||
pull_request: issue.pull_request ? true : false,
|
||||
created_at: issue[:created_at],
|
||||
updated_at: issue[:updated_at],
|
||||
pull_request: issue[:pull_request] ? true : false,
|
||||
work_item_type_id: additional_data[:work_item_type_id]
|
||||
}
|
||||
|
||||
|
|
|
@ -37,20 +37,20 @@ module Gitlab
|
|||
# event - An instance of `Sawyer::Resource` containing the event details.
|
||||
def from_api_response(event, additional_data = {})
|
||||
new(
|
||||
id: event.id,
|
||||
actor: user_representation(event.actor),
|
||||
event: event.event,
|
||||
commit_id: event.commit_id,
|
||||
label_title: event.label && event.label[:name],
|
||||
old_title: event.rename && event.rename[:from],
|
||||
new_title: event.rename && event.rename[:to],
|
||||
milestone_title: event.milestone && event.milestone[:title],
|
||||
issue: event.issue&.to_h&.symbolize_keys,
|
||||
source: event.source,
|
||||
assignee: user_representation(event.assignee),
|
||||
requested_reviewer: user_representation(event.requested_reviewer),
|
||||
review_requester: user_representation(event.review_requester),
|
||||
created_at: event.created_at
|
||||
id: event[:id],
|
||||
actor: user_representation(event[:actor]),
|
||||
event: event[:event],
|
||||
commit_id: event[:commit_id],
|
||||
label_title: event.dig(:label, :name),
|
||||
old_title: event.dig(:rename, :from),
|
||||
new_title: event.dig(:rename, :to),
|
||||
milestone_title: event.dig(:milestone, :title),
|
||||
issue: event[:issue]&.symbolize_keys,
|
||||
source: event[:source],
|
||||
assignee: user_representation(event[:assignee]),
|
||||
requested_reviewer: user_representation(event[:requested_reviewer]),
|
||||
review_requester: user_representation(event[:review_requester]),
|
||||
created_at: event[:created_at]
|
||||
)
|
||||
end
|
||||
|
||||
|
|
|
@ -18,12 +18,12 @@ module Gitlab
|
|||
#
|
||||
# note - An instance of `Sawyer::Resource` containing the note details.
|
||||
def self.from_api_response(note, additional_data = {})
|
||||
matches = note.html_url.match(NOTEABLE_TYPE_REGEX)
|
||||
matches = note[:html_url].match(NOTEABLE_TYPE_REGEX)
|
||||
|
||||
if !matches || !matches[:type]
|
||||
raise(
|
||||
ArgumentError,
|
||||
"The note URL #{note.html_url.inspect} is not supported"
|
||||
"The note URL #{note[:html_url].inspect} is not supported"
|
||||
)
|
||||
end
|
||||
|
||||
|
@ -34,15 +34,15 @@ module Gitlab
|
|||
'Issue'
|
||||
end
|
||||
|
||||
user = Representation::User.from_api_response(note.user) if note.user
|
||||
user = Representation::User.from_api_response(note[:user]) if note[:user]
|
||||
hash = {
|
||||
noteable_type: noteable_type,
|
||||
noteable_id: matches[:iid].to_i,
|
||||
author: user,
|
||||
note: note.body,
|
||||
created_at: note.created_at,
|
||||
updated_at: note.updated_at,
|
||||
note_id: note.id
|
||||
note: note[:body],
|
||||
created_at: note[:created_at],
|
||||
updated_at: note[:updated_at],
|
||||
note_id: note[:id]
|
||||
}
|
||||
|
||||
new(hash)
|
||||
|
|
|
@ -19,28 +19,28 @@ module Gitlab
|
|||
#
|
||||
# issue - An instance of `Sawyer::Resource` containing the PR details.
|
||||
def self.from_api_response(pr, additional_data = {})
|
||||
assignee = Representation::User.from_api_response(pr.assignee) if pr.assignee
|
||||
user = Representation::User.from_api_response(pr.user) if pr.user
|
||||
merged_by = Representation::User.from_api_response(pr.merged_by) if pr.merged_by
|
||||
assignee = Representation::User.from_api_response(pr[:assignee]) if pr[:assignee]
|
||||
user = Representation::User.from_api_response(pr[:user]) if pr[:user]
|
||||
merged_by = Representation::User.from_api_response(pr[:merged_by]) if pr[:merged_by]
|
||||
|
||||
hash = {
|
||||
iid: pr.number,
|
||||
title: pr.title,
|
||||
description: pr.body,
|
||||
source_branch: pr.head.ref,
|
||||
target_branch: pr.base.ref,
|
||||
source_branch_sha: pr.head.sha,
|
||||
target_branch_sha: pr.base.sha,
|
||||
source_repository_id: pr.head&.repo&.id,
|
||||
target_repository_id: pr.base&.repo&.id,
|
||||
source_repository_owner: pr.head&.user&.login,
|
||||
state: pr.state == 'open' ? :opened : :closed,
|
||||
milestone_number: pr.milestone&.number,
|
||||
iid: pr[:number],
|
||||
title: pr[:title],
|
||||
description: pr[:body],
|
||||
source_branch: pr.dig(:head, :ref),
|
||||
target_branch: pr.dig(:base, :ref),
|
||||
source_branch_sha: pr.dig(:head, :sha),
|
||||
target_branch_sha: pr.dig(:base, :sha),
|
||||
source_repository_id: pr.dig(:head, :repo, :id),
|
||||
target_repository_id: pr.dig(:base, :repo, :id),
|
||||
source_repository_owner: pr.dig(:head, :user, :login),
|
||||
state: pr[:state] == 'open' ? :opened : :closed,
|
||||
milestone_number: pr.dig(:milestone, :number),
|
||||
author: user,
|
||||
assignee: assignee,
|
||||
created_at: pr.created_at,
|
||||
updated_at: pr.updated_at,
|
||||
merged_at: pr.merged_at,
|
||||
created_at: pr[:created_at],
|
||||
updated_at: pr[:updated_at],
|
||||
merged_at: pr[:merged_at],
|
||||
merged_by: merged_by
|
||||
}
|
||||
|
||||
|
|
|
@ -11,16 +11,19 @@ module Gitlab
|
|||
|
||||
expose_attribute :author, :note, :review_type, :submitted_at, :merge_request_id, :review_id
|
||||
|
||||
# Builds a PullRequestReview from a GitHub API response.
|
||||
#
|
||||
# review - An instance of `Sawyer::Resource` containing the note details.
|
||||
def self.from_api_response(review, additional_data = {})
|
||||
user = Representation::User.from_api_response(review.user) if review.user
|
||||
user = Representation::User.from_api_response(review[:user]) if review[:user]
|
||||
|
||||
new(
|
||||
merge_request_id: review.merge_request_id,
|
||||
merge_request_id: review[:merge_request_id],
|
||||
author: user,
|
||||
note: review.body,
|
||||
review_type: review.state,
|
||||
submitted_at: review.submitted_at,
|
||||
review_id: review.id
|
||||
note: review[:body],
|
||||
review_type: review[:state],
|
||||
submitted_at: review[:submitted_at],
|
||||
review_id: review[:id]
|
||||
)
|
||||
end
|
||||
|
||||
|
|
|
@ -16,8 +16,8 @@ module Gitlab
|
|||
# user - An instance of `Sawyer::Resource` containing the user details.
|
||||
def self.from_api_response(user, additional_data = {})
|
||||
new(
|
||||
id: user.id,
|
||||
login: user.login
|
||||
id: user[:id],
|
||||
login: user[:login]
|
||||
)
|
||||
end
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ module Gitlab
|
|||
end
|
||||
|
||||
def id_for_already_imported_cache(associated)
|
||||
associated.id
|
||||
associated[:id]
|
||||
end
|
||||
|
||||
def parent_collection
|
||||
|
|
|
@ -39,18 +39,19 @@ module Gitlab
|
|||
#
|
||||
# If the object has no author ID we'll use the ID of the GitLab ghost
|
||||
# user.
|
||||
# object - An instance of `Sawyer::Resource` or a `Github::Representer`
|
||||
def author_id_for(object, author_key: :author)
|
||||
user_info = case author_key
|
||||
when :actor
|
||||
object&.actor
|
||||
object[:actor]
|
||||
when :assignee
|
||||
object&.assignee
|
||||
object[:assignee]
|
||||
when :requested_reviewer
|
||||
object&.requested_reviewer
|
||||
object[:requested_reviewer]
|
||||
when :review_requester
|
||||
object&.review_requester
|
||||
object[:review_requester]
|
||||
else
|
||||
object&.author
|
||||
object ? object[:author] : nil
|
||||
end
|
||||
|
||||
id = user_info ? user_id_for(user_info) : GithubImport.ghost_user_id
|
||||
|
@ -64,14 +65,14 @@ module Gitlab
|
|||
|
||||
# Returns the GitLab user ID of an issuable's assignee.
|
||||
def assignee_id_for(issuable)
|
||||
user_id_for(issuable.assignee) if issuable.assignee
|
||||
user_id_for(issuable[:assignee]) if issuable[:assignee]
|
||||
end
|
||||
|
||||
# Returns the GitLab user ID for a GitHub user.
|
||||
#
|
||||
# user - An instance of `Gitlab::GithubImport::Representation::User`.
|
||||
# user - An instance of `Gitlab::GithubImport::Representation::User` or `Sawyer::Resource`.
|
||||
def user_id_for(user)
|
||||
find(user.id, user.login) if user.present?
|
||||
find(user[:id], user[:login]) if user.present?
|
||||
end
|
||||
|
||||
# Returns the GitLab ID for the given GitHub ID or username.
|
||||
|
@ -114,7 +115,7 @@ module Gitlab
|
|||
|
||||
unless email
|
||||
user = client.user(username)
|
||||
email = Gitlab::Cache::Import::Caching.write(cache_key, user.email, timeout: timeout(user.email)) if user
|
||||
email = Gitlab::Cache::Import::Caching.write(cache_key, user[:email], timeout: timeout(user[:email])) if user
|
||||
end
|
||||
|
||||
email
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/bin/bash
|
||||
#!/bin/sh
|
||||
# This is based on https://gitlab.com/gitlab-org/gitlab-qa/-/blob/master/bin/slack
|
||||
#
|
||||
# Sends Slack notification MSG to CI_SLACK_WEBHOOK_URL (which needs to be set).
|
||||
|
|
|
@ -26,12 +26,13 @@ describe('ContentEditor', () => {
|
|||
const findEditorStateObserver = () => wrapper.findComponent(EditorStateObserver);
|
||||
const findLoadingIndicator = () => wrapper.findComponent(LoadingIndicator);
|
||||
const findContentEditorAlert = () => wrapper.findComponent(ContentEditorAlert);
|
||||
const createWrapper = ({ markdown } = {}) => {
|
||||
const createWrapper = ({ markdown, autofocus } = {}) => {
|
||||
wrapper = shallowMountExtended(ContentEditor, {
|
||||
propsData: {
|
||||
renderMarkdown,
|
||||
uploadsPath,
|
||||
markdown,
|
||||
autofocus,
|
||||
},
|
||||
stubs: {
|
||||
EditorStateObserver,
|
||||
|
@ -70,14 +71,22 @@ describe('ContentEditor', () => {
|
|||
expect(editorContent.classes()).toContain('md');
|
||||
});
|
||||
|
||||
it('renders ContentEditorProvider component', async () => {
|
||||
await createWrapper();
|
||||
it('allows setting the tiptap editor to autofocus', async () => {
|
||||
createWrapper({ autofocus: 'start' });
|
||||
|
||||
await nextTick();
|
||||
|
||||
expect(findEditorContent().props().editor.options.autofocus).toBe('start');
|
||||
});
|
||||
|
||||
it('renders ContentEditorProvider component', () => {
|
||||
createWrapper();
|
||||
|
||||
expect(wrapper.findComponent(ContentEditorProvider).exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('renders top toolbar component', async () => {
|
||||
await createWrapper();
|
||||
it('renders top toolbar component', () => {
|
||||
createWrapper();
|
||||
|
||||
expect(wrapper.findComponent(TopToolbar).exists()).toBe(true);
|
||||
});
|
||||
|
|
|
@ -123,7 +123,7 @@ describe('WikiForm', () => {
|
|||
renderMarkdownPath: pageInfoPersisted.markdownPreviewPath,
|
||||
markdownDocsPath: pageInfoPersisted.markdownHelpPath,
|
||||
uploadsPath: pageInfoPersisted.uploadsPath,
|
||||
autofocus: pageInfoPersisted.persisted,
|
||||
initOnAutofocus: pageInfoPersisted.persisted,
|
||||
formFieldId: 'wiki_content',
|
||||
formFieldName: 'wiki[content]',
|
||||
}),
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
import { GlSegmentedControl } from '@gitlab/ui';
|
||||
import axios from 'axios';
|
||||
import MockAdapter from 'axios-mock-adapter';
|
||||
import { nextTick } from 'vue';
|
||||
import { mountExtended } from 'helpers/vue_test_utils_helper';
|
||||
import { EDITING_MODE_MARKDOWN_FIELD, EDITING_MODE_CONTENT_EDITOR } from '~/vue_shared/constants';
|
||||
import MarkdownEditor from '~/vue_shared/components/markdown/markdown_editor.vue';
|
||||
import ContentEditor from '~/content_editor/components/content_editor.vue';
|
||||
import BubbleMenu from '~/content_editor/components/bubble_menus/bubble_menu.vue';
|
||||
import LocalStorageSync from '~/vue_shared/components/local_storage_sync.vue';
|
||||
import MarkdownField from '~/vue_shared/components/markdown/field.vue';
|
||||
import { stubComponent } from 'helpers/stub_component';
|
||||
|
||||
jest.mock('~/emoji');
|
||||
|
||||
|
@ -15,7 +18,6 @@ describe('vue_shared/component/markdown/markdown_editor', () => {
|
|||
const value = 'test markdown';
|
||||
const renderMarkdownPath = '/api/markdown';
|
||||
const markdownDocsPath = '/help/markdown';
|
||||
const uploadsPath = '/uploads';
|
||||
const enableAutocomplete = true;
|
||||
const enablePreview = false;
|
||||
const formFieldId = 'markdown_field';
|
||||
|
@ -24,13 +26,13 @@ describe('vue_shared/component/markdown/markdown_editor', () => {
|
|||
const formFieldAriaLabel = 'Edit your content';
|
||||
let mock;
|
||||
|
||||
const buildWrapper = (propsData = {}) => {
|
||||
const buildWrapper = ({ propsData = {}, attachTo } = {}) => {
|
||||
wrapper = mountExtended(MarkdownEditor, {
|
||||
attachTo,
|
||||
propsData: {
|
||||
value,
|
||||
renderMarkdownPath,
|
||||
markdownDocsPath,
|
||||
uploadsPath,
|
||||
enableAutocomplete,
|
||||
enablePreview,
|
||||
formFieldId,
|
||||
|
@ -39,6 +41,9 @@ describe('vue_shared/component/markdown/markdown_editor', () => {
|
|||
formFieldAriaLabel,
|
||||
...propsData,
|
||||
},
|
||||
stubs: {
|
||||
BubbleMenu: stubComponent(BubbleMenu),
|
||||
},
|
||||
});
|
||||
};
|
||||
const findSegmentedControl = () => wrapper.findComponent(GlSegmentedControl);
|
||||
|
@ -48,6 +53,7 @@ describe('vue_shared/component/markdown/markdown_editor', () => {
|
|||
const findContentEditor = () => wrapper.findComponent(ContentEditor);
|
||||
|
||||
beforeEach(() => {
|
||||
window.uploads_path = 'uploads';
|
||||
mock = new MockAdapter(axios);
|
||||
});
|
||||
|
||||
|
@ -66,7 +72,7 @@ describe('vue_shared/component/markdown/markdown_editor', () => {
|
|||
enableAutocomplete,
|
||||
textareaValue: value,
|
||||
markdownDocsPath,
|
||||
uploadsPath,
|
||||
uploadsPath: window.uploads_path,
|
||||
enablePreview,
|
||||
}),
|
||||
);
|
||||
|
@ -129,18 +135,32 @@ describe('vue_shared/component/markdown/markdown_editor', () => {
|
|||
expect(wrapper.emitted('input')).toEqual([[newValue]]);
|
||||
});
|
||||
|
||||
describe('when initOnAutofocus is true', () => {
|
||||
beforeEach(async () => {
|
||||
buildWrapper({ attachTo: document.body, propsData: { initOnAutofocus: true } });
|
||||
|
||||
await nextTick();
|
||||
});
|
||||
|
||||
it('sets the markdown field as the active element in the document', () => {
|
||||
expect(document.activeElement).toBe(findTextarea().element);
|
||||
});
|
||||
});
|
||||
|
||||
describe(`when segmented control triggers input event with ${EDITING_MODE_CONTENT_EDITOR} value`, () => {
|
||||
beforeEach(() => {
|
||||
buildWrapper();
|
||||
findSegmentedControl().vm.$emit('input', EDITING_MODE_CONTENT_EDITOR);
|
||||
findSegmentedControl().vm.$emit('change', EDITING_MODE_CONTENT_EDITOR);
|
||||
});
|
||||
|
||||
it('displays the content editor', () => {
|
||||
expect(findContentEditor().props()).toEqual(
|
||||
expect.objectContaining({
|
||||
renderMarkdown: expect.any(Function),
|
||||
uploadsPath,
|
||||
uploadsPath: window.uploads_path,
|
||||
markdown: value,
|
||||
autofocus: 'end',
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
@ -173,6 +193,17 @@ describe('vue_shared/component/markdown/markdown_editor', () => {
|
|||
findSegmentedControl().vm.$emit('input', EDITING_MODE_CONTENT_EDITOR);
|
||||
});
|
||||
|
||||
describe('when initOnAutofocus is true', () => {
|
||||
beforeEach(() => {
|
||||
buildWrapper({ propsData: { initOnAutofocus: true } });
|
||||
findLocalStorageSync().vm.$emit('input', EDITING_MODE_CONTENT_EDITOR);
|
||||
});
|
||||
|
||||
it('sets the content editor autofocus property to end', () => {
|
||||
expect(findContentEditor().props().autofocus).toBe('end');
|
||||
});
|
||||
});
|
||||
|
||||
it('emits input event when content editor emits change event', async () => {
|
||||
const newValue = 'new value';
|
||||
|
||||
|
@ -197,6 +228,19 @@ describe('vue_shared/component/markdown/markdown_editor', () => {
|
|||
it('updates localStorage value', () => {
|
||||
expect(findLocalStorageSync().props().value).toBe(EDITING_MODE_MARKDOWN_FIELD);
|
||||
});
|
||||
|
||||
it('sets the textarea as the activeElement in the document', async () => {
|
||||
// The component should be rebuilt to attach it to the document body
|
||||
buildWrapper({ attachTo: document.body });
|
||||
await findSegmentedControl().vm.$emit('input', EDITING_MODE_CONTENT_EDITOR);
|
||||
|
||||
expect(findContentEditor().exists()).toBe(true);
|
||||
|
||||
await findSegmentedControl().vm.$emit('input', EDITING_MODE_MARKDOWN_FIELD);
|
||||
await findSegmentedControl().vm.$emit('change', EDITING_MODE_MARKDOWN_FIELD);
|
||||
|
||||
expect(document.activeElement).toBe(findTextarea().element);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when content editor emits loading event', () => {
|
||||
|
|
|
@ -68,8 +68,10 @@ RSpec.describe Gitlab::Ci::Pipeline::Chain::Seed do
|
|||
end
|
||||
|
||||
context 'when refs policy is specified' do
|
||||
let(:tag_name) { project.repository.tags.first.name }
|
||||
|
||||
let(:pipeline) do
|
||||
build(:ci_pipeline, project: project, ref: 'feature', tag: true)
|
||||
build(:ci_pipeline, project: project, ref: tag_name, tag: true)
|
||||
end
|
||||
|
||||
let(:config) do
|
||||
|
|
|
@ -7,14 +7,13 @@ RSpec.describe Gitlab::GithubImport::Importer::DiffNotesImporter do
|
|||
let(:client) { double(:client) }
|
||||
|
||||
let(:github_comment) do
|
||||
double(
|
||||
:response,
|
||||
{
|
||||
html_url: 'https://github.com/foo/bar/pull/42',
|
||||
path: 'README.md',
|
||||
commit_id: '123abc',
|
||||
original_commit_id: 'original123abc',
|
||||
diff_hunk: "@@ -1 +1 @@\n-Hello\n+Hello world",
|
||||
user: double(:user, id: 4, login: 'alice'),
|
||||
user: { id: 4, login: 'alice' },
|
||||
created_at: Time.zone.now,
|
||||
updated_at: Time.zone.now,
|
||||
line: 23,
|
||||
|
@ -29,7 +28,7 @@ RSpec.describe Gitlab::GithubImport::Importer::DiffNotesImporter do
|
|||
sug1
|
||||
```
|
||||
BODY
|
||||
)
|
||||
}
|
||||
end
|
||||
|
||||
describe '#parallel?' do
|
||||
|
|
|
@ -9,20 +9,19 @@ RSpec.describe Gitlab::GithubImport::Importer::IssuesImporter do
|
|||
let(:updated_at) { Time.new(2017, 1, 1, 12, 15) }
|
||||
|
||||
let(:github_issue) do
|
||||
double(
|
||||
:response,
|
||||
{
|
||||
number: 42,
|
||||
title: 'My Issue',
|
||||
body: 'This is my issue',
|
||||
milestone: double(:milestone, number: 4),
|
||||
milestone: { number: 4 },
|
||||
state: 'open',
|
||||
assignees: [double(:user, id: 4, login: 'alice')],
|
||||
labels: [double(:label, name: 'bug')],
|
||||
user: double(:user, id: 4, login: 'alice'),
|
||||
assignees: [{ id: 4, login: 'alice' }],
|
||||
labels: [{ name: 'bug' }],
|
||||
user: { id: 4, login: 'alice' },
|
||||
created_at: created_at,
|
||||
updated_at: updated_at,
|
||||
pull_request: false
|
||||
)
|
||||
}
|
||||
end
|
||||
|
||||
describe '#parallel?' do
|
||||
|
|
|
@ -28,7 +28,7 @@ RSpec.describe Gitlab::GithubImport::Importer::LabelsImporter, :clean_gitlab_red
|
|||
|
||||
describe '#build_labels' do
|
||||
it 'returns an Array containnig label rows' do
|
||||
label = double(:label, name: 'bug', color: 'ffffff')
|
||||
label = { name: 'bug', color: 'ffffff' }
|
||||
|
||||
expect(importer).to receive(:each_label).and_return([label])
|
||||
|
||||
|
@ -41,7 +41,7 @@ RSpec.describe Gitlab::GithubImport::Importer::LabelsImporter, :clean_gitlab_red
|
|||
it 'does not create labels that already exist' do
|
||||
create(:label, project: project, title: 'bug')
|
||||
|
||||
label = double(:label, name: 'bug', color: 'ffffff')
|
||||
label = { name: 'bug', color: 'ffffff' }
|
||||
|
||||
expect(importer).to receive(:each_label).and_return([label])
|
||||
expect(importer.build_labels).to be_empty
|
||||
|
@ -60,7 +60,7 @@ RSpec.describe Gitlab::GithubImport::Importer::LabelsImporter, :clean_gitlab_red
|
|||
|
||||
describe '#build' do
|
||||
let(:label_hash) do
|
||||
importer.build(double(:label, name: 'bug', color: 'ffffff'))
|
||||
importer.build({ name: 'bug', color: 'ffffff' })
|
||||
end
|
||||
|
||||
it 'returns the attributes of the label as a Hash' do
|
||||
|
|
|
@ -11,8 +11,7 @@ RSpec.describe Gitlab::GithubImport::Importer::MilestonesImporter, :clean_gitlab
|
|||
let(:updated_at) { Time.new(2017, 1, 1, 12, 15) }
|
||||
|
||||
let(:milestone) do
|
||||
double(
|
||||
:milestone,
|
||||
{
|
||||
number: 1,
|
||||
title: '1.0',
|
||||
description: 'The first release',
|
||||
|
@ -20,12 +19,11 @@ RSpec.describe Gitlab::GithubImport::Importer::MilestonesImporter, :clean_gitlab
|
|||
due_on: due_on,
|
||||
created_at: created_at,
|
||||
updated_at: updated_at
|
||||
)
|
||||
}
|
||||
end
|
||||
|
||||
let(:milestone2) do
|
||||
double(
|
||||
:milestone,
|
||||
{
|
||||
number: 1,
|
||||
title: '1.0',
|
||||
description: 'The first release',
|
||||
|
@ -33,7 +31,7 @@ RSpec.describe Gitlab::GithubImport::Importer::MilestonesImporter, :clean_gitlab
|
|||
due_on: nil,
|
||||
created_at: created_at,
|
||||
updated_at: updated_at
|
||||
)
|
||||
}
|
||||
end
|
||||
|
||||
describe '#execute' do
|
||||
|
|
|
@ -7,15 +7,14 @@ RSpec.describe Gitlab::GithubImport::Importer::NotesImporter do
|
|||
let(:client) { double(:client) }
|
||||
|
||||
let(:github_comment) do
|
||||
double(
|
||||
:response,
|
||||
{
|
||||
html_url: 'https://github.com/foo/bar/issues/42',
|
||||
user: double(:user, id: 4, login: 'alice'),
|
||||
user: { id: 4, login: 'alice' },
|
||||
body: 'Hello world',
|
||||
created_at: Time.zone.now,
|
||||
updated_at: Time.zone.now,
|
||||
id: 1
|
||||
)
|
||||
}
|
||||
end
|
||||
|
||||
describe '#parallel?' do
|
||||
|
|
|
@ -7,15 +7,16 @@ RSpec.describe Gitlab::GithubImport::Importer::PullRequestMergedByImporter, :cle
|
|||
|
||||
let(:project) { merge_request.project }
|
||||
let(:merged_at) { Time.new(2017, 1, 1, 12, 00).utc }
|
||||
let(:client_double) { double(user: double(id: 999, login: 'merger', email: 'merger@email.com')) }
|
||||
let(:merger_user) { double(id: 999, login: 'merger') }
|
||||
let(:client_double) { double(user: { id: 999, login: 'merger', email: 'merger@email.com' } ) }
|
||||
let(:merger_user) { { id: 999, login: 'merger' } }
|
||||
|
||||
let(:pull_request) do
|
||||
instance_double(
|
||||
Gitlab::GithubImport::Representation::PullRequest,
|
||||
iid: merge_request.iid,
|
||||
merged_at: merged_at,
|
||||
merged_by: merger_user
|
||||
Gitlab::GithubImport::Representation::PullRequest.from_api_response(
|
||||
{
|
||||
number: merge_request.iid,
|
||||
merged_at: merged_at,
|
||||
merged_by: merger_user
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ RSpec.describe Gitlab::GithubImport::Importer::PullRequestReviewImporter, :clean
|
|||
let_it_be(:merge_request) { create(:merge_request) }
|
||||
|
||||
let(:project) { merge_request.project }
|
||||
let(:client_double) { double(user: double(id: 999, login: 'author', email: 'author@email.com')) }
|
||||
let(:client_double) { double(user: { id: 999, login: 'author', email: 'author@email.com' }) }
|
||||
let(:submitted_at) { Time.new(2017, 1, 1, 12, 00).utc }
|
||||
|
||||
subject { described_class.new(review, project, client_double) }
|
||||
|
|
|
@ -8,33 +8,30 @@ RSpec.describe Gitlab::GithubImport::Importer::PullRequestsImporter do
|
|||
let(:client) { double(:client) }
|
||||
|
||||
let(:pull_request) do
|
||||
double(
|
||||
:response,
|
||||
{
|
||||
number: 42,
|
||||
title: 'My Pull Request',
|
||||
body: 'This is my pull request',
|
||||
state: 'closed',
|
||||
head: double(
|
||||
:head,
|
||||
head: {
|
||||
sha: '123abc',
|
||||
ref: 'my-feature',
|
||||
repo: double(:repo, id: 400),
|
||||
user: double(:user, id: 4, login: 'alice')
|
||||
),
|
||||
base: double(
|
||||
:base,
|
||||
repo: { id: 400 },
|
||||
user: { id: 4, login: 'alice' }
|
||||
},
|
||||
base: {
|
||||
sha: '456def',
|
||||
ref: 'master',
|
||||
repo: double(:repo, id: 200)
|
||||
),
|
||||
milestone: double(:milestone, number: 4),
|
||||
user: double(:user, id: 4, login: 'alice'),
|
||||
assignee: double(:user, id: 4, login: 'alice'),
|
||||
merged_by: double(:user, id: 4, login: 'alice'),
|
||||
repo: { id: 200 }
|
||||
},
|
||||
milestone: { number: 4 },
|
||||
user: { id: 4, login: 'alice' },
|
||||
assignee: { id: 4, login: 'alice' },
|
||||
merged_by: { id: 4, login: 'alice' },
|
||||
created_at: 1.second.ago,
|
||||
updated_at: 1.second.ago,
|
||||
merged_at: 1.second.ago
|
||||
)
|
||||
}
|
||||
end
|
||||
|
||||
describe '#parallel?' do
|
||||
|
@ -184,12 +181,11 @@ RSpec.describe Gitlab::GithubImport::Importer::PullRequestsImporter do
|
|||
|
||||
context 'when the pull request was updated after the last update' do
|
||||
let(:pr) do
|
||||
double(
|
||||
:pr,
|
||||
{
|
||||
updated_at: Time.zone.now,
|
||||
head: double(:head, sha: '123'),
|
||||
base: double(:base, sha: '456')
|
||||
)
|
||||
head: { sha: '123' },
|
||||
base: { sha: '456' }
|
||||
}
|
||||
end
|
||||
|
||||
before do
|
||||
|
@ -201,7 +197,7 @@ RSpec.describe Gitlab::GithubImport::Importer::PullRequestsImporter do
|
|||
it 'returns true when the head SHA is not present' do
|
||||
expect(importer)
|
||||
.to receive(:commit_exists?)
|
||||
.with(pr.head.sha)
|
||||
.with('123')
|
||||
.and_return(false)
|
||||
|
||||
expect(importer.update_repository?(pr)).to eq(true)
|
||||
|
@ -210,12 +206,12 @@ RSpec.describe Gitlab::GithubImport::Importer::PullRequestsImporter do
|
|||
it 'returns true when the base SHA is not present' do
|
||||
expect(importer)
|
||||
.to receive(:commit_exists?)
|
||||
.with(pr.head.sha)
|
||||
.with('123')
|
||||
.and_return(true)
|
||||
|
||||
expect(importer)
|
||||
.to receive(:commit_exists?)
|
||||
.with(pr.base.sha)
|
||||
.with('456')
|
||||
.and_return(false)
|
||||
|
||||
expect(importer.update_repository?(pr)).to eq(true)
|
||||
|
@ -224,12 +220,12 @@ RSpec.describe Gitlab::GithubImport::Importer::PullRequestsImporter do
|
|||
it 'returns false if both the head and base SHAs are present' do
|
||||
expect(importer)
|
||||
.to receive(:commit_exists?)
|
||||
.with(pr.head.sha)
|
||||
.with('123')
|
||||
.and_return(true)
|
||||
|
||||
expect(importer)
|
||||
.to receive(:commit_exists?)
|
||||
.with(pr.base.sha)
|
||||
.with('456')
|
||||
.and_return(true)
|
||||
|
||||
expect(importer.update_repository?(pr)).to eq(false)
|
||||
|
@ -238,7 +234,7 @@ RSpec.describe Gitlab::GithubImport::Importer::PullRequestsImporter do
|
|||
|
||||
context 'when the pull request was updated before the last update' do
|
||||
it 'returns false' do
|
||||
pr = double(:pr, updated_at: 1.year.ago)
|
||||
pr = { updated_at: 1.year.ago }
|
||||
|
||||
allow(project)
|
||||
.to receive(:last_repository_updated_at)
|
||||
|
|
|
@ -23,7 +23,7 @@ RSpec.describe Gitlab::GithubImport::Importer::PullRequestsReviewsImporter do
|
|||
end
|
||||
|
||||
describe '#id_for_already_imported_cache' do
|
||||
it { expect(subject.id_for_already_imported_cache(double(id: 1))).to eq(1) }
|
||||
it { expect(subject.id_for_already_imported_cache({ id: 1 })).to eq(1) }
|
||||
end
|
||||
|
||||
describe '#each_object_to_import', :clean_gitlab_redis_cache do
|
||||
|
@ -36,15 +36,11 @@ RSpec.describe Gitlab::GithubImport::Importer::PullRequestsReviewsImporter do
|
|||
)
|
||||
end
|
||||
|
||||
let(:review) { double(id: 1) }
|
||||
let(:review) { { id: 1 } }
|
||||
|
||||
it 'fetches the pull requests reviews data' do
|
||||
page = double(objects: [review], number: 1)
|
||||
|
||||
expect(review)
|
||||
.to receive(:merge_request_id=)
|
||||
.with(merge_request.id)
|
||||
|
||||
expect(client)
|
||||
.to receive(:each_page)
|
||||
.exactly(:once) # ensure to be cached on the second call
|
||||
|
@ -55,6 +51,8 @@ RSpec.describe Gitlab::GithubImport::Importer::PullRequestsReviewsImporter do
|
|||
.to yield_with_args(review)
|
||||
|
||||
subject.each_object_to_import {}
|
||||
|
||||
expect(review[:merge_request_id]).to eq(merge_request.id)
|
||||
end
|
||||
|
||||
it 'skips cached pages' do
|
||||
|
|
|
@ -10,22 +10,21 @@ RSpec.describe Gitlab::GithubImport::Importer::ReleasesImporter do
|
|||
let(:created_at) { Time.new(2017, 1, 1, 12, 00) }
|
||||
let(:released_at) { Time.new(2017, 1, 1, 12, 00) }
|
||||
let(:author) do
|
||||
double(
|
||||
{
|
||||
login: 'User A',
|
||||
id: 1
|
||||
)
|
||||
}
|
||||
end
|
||||
|
||||
let(:github_release) do
|
||||
double(
|
||||
:github_release,
|
||||
{
|
||||
tag_name: '1.0',
|
||||
name: github_release_name,
|
||||
body: 'This is my release',
|
||||
created_at: created_at,
|
||||
published_at: released_at,
|
||||
author: author
|
||||
)
|
||||
}
|
||||
end
|
||||
|
||||
def stub_email_for_github_username(user_name = 'User A', user_email = 'user@example.com')
|
||||
|
@ -56,7 +55,7 @@ RSpec.describe Gitlab::GithubImport::Importer::ReleasesImporter do
|
|||
end
|
||||
|
||||
it 'imports draft releases' do
|
||||
release_double = double(
|
||||
release_double = {
|
||||
name: 'Test',
|
||||
body: 'This is description',
|
||||
tag_name: '1.0',
|
||||
|
@ -65,7 +64,7 @@ RSpec.describe Gitlab::GithubImport::Importer::ReleasesImporter do
|
|||
updated_at: created_at,
|
||||
published_at: nil,
|
||||
author: author
|
||||
)
|
||||
}
|
||||
|
||||
expect(importer).to receive(:each_release).and_return([release_double])
|
||||
|
||||
|
@ -101,7 +100,7 @@ RSpec.describe Gitlab::GithubImport::Importer::ReleasesImporter do
|
|||
end
|
||||
|
||||
it 'uses a default release description if none is provided' do
|
||||
expect(github_release).to receive(:body).and_return('')
|
||||
github_release[:body] = nil
|
||||
expect(importer).to receive(:each_release).and_return([github_release])
|
||||
|
||||
release = importer.build_releases.first
|
||||
|
@ -110,10 +109,10 @@ RSpec.describe Gitlab::GithubImport::Importer::ReleasesImporter do
|
|||
end
|
||||
|
||||
it 'does not create releases that have a NULL tag' do
|
||||
null_tag_release = double(
|
||||
null_tag_release = {
|
||||
name: 'NULL Test',
|
||||
tag_name: nil
|
||||
)
|
||||
}
|
||||
|
||||
expect(importer).to receive(:each_release).and_return([null_tag_release])
|
||||
expect(importer.build_releases).to be_empty
|
||||
|
@ -179,13 +178,13 @@ RSpec.describe Gitlab::GithubImport::Importer::ReleasesImporter do
|
|||
end
|
||||
|
||||
it 'returns ghost user when author is empty in Github release' do
|
||||
allow(github_release).to receive(:author).and_return(nil)
|
||||
github_release[:author] = nil
|
||||
|
||||
expect(release_hash[:author_id]).to eq(Gitlab::GithubImport.ghost_user_id)
|
||||
end
|
||||
|
||||
context 'when Github author is not found in Gitlab' do
|
||||
let(:author) { double(login: 'octocat', id: 1 ) }
|
||||
let(:author) { { login: 'octocat', id: 1 } }
|
||||
|
||||
before do
|
||||
# Stub user email which does not match a Gitlab user.
|
||||
|
@ -222,11 +221,11 @@ RSpec.describe Gitlab::GithubImport::Importer::ReleasesImporter do
|
|||
|
||||
describe '#description_for' do
|
||||
it 'returns the description when present' do
|
||||
expect(importer.description_for(github_release)).to eq(github_release.body)
|
||||
expect(importer.description_for(github_release)).to eq(github_release[:body])
|
||||
end
|
||||
|
||||
it 'returns a generated description when one is not present' do
|
||||
allow(github_release).to receive(:body).and_return('')
|
||||
github_release[:body] = nil
|
||||
|
||||
expect(importer.description_for(github_release)).to eq('Release for tag 1.0')
|
||||
end
|
||||
|
|
|
@ -14,7 +14,7 @@ RSpec.describe Gitlab::GithubImport::Importer::SingleEndpointDiffNotesImporter d
|
|||
it { expect(subject.importer_class).to eq(Gitlab::GithubImport::Importer::DiffNoteImporter) }
|
||||
it { expect(subject.collection_method).to eq(:pull_request_comments) }
|
||||
it { expect(subject.object_type).to eq(:diff_note) }
|
||||
it { expect(subject.id_for_already_imported_cache(double(id: 1))).to eq(1) }
|
||||
it { expect(subject.id_for_already_imported_cache({ id: 1 })).to eq(1) }
|
||||
|
||||
describe '#each_object_to_import', :clean_gitlab_redis_cache do
|
||||
let(:merge_request) do
|
||||
|
@ -26,7 +26,7 @@ RSpec.describe Gitlab::GithubImport::Importer::SingleEndpointDiffNotesImporter d
|
|||
)
|
||||
end
|
||||
|
||||
let(:note) { double(id: 1) }
|
||||
let(:note) { { id: 1 } }
|
||||
let(:page) { double(objects: [note], number: 1) }
|
||||
|
||||
it 'fetches data' do
|
||||
|
|
|
@ -40,7 +40,7 @@ RSpec.describe Gitlab::GithubImport::Importer::SingleEndpointIssueEventsImporter
|
|||
end
|
||||
|
||||
describe '#id_for_already_imported_cache' do
|
||||
let(:event) { instance_double('Event', id: 1) }
|
||||
let(:event) { { id: 1 } }
|
||||
|
||||
it { expect(subject.id_for_already_imported_cache(event)).to eq(1) }
|
||||
end
|
||||
|
@ -116,8 +116,8 @@ RSpec.describe Gitlab::GithubImport::Importer::SingleEndpointIssueEventsImporter
|
|||
counter = 0
|
||||
subject.each_object_to_import do |object|
|
||||
expect(object).to eq issue_event
|
||||
expect(issue_event.issue['number']).to eq issuable.iid
|
||||
expect(issue_event.issue['pull_request']).to eq false
|
||||
expect(issue_event[:issue]['number']).to eq issuable.iid
|
||||
expect(issue_event[:issue]['pull_request']).to eq false
|
||||
counter += 1
|
||||
end
|
||||
expect(counter).to eq 1
|
||||
|
@ -131,8 +131,8 @@ RSpec.describe Gitlab::GithubImport::Importer::SingleEndpointIssueEventsImporter
|
|||
counter = 0
|
||||
subject.each_object_to_import do |object|
|
||||
expect(object).to eq issue_event
|
||||
expect(issue_event.issue['number']).to eq issuable.iid
|
||||
expect(issue_event.issue['pull_request']).to eq true
|
||||
expect(issue_event[:issue]['number']).to eq issuable.iid
|
||||
expect(issue_event[:issue]['pull_request']).to eq true
|
||||
counter += 1
|
||||
end
|
||||
expect(counter).to eq 1
|
||||
|
|
|
@ -14,7 +14,7 @@ RSpec.describe Gitlab::GithubImport::Importer::SingleEndpointIssueNotesImporter
|
|||
it { expect(subject.importer_class).to eq(Gitlab::GithubImport::Importer::NoteImporter) }
|
||||
it { expect(subject.collection_method).to eq(:issue_comments) }
|
||||
it { expect(subject.object_type).to eq(:note) }
|
||||
it { expect(subject.id_for_already_imported_cache(double(id: 1))).to eq(1) }
|
||||
it { expect(subject.id_for_already_imported_cache({ id: 1 })).to eq(1) }
|
||||
|
||||
describe '#each_object_to_import', :clean_gitlab_redis_cache do
|
||||
let(:issue) do
|
||||
|
@ -25,7 +25,7 @@ RSpec.describe Gitlab::GithubImport::Importer::SingleEndpointIssueNotesImporter
|
|||
)
|
||||
end
|
||||
|
||||
let(:note) { double(id: 1) }
|
||||
let(:note) { { id: 1 } }
|
||||
let(:page) { double(objects: [note], number: 1) }
|
||||
|
||||
it 'fetches data' do
|
||||
|
|
|
@ -14,7 +14,7 @@ RSpec.describe Gitlab::GithubImport::Importer::SingleEndpointMergeRequestNotesIm
|
|||
it { expect(subject.importer_class).to eq(Gitlab::GithubImport::Importer::NoteImporter) }
|
||||
it { expect(subject.collection_method).to eq(:issue_comments) }
|
||||
it { expect(subject.object_type).to eq(:note) }
|
||||
it { expect(subject.id_for_already_imported_cache(double(id: 1))).to eq(1) }
|
||||
it { expect(subject.id_for_already_imported_cache({ id: 1 })).to eq(1) }
|
||||
|
||||
describe '#each_object_to_import', :clean_gitlab_redis_cache do
|
||||
let(:merge_request) do
|
||||
|
@ -26,7 +26,7 @@ RSpec.describe Gitlab::GithubImport::Importer::SingleEndpointMergeRequestNotesIm
|
|||
)
|
||||
end
|
||||
|
||||
let(:note) { double(id: 1) }
|
||||
let(:note) { { id: 1 } }
|
||||
let(:page) { double(objects: [note], number: 1) }
|
||||
|
||||
it 'fetches data' do
|
||||
|
|
|
@ -28,7 +28,7 @@ RSpec.describe Gitlab::GithubImport::Representation::DiffNote, :clean_gitlab_red
|
|||
let(:start_line) { nil }
|
||||
let(:end_line) { 23 }
|
||||
let(:note_body) { 'Hello world' }
|
||||
let(:user_data) { { 'id' => 4, 'login' => 'alice' } }
|
||||
let(:user_data) { { id: 4, login: 'alice' } }
|
||||
let(:side) { 'RIGHT' }
|
||||
let(:created_at) { Time.new(2017, 1, 1, 12, 00) }
|
||||
let(:updated_at) { Time.new(2017, 1, 1, 12, 15) }
|
||||
|
@ -275,15 +275,14 @@ RSpec.describe Gitlab::GithubImport::Representation::DiffNote, :clean_gitlab_red
|
|||
describe '.from_api_response' do
|
||||
it_behaves_like 'a DiffNote representation' do
|
||||
let(:response) do
|
||||
double(
|
||||
:response,
|
||||
{
|
||||
id: note_id,
|
||||
html_url: 'https://github.com/foo/bar/pull/42',
|
||||
path: 'README.md',
|
||||
commit_id: '123abc',
|
||||
original_commit_id: 'original123abc',
|
||||
side: side,
|
||||
user: user_data && double(:user, user_data),
|
||||
user: user_data,
|
||||
diff_hunk: hunk,
|
||||
body: note_body,
|
||||
created_at: created_at,
|
||||
|
@ -291,7 +290,7 @@ RSpec.describe Gitlab::GithubImport::Representation::DiffNote, :clean_gitlab_red
|
|||
line: end_line,
|
||||
start_line: start_line,
|
||||
in_reply_to_id: in_reply_to_id
|
||||
)
|
||||
}
|
||||
end
|
||||
|
||||
subject(:note) { described_class.from_api_response(response) }
|
||||
|
|
|
@ -74,20 +74,19 @@ RSpec.describe Gitlab::GithubImport::Representation::Issue do
|
|||
|
||||
describe '.from_api_response' do
|
||||
let(:response) do
|
||||
double(
|
||||
:response,
|
||||
{
|
||||
number: 42,
|
||||
title: 'My Issue',
|
||||
body: 'This is my issue',
|
||||
milestone: double(:milestone, number: 4),
|
||||
milestone: { number: 4 },
|
||||
state: 'open',
|
||||
assignees: [double(:user, id: 4, login: 'alice')],
|
||||
labels: [double(:label, name: 'bug')],
|
||||
user: double(:user, id: 4, login: 'alice'),
|
||||
assignees: [{ id: 4, login: 'alice' }],
|
||||
labels: [{ name: 'bug' }],
|
||||
user: { id: 4, login: 'alice' },
|
||||
created_at: created_at,
|
||||
updated_at: updated_at,
|
||||
pull_request: false
|
||||
)
|
||||
}
|
||||
end
|
||||
|
||||
let(:additional_data) { { work_item_type_id: work_item_type_id } }
|
||||
|
@ -97,9 +96,7 @@ RSpec.describe Gitlab::GithubImport::Representation::Issue do
|
|||
end
|
||||
|
||||
it 'does not set the user if the response did not include a user' do
|
||||
allow(response)
|
||||
.to receive(:user)
|
||||
.and_return(nil)
|
||||
response[:user] = nil
|
||||
|
||||
issue = described_class.from_api_response(response, additional_data)
|
||||
|
||||
|
|
|
@ -48,15 +48,14 @@ RSpec.describe Gitlab::GithubImport::Representation::Note do
|
|||
|
||||
describe '.from_api_response' do
|
||||
let(:response) do
|
||||
double(
|
||||
:response,
|
||||
{
|
||||
html_url: 'https://github.com/foo/bar/issues/42',
|
||||
user: double(:user, id: 4, login: 'alice'),
|
||||
user: { id: 4, login: 'alice' },
|
||||
body: 'Hello world',
|
||||
created_at: created_at,
|
||||
updated_at: updated_at,
|
||||
id: 1
|
||||
)
|
||||
}
|
||||
end
|
||||
|
||||
it_behaves_like 'a Note' do
|
||||
|
@ -64,9 +63,7 @@ RSpec.describe Gitlab::GithubImport::Representation::Note do
|
|||
end
|
||||
|
||||
it 'does not set the user if the response did not include a user' do
|
||||
allow(response)
|
||||
.to receive(:user)
|
||||
.and_return(nil)
|
||||
response[:user] = nil
|
||||
|
||||
note = described_class.from_api_response(response)
|
||||
|
||||
|
|
|
@ -21,15 +21,14 @@ RSpec.describe Gitlab::GithubImport::Representation::PullRequestReview do
|
|||
|
||||
describe '.from_api_response' do
|
||||
let(:response) do
|
||||
double(
|
||||
:response,
|
||||
{
|
||||
id: 999,
|
||||
merge_request_id: 42,
|
||||
body: 'note',
|
||||
state: 'APPROVED',
|
||||
user: double(:user, id: 4, login: 'alice'),
|
||||
user: { id: 4, login: 'alice' },
|
||||
submitted_at: submitted_at
|
||||
)
|
||||
}
|
||||
end
|
||||
|
||||
it_behaves_like 'a PullRequest review' do
|
||||
|
@ -37,9 +36,7 @@ RSpec.describe Gitlab::GithubImport::Representation::PullRequestReview do
|
|||
end
|
||||
|
||||
it 'does not set the user if the response did not include a user' do
|
||||
allow(response)
|
||||
.to receive(:user)
|
||||
.and_return(nil)
|
||||
response[:user] = nil
|
||||
|
||||
review = described_class.from_api_response(response)
|
||||
|
||||
|
|
|
@ -93,33 +93,30 @@ RSpec.describe Gitlab::GithubImport::Representation::PullRequest do
|
|||
|
||||
describe '.from_api_response' do
|
||||
let(:response) do
|
||||
double(
|
||||
:response,
|
||||
{
|
||||
number: 42,
|
||||
title: 'My Pull Request',
|
||||
body: 'This is my pull request',
|
||||
state: 'closed',
|
||||
head: double(
|
||||
:head,
|
||||
head: {
|
||||
sha: '123abc',
|
||||
ref: 'my-feature',
|
||||
repo: double(:repo, id: 400),
|
||||
user: double(:user, id: 4, login: 'alice')
|
||||
),
|
||||
base: double(
|
||||
:base,
|
||||
repo: { id: 400 },
|
||||
user: { id: 4, login: 'alice' }
|
||||
},
|
||||
base: {
|
||||
sha: '456def',
|
||||
ref: 'master',
|
||||
repo: double(:repo, id: 200)
|
||||
),
|
||||
milestone: double(:milestone, number: 4),
|
||||
user: double(:user, id: 4, login: 'alice'),
|
||||
assignee: double(:user, id: 4, login: 'alice'),
|
||||
merged_by: double(:user, id: 4, login: 'alice'),
|
||||
repo: { id: 200 }
|
||||
},
|
||||
milestone: { number: 4 },
|
||||
user: { id: 4, login: 'alice' },
|
||||
assignee: { id: 4, login: 'alice' },
|
||||
merged_by: { id: 4, login: 'alice' },
|
||||
created_at: created_at,
|
||||
updated_at: updated_at,
|
||||
merged_at: merged_at
|
||||
)
|
||||
}
|
||||
end
|
||||
|
||||
it_behaves_like 'a PullRequest' do
|
||||
|
@ -127,9 +124,7 @@ RSpec.describe Gitlab::GithubImport::Representation::PullRequest do
|
|||
end
|
||||
|
||||
it 'does not set the user if the response did not include a user' do
|
||||
allow(response)
|
||||
.to receive(:user)
|
||||
.and_return(nil)
|
||||
response[:user] = nil
|
||||
|
||||
pr = described_class.from_api_response(response)
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ RSpec.describe Gitlab::GithubImport::Representation::User do
|
|||
|
||||
describe '.from_api_response' do
|
||||
it_behaves_like 'a User' do
|
||||
let(:response) { double(:response, id: 42, login: 'alice') }
|
||||
let(:response) { { id: 42, login: 'alice' } }
|
||||
let(:user) { described_class.from_api_response(response) }
|
||||
end
|
||||
end
|
||||
|
|
|
@ -17,8 +17,8 @@ RSpec.describe Gitlab::GithubImport::UserFinder, :clean_gitlab_redis_cache do
|
|||
describe '#author_id_for' do
|
||||
context 'with default author_key' do
|
||||
it 'returns the user ID for the author of an object' do
|
||||
user = double(:user, id: 4, login: 'kittens')
|
||||
note = double(:note, author: user)
|
||||
user = { id: 4, login: 'kittens' }
|
||||
note = { author: user }
|
||||
|
||||
expect(finder).to receive(:user_id_for).with(user).and_return(42)
|
||||
|
||||
|
@ -26,8 +26,8 @@ RSpec.describe Gitlab::GithubImport::UserFinder, :clean_gitlab_redis_cache do
|
|||
end
|
||||
|
||||
it 'returns the ID of the project creator if no user ID could be found' do
|
||||
user = double(:user, id: 4, login: 'kittens')
|
||||
note = double(:note, author: user)
|
||||
user = { id: 4, login: 'kittens' }
|
||||
note = { author: user }
|
||||
|
||||
expect(finder).to receive(:user_id_for).with(user).and_return(nil)
|
||||
|
||||
|
@ -35,7 +35,7 @@ RSpec.describe Gitlab::GithubImport::UserFinder, :clean_gitlab_redis_cache do
|
|||
end
|
||||
|
||||
it 'returns the ID of the ghost user when the object has no user' do
|
||||
note = double(:note, author: nil)
|
||||
note = { author: nil }
|
||||
|
||||
expect(finder.author_id_for(note)).to eq([User.ghost.id, true])
|
||||
end
|
||||
|
@ -46,7 +46,7 @@ RSpec.describe Gitlab::GithubImport::UserFinder, :clean_gitlab_redis_cache do
|
|||
end
|
||||
|
||||
context 'with a non-default author_key' do
|
||||
let(:user) { double(:user, id: 4, login: 'kittens') }
|
||||
let(:user) { { id: 4, login: 'kittens' } }
|
||||
|
||||
shared_examples 'user ID finder' do |author_key|
|
||||
it 'returns the user ID for an object' do
|
||||
|
@ -57,25 +57,25 @@ RSpec.describe Gitlab::GithubImport::UserFinder, :clean_gitlab_redis_cache do
|
|||
end
|
||||
|
||||
context 'when the author_key parameter is :actor' do
|
||||
let(:issue_event) { double('Gitlab::GithubImport::Representation::IssueEvent', actor: user) }
|
||||
let(:issue_event) { { actor: user } }
|
||||
|
||||
it_behaves_like 'user ID finder', :actor
|
||||
end
|
||||
|
||||
context 'when the author_key parameter is :assignee' do
|
||||
let(:issue_event) { double('Gitlab::GithubImport::Representation::IssueEvent', assignee: user) }
|
||||
let(:issue_event) { { assignee: user } }
|
||||
|
||||
it_behaves_like 'user ID finder', :assignee
|
||||
end
|
||||
|
||||
context 'when the author_key parameter is :requested_reviewer' do
|
||||
let(:issue_event) { double('Gitlab::GithubImport::Representation::IssueEvent', requested_reviewer: user) }
|
||||
let(:issue_event) { { requested_reviewer: user } }
|
||||
|
||||
it_behaves_like 'user ID finder', :requested_reviewer
|
||||
end
|
||||
|
||||
context 'when the author_key parameter is :review_requester' do
|
||||
let(:issue_event) { double('Gitlab::GithubImport::Representation::IssueEvent', review_requester: user) }
|
||||
let(:issue_event) { { review_requester: user } }
|
||||
|
||||
it_behaves_like 'user ID finder', :review_requester
|
||||
end
|
||||
|
@ -84,15 +84,15 @@ RSpec.describe Gitlab::GithubImport::UserFinder, :clean_gitlab_redis_cache do
|
|||
|
||||
describe '#assignee_id_for' do
|
||||
it 'returns the user ID for the assignee of an issuable' do
|
||||
user = double(:user, id: 4, login: 'kittens')
|
||||
issue = double(:issue, assignee: user)
|
||||
user = { id: 4, login: 'kittens' }
|
||||
issue = { assignee: user }
|
||||
|
||||
expect(finder).to receive(:user_id_for).with(user).and_return(42)
|
||||
expect(finder.assignee_id_for(issue)).to eq(42)
|
||||
end
|
||||
|
||||
it 'returns nil if the issuable does not have an assignee' do
|
||||
issue = double(:issue, assignee: nil)
|
||||
issue = { assignee: nil }
|
||||
|
||||
expect(finder).not_to receive(:user_id_for)
|
||||
expect(finder.assignee_id_for(issue)).to be_nil
|
||||
|
@ -101,9 +101,9 @@ RSpec.describe Gitlab::GithubImport::UserFinder, :clean_gitlab_redis_cache do
|
|||
|
||||
describe '#user_id_for' do
|
||||
it 'returns the user ID for the given user' do
|
||||
user = double(:user, id: 4, login: 'kittens')
|
||||
user = { id: 4, login: 'kittens' }
|
||||
|
||||
expect(finder).to receive(:find).with(user.id, user.login).and_return(42)
|
||||
expect(finder).to receive(:find).with(user[:id], user[:login]).and_return(42)
|
||||
expect(finder.user_id_for(user)).to eq(42)
|
||||
end
|
||||
|
||||
|
@ -221,7 +221,7 @@ RSpec.describe Gitlab::GithubImport::UserFinder, :clean_gitlab_redis_cache do
|
|||
end
|
||||
|
||||
context 'when an Email address is not cached' do
|
||||
let(:user) { double(:user, email: email) }
|
||||
let(:user) { { email: email } }
|
||||
|
||||
it 'retrieves the Email address from the GitHub API' do
|
||||
expect(client).to receive(:user).with('kittens').and_return(user)
|
||||
|
@ -251,7 +251,7 @@ RSpec.describe Gitlab::GithubImport::UserFinder, :clean_gitlab_redis_cache do
|
|||
end
|
||||
|
||||
it 'shortens the timeout for Email address in cache when an Email address is private/nil from GitHub' do
|
||||
user = double(:user, email: nil)
|
||||
user = { email: nil }
|
||||
expect(client).to receive(:user).with('kittens').and_return(user)
|
||||
|
||||
expect(Gitlab::Cache::Import::Caching)
|
||||
|
|
|
@ -3069,8 +3069,24 @@ RSpec.describe Ci::Build do
|
|||
end
|
||||
|
||||
context 'when build is for tag' do
|
||||
let(:tag_name) { project.repository.tags.first.name }
|
||||
let(:tag_message) { project.repository.tags.first.message }
|
||||
|
||||
let!(:pipeline) do
|
||||
create(:ci_pipeline, project: project,
|
||||
sha: project.commit.id,
|
||||
ref: tag_name,
|
||||
status: 'success')
|
||||
end
|
||||
|
||||
let!(:build) { create(:ci_build, pipeline: pipeline, ref: tag_name) }
|
||||
|
||||
let(:tag_variable) do
|
||||
{ key: 'CI_COMMIT_TAG', value: 'master', public: true, masked: false }
|
||||
{ key: 'CI_COMMIT_TAG', value: tag_name, public: true, masked: false }
|
||||
end
|
||||
|
||||
let(:tag_message_variable) do
|
||||
{ key: 'CI_COMMIT_TAG_MESSAGE', value: tag_message, public: true, masked: false }
|
||||
end
|
||||
|
||||
before do
|
||||
|
@ -3081,7 +3097,7 @@ RSpec.describe Ci::Build do
|
|||
it do
|
||||
build.reload
|
||||
|
||||
expect(subject).to include(tag_variable)
|
||||
expect(subject).to include(tag_variable, tag_message_variable)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in New Issue