summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitlab-ci.yml11
-rw-r--r--.gitlab/route-map.yml3
-rw-r--r--.rubocop.yml2
-rw-r--r--.ruby-version2
-rw-r--r--.scss-lint.yml3
-rw-r--r--CHANGELOG.md192
-rw-r--r--CONTRIBUTING.md4
-rw-r--r--GITALY_SERVER_VERSION2
-rw-r--r--Gemfile8
-rw-r--r--Gemfile.lock16
-rw-r--r--VERSION2
-rw-r--r--app/assets/javascripts/api.js1
-rw-r--r--app/assets/javascripts/autosave.js31
-rw-r--r--app/assets/javascripts/behaviors/autosize.js6
-rw-r--r--app/assets/javascripts/boards/components/board_sidebar.js2
-rw-r--r--app/assets/javascripts/clusters.js22
-rw-r--r--app/assets/javascripts/commit/pipelines/pipelines_table.vue6
-rw-r--r--app/assets/javascripts/contextual_sidebar.js (renamed from app/assets/javascripts/new_sidebar.js)4
-rw-r--r--app/assets/javascripts/diff.js15
-rw-r--r--app/assets/javascripts/dispatcher.js37
-rw-r--r--app/assets/javascripts/files_comment_button.js9
-rw-r--r--app/assets/javascripts/gl_dropdown.js1
-rw-r--r--app/assets/javascripts/group_avatar.js31
-rw-r--r--app/assets/javascripts/group_label_subscription.js11
-rw-r--r--app/assets/javascripts/groups_select.js185
-rw-r--r--app/assets/javascripts/header.js14
-rw-r--r--app/assets/javascripts/importer_status.js144
-rw-r--r--app/assets/javascripts/init_changes_dropdown.js4
-rw-r--r--app/assets/javascripts/init_issuable_sidebar.js2
-rw-r--r--app/assets/javascripts/init_legacy_filters.js4
-rw-r--r--app/assets/javascripts/issuable_bulk_update_actions.js1
-rw-r--r--app/assets/javascripts/issuable_bulk_update_sidebar.js7
-rw-r--r--app/assets/javascripts/issuable_context.js96
-rw-r--r--app/assets/javascripts/issuable_form.js197
-rw-r--r--app/assets/javascripts/issuable_index.js201
-rw-r--r--app/assets/javascripts/issue.js4
-rw-r--r--app/assets/javascripts/issue_status_select.js57
-rw-r--r--app/assets/javascripts/layout_nav.js6
-rw-r--r--app/assets/javascripts/lib/utils/sticky.js8
-rw-r--r--app/assets/javascripts/main.js18
-rw-r--r--app/assets/javascripts/merge_request_tabs.js15
-rw-r--r--app/assets/javascripts/notes.js16
-rw-r--r--app/assets/javascripts/notes/components/issue_comment_form.vue7
-rw-r--r--app/assets/javascripts/notes/components/issue_discussion.vue4
-rw-r--r--app/assets/javascripts/notes/components/issue_notes_app.vue10
-rw-r--r--app/assets/javascripts/notes/mixins/autosave.js3
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines.vue12
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_table.vue5
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_table_row.vue23
-rw-r--r--app/assets/javascripts/project_find_file.js3
-rw-r--r--app/assets/javascripts/project_select.js24
-rw-r--r--app/assets/javascripts/registry/stores/actions.js6
-rw-r--r--app/assets/javascripts/repo/components/new_branch_form.vue108
-rw-r--r--app/assets/javascripts/repo/components/new_dropdown/index.vue84
-rw-r--r--app/assets/javascripts/repo/components/new_dropdown/modal.vue98
-rw-r--r--app/assets/javascripts/repo/components/new_dropdown/upload.vue68
-rw-r--r--app/assets/javascripts/repo/components/repo.vue65
-rw-r--r--app/assets/javascripts/repo/components/repo_commit_section.vue168
-rw-r--r--app/assets/javascripts/repo/components/repo_edit_button.vue75
-rw-r--r--app/assets/javascripts/repo/components/repo_editor.vue163
-rw-r--r--app/assets/javascripts/repo/components/repo_file.vue20
-rw-r--r--app/assets/javascripts/repo/components/repo_file_buttons.vue55
-rw-r--r--app/assets/javascripts/repo/components/repo_loading_file.vue12
-rw-r--r--app/assets/javascripts/repo/components/repo_prev_directory.vue30
-rw-r--r--app/assets/javascripts/repo/components/repo_preview.vue49
-rw-r--r--app/assets/javascripts/repo/components/repo_sidebar.vue120
-rw-r--r--app/assets/javascripts/repo/components/repo_tab.vue30
-rw-r--r--app/assets/javascripts/repo/components/repo_tabs.vue12
-rw-r--r--app/assets/javascripts/repo/event_hub.js3
-rw-r--r--app/assets/javascripts/repo/helpers/monaco_loader_helper.js25
-rw-r--r--app/assets/javascripts/repo/helpers/repo_helper.js228
-rw-r--r--app/assets/javascripts/repo/index.js122
-rw-r--r--app/assets/javascripts/repo/mixins/repo_mixin.js17
-rw-r--r--app/assets/javascripts/repo/services/index.js33
-rw-r--r--app/assets/javascripts/repo/services/repo_service.js85
-rw-r--r--app/assets/javascripts/repo/stores/actions.js129
-rw-r--r--app/assets/javascripts/repo/stores/actions/branch.js20
-rw-r--r--app/assets/javascripts/repo/stores/actions/file.js108
-rw-r--r--app/assets/javascripts/repo/stores/actions/tree.js110
-rw-r--r--app/assets/javascripts/repo/stores/getters.js36
-rw-r--r--app/assets/javascripts/repo/stores/index.js15
-rw-r--r--app/assets/javascripts/repo/stores/mutation_types.js28
-rw-r--r--app/assets/javascripts/repo/stores/mutations.js54
-rw-r--r--app/assets/javascripts/repo/stores/mutations/branch.js9
-rw-r--r--app/assets/javascripts/repo/stores/mutations/file.js54
-rw-r--r--app/assets/javascripts/repo/stores/mutations/tree.js45
-rw-r--r--app/assets/javascripts/repo/stores/repo_store.js180
-rw-r--r--app/assets/javascripts/repo/stores/state.js23
-rw-r--r--app/assets/javascripts/repo/stores/utils.js108
-rw-r--r--app/assets/javascripts/sidebar/components/participants/participants.vue125
-rw-r--r--app/assets/javascripts/sidebar/components/participants/sidebar_participants.vue26
-rw-r--r--app/assets/javascripts/sidebar/components/subscriptions/sidebar_subscriptions.vue45
-rw-r--r--app/assets/javascripts/sidebar/components/subscriptions/subscriptions.vue60
-rw-r--r--app/assets/javascripts/sidebar/services/sidebar_service.js5
-rw-r--r--app/assets/javascripts/sidebar/sidebar_bundle.js34
-rw-r--r--app/assets/javascripts/sidebar/sidebar_mediator.js16
-rw-r--r--app/assets/javascripts/sidebar/stores/sidebar_store.js22
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_ready_to_merge.js5
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/services/mr_widget_service.js2
-rw-r--r--app/assets/javascripts/vue_shared/components/ci_badge_link.vue92
-rw-r--r--app/assets/javascripts/vue_shared/components/commit.vue56
-rw-r--r--app/assets/javascripts/vue_shared/components/loading_button.vue71
-rw-r--r--app/assets/javascripts/vue_shared/components/notes/placeholder_note.vue (renamed from app/assets/javascripts/notes/components/issue_placeholder_note.vue)21
-rw-r--r--app/assets/javascripts/vue_shared/components/notes/placeholder_system_note.vue (renamed from app/assets/javascripts/notes/components/issue_placeholder_system_note.vue)8
-rw-r--r--app/assets/javascripts/vue_shared/components/notes/system_note.vue (renamed from app/assets/javascripts/notes/components/issue_system_note.vue)25
-rw-r--r--app/assets/javascripts/vue_shared/components/popup_dialog.vue11
-rw-r--r--app/assets/javascripts/vue_shared/components/user_avatar/user_avatar_link.vue29
-rw-r--r--app/assets/stylesheets/framework.scss3
-rw-r--r--app/assets/stylesheets/framework/buttons.scss5
-rw-r--r--app/assets/stylesheets/framework/contextual-sidebar.scss (renamed from app/assets/stylesheets/framework/new-sidebar.scss)54
-rw-r--r--app/assets/stylesheets/framework/dropdowns.scss3
-rw-r--r--app/assets/stylesheets/framework/filters.scss13
-rw-r--r--app/assets/stylesheets/framework/gitlab-theme.scss7
-rw-r--r--app/assets/stylesheets/framework/header.scss6
-rw-r--r--app/assets/stylesheets/framework/variables.scss10
-rw-r--r--app/assets/stylesheets/framework/vue_transitions.scss9
-rw-r--r--app/assets/stylesheets/pages/boards.scss2
-rw-r--r--app/assets/stylesheets/pages/issuable.scss6
-rw-r--r--app/assets/stylesheets/pages/note_form.scss3
-rw-r--r--app/assets/stylesheets/pages/notes.scss16
-rw-r--r--app/assets/stylesheets/pages/repo.scss63
-rw-r--r--app/controllers/confirmations_controller.rb2
-rw-r--r--app/controllers/groups_controller.rb11
-rw-r--r--app/controllers/help_controller.rb4
-rw-r--r--app/controllers/projects/blob_controller.rb1
-rw-r--r--app/controllers/projects/branches_controller.rb2
-rw-r--r--app/controllers/projects/issues_controller.rb12
-rw-r--r--app/controllers/projects/merge_requests_controller.rb2
-rw-r--r--app/controllers/projects/milestones_controller.rb12
-rw-r--r--app/controllers/projects/tree_controller.rb1
-rw-r--r--app/finders/branches_finder.rb2
-rw-r--r--app/helpers/application_settings_helper.rb11
-rw-r--r--app/helpers/instance_configuration_helper.rb18
-rw-r--r--app/helpers/issuables_helper.rb23
-rw-r--r--app/helpers/nav_helper.rb8
-rw-r--r--app/helpers/storage_health_helper.rb5
-rw-r--r--app/models/application_setting.rb16
-rw-r--r--app/models/ci/artifact_blob.rb17
-rw-r--r--app/models/ci/pipeline.rb4
-rw-r--r--app/models/concerns/subscribable.rb2
-rw-r--r--app/models/email.rb2
-rw-r--r--app/models/environment.rb2
-rw-r--r--app/models/identity.rb5
-rw-r--r--app/models/instance_configuration.rb71
-rw-r--r--app/models/merge_request.rb6
-rw-r--r--app/models/merge_request_diff_commit.rb4
-rw-r--r--app/models/pages_domain.rb8
-rw-r--r--app/models/project.rb51
-rw-r--r--app/models/project_services/jira_service.rb2
-rw-r--r--app/models/project_services/kubernetes_service.rb5
-rw-r--r--app/models/project_services/packagist_service.rb65
-rw-r--r--app/models/repository.rb86
-rw-r--r--app/models/service.rb1
-rw-r--r--app/serializers/issuable_sidebar_entity.rb16
-rw-r--r--app/serializers/issue_serializer.rb15
-rw-r--r--app/serializers/issue_sidebar_entity.rb3
-rw-r--r--app/serializers/merge_request_basic_entity.rb6
-rw-r--r--app/serializers/merge_request_serializer.rb9
-rw-r--r--app/services/issues/reopen_service.rb1
-rw-r--r--app/services/merge_requests/merge_service.rb9
-rw-r--r--app/services/merge_requests/reopen_service.rb1
-rw-r--r--app/services/milestones/promote_service.rb80
-rw-r--r--app/services/projects/hashed_storage_migration_service.rb2
-rw-r--r--app/services/system_hooks_service.rb2
-rw-r--r--app/services/users/last_push_event_service.rb4
-rw-r--r--app/uploaders/file_uploader.rb2
-rw-r--r--app/views/admin/application_settings/_form.html.haml30
-rw-r--r--app/views/dashboard/_projects_head.html.haml6
-rw-r--r--app/views/groups/milestones/_form.html.haml2
-rw-r--r--app/views/help/index.html.haml2
-rw-r--r--app/views/help/instance_configuration.html.haml17
-rw-r--r--app/views/help/instance_configuration/_gitlab_ci.html.haml24
-rw-r--r--app/views/help/instance_configuration/_gitlab_pages.html.haml35
-rw-r--r--app/views/help/instance_configuration/_ssh_info.html.haml27
-rw-r--r--app/views/layouts/nav/sidebar/_project.html.haml2
-rw-r--r--app/views/peek/views/_gitaly.html.haml7
-rw-r--r--app/views/projects/branches/_branch.html.haml5
-rw-r--r--app/views/projects/branches/index.html.haml2
-rw-r--r--app/views/projects/clusters/show.html.haml4
-rw-r--r--app/views/projects/commit/_commit_box.html.haml5
-rw-r--r--app/views/projects/empty.html.haml1
-rw-r--r--app/views/projects/issues/edit.html.haml7
-rw-r--r--app/views/projects/milestones/show.html.haml11
-rw-r--r--app/views/projects/tree/_tree_header.html.haml8
-rw-r--r--app/views/shared/_ref_switcher.html.haml23
-rw-r--r--app/views/shared/issuable/_participants.html.haml18
-rw-r--r--app/views/shared/issuable/_search_bar.html.haml1
-rw-r--r--app/views/shared/issuable/_sidebar.html.haml13
-rw-r--r--app/views/shared/milestones/_milestone.html.haml7
-rw-r--r--app/views/shared/repo/_editable_mode.html.haml2
-rw-r--r--app/views/shared/repo/_repo.html.haml10
-rw-r--r--app/workers/stuck_merge_jobs_worker.rb2
-rw-r--r--changelogs/unreleased/13637-show-account-confirmation-link-in-e-mail-text.yml5
-rw-r--r--changelogs/unreleased/13711-allow-same-period-housekeeping.yml6
-rw-r--r--changelogs/unreleased/14395-upgrade-gitlab-markup.yml5
-rw-r--r--changelogs/unreleased/14553-missing-space-in-log-msg.yml5
-rw-r--r--changelogs/unreleased/14970-suggest-rename-remote.yml5
-rw-r--r--changelogs/unreleased/18308-escape-characters.yml5
-rw-r--r--changelogs/unreleased/18608-lock-issues.yml4
-rw-r--r--changelogs/unreleased/20049-projects-api-forks.yml5
-rw-r--r--changelogs/unreleased/20824-scope-users-to-members-in-group-issuable-list.yml5
-rw-r--r--changelogs/unreleased/21331-improve-confusing-compare-page.yml5
-rw-r--r--changelogs/unreleased/23000-pages-api.yml5
-rw-r--r--changelogs/unreleased/23206-load-participants-async.yml5
-rw-r--r--changelogs/unreleased/23888-fix-unsubscription-link-for-snippet-notification.yml5
-rw-r--r--changelogs/unreleased/24121_extract_yet_another_users_finder.yml5
-rw-r--r--changelogs/unreleased/26890-fix-default-branches-sorting.yml5
-rw-r--r--changelogs/unreleased/28202_decrease_abc_threshold_step5.yml5
-rw-r--r--changelogs/unreleased/31358_decrease_perceived_complexity_threshold_step2.yml5
-rw-r--r--changelogs/unreleased/31362_decrease_cyclomatic_complexity_threshold_step4.yml5
-rw-r--r--changelogs/unreleased/31454-missing-project-id-pipeline-hook-data.yml5
-rw-r--r--changelogs/unreleased/32163-protected-branch-form-should-have-sane-defaults-for-dropdowns.yml5
-rw-r--r--changelogs/unreleased/32318-filter-icon.yml5
-rw-r--r--changelogs/unreleased/33328-usage-ping-for-gitlab-features-and-components.yml5
-rw-r--r--changelogs/unreleased/33493-attempt-to-link-saml-users-to-ldap-by-email.yml5
-rw-r--r--changelogs/unreleased/34102-online-view-of-artifacts-fe.yml5
-rw-r--r--changelogs/unreleased/34259-project-denial-of-service-via-gitmodules-fix.yml5
-rw-r--r--changelogs/unreleased/34366-issue-sidebar-don-t-render-participants-in-collapsed-state.yml5
-rw-r--r--changelogs/unreleased/34371-cycle-analitcs-global.yml5
-rw-r--r--changelogs/unreleased/34510-board-issues-sql-speedup.yml5
-rw-r--r--changelogs/unreleased/35199-case-insensitive-branches-search.yml5
-rw-r--r--changelogs/unreleased/3523-i18n-autodevops.yml5
-rw-r--r--changelogs/unreleased/35290_allow_public_project_apis.yml4
-rw-r--r--changelogs/unreleased/35580-cannot-import-project-with-milestones.yml5
-rw-r--r--changelogs/unreleased/35644-refactor-have-http-status-into-have-gitlab-http-status.yml5
-rw-r--r--changelogs/unreleased/35917_create_services_for_keys.yml4
-rw-r--r--changelogs/unreleased/3612-update-script-template-order-in-vue-files.yml5
-rw-r--r--changelogs/unreleased/36255-metrics-that-do-not-have-a-complete-history-are-not-shown-at-all.yml5
-rw-r--r--changelogs/unreleased/36549-circuit-breaker-handles-missing-storages.yml5
-rw-r--r--changelogs/unreleased/36631-activerecord-statementinvalid-pg-querycanceled-error-canceling-statement-due-to-statement-timeout.yml6
-rw-r--r--changelogs/unreleased/36670-remove-edit-form.yml5
-rw-r--r--changelogs/unreleased/3674-hashed-storage-attachments.yml5
-rw-r--r--changelogs/unreleased/36742-hide-close-mr-button-on-merge.yml5
-rw-r--r--changelogs/unreleased/36829-add-ability-to-verify-gpg-subkeys.yml5
-rw-r--r--changelogs/unreleased/36884-gitaly-admin-version.yml5
-rw-r--r--changelogs/unreleased/36953-add-gitLab-pages-version-to-admin-dashboard.yml5
-rw-r--r--changelogs/unreleased/37025-error-500-in-non-utf8-branch-names.yml4
-rw-r--r--changelogs/unreleased/37105-monitoring-graph-axes-labels-are-inaccurate-and-inconsistent.yml5
-rw-r--r--changelogs/unreleased/37220-es-modules.yml5
-rw-r--r--changelogs/unreleased/37229-mr-widget-status-icon.yml5
-rw-r--r--changelogs/unreleased/37335-counter-active-state.yml5
-rw-r--r--changelogs/unreleased/37405-admin-page-runner-tag-help-update.yml5
-rw-r--r--changelogs/unreleased/37483-activity-log-show-wrong-number-of-commits-per-push.yml5
-rw-r--r--changelogs/unreleased/37552-replace-js-true-with-js.yml5
-rw-r--r--changelogs/unreleased/37691-subscription-fires-multiple-notifications.yml5
-rw-r--r--changelogs/unreleased/37970-ci-sections-tracking.yml5
-rw-r--r--changelogs/unreleased/37970-timestamped-ci.yml5
-rw-r--r--changelogs/unreleased/37999-fix-circuit-breaker.yml5
-rw-r--r--changelogs/unreleased/38031-monitoring-hover-info-is-clipped.yml6
-rw-r--r--changelogs/unreleased/38036-hover-and-legend-data-should-be-linked.yml5
-rw-r--r--changelogs/unreleased/38052-use-simple-api-for-projects.yml5
-rw-r--r--changelogs/unreleased/38178-fl-mr-notes-components.yml6
-rw-r--r--changelogs/unreleased/38187-38315-fix-dropdown-open-top-bottom-spacing.yml5
-rw-r--r--changelogs/unreleased/38197-fix-ImapAuthenticationCheck.yml5
-rw-r--r--changelogs/unreleased/38202-cannot-rename-a-hashed-project.yml6
-rw-r--r--changelogs/unreleased/38234-reserve-refs-replace.yml5
-rw-r--r--changelogs/unreleased/38389-allow-merge-without-success.yml6
-rw-r--r--changelogs/unreleased/38417-use-explicit-boolean-vue-attribute.yml5
-rw-r--r--changelogs/unreleased/38432-fix-notes-type-for-import.yml6
-rw-r--r--changelogs/unreleased/38502-fix-nav-dropdown-close-animation.yml5
-rw-r--r--changelogs/unreleased/38534-minigraph.yml5
-rw-r--r--changelogs/unreleased/38571-fix-exception-in-raven-report.yml6
-rw-r--r--changelogs/unreleased/38619-fix-comment-delete-confirm-text.yml5
-rw-r--r--changelogs/unreleased/38635-fix-gitlab-check-git-ssh-config.yml5
-rw-r--r--changelogs/unreleased/38696-fix-project-snippets-breadcrumb-link.yml5
-rw-r--r--changelogs/unreleased/38775-scrollable-tabs-on-admin.yml5
-rw-r--r--changelogs/unreleased/38789-prometheus-graphs-occasionally-have-incorrect-y-scale.yml5
-rw-r--r--changelogs/unreleased/39017-gitlabusagepingworker-is-not-running-on-gitlab-com.yml5
-rw-r--r--changelogs/unreleased/39032-improve-merge-ongoing-check-consistency.yml5
-rw-r--r--changelogs/unreleased/39054-activerecord-statementinvalid-pg-querycanceled-error-canceling-statement-due-to-statement-timeout.yml5
-rw-r--r--changelogs/unreleased/39188-change-default-disabled-merge-message.yml5
-rw-r--r--changelogs/unreleased/39366-email-confirmation-fails.yml5
-rw-r--r--changelogs/unreleased/39419-remove-overzealous-tooltips.yml5
-rw-r--r--changelogs/unreleased/39441-bring-edit-form-back.yml5
-rw-r--r--changelogs/unreleased/39495-fix-bitbucket-login.yml5
-rw-r--r--changelogs/unreleased/39509-fix-wiki-create-sidebar-overlap.yml5
-rw-r--r--changelogs/unreleased/39570-performance-bar-appears-enabled-even-though-it-won-t-show-up.yml5
-rw-r--r--changelogs/unreleased/39580-bump-carrierwave-to-1-2-1.yml5
-rw-r--r--changelogs/unreleased/39582-nestingdepth-6.yml5
-rw-r--r--changelogs/unreleased/39583-reopen-issue-count-cache.yml5
-rw-r--r--changelogs/unreleased/39593-emails-on-push-are-sent-to-only-the-first-recipient-when-using-aws-ses.yml5
-rw-r--r--changelogs/unreleased/39619-cancel-merge-when-pipeline-succeeds-from-the-api-fails.yml5
-rw-r--r--changelogs/unreleased/39639-clusters-poll.yml5
-rw-r--r--changelogs/unreleased/5836-move-lib-ci-into-gitlab-namespace.yml5
-rw-r--r--changelogs/unreleased/add-1000-plus-counters-for-jobs-page.yml5
-rw-r--r--changelogs/unreleased/add-ci-builds-index-for-jobscontroller.yml5
-rw-r--r--changelogs/unreleased/add-composite-index-on-merge-requests-merge-commit-sha.yml5
-rw-r--r--changelogs/unreleased/add-labels-template-index.yml5
-rw-r--r--changelogs/unreleased/add-packagist-project-service.yml5
-rw-r--r--changelogs/unreleased/add-shared-vue-loading-button.yml5
-rw-r--r--changelogs/unreleased/add-view-replaced-file-link.yml5
-rw-r--r--changelogs/unreleased/add_closed_at_attribute.yml5
-rw-r--r--changelogs/unreleased/add_tooltip_for_milestone_in_issues_list.yml5
-rw-r--r--changelogs/unreleased/adjusting-tooltips.yml5
-rw-r--r--changelogs/unreleased/an-popen-deadline.yml5
-rw-r--r--changelogs/unreleased/api-configure-jira.yml5
-rw-r--r--changelogs/unreleased/api-doc-group-statistics.yml5
-rw-r--r--changelogs/unreleased/breadcrumb-item-links.yml5
-rw-r--r--changelogs/unreleased/breadcrumbs-line-height-padding.yml5
-rw-r--r--changelogs/unreleased/bugfix-graph-friendly-notes-number.yml5
-rw-r--r--changelogs/unreleased/bvl-circuitbreaker-backoff.yml6
-rw-r--r--changelogs/unreleased/bvl-dont-rename-free-names.yml5
-rw-r--r--changelogs/unreleased/bvl-fix-deleting-forked-projects.yml5
-rw-r--r--changelogs/unreleased/bvl-fix-group-atom-feed.yml5
-rw-r--r--changelogs/unreleased/bvl-fix-locale-path.yml5
-rw-r--r--changelogs/unreleased/bvl-fix-push-event-service-for-forks.yml5
-rw-r--r--changelogs/unreleased/bvl-fix-system-hook-project-visibility.yml5
-rw-r--r--changelogs/unreleased/bvl-fork-network-schema.yml5
-rw-r--r--changelogs/unreleased/cache-issuable-template-names.yml5
-rw-r--r--changelogs/unreleased/change-dashed-border-button-color.yml5
-rw-r--r--changelogs/unreleased/close-issue-by-implements.yml5
-rw-r--r--changelogs/unreleased/commit-row-avatar-align-top.yml5
-rw-r--r--changelogs/unreleased/consistent-tooltip-direction-on-commits.yml5
-rw-r--r--changelogs/unreleased/content-title-link-hover-bg.yml5
-rw-r--r--changelogs/unreleased/declarative-policy-optimisations.yml5
-rw-r--r--changelogs/unreleased/dm-bitbucket-import-truncated-shas.yml6
-rw-r--r--changelogs/unreleased/dm-closing-issue-urls.yml5
-rw-r--r--changelogs/unreleased/dm-copy-parallel-diff.yml5
-rw-r--r--changelogs/unreleased/dm-ldap-identity-normalize-dn.yml5
-rw-r--r--changelogs/unreleased/dm-pat-revoke.yml5
-rw-r--r--changelogs/unreleased/dm-simple-project-avatar-url.yml5
-rw-r--r--changelogs/unreleased/docs-17499-documentation-errors-about-creating-a-new-tag.yml5
-rw-r--r--changelogs/unreleased/docs-28814-clarify-artifacts-ref.yml5
-rw-r--r--changelogs/unreleased/docs-38152-bump-recommended-mysql-version.yml5
-rw-r--r--changelogs/unreleased/docs-add-summary-about-project-archiving.yml5
-rw-r--r--changelogs/unreleased/docs-openid-connect.yml5
-rw-r--r--changelogs/unreleased/ee-add-project-repository-storages-index.yml5
-rw-r--r--changelogs/unreleased/expose-last-pipeline-details-in-api-for-single-commit.yml5
-rw-r--r--changelogs/unreleased/feature-custom-attributes.yml4
-rw-r--r--changelogs/unreleased/feature-sm-35954-create-kubernetes-cluster-on-gke-from-k8s-service.yml5
-rw-r--r--changelogs/unreleased/feature-ssh_host_fingerprint.yml5
-rw-r--r--changelogs/unreleased/feature-verify_secondary_emails.yml5
-rw-r--r--changelogs/unreleased/ff_port_from_ee.yml5
-rw-r--r--changelogs/unreleased/fix-500-on-old-merge-requests.yml5
-rw-r--r--changelogs/unreleased/fix-add-path-attr-to-wiki-file.yml5
-rw-r--r--changelogs/unreleased/fix-application-setting-nil-cache.yml5
-rw-r--r--changelogs/unreleased/fix-edit-project-service-cancel-button-position.yml5
-rw-r--r--changelogs/unreleased/fix-gpg-case-insensitive.yml5
-rw-r--r--changelogs/unreleased/fix-image-diff-swipe-handle.yml5
-rw-r--r--changelogs/unreleased/fix-import-issue-assignees.yml5
-rw-r--r--changelogs/unreleased/fix-multi-line-hook-output.yml5
-rw-r--r--changelogs/unreleased/fix-non-diff-resolved-discussion.yml5
-rw-r--r--changelogs/unreleased/fix-project-select-js-without-button.yml5
-rw-r--r--changelogs/unreleased/fix-resolved-side-by-side.yml5
-rw-r--r--changelogs/unreleased/fix-sidebar-with-scrollbars.yml5
-rw-r--r--changelogs/unreleased/fix-tooltip-width-issue-board.yml5
-rw-r--r--changelogs/unreleased/fix-update-doorkeeper-openid-connect.yml5
-rw-r--r--changelogs/unreleased/fl-autodevops-fix.yml5
-rw-r--r--changelogs/unreleased/fl-fix-ca-time-component.yml5
-rw-r--r--changelogs/unreleased/force-two-up-view.yml5
-rw-r--r--changelogs/unreleased/gem-sm-bump-google-api-client-gem-from-0-8-6-to-0-13-6.yml5
-rw-r--r--changelogs/unreleased/gitaly_feature_flag_metadata.yml5
-rw-r--r--changelogs/unreleased/group-milestones-breadcrumb.yml5
-rw-r--r--changelogs/unreleased/group-sort-dropdown-blank.yml5
-rw-r--r--changelogs/unreleased/hash-mr-scroll-load.yml5
-rw-r--r--changelogs/unreleased/hashed-storage-migration-path.yml5
-rw-r--r--changelogs/unreleased/hide-pipeline-zero-duration.yml5
-rw-r--r--changelogs/unreleased/hide-read-registry-scope-when-registry-disabled.yml4
-rw-r--r--changelogs/unreleased/ie-event-polyfill.yml5
-rw-r--r--changelogs/unreleased/import-sources-fix.yml5
-rw-r--r--changelogs/unreleased/improve_sorting_list.yml5
-rw-r--r--changelogs/unreleased/issue_32215.yml5
-rw-r--r--changelogs/unreleased/issue_35873.yml5
-rw-r--r--changelogs/unreleased/issue_38777.yml5
-rw-r--r--changelogs/unreleased/italicized_emoji.yml5
-rw-r--r--changelogs/unreleased/jobs-sort-by-id.yml5
-rw-r--r--changelogs/unreleased/kt-bug-fix-revision-and-size-for-container-registry.yml5
-rw-r--r--changelogs/unreleased/lint-changelog-yaml.yml5
-rw-r--r--changelogs/unreleased/make-merge-jid-handling-less-stateful.yml5
-rw-r--r--changelogs/unreleased/mentions-in-comments.yml5
-rw-r--r--changelogs/unreleased/merge-request-notes-performance.yml5
-rw-r--r--changelogs/unreleased/milestone-avatar-issuable-link.yml5
-rw-r--r--changelogs/unreleased/mk-clarify-moving-namespaces.yml5
-rw-r--r--changelogs/unreleased/mk-normalize-ldap-user-dns.yml5
-rw-r--r--changelogs/unreleased/mr-14642.yml6
-rw-r--r--changelogs/unreleased/mr-side-by-side-breadcrumbs-container.yml5
-rw-r--r--changelogs/unreleased/mr-widget-merged-date-tooltip.yml5
-rw-r--r--changelogs/unreleased/ph-multi-file-upload-file.yml5
-rw-r--r--changelogs/unreleased/prevent-creating-multiple-application-settings.yml5
-rw-r--r--changelogs/unreleased/project-page-clearer.yml5
-rw-r--r--changelogs/unreleased/rc-fix-gh-import-branches-performance.yml5
-rw-r--r--changelogs/unreleased/rd-fix-case-sensative-email-conf-signup.yml5
-rw-r--r--changelogs/unreleased/refactor-animate-js.yml5
-rw-r--r--changelogs/unreleased/refactor-monitoring-service.yml5
-rw-r--r--changelogs/unreleased/remote_user.yml4
-rw-r--r--changelogs/unreleased/remove-temporary-ci-index.yml5
-rw-r--r--changelogs/unreleased/remove-use-key-worker.yml5
-rw-r--r--changelogs/unreleased/remove_repo_prefix_from_api.yml5
-rw-r--r--changelogs/unreleased/replace_emails-feature.yml5
-rw-r--r--changelogs/unreleased/replace_group_links-feature.yml5
-rw-r--r--changelogs/unreleased/replace_milestone-feature.yml5
-rw-r--r--changelogs/unreleased/replace_profile_active_tab-feature.yml5
-rw-r--r--changelogs/unreleased/replace_project_archived-feature.yml5
-rw-r--r--changelogs/unreleased/replace_project_builds_summary-feature.yml5
-rw-r--r--changelogs/unreleased/replace_project_commits_revert-feature.yml5
-rw-r--r--changelogs/unreleased/replace_project_issues_award_emoji-feature.yml5
-rw-r--r--changelogs/unreleased/replace_project_merge_requests-feature.yml5
-rw-r--r--changelogs/unreleased/replace_project_merge_requests_accept-feature.yml5
-rw-r--r--changelogs/unreleased/replace_project_merge_requests_revert-feature.yml6
-rw-r--r--changelogs/unreleased/replace_project_service-feature.yml5
-rw-r--r--changelogs/unreleased/replace_project_shortcuts-feature.yml5
-rw-r--r--changelogs/unreleased/replace_project_snippets-feature.yml5
-rw-r--r--changelogs/unreleased/replace_search-feature.yml5
-rw-r--r--changelogs/unreleased/replace_spinach_wiki-feature.yml5
-rw-r--r--changelogs/unreleased/replace_team_management-feature.yml5
-rw-r--r--changelogs/unreleased/rotated_profile_image.yml5
-rw-r--r--changelogs/unreleased/save-a-query-on-todos-with-no-filters.yml5
-rw-r--r--changelogs/unreleased/sh-fix-broken-redirection-relative-url-root.yml5
-rw-r--r--changelogs/unreleased/sh-fix-container-registry-destroy.yml5
-rw-r--r--changelogs/unreleased/sh-fix-environment-write-ref.yml5
-rw-r--r--changelogs/unreleased/sh-fix-username-logging.yml5
-rw-r--r--changelogs/unreleased/sh-memoize-logger.yml5
-rw-r--r--changelogs/unreleased/sh-show-all-slack-names.yml5
-rw-r--r--changelogs/unreleased/sh-thread-safe-markdown.yml5
-rw-r--r--changelogs/unreleased/tag-link-size.yml5
-rw-r--r--changelogs/unreleased/tc-geo-read-only-idea.yml5
-rw-r--r--changelogs/unreleased/uipolish-fix-2factor-warning.yml5
-rw-r--r--changelogs/unreleased/uipolish-fix-remember-me-checkbox.yml5
-rw-r--r--changelogs/unreleased/update-fe-i18n-guide.yml5
-rw-r--r--changelogs/unreleased/update-pages-0-6.yml5
-rw-r--r--changelogs/unreleased/use-git-branch-merged.yml5
-rw-r--r--changelogs/unreleased/valid-branch-name-dash-bug.yml5
-rw-r--r--changelogs/unreleased/voogsgerd-gitlab-ce-daniel-legacy-config.yml5
-rw-r--r--changelogs/unreleased/winh-delete-account-modal.yml5
-rw-r--r--changelogs/unreleased/winh-indeterminate-dropdown.yml5
-rw-r--r--changelogs/unreleased/winh-protected-branch-modal-merged.yml5
-rw-r--r--changelogs/unreleased/winh-sprintf.yml5
-rw-r--r--changelogs/unreleased/zj-commit-cache.yml5
-rw-r--r--changelogs/unreleased/zj-peek-gitaly.yml5
-rw-r--r--changelogs/unreleased/zj-ruby-2-3-5.yml5
-rw-r--r--config/initializers/peek.rb1
-rw-r--r--config/routes/ci.rb2
-rw-r--r--config/routes/group.rb70
-rw-r--r--config/routes/help.rb9
-rw-r--r--config/routes/project.rb3
-rw-r--r--config/routes/snippets.rb2
-rw-r--r--config/routes/user.rb12
-rw-r--r--db/migrate/20171017145932_add_new_circuitbreaker_settings_to_application_settings.rb16
-rw-r--r--db/post_migrate/20170525140254_rename_all_reserved_paths_again.rb11
-rw-r--r--db/schema.rb4
-rw-r--r--doc/README.md4
-rw-r--r--doc/administration/img/circuitbreaker_config.pngbin213210 -> 335073 bytes
-rw-r--r--doc/administration/monitoring/performance/performance_bar.md6
-rw-r--r--doc/administration/monitoring/prometheus/gitlab_metrics.md4
-rw-r--r--doc/administration/repository_storage_paths.md14
-rw-r--r--doc/administration/repository_storage_types.md25
-rw-r--r--doc/api/README.md3
-rw-r--r--doc/api/groups.md32
-rw-r--r--doc/api/pages_domains.md170
-rw-r--r--doc/api/pipelines.md2
-rw-r--r--doc/api/services.md38
-rw-r--r--doc/api/settings.md2
-rw-r--r--doc/ci/docker/using_docker_images.md4
-rw-r--r--doc/ci/variables/README.md2
-rw-r--r--doc/development/ee_features.md382
-rw-r--r--doc/development/fe_guide/index.md7
-rw-r--r--doc/development/fe_guide/vue.md51
-rw-r--r--doc/development/fe_guide/vue_resource.md72
-rw-r--r--doc/development/i18n/externalization.md40
-rw-r--r--doc/gitlab-basics/add-merge-request.md23
-rw-r--r--doc/gitlab-basics/img/merge_request_new.pngbin2234 -> 0 bytes
-rw-r--r--doc/gitlab-basics/img/merge_request_select_branch.pngbin20332 -> 16668 bytes
-rw-r--r--doc/gitlab-basics/img/project_navbar.pngbin3259 -> 0 bytes
-rw-r--r--doc/integration/saml.md11
-rw-r--r--doc/integration/trello_power_up.md2
-rw-r--r--doc/policy/maintenance.md31
-rw-r--r--doc/raketasks/backup_restore.md123
-rw-r--r--doc/user/project/import/index.md2
-rw-r--r--doc/user/project/integrations/project_services.md1
-rw-r--r--doc/user/project/integrations/webhooks.md10
-rw-r--r--doc/user/project/merge_requests/index.md1
-rw-r--r--doc/user/project/milestones/index.md3
-rw-r--r--doc/user/project/pages/introduction.md8
-rw-r--r--doc/user/project/repository/branches/index.md2
-rw-r--r--doc/user/project/repository/web_editor.md2
-rw-r--r--doc/workflow/shortcuts.md2
-rw-r--r--features/steps/project/issues/issues.rb6
-rw-r--r--lib/additional_email_headers_interceptor.rb6
-rw-r--r--lib/api/api.rb1
-rw-r--r--lib/api/entities.rb17
-rw-r--r--lib/api/helpers.rb4
-rw-r--r--lib/api/merge_requests.rb2
-rw-r--r--lib/api/pages_domains.rb117
-rw-r--r--lib/api/services.rb25
-rw-r--r--lib/api/v3/services.rb20
-rw-r--r--lib/backup/manager.rb10
-rw-r--r--lib/gitlab/database.rb8
-rw-r--r--lib/gitlab/diff/position.rb8
-rw-r--r--lib/gitlab/git/branch.rb8
-rw-r--r--lib/gitlab/git/commit.rb3
-rw-r--r--lib/gitlab/git/hooks_service.rb2
-rw-r--r--lib/gitlab/git/repository.rb23
-rw-r--r--lib/gitlab/git/storage.rb1
-rw-r--r--lib/gitlab/git/storage/circuit_breaker.rb41
-rw-r--r--lib/gitlab/git/storage/circuit_breaker_settings.rb8
-rw-r--r--lib/gitlab/git/storage/forked_storage_check.rb13
-rw-r--r--lib/gitlab/git/storage/null_circuit_breaker.rb4
-rw-r--r--lib/gitlab/git/user.rb7
-rw-r--r--lib/gitlab/git/wiki.rb65
-rw-r--r--lib/gitlab/git/wiki_file.rb3
-rw-r--r--lib/gitlab/git_access.rb4
-rw-r--r--lib/gitlab/gitaly_client.rb9
-rw-r--r--lib/gitlab/gitaly_client/operation_service.rb10
-rw-r--r--lib/gitlab/gitaly_client/util.rb10
-rw-r--r--lib/gitlab/gitaly_client/wiki_page.rb25
-rw-r--r--lib/gitlab/gitaly_client/wiki_service.rb59
-rw-r--r--lib/gitlab/import_export/import_export.yml1
-rw-r--r--lib/gitlab/ldap/auth_hash.rb2
-rw-r--r--lib/gitlab/ldap/user.rb5
-rw-r--r--lib/gitlab/logger.rb12
-rw-r--r--lib/gitlab/performance_bar/peek_query_tracker.rb4
-rw-r--r--lib/omni_auth/strategies/bitbucket.rb4
-rw-r--r--lib/peek/views/gitaly.rb34
-rw-r--r--lib/system_check/app/ruby_version_check.rb2
-rw-r--r--locale/gitlab.pot75
-rw-r--r--package.json2
-rw-r--r--qa/qa/page/group/show.rb16
-rw-r--r--qa/qa/scenario/gitlab/project/create.rb2
-rw-r--r--spec/controllers/admin/hooks_controller_spec.rb2
-rw-r--r--spec/controllers/admin/impersonations_controller_spec.rb6
-rw-r--r--spec/controllers/admin/projects_controller_spec.rb2
-rw-r--r--spec/controllers/admin/runners_controller_spec.rb14
-rw-r--r--spec/controllers/admin/services_controller_spec.rb6
-rw-r--r--spec/controllers/admin/spam_logs_controller_spec.rb8
-rw-r--r--spec/controllers/admin/users_controller_spec.rb4
-rw-r--r--spec/controllers/application_controller_spec.rb16
-rw-r--r--spec/controllers/autocomplete_controller_spec.rb10
-rw-r--r--spec/controllers/boards/issues_controller_spec.rb28
-rw-r--r--spec/controllers/boards/lists_controller_spec.rb32
-rw-r--r--spec/controllers/dashboard/milestones_controller_spec.rb2
-rw-r--r--spec/controllers/dashboard/todos_controller_spec.rb14
-rw-r--r--spec/controllers/groups/group_members_controller_spec.rb18
-rw-r--r--spec/controllers/groups/labels_controller_spec.rb2
-rw-r--r--spec/controllers/groups/milestones_controller_spec.rb14
-rw-r--r--spec/controllers/groups/settings/ci_cd_controller_spec.rb2
-rw-r--r--spec/controllers/groups/variables_controller_spec.rb2
-rw-r--r--spec/controllers/groups_controller_spec.rb43
-rw-r--r--spec/controllers/health_check_controller_spec.rb8
-rw-r--r--spec/controllers/help_controller_spec.rb2
-rw-r--r--spec/controllers/invites_controller_spec.rb4
-rw-r--r--spec/controllers/notification_settings_controller_spec.rb4
-rw-r--r--spec/controllers/oauth/applications_controller_spec.rb4
-rw-r--r--spec/controllers/oauth/authorizations_controller_spec.rb6
-rw-r--r--spec/controllers/passwords_controller_spec.rb2
-rw-r--r--spec/controllers/profiles/accounts_controller_spec.rb6
-rw-r--r--spec/controllers/projects/artifacts_controller_spec.rb8
-rw-r--r--spec/controllers/projects/badges_controller_spec.rb4
-rw-r--r--spec/controllers/projects/blame_controller_spec.rb2
-rw-r--r--spec/controllers/projects/blob_controller_spec.rb4
-rw-r--r--spec/controllers/projects/boards_controller_spec.rb6
-rw-r--r--spec/controllers/projects/branches_controller_spec.rb28
-rw-r--r--spec/controllers/projects/clusters_controller_spec.rb14
-rw-r--r--spec/controllers/projects/commit_controller_spec.rb12
-rw-r--r--spec/controllers/projects/compare_controller_spec.rb8
-rw-r--r--spec/controllers/projects/deployments_controller_spec.rb4
-rw-r--r--spec/controllers/projects/discussions_controller_spec.rb12
-rw-r--r--spec/controllers/projects/environments_controller_spec.rb26
-rw-r--r--spec/controllers/projects/forks_controller_spec.rb4
-rw-r--r--spec/controllers/projects/issues_controller_spec.rb67
-rw-r--r--spec/controllers/projects/jobs_controller_spec.rb46
-rw-r--r--spec/controllers/projects/labels_controller_spec.rb18
-rw-r--r--spec/controllers/projects/mattermosts_controller_spec.rb2
-rw-r--r--spec/controllers/projects/merge_requests/conflicts_controller_spec.rb16
-rw-r--r--spec/controllers/projects/merge_requests/creations_controller_spec.rb2
-rw-r--r--spec/controllers/projects/merge_requests/diffs_controller_spec.rb8
-rw-r--r--spec/controllers/projects/merge_requests_controller_spec.rb20
-rw-r--r--spec/controllers/projects/milestones_controller_spec.rb30
-rw-r--r--spec/controllers/projects/notes_controller_spec.rb38
-rw-r--r--spec/controllers/projects/pages_controller_spec.rb10
-rw-r--r--spec/controllers/projects/pages_domains_controller_spec.rb12
-rw-r--r--spec/controllers/projects/pipeline_schedules_controller_spec.rb16
-rw-r--r--spec/controllers/projects/pipelines_controller_spec.rb20
-rw-r--r--spec/controllers/projects/pipelines_settings_controller_spec.rb2
-rw-r--r--spec/controllers/projects/project_members_controller_spec.rb16
-rw-r--r--spec/controllers/projects/prometheus_controller_spec.rb6
-rw-r--r--spec/controllers/projects/raw_controller_spec.rb10
-rw-r--r--spec/controllers/projects/registry/repositories_controller_spec.rb12
-rw-r--r--spec/controllers/projects/registry/tags_controller_spec.rb6
-rw-r--r--spec/controllers/projects/repositories_controller_spec.rb2
-rw-r--r--spec/controllers/projects/runners_controller_spec.rb8
-rw-r--r--spec/controllers/projects/services_controller_spec.rb2
-rw-r--r--spec/controllers/projects/settings/ci_cd_controller_spec.rb2
-rw-r--r--spec/controllers/projects/settings/integrations_controller_spec.rb2
-rw-r--r--spec/controllers/projects/settings/repository_controller_spec.rb2
-rw-r--r--spec/controllers/projects/snippets_controller_spec.rb18
-rw-r--r--spec/controllers/projects/todos_controller_spec.rb20
-rw-r--r--spec/controllers/projects/tree_controller_spec.rb2
-rw-r--r--spec/controllers/projects/uploads_controller_spec.rb22
-rw-r--r--spec/controllers/projects/variables_controller_spec.rb2
-rw-r--r--spec/controllers/projects_controller_spec.rb54
-rw-r--r--spec/controllers/sent_notifications_controller_spec.rb2
-rw-r--r--spec/controllers/sessions_controller_spec.rb4
-rw-r--r--spec/controllers/snippets/notes_controller_spec.rb20
-rw-r--r--spec/controllers/snippets_controller_spec.rb26
-rw-r--r--spec/controllers/uploads_controller_spec.rb40
-rw-r--r--spec/controllers/users_controller_spec.rb12
-rw-r--r--spec/factories/ci/builds.rb2
-rw-r--r--spec/factories/instance_configuration.rb5
-rw-r--r--spec/factories/services.rb2
-rw-r--r--spec/features/admin/admin_settings_spec.rb23
-rw-r--r--spec/features/boards/boards_spec.rb2
-rw-r--r--spec/features/groups/milestone_spec.rb13
-rw-r--r--spec/features/issues/form_spec.rb49
-rw-r--r--spec/features/issues_spec.rb108
-rw-r--r--spec/features/merge_requests/created_from_fork_spec.rb1
-rw-r--r--spec/features/profiles/chat_names_spec.rb4
-rw-r--r--spec/features/profiles/password_spec.rb4
-rw-r--r--spec/features/projects/badges/coverage_spec.rb2
-rw-r--r--spec/features/projects/commit/builds_spec.rb1
-rw-r--r--spec/features/projects/environments/environment_spec.rb2
-rw-r--r--spec/features/projects/jobs_spec.rb2
-rw-r--r--spec/features/projects/members/share_with_group_spec.rb2
-rw-r--r--spec/features/projects/merge_requests/user_manages_subscription_spec.rb2
-rw-r--r--spec/features/projects/pipelines/pipelines_spec.rb2
-rw-r--r--spec/features/projects/ref_switcher_spec.rb35
-rw-r--r--spec/features/projects/services/user_activates_packagist_spec.rb24
-rw-r--r--spec/features/projects/services/user_views_services_spec.rb1
-rw-r--r--spec/features/projects/tree/create_directory_spec.rb43
-rw-r--r--spec/features/projects/tree/create_file_spec.rb38
-rw-r--r--spec/features/projects/tree/upload_file_spec.rb48
-rw-r--r--spec/features/security/project/internal_access_spec.rb15
-rw-r--r--spec/features/security/project/private_access_spec.rb15
-rw-r--r--spec/features/security/project/public_access_spec.rb15
-rw-r--r--spec/finders/branches_finder_spec.rb9
-rw-r--r--spec/fixtures/api/schemas/entities/issue.json44
-rw-r--r--spec/fixtures/api/schemas/entities/issue_sidebar.json21
-rw-r--r--spec/fixtures/api/schemas/entities/label.json26
-rw-r--r--spec/fixtures/api/schemas/entities/merge_request_basic.json4
-rw-r--r--spec/fixtures/api/schemas/issue.json27
-rw-r--r--spec/fixtures/api/schemas/public_api/v4/pages_domains.json23
-rw-r--r--spec/fixtures/ssh_host_example_key.pub1
-rw-r--r--spec/helpers/instance_configuration_helper_spec.rb51
-rw-r--r--spec/javascripts/gl_form_spec.js4
-rw-r--r--spec/javascripts/header_spec.js3
-rw-r--r--spec/javascripts/helpers/vue_mount_component_helper.js10
-rw-r--r--spec/javascripts/issuable_context_spec.js34
-rw-r--r--spec/javascripts/issuable_spec.js102
-rw-r--r--spec/javascripts/labels_issue_sidebar_spec.js3
-rw-r--r--spec/javascripts/merge_request_notes_spec.js2
-rw-r--r--spec/javascripts/merge_request_tabs_spec.js5
-rw-r--r--spec/javascripts/notes/components/issue_comment_form_spec.js6
-rw-r--r--spec/javascripts/notes/components/issue_placeholder_system_note_spec.js24
-rw-r--r--spec/javascripts/notes_spec.js12
-rw-r--r--spec/javascripts/pipelines/pipelines_table_row_spec.js1
-rw-r--r--spec/javascripts/pipelines/pipelines_table_spec.js3
-rw-r--r--spec/javascripts/repo/components/new_branch_form_spec.js114
-rw-r--r--spec/javascripts/repo/components/new_dropdown/index_spec.js71
-rw-r--r--spec/javascripts/repo/components/new_dropdown/modal_spec.js198
-rw-r--r--spec/javascripts/repo/components/new_dropdown/upload_spec.js103
-rw-r--r--spec/javascripts/repo/components/repo_commit_section_spec.js207
-rw-r--r--spec/javascripts/repo/components/repo_edit_button_spec.js82
-rw-r--r--spec/javascripts/repo/components/repo_editor_spec.js48
-rw-r--r--spec/javascripts/repo/components/repo_file_buttons_spec.js92
-rw-r--r--spec/javascripts/repo/components/repo_file_spec.js68
-rw-r--r--spec/javascripts/repo/components/repo_loading_file_spec.js42
-rw-r--r--spec/javascripts/repo/components/repo_prev_directory_spec.js56
-rw-r--r--spec/javascripts/repo/components/repo_preview_spec.js32
-rw-r--r--spec/javascripts/repo/components/repo_sidebar_spec.js168
-rw-r--r--spec/javascripts/repo/components/repo_spec.js35
-rw-r--r--spec/javascripts/repo/components/repo_tab_spec.js104
-rw-r--r--spec/javascripts/repo/components/repo_tabs_spec.js39
-rw-r--r--spec/javascripts/repo/helpers.js20
-rw-r--r--spec/javascripts/repo/mock_data.js14
-rw-r--r--spec/javascripts/repo/services/repo_service_spec.js171
-rw-r--r--spec/javascripts/search_autocomplete_spec.js1
-rw-r--r--spec/javascripts/sidebar/mock_data.js2
-rw-r--r--spec/javascripts/sidebar/participants_spec.js174
-rw-r--r--spec/javascripts/sidebar/sidebar_mediator_spec.js17
-rw-r--r--spec/javascripts/sidebar/sidebar_service_spec.js17
-rw-r--r--spec/javascripts/sidebar/sidebar_store_spec.js93
-rw-r--r--spec/javascripts/sidebar/sidebar_subscriptions_spec.js36
-rw-r--r--spec/javascripts/sidebar/subscriptions_spec.js42
-rw-r--r--spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js46
-rw-r--r--spec/javascripts/vue_shared/components/ci_badge_link_spec.js23
-rw-r--r--spec/javascripts/vue_shared/components/loading_button_spec.js93
-rw-r--r--spec/javascripts/vue_shared/components/notes/placeholder_note_spec.js (renamed from spec/javascripts/notes/components/issue_placeholder_note_spec.js)4
-rw-r--r--spec/javascripts/vue_shared/components/notes/placeholder_system_note_spec.js25
-rw-r--r--spec/javascripts/vue_shared/components/notes/system_note_spec.js (renamed from spec/javascripts/notes/components/issue_system_note_spec.js)6
-rw-r--r--spec/javascripts/vue_shared/components/user_avatar/user_avatar_link_spec.js39
-rw-r--r--spec/lib/additional_email_headers_interceptor_spec.rb21
-rw-r--r--spec/lib/banzai/filter/gollum_tags_filter_spec.rb10
-rw-r--r--spec/lib/gitlab/app_logger_spec.rb12
-rw-r--r--spec/lib/gitlab/database_spec.rb22
-rw-r--r--spec/lib/gitlab/diff/position_spec.rb37
-rw-r--r--spec/lib/gitlab/git/branch_spec.rb32
-rw-r--r--spec/lib/gitlab/git/hooks_service_spec.rb28
-rw-r--r--spec/lib/gitlab/git/repository_spec.rb80
-rw-r--r--spec/lib/gitlab/git/storage/circuit_breaker_spec.rb261
-rw-r--r--spec/lib/gitlab/git/storage/forked_storage_check_spec.rb15
-rw-r--r--spec/lib/gitlab/git/storage/null_circuit_breaker_spec.rb13
-rw-r--r--spec/lib/gitlab/git/user_spec.rb22
-rw-r--r--spec/lib/gitlab/gitaly_client/operation_service_spec.rb2
-rw-r--r--spec/lib/gitlab/gitaly_client/util_spec.rb14
-rw-r--r--spec/lib/gitlab/import_export/all_models.yml4
-rw-r--r--spec/lib/gitlab/import_export/project.json8
-rw-r--r--spec/lib/gitlab/import_export/project_tree_restorer_spec.rb4
-rw-r--r--spec/lib/gitlab/import_export/project_tree_saver_spec.rb4
-rw-r--r--spec/lib/gitlab/import_export/safe_model_attributes.yml3
-rw-r--r--spec/lib/gitlab/ldap/authentication_spec.rb4
-rw-r--r--spec/lib/gitlab/ldap/user_spec.rb8
-rw-r--r--spec/lib/gitlab/o_auth/user_spec.rb2
-rw-r--r--spec/lib/gitlab/saml/user_spec.rb2
-rw-r--r--spec/models/application_setting_spec.rb13
-rw-r--r--spec/models/ci/artifact_blob_spec.rb7
-rw-r--r--spec/models/concerns/subscribable_spec.rb6
-rw-r--r--spec/models/email_spec.rb8
-rw-r--r--spec/models/environment_spec.rb10
-rw-r--r--spec/models/identity_spec.rb14
-rw-r--r--spec/models/instance_configuration_spec.rb109
-rw-r--r--spec/models/merge_request_diff_commit_spec.rb83
-rw-r--r--spec/models/merge_request_spec.rb10
-rw-r--r--spec/models/project_services/jira_service_spec.rb14
-rw-r--r--spec/models/project_services/kubernetes_service_spec.rb39
-rw-r--r--spec/models/project_services/packagist_service_spec.rb46
-rw-r--r--spec/models/project_spec.rb68
-rw-r--r--spec/models/project_wiki_spec.rb84
-rw-r--r--spec/models/repository_spec.rb72
-rw-r--r--spec/models/wiki_page_spec.rb2
-rw-r--r--spec/requests/api/access_requests_spec.rb28
-rw-r--r--spec/requests/api/award_emoji_spec.rb54
-rw-r--r--spec/requests/api/boards_spec.rb34
-rw-r--r--spec/requests/api/broadcast_messages_spec.rb38
-rw-r--r--spec/requests/api/circuit_breakers_spec.rb10
-rw-r--r--spec/requests/api/commit_statuses_spec.rb38
-rw-r--r--spec/requests/api/commits_spec.rb32
-rw-r--r--spec/requests/api/deploy_keys_spec.rb30
-rw-r--r--spec/requests/api/deployments_spec.rb8
-rw-r--r--spec/requests/api/doorkeeper_access_spec.rb10
-rw-r--r--spec/requests/api/environments_spec.rb34
-rw-r--r--spec/requests/api/events_spec.rb24
-rw-r--r--spec/requests/api/features_spec.rb34
-rw-r--r--spec/requests/api/files_spec.rb44
-rw-r--r--spec/requests/api/group_variables_spec.rb40
-rw-r--r--spec/requests/api/groups_spec.rb120
-rw-r--r--spec/requests/api/internal_spec.rb78
-rw-r--r--spec/requests/api/issues_spec.rb160
-rw-r--r--spec/requests/api/jobs_spec.rb80
-rw-r--r--spec/requests/api/keys_spec.rb6
-rw-r--r--spec/requests/api/labels_spec.rb64
-rw-r--r--spec/requests/api/lint_spec.rb8
-rw-r--r--spec/requests/api/members_spec.rb44
-rw-r--r--spec/requests/api/merge_request_diffs_spec.rb10
-rw-r--r--spec/requests/api/merge_requests_spec.rb36
-rw-r--r--spec/requests/api/namespaces_spec.rb12
-rw-r--r--spec/requests/api/notes_spec.rb92
-rw-r--r--spec/requests/api/notification_settings_spec.rb16
-rw-r--r--spec/requests/api/oauth_tokens_spec.rb8
-rw-r--r--spec/requests/api/pages_domains_spec.rb440
-rw-r--r--spec/requests/api/pipeline_schedules_spec.rb72
-rw-r--r--spec/requests/api/pipelines_spec.rb64
-rw-r--r--spec/requests/api/project_hooks_spec.rb38
-rw-r--r--spec/requests/api/project_snippets_spec.rb34
-rw-r--r--spec/requests/api/projects_spec.rb256
-rw-r--r--spec/requests/api/repositories_spec.rb24
-rw-r--r--spec/requests/api/runner_spec.rb138
-rw-r--r--spec/requests/api/runners_spec.rb98
-rw-r--r--spec/requests/api/services_spec.rb24
-rw-r--r--spec/requests/api/session_spec.rb16
-rw-r--r--spec/requests/api/settings_spec.rb8
-rw-r--r--spec/requests/api/sidekiq_metrics_spec.rb8
-rw-r--r--spec/requests/api/snippets_spec.rb38
-rw-r--r--spec/requests/api/system_hooks_spec.rb20
-rw-r--r--spec/requests/api/templates_spec.rb12
-rw-r--r--spec/requests/api/todos_spec.rb12
-rw-r--r--spec/requests/api/triggers_spec.rb64
-rw-r--r--spec/requests/api/users_spec.rb344
-rw-r--r--spec/requests/api/v3/award_emoji_spec.rb54
-rw-r--r--spec/requests/api/v3/boards_spec.rb16
-rw-r--r--spec/requests/api/v3/branches_spec.rb24
-rw-r--r--spec/requests/api/v3/broadcast_messages_spec.rb6
-rw-r--r--spec/requests/api/v3/builds_spec.rb58
-rw-r--r--spec/requests/api/v3/commits_spec.rb82
-rw-r--r--spec/requests/api/v3/deploy_keys_spec.rb26
-rw-r--r--spec/requests/api/v3/deployments_spec.rb8
-rw-r--r--spec/requests/api/v3/environments_spec.rb28
-rw-r--r--spec/requests/api/v3/files_spec.rb28
-rw-r--r--spec/requests/api/v3/groups_spec.rb114
-rw-r--r--spec/requests/api/v3/issues_spec.rb236
-rw-r--r--spec/requests/api/v3/labels_spec.rb24
-rw-r--r--spec/requests/api/v3/members_spec.rb44
-rw-r--r--spec/requests/api/v3/merge_request_diffs_spec.rb4
-rw-r--r--spec/requests/api/v3/merge_requests_spec.rb120
-rw-r--r--spec/requests/api/v3/milestones_spec.rb46
-rw-r--r--spec/requests/api/v3/notes_spec.rb88
-rw-r--r--spec/requests/api/v3/pipelines_spec.rb26
-rw-r--r--spec/requests/api/v3/project_hooks_spec.rb40
-rw-r--r--spec/requests/api/v3/project_snippets_spec.rb26
-rw-r--r--spec/requests/api/v3/projects_spec.rb224
-rw-r--r--spec/requests/api/v3/repositories_spec.rb24
-rw-r--r--spec/requests/api/v3/runners_spec.rb28
-rw-r--r--spec/requests/api/v3/services_spec.rb2
-rw-r--r--spec/requests/api/v3/settings_spec.rb8
-rw-r--r--spec/requests/api/v3/snippets_spec.rb28
-rw-r--r--spec/requests/api/v3/system_hooks_spec.rb10
-rw-r--r--spec/requests/api/v3/tags_spec.rb10
-rw-r--r--spec/requests/api/v3/templates_spec.rb12
-rw-r--r--spec/requests/api/v3/triggers_spec.rb48
-rw-r--r--spec/requests/api/v3/users_spec.rb52
-rw-r--r--spec/requests/api/variables_spec.rb40
-rw-r--r--spec/requests/api/wikis_spec.rb22
-rw-r--r--spec/requests/git_http_spec.rb88
-rw-r--r--spec/requests/jwt_controller_spec.rb20
-rw-r--r--spec/requests/lfs_http_spec.rb108
-rw-r--r--spec/requests/openid_connect_spec.rb2
-rw-r--r--spec/requests/projects/cycle_analytics_events_spec.rb6
-rw-r--r--spec/routing/project_routing_spec.rb19
-rw-r--r--spec/routing/routing_spec.rb12
-rw-r--r--spec/serializers/issue_serializer_spec.rb27
-rw-r--r--spec/serializers/merge_request_basic_serializer_spec.rb10
-rw-r--r--spec/serializers/merge_request_serializer_spec.rb12
-rw-r--r--spec/services/merge_requests/merge_service_spec.rb49
-rw-r--r--spec/services/milestones/promote_service_spec.rb77
-rw-r--r--spec/services/projects/hashed_storage_migration_service_spec.rb2
-rw-r--r--spec/services/system_hooks_service_spec.rb6
-rw-r--r--spec/services/users/last_push_event_service_spec.rb1
-rw-r--r--spec/support/api/issues_resolving_discussions_shared_examples.rb2
-rw-r--r--spec/support/api/members_shared_examples.rb2
-rw-r--r--spec/support/api/milestones_shared_examples.rb66
-rw-r--r--spec/support/api/scopes/read_user_shared_examples.rb14
-rw-r--r--spec/support/api/time_tracking_shared_examples.rb18
-rw-r--r--spec/support/api/v3/time_tracking_shared_examples.rb18
-rw-r--r--spec/support/jira_service_helper.rb2
-rw-r--r--spec/support/shared_examples/requests/api/custom_attributes_shared_examples.rb14
-rw-r--r--spec/support/unique_ip_check_shared_examples.rb8
-rw-r--r--spec/support/update_invalid_issuable.rb27
-rw-r--r--spec/uploaders/file_uploader_spec.rb52
-rw-r--r--spec/views/help/index.html.haml_spec.rb8
-rw-r--r--spec/views/help/instance_configuration.html.haml_spec.rb29
-rw-r--r--spec/views/shared/issuable/_participants.html.haml.rb26
-rw-r--r--spec/workers/stuck_merge_jobs_worker_spec.rb9
-rw-r--r--vendor/assets/javascripts/autosize.js243
-rw-r--r--vendor/assets/javascripts/fuzzaldrin-plus.js1161
-rw-r--r--yarn.lock8
833 files changed, 11992 insertions, 8905 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 7757c8a7979..38fb743b0c9 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,7 +1,7 @@
-image: "dev.gitlab.org:5005/gitlab/gitlab-build-images:ruby-2.3.3-golang-1.8-git-2.13-phantomjs-2.1-node-8.x-yarn-1.0-postgresql-9.6"
+image: "dev.gitlab.org:5005/gitlab/gitlab-build-images:ruby-2.3.5-golang-1.8-git-2.13-phantomjs-2.1-node-8.x-yarn-1.0-postgresql-9.6"
.default-cache: &default-cache
- key: "ruby-233-with-yarn"
+ key: "ruby-235-with-yarn"
paths:
- vendor/ruby
- .yarn-cache/
@@ -52,7 +52,8 @@ stages:
<<: *dedicated-runner
variables:
TESTS_METADATA_S3_BUCKET: "gitlab-ce-cache"
- before_script: []
+ before_script:
+ - source scripts/utils.sh
artifacts:
expire_in: 31d
paths:
@@ -454,7 +455,7 @@ db:migrate:reset-mysql:
variables:
SETUP_DB: "false"
script:
- - git fetch origin v8.14.10
+ - git fetch origin v9.3.0
- git checkout -f FETCH_HEAD
- bundle install $BUNDLE_INSTALL_FLAGS
- cp config/gitlab.yml.example config/gitlab.yml
@@ -550,7 +551,7 @@ karma:
<<: *dedicated-runner
<<: *except-docs
<<: *pull-cache
- image: "dev.gitlab.org:5005/gitlab/gitlab-build-images:ruby-2.3.3-golang-1.8-git-2.13-chrome-61.0-node-8.x-yarn-1.0-postgresql-9.6"
+ image: "dev.gitlab.org:5005/gitlab/gitlab-build-images:ruby-2.3.5-golang-1.8-git-2.13-chrome-61.0-node-8.x-yarn-1.0-postgresql-9.6"
stage: test
variables:
BABEL_ENV: "coverage"
diff --git a/.gitlab/route-map.yml b/.gitlab/route-map.yml
new file mode 100644
index 00000000000..0b37dc68f8b
--- /dev/null
+++ b/.gitlab/route-map.yml
@@ -0,0 +1,3 @@
+# Documentation
+- source: /doc/(.+?)\.md/ # doc/administration/build_artifacts.md
+ public: '\1.html' # doc/administration/build_artifacts.html
diff --git a/.rubocop.yml b/.rubocop.yml
index a900f2e39f9..c427f219a0d 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -624,7 +624,7 @@ Style/PredicateName:
# branches, and conditions.
Metrics/AbcSize:
Enabled: true
- Max: 55.25
+ Max: 54.28
# This cop checks if the length of a block exceeds some maximum value.
Metrics/BlockLength:
diff --git a/.ruby-version b/.ruby-version
index 0bee604df76..cc6c9a491e0 100644
--- a/.ruby-version
+++ b/.ruby-version
@@ -1 +1 @@
-2.3.3
+2.3.5
diff --git a/.scss-lint.yml b/.scss-lint.yml
index 73f8d27f78c..d2c972fa9c4 100644
--- a/.scss-lint.yml
+++ b/.scss-lint.yml
@@ -121,7 +121,8 @@ linters:
# Avoid nesting selectors too deeply.
NestingDepth:
- enabled: false
+ enabled: true
+ max_depth: 6
# Always use placeholder selectors in @extend.
PlaceholderInExtend:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c857efddb15..6bca9944bb1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,198 @@
documentation](doc/development/changelog.md) for instructions on adding your own
entry.
+## 10.1.0 (2017-10-22)
+
+- [SECURITY] Use a timeout on certain git operations. !14872
+- [SECURITY] Move project repositories between namespaces when renaming users.
+- [SECURITY] Prevent an open redirect on project pages.
+- [SECURITY] Prevent a persistent XSS in user-provided markup.
+- [REMOVED] Remove the ability to visit the issue edit form directly. !14523
+- [REMOVED] Remove animate.js and label animation.
+- [FIXED] Perform prometheus data endpoint requests in parallel. !14003
+- [FIXED] Escape quotes in git username. !14020 (Brandon Everett)
+- [FIXED] Fixed non-UTF-8 valid branch names from causing an error. !14090
+- [FIXED] Read import sources from setting at first initialization. !14141 (Visay Keo)
+- [FIXED] Display full pre-receive and post-receive hook output in GitLab UI. !14222 (Robin Bobbitt)
+- [FIXED] Fix incorrect X-axis labels in Prometheus graphs. !14258
+- [FIXED] Fix the default branches sorting to actually be 'Last updated'. !14295
+- [FIXED] Fixes project denial of service via gitmodules using Extended ASCII. !14301
+- [FIXED] Fix the filesystem shard health check to check all configured shards. !14341
+- [FIXED] Compare email addresses case insensitively when verifying GPG signatures. !14376 (Tim Bishop)
+- [FIXED] Allow the git circuit breaker to correctly handle missing repository storages. !14417
+- [FIXED] Fix `rake gitlab:incoming_email:check` and make it report the actual error. !14423
+- [FIXED] Does not check if an invariant hashed storage path exists on disk when renaming projects. !14428
+- [FIXED] Also reserve refs/replace after importing a project. !14436
+- [FIXED] Fix profile image orientation based on EXIF data gvieira37. !14461 (gvieira37)
+- [FIXED] Move the deployment flag content to the left when deployment marker is near the end. !14514
+- [FIXED] Fix notes type created from import. This should fix some missing notes issues from imported projects. !14524
+- [FIXED] Fix bottom spacing for dropdowns that open upwards. !14535
+- [FIXED] Adjusts tag link to avoid underlining spaces. !14544 (Guilherme Vieira)
+- [FIXED] Add missing space in Sidekiq memory killer log message. !14553 (Benjamin Drung)
+- [FIXED] Ensure no exception is raised when Raven tries to get the current user in API context. !14580
+- [FIXED] Fix edit project service cancel button position. !14596 (Matt Coleman)
+- [FIXED] Fix case sensitive email confirmation on signup. !14606 (robdel12)
+- [FIXED] Whitelist authorized_keys.lock in the gitlab:check rake task. !14624
+- [FIXED] Allow merge in MR widget with no pipeline but using "Only allow merge requests to be merged if the pipeline succeeds". !14633
+- [FIXED] Fix navigation dropdown close animation on mobile screens. !14649
+- [FIXED] Fix the project import with issues and milestones. !14657
+- [FIXED] Use explicit boolean true attribute for show-disabled-button in Vue files. !14672
+- [FIXED] Make tabs on top scrollable on admin dashboard. !14685 (Takuya Noguchi)
+- [FIXED] Fix broken Y-axis scaling in some Prometheus graphs. !14693
+- [FIXED] Search or compare LDAP DNs case-insensitively and ignore excess whitespace. !14697
+- [FIXED] Allow prometheus graphs to correctly handle NaN values. !14741
+- [FIXED] Don't show an "Unsubscribe" link in snippet comment notifications. !14764
+- [FIXED] Fixed duplicate notifications when added multiple labels on an issue. !14798
+- [FIXED] Fix alignment for indeterminate marker in dropdowns. !14809
+- [FIXED] Fix error when updating a forked project with deleted `ForkedProjectLink`. !14916
+- [FIXED] Correctly render asset path for locales with a region. !14924
+- [FIXED] Fix the external URLs generated for online view of HTML artifacts. !14977
+- [FIXED] Reschedule merge request diff background migrations to catch failures from 9.5 run.
+- [FIXED] fix merge request widget status icon for failed CI.
+- [FIXED] Fix the number representing the amount of commits related to a push event.
+- [FIXED] Sync up hover and legend data across all graphs for the prometheus dashboard.
+- [FIXED] Fixes mini pipeline graph in commit view.
+- [FIXED] Fix comment deletion confirmation dialog typo.
+- [FIXED] Fix project snippets breadcrumb link.
+- [FIXED] Make usage ping scheduling more robust.
+- [FIXED] Make "merge ongoing" check more consistent.
+- [FIXED] Add 1000+ counters to job page.
+- [FIXED] Fixed issue/merge request breadcrumb titles not having links.
+- [FIXED] Fixed commit avatars being centered vertically.
+- [FIXED] Tooltips in the commit info box now all face the same direction. (Jedidiah Broadbent)
+- [FIXED] Fixed navbar title colors leaking out of the navbar.
+- [FIXED] Fix bug that caused merge requests with diff notes imported from Bitbucket to raise errors.
+- [FIXED] Correctly detect multiple issue URLs after 'Closes...' in MR descriptions.
+- [FIXED] Set default scope on PATs that don't have one set to allow them to be revoked.
+- [FIXED] Fix application setting to cache nil object.
+- [FIXED] Fix image diff swipe handle offset to correctly align with the frame.
+- [FIXED] Force non diff resolved discussion to display when collapse toggled.
+- [FIXED] Fix resolved discussions not expanding on side by side view.
+- [FIXED] Fixed the sidebar scrollbar overlapping links.
+- [FIXED] Issue board tooltips are now the correct width when the column is collapsed. (Jedidiah Broadbent)
+- [FIXED] Improve autodevops banner UX and render it only in project page.
+- [FIXED] Fix typo in cycle analytics breaking time component.
+- [FIXED] Force two up view to load by default for image diffs.
+- [FIXED] Fixed milestone breadcrumb links.
+- [FIXED] Fixed group sort dropdown defaulting to empty.
+- [FIXED] Fixed notes not being scrolled to in merge requests.
+- [FIXED] Adds Event polyfill for IE11.
+- [FIXED] Update native unicode emojis to always render as normal text (previously could render italicized). (Branka Martinovic)
+- [FIXED] Sort JobsController by id, not created_at.
+- [FIXED] Fix revision and total size missing for Container Registry.
+- [FIXED] Fixed milestone issuable assignee link URL.
+- [FIXED] Fixed breadcrumbs container expanding in side-by-side diff view.
+- [FIXED] Fixed merge request widget merged & closed date tooltip text.
+- [FIXED] Prevent creating multiple ApplicationSetting instances.
+- [FIXED] Fix username and ID not logging in production_json.log for Git activity.
+- [FIXED] Make Redcarpet Markdown renderer thread-safe.
+- [FIXED] Two factor auth messages in settings no longer overlap the button. (Jedidiah Broadbent)
+- [FIXED] Made the "remember me" check boxes have consistent styles and alignment. (Jedidiah Broadbent)
+- [FIXED] Prevent branches or tags from starting with invalid characters (e.g. -, .).
+- [DEPRECATED] Removed two legacy config options. (Daniel Voogsgerd)
+- [CHANGED] Show notes number more user-friendly in the graph. !13949 (Vladislav Kaverin)
+- [CHANGED] Link SAML users to LDAP by email. !14216
+- [CHANGED] Display whether branch has been merged when deleting protected branch. !14220
+- [CHANGED] Make the labels in the Compare form less confusing. !14225
+- [CHANGED] Confirmation email shows link as text instead of human readable text. !14243 (bitsapien)
+- [CHANGED] Return only group's members in user dropdowns on issuables list pages. !14249
+- [CHANGED] Added defaults for protected branches dropdowns on the repository settings. !14278
+- [CHANGED] Show confirmation modal before deleting account. !14360
+- [CHANGED] Allow creating merge requests across a fork network. !14422
+- [CHANGED] Re-arrange script HTML tags before template HTML tags in .vue files. !14671
+- [CHANGED] Create idea of read-only database. !14688
+- [CHANGED] Add active states to nav bar counters.
+- [CHANGED] Add view replaced file link for image diffs.
+- [CHANGED] Adjust tooltips to adhere to 8px grid and make them more readable.
+- [CHANGED] breadcrumbs receives padding when double lined.
+- [CHANGED] Allow developer role to admin milestones.
+- [CHANGED] Stop using Sidekiq for updating Key#last_used_at.
+- [CHANGED] Include GitLab full name in Slack messages.
+- [ADDED] Expose last pipeline details in API response when getting a single commit. !13521 (Mehdi Lahmam (@mehlah))
+- [ADDED] Allow to use same periods for different housekeeping tasks (effectively skipping the lesser task). !13711 (cernvcs)
+- [ADDED] Add GitLab-Pages version to Admin Dashboard. !14040 (travismiller)
+- [ADDED] Commenting on image diffs. !14061
+- [ADDED] Script to migrate project's repositories to new Hashed Storage. !14067
+- [ADDED] Hide close MR button after merge without reloading page. !14122 (Jacopo Beschi @jacopo-beschi)
+- [ADDED] Add Gitaly version to Admin Dashboard. !14313 (Jacopo Beschi @jacopo-beschi)
+- [ADDED] Add 'closed_at' attribute to Issues API. !14316 (Vitaliy @blackst0ne Klachkov)
+- [ADDED] Add tooltip for milestone due date to issue and merge request lists. !14318 (Vitaliy @blackst0ne Klachkov)
+- [ADDED] Improve list of sorting options. !14320 (Vitaliy @blackst0ne Klachkov)
+- [ADDED] Add client and call site metadata to Gitaly calls for better traceability. !14332
+- [ADDED] Strip gitlab-runner section markers in build trace HTML view. !14393
+- [ADDED] Add online view of HTML artifacts for public projects. !14399
+- [ADDED] Create Kubernetes cluster on GKE from k8s service. !14470
+- [ADDED] Add support for GPG subkeys in signature verification. !14517
+- [ADDED] Parse and store gitlab-runner timestamped section markers. !14551
+- [ADDED] Add "implements" to the default issue closing message regex. !14612 (Guilherme Vieira)
+- [ADDED] Replace `tag: true` into `:tag` in the specs. !14653 (Jacopo Beschi @jacopo-beschi)
+- [ADDED] Discussion lock for issues and merge requests.
+- [ADDED] Add an API endpoint to determine the forks of a project.
+- [ADDED] Add help text to runner edit: tags should be separated by commas. (Brendan O'Leary)
+- [ADDED] Only copy old/new code when selecting left/right side of parallel diff.
+- [ADDED] Expose avatar_url when requesting list of projects from API with simple=true.
+- [ADDED] A confirmation email is now sent when adding a secondary email address. (digitalmoksha)
+- [ADDED] Move Custom merge methods from EE.
+- [ADDED] Makes @mentions links have a different styling for better separation.
+- [ADDED] Added tabs to dashboard/projects to easily switch to personal projects.
+- [OTHER] Extract AutocompleteController#users into finder. !13778 (Maxim Rydkin, Mayra Cabrera)
+- [OTHER] Replace 'project/wiki.feature' spinach test with an rspec analog. !13856 (Vitaliy @blackst0ne Klachkov)
+- [OTHER] Expand docs for changing username or group path. !13914
+- [OTHER] Move `lib/ci` to `lib/gitlab/ci`. !14078 (Maxim Rydkin)
+- [OTHER] Decrease Cyclomatic Complexity threshold to 13. !14152 (Maxim Rydkin)
+- [OTHER] Decrease Perceived Complexity threshold to 15. !14160 (Maxim Rydkin)
+- [OTHER] Replace project/group_links.feature spinach test with an rspec analog. !14169 (Vitaliy @blackst0ne Klachkov)
+- [OTHER] Replace the project/milestone.feature spinach test with an rspec analog. !14171 (Vitaliy @blackst0ne Klachkov)
+- [OTHER] Replace the profile/emails.feature spinach test with an rspec analog. !14172 (Vitaliy @blackst0ne Klachkov)
+- [OTHER] Replace the project/team_management.feature spinach test with an rspec analog. !14173 (Vitaliy @blackst0ne Klachkov)
+- [OTHER] Replace the 'project/merge_requests/accept.feature' spinach test with an rspec analog. !14176 (Vitaliy @blackst0ne Klachkov)
+- [OTHER] Replace the 'project/builds/summary.feature' spinach test with an rspec analog. !14177 (Vitaliy @blackst0ne Klachkov)
+- [OTHER] Optimize the boards' issues fetching. !14198
+- [OTHER] Replace the 'project/merge_requests/revert.feature' spinach test with an rspec analog. !14201 (Vitaliy @blackst0ne Klachkov)
+- [OTHER] Replace the 'project/issues/award_emoji.feature' spinach test with an rspec analog. !14202 (Vitaliy @blackst0ne Klachkov)
+- [OTHER] Replace the 'profile/active_tab.feature' spinach test with an rspec analog. !14239 (Vitaliy @blackst0ne Klachkov)
+- [OTHER] Replace the 'search.feature' spinach test with an rspec analog. !14248 (Vitaliy @blackst0ne Klachkov)
+- [OTHER] Load sidebar participants avatars only when visible. !14270
+- [OTHER] Adds gitlab features and components to usage ping data. !14305
+- [OTHER] Replace the 'project/archived.feature' spinach test with an rspec analog. !14322 (Vitaliy @blackst0ne Klachkov)
+- [OTHER] Replace the 'project/commits/revert.feature' spinach test with an rspec analog. !14325 (Vitaliy @blackst0ne Klachkov)
+- [OTHER] Replace the 'project/snippets.feature' spinach test with an rspec analog. !14326 (Vitaliy @blackst0ne Klachkov)
+- [OTHER] Add link to OpenID Connect documentation. !14368 (Markus Koller)
+- [OTHER] Upgrade doorkeeper-openid_connect. !14372 (Markus Koller)
+- [OTHER] Upgrade gitlab-markup gem. !14395 (Markus Koller)
+- [OTHER] Index projects on repository storage. !14414
+- [OTHER] Replace the 'project/shortcuts.feature' spinach test with an rspec analog. !14431 (Vitaliy @blackst0ne Klachkov)
+- [OTHER] Replace the 'project/service.feature' spinach test with an rspec analog. !14432 (Vitaliy @blackst0ne Klachkov)
+- [OTHER] Improve GitHub import performance. !14445
+- [OTHER] Add basic sprintf implementation to JavaScript. !14506
+- [OTHER] Replace the 'project/merge_requests.feature' spinach test with an rspec analog. !14621 (Vitaliy @blackst0ne Klachkov)
+- [OTHER] Update GitLab Pages to v0.6.0. !14630
+- [OTHER] Add documentation to summarise project archiving. !14650
+- [OTHER] Remove 'Repo' prefix from API entites. !14694 (Vitaliy @blackst0ne Klachkov)
+- [OTHER] Removes cycle analytics service and store from global namespace.
+- [OTHER] Improves i18n for Auto Devops callout.
+- [OTHER] Exports common_utils utility functions as modules.
+- [OTHER] Use `simple=true` for projects API in Projects dropdown for better search performance.
+- [OTHER] Change index on ci_builds to optimize Jobs Controller.
+- [OTHER] Add index for merge_requests.merge_commit_sha.
+- [OTHER] Add (partial) index on Labels.template.
+- [OTHER] Cache issue and MR template names in Redis.
+- [OTHER] changed dashed border button color to be darker.
+- [OTHER] Speed up permission checks.
+- [OTHER] Fix docs for lightweight tag creation via API.
+- [OTHER] Clarify artifact download via the API only accepts branch or tag name for ref.
+- [OTHER] Change recommended MySQL version to 5.6.
+- [OTHER] Bump google-api-client Gem from 0.8.6 to 0.13.6.
+- [OTHER] Detect when changelog entries are invalid.
+- [OTHER] Use a UNION ALL for getting merge request notes.
+- [OTHER] Remove an index on ci_builds meant to be only temporary.
+- [OTHER] Remove a SQL query from the todos index page.
+- Support custom attributes on users. !13038 (Markus Koller)
+- made read-only APIs for public merge requests available without authentication. !13291 (haseebeqx)
+- Hide read_registry scope when registry is disabled on instance. !13314 (Robin Bobbitt)
+- creation of keys moved to services. !13331 (haseebeqx)
+- Add username as GL_USERNAME in hooks.
+
## 10.0.4 (2017-10-16)
- [SECURITY] Move project repositories between namespaces when renaming users.
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 83e41a11e52..9b2ee157193 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -21,10 +21,10 @@ _This notice should stay as the first item in the CONTRIBUTING.md file._
- [Workflow labels](#workflow-labels)
- [Type labels (~"feature proposal", ~bug, ~customer, etc.)](#type-labels-feature-proposal-bug-customer-etc)
- [Subject labels (~wiki, ~"container registry", ~ldap, ~api, etc.)](#subject-labels-wiki-container-registry-ldap-api-etc)
- - [Team labels (~"CI/CD", ~Discussion, ~Edge, ~Platform, etc.)](#team-labels-ci-discussion-edge-platform-etc)
+ - [Team labels (~"CI/CD", ~Discussion, ~Edge, ~Platform, etc.)](#team-labels-cicd-discussion-edge-platform-etc)
- [Priority labels (~Deliverable and ~Stretch)](#priority-labels-deliverable-and-stretch)
- [Label for community contributors (~"Accepting Merge Requests")](#label-for-community-contributors-accepting-merge-requests)
-- [Implement design & UI elements](#implement-design--ui-elements)
+- [Implement design & UI elements](#implement-design-ui-elements)
- [Issue tracker](#issue-tracker)
- [Issue triaging](#issue-triaging)
- [Feature proposals](#feature-proposals)
diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION
index fbaaafa001b..c5d4cee36a1 100644
--- a/GITALY_SERVER_VERSION
+++ b/GITALY_SERVER_VERSION
@@ -1 +1 @@
-0.49.0 \ No newline at end of file
+0.51.0
diff --git a/Gemfile b/Gemfile
index 6859ea73e4f..c97b1896d06 100644
--- a/Gemfile
+++ b/Gemfile
@@ -90,7 +90,7 @@ gem 'kaminari', '~> 1.0'
gem 'hamlit', '~> 2.6.1'
# Files attachments
-gem 'carrierwave', '~> 1.1'
+gem 'carrierwave', '~> 1.2'
# Drag and Drop UI
gem 'dropzonejs-rails', '~> 0.7.1'
@@ -102,7 +102,7 @@ gem 'fog-google', '~> 0.5'
gem 'fog-local', '~> 0.3'
gem 'fog-openstack', '~> 0.1'
gem 'fog-rackspace', '~> 0.1.1'
-gem 'fog-aliyun', '~> 0.1.0'
+gem 'fog-aliyun', '~> 0.2.0'
# for Google storage
gem 'google-api-client', '~> 0.13.6'
@@ -281,7 +281,7 @@ group :metrics do
gem 'influxdb', '~> 0.2', require: false
# Prometheus
- gem 'prometheus-client-mmap', '~>0.7.0.beta17'
+ gem 'prometheus-client-mmap', '~>0.7.0.beta18'
gem 'raindrops', '~> 0.18'
end
@@ -398,7 +398,7 @@ group :ed25519 do
end
# Gitaly GRPC client
-gem 'gitaly-proto', '~> 0.45.0', require: 'gitaly'
+gem 'gitaly-proto', '~> 0.51.0', require: 'gitaly'
gem 'toml-rb', '~> 0.3.15', require: false
diff --git a/Gemfile.lock b/Gemfile.lock
index 27a76dc36cb..4142977285e 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -107,7 +107,7 @@ GEM
capybara-screenshot (1.0.14)
capybara (>= 1.0, < 3)
launchy
- carrierwave (1.1.0)
+ carrierwave (1.2.1)
activemodel (>= 4.0.0)
activesupport (>= 4.0.0)
mime-types (>= 1.16)
@@ -214,7 +214,7 @@ GEM
flowdock (0.7.1)
httparty (~> 0.7)
multi_json
- fog-aliyun (0.1.0)
+ fog-aliyun (0.2.0)
fog-core (~> 1.27)
fog-json (~> 1.0)
ipaddress (~> 0.8)
@@ -273,7 +273,7 @@ GEM
po_to_json (>= 1.0.0)
rails (>= 3.2.0)
gherkin-ruby (0.3.2)
- gitaly-proto (0.45.0)
+ gitaly-proto (0.51.0)
google-protobuf (~> 3.1)
grpc (~> 1.0)
github-linguist (4.7.6)
@@ -623,7 +623,7 @@ GEM
parser
unparser
procto (0.0.3)
- prometheus-client-mmap (0.7.0.beta17)
+ prometheus-client-mmap (0.7.0.beta18)
mmap2 (~> 2.2, >= 2.2.7)
pry (0.10.4)
coderay (~> 1.1.0)
@@ -990,7 +990,7 @@ DEPENDENCIES
bundler-audit (~> 0.5.0)
capybara (~> 2.15.0)
capybara-screenshot (~> 1.0.0)
- carrierwave (~> 1.1)
+ carrierwave (~> 1.2)
charlock_holmes (~> 0.7.5)
chronic (~> 0.10.2)
chronic_duration (~> 0.10.6)
@@ -1015,7 +1015,7 @@ DEPENDENCIES
flay (~> 2.8.0)
flipper (~> 0.10.2)
flipper-active_record (~> 0.10.2)
- fog-aliyun (~> 0.1.0)
+ fog-aliyun (~> 0.2.0)
fog-aws (~> 1.4)
fog-core (~> 1.44)
fog-google (~> 0.5)
@@ -1030,7 +1030,7 @@ DEPENDENCIES
gettext (~> 3.2.2)
gettext_i18n_rails (~> 1.8.0)
gettext_i18n_rails_js (~> 1.2.0)
- gitaly-proto (~> 0.45.0)
+ gitaly-proto (~> 0.51.0)
github-linguist (~> 4.7.0)
gitlab-flowdock-git-hook (~> 1.0.1)
gitlab-markup (~> 1.6.2)
@@ -1106,7 +1106,7 @@ DEPENDENCIES
pg (~> 0.18.2)
poltergeist (~> 1.9.0)
premailer-rails (~> 1.9.7)
- prometheus-client-mmap (~> 0.7.0.beta17)
+ prometheus-client-mmap (~> 0.7.0.beta18)
pry-byebug (~> 3.4.1)
pry-rails (~> 0.3.4)
rack-attack (~> 4.4.1)
diff --git a/VERSION b/VERSION
index 22dd5aa0686..19eac09041d 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-10.1.0-pre
+10.2.0-pre
diff --git a/app/assets/javascripts/api.js b/app/assets/javascripts/api.js
index 242b3e2b990..d963101028a 100644
--- a/app/assets/javascripts/api.js
+++ b/app/assets/javascripts/api.js
@@ -16,6 +16,7 @@ const Api = {
usersPath: '/api/:version/users.json',
commitPath: '/api/:version/projects/:id/repository/commits',
branchSinglePath: '/api/:version/projects/:id/repository/branches/:branch',
+ createBranchPath: '/api/:version/projects/:id/repository/branches',
group(groupId, callback) {
const url = Api.buildUrl(Api.groupPath)
diff --git a/app/assets/javascripts/autosave.js b/app/assets/javascripts/autosave.js
index 4d2d4db7c0e..0f28bd233ac 100644
--- a/app/assets/javascripts/autosave.js
+++ b/app/assets/javascripts/autosave.js
@@ -1,8 +1,9 @@
-/* eslint-disable func-names, space-before-function-paren, wrap-iife, no-param-reassign, quotes, prefer-template, no-var, one-var, no-unused-vars, one-var-declaration-per-line, no-void, consistent-return, no-empty, max-len */
+/* eslint-disable no-param-reassign, prefer-template, no-var, no-void, consistent-return */
+
import AccessorUtilities from './lib/utils/accessor';
-window.Autosave = (function() {
- function Autosave(field, key, resource) {
+export default class Autosave {
+ constructor(field, key, resource) {
this.field = field;
this.isLocalStorageAvailable = AccessorUtilities.isLocalStorageAccessSafe();
this.resource = resource;
@@ -12,14 +13,10 @@ window.Autosave = (function() {
this.key = 'autosave/' + key;
this.field.data('autosave', this);
this.restore();
- this.field.on('input', (function(_this) {
- return function() {
- return _this.save();
- };
- })(this));
+ this.field.on('input', () => this.save());
}
- Autosave.prototype.restore = function() {
+ restore() {
var text;
if (!this.isLocalStorageAvailable) return;
@@ -40,9 +37,9 @@ window.Autosave = (function() {
field.dispatchEvent(event);
}
}
- };
+ }
- Autosave.prototype.save = function() {
+ save() {
var text;
text = this.field.val();
@@ -51,15 +48,11 @@ window.Autosave = (function() {
}
return this.reset();
- };
+ }
- Autosave.prototype.reset = function() {
+ reset() {
if (!this.isLocalStorageAvailable) return;
return window.localStorage.removeItem(this.key);
- };
-
- return Autosave;
-})();
-
-export default window.Autosave;
+ }
+}
diff --git a/app/assets/javascripts/behaviors/autosize.js b/app/assets/javascripts/behaviors/autosize.js
index e00af4b2fa8..add43b81f6d 100644
--- a/app/assets/javascripts/behaviors/autosize.js
+++ b/app/assets/javascripts/behaviors/autosize.js
@@ -1,8 +1,8 @@
-import autosize from 'vendor/autosize';
+import Autosize from 'autosize';
document.addEventListener('DOMContentLoaded', () => {
const autosizeEls = document.querySelectorAll('.js-autosize');
- autosize(autosizeEls);
- autosize.update(autosizeEls);
+ Autosize(autosizeEls);
+ Autosize.update(autosizeEls);
});
diff --git a/app/assets/javascripts/boards/components/board_sidebar.js b/app/assets/javascripts/boards/components/board_sidebar.js
index c1f902a785a..5d27518ac85 100644
--- a/app/assets/javascripts/boards/components/board_sidebar.js
+++ b/app/assets/javascripts/boards/components/board_sidebar.js
@@ -1,5 +1,4 @@
/* eslint-disable comma-dangle, space-before-function-paren, no-new */
-/* global IssuableContext */
/* global MilestoneSelect */
/* global LabelsSelect */
/* global Sidebar */
@@ -11,6 +10,7 @@ import AssigneeTitle from '../../sidebar/components/assignees/assignee_title';
import Assignees from '../../sidebar/components/assignees/assignees';
import DueDateSelectors from '../../due_date_select';
import './sidebar/remove_issue';
+import IssuableContext from '../../issuable_context';
const Store = gl.issueBoards.BoardsStore;
diff --git a/app/assets/javascripts/clusters.js b/app/assets/javascripts/clusters.js
index 180aa30e98c..661870c226c 100644
--- a/app/assets/javascripts/clusters.js
+++ b/app/assets/javascripts/clusters.js
@@ -64,19 +64,16 @@ export default class Clusters {
this.poll = new Poll({
resource: this.service,
method: 'fetchData',
- successCallback: (data) => {
- const { status, status_reason } = data.data;
- this.updateContainer(status, status_reason);
- },
- errorCallback: () => {
- Flash(s__('ClusterIntegration|Something went wrong on our end.'));
- },
+ successCallback: data => this.handleSuccess(data),
+ errorCallback: () => Clusters.handleError(),
});
if (!Visibility.hidden()) {
this.poll.makeRequest();
} else {
- this.service.fetchData();
+ this.service.fetchData()
+ .then(data => this.handleSuccess(data))
+ .catch(() => Clusters.handleError());
}
Visibility.change(() => {
@@ -88,6 +85,15 @@ export default class Clusters {
});
}
+ static handleError() {
+ Flash(s__('ClusterIntegration|Something went wrong on our end.'));
+ }
+
+ handleSuccess(data) {
+ const { status, status_reason } = data.data;
+ this.updateContainer(status, status_reason);
+ }
+
hideAll() {
this.errorContainer.classList.add('hidden');
this.successContainer.classList.add('hidden');
diff --git a/app/assets/javascripts/commit/pipelines/pipelines_table.vue b/app/assets/javascripts/commit/pipelines/pipelines_table.vue
index 0661087a1ba..e9a0dbaa59d 100644
--- a/app/assets/javascripts/commit/pipelines/pipelines_table.vue
+++ b/app/assets/javascripts/commit/pipelines/pipelines_table.vue
@@ -25,6 +25,11 @@
type: String,
required: true,
},
+ viewType: {
+ type: String,
+ required: false,
+ default: 'child',
+ },
},
mixins: [
pipelinesMixin,
@@ -110,6 +115,7 @@
:pipelines="state.pipelines"
:update-graph-dropdown="updateGraphDropdown"
:auto-devops-help-path="autoDevopsHelpPath"
+ :view-type="viewType"
/>
</div>
</div>
diff --git a/app/assets/javascripts/new_sidebar.js b/app/assets/javascripts/contextual_sidebar.js
index 997550b37fb..46b68ebe158 100644
--- a/app/assets/javascripts/new_sidebar.js
+++ b/app/assets/javascripts/contextual_sidebar.js
@@ -2,7 +2,7 @@ import Cookies from 'js-cookie';
import _ from 'underscore';
import bp from './breakpoints';
-export default class NewNavSidebar {
+export default class ContextualSidebar {
constructor() {
this.initDomElements();
this.render();
@@ -55,7 +55,7 @@ export default class NewNavSidebar {
this.$sidebar.toggleClass('sidebar-icons-only', collapsed);
this.$page.toggleClass('page-with-icon-sidebar', breakpoint === 'sm' ? true : collapsed);
}
- NewNavSidebar.setCollapsedCookie(collapsed);
+ ContextualSidebar.setCollapsedCookie(collapsed);
this.toggleSidebarOverflow();
}
diff --git a/app/assets/javascripts/diff.js b/app/assets/javascripts/diff.js
index 6c78662baa7..c8874e48c09 100644
--- a/app/assets/javascripts/diff.js
+++ b/app/assets/javascripts/diff.js
@@ -1,5 +1,3 @@
-/* eslint-disable class-methods-use-this */
-
import './lib/utils/url_utility';
import FilesCommentButton from './files_comment_button';
import SingleFileDiff from './single_file_diff';
@@ -8,7 +6,7 @@ import imageDiffHelper from './image_diff/helpers/index';
const UNFOLD_COUNT = 20;
let isBound = false;
-class Diff {
+export default class Diff {
constructor() {
const $diffFile = $('.files .diff-file');
@@ -104,7 +102,7 @@ class Diff {
}
this.highlightSelectedLine();
}
-
+ // eslint-disable-next-line class-methods-use-this
handleParallelLineDown(e) {
const line = $(e.currentTarget);
const table = line.closest('table');
@@ -116,11 +114,11 @@ class Diff {
table.addClass(`${lineClass}-selected`);
}
}
-
+ // eslint-disable-next-line class-methods-use-this
diffViewType() {
return $('.inline-parallel-buttons a.active').data('view-type');
}
-
+ // eslint-disable-next-line class-methods-use-this
lineNumbers(line) {
const children = line.find('.diff-line-num').toArray();
if (children.length !== 2) {
@@ -128,7 +126,7 @@ class Diff {
}
return children.map(elm => parseInt($(elm).data('linenumber'), 10) || 0);
}
-
+ // eslint-disable-next-line class-methods-use-this
highlightSelectedLine() {
const hash = gl.utils.getLocationHash();
const $diffFiles = $('.diff-file');
@@ -141,6 +139,3 @@ class Diff {
}
}
}
-
-window.gl = window.gl || {};
-window.gl.Diff = Diff;
diff --git a/app/assets/javascripts/dispatcher.js b/app/assets/javascripts/dispatcher.js
index 2885923aeda..b516fda84b9 100644
--- a/app/assets/javascripts/dispatcher.js
+++ b/app/assets/javascripts/dispatcher.js
@@ -1,18 +1,19 @@
/* eslint-disable func-names, space-before-function-paren, no-var, prefer-arrow-callback, wrap-iife, no-shadow, consistent-return, one-var, one-var-declaration-per-line, camelcase, default-case, no-new, quotes, no-duplicate-case, no-case-declarations, no-fallthrough, max-len */
/* global ProjectSelect */
-/* global IssuableIndex */
+import IssuableIndex from './issuable_index';
/* global Milestone */
-/* global IssuableForm */
+import IssuableForm from './issuable_form';
/* global LabelsSelect */
/* global MilestoneSelect */
/* global NewBranchForm */
/* global NotificationsForm */
/* global NotificationsDropdown */
-/* global GroupAvatar */
+import groupAvatar from './group_avatar';
+import GroupLabelSubscription from './group_label_subscription';
/* global LineHighlighter */
import BuildArtifacts from './build_artifacts';
import CILintEditor from './ci_lint_editor';
-/* global GroupsSelect */
+import groupsSelect from './groups_select';
/* global Search */
/* global Admin */
/* global NamespaceSelects */
@@ -87,6 +88,7 @@ import U2FAuthenticate from './u2f/authenticate';
import Members from './members';
import memberExpirationDate from './member_expiration_date';
import DueDateSelectors from './due_date_select';
+import Diff from './diff';
(function() {
var Dispatcher;
@@ -171,7 +173,7 @@ import DueDateSelectors from './due_date_select';
filteredSearchManager.setup();
}
const pagePrefix = page === 'projects:merge_requests:index' ? 'merge_request_' : 'issue_';
- IssuableIndex.init(pagePrefix);
+ new IssuableIndex(pagePrefix);
shortcut_handler = new ShortcutsNavigation();
new UsersSelect();
@@ -229,16 +231,21 @@ import DueDateSelectors from './due_date_select';
case 'projects:milestones:new':
case 'projects:milestones:edit':
case 'projects:milestones:update':
+ new ZenMode();
+ new DueDateSelectors();
+ new GLForm($('.milestone-form'), true);
+ break;
case 'groups:milestones:new':
case 'groups:milestones:edit':
case 'groups:milestones:update':
new ZenMode();
new DueDateSelectors();
- new GLForm($('.milestone-form'), true);
+ new GLForm($('.milestone-form'), false);
break;
case 'projects:compare:show':
- new gl.Diff();
- initChangesDropdown();
+ new Diff();
+ const paddingTop = 16;
+ initChangesDropdown(document.querySelector('.navbar-gitlab').offsetHeight - paddingTop);
break;
case 'projects:branches:new':
case 'projects:branches:create':
@@ -273,7 +280,7 @@ import DueDateSelectors from './due_date_select';
}
case 'projects:merge_requests:creations:diffs':
case 'projects:merge_requests:edit':
- new gl.Diff();
+ new Diff();
shortcut_handler = new ShortcutsNavigation();
new GLForm($('.merge-request-form'), true);
new IssuableForm($('.merge-request-form'));
@@ -307,7 +314,7 @@ import DueDateSelectors from './due_date_select';
new GLForm($('.release-form'), true);
break;
case 'projects:merge_requests:show':
- new gl.Diff();
+ new Diff();
shortcut_handler = new ShortcutsIssuable(true);
new ZenMode();
@@ -323,7 +330,7 @@ import DueDateSelectors from './due_date_select';
new gl.Activities();
break;
case 'projects:commit:show':
- new gl.Diff();
+ new Diff();
new ZenMode();
shortcut_handler = new ShortcutsNavigation();
new MiniPipelineGraph({
@@ -411,7 +418,7 @@ import DueDateSelectors from './due_date_select';
break;
case 'projects:project_members:index':
memberExpirationDate('.js-access-expiration-date-groups');
- new GroupsSelect();
+ groupsSelect();
memberExpirationDate();
new Members();
new UsersSelect();
@@ -422,11 +429,11 @@ import DueDateSelectors from './due_date_select';
case 'admin:groups:create':
BindInOut.initAll();
new Group();
- new GroupAvatar();
+ groupAvatar();
break;
case 'groups:edit':
case 'admin:groups:edit':
- new GroupAvatar();
+ groupAvatar();
break;
case 'projects:tree:show':
shortcut_handler = new ShortcutsNavigation();
@@ -473,7 +480,7 @@ import DueDateSelectors from './due_date_select';
const $el = $(el);
if ($el.find('.dropdown-group-label').length) {
- new gl.GroupLabelSubscription($el);
+ new GroupLabelSubscription($el);
} else {
new gl.ProjectLabelSubscription($el);
}
diff --git a/app/assets/javascripts/files_comment_button.js b/app/assets/javascripts/files_comment_button.js
index a00d29a845a..90020344748 100644
--- a/app/assets/javascripts/files_comment_button.js
+++ b/app/assets/javascripts/files_comment_button.js
@@ -1,6 +1,3 @@
-/* eslint-disable func-names, space-before-function-paren, no-var, prefer-rest-params, wrap-iife, max-len, one-var, one-var-declaration-per-line, quotes, prefer-template, newline-per-chained-call, comma-dangle, new-cap, no-else-return, consistent-return */
-/* global notes */
-
/* Developer beware! Do not add logic to showButton or hideButton
* that will force a reflow. Doing so will create a signficant performance
* bottleneck for pages with large diffs. For a comprehensive list of what
@@ -20,8 +17,10 @@ const DIFF_EXPANDED_CLASS = 'diff-expanded';
export default {
init($diffFile) {
- /* Caching is used only when the following members are *true*. This is because there are likely to be
- * differently configured versions of diffs in the same session. However if these values are true, they
+ /* Caching is used only when the following members are *true*.
+ * This is because there are likely to be
+ * differently configured versions of diffs in the same session.
+ * However if these values are true, they
* will be true in all cases */
if (!this.userCanCreateNote) {
diff --git a/app/assets/javascripts/gl_dropdown.js b/app/assets/javascripts/gl_dropdown.js
index e8d8fef8579..c4202f92443 100644
--- a/app/assets/javascripts/gl_dropdown.js
+++ b/app/assets/javascripts/gl_dropdown.js
@@ -1,6 +1,7 @@
/* eslint-disable func-names, no-underscore-dangle, space-before-function-paren, no-var, one-var, one-var-declaration-per-line, prefer-rest-params, max-len, vars-on-top, wrap-iife, no-unused-vars, quotes, no-shadow, no-cond-assign, prefer-arrow-callback, no-return-assign, no-else-return, camelcase, comma-dangle, no-lonely-if, guard-for-in, no-restricted-syntax, consistent-return, prefer-template, no-param-reassign, no-loop-func, no-mixed-operators */
/* global fuzzaldrinPlus */
import _ from 'underscore';
+import fuzzaldrinPlus from 'fuzzaldrin-plus';
import { isObject } from './lib/utils/type_utility';
var GitLabDropdown, GitLabDropdownFilter, GitLabDropdownRemote, GitLabDropdownInput;
diff --git a/app/assets/javascripts/group_avatar.js b/app/assets/javascripts/group_avatar.js
index f03b47b1c1d..2168ff3a8ba 100644
--- a/app/assets/javascripts/group_avatar.js
+++ b/app/assets/javascripts/group_avatar.js
@@ -1,19 +1,12 @@
-/* eslint-disable func-names, space-before-function-paren, wrap-iife, quotes, no-var, one-var, one-var-declaration-per-line, no-useless-escape, max-len */
-
-window.GroupAvatar = (function() {
- function GroupAvatar() {
- $('.js-choose-group-avatar-button').on("click", function() {
- var form;
- form = $(this).closest("form");
- return form.find(".js-group-avatar-input").click();
- });
- $('.js-group-avatar-input').on("change", function() {
- var filename, form;
- form = $(this).closest("form");
- filename = $(this).val().replace(/^.*[\\\/]/, '');
- return form.find(".js-avatar-filename").text(filename);
- });
- }
-
- return GroupAvatar;
-})();
+export default function groupAvatar() {
+ $('.js-choose-group-avatar-button').on('click', function onClickGroupAvatar() {
+ const form = $(this).closest('form');
+ return form.find('.js-group-avatar-input').click();
+ });
+ $('.js-group-avatar-input').on('change', function onChangeAvatarInput() {
+ const form = $(this).closest('form');
+ // eslint-disable-next-line no-useless-escape
+ const filename = $(this).val().replace(/^.*[\\\/]/, '');
+ return form.find('.js-avatar-filename').text(filename);
+ });
+}
diff --git a/app/assets/javascripts/group_label_subscription.js b/app/assets/javascripts/group_label_subscription.js
index 7dc9ce898e8..befaebb635e 100644
--- a/app/assets/javascripts/group_label_subscription.js
+++ b/app/assets/javascripts/group_label_subscription.js
@@ -1,6 +1,4 @@
-/* eslint-disable func-names, object-shorthand, comma-dangle, wrap-iife, space-before-function-paren, no-param-reassign, max-len */
-
-class GroupLabelSubscription {
+export default class GroupLabelSubscription {
constructor(container) {
const $container = $(container);
this.$dropdown = $container.find('.dropdown');
@@ -18,7 +16,7 @@ class GroupLabelSubscription {
$.ajax({
type: 'POST',
- url: url
+ url,
}).done(() => {
this.toggleSubscriptionButtons();
this.$unsubscribeButtons.removeAttr('data-url');
@@ -35,7 +33,7 @@ class GroupLabelSubscription {
$.ajax({
type: 'POST',
- url: url
+ url,
}).done(() => {
this.toggleSubscriptionButtons();
});
@@ -47,6 +45,3 @@ class GroupLabelSubscription {
this.$unsubscribeButtons.toggleClass('hidden');
}
}
-
-window.gl = window.gl || {};
-window.gl.GroupLabelSubscription = GroupLabelSubscription;
diff --git a/app/assets/javascripts/groups_select.js b/app/assets/javascripts/groups_select.js
index 90ca70289ab..a69a0bde17b 100644
--- a/app/assets/javascripts/groups_select.js
+++ b/app/assets/javascripts/groups_select.js
@@ -1,121 +1,86 @@
-/* eslint-disable func-names, space-before-function-paren, no-var, wrap-iife, one-var,
- camelcase, one-var-declaration-per-line, quotes, object-shorthand,
- prefer-arrow-callback, comma-dangle, consistent-return, yoda,
- prefer-rest-params, prefer-spread, no-unused-vars, prefer-template,
- promise/catch-or-return */
import Api from './api';
import { normalizeCRLFHeaders } from './lib/utils/common_utils';
-var slice = [].slice;
+export default function groupsSelect() {
+ // Needs to be accessible in rspec
+ window.GROUP_SELECT_PER_PAGE = 20;
+ $('.ajax-groups-select').each(function setAjaxGroupsSelect2() {
+ const $select = $(this);
+ const allAvailable = $select.data('all-available');
+ const skipGroups = $select.data('skip-groups') || [];
+ $select.select2({
+ placeholder: 'Search for a group',
+ multiple: $select.hasClass('multiselect'),
+ minimumInputLength: 0,
+ ajax: {
+ url: Api.buildUrl(Api.groupsPath),
+ dataType: 'json',
+ quietMillis: 250,
+ transport(params) {
+ return $.ajax(params)
+ .then((data, status, xhr) => {
+ const results = data || [];
-window.GroupsSelect = (function() {
- function GroupsSelect() {
- $('.ajax-groups-select').each((function(_this) {
- const self = _this;
-
- return function(i, select) {
- var all_available, skip_groups;
- const $select = $(select);
- all_available = $select.data('all-available');
- skip_groups = $select.data('skip-groups') || [];
-
- $select.select2({
- placeholder: "Search for a group",
- multiple: $select.hasClass('multiselect'),
- minimumInputLength: 0,
- ajax: {
- url: Api.buildUrl(Api.groupsPath),
- dataType: 'json',
- quietMillis: 250,
- transport: function (params) {
- $.ajax(params).then((data, status, xhr) => {
- const results = data || [];
-
- const headers = normalizeCRLFHeaders(xhr.getAllResponseHeaders());
- const currentPage = parseInt(headers['X-PAGE'], 10) || 0;
- const totalPages = parseInt(headers['X-TOTAL-PAGES'], 10) || 0;
- const more = currentPage < totalPages;
-
- return {
- results,
- pagination: {
- more,
- },
- };
- }).then(params.success).fail(params.error);
- },
- data: function (search, page) {
- return {
- search,
- page,
- per_page: GroupsSelect.PER_PAGE,
- all_available,
- };
- },
- results: function (data, page) {
- if (data.length) return { results: [] };
-
- const groups = data.length ? data : data.results || [];
- const more = data.pagination ? data.pagination.more : false;
- const results = groups.filter(group => skip_groups.indexOf(group.id) === -1);
+ const headers = normalizeCRLFHeaders(xhr.getAllResponseHeaders());
+ const currentPage = parseInt(headers['X-PAGE'], 10) || 0;
+ const totalPages = parseInt(headers['X-TOTAL-PAGES'], 10) || 0;
+ const more = currentPage < totalPages;
return {
results,
- page,
- more,
+ pagination: {
+ more,
+ },
};
- },
- },
- initSelection: function(element, callback) {
- var id;
- id = $(element).val();
- if (id !== "") {
- return Api.group(id, callback);
- }
- },
- formatResult: function() {
- var args;
- args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
- return self.formatResult.apply(self, args);
- },
- formatSelection: function() {
- var args;
- args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
- return self.formatSelection.apply(self, args);
- },
- dropdownCssClass: "ajax-groups-dropdown select2-infinite",
- // we do not want to escape markup since we are displaying html in results
- escapeMarkup: function(m) {
- return m;
- }
- });
-
- self.dropdown = document.querySelector('.select2-infinite .select2-results');
-
- $select.on('select2-loaded', self.forceOverflow.bind(self));
- };
- })(this));
- }
-
- GroupsSelect.prototype.formatResult = function(group) {
- var avatar;
- if (group.avatar_url) {
- avatar = group.avatar_url;
- } else {
- avatar = gon.default_avatar_url;
- }
- return "<div class='group-result'> <div class='group-name'>" + group.full_name + "</div> <div class='group-path'>" + group.full_path + "</div> </div>";
- };
-
- GroupsSelect.prototype.formatSelection = function(group) {
- return group.full_name;
- };
+ })
+ .then(params.success)
+ .fail(params.error);
+ },
+ data(search, page) {
+ return {
+ search,
+ page,
+ per_page: window.GROUP_SELECT_PER_PAGE,
+ all_available: allAvailable,
+ };
+ },
+ results(data, page) {
+ if (data.length) return { results: [] };
- GroupsSelect.prototype.forceOverflow = function (e) {
- this.dropdown.style.height = `${Math.floor(this.dropdown.scrollHeight)}px`;
- };
+ const groups = data.length ? data : data.results || [];
+ const more = data.pagination ? data.pagination.more : false;
+ const results = groups.filter(group => skipGroups.indexOf(group.id) === -1);
- GroupsSelect.PER_PAGE = 20;
+ return {
+ results,
+ page,
+ more,
+ };
+ },
+ },
+ // eslint-disable-next-line consistent-return
+ initSelection(element, callback) {
+ const id = $(element).val();
+ if (id !== '') {
+ return Api.group(id, callback);
+ }
+ },
+ formatResult(object) {
+ return `<div class='group-result'> <div class='group-name'>${object.full_name}</div> <div class='group-path'>${object.full_path}</div> </div>`;
+ },
+ formatSelection(object) {
+ return object.full_name;
+ },
+ dropdownCssClass: 'ajax-groups-dropdown select2-infinite',
+ // we do not want to escape markup since we are displaying html in results
+ escapeMarkup(m) {
+ return m;
+ },
+ });
- return GroupsSelect;
-})();
+ $select.on('select2-loaded', () => {
+ const dropdown = document.querySelector('.select2-infinite .select2-results');
+ dropdown.style.height = `${Math.floor(dropdown.scrollHeight)}px`;
+ });
+ });
+}
diff --git a/app/assets/javascripts/header.js b/app/assets/javascripts/header.js
index ea2e2205077..33a352e158a 100644
--- a/app/assets/javascripts/header.js
+++ b/app/assets/javascripts/header.js
@@ -7,10 +7,12 @@ import { highCountTrim } from '~/lib/utils/text_utility';
* @param {jQuery.Event} e
* @param {String} count
*/
-$(document).on('todo:toggle', (e, count) => {
- const parsedCount = parseInt(count, 10);
- const $todoPendingCount = $('.todos-count');
+export default function initTodoToggle() {
+ $(document).on('todo:toggle', (e, count) => {
+ const parsedCount = parseInt(count, 10);
+ const $todoPendingCount = $('.todos-count');
- $todoPendingCount.text(highCountTrim(parsedCount));
- $todoPendingCount.toggleClass('hidden', parsedCount === 0);
-});
+ $todoPendingCount.text(highCountTrim(parsedCount));
+ $todoPendingCount.toggleClass('hidden', parsedCount === 0);
+ });
+}
diff --git a/app/assets/javascripts/importer_status.js b/app/assets/javascripts/importer_status.js
index 5b4ca94ed30..1dc70872d92 100644
--- a/app/assets/javascripts/importer_status.js
+++ b/app/assets/javascripts/importer_status.js
@@ -1,83 +1,81 @@
-/* eslint-disable func-names, space-before-function-paren, wrap-iife, camelcase, no-var, one-var, one-var-declaration-per-line, prefer-template, quotes, object-shorthand, comma-dangle, no-unused-vars, prefer-arrow-callback, no-else-return, vars-on-top, no-new, max-len */
+class ImporterStatus {
+ constructor(jobsUrl, importUrl) {
+ this.jobsUrl = jobsUrl;
+ this.importUrl = importUrl;
+ this.initStatusPage();
+ this.setAutoUpdate();
+ }
-(function() {
- window.ImporterStatus = (function() {
- function ImporterStatus(jobs_url, import_url) {
- this.jobs_url = jobs_url;
- this.import_url = import_url;
- this.initStatusPage();
- this.setAutoUpdate();
- }
+ initStatusPage() {
+ $('.js-add-to-import')
+ .off('click')
+ .on('click', (event) => {
+ const $btn = $(event.currentTarget);
+ const $tr = $btn.closest('tr');
+ const $targetField = $tr.find('.import-target');
+ const $namespaceInput = $targetField.find('.js-select-namespace option:selected');
+ const id = $tr.attr('id').replace('repo_', '');
+ let targetNamespace;
+ let newName;
+ if ($namespaceInput.length > 0) {
+ targetNamespace = $namespaceInput[0].innerHTML;
+ newName = $targetField.find('#path').prop('value');
+ $targetField.empty().append(`${targetNamespace}/${newName}`);
+ }
+ $btn.disable().addClass('is-loading');
- ImporterStatus.prototype.initStatusPage = function() {
- $('.js-add-to-import').off('click').on('click', (function(_this) {
- return function(e) {
- var $btn, $namespace_input, $target_field, $tr, id, target_namespace, newName;
- $btn = $(e.currentTarget);
- $tr = $btn.closest('tr');
- $target_field = $tr.find('.import-target');
- $namespace_input = $target_field.find('.js-select-namespace option:selected');
- id = $tr.attr('id').replace('repo_', '');
- target_namespace = null;
- newName = null;
- if ($namespace_input.length > 0) {
- target_namespace = $namespace_input[0].innerHTML;
- newName = $target_field.find('#path').prop('value');
- $target_field.empty().append(target_namespace + "/" + newName);
- }
- $btn.disable().addClass('is-loading');
- return $.post(_this.import_url, {
- repo_id: id,
- target_namespace: target_namespace,
- new_name: newName
- }, {
- dataType: 'script'
- });
- };
- })(this));
- return $('.js-import-all').off('click').on('click', function(e) {
- var $btn;
- $btn = $(this);
+ return $.post(this.importUrl, {
+ repo_id: id,
+ target_namespace: targetNamespace,
+ new_name: newName,
+ }, {
+ dataType: 'script',
+ });
+ });
+
+ $('.js-import-all')
+ .off('click')
+ .on('click', function onClickImportAll() {
+ const $btn = $(this);
$btn.disable().addClass('is-loading');
- return $('.js-add-to-import').each(function() {
+ return $('.js-add-to-import').each(function triggerAddImport() {
return $(this).trigger('click');
});
});
- };
+ }
+
+ setAutoUpdate() {
+ return setInterval(() => $.get(this.jobsUrl, data => $.each(data, (i, job) => {
+ const jobItem = $(`#project_${job.id}`);
+ const statusField = jobItem.find('.job-status');
- ImporterStatus.prototype.setAutoUpdate = function() {
- return setInterval(((function(_this) {
- return function() {
- return $.get(_this.jobs_url, function(data) {
- return $.each(data, function(i, job) {
- var job_item, status_field;
- job_item = $("#project_" + job.id);
- status_field = job_item.find(".job-status");
- if (job.import_status === 'finished') {
- job_item.removeClass("active").addClass("success");
- return status_field.html('<span><i class="fa fa-check"></i> done</span>');
- } else if (job.import_status === 'scheduled') {
- return status_field.html("<i class='fa fa-spinner fa-spin'></i> scheduled");
- } else if (job.import_status === 'started') {
- return status_field.html("<i class='fa fa-spinner fa-spin'></i> started");
- } else {
- return status_field.html(job.import_status);
- }
- });
- });
- };
- })(this)), 4000);
- };
+ const spinner = '<i class="fa fa-spinner fa-spin"></i>';
- return ImporterStatus;
- })();
+ switch (job.import_status) {
+ case 'finished':
+ jobItem.removeClass('active').addClass('success');
+ statusField.html('<span><i class="fa fa-check"></i> done</span>');
+ break;
+ case 'scheduled':
+ statusField.html(`${spinner} scheduled`);
+ break;
+ case 'started':
+ statusField.html(`${spinner} started`);
+ break;
+ default:
+ statusField.html(job.import_status);
+ break;
+ }
+ })), 4000);
+ }
+}
- $(function() {
- if ($('.js-importer-status').length) {
- var jobsImportPath = $('.js-importer-status').data('jobs-import-path');
- var importPath = $('.js-importer-status').data('import-path');
+// eslint-disable-next-line consistent-return
+export default function initImporterStatus() {
+ const importerStatus = document.querySelector('.js-importer-status');
- new window.ImporterStatus(jobsImportPath, importPath);
- }
- });
-}).call(window);
+ if (importerStatus) {
+ const data = importerStatus.dataset;
+ return new ImporterStatus(data.jobsImportPath, data.importPath);
+ }
+}
diff --git a/app/assets/javascripts/init_changes_dropdown.js b/app/assets/javascripts/init_changes_dropdown.js
index f785ed29e6c..1bab7965c19 100644
--- a/app/assets/javascripts/init_changes_dropdown.js
+++ b/app/assets/javascripts/init_changes_dropdown.js
@@ -1,7 +1,7 @@
import stickyMonitor from './lib/utils/sticky';
-export default () => {
- stickyMonitor(document.querySelector('.js-diff-files-changed'));
+export default (stickyTop) => {
+ stickyMonitor(document.querySelector('.js-diff-files-changed'), stickyTop);
$('.js-diff-stats-dropdown').glDropdown({
filterable: true,
diff --git a/app/assets/javascripts/init_issuable_sidebar.js b/app/assets/javascripts/init_issuable_sidebar.js
index 32a1a269f9a..6f476f96f72 100644
--- a/app/assets/javascripts/init_issuable_sidebar.js
+++ b/app/assets/javascripts/init_issuable_sidebar.js
@@ -1,7 +1,7 @@
/* eslint-disable no-new */
/* global MilestoneSelect */
/* global LabelsSelect */
-/* global IssuableContext */
+import IssuableContext from './issuable_context';
/* global Sidebar */
import DueDateSelectors from './due_date_select';
diff --git a/app/assets/javascripts/init_legacy_filters.js b/app/assets/javascripts/init_legacy_filters.js
index 1211c2c802c..fcf424408f2 100644
--- a/app/assets/javascripts/init_legacy_filters.js
+++ b/app/assets/javascripts/init_legacy_filters.js
@@ -1,15 +1,15 @@
/* eslint-disable no-new */
/* global LabelsSelect */
/* global MilestoneSelect */
-/* global IssueStatusSelect */
/* global SubscriptionSelect */
import UsersSelect from './users_select';
+import issueStatusSelect from './issue_status_select';
export default () => {
new UsersSelect();
new LabelsSelect();
new MilestoneSelect();
- new IssueStatusSelect();
+ issueStatusSelect();
new SubscriptionSelect();
};
diff --git a/app/assets/javascripts/issuable_bulk_update_actions.js b/app/assets/javascripts/issuable_bulk_update_actions.js
index eb15949603f..b124fafec70 100644
--- a/app/assets/javascripts/issuable_bulk_update_actions.js
+++ b/app/assets/javascripts/issuable_bulk_update_actions.js
@@ -1,5 +1,4 @@
/* eslint-disable comma-dangle, quotes, consistent-return, func-names, array-callback-return, space-before-function-paren, prefer-arrow-callback, max-len, no-unused-expressions, no-sequences, no-underscore-dangle, no-unused-vars, no-param-reassign */
-/* global IssuableIndex */
import _ from 'underscore';
import Flash from './flash';
diff --git a/app/assets/javascripts/issuable_bulk_update_sidebar.js b/app/assets/javascripts/issuable_bulk_update_sidebar.js
index 0e8a0519928..4a15ec8b147 100644
--- a/app/assets/javascripts/issuable_bulk_update_sidebar.js
+++ b/app/assets/javascripts/issuable_bulk_update_sidebar.js
@@ -1,10 +1,13 @@
/* eslint-disable class-methods-use-this, no-new */
/* global LabelsSelect */
/* global MilestoneSelect */
-/* global IssueStatusSelect */
/* global SubscriptionSelect */
import IssuableBulkUpdateActions from './issuable_bulk_update_actions';
+import './milestone_select';
+import issueStatusSelect from './issue_status_select';
+import './subscription_select';
+import './labels_select';
const HIDDEN_CLASS = 'hidden';
const DISABLED_CONTENT_CLASS = 'disabled-content';
@@ -45,7 +48,7 @@ export default class IssuableBulkUpdateSidebar {
initDropdowns() {
new LabelsSelect();
new MilestoneSelect();
- new IssueStatusSelect();
+ issueStatusSelect();
new SubscriptionSelect();
}
diff --git a/app/assets/javascripts/issuable_context.js b/app/assets/javascripts/issuable_context.js
index 1d305f1eb2f..da99394ff90 100644
--- a/app/assets/javascripts/issuable_context.js
+++ b/app/assets/javascripts/issuable_context.js
@@ -1,33 +1,32 @@
-/* eslint-disable func-names, space-before-function-paren, wrap-iife, no-new, comma-dangle, quotes, prefer-arrow-callback, consistent-return, one-var, no-var, one-var-declaration-per-line, no-underscore-dangle, max-len */
import Cookies from 'js-cookie';
import bp from './breakpoints';
import UsersSelect from './users_select';
-const PARTICIPANTS_ROW_COUNT = 7;
+export default class IssuableContext {
+ constructor(currentUser) {
+ this.userSelect = new UsersSelect(currentUser);
-(function() {
- this.IssuableContext = (function() {
- function IssuableContext(currentUser) {
- this.initParticipants();
- new UsersSelect(currentUser);
- $('select.select2').select2({
- width: 'resolve',
- dropdownAutoWidth: true
- });
- $(".issuable-sidebar .inline-update").on("change", "select", function() {
- return $(this).submit();
- });
- $(".issuable-sidebar .inline-update").on("change", ".js-assignee", function() {
- return $(this).submit();
- });
- $(document).off('click', '.issuable-sidebar .dropdown-content a').on('click', '.issuable-sidebar .dropdown-content a', function(e) {
- return e.preventDefault();
- });
- $(document).off('click', '.edit-link').on('click', '.edit-link', function(e) {
- var $block, $selectbox;
+ $('select.select2').select2({
+ width: 'resolve',
+ dropdownAutoWidth: true,
+ });
+
+ $('.issuable-sidebar .inline-update').on('change', 'select', function onClickSelect() {
+ return $(this).submit();
+ });
+ $('.issuable-sidebar .inline-update').on('change', '.js-assignee', function onClickAssignee() {
+ return $(this).submit();
+ });
+ $(document)
+ .off('click', '.issuable-sidebar .dropdown-content a')
+ .on('click', '.issuable-sidebar .dropdown-content a', e => e.preventDefault());
+
+ $(document)
+ .off('click', '.edit-link')
+ .on('click', '.edit-link', function onClickEdit(e) {
e.preventDefault();
- $block = $(this).parents('.block');
- $selectbox = $block.find('.selectbox');
+ const $block = $(this).parents('.block');
+ const $selectbox = $block.find('.selectbox');
if ($selectbox.is(':visible')) {
$selectbox.hide();
$block.find('.value').show();
@@ -35,47 +34,18 @@ const PARTICIPANTS_ROW_COUNT = 7;
$selectbox.show();
$block.find('.value').hide();
}
- if ($selectbox.is(':visible')) {
- return setTimeout(function() {
- return $block.find('.dropdown-menu-toggle').trigger('click');
- }, 0);
- }
- });
- window.addEventListener('beforeunload', function() {
- // collapsed_gutter cookie hides the sidebar
- var bpBreakpoint = bp.getBreakpointSize();
- if (bpBreakpoint === 'xs' || bpBreakpoint === 'sm') {
- Cookies.set('collapsed_gutter', true);
- }
- });
- }
- IssuableContext.prototype.initParticipants = function() {
- $(document).on("click", ".js-participants-more", this.toggleHiddenParticipants);
- return $(".js-participants-author").each(function(i) {
- if (i >= PARTICIPANTS_ROW_COUNT) {
- return $(this).addClass("js-participants-hidden").hide();
+ if ($selectbox.is(':visible')) {
+ setTimeout(() => $block.find('.dropdown-menu-toggle').trigger('click'), 0);
}
});
- };
- IssuableContext.prototype.toggleHiddenParticipants = function(e) {
- var currentText, lessText, originalText;
- e.preventDefault();
- currentText = $(this).text().trim();
- lessText = $(this).data("less-text");
- originalText = $(this).data("original-text");
- if (currentText === originalText) {
- $(this).text(lessText);
-
- if (gl.lazyLoader) gl.lazyLoader.loadCheck();
- } else {
- $(this).text(originalText);
+ window.addEventListener('beforeunload', () => {
+ // collapsed_gutter cookie hides the sidebar
+ const bpBreakpoint = bp.getBreakpointSize();
+ if (bpBreakpoint === 'xs' || bpBreakpoint === 'sm') {
+ Cookies.set('collapsed_gutter', true);
}
-
- $(".js-participants-hidden").toggle();
- };
-
- return IssuableContext;
- })();
-}).call(window);
+ });
+ }
+}
diff --git a/app/assets/javascripts/issuable_form.js b/app/assets/javascripts/issuable_form.js
index cd2562bc6a9..57dcaa0e1ac 100644
--- a/app/assets/javascripts/issuable_form.js
+++ b/app/assets/javascripts/issuable_form.js
@@ -1,110 +1,107 @@
-/* eslint-disable func-names, space-before-function-paren, no-var, prefer-rest-params, wrap-iife, no-use-before-define, no-useless-escape, no-new, quotes, object-shorthand, no-unused-vars, comma-dangle, no-alert, consistent-return, no-else-return, prefer-template, one-var, one-var-declaration-per-line, curly, max-len */
+/* eslint-disable func-names, prefer-rest-params, wrap-iife, no-use-before-define, no-useless-escape, no-new, object-shorthand, no-unused-vars, comma-dangle, no-alert, consistent-return, no-else-return, prefer-template, one-var, one-var-declaration-per-line, curly, max-len */
/* global GitLab */
-/* global Autosave */
import Pikaday from 'pikaday';
+import Autosave from './autosave';
import UsersSelect from './users_select';
import GfmAutoComplete from './gfm_auto_complete';
import ZenMode from './zen_mode';
import { parsePikadayDate, pikadayToString } from './lib/utils/datefix';
-(function() {
- this.IssuableForm = (function() {
- IssuableForm.prototype.wipRegex = /^\s*(\[WIP\]\s*|WIP:\s*|WIP\s+)+\s*/i;
-
- function IssuableForm(form) {
- var $issuableDueDate, calendar;
- this.form = form;
- this.toggleWip = this.toggleWip.bind(this);
- this.renderWipExplanation = this.renderWipExplanation.bind(this);
- this.resetAutosave = this.resetAutosave.bind(this);
- this.handleSubmit = this.handleSubmit.bind(this);
- new GfmAutoComplete(gl.GfmAutoComplete && gl.GfmAutoComplete.dataSources).setup();
- new UsersSelect();
- new ZenMode();
- this.titleField = this.form.find("input[name*='[title]']");
- this.descriptionField = this.form.find("textarea[name*='[description]']");
- if (!(this.titleField.length && this.descriptionField.length)) {
- return;
- }
- this.initAutosave();
- this.form.on("submit", this.handleSubmit);
- this.form.on("click", ".btn-cancel", this.resetAutosave);
- this.initWip();
- $issuableDueDate = $('#issuable-due-date');
- if ($issuableDueDate.length) {
- calendar = new Pikaday({
- field: $issuableDueDate.get(0),
- theme: 'gitlab-theme animate-picker',
- format: 'yyyy-mm-dd',
- container: $issuableDueDate.parent().get(0),
- parse: dateString => parsePikadayDate(dateString),
- toString: date => pikadayToString(date),
- onSelect: function(dateText) {
- $issuableDueDate.val(calendar.toString(dateText));
- }
- });
- calendar.setDate(parsePikadayDate($issuableDueDate.val()));
- }
+export default class IssuableForm {
+ constructor(form) {
+ this.form = form;
+ this.toggleWip = this.toggleWip.bind(this);
+ this.renderWipExplanation = this.renderWipExplanation.bind(this);
+ this.resetAutosave = this.resetAutosave.bind(this);
+ this.handleSubmit = this.handleSubmit.bind(this);
+ this.wipRegex = /^\s*(\[WIP\]\s*|WIP:\s*|WIP\s+)+\s*/i;
+
+ new GfmAutoComplete(gl.GfmAutoComplete && gl.GfmAutoComplete.dataSources).setup();
+ new UsersSelect();
+ new ZenMode();
+
+ this.titleField = this.form.find('input[name*="[title]"]');
+ this.descriptionField = this.form.find('textarea[name*="[description]"]');
+ if (!(this.titleField.length && this.descriptionField.length)) {
+ return;
}
- IssuableForm.prototype.initAutosave = function() {
- new Autosave(this.titleField, [document.location.pathname, document.location.search, "title"]);
- return new Autosave(this.descriptionField, [document.location.pathname, document.location.search, "description"]);
- };
-
- IssuableForm.prototype.handleSubmit = function() {
- return this.resetAutosave();
- };
-
- IssuableForm.prototype.resetAutosave = function() {
- this.titleField.data("autosave").reset();
- return this.descriptionField.data("autosave").reset();
- };
-
- IssuableForm.prototype.initWip = function() {
- this.$wipExplanation = this.form.find(".js-wip-explanation");
- this.$noWipExplanation = this.form.find(".js-no-wip-explanation");
- if (!(this.$wipExplanation.length && this.$noWipExplanation.length)) {
- return;
- }
- this.form.on("click", ".js-toggle-wip", this.toggleWip);
- this.titleField.on("keyup blur", this.renderWipExplanation);
- return this.renderWipExplanation();
- };
-
- IssuableForm.prototype.workInProgress = function() {
- return this.wipRegex.test(this.titleField.val());
- };
-
- IssuableForm.prototype.renderWipExplanation = function() {
- if (this.workInProgress()) {
- this.$wipExplanation.show();
- return this.$noWipExplanation.hide();
- } else {
- this.$wipExplanation.hide();
- return this.$noWipExplanation.show();
- }
- };
-
- IssuableForm.prototype.toggleWip = function(event) {
- event.preventDefault();
- if (this.workInProgress()) {
- this.removeWip();
- } else {
- this.addWip();
- }
- return this.renderWipExplanation();
- };
-
- IssuableForm.prototype.removeWip = function() {
- return this.titleField.val(this.titleField.val().replace(this.wipRegex, ""));
- };
-
- IssuableForm.prototype.addWip = function() {
- return this.titleField.val("WIP: " + (this.titleField.val()));
- };
-
- return IssuableForm;
- })();
-}).call(window);
+ this.initAutosave();
+ this.form.on('submit', this.handleSubmit);
+ this.form.on('click', '.btn-cancel', this.resetAutosave);
+ this.initWip();
+
+ const $issuableDueDate = $('#issuable-due-date');
+
+ if ($issuableDueDate.length) {
+ const calendar = new Pikaday({
+ field: $issuableDueDate.get(0),
+ theme: 'gitlab-theme animate-picker',
+ format: 'yyyy-mm-dd',
+ container: $issuableDueDate.parent().get(0),
+ parse: dateString => parsePikadayDate(dateString),
+ toString: date => pikadayToString(date),
+ onSelect: dateText => $issuableDueDate.val(calendar.toString(dateText)),
+ });
+ calendar.setDate(parsePikadayDate($issuableDueDate.val()));
+ }
+ }
+
+ initAutosave() {
+ new Autosave(this.titleField, [document.location.pathname, document.location.search, 'title']);
+ return new Autosave(this.descriptionField, [document.location.pathname, document.location.search, 'description']);
+ }
+
+ handleSubmit() {
+ return this.resetAutosave();
+ }
+
+ resetAutosave() {
+ this.titleField.data('autosave').reset();
+ return this.descriptionField.data('autosave').reset();
+ }
+
+ initWip() {
+ this.$wipExplanation = this.form.find('.js-wip-explanation');
+ this.$noWipExplanation = this.form.find('.js-no-wip-explanation');
+ if (!(this.$wipExplanation.length && this.$noWipExplanation.length)) {
+ return;
+ }
+ this.form.on('click', '.js-toggle-wip', this.toggleWip);
+ this.titleField.on('keyup blur', this.renderWipExplanation);
+ return this.renderWipExplanation();
+ }
+
+ workInProgress() {
+ return this.wipRegex.test(this.titleField.val());
+ }
+
+ renderWipExplanation() {
+ if (this.workInProgress()) {
+ this.$wipExplanation.show();
+ return this.$noWipExplanation.hide();
+ } else {
+ this.$wipExplanation.hide();
+ return this.$noWipExplanation.show();
+ }
+ }
+
+ toggleWip(event) {
+ event.preventDefault();
+ if (this.workInProgress()) {
+ this.removeWip();
+ } else {
+ this.addWip();
+ }
+ return this.renderWipExplanation();
+ }
+
+ removeWip() {
+ return this.titleField.val(this.titleField.val().replace(this.wipRegex, ''));
+ }
+
+ addWip() {
+ this.titleField.val(`WIP: ${(this.titleField.val())}`);
+ }
+}
diff --git a/app/assets/javascripts/issuable_index.js b/app/assets/javascripts/issuable_index.js
index ece0220c927..0b123a11a3b 100644
--- a/app/assets/javascripts/issuable_index.js
+++ b/app/assets/javascripts/issuable_index.js
@@ -1,171 +1,42 @@
-/* eslint-disable no-param-reassign, func-names, no-var, camelcase, no-unused-vars, object-shorthand, space-before-function-paren, no-return-assign, comma-dangle, consistent-return, one-var, one-var-declaration-per-line, quotes, prefer-template, prefer-arrow-callback, wrap-iife, max-len */
-/* global IssuableIndex */
-import _ from 'underscore';
import IssuableBulkUpdateSidebar from './issuable_bulk_update_sidebar';
import IssuableBulkUpdateActions from './issuable_bulk_update_actions';
-((global) => {
- var issuable_created;
-
- issuable_created = false;
-
- global.IssuableIndex = {
- init: function(pagePrefix) {
- IssuableIndex.initTemplates();
- IssuableIndex.initSearch();
- IssuableIndex.initBulkUpdate(pagePrefix);
- IssuableIndex.initResetFilters();
- IssuableIndex.resetIncomingEmailToken();
- IssuableIndex.initLabelFilterRemove();
- },
- initTemplates: function() {
- return IssuableIndex.labelRow = _.template('<% _.each(labels, function(label){ %> <span class="label-row btn-group" role="group" aria-label="<%- label.title %>" style="color: <%- label.text_color %>;"> <a href="#" class="btn btn-transparent has-tooltip" style="background-color: <%- label.color %>;" title="<%- label.description %>" data-container="body"> <%- label.title %> </a> <button type="button" class="btn btn-transparent label-remove js-label-filter-remove" style="background-color: <%- label.color %>;" data-label="<%- label.title %>"> <i class="fa fa-times"></i> </button> </span> <% }); %>');
- },
- initSearch: function() {
- const $searchInput = $('#issuable_search');
-
- IssuableIndex.initSearchState($searchInput);
-
- // `immediate` param set to false debounces on the `trailing` edge, lets user finish typing
- const debouncedExecSearch = _.debounce(IssuableIndex.executeSearch, 1000, false);
-
- $searchInput.off('keyup').on('keyup', debouncedExecSearch);
-
- // ensures existing filters are preserved when manually submitted
- $('#issuable_search_form').on('submit', (e) => {
- e.preventDefault();
- debouncedExecSearch(e);
- });
- },
- initSearchState: function($searchInput) {
- const currentSearchVal = $searchInput.val();
-
- IssuableIndex.searchState = {
- elem: $searchInput,
- current: currentSearchVal
- };
-
- IssuableIndex.maybeFocusOnSearch();
- },
- accessSearchPristine: function(set) {
- // store reference to previous value to prevent search on non-mutating keyup
- const state = IssuableIndex.searchState;
- const currentSearchVal = state.elem.val();
-
- if (set) {
- state.current = currentSearchVal;
- } else {
- return state.current === currentSearchVal;
- }
- },
- maybeFocusOnSearch: function() {
- const currentSearchVal = IssuableIndex.searchState.current;
- if (currentSearchVal && currentSearchVal !== '') {
- const queryLength = currentSearchVal.length;
- const $searchInput = IssuableIndex.searchState.elem;
-
- /* The following ensures that the cursor is initially placed at
- * the end of search input when focus is applied. It accounts
- * for differences in browser implementations of `setSelectionRange`
- * and cursor placement for elements in focus.
- */
- $searchInput.focus();
- if ($searchInput.setSelectionRange) {
- $searchInput.setSelectionRange(queryLength, queryLength);
- } else {
- $searchInput.val(currentSearchVal);
- }
- }
- },
- executeSearch: function(e) {
- const $search = $('#issuable_search');
- const $searchName = $search.attr('name');
- const $searchValue = $search.val();
- const $filtersForm = $('.js-filter-form');
- const $input = $(`input[name='${$searchName}']`, $filtersForm);
- const isPristine = IssuableIndex.accessSearchPristine();
-
- if (isPristine) {
- return;
- }
-
- if (!$input.length) {
- $filtersForm.append(`<input type='hidden' name='${$searchName}' value='${_.escape($searchValue)}'/>`);
- } else {
- $input.val($searchValue);
- }
-
- IssuableIndex.filterResults($filtersForm);
- },
- initLabelFilterRemove: function() {
- return $(document).off('click', '.js-label-filter-remove').on('click', '.js-label-filter-remove', function(e) {
- var $button;
- $button = $(this);
- // Remove the label input box
- $('input[name="label_name[]"]').filter(function() {
- return this.value === $button.data('label');
- }).remove();
- // Submit the form to get new data
- IssuableIndex.filterResults($('.filter-form'));
- });
- },
- filterResults: (function(_this) {
- return function(form) {
- var formAction, formData, issuesUrl;
- formData = form.serializeArray();
- formData = formData.filter(function(data) {
- return data.value !== '';
- });
- formData = $.param(formData);
- formAction = form.attr('action');
- issuesUrl = formAction;
- issuesUrl += "" + (formAction.indexOf('?') === -1 ? '?' : '&');
- issuesUrl += formData;
- return gl.utils.visitUrl(issuesUrl);
- };
- })(this),
- initResetFilters: function() {
- $('.reset-filters').on('click', function(e) {
- e.preventDefault();
- const target = e.target;
- const $form = $(target).parents('.js-filter-form');
- const baseIssuesUrl = target.href;
-
- $form.attr('action', baseIssuesUrl);
- gl.utils.visitUrl(baseIssuesUrl);
+export default class IssuableIndex {
+ constructor(pagePrefix) {
+ this.initBulkUpdate(pagePrefix);
+ IssuableIndex.resetIncomingEmailToken();
+ }
+ initBulkUpdate(pagePrefix) {
+ const userCanBulkUpdate = $('.issues-bulk-update').length > 0;
+ const alreadyInitialized = !!this.bulkUpdateSidebar;
+
+ if (userCanBulkUpdate && !alreadyInitialized) {
+ IssuableBulkUpdateActions.init({
+ prefixId: pagePrefix,
});
- },
- initBulkUpdate: function(pagePrefix) {
- const userCanBulkUpdate = $('.issues-bulk-update').length > 0;
- const alreadyInitialized = !!this.bulkUpdateSidebar;
-
- if (userCanBulkUpdate && !alreadyInitialized) {
- IssuableBulkUpdateActions.init({
- prefixId: pagePrefix,
- });
-
- this.bulkUpdateSidebar = new IssuableBulkUpdateSidebar();
- }
- },
- resetIncomingEmailToken: function() {
- $('.incoming-email-token-reset').on('click', function(e) {
- e.preventDefault();
- $.ajax({
- type: 'PUT',
- url: $('.incoming-email-token-reset').attr('href'),
- dataType: 'json',
- success: function(response) {
- $('#issue_email').val(response.new_issue_address).focus();
- },
- beforeSend: function() {
- $('.incoming-email-token-reset').text('resetting...');
- },
- complete: function() {
- $('.incoming-email-token-reset').text('reset it');
- }
- });
- });
+ this.bulkUpdateSidebar = new IssuableBulkUpdateSidebar();
}
- };
-})(window);
+ }
+
+ static resetIncomingEmailToken() {
+ $('.incoming-email-token-reset').on('click', (e) => {
+ e.preventDefault();
+
+ $.ajax({
+ type: 'PUT',
+ url: $('.incoming-email-token-reset').attr('href'),
+ dataType: 'json',
+ success(response) {
+ $('#issue_email').val(response.new_issue_address).focus();
+ },
+ beforeSend() {
+ $('.incoming-email-token-reset').text('resetting...');
+ },
+ complete() {
+ $('.incoming-email-token-reset').text('reset it');
+ },
+ });
+ });
+ }
+}
diff --git a/app/assets/javascripts/issue.js b/app/assets/javascripts/issue.js
index 3fc29f9a661..acd5730cf3c 100644
--- a/app/assets/javascripts/issue.js
+++ b/app/assets/javascripts/issue.js
@@ -6,7 +6,7 @@ import TaskList from './task_list';
import CreateMergeRequestDropdown from './create_merge_request_dropdown';
import IssuablesHelper from './helpers/issuables_helper';
-class Issue {
+export default class Issue {
constructor() {
if ($('a.btn-close').length) {
this.taskList = new TaskList({
@@ -147,5 +147,3 @@ class Issue {
});
}
}
-
-export default Issue;
diff --git a/app/assets/javascripts/issue_status_select.js b/app/assets/javascripts/issue_status_select.js
index 56cb536dcde..03546f61d1f 100644
--- a/app/assets/javascripts/issue_status_select.js
+++ b/app/assets/javascripts/issue_status_select.js
@@ -1,34 +1,23 @@
-/* eslint-disable func-names, space-before-function-paren, wrap-iife, no-var, quotes, object-shorthand, no-unused-vars, no-shadow, one-var, one-var-declaration-per-line, comma-dangle, max-len */
-(function() {
- this.IssueStatusSelect = (function() {
- function IssueStatusSelect() {
- $('.js-issue-status').each(function(i, el) {
- var fieldName;
- fieldName = $(el).data("field-name");
- return $(el).glDropdown({
- selectable: true,
- fieldName: fieldName,
- toggleLabel: (function(_this) {
- return function(selected, el, instance) {
- var $item, label;
- label = 'Author';
- $item = instance.dropdown.find('.is-active');
- if ($item.length) {
- label = $item.text();
- }
- return label;
- };
- })(this),
- clicked: function(options) {
- return options.e.preventDefault();
- },
- id: function(obj, el) {
- return $(el).data("id");
- }
- });
- });
- }
-
- return IssueStatusSelect;
- })();
-}).call(window);
+export default function issueStatusSelect() {
+ $('.js-issue-status').each((i, el) => {
+ const fieldName = $(el).data('field-name');
+ return $(el).glDropdown({
+ selectable: true,
+ fieldName,
+ toggleLabel(selected, element, instance) {
+ let label = 'Author';
+ const $item = instance.dropdown.find('.is-active');
+ if ($item.length) {
+ label = $item.text();
+ }
+ return label;
+ },
+ clicked(options) {
+ return options.e.preventDefault();
+ },
+ id(obj, element) {
+ return $(element).data('id');
+ },
+ });
+ });
+}
diff --git a/app/assets/javascripts/layout_nav.js b/app/assets/javascripts/layout_nav.js
index d064a2c0024..a6f82b247e2 100644
--- a/app/assets/javascripts/layout_nav.js
+++ b/app/assets/javascripts/layout_nav.js
@@ -1,7 +1,7 @@
/* eslint-disable func-names, space-before-function-paren, no-var, prefer-arrow-callback, no-unused-vars, one-var, one-var-declaration-per-line, vars-on-top, max-len */
import _ from 'underscore';
import Cookies from 'js-cookie';
-import NewNavSidebar from './new_sidebar';
+import ContextualSidebar from './contextual_sidebar';
import initFlyOutNav from './fly_out_nav';
(function() {
@@ -51,8 +51,8 @@ import initFlyOutNav from './fly_out_nav';
});
$(() => {
- const newNavSidebar = new NewNavSidebar();
- newNavSidebar.bindEvents();
+ const contextualSidebar = new ContextualSidebar();
+ contextualSidebar.bindEvents();
initFlyOutNav();
});
diff --git a/app/assets/javascripts/lib/utils/sticky.js b/app/assets/javascripts/lib/utils/sticky.js
index 64db42701ce..098afcfa1b4 100644
--- a/app/assets/javascripts/lib/utils/sticky.js
+++ b/app/assets/javascripts/lib/utils/sticky.js
@@ -28,14 +28,10 @@ export const isSticky = (el, scrollY, stickyTop, insertPlaceholder) => {
}
};
-export default (el, insertPlaceholder = true) => {
+export default (el, stickyTop, insertPlaceholder = true) => {
if (!el) return;
- const computedStyle = window.getComputedStyle(el);
-
- if (!/sticky/.test(computedStyle.position)) return;
-
- const stickyTop = parseInt(computedStyle.top, 10);
+ if (typeof CSS === 'undefined' || !(CSS.supports('(position: -webkit-sticky) or (position: sticky)'))) return;
document.addEventListener('scroll', () => isSticky(el, window.scrollY, stickyTop, insertPlaceholder), {
passive: true,
diff --git a/app/assets/javascripts/main.js b/app/assets/javascripts/main.js
index 4cf07e99161..dae3a9e4f49 100644
--- a/app/assets/javascripts/main.js
+++ b/app/assets/javascripts/main.js
@@ -12,7 +12,6 @@ import svg4everybody from 'svg4everybody';
// libraries with import side-effects
import 'mousetrap';
import 'mousetrap/plugins/pause/mousetrap-pause';
-import 'vendor/fuzzaldrin-plus';
// expose common libraries as globals (TODO: remove these)
window.jQuery = jQuery;
@@ -41,7 +40,6 @@ import './behaviors/';
import './activities';
import './admin';
import './aside';
-import './autosave';
import loadAwardsHandler from './awards_handler';
import bp from './breakpoints';
import './commits';
@@ -50,23 +48,13 @@ import './compare_autocomplete';
import './confirm_danger_modal';
import './copy_as_gfm';
import './copy_to_clipboard';
-import './diff';
-import './files_comment_button';
import Flash, { removeFlashClickListener } from './flash';
import './gl_dropdown';
import './gl_field_error';
import './gl_field_errors';
import './gl_form';
-import './group_avatar';
-import './group_label_subscription';
-import './groups_select';
-import './header';
-import './importer_status';
-import './issuable_index';
-import './issuable_context';
-import './issuable_form';
-import './issue';
-import './issue_status_select';
+import initTodoToggle from './header';
+import initImporterStatus from './importer_status';
import './labels_select';
import './layout_nav';
import LazyLoader from './lazy_loader';
@@ -144,6 +132,8 @@ $(function () {
var fitSidebarForSize;
initBreadcrumbs();
+ initImporterStatus();
+ initTodoToggle();
// Set the default path for all cookies to GitLab's root directory
Cookies.defaults.path = gon.relative_url_root || '/';
diff --git a/app/assets/javascripts/merge_request_tabs.js b/app/assets/javascripts/merge_request_tabs.js
index df042c7baff..54c1b7a268e 100644
--- a/app/assets/javascripts/merge_request_tabs.js
+++ b/app/assets/javascripts/merge_request_tabs.js
@@ -11,8 +11,8 @@ import {
handleLocationHash,
isMetaClick,
} from './lib/utils/common_utils';
-
import initDiscussionTab from './image_diff/init_discussion_tab';
+import Diff from './diff';
/* eslint-disable max-len */
// MergeRequestTabs
@@ -67,6 +67,10 @@ import initDiscussionTab from './image_diff/init_discussion_tab';
class MergeRequestTabs {
constructor({ action, setUrl, stubLocation } = {}) {
+ const mergeRequestTabs = document.querySelector('.js-tabs-affix');
+ const navbar = document.querySelector('.navbar-gitlab');
+ const paddingTop = 16;
+
this.diffsLoaded = false;
this.pipelinesLoaded = false;
this.commitsLoaded = false;
@@ -76,6 +80,11 @@ import initDiscussionTab from './image_diff/init_discussion_tab';
this.setCurrentAction = this.setCurrentAction.bind(this);
this.tabShown = this.tabShown.bind(this);
this.showTab = this.showTab.bind(this);
+ this.stickyTop = navbar ? navbar.offsetHeight - paddingTop : 0;
+
+ if (mergeRequestTabs) {
+ this.stickyTop += mergeRequestTabs.offsetHeight;
+ }
if (stubLocation) {
location = stubLocation;
@@ -278,7 +287,7 @@ import initDiscussionTab from './image_diff/init_discussion_tab';
const $container = $('#diffs');
$container.html(data.html);
- initChangesDropdown();
+ initChangesDropdown(this.stickyTop);
if (typeof gl.diffNotesCompileComponents !== 'undefined') {
gl.diffNotesCompileComponents();
@@ -292,7 +301,7 @@ import initDiscussionTab from './image_diff/init_discussion_tab';
}
this.diffsLoaded = true;
- new gl.Diff();
+ new Diff();
this.scrollToElement('#diffs');
$('.diff-file').each((i, el) => {
diff --git a/app/assets/javascripts/notes.js b/app/assets/javascripts/notes.js
index 9c008da1a5d..705bec23b53 100644
--- a/app/assets/javascripts/notes.js
+++ b/app/assets/javascripts/notes.js
@@ -5,14 +5,14 @@ default-case, prefer-template, consistent-return, no-alert, no-return-assign,
no-param-reassign, prefer-arrow-callback, no-else-return, comma-dangle, no-new,
brace-style, no-lonely-if, vars-on-top, no-unused-vars, no-sequences, no-shadow,
newline-per-chained-call, no-useless-escape, class-methods-use-this */
-/* global Autosave */
+
/* global ResolveService */
/* global mrRefreshWidgetUrl */
import $ from 'jquery';
import _ from 'underscore';
import Cookies from 'js-cookie';
-import autosize from 'vendor/autosize';
+import Autosize from 'autosize';
import 'vendor/jquery.caret'; // required by jquery.atwho
import 'vendor/jquery.atwho';
import AjaxCache from '~/lib/utils/ajax_cache';
@@ -20,12 +20,12 @@ import Flash from './flash';
import CommentTypeToggle from './comment_type_toggle';
import GLForm from './gl_form';
import loadAwardsHandler from './awards_handler';
-import './autosave';
+import Autosave from './autosave';
import TaskList from './task_list';
import { ajaxPost, isInViewport, getPagePath, scrollToElement, isMetaKey } from './lib/utils/common_utils';
import imageDiffHelper from './image_diff/helpers/index';
-window.autosize = autosize;
+window.autosize = Autosize;
function normalizeNewlines(str) {
return str.replace(/\r\n/g, '\n');
@@ -1280,10 +1280,12 @@ export default class Notes {
* Get data from Form attributes to use for saving/submitting comment.
*/
getFormData($form) {
+ const content = $form.find('.js-note-text').val();
return {
formData: $form.serialize(),
- formContent: _.escape($form.find('.js-note-text').val()),
+ formContent: _.escape(content),
formAction: $form.attr('action'),
+ formContentOriginal: content,
};
}
@@ -1415,7 +1417,7 @@ export default class Notes {
const isMainForm = $form.hasClass('js-main-target-form');
const isDiscussionForm = $form.hasClass('js-discussion-note-form');
const isDiscussionResolve = $submitBtn.hasClass('js-comment-resolve-button');
- const { formData, formContent, formAction } = this.getFormData($form);
+ const { formData, formContent, formAction, formContentOriginal } = this.getFormData($form);
let noteUniqueId;
let systemNoteUniqueId;
let hasQuickActions = false;
@@ -1574,7 +1576,7 @@ export default class Notes {
$form = $notesContainer.parent().find('form');
}
- $form.find('.js-note-text').val(formContent);
+ $form.find('.js-note-text').val(formContentOriginal);
this.reenableTargetFormSubmitButton(e);
this.addNoteError($form);
});
diff --git a/app/assets/javascripts/notes/components/issue_comment_form.vue b/app/assets/javascripts/notes/components/issue_comment_form.vue
index 2ce52e4538a..db8f85759b2 100644
--- a/app/assets/javascripts/notes/components/issue_comment_form.vue
+++ b/app/assets/javascripts/notes/components/issue_comment_form.vue
@@ -1,10 +1,9 @@
<script>
- /* global Autosave */
import { mapActions, mapGetters } from 'vuex';
import _ from 'underscore';
- import autosize from 'vendor/autosize';
+ import Autosize from 'autosize';
import Flash from '../../flash';
- import '../../autosave';
+ import Autosave from '../../autosave';
import TaskList from '../../task_list';
import * as constants from '../constants';
import eventHub from '../event_hub';
@@ -220,7 +219,7 @@
},
resizeTextarea() {
this.$nextTick(() => {
- autosize.update(this.$refs.textarea);
+ Autosize.update(this.$refs.textarea);
});
},
},
diff --git a/app/assets/javascripts/notes/components/issue_discussion.vue b/app/assets/javascripts/notes/components/issue_discussion.vue
index baf43190d9e..0f13221b81e 100644
--- a/app/assets/javascripts/notes/components/issue_discussion.vue
+++ b/app/assets/javascripts/notes/components/issue_discussion.vue
@@ -9,8 +9,8 @@
import issueNoteSignedOutWidget from './issue_note_signed_out_widget.vue';
import issueNoteEditedText from './issue_note_edited_text.vue';
import issueNoteForm from './issue_note_form.vue';
- import placeholderNote from './issue_placeholder_note.vue';
- import placeholderSystemNote from './issue_placeholder_system_note.vue';
+ import placeholderNote from '../../vue_shared/components/notes/placeholder_note.vue';
+ import placeholderSystemNote from '../../vue_shared/components/notes/placeholder_system_note.vue';
import autosave from '../mixins/autosave';
export default {
diff --git a/app/assets/javascripts/notes/components/issue_notes_app.vue b/app/assets/javascripts/notes/components/issue_notes_app.vue
index aecd1f957e5..5c9119644e3 100644
--- a/app/assets/javascripts/notes/components/issue_notes_app.vue
+++ b/app/assets/javascripts/notes/components/issue_notes_app.vue
@@ -5,10 +5,10 @@
import * as constants from '../constants';
import issueNote from './issue_note.vue';
import issueDiscussion from './issue_discussion.vue';
- import issueSystemNote from './issue_system_note.vue';
+ import systemNote from '../../vue_shared/components/notes/system_note.vue';
import issueCommentForm from './issue_comment_form.vue';
- import placeholderNote from './issue_placeholder_note.vue';
- import placeholderSystemNote from './issue_placeholder_system_note.vue';
+ import placeholderNote from '../../vue_shared/components/notes/placeholder_note.vue';
+ import placeholderSystemNote from '../../vue_shared/components/notes/placeholder_system_note.vue';
import loadingIcon from '../../vue_shared/components/loading_icon.vue';
export default {
@@ -37,7 +37,7 @@
components: {
issueNote,
issueDiscussion,
- issueSystemNote,
+ systemNote,
issueCommentForm,
loadingIcon,
placeholderNote,
@@ -68,7 +68,7 @@
}
return placeholderNote;
} else if (note.individual_note) {
- return note.notes[0].system ? issueSystemNote : issueNote;
+ return note.notes[0].system ? systemNote : issueNote;
}
return issueDiscussion;
diff --git a/app/assets/javascripts/notes/mixins/autosave.js b/app/assets/javascripts/notes/mixins/autosave.js
index 5843b97f225..a008171beda 100644
--- a/app/assets/javascripts/notes/mixins/autosave.js
+++ b/app/assets/javascripts/notes/mixins/autosave.js
@@ -1,5 +1,4 @@
-/* globals Autosave */
-import '../../autosave';
+import Autosave from '../../autosave';
export default {
methods: {
diff --git a/app/assets/javascripts/pipelines/components/pipelines.vue b/app/assets/javascripts/pipelines/components/pipelines.vue
index 085bd20cefe..3da60e88474 100644
--- a/app/assets/javascripts/pipelines/components/pipelines.vue
+++ b/app/assets/javascripts/pipelines/components/pipelines.vue
@@ -12,6 +12,15 @@
type: Object,
required: true,
},
+ // Can be rendered in 3 different places, with some visual differences
+ // Accepts root | child
+ // `root` -> main view
+ // `child` -> rendered inside MR or Commit View
+ viewType: {
+ type: String,
+ required: false,
+ default: 'root',
+ },
},
components: {
tablePagination,
@@ -187,7 +196,7 @@
:empty-state-svg-path="emptyStateSvgPath"
/>
- <error-state
+ <error-state
v-if="shouldRenderErrorState"
:error-state-svg-path="errorStateSvgPath"
/>
@@ -206,6 +215,7 @@
:pipelines="state.pipelines"
:update-graph-dropdown="updateGraphDropdown"
:auto-devops-help-path="autoDevopsPath"
+ :view-type="viewType"
/>
</div>
diff --git a/app/assets/javascripts/pipelines/components/pipelines_table.vue b/app/assets/javascripts/pipelines/components/pipelines_table.vue
index 7aa0c0e8a7f..16a705cbaff 100644
--- a/app/assets/javascripts/pipelines/components/pipelines_table.vue
+++ b/app/assets/javascripts/pipelines/components/pipelines_table.vue
@@ -21,6 +21,10 @@
type: String,
required: true,
},
+ viewType: {
+ type: String,
+ required: true,
+ },
},
components: {
pipelinesTableRowComponent,
@@ -59,6 +63,7 @@
:pipeline="model"
:update-graph-dropdown="updateGraphDropdown"
:auto-devops-help-path="autoDevopsHelpPath"
+ :view-type="viewType"
/>
</div>
</template>
diff --git a/app/assets/javascripts/pipelines/components/pipelines_table_row.vue b/app/assets/javascripts/pipelines/components/pipelines_table_row.vue
index 5b9bb6c3750..33fbce993b2 100644
--- a/app/assets/javascripts/pipelines/components/pipelines_table_row.vue
+++ b/app/assets/javascripts/pipelines/components/pipelines_table_row.vue
@@ -29,6 +29,10 @@ export default {
type: String,
required: true,
},
+ viewType: {
+ type: String,
+ required: true,
+ },
},
components: {
asyncButtonComponent,
@@ -203,9 +207,13 @@ export default {
displayPipelineActions() {
return this.pipeline.flags.retryable ||
- this.pipeline.flags.cancelable ||
- this.pipeline.details.manual_actions.length ||
- this.pipeline.details.artifacts.length;
+ this.pipeline.flags.cancelable ||
+ this.pipeline.details.manual_actions.length ||
+ this.pipeline.details.artifacts.length;
+ },
+
+ isChildView() {
+ return this.viewType === 'child';
},
},
};
@@ -218,7 +226,10 @@ export default {
Status
</div>
<div class="table-mobile-content">
- <ci-badge :status="pipelineStatus"/>
+ <ci-badge
+ :status="pipelineStatus"
+ :show-text="!isChildView"
+ />
</div>
</div>
@@ -240,7 +251,9 @@ export default {
:commit-url="commitUrl"
:short-sha="commitShortSha"
:title="commitTitle"
- :author="commitAuthor"/>
+ :author="commitAuthor"
+ :show-branch="!isChildView"
+ />
</div>
</div>
diff --git a/app/assets/javascripts/project_find_file.js b/app/assets/javascripts/project_find_file.js
index 11f9754780d..19682b20a4a 100644
--- a/app/assets/javascripts/project_find_file.js
+++ b/app/assets/javascripts/project_find_file.js
@@ -1,5 +1,6 @@
/* eslint-disable func-names, space-before-function-paren, no-var, prefer-rest-params, wrap-iife, quotes, consistent-return, one-var, one-var-declaration-per-line, no-cond-assign, max-len, object-shorthand, no-param-reassign, comma-dangle, prefer-template, no-unused-vars, no-return-assign */
-/* global fuzzaldrinPlus */
+
+import fuzzaldrinPlus from 'fuzzaldrin-plus';
(function() {
this.ProjectFindFile = (function() {
diff --git a/app/assets/javascripts/project_select.js b/app/assets/javascripts/project_select.js
index fb01390f91c..bffc85e6315 100644
--- a/app/assets/javascripts/project_select.js
+++ b/app/assets/javascripts/project_select.js
@@ -2,13 +2,15 @@
import Api from './api';
import ProjectSelectComboButton from './project_select_combo_button';
-(function() {
- this.ProjectSelect = (function() {
+(function () {
+ this.ProjectSelect = (function () {
function ProjectSelect() {
$('.ajax-project-select').each(function(i, select) {
var placeholder;
+ const simpleFilter = $(select).data('simple-filter') || false;
this.groupId = $(select).data('group-id');
this.includeGroups = $(select).data('include-groups');
+ this.allProjects = $(select).data('all-projects') || false;
this.orderBy = $(select).data('order-by') || 'id';
this.withIssuesEnabled = $(select).data('with-issues-enabled');
this.withMergeRequestsEnabled = $(select).data('with-merge-requests-enabled');
@@ -21,10 +23,10 @@ import ProjectSelectComboButton from './project_select_combo_button';
$(select).select2({
placeholder: placeholder,
minimumInputLength: 0,
- query: (function(_this) {
- return function(query) {
+ query: (function (_this) {
+ return function (query) {
var finalCallback, projectsCallback;
- finalCallback = function(projects) {
+ finalCallback = function (projects) {
var data;
data = {
results: projects
@@ -32,9 +34,9 @@ import ProjectSelectComboButton from './project_select_combo_button';
return query.callback(data);
};
if (_this.includeGroups) {
- projectsCallback = function(projects) {
+ projectsCallback = function (projects) {
var groupsCallback;
- groupsCallback = function(groups) {
+ groupsCallback = function (groups) {
var data;
data = groups.concat(projects);
return finalCallback(data);
@@ -50,23 +52,25 @@ import ProjectSelectComboButton from './project_select_combo_button';
return Api.projects(query.term, {
order_by: _this.orderBy,
with_issues_enabled: _this.withIssuesEnabled,
- with_merge_requests_enabled: _this.withMergeRequestsEnabled
+ with_merge_requests_enabled: _this.withMergeRequestsEnabled,
+ membership: !_this.allProjects,
}, projectsCallback);
}
};
})(this),
id: function(project) {
+ if (simpleFilter) return project.id;
return JSON.stringify({
name: project.name,
url: project.web_url,
});
},
- text: function(project) {
+ text: function (project) {
return project.name_with_namespace || project.name;
},
dropdownCssClass: "ajax-project-dropdown"
});
-
+ if (simpleFilter) return select;
return new ProjectSelectComboButton(select);
});
}
diff --git a/app/assets/javascripts/registry/stores/actions.js b/app/assets/javascripts/registry/stores/actions.js
index 34ed40b8b65..795b39bb3dc 100644
--- a/app/assets/javascripts/registry/stores/actions.js
+++ b/app/assets/javascripts/registry/stores/actions.js
@@ -29,11 +29,9 @@ export const fetchList = ({ commit }, { repo, page }) => {
});
};
-export const deleteRepo = ({ commit }, repo) => Vue.http.delete(repo.destroyPath)
- .then(res => res.json());
+export const deleteRepo = ({ commit }, repo) => Vue.http.delete(repo.destroyPath);
-export const deleteRegistry = ({ commit }, image) => Vue.http.delete(image.destroyPath)
- .then(res => res.json());
+export const deleteRegistry = ({ commit }, image) => Vue.http.delete(image.destroyPath);
export const setMainEndpoint = ({ commit }, data) => commit(types.SET_MAIN_ENDPOINT, data);
export const toggleLoading = ({ commit }) => commit(types.TOGGLE_MAIN_LOADING);
diff --git a/app/assets/javascripts/repo/components/new_branch_form.vue b/app/assets/javascripts/repo/components/new_branch_form.vue
new file mode 100644
index 00000000000..ba7090e4a9d
--- /dev/null
+++ b/app/assets/javascripts/repo/components/new_branch_form.vue
@@ -0,0 +1,108 @@
+<script>
+ import { mapState, mapActions } from 'vuex';
+ import flash, { hideFlash } from '../../flash';
+ import loadingIcon from '../../vue_shared/components/loading_icon.vue';
+
+ export default {
+ components: {
+ loadingIcon,
+ },
+ data() {
+ return {
+ branchName: '',
+ loading: false,
+ };
+ },
+ computed: {
+ ...mapState([
+ 'currentBranch',
+ ]),
+ btnDisabled() {
+ return this.loading || this.branchName === '';
+ },
+ },
+ methods: {
+ ...mapActions([
+ 'createNewBranch',
+ ]),
+ toggleDropdown() {
+ this.$dropdown.dropdown('toggle');
+ },
+ submitNewBranch() {
+ // need to query as the element is appended outside of Vue
+ const flashEl = this.$refs.flashContainer.querySelector('.flash-alert');
+
+ this.loading = true;
+
+ if (flashEl) {
+ hideFlash(flashEl, false);
+ }
+
+ this.createNewBranch(this.branchName)
+ .then(() => {
+ this.loading = false;
+ this.branchName = '';
+
+ if (this.dropdownText) {
+ this.dropdownText.textContent = this.currentBranch;
+ }
+
+ this.toggleDropdown();
+ })
+ .catch(res => res.json().then((data) => {
+ this.loading = false;
+ flash(data.message, 'alert', this.$el);
+ }));
+ },
+ },
+ created() {
+ // Dropdown is outside of Vue instance & is controlled by Bootstrap
+ this.$dropdown = $('.git-revision-dropdown');
+
+ // text element is outside Vue app
+ this.dropdownText = document.querySelector('.project-refs-form .dropdown-toggle-text');
+ },
+ };
+</script>
+
+<template>
+ <div>
+ <div
+ class="flash-container"
+ ref="flashContainer"
+ >
+ </div>
+ <p>
+ Create from:
+ <code>{{ currentBranch }}</code>
+ </p>
+ <input
+ class="form-control js-new-branch-name"
+ type="text"
+ placeholder="Name new branch"
+ v-model="branchName"
+ @keyup.enter.stop.prevent="submitNewBranch"
+ />
+ <div class="prepend-top-default clearfix">
+ <button
+ type="button"
+ class="btn btn-primary pull-left"
+ :disabled="btnDisabled"
+ @click.stop.prevent="submitNewBranch"
+ >
+ <loading-icon
+ v-if="loading"
+ :inline="true"
+ />
+ <span>Create</span>
+ </button>
+ <button
+ type="button"
+ class="btn btn-default pull-right"
+ @click.stop.prevent="toggleDropdown"
+ >
+ Cancel
+ </button>
+ </div>
+ </div>
+</template>
diff --git a/app/assets/javascripts/repo/components/new_dropdown/index.vue b/app/assets/javascripts/repo/components/new_dropdown/index.vue
new file mode 100644
index 00000000000..a5ee4f71281
--- /dev/null
+++ b/app/assets/javascripts/repo/components/new_dropdown/index.vue
@@ -0,0 +1,84 @@
+<script>
+ import { mapState } from 'vuex';
+ import newModal from './modal.vue';
+ import upload from './upload.vue';
+
+ export default {
+ components: {
+ newModal,
+ upload,
+ },
+ data() {
+ return {
+ openModal: false,
+ modalType: '',
+ };
+ },
+ computed: {
+ ...mapState([
+ 'path',
+ ]),
+ },
+ methods: {
+ createNewItem(type) {
+ this.modalType = type;
+ this.toggleModalOpen();
+ },
+ toggleModalOpen() {
+ this.openModal = !this.openModal;
+ },
+ },
+ };
+</script>
+
+<template>
+ <div>
+ <ul class="breadcrumb repo-breadcrumb">
+ <li class="dropdown">
+ <button
+ type="button"
+ class="btn btn-default dropdown-toggle add-to-tree"
+ data-toggle="dropdown"
+ aria-label="Create new file or directory"
+ >
+ <i
+ class="fa fa-plus"
+ aria-hidden="true"
+ >
+ </i>
+ </button>
+ <ul class="dropdown-menu">
+ <li>
+ <a
+ href="#"
+ role="button"
+ @click.prevent="createNewItem('blob')"
+ >
+ {{ __('New file') }}
+ </a>
+ </li>
+ <li>
+ <upload
+ :path="path"
+ />
+ </li>
+ <li>
+ <a
+ href="#"
+ role="button"
+ @click.prevent="createNewItem('tree')"
+ >
+ {{ __('New directory') }}
+ </a>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ <new-modal
+ v-if="openModal"
+ :type="modalType"
+ :path="path"
+ @toggle="toggleModalOpen"
+ />
+ </div>
+</template>
diff --git a/app/assets/javascripts/repo/components/new_dropdown/modal.vue b/app/assets/javascripts/repo/components/new_dropdown/modal.vue
new file mode 100644
index 00000000000..ac1f613bb71
--- /dev/null
+++ b/app/assets/javascripts/repo/components/new_dropdown/modal.vue
@@ -0,0 +1,98 @@
+<script>
+ import { mapActions } from 'vuex';
+ import { __ } from '../../../locale';
+ import popupDialog from '../../../vue_shared/components/popup_dialog.vue';
+
+ export default {
+ props: {
+ type: {
+ type: String,
+ required: true,
+ },
+ path: {
+ type: String,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ entryName: this.path !== '' ? `${this.path}/` : '',
+ };
+ },
+ components: {
+ popupDialog,
+ },
+ methods: {
+ ...mapActions([
+ 'createTempEntry',
+ ]),
+ createEntryInStore() {
+ this.createTempEntry({
+ name: this.entryName.replace(new RegExp(`^${this.path}/`), ''),
+ type: this.type,
+ });
+
+ this.toggleModalOpen();
+ },
+ toggleModalOpen() {
+ this.$emit('toggle');
+ },
+ },
+ computed: {
+ modalTitle() {
+ if (this.type === 'tree') {
+ return __('Create new directory');
+ }
+
+ return __('Create new file');
+ },
+ buttonLabel() {
+ if (this.type === 'tree') {
+ return __('Create directory');
+ }
+
+ return __('Create file');
+ },
+ formLabelName() {
+ if (this.type === 'tree') {
+ return __('Directory name');
+ }
+
+ return __('File name');
+ },
+ },
+ mounted() {
+ this.$refs.fieldName.focus();
+ },
+ };
+</script>
+
+<template>
+ <popup-dialog
+ :title="modalTitle"
+ :primary-button-label="buttonLabel"
+ kind="success"
+ @toggle="toggleModalOpen"
+ @submit="createEntryInStore"
+ >
+ <form
+ class="form-horizontal"
+ slot="body"
+ @submit.prevent="createEntryInStore"
+ >
+ <fieldset class="form-group append-bottom-0">
+ <label class="label-light col-sm-3">
+ {{ formLabelName }}
+ </label>
+ <div class="col-sm-9">
+ <input
+ type="text"
+ class="form-control"
+ v-model="entryName"
+ ref="fieldName"
+ />
+ </div>
+ </fieldset>
+ </form>
+ </popup-dialog>
+</template>
diff --git a/app/assets/javascripts/repo/components/new_dropdown/upload.vue b/app/assets/javascripts/repo/components/new_dropdown/upload.vue
new file mode 100644
index 00000000000..14ad32f4ae0
--- /dev/null
+++ b/app/assets/javascripts/repo/components/new_dropdown/upload.vue
@@ -0,0 +1,68 @@
+<script>
+ import { mapActions } from 'vuex';
+
+ export default {
+ props: {
+ path: {
+ type: String,
+ required: true,
+ },
+ },
+ methods: {
+ ...mapActions([
+ 'createTempEntry',
+ ]),
+ createFile(target, file, isText) {
+ const { name } = file;
+ let { result } = target;
+
+ if (!isText) {
+ result = result.split('base64,')[1];
+ }
+
+ this.createTempEntry({
+ name,
+ type: 'blob',
+ content: result,
+ base64: !isText,
+ });
+ },
+ readFile(file) {
+ const reader = new FileReader();
+ const isText = file.type.match(/text.*/) !== null;
+
+ reader.addEventListener('load', e => this.createFile(e.target, file, isText), { once: true });
+
+ if (isText) {
+ reader.readAsText(file);
+ } else {
+ reader.readAsDataURL(file);
+ }
+ },
+ openFile() {
+ Array.from(this.$refs.fileUpload.files).forEach(file => this.readFile(file));
+ },
+ },
+ mounted() {
+ this.$refs.fileUpload.addEventListener('change', this.openFile);
+ },
+ beforeDestroy() {
+ this.$refs.fileUpload.removeEventListener('change', this.openFile);
+ },
+ };
+</script>
+
+<template>
+ <label
+ role="button"
+ class="menu-item"
+ >
+ {{ __('Upload file') }}
+ <input
+ id="file-upload"
+ type="file"
+ class="hidden"
+ ref="fileUpload"
+ />
+ </label>
+</template>
diff --git a/app/assets/javascripts/repo/components/repo.vue b/app/assets/javascripts/repo/components/repo.vue
index 0a89a9f16cb..98117802016 100644
--- a/app/assets/javascripts/repo/components/repo.vue
+++ b/app/assets/javascripts/repo/components/repo.vue
@@ -1,72 +1,59 @@
<script>
+import { mapState, mapGetters } from 'vuex';
import RepoSidebar from './repo_sidebar.vue';
import RepoCommitSection from './repo_commit_section.vue';
import RepoTabs from './repo_tabs.vue';
import RepoFileButtons from './repo_file_buttons.vue';
import RepoPreview from './repo_preview.vue';
-import RepoMixin from '../mixins/repo_mixin';
-import PopupDialog from '../../vue_shared/components/popup_dialog.vue';
-import Store from '../stores/repo_store';
-import Helper from '../helpers/repo_helper';
-import MonacoLoaderHelper from '../helpers/monaco_loader_helper';
+import repoEditor from './repo_editor.vue';
export default {
- data() {
- return Store;
+ computed: {
+ ...mapState([
+ 'currentBlobView',
+ ]),
+ ...mapGetters([
+ 'isCollapsed',
+ 'changedFiles',
+ ]),
},
- mixins: [RepoMixin],
components: {
RepoSidebar,
RepoTabs,
RepoFileButtons,
- 'repo-editor': MonacoLoaderHelper.repoEditorLoader,
+ repoEditor,
RepoCommitSection,
- PopupDialog,
RepoPreview,
},
-
mounted() {
- Helper.getContent().catch(Helper.loadingError);
- },
-
- methods: {
- toggleDialogOpen(toggle) {
- this.dialog.open = toggle;
- },
-
- dialogSubmitted(status) {
- this.toggleDialogOpen(false);
- this.dialog.status = status;
- },
+ const returnValue = 'Are you sure you want to lose unsaved changes?';
+ window.onbeforeunload = (e) => {
+ if (!this.changedFiles.length) return undefined;
- toggleBlobView: Store.toggleBlobView,
+ Object.assign(e, {
+ returnValue,
+ });
+ return returnValue;
+ };
},
};
</script>
<template>
<div class="repository-view">
- <div class="tree-content-holder" :class="{'tree-content-holder-mini' : isMini}">
+ <div class="tree-content-holder" :class="{'tree-content-holder-mini' : isCollapsed}">
<repo-sidebar/>
- <div v-if="isMini"
- class="panel-right"
- :class="{'edit-mode': editMode}">
+ <div
+ v-if="isCollapsed"
+ class="panel-right"
+ >
<repo-tabs/>
<component
:is="currentBlobView"
- class="blob-viewer-container"/>
+ />
<repo-file-buttons/>
</div>
</div>
- <repo-commit-section/>
- <popup-dialog
- v-show="dialog.open"
- :primary-button-label="__('Discard changes')"
- kind="warning"
- :title="__('Are you sure?')"
- :text="__('Are you sure you want to discard your changes?')"
- @toggle="toggleDialogOpen"
- @submit="dialogSubmitted"
- />
+ <repo-commit-section v-if="changedFiles.length" />
</div>
</template>
diff --git a/app/assets/javascripts/repo/components/repo_commit_section.vue b/app/assets/javascripts/repo/components/repo_commit_section.vue
index 185cd90ac06..377e3d65348 100644
--- a/app/assets/javascripts/repo/components/repo_commit_section.vue
+++ b/app/assets/javascripts/repo/components/repo_commit_section.vue
@@ -1,139 +1,100 @@
<script>
-import Flash from '../../flash';
-import Store from '../stores/repo_store';
-import RepoMixin from '../mixins/repo_mixin';
-import Service from '../services/repo_service';
+import { mapGetters, mapState, mapActions } from 'vuex';
import PopupDialog from '../../vue_shared/components/popup_dialog.vue';
-import { visitUrl } from '../../lib/utils/url_utility';
+import { n__ } from '../../locale';
export default {
- mixins: [RepoMixin],
-
- data() {
- return Store;
- },
-
components: {
PopupDialog,
},
-
+ data() {
+ return {
+ showNewBranchDialog: false,
+ submitCommitsLoading: false,
+ startNewMR: false,
+ commitMessage: '',
+ };
+ },
computed: {
- showCommitable() {
- return this.isCommitable && this.changedFiles.length;
- },
-
- branchPaths() {
- return this.changedFiles.map(f => f.path);
- },
-
- cantCommitYet() {
+ ...mapState([
+ 'currentBranch',
+ ]),
+ ...mapGetters([
+ 'changedFiles',
+ ]),
+ commitButtonDisabled() {
return !this.commitMessage || this.submitCommitsLoading;
},
-
- filePluralize() {
- return this.changedFiles.length > 1 ? 'files' : 'file';
+ commitButtonText() {
+ return n__('Commit %d file', 'Commit %d files', this.changedFiles.length);
},
},
-
methods: {
- commitToNewBranch(status) {
- if (status) {
- this.showNewBranchDialog = false;
- this.tryCommit(null, true, true);
- } else {
- // reset the state
- }
- },
+ ...mapActions([
+ 'checkCommitStatus',
+ 'commitChanges',
+ 'getTreeData',
+ ]),
+ makeCommit(newBranch = false) {
+ const createNewBranch = newBranch || this.startNewMR;
- makeCommit(newBranch) {
- // see https://docs.gitlab.com/ce/api/commits.html#create-a-commit-with-multiple-files-and-actions
- const commitMessage = this.commitMessage;
- const actions = this.changedFiles.map(f => ({
- action: 'update',
- file_path: f.path,
- content: f.newContent,
- }));
- const branch = newBranch ? `${this.currentBranch}-${this.currentShortHash}` : this.currentBranch;
const payload = {
- branch,
- commit_message: commitMessage,
- actions,
+ branch: createNewBranch ? `${this.currentBranch}-${new Date().getTime().toString()}` : this.currentBranch,
+ commit_message: this.commitMessage,
+ actions: this.changedFiles.map(f => ({
+ action: f.tempFile ? 'create' : 'update',
+ file_path: f.path,
+ content: f.content,
+ encoding: f.base64 ? 'base64' : 'text',
+ })),
+ start_branch: createNewBranch ? this.currentBranch : undefined,
};
- if (newBranch) {
- payload.start_branch = this.currentBranch;
- }
+
+ this.showNewBranchDialog = false;
this.submitCommitsLoading = true;
- Service.commitFiles(payload)
+
+ this.commitChanges({ payload, newMr: this.startNewMR })
.then(() => {
- this.resetCommitState();
- if (this.startNewMR) {
- this.redirectToNewMr(branch);
- } else {
- this.redirectToBranch(branch);
- }
+ this.submitCommitsLoading = false;
+ this.getTreeData();
})
.catch(() => {
- Flash('An error occurred while committing your changes');
+ this.submitCommitsLoading = false;
});
},
+ tryCommit() {
+ this.submitCommitsLoading = true;
- tryCommit(e, skipBranchCheck = false, newBranch = false) {
- if (skipBranchCheck) {
- this.makeCommit(newBranch);
- } else {
- Store.setBranchHash()
- .then(() => {
- if (Store.branchChanged) {
- Store.showNewBranchDialog = true;
- return;
- }
- this.makeCommit(newBranch);
- })
- .catch(() => {
- Flash('An error occurred while committing your changes');
- });
- }
- },
-
- redirectToNewMr(branch) {
- visitUrl(this.newMrTemplateUrl.replace('{{source_branch}}', branch));
- },
-
- redirectToBranch(branch) {
- visitUrl(this.customBranchURL.replace('{{branch}}', branch));
- },
-
- resetCommitState() {
- this.submitCommitsLoading = false;
- this.openedFiles = this.openedFiles.map((file) => {
- const f = file;
- f.changed = false;
- return f;
- });
- this.changedFiles = [];
- this.commitMessage = '';
- this.editMode = false;
- window.scrollTo(0, 0);
+ this.checkCommitStatus()
+ .then((branchChanged) => {
+ if (branchChanged) {
+ this.showNewBranchDialog = true;
+ } else {
+ this.makeCommit();
+ }
+ })
+ .catch(() => {
+ this.submitCommitsLoading = false;
+ });
},
},
};
</script>
<template>
-<div
- v-if="showCommitable"
- id="commit-area">
+<div id="commit-area">
<popup-dialog
v-if="showNewBranchDialog"
:primary-button-label="__('Create new branch')"
kind="primary"
:title="__('Branch has changed')"
:text="__('This branch has changed since you started editing. Would you like to create a new branch?')"
- @submit="commitToNewBranch"
+ @toggle="showNewBranchDialog = false"
+ @submit="makeCommit(true)"
/>
<form
class="form-horizontal"
- @submit.prevent="tryCommit">
+ @submit.prevent="tryCommit()">
<fieldset>
<div class="form-group">
<label class="col-md-4 control-label staged-files">
@@ -142,10 +103,10 @@ export default {
<div class="col-md-6">
<ul class="list-unstyled changed-files">
<li
- v-for="branchPath in branchPaths"
- :key="branchPath">
+ v-for="(file, index) in changedFiles"
+ :key="index">
<span class="help-block">
- {{branchPath}}
+ {{ file.path }}
</span>
</li>
</ul>
@@ -180,9 +141,8 @@ export default {
</div>
<div class="col-md-offset-4 col-md-6">
<button
- ref="submitCommit"
type="submit"
- :disabled="cantCommitYet"
+ :disabled="commitButtonDisabled"
class="btn btn-success">
<i
v-if="submitCommitsLoading"
@@ -191,7 +151,7 @@ export default {
aria-label="loading">
</i>
<span class="commit-summary">
- Commit {{changedFiles.length}} {{filePluralize}}
+ {{ commitButtonText }}
</span>
</button>
</div>
diff --git a/app/assets/javascripts/repo/components/repo_edit_button.vue b/app/assets/javascripts/repo/components/repo_edit_button.vue
index e6e8b2e5205..6c1bb4b8566 100644
--- a/app/assets/javascripts/repo/components/repo_edit_button.vue
+++ b/app/assets/javascripts/repo/components/repo_edit_button.vue
@@ -1,50 +1,57 @@
<script>
-import Store from '../stores/repo_store';
-import RepoMixin from '../mixins/repo_mixin';
+import { mapGetters, mapActions, mapState } from 'vuex';
+import popupDialog from '../../vue_shared/components/popup_dialog.vue';
export default {
- data() {
- return Store;
+ components: {
+ popupDialog,
},
- mixins: [RepoMixin],
computed: {
+ ...mapState([
+ 'editMode',
+ 'discardPopupOpen',
+ ]),
+ ...mapGetters([
+ 'canEditFile',
+ ]),
buttonLabel() {
return this.editMode ? this.__('Cancel edit') : this.__('Edit');
},
-
- showButton() {
- return this.isCommitable &&
- !this.activeFile.render_error &&
- !this.binary &&
- this.openedFiles.length;
- },
},
methods: {
- editCancelClicked() {
- if (this.changedFiles.length) {
- this.dialog.open = true;
- return;
- }
- this.editMode = !this.editMode;
- Store.toggleBlobView();
- },
+ ...mapActions([
+ 'toggleEditMode',
+ 'closeDiscardPopup',
+ ]),
},
};
</script>
<template>
-<button
- v-if="showButton"
- class="btn btn-default"
- type="button"
- @click.prevent="editCancelClicked">
- <i
- v-if="!editMode"
- class="fa fa-pencil"
- aria-hidden="true">
- </i>
- <span>
- {{buttonLabel}}
- </span>
-</button>
+ <div class="editable-mode">
+ <button
+ v-if="canEditFile"
+ class="btn btn-default"
+ type="button"
+ @click.prevent="toggleEditMode()">
+ <i
+ v-if="!editMode"
+ class="fa fa-pencil"
+ aria-hidden="true">
+ </i>
+ <span>
+ {{buttonLabel}}
+ </span>
+ </button>
+ <popup-dialog
+ v-if="discardPopupOpen"
+ class="text-left"
+ :primary-button-label="__('Discard changes')"
+ kind="warning"
+ :title="__('Are you sure?')"
+ :text="__('Are you sure you want to discard your changes?')"
+ @toggle="closeDiscardPopup"
+ @submit="toggleEditMode(true)"
+ />
+ </div>
</template>
diff --git a/app/assets/javascripts/repo/components/repo_editor.vue b/app/assets/javascripts/repo/components/repo_editor.vue
index 4639bee6d66..0d6729bb99b 100644
--- a/app/assets/javascripts/repo/components/repo_editor.vue
+++ b/app/assets/javascripts/repo/components/repo_editor.vue
@@ -1,124 +1,101 @@
<script>
/* global monaco */
-import Store from '../stores/repo_store';
-import Service from '../services/repo_service';
-import Helper from '../helpers/repo_helper';
-
-const RepoEditor = {
- data() {
- return Store;
- },
+import { mapGetters, mapActions } from 'vuex';
+import flash from '../../flash';
+import monacoLoader from '../monaco_loader';
+export default {
destroyed() {
- if (Helper.monacoInstance) {
- Helper.monacoInstance.destroy();
+ if (this.monacoInstance) {
+ this.monacoInstance.destroy();
}
},
-
mounted() {
- Service.getRaw(this.activeFile.raw_path)
- .then((rawResponse) => {
- Store.blobRaw = rawResponse.data;
- Store.activeFile.plain = rawResponse.data;
-
- const monacoInstance = Helper.monaco.editor.create(this.$el, {
- model: null,
- readOnly: false,
- contextmenu: true,
- scrollBeyondLastLine: false,
- });
+ if (this.monaco) {
+ this.initMonaco();
+ } else {
+ monacoLoader(['vs/editor/editor.main'], () => {
+ this.monaco = monaco;
+
+ this.initMonaco();
+ });
+ }
+ },
+ methods: {
+ ...mapActions([
+ 'getRawFileData',
+ 'changeFileContent',
+ ]),
+ initMonaco() {
+ if (this.monacoInstance) {
+ this.monacoInstance.setModel(null);
+ }
- Helper.monacoInstance = monacoInstance;
+ this.getRawFileData(this.activeFile)
+ .then(() => {
+ if (!this.monacoInstance) {
+ this.monacoInstance = this.monaco.editor.create(this.$el, {
+ model: null,
+ readOnly: false,
+ contextmenu: true,
+ scrollBeyondLastLine: false,
+ });
- this.addMonacoEvents();
+ this.languages = this.monaco.languages.getLanguages();
- this.setupEditor();
- })
- .catch(Helper.loadingError);
- },
+ this.addMonacoEvents();
+ }
- methods: {
+ this.setupEditor();
+ })
+ .catch(() => flash('Error setting up monaco. Please try again.'));
+ },
setupEditor() {
- this.showHide();
+ if (!this.activeFile) return;
+ const content = this.activeFile.content !== '' ? this.activeFile.content : this.activeFile.raw;
- Helper.setMonacoModelFromLanguage();
- },
+ const foundLang = this.languages.find(lang =>
+ lang.extensions && lang.extensions.indexOf(this.activeFileExtension) === 0,
+ );
+ const newModel = this.monaco.editor.createModel(
+ content, foundLang ? foundLang.id : 'plaintext',
+ );
- showHide() {
- if (!this.openedFiles.length || (this.binary && !this.activeFile.raw)) {
- this.$el.style.display = 'none';
- } else {
- this.$el.style.display = 'inline-block';
- }
+ this.monacoInstance.setModel(newModel);
},
-
addMonacoEvents() {
- Helper.monacoInstance.onMouseUp(this.onMonacoEditorMouseUp);
- Helper.monacoInstance.onKeyUp(this.onMonacoEditorKeysPressed.bind(this));
- },
-
- onMonacoEditorKeysPressed() {
- Store.setActiveFileContents(Helper.monacoInstance.getValue());
- },
-
- onMonacoEditorMouseUp(e) {
- if (!e.target.position) return;
- const lineNumber = e.target.position.lineNumber;
- if (e.target.element.classList.contains('line-numbers')) {
- location.hash = `L${lineNumber}`;
- Store.setActiveLine(lineNumber);
- }
+ this.monacoInstance.onKeyUp(() => {
+ this.changeFileContent({
+ file: this.activeFile,
+ content: this.monacoInstance.getValue(),
+ });
+ });
},
},
-
watch: {
- dialog: {
- handler(obj) {
- const newObj = obj;
- if (newObj.status) {
- newObj.status = false;
- this.openedFiles = this.openedFiles.map((file) => {
- const f = file;
- if (f.active) {
- this.blobRaw = f.plain;
- }
- f.changed = false;
- delete f.newContent;
-
- return f;
- });
- this.editMode = false;
- Store.toggleBlobView();
- }
- },
- deep: true,
- },
-
- blobRaw() {
- if (Helper.monacoInstance) {
- this.setupEditor();
- }
- },
-
- activeLine() {
- if (Helper.monacoInstance) {
- Helper.monacoInstance.setPosition({
- lineNumber: this.activeLine,
- column: 1,
- });
+ activeFile(oldVal, newVal) {
+ if (newVal && !newVal.active) {
+ this.initMonaco();
}
},
},
computed: {
+ ...mapGetters([
+ 'activeFile',
+ 'activeFileExtension',
+ ]),
shouldHideEditor() {
- return !this.openedFiles.length || (this.binary && !this.activeFile.raw);
+ return this.activeFile.binary && !this.activeFile.raw;
},
},
};
-
-export default RepoEditor;
</script>
<template>
-<div id="ide" v-if='!shouldHideEditor'></div>
+ <div
+ id="ide"
+ v-if='!shouldHideEditor'
+ class="blob-viewer-container blob-editor-container"
+ >
+ </div>
</template>
diff --git a/app/assets/javascripts/repo/components/repo_file.vue b/app/assets/javascripts/repo/components/repo_file.vue
index 8c86e87ed3a..7a23154b340 100644
--- a/app/assets/javascripts/repo/components/repo_file.vue
+++ b/app/assets/javascripts/repo/components/repo_file.vue
@@ -1,11 +1,9 @@
<script>
+ import { mapActions, mapGetters } from 'vuex';
import timeAgoMixin from '../../vue_shared/mixins/timeago';
- import eventHub from '../event_hub';
- import repoMixin from '../mixins/repo_mixin';
export default {
mixins: [
- repoMixin,
timeAgoMixin,
],
props: {
@@ -15,13 +13,15 @@
},
},
computed: {
+ ...mapGetters([
+ 'isCollapsed',
+ ]),
fileIcon() {
- const classObj = {
+ return {
'fa-spinner fa-spin': this.file.loading,
[this.file.icon]: !this.file.loading,
'fa-folder-open': !this.file.loading && this.file.opened,
};
- return classObj;
},
levelIndentation() {
return {
@@ -33,9 +33,9 @@
},
},
methods: {
- linkClicked(file) {
- eventHub.$emit('fileNameClicked', file);
- },
+ ...mapActions([
+ 'clickedTreeRow',
+ ]),
},
};
</script>
@@ -43,7 +43,7 @@
<template>
<tr
class="file"
- @click.prevent="linkClicked(file)">
+ @click.prevent="clickedTreeRow(file)">
<td>
<i
class="fa fa-fw file-icon"
@@ -71,7 +71,7 @@
</template>
</td>
- <template v-if="!isMini">
+ <template v-if="!isCollapsed">
<td class="hidden-sm hidden-xs">
<a
@click.stop
diff --git a/app/assets/javascripts/repo/components/repo_file_buttons.vue b/app/assets/javascripts/repo/components/repo_file_buttons.vue
index 03cd219e718..dd948ee84fb 100644
--- a/app/assets/javascripts/repo/components/repo_file_buttons.vue
+++ b/app/assets/javascripts/repo/components/repo_file_buttons.vue
@@ -1,42 +1,35 @@
<script>
-import Store from '../stores/repo_store';
-import Helper from '../helpers/repo_helper';
-import RepoMixin from '../mixins/repo_mixin';
-
-const RepoFileButtons = {
- data() {
- return Store;
- },
-
- mixins: [RepoMixin],
+import { mapGetters } from 'vuex';
+export default {
computed: {
-
- rawDownloadButtonLabel() {
- return this.binary ? 'Download' : 'Raw';
+ ...mapGetters([
+ 'activeFile',
+ ]),
+ showButtons() {
+ return this.activeFile.rawPath ||
+ this.activeFile.blamePath ||
+ this.activeFile.commitsPath ||
+ this.activeFile.permalink;
},
-
- canPreview() {
- return Helper.isRenderable();
+ rawDownloadButtonLabel() {
+ return this.activeFile.binary ? 'Download' : 'Raw';
},
},
-
- methods: {
- rawPreviewToggle: Store.toggleRawPreview,
- },
};
-
-export default RepoFileButtons;
</script>
<template>
- <div id="repo-file-buttons">
+ <div
+ v-if="showButtons"
+ class="repo-file-buttons"
+ >
<a
- :href="activeFile.raw_path"
+ :href="activeFile.rawPath"
target="_blank"
class="btn btn-default raw"
rel="noopener noreferrer">
- {{rawDownloadButtonLabel}}
+ {{ rawDownloadButtonLabel }}
</a>
<div
@@ -44,12 +37,12 @@ export default RepoFileButtons;
role="group"
aria-label="File actions">
<a
- :href="activeFile.blame_path"
+ :href="activeFile.blamePath"
class="btn btn-default blame">
Blame
</a>
<a
- :href="activeFile.commits_path"
+ :href="activeFile.commitsPath"
class="btn btn-default history">
History
</a>
@@ -59,13 +52,5 @@ export default RepoFileButtons;
Permalink
</a>
</div>
-
- <a
- v-if="canPreview"
- href="#"
- @click.prevent="rawPreviewToggle"
- class="btn btn-default preview">
- {{activeFileLabel}}
- </a>
</div>
</template>
diff --git a/app/assets/javascripts/repo/components/repo_loading_file.vue b/app/assets/javascripts/repo/components/repo_loading_file.vue
index 832b45b2b29..1e6c405f292 100644
--- a/app/assets/javascripts/repo/components/repo_loading_file.vue
+++ b/app/assets/javascripts/repo/components/repo_loading_file.vue
@@ -1,10 +1,12 @@
<script>
- import repoMixin from '../mixins/repo_mixin';
+ import { mapGetters } from 'vuex';
export default {
- mixins: [
- repoMixin,
- ],
+ computed: {
+ ...mapGetters([
+ 'isCollapsed',
+ ]),
+ },
methods: {
lineOfCode(n) {
return `skeleton-line-${n}`;
@@ -28,7 +30,7 @@
</div>
</div>
</td>
- <template v-if="!isMini">
+ <template v-if="!isCollapsed">
<td
class="hidden-sm hidden-xs">
<div class="animation-container">
diff --git a/app/assets/javascripts/repo/components/repo_prev_directory.vue b/app/assets/javascripts/repo/components/repo_prev_directory.vue
index c4bf6dcdec2..a2b305bbd05 100644
--- a/app/assets/javascripts/repo/components/repo_prev_directory.vue
+++ b/app/assets/javascripts/repo/components/repo_prev_directory.vue
@@ -1,26 +1,22 @@
<script>
- import eventHub from '../event_hub';
- import repoMixin from '../mixins/repo_mixin';
+ import { mapGetters, mapState, mapActions } from 'vuex';
export default {
- mixins: [
- repoMixin,
- ],
- props: {
- prevUrl: {
- type: String,
- required: true,
- },
- },
computed: {
+ ...mapState([
+ 'parentTreeUrl',
+ ]),
+ ...mapGetters([
+ 'isCollapsed',
+ ]),
colSpanCondition() {
- return this.isMini ? undefined : 3;
+ return this.isCollapsed ? undefined : 3;
},
},
methods: {
- linkClicked(file) {
- eventHub.$emit('goToPreviousDirectoryClicked', file);
- },
+ ...mapActions([
+ 'getTreeData',
+ ]),
},
};
</script>
@@ -30,9 +26,9 @@
<td
:colspan="colSpanCondition"
class="table-cell"
- @click.prevent="linkClicked(prevUrl)"
+ @click.prevent="getTreeData({ endpoint: parentTreeUrl })"
>
- <a :href="prevUrl">...</a>
+ <a :href="parentTreeUrl">...</a>
</td>
</tr>
</template>
diff --git a/app/assets/javascripts/repo/components/repo_preview.vue b/app/assets/javascripts/repo/components/repo_preview.vue
index b5be771d539..d1883299bd9 100644
--- a/app/assets/javascripts/repo/components/repo_preview.vue
+++ b/app/assets/javascripts/repo/components/repo_preview.vue
@@ -1,26 +1,20 @@
<script>
/* global LineHighlighter */
-
-import Store from '../stores/repo_store';
+import { mapGetters } from 'vuex';
export default {
- data() {
- return Store;
- },
computed: {
- html() {
- return this.activeFile.html;
+ ...mapGetters([
+ 'activeFile',
+ ]),
+ renderErrorTooLarge() {
+ return this.activeFile.renderError === 'too_large';
},
},
methods: {
highlightFile() {
$(this.$el).find('.file-content').syntaxHighlight();
},
- highlightLine() {
- if (Store.activeLine > -1) {
- this.lineHighlighter.highlightHash(`#L${Store.activeLine}`);
- }
- },
},
mounted() {
this.highlightFile();
@@ -29,38 +23,39 @@ export default {
scrollFileHolder: true,
});
},
- watch: {
- html() {
- this.$nextTick(() => {
- this.highlightFile();
- this.highlightLine();
- });
- },
- activeLine() {
- this.highlightLine();
- },
+ updated() {
+ this.$nextTick(() => {
+ this.highlightFile();
+ });
},
};
</script>
<template>
-<div>
+<div class="blob-viewer-container">
<div
- v-if="!activeFile.render_error"
+ v-if="!activeFile.renderError"
v-html="activeFile.html">
</div>
<div
- v-else-if="activeFile.tooLarge"
+ v-else-if="activeFile.tempFile"
+ class="vertical-center render-error">
+ <p class="text-center">
+ The source could not be displayed for this temporary file.
+ </p>
+ </div>
+ <div
+ v-else-if="renderErrorTooLarge"
class="vertical-center render-error">
<p class="text-center">
- The source could not be displayed because it is too large. You can <a :href="activeFile.raw_path">download</a> it instead.
+ The source could not be displayed because it is too large. You can <a :href="activeFile.rawPath" download>download</a> it instead.
</p>
</div>
<div
v-else
class="vertical-center render-error">
<p class="text-center">
- The source could not be displayed because a rendering error occurred. You can <a :href="activeFile.raw_path">download</a> it instead.
+ The source could not be displayed because a rendering error occurred. You can <a :href="activeFile.rawPath" download>download</a> it instead.
</p>
</div>
</div>
diff --git a/app/assets/javascripts/repo/components/repo_sidebar.vue b/app/assets/javascripts/repo/components/repo_sidebar.vue
index 09dc9ee25d7..63c0d70f5c0 100644
--- a/app/assets/javascripts/repo/components/repo_sidebar.vue
+++ b/app/assets/javascripts/repo/components/repo_sidebar.vue
@@ -1,120 +1,55 @@
<script>
-import _ from 'underscore';
-import Service from '../services/repo_service';
-import Helper from '../helpers/repo_helper';
-import Store from '../stores/repo_store';
-import eventHub from '../event_hub';
+import { mapState, mapGetters, mapActions } from 'vuex';
import RepoPreviousDirectory from './repo_prev_directory.vue';
import RepoFile from './repo_file.vue';
import RepoLoadingFile from './repo_loading_file.vue';
-import RepoMixin from '../mixins/repo_mixin';
export default {
- mixins: [RepoMixin],
components: {
'repo-previous-directory': RepoPreviousDirectory,
'repo-file': RepoFile,
'repo-loading-file': RepoLoadingFile,
},
created() {
- window.addEventListener('popstate', this.checkHistory);
+ window.addEventListener('popstate', this.popHistoryState);
},
destroyed() {
- eventHub.$off('fileNameClicked', this.fileClicked);
- eventHub.$off('goToPreviousDirectoryClicked', this.goToPreviousDirectoryClicked);
- window.removeEventListener('popstate', this.checkHistory);
+ window.removeEventListener('popstate', this.popHistoryState);
},
mounted() {
- eventHub.$on('fileNameClicked', this.fileClicked);
- eventHub.$on('goToPreviousDirectoryClicked', this.goToPreviousDirectoryClicked);
- },
- data() {
- return Store;
+ this.getTreeData();
},
computed: {
- flattendFiles() {
- const mapFiles = arr => (!arr.files.length ? [] : _.map(arr.files, a => [a, mapFiles(a)]));
-
- return _.chain(this.files)
- .map(arr => [arr, mapFiles(arr)])
- .flatten()
- .value();
- },
+ ...mapState([
+ 'loading',
+ 'isRoot',
+ ]),
+ ...mapState({
+ projectName(state) {
+ return state.project.name;
+ },
+ }),
+ ...mapGetters([
+ 'treeList',
+ 'isCollapsed',
+ ]),
},
methods: {
- checkHistory() {
- let selectedFile = this.files.find(file => location.pathname.indexOf(file.url) > -1);
- if (!selectedFile) {
- // Maybe it is not in the current tree but in the opened tabs
- selectedFile = Helper.getFileFromPath(location.pathname);
- }
-
- let lineNumber = null;
- if (location.hash.indexOf('#L') > -1) lineNumber = Number(location.hash.substr(2));
-
- if (selectedFile) {
- if (selectedFile.url !== this.activeFile.url) {
- this.fileClicked(selectedFile, lineNumber);
- } else {
- Store.setActiveLine(lineNumber);
- }
- } else {
- // Not opened at all lets open new tab
- this.fileClicked({
- url: location.href,
- }, lineNumber);
- }
- },
-
- fileClicked(clickedFile, lineNumber) {
- const file = clickedFile;
-
- if (file.loading) return;
-
- if (file.type === 'tree' && file.opened) {
- Helper.setDirectoryToClosed(file);
- Store.setActiveLine(lineNumber);
- } else if (file.type === 'submodule') {
- file.loading = true;
-
- gl.utils.visitUrl(file.url);
- } else {
- const openFile = Helper.getFileFromPath(file.url);
-
- if (openFile) {
- Store.setActiveFiles(openFile);
- Store.setActiveLine(lineNumber);
- } else {
- file.loading = true;
- Service.url = file.url;
- Helper.getContent(file)
- .then(() => {
- file.loading = false;
- Helper.scrollTabsRight();
- Store.setActiveLine(lineNumber);
- })
- .catch(Helper.loadingError);
- }
- }
- },
-
- goToPreviousDirectoryClicked(prevURL) {
- Service.url = prevURL;
- Helper.getContent(null, true)
- .then(() => Helper.scrollTabsRight())
- .catch(Helper.loadingError);
- },
+ ...mapActions([
+ 'getTreeData',
+ 'popHistoryState',
+ ]),
},
};
</script>
<template>
-<div id="sidebar" :class="{'sidebar-mini' : isMini}">
+<div id="sidebar" :class="{'sidebar-mini' : isCollapsed}">
<table class="table">
<thead>
<tr>
<th
- v-if="isMini"
+ v-if="isCollapsed"
class="repo-file-options title"
>
<strong class="clgray">
@@ -136,17 +71,16 @@ export default {
</thead>
<tbody>
<repo-previous-directory
- v-if="!isRoot && !loading.tree"
- :prev-url="prevURL"
+ v-if="!isRoot && treeList.length"
/>
<repo-loading-file
- v-if="!flattendFiles.length && loading.tree"
+ v-if="!treeList.length && loading"
v-for="n in 5"
:key="n"
/>
<repo-file
- v-for="file in flattendFiles"
- :key="file.id"
+ v-for="(file, index) in treeList"
+ :key="index"
:file="file"
/>
</tbody>
diff --git a/app/assets/javascripts/repo/components/repo_tab.vue b/app/assets/javascripts/repo/components/repo_tab.vue
index 098715915b0..da0714c368c 100644
--- a/app/assets/javascripts/repo/components/repo_tab.vue
+++ b/app/assets/javascripts/repo/components/repo_tab.vue
@@ -1,7 +1,7 @@
<script>
-import Store from '../stores/repo_store';
+import { mapActions } from 'vuex';
-const RepoTab = {
+export default {
props: {
tab: {
type: Object,
@@ -11,44 +11,38 @@ const RepoTab = {
computed: {
closeLabel() {
- if (this.tab.changed) {
+ if (this.tab.changed || this.tab.tempFile) {
return `${this.tab.name} changed`;
}
return `Close ${this.tab.name}`;
},
changedClass() {
const tabChangedObj = {
- 'fa-times close-icon': !this.tab.changed,
- 'fa-circle unsaved-icon': this.tab.changed,
+ 'fa-times close-icon': !this.tab.changed && !this.tab.tempFile,
+ 'fa-circle unsaved-icon': this.tab.changed || this.tab.tempFile,
};
return tabChangedObj;
},
},
methods: {
- tabClicked(file) {
- Store.setActiveFiles(file);
- },
- closeTab(file) {
- if (file.changed) return;
-
- Store.removeFromOpenedFiles(file);
- },
+ ...mapActions([
+ 'setFileActive',
+ 'closeFile',
+ ]),
},
};
-
-export default RepoTab;
</script>
<template>
<li
:class="{ active : tab.active }"
- @click="tabClicked(tab)"
+ @click="setFileActive(tab)"
>
<button
type="button"
class="close-btn"
- @click.stop.prevent="closeTab(tab)"
+ @click.stop.prevent="closeFile({ file: tab })"
:aria-label="closeLabel">
<i
class="fa"
@@ -61,7 +55,7 @@ export default RepoTab;
href="#"
class="repo-tab"
:title="tab.url"
- @click.prevent="tabClicked(tab)">
+ @click.prevent.stop="setFileActive(tab)">
{{tab.name}}
</a>
</li>
diff --git a/app/assets/javascripts/repo/components/repo_tabs.vue b/app/assets/javascripts/repo/components/repo_tabs.vue
index b57cd0960de..59beae53e8d 100644
--- a/app/assets/javascripts/repo/components/repo_tabs.vue
+++ b/app/assets/javascripts/repo/components/repo_tabs.vue
@@ -1,15 +1,15 @@
<script>
- import Store from '../stores/repo_store';
+ import { mapState } from 'vuex';
import RepoTab from './repo_tab.vue';
- import RepoMixin from '../mixins/repo_mixin';
export default {
- mixins: [RepoMixin],
components: {
'repo-tab': RepoTab,
},
- data() {
- return Store;
+ computed: {
+ ...mapState([
+ 'openFiles',
+ ]),
},
};
</script>
@@ -20,7 +20,7 @@
class="list-unstyled"
>
<repo-tab
- v-for="tab in openedFiles"
+ v-for="tab in openFiles"
:key="tab.id"
:tab="tab"
/>
diff --git a/app/assets/javascripts/repo/event_hub.js b/app/assets/javascripts/repo/event_hub.js
deleted file mode 100644
index 0948c2e5352..00000000000
--- a/app/assets/javascripts/repo/event_hub.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import Vue from 'vue';
-
-export default new Vue();
diff --git a/app/assets/javascripts/repo/helpers/monaco_loader_helper.js b/app/assets/javascripts/repo/helpers/monaco_loader_helper.js
deleted file mode 100644
index f8729bbf585..00000000000
--- a/app/assets/javascripts/repo/helpers/monaco_loader_helper.js
+++ /dev/null
@@ -1,25 +0,0 @@
-/* global monaco */
-import RepoEditor from '../components/repo_editor.vue';
-import Store from '../stores/repo_store';
-import Helper from '../helpers/repo_helper';
-import monacoLoader from '../monaco_loader';
-
-function repoEditorLoader() {
- Store.monacoLoading = true;
- return new Promise((resolve, reject) => {
- monacoLoader(['vs/editor/editor.main'], () => {
- Helper.monaco = monaco;
- Store.monacoLoading = false;
- resolve(RepoEditor);
- }, () => {
- Store.monacoLoading = false;
- reject();
- });
- });
-}
-
-const MonacoLoaderHelper = {
- repoEditorLoader,
-};
-
-export default MonacoLoaderHelper;
diff --git a/app/assets/javascripts/repo/helpers/repo_helper.js b/app/assets/javascripts/repo/helpers/repo_helper.js
deleted file mode 100644
index f7b7f93e4b8..00000000000
--- a/app/assets/javascripts/repo/helpers/repo_helper.js
+++ /dev/null
@@ -1,228 +0,0 @@
-import { convertPermissionToBoolean } from '../../lib/utils/common_utils';
-import Service from '../services/repo_service';
-import Store from '../stores/repo_store';
-import Flash from '../../flash';
-
-const RepoHelper = {
- monacoInstance: null,
-
- getDefaultActiveFile() {
- return {
- active: true,
- binary: false,
- extension: '',
- html: '',
- mime_type: '',
- name: '',
- plain: '',
- size: 0,
- url: '',
- raw: false,
- newContent: '',
- changed: false,
- loading: false,
- };
- },
-
- key: '',
-
- Time: window.performance
- && window.performance.now
- ? window.performance
- : Date,
-
- getFileExtension(fileName) {
- return fileName.split('.').pop();
- },
-
- getLanguageIDForFile(file, langs) {
- const ext = RepoHelper.getFileExtension(file.name);
- const foundLang = RepoHelper.findLanguage(ext, langs);
-
- return foundLang ? foundLang.id : 'plaintext';
- },
-
- setMonacoModelFromLanguage() {
- RepoHelper.monacoInstance.setModel(null);
- const languages = RepoHelper.monaco.languages.getLanguages();
- const languageID = RepoHelper.getLanguageIDForFile(Store.activeFile, languages);
- const newModel = RepoHelper.monaco.editor.createModel(Store.blobRaw, languageID);
- RepoHelper.monacoInstance.setModel(newModel);
- },
-
- findLanguage(ext, langs) {
- return langs.find(lang => lang.extensions && lang.extensions.indexOf(`.${ext}`) > -1);
- },
-
- setDirectoryOpen(tree, title) {
- if (!tree) return;
-
- Object.assign(tree, {
- opened: true,
- });
-
- RepoHelper.updateHistoryEntry(tree.url, title);
- },
-
- setDirectoryToClosed(entry) {
- Object.assign(entry, {
- opened: false,
- files: [],
- });
- },
-
- isRenderable() {
- const okExts = ['md', 'svg'];
- return okExts.indexOf(Store.activeFile.extension) > -1;
- },
-
- setBinaryDataAsBase64(file) {
- Service.getBase64Content(file.raw_path)
- .then((response) => {
- Store.blobRaw = response;
- file.base64 = response; // eslint-disable-line no-param-reassign
- })
- .catch(RepoHelper.loadingError);
- },
-
- getContent(treeOrFile, emptyFiles = false) {
- let file = treeOrFile;
-
- if (!Store.files.length) {
- Store.loading.tree = true;
- }
-
- return Service.getContent()
- .then((response) => {
- const data = response.data;
- if (response.headers && response.headers['page-title']) data.pageTitle = decodeURI(response.headers['page-title']);
- if (response.headers && response.headers['is-root'] && !Store.isInitialRoot) {
- Store.isRoot = convertPermissionToBoolean(response.headers['is-root']);
- Store.isInitialRoot = Store.isRoot;
- }
-
- if (file && file.type === 'blob') {
- if (!file) file = data;
- Store.binary = data.binary;
-
- if (data.binary) {
- // file might be undefined
- RepoHelper.setBinaryDataAsBase64(data);
- Store.setViewToPreview();
- } else if (!Store.isPreviewView() && !data.render_error) {
- Service.getRaw(data.raw_path)
- .then((rawResponse) => {
- Store.blobRaw = rawResponse.data;
- data.plain = rawResponse.data;
- RepoHelper.setFile(data, file);
- }).catch(RepoHelper.loadingError);
- }
-
- if (Store.isPreviewView()) {
- RepoHelper.setFile(data, file);
- }
- } else {
- Store.loading.tree = false;
- RepoHelper.setDirectoryOpen(file, data.pageTitle || data.name);
-
- if (emptyFiles) {
- Store.files = [];
- }
-
- this.addToDirectory(file, data);
-
- Store.prevURL = Service.blobURLtoParentTree(Service.url);
- }
- }).catch(RepoHelper.loadingError);
- },
-
- addToDirectory(file, data) {
- const tree = file || Store;
- const files = tree.files.concat(this.dataToListOfFiles(data, file ? file.level + 1 : 0));
-
- tree.files = files;
- },
-
- setFile(data, file) {
- const newFile = data;
- newFile.url = file.url || Service.url; // Grab the URL from service, happens on page refresh.
-
- if (newFile.render_error === 'too_large' || newFile.render_error === 'collapsed') {
- newFile.tooLarge = true;
- }
- newFile.newContent = '';
-
- Store.addToOpenedFiles(newFile);
- Store.setActiveFiles(newFile);
- },
-
- serializeRepoEntity(type, entity, level = 0) {
- const { id, url, name, icon, last_commit, tree_url } = entity;
-
- return {
- id,
- type,
- name,
- url,
- tree_url,
- level,
- icon: `fa-${icon}`,
- files: [],
- loading: false,
- opened: false,
- // eslint-disable-next-line camelcase
- lastCommit: last_commit ? {
- url: `${Store.projectUrl}/commit/${last_commit.id}`,
- message: last_commit.message,
- updatedAt: last_commit.committed_date,
- } : {},
- };
- },
-
- scrollTabsRight() {
- const tabs = document.getElementById('tabs');
- if (!tabs) return;
- tabs.scrollLeft = tabs.scrollWidth;
- },
-
- dataToListOfFiles(data, level) {
- const { blobs, trees, submodules } = data;
- return [
- ...trees.map(tree => RepoHelper.serializeRepoEntity('tree', tree, level)),
- ...submodules.map(submodule => RepoHelper.serializeRepoEntity('submodule', submodule, level)),
- ...blobs.map(blob => RepoHelper.serializeRepoEntity('blob', blob, level)),
- ];
- },
-
- genKey() {
- return RepoHelper.Time.now().toFixed(3);
- },
-
- updateHistoryEntry(url, title) {
- const history = window.history;
-
- RepoHelper.key = RepoHelper.genKey();
-
- if (document.location.pathname !== url) {
- history.pushState({ key: RepoHelper.key }, '', url);
- }
-
- if (title) {
- document.title = title;
- }
- },
-
- findOpenedFileFromActive() {
- return Store.openedFiles.find(openedFile => Store.activeFile.url === openedFile.url);
- },
-
- getFileFromPath(path) {
- return Store.openedFiles.find(file => file.url === path);
- },
-
- loadingError() {
- Flash('Unable to load this content at this time.');
- },
-};
-
-export default RepoHelper;
diff --git a/app/assets/javascripts/repo/index.js b/app/assets/javascripts/repo/index.js
index 65dee7d5fd1..b6801af7fcb 100644
--- a/app/assets/javascripts/repo/index.js
+++ b/app/assets/javascripts/repo/index.js
@@ -1,52 +1,50 @@
-import $ from 'jquery';
import Vue from 'vue';
+import { mapActions } from 'vuex';
import { convertPermissionToBoolean } from '../lib/utils/common_utils';
-import Service from './services/repo_service';
-import Store from './stores/repo_store';
import Repo from './components/repo.vue';
import RepoEditButton from './components/repo_edit_button.vue';
+import newBranchForm from './components/new_branch_form.vue';
+import newDropdown from './components/new_dropdown/index.vue';
+import store from './stores';
import Translate from '../vue_shared/translate';
-function initDropdowns() {
- $('.js-tree-ref-target-holder').hide();
-}
-
-function addEventsForNonVueEls() {
- window.onbeforeunload = function confirmUnload(e) {
- const hasChanged = Store.openedFiles
- .some(file => file.changed);
- if (!hasChanged) return undefined;
- const event = e || window.event;
- if (event) event.returnValue = 'Are you sure you want to lose unsaved changes?';
- // For Safari
- return 'Are you sure you want to lose unsaved changes?';
- };
-}
-
-function setInitialStore(data) {
- Store.service = Service;
- Store.service.url = data.url;
- Store.service.refsUrl = data.refsUrl;
- Store.projectId = data.projectId;
- Store.projectName = data.projectName;
- Store.projectUrl = data.projectUrl;
- Store.canCommit = data.canCommit;
- Store.onTopOfBranch = data.onTopOfBranch;
- Store.newMrTemplateUrl = decodeURIComponent(data.newMrTemplateUrl);
- Store.customBranchURL = decodeURIComponent(data.blobUrl);
- Store.isRoot = convertPermissionToBoolean(data.root);
- Store.isInitialRoot = convertPermissionToBoolean(data.root);
- Store.currentBranch = $('button.dropdown-menu-toggle').attr('data-ref');
- Store.checkIsCommitable();
- Store.setBranchHash();
-}
-
function initRepo(el) {
+ if (!el) return null;
+
return new Vue({
el,
+ store,
components: {
repo: Repo,
},
+ methods: {
+ ...mapActions([
+ 'setInitialData',
+ ]),
+ },
+ created() {
+ const data = el.dataset;
+
+ this.setInitialData({
+ project: {
+ id: data.projectId,
+ name: data.projectName,
+ url: data.projectUrl,
+ },
+ endpoints: {
+ rootEndpoint: data.url,
+ newMergeRequestUrl: data.newMergeRequestUrl,
+ rootUrl: data.rootUrl,
+ },
+ canCommit: convertPermissionToBoolean(data.canCommit),
+ onTopOfBranch: convertPermissionToBoolean(data.onTopOfBranch),
+ currentRef: data.ref,
+ path: data.currentPath,
+ currentBranch: data.currentBranch,
+ isRoot: convertPermissionToBoolean(data.root),
+ isInitialRoot: convertPermissionToBoolean(data.root),
+ });
+ },
render(createElement) {
return createElement('repo');
},
@@ -56,25 +54,53 @@ function initRepo(el) {
function initRepoEditButton(el) {
return new Vue({
el,
+ store,
components: {
repoEditButton: RepoEditButton,
},
+ render(createElement) {
+ return createElement('repo-edit-button');
+ },
});
}
-function initRepoBundle() {
- const repo = document.getElementById('repo');
- const editButton = document.querySelector('.editable-mode');
- setInitialStore(repo.dataset);
- addEventsForNonVueEls();
- initDropdowns();
+function initNewDropdown(el) {
+ return new Vue({
+ el,
+ store,
+ components: {
+ newDropdown,
+ },
+ render(createElement) {
+ return createElement('new-dropdown');
+ },
+ });
+}
+
+function initNewBranchForm() {
+ const el = document.querySelector('.js-new-branch-dropdown');
- Vue.use(Translate);
+ if (!el) return null;
- initRepo(repo);
- initRepoEditButton(editButton);
+ return new Vue({
+ el,
+ components: {
+ newBranchForm,
+ },
+ store,
+ render(createElement) {
+ return createElement('new-branch-form');
+ },
+ });
}
-$(initRepoBundle);
+const repo = document.getElementById('repo');
+const editButton = document.querySelector('.editable-mode');
+const newDropdownHolder = document.querySelector('.js-new-dropdown');
+
+Vue.use(Translate);
-export default initRepoBundle;
+initRepo(repo);
+initRepoEditButton(editButton);
+initNewBranchForm();
+initNewDropdown(newDropdownHolder);
diff --git a/app/assets/javascripts/repo/mixins/repo_mixin.js b/app/assets/javascripts/repo/mixins/repo_mixin.js
deleted file mode 100644
index c8e8238a0d3..00000000000
--- a/app/assets/javascripts/repo/mixins/repo_mixin.js
+++ /dev/null
@@ -1,17 +0,0 @@
-import Store from '../stores/repo_store';
-
-const RepoMixin = {
- computed: {
- isMini() {
- return !!Store.openedFiles.length;
- },
-
- changedFiles() {
- const changedFileList = this.openedFiles
- .filter(file => file.changed);
- return changedFileList;
- },
- },
-};
-
-export default RepoMixin;
diff --git a/app/assets/javascripts/repo/services/index.js b/app/assets/javascripts/repo/services/index.js
new file mode 100644
index 00000000000..dc222ccac01
--- /dev/null
+++ b/app/assets/javascripts/repo/services/index.js
@@ -0,0 +1,33 @@
+import Vue from 'vue';
+import VueResource from 'vue-resource';
+import Api from '../../api';
+
+Vue.use(VueResource);
+
+export default {
+ getTreeData(endpoint) {
+ return Vue.http.get(endpoint, { params: { format: 'json' } });
+ },
+ getFileData(endpoint) {
+ return Vue.http.get(endpoint, { params: { format: 'json' } });
+ },
+ getRawFileData(file) {
+ if (file.tempFile) {
+ return Promise.resolve(file.content);
+ }
+
+ return Vue.http.get(file.rawPath, { params: { format: 'json' } })
+ .then(res => res.text());
+ },
+ getBranchData(projectId, currentBranch) {
+ return Api.branchSingle(projectId, currentBranch);
+ },
+ createBranch(projectId, payload) {
+ const url = Api.buildUrl(Api.createBranchPath).replace(':id', projectId);
+
+ return Vue.http.post(url, payload);
+ },
+ commit(projectId, payload) {
+ return Api.commitMultiple(projectId, payload);
+ },
+};
diff --git a/app/assets/javascripts/repo/services/repo_service.js b/app/assets/javascripts/repo/services/repo_service.js
deleted file mode 100644
index d68d71a4629..00000000000
--- a/app/assets/javascripts/repo/services/repo_service.js
+++ /dev/null
@@ -1,85 +0,0 @@
-import axios from 'axios';
-import Store from '../stores/repo_store';
-import Api from '../../api';
-import Helper from '../helpers/repo_helper';
-
-const RepoService = {
- url: '',
- options: {
- params: {
- format: 'json',
- },
- },
- richExtensionRegExp: /md/,
-
- getRaw(url) {
- return axios.get(url, {
- // Stop Axios from parsing a JSON file into a JS object
- transformResponse: [res => res],
- });
- },
-
- buildParams(url = this.url) {
- // shallow clone object without reference
- const params = Object.assign({}, this.options.params);
-
- if (this.urlIsRichBlob(url)) params.viewer = 'rich';
-
- return params;
- },
-
- urlIsRichBlob(url = this.url) {
- const extension = Helper.getFileExtension(url);
-
- return this.richExtensionRegExp.test(extension);
- },
-
- getContent(url = this.url) {
- const params = this.buildParams(url);
-
- return axios.get(url, {
- params,
- });
- },
-
- getBase64Content(url = this.url) {
- const request = axios.get(url, {
- responseType: 'arraybuffer',
- });
-
- return request.then(response => this.bufferToBase64(response.data));
- },
-
- bufferToBase64(data) {
- return new Buffer(data, 'binary').toString('base64');
- },
-
- blobURLtoParentTree(url) {
- const urlArray = url.split('/');
- urlArray.pop();
- const blobIndex = urlArray.lastIndexOf('blob');
-
- if (blobIndex > -1) urlArray[blobIndex] = 'tree';
-
- return urlArray.join('/');
- },
-
- getBranch() {
- return Api.branchSingle(Store.projectId, Store.currentBranch);
- },
-
- commitFiles(payload) {
- return Api.commitMultiple(Store.projectId, payload)
- .then(this.commitFlash);
- },
-
- commitFlash(data) {
- if (data.short_id && data.stats) {
- window.Flash(`Your changes have been committed. Commit ${data.short_id} with ${data.stats.additions} additions, ${data.stats.deletions} deletions.`, 'notice');
- } else {
- window.Flash(data.message);
- }
- },
-};
-
-export default RepoService;
diff --git a/app/assets/javascripts/repo/stores/actions.js b/app/assets/javascripts/repo/stores/actions.js
new file mode 100644
index 00000000000..ca2f2a5ce7a
--- /dev/null
+++ b/app/assets/javascripts/repo/stores/actions.js
@@ -0,0 +1,129 @@
+import Vue from 'vue';
+import flash from '../../flash';
+import service from '../services';
+import * as types from './mutation_types';
+
+export const redirectToUrl = url => gl.utils.visitUrl(url);
+
+export const setInitialData = ({ commit }, data) => commit(types.SET_INITIAL_DATA, data);
+
+export const closeDiscardPopup = ({ commit }) => commit(types.TOGGLE_DISCARD_POPUP, false);
+
+export const discardAllChanges = ({ commit, getters, dispatch }) => {
+ const changedFiles = getters.changedFiles;
+
+ changedFiles.forEach((file) => {
+ commit(types.DISCARD_FILE_CHANGES, file);
+
+ if (file.tempFile) {
+ dispatch('closeFile', { file, force: true });
+ }
+ });
+};
+
+export const closeAllFiles = ({ state, dispatch }) => {
+ state.openFiles.forEach(file => dispatch('closeFile', { file }));
+};
+
+export const toggleEditMode = ({ state, commit, getters, dispatch }, force = false) => {
+ const changedFiles = getters.changedFiles;
+
+ if (changedFiles.length && !force) {
+ commit(types.TOGGLE_DISCARD_POPUP, true);
+ } else {
+ commit(types.TOGGLE_EDIT_MODE);
+ commit(types.TOGGLE_DISCARD_POPUP, false);
+ dispatch('toggleBlobView');
+
+ if (!state.editMode) {
+ dispatch('discardAllChanges');
+ }
+ }
+};
+
+export const toggleBlobView = ({ commit, state }) => {
+ if (state.editMode) {
+ commit(types.SET_EDIT_MODE);
+ } else {
+ commit(types.SET_PREVIEW_MODE);
+ }
+};
+
+export const checkCommitStatus = ({ state }) => service.getBranchData(
+ state.project.id,
+ state.currentBranch,
+)
+ .then((data) => {
+ const { id } = data.commit;
+
+ if (state.currentRef !== id) {
+ return true;
+ }
+
+ return false;
+ })
+ .catch(() => flash('Error checking branch data. Please try again.'));
+
+export const commitChanges = ({ commit, state, dispatch }, { payload, newMr }) =>
+ service.commit(state.project.id, payload)
+ .then((data) => {
+ const { branch } = payload;
+ if (!data.short_id) {
+ flash(data.message);
+ return;
+ }
+
+ flash(`Your changes have been committed. Commit ${data.short_id} with ${data.stats.additions} additions, ${data.stats.deletions} deletions.`, 'notice');
+
+ if (newMr) {
+ redirectToUrl(`${state.endpoints.newMergeRequestUrl}${branch}`);
+ } else {
+ commit(types.SET_COMMIT_REF, data.id);
+ dispatch('discardAllChanges');
+ dispatch('closeAllFiles');
+ dispatch('toggleEditMode');
+
+ window.scrollTo(0, 0);
+ }
+ })
+ .catch(() => flash('Error committing changes. Please try again.'));
+
+export const createTempEntry = ({ state, dispatch }, { name, type, content = '', base64 = false }) => {
+ if (type === 'tree') {
+ dispatch('createTempTree', name);
+ } else if (type === 'blob') {
+ dispatch('createTempFile', {
+ tree: state,
+ name,
+ base64,
+ content,
+ });
+ }
+};
+
+export const popHistoryState = ({ state, dispatch, getters }) => {
+ const treeList = getters.treeList;
+ const tree = treeList.find(file => file.url === state.previousUrl);
+
+ if (!tree) return;
+
+ if (tree.type === 'tree') {
+ dispatch('toggleTreeOpen', { endpoint: tree.url, tree });
+ }
+};
+
+export const scrollToTab = () => {
+ Vue.nextTick(() => {
+ const tabs = document.getElementById('tabs');
+
+ if (tabs) {
+ const tabEl = tabs.querySelector('.active .repo-tab');
+
+ tabEl.focus();
+ }
+ });
+};
+
+export * from './actions/tree';
+export * from './actions/file';
+export * from './actions/branch';
diff --git a/app/assets/javascripts/repo/stores/actions/branch.js b/app/assets/javascripts/repo/stores/actions/branch.js
new file mode 100644
index 00000000000..b81a70dfd1e
--- /dev/null
+++ b/app/assets/javascripts/repo/stores/actions/branch.js
@@ -0,0 +1,20 @@
+import service from '../../services';
+import * as types from '../mutation_types';
+import { pushState } from '../utils';
+
+// eslint-disable-next-line import/prefer-default-export
+export const createNewBranch = ({ rootState, commit }, branch) => service.createBranch(
+ rootState.project.id,
+ {
+ branch,
+ ref: rootState.currentBranch,
+ },
+).then(res => res.json())
+.then((data) => {
+ const branchName = data.name;
+ const url = location.href.replace(rootState.currentBranch, branchName);
+
+ pushState(url);
+
+ commit(types.SET_CURRENT_BRANCH, branchName);
+});
diff --git a/app/assets/javascripts/repo/stores/actions/file.js b/app/assets/javascripts/repo/stores/actions/file.js
new file mode 100644
index 00000000000..afbe0b78a82
--- /dev/null
+++ b/app/assets/javascripts/repo/stores/actions/file.js
@@ -0,0 +1,108 @@
+import { normalizeHeaders } from '../../../lib/utils/common_utils';
+import flash from '../../../flash';
+import service from '../../services';
+import * as types from '../mutation_types';
+import {
+ findEntry,
+ pushState,
+ setPageTitle,
+ createTemp,
+ findIndexOfFile,
+} from '../utils';
+
+export const closeFile = ({ commit, state, dispatch }, { file, force = false }) => {
+ if ((file.changed || file.tempFile) && !force) return;
+
+ const indexOfClosedFile = findIndexOfFile(state.openFiles, file);
+ const fileWasActive = file.active;
+
+ commit(types.TOGGLE_FILE_OPEN, file);
+ commit(types.SET_FILE_ACTIVE, { file, active: false });
+
+ if (state.openFiles.length > 0 && fileWasActive) {
+ const nextIndexToOpen = indexOfClosedFile === 0 ? 0 : indexOfClosedFile - 1;
+ const nextFileToOpen = state.openFiles[nextIndexToOpen];
+
+ dispatch('setFileActive', nextFileToOpen);
+ } else if (!state.openFiles.length) {
+ pushState(file.parentTreeUrl);
+ }
+};
+
+export const setFileActive = ({ commit, state, getters, dispatch }, file) => {
+ const currentActiveFile = getters.activeFile;
+
+ if (file.active) return;
+
+ if (currentActiveFile) {
+ commit(types.SET_FILE_ACTIVE, { file: currentActiveFile, active: false });
+ }
+
+ commit(types.SET_FILE_ACTIVE, { file, active: true });
+ dispatch('scrollToTab');
+
+ // reset hash for line highlighting
+ location.hash = '';
+};
+
+export const getFileData = ({ state, commit, dispatch }, file) => {
+ commit(types.TOGGLE_LOADING, file);
+
+ service.getFileData(file.url)
+ .then((res) => {
+ const pageTitle = decodeURI(normalizeHeaders(res.headers)['PAGE-TITLE']);
+
+ setPageTitle(pageTitle);
+
+ return res.json();
+ })
+ .then((data) => {
+ commit(types.SET_FILE_DATA, { data, file });
+ commit(types.TOGGLE_FILE_OPEN, file);
+ dispatch('setFileActive', file);
+ commit(types.TOGGLE_LOADING, file);
+
+ pushState(file.url);
+ })
+ .catch(() => {
+ commit(types.TOGGLE_LOADING, file);
+ flash('Error loading file data. Please try again.');
+ });
+};
+
+export const getRawFileData = ({ commit, dispatch }, file) => service.getRawFileData(file)
+ .then((raw) => {
+ commit(types.SET_FILE_RAW_DATA, { file, raw });
+ })
+ .catch(() => flash('Error loading file content. Please try again.'));
+
+export const changeFileContent = ({ commit }, { file, content }) => {
+ commit(types.UPDATE_FILE_CONTENT, { file, content });
+};
+
+export const createTempFile = ({ state, commit, dispatch }, { tree, name, content = '', base64 = '' }) => {
+ const file = createTemp({
+ name: name.replace(`${state.path}/`, ''),
+ path: tree.path,
+ type: 'blob',
+ level: tree.level !== undefined ? tree.level + 1 : 0,
+ changed: true,
+ content,
+ base64,
+ });
+
+ if (findEntry(tree, 'blob', file.name)) return flash(`The name "${file.name}" is already taken in this directory.`);
+
+ commit(types.CREATE_TMP_FILE, {
+ parent: tree,
+ file,
+ });
+ commit(types.TOGGLE_FILE_OPEN, file);
+ dispatch('setFileActive', file);
+
+ if (!state.editMode && !file.base64) {
+ dispatch('toggleEditMode', true);
+ }
+
+ return Promise.resolve(file);
+};
diff --git a/app/assets/javascripts/repo/stores/actions/tree.js b/app/assets/javascripts/repo/stores/actions/tree.js
new file mode 100644
index 00000000000..129743c66c2
--- /dev/null
+++ b/app/assets/javascripts/repo/stores/actions/tree.js
@@ -0,0 +1,110 @@
+import { normalizeHeaders } from '../../../lib/utils/common_utils';
+import flash from '../../../flash';
+import service from '../../services';
+import * as types from '../mutation_types';
+import {
+ pushState,
+ setPageTitle,
+ findEntry,
+ createTemp,
+} from '../utils';
+
+export const getTreeData = (
+ { commit, state },
+ { endpoint = state.endpoints.rootEndpoint, tree = state } = {},
+) => {
+ commit(types.TOGGLE_LOADING, tree);
+
+ service.getTreeData(endpoint)
+ .then((res) => {
+ const pageTitle = decodeURI(normalizeHeaders(res.headers)['PAGE-TITLE']);
+
+ setPageTitle(pageTitle);
+
+ return res.json();
+ })
+ .then((data) => {
+ if (!state.isInitialRoot) {
+ commit(types.SET_ROOT, data.path === '/');
+ }
+
+ commit(types.SET_DIRECTORY_DATA, { data, tree });
+ commit(types.SET_PARENT_TREE_URL, data.parent_tree_url);
+ commit(types.TOGGLE_LOADING, tree);
+
+ pushState(endpoint);
+ })
+ .catch(() => {
+ flash('Error loading tree data. Please try again.');
+ commit(types.TOGGLE_LOADING, tree);
+ });
+};
+
+export const toggleTreeOpen = ({ commit, dispatch }, { endpoint, tree }) => {
+ if (tree.opened) {
+ // send empty data to clear the tree
+ const data = { trees: [], blobs: [], submodules: [] };
+
+ pushState(tree.parentTreeUrl);
+
+ commit(types.SET_PREVIOUS_URL, tree.parentTreeUrl);
+ commit(types.SET_DIRECTORY_DATA, { data, tree });
+ } else {
+ commit(types.SET_PREVIOUS_URL, endpoint);
+ dispatch('getTreeData', { endpoint, tree });
+ }
+
+ commit(types.TOGGLE_TREE_OPEN, tree);
+};
+
+export const clickedTreeRow = ({ commit, dispatch }, row) => {
+ if (row.type === 'tree') {
+ dispatch('toggleTreeOpen', {
+ endpoint: row.url,
+ tree: row,
+ });
+ } else if (row.type === 'submodule') {
+ commit(types.TOGGLE_LOADING, row);
+
+ gl.utils.visitUrl(row.url);
+ } else if (row.type === 'blob' && row.opened) {
+ dispatch('setFileActive', row);
+ } else {
+ dispatch('getFileData', row);
+ }
+};
+
+export const createTempTree = ({ state, commit, dispatch }, name) => {
+ let tree = state;
+ const dirNames = name.replace(new RegExp(`^${state.path}/`), '').split('/');
+
+ dirNames.forEach((dirName) => {
+ const foundEntry = findEntry(tree, 'tree', dirName);
+
+ if (!foundEntry) {
+ const tmpEntry = createTemp({
+ name: dirName,
+ path: tree.path,
+ type: 'tree',
+ level: tree.level !== undefined ? tree.level + 1 : 0,
+ });
+
+ commit(types.CREATE_TMP_TREE, {
+ parent: tree,
+ tmpEntry,
+ });
+ commit(types.TOGGLE_TREE_OPEN, tmpEntry);
+
+ tree = tmpEntry;
+ } else {
+ tree = foundEntry;
+ }
+ });
+
+ if (tree.tempFile) {
+ dispatch('createTempFile', {
+ tree,
+ name: '.gitkeep',
+ });
+ }
+};
diff --git a/app/assets/javascripts/repo/stores/getters.js b/app/assets/javascripts/repo/stores/getters.js
new file mode 100644
index 00000000000..1ed05ac6e35
--- /dev/null
+++ b/app/assets/javascripts/repo/stores/getters.js
@@ -0,0 +1,36 @@
+import _ from 'underscore';
+
+/*
+ Takes the multi-dimensional tree and returns a flattened array.
+ This allows for the table to recursively render the table rows but keeps the data
+ structure nested to make it easier to add new files/directories.
+*/
+export const treeList = (state) => {
+ const mapTree = arr => (!arr.tree.length ? [] : _.map(arr.tree, a => [a, mapTree(a)]));
+
+ return _.chain(state.tree)
+ .map(arr => [arr, mapTree(arr)])
+ .flatten()
+ .value();
+};
+
+export const changedFiles = state => state.openFiles.filter(file => file.changed);
+
+export const activeFile = state => state.openFiles.find(file => file.active);
+
+export const activeFileExtension = (state) => {
+ const file = activeFile(state);
+ return file ? `.${file.path.split('.').pop()}` : '';
+};
+
+export const isCollapsed = state => !!state.openFiles.length;
+
+export const canEditFile = (state) => {
+ const currentActiveFile = activeFile(state);
+ const openedFiles = state.openFiles;
+
+ return state.canCommit &&
+ state.onTopOfBranch &&
+ openedFiles.length &&
+ (currentActiveFile && !currentActiveFile.renderError && !currentActiveFile.binary);
+};
diff --git a/app/assets/javascripts/repo/stores/index.js b/app/assets/javascripts/repo/stores/index.js
new file mode 100644
index 00000000000..6ac9bfd8189
--- /dev/null
+++ b/app/assets/javascripts/repo/stores/index.js
@@ -0,0 +1,15 @@
+import Vue from 'vue';
+import Vuex from 'vuex';
+import state from './state';
+import * as actions from './actions';
+import * as getters from './getters';
+import mutations from './mutations';
+
+Vue.use(Vuex);
+
+export default new Vuex.Store({
+ state: state(),
+ actions,
+ mutations,
+ getters,
+});
diff --git a/app/assets/javascripts/repo/stores/mutation_types.js b/app/assets/javascripts/repo/stores/mutation_types.js
new file mode 100644
index 00000000000..4722a7dd0df
--- /dev/null
+++ b/app/assets/javascripts/repo/stores/mutation_types.js
@@ -0,0 +1,28 @@
+export const SET_INITIAL_DATA = 'SET_INITIAL_DATA';
+export const TOGGLE_LOADING = 'TOGGLE_LOADING';
+export const SET_COMMIT_REF = 'SET_COMMIT_REF';
+export const SET_PARENT_TREE_URL = 'SET_PARENT_TREE_URL';
+export const SET_ROOT = 'SET_ROOT';
+export const SET_PREVIOUS_URL = 'SET_PREVIOUS_URL';
+
+// Tree mutation types
+export const SET_DIRECTORY_DATA = 'SET_DIRECTORY_DATA';
+export const TOGGLE_TREE_OPEN = 'TOGGLE_TREE_OPEN';
+export const CREATE_TMP_TREE = 'CREATE_TMP_TREE';
+
+// File mutation types
+export const SET_FILE_DATA = 'SET_FILE_DATA';
+export const TOGGLE_FILE_OPEN = 'TOGGLE_FILE_OPEN';
+export const SET_FILE_ACTIVE = 'SET_FILE_ACTIVE';
+export const SET_FILE_RAW_DATA = 'SET_FILE_RAW_DATA';
+export const UPDATE_FILE_CONTENT = 'UPDATE_FILE_CONTENT';
+export const DISCARD_FILE_CHANGES = 'DISCARD_FILE_CHANGES';
+export const CREATE_TMP_FILE = 'CREATE_TMP_FILE';
+
+// Viewer mutation types
+export const SET_PREVIEW_MODE = 'SET_PREVIEW_MODE';
+export const SET_EDIT_MODE = 'SET_EDIT_MODE';
+export const TOGGLE_EDIT_MODE = 'TOGGLE_EDIT_MODE';
+export const TOGGLE_DISCARD_POPUP = 'TOGGLE_DISCARD_POPUP';
+
+export const SET_CURRENT_BRANCH = 'SET_CURRENT_BRANCH';
diff --git a/app/assets/javascripts/repo/stores/mutations.js b/app/assets/javascripts/repo/stores/mutations.js
new file mode 100644
index 00000000000..2f9b038322b
--- /dev/null
+++ b/app/assets/javascripts/repo/stores/mutations.js
@@ -0,0 +1,54 @@
+import * as types from './mutation_types';
+import fileMutations from './mutations/file';
+import treeMutations from './mutations/tree';
+import branchMutations from './mutations/branch';
+
+export default {
+ [types.SET_INITIAL_DATA](state, data) {
+ Object.assign(state, data);
+ },
+ [types.SET_PREVIEW_MODE](state) {
+ Object.assign(state, {
+ currentBlobView: 'repo-preview',
+ });
+ },
+ [types.SET_EDIT_MODE](state) {
+ Object.assign(state, {
+ currentBlobView: 'repo-editor',
+ });
+ },
+ [types.TOGGLE_LOADING](state, entry) {
+ Object.assign(entry, {
+ loading: !entry.loading,
+ });
+ },
+ [types.TOGGLE_EDIT_MODE](state) {
+ Object.assign(state, {
+ editMode: !state.editMode,
+ });
+ },
+ [types.TOGGLE_DISCARD_POPUP](state, discardPopupOpen) {
+ Object.assign(state, {
+ discardPopupOpen,
+ });
+ },
+ [types.SET_COMMIT_REF](state, ref) {
+ Object.assign(state, {
+ currentRef: ref,
+ });
+ },
+ [types.SET_ROOT](state, isRoot) {
+ Object.assign(state, {
+ isRoot,
+ isInitialRoot: isRoot,
+ });
+ },
+ [types.SET_PREVIOUS_URL](state, previousUrl) {
+ Object.assign(state, {
+ previousUrl,
+ });
+ },
+ ...fileMutations,
+ ...treeMutations,
+ ...branchMutations,
+};
diff --git a/app/assets/javascripts/repo/stores/mutations/branch.js b/app/assets/javascripts/repo/stores/mutations/branch.js
new file mode 100644
index 00000000000..d8229e8a620
--- /dev/null
+++ b/app/assets/javascripts/repo/stores/mutations/branch.js
@@ -0,0 +1,9 @@
+import * as types from '../mutation_types';
+
+export default {
+ [types.SET_CURRENT_BRANCH](state, currentBranch) {
+ Object.assign(state, {
+ currentBranch,
+ });
+ },
+};
diff --git a/app/assets/javascripts/repo/stores/mutations/file.js b/app/assets/javascripts/repo/stores/mutations/file.js
new file mode 100644
index 00000000000..f9ba80b9dc2
--- /dev/null
+++ b/app/assets/javascripts/repo/stores/mutations/file.js
@@ -0,0 +1,54 @@
+import * as types from '../mutation_types';
+import { findIndexOfFile } from '../utils';
+
+export default {
+ [types.SET_FILE_ACTIVE](state, { file, active }) {
+ Object.assign(file, {
+ active,
+ });
+ },
+ [types.TOGGLE_FILE_OPEN](state, file) {
+ Object.assign(file, {
+ opened: !file.opened,
+ });
+
+ if (file.opened) {
+ state.openFiles.push(file);
+ } else {
+ state.openFiles.splice(findIndexOfFile(state.openFiles, file), 1);
+ }
+ },
+ [types.SET_FILE_DATA](state, { data, file }) {
+ Object.assign(file, {
+ blamePath: data.blame_path,
+ commitsPath: data.commits_path,
+ permalink: data.permalink,
+ rawPath: data.raw_path,
+ binary: data.binary,
+ html: data.html,
+ renderError: data.render_error,
+ });
+ },
+ [types.SET_FILE_RAW_DATA](state, { file, raw }) {
+ Object.assign(file, {
+ raw,
+ });
+ },
+ [types.UPDATE_FILE_CONTENT](state, { file, content }) {
+ const changed = content !== file.raw;
+
+ Object.assign(file, {
+ content,
+ changed,
+ });
+ },
+ [types.DISCARD_FILE_CHANGES](state, file) {
+ Object.assign(file, {
+ content: '',
+ changed: false,
+ });
+ },
+ [types.CREATE_TMP_FILE](state, { file, parent }) {
+ parent.tree.push(file);
+ },
+};
diff --git a/app/assets/javascripts/repo/stores/mutations/tree.js b/app/assets/javascripts/repo/stores/mutations/tree.js
new file mode 100644
index 00000000000..52be2673107
--- /dev/null
+++ b/app/assets/javascripts/repo/stores/mutations/tree.js
@@ -0,0 +1,45 @@
+import * as types from '../mutation_types';
+import * as utils from '../utils';
+
+export default {
+ [types.TOGGLE_TREE_OPEN](state, tree) {
+ Object.assign(tree, {
+ opened: !tree.opened,
+ });
+ },
+ [types.SET_DIRECTORY_DATA](state, { data, tree }) {
+ const level = tree.level !== undefined ? tree.level + 1 : 0;
+ const parentTreeUrl = data.parent_tree_url ? `${data.parent_tree_url}${data.path}` : state.endpoints.rootUrl;
+
+ Object.assign(tree, {
+ tree: [
+ ...data.trees.map(t => utils.decorateData({
+ ...t,
+ type: 'tree',
+ parentTreeUrl,
+ level,
+ }, state.project.url)),
+ ...data.submodules.map(m => utils.decorateData({
+ ...m,
+ type: 'submodule',
+ parentTreeUrl,
+ level,
+ }, state.project.url)),
+ ...data.blobs.map(b => utils.decorateData({
+ ...b,
+ type: 'blob',
+ parentTreeUrl,
+ level,
+ }, state.project.url)),
+ ],
+ });
+ },
+ [types.SET_PARENT_TREE_URL](state, url) {
+ Object.assign(state, {
+ parentTreeUrl: url,
+ });
+ },
+ [types.CREATE_TMP_TREE](state, { parent, tmpEntry }) {
+ parent.tree.push(tmpEntry);
+ },
+};
diff --git a/app/assets/javascripts/repo/stores/repo_store.js b/app/assets/javascripts/repo/stores/repo_store.js
deleted file mode 100644
index 49d7317a17e..00000000000
--- a/app/assets/javascripts/repo/stores/repo_store.js
+++ /dev/null
@@ -1,180 +0,0 @@
-import Helper from '../helpers/repo_helper';
-import Service from '../services/repo_service';
-
-const RepoStore = {
- monacoLoading: false,
- service: '',
- canCommit: false,
- onTopOfBranch: false,
- editMode: false,
- isRoot: null,
- isInitialRoot: null,
- prevURL: '',
- projectId: '',
- projectName: '',
- projectUrl: '',
- blobRaw: '',
- currentBlobView: 'repo-preview',
- openedFiles: [],
- submitCommitsLoading: false,
- dialog: {
- open: false,
- title: '',
- status: false,
- },
- showNewBranchDialog: false,
- activeFile: Helper.getDefaultActiveFile(),
- activeFileIndex: 0,
- activeLine: -1,
- activeFileLabel: 'Raw',
- files: [],
- isCommitable: false,
- binary: false,
- currentBranch: '',
- startNewMR: false,
- currentHash: '',
- currentShortHash: '',
- customBranchURL: '',
- newMrTemplateUrl: '',
- branchChanged: false,
- commitMessage: '',
- loading: {
- tree: false,
- blob: false,
- },
-
- setBranchHash() {
- return Service.getBranch()
- .then((data) => {
- if (RepoStore.currentHash !== '' && data.commit.id !== RepoStore.currentHash) {
- RepoStore.branchChanged = true;
- }
- RepoStore.currentHash = data.commit.id;
- RepoStore.currentShortHash = data.commit.short_id;
- });
- },
-
- // mutations
- checkIsCommitable() {
- RepoStore.isCommitable = RepoStore.onTopOfBranch && RepoStore.canCommit;
- },
-
- toggleRawPreview() {
- RepoStore.activeFile.raw = !RepoStore.activeFile.raw;
- RepoStore.activeFileLabel = RepoStore.activeFile.raw ? 'Display rendered file' : 'Display source';
- },
-
- setActiveFiles(file) {
- if (RepoStore.isActiveFile(file)) return;
- RepoStore.openedFiles = RepoStore.openedFiles
- .map((openedFile, i) => RepoStore.setFileActivity(file, openedFile, i));
-
- RepoStore.setActiveToRaw();
-
- if (file.binary) {
- RepoStore.blobRaw = file.base64;
- } else if (file.newContent || file.plain) {
- RepoStore.blobRaw = file.newContent || file.plain;
- } else {
- Service.getRaw(file.raw_path)
- .then((rawResponse) => {
- RepoStore.blobRaw = rawResponse.data;
- Helper.findOpenedFileFromActive().plain = rawResponse.data;
- }).catch(Helper.loadingError);
- }
-
- if (!file.loading) Helper.updateHistoryEntry(file.url, file.pageTitle || file.name);
- RepoStore.binary = file.binary;
- RepoStore.setActiveLine(-1);
- },
-
- setFileActivity(file, openedFile, i) {
- const activeFile = openedFile;
- activeFile.active = file.url === activeFile.url;
-
- if (activeFile.active) RepoStore.setActiveFile(activeFile, i);
-
- return activeFile;
- },
-
- setActiveFile(activeFile, i) {
- RepoStore.activeFile = Object.assign({}, RepoStore.activeFile, activeFile);
- RepoStore.activeFileIndex = i;
- },
-
- setActiveLine(activeLine) {
- if (!isNaN(activeLine)) RepoStore.activeLine = activeLine;
- },
-
- setActiveToRaw() {
- RepoStore.activeFile.raw = false;
- // can't get vue to listen to raw for some reason so RepoStore for now.
- RepoStore.activeFileLabel = 'Display source';
- },
-
- removeFromOpenedFiles(file) {
- if (file.type === 'tree') return;
- let foundIndex;
- RepoStore.openedFiles = RepoStore.openedFiles.filter((openedFile, i) => {
- if (openedFile.path === file.path) foundIndex = i;
- return openedFile.path !== file.path;
- });
-
- // now activate the right tab based on what you closed.
- if (RepoStore.openedFiles.length === 0) {
- RepoStore.activeFile = {};
- return;
- }
-
- if (RepoStore.openedFiles.length === 1 || foundIndex === 0) {
- RepoStore.setActiveFiles(RepoStore.openedFiles[0]);
- return;
- }
-
- if (foundIndex && foundIndex > 0) {
- RepoStore.setActiveFiles(RepoStore.openedFiles[foundIndex - 1]);
- }
- },
-
- addToOpenedFiles(file) {
- const openFile = file;
-
- const openedFilesAlreadyExists = RepoStore.openedFiles
- .some(openedFile => openedFile.path === openFile.path);
-
- if (openedFilesAlreadyExists) return;
-
- openFile.changed = false;
- openFile.active = true;
- RepoStore.openedFiles.push(openFile);
- },
-
- setActiveFileContents(contents) {
- if (!RepoStore.editMode) return;
- const currentFile = RepoStore.openedFiles[RepoStore.activeFileIndex];
- RepoStore.activeFile.newContent = contents;
- RepoStore.activeFile.changed = RepoStore.activeFile.plain !== RepoStore.activeFile.newContent;
- currentFile.changed = RepoStore.activeFile.changed;
- currentFile.newContent = contents;
- },
-
- toggleBlobView() {
- RepoStore.currentBlobView = RepoStore.isPreviewView() ? 'repo-editor' : 'repo-preview';
- },
-
- setViewToPreview() {
- RepoStore.currentBlobView = 'repo-preview';
- },
-
- // getters
-
- isActiveFile(file) {
- return file && file.url === RepoStore.activeFile.url;
- },
-
- isPreviewView() {
- return RepoStore.currentBlobView === 'repo-preview';
- },
-};
-
-export default RepoStore;
diff --git a/app/assets/javascripts/repo/stores/state.js b/app/assets/javascripts/repo/stores/state.js
new file mode 100644
index 00000000000..aab74754f02
--- /dev/null
+++ b/app/assets/javascripts/repo/stores/state.js
@@ -0,0 +1,23 @@
+export default () => ({
+ canCommit: false,
+ currentBranch: '',
+ currentBlobView: 'repo-preview',
+ currentRef: '',
+ discardPopupOpen: false,
+ editMode: false,
+ endpoints: {},
+ isRoot: false,
+ isInitialRoot: false,
+ loading: false,
+ onTopOfBranch: false,
+ openFiles: [],
+ path: '',
+ project: {
+ id: 0,
+ name: '',
+ url: '',
+ },
+ parentTreeUrl: '',
+ previousUrl: '',
+ tree: [],
+});
diff --git a/app/assets/javascripts/repo/stores/utils.js b/app/assets/javascripts/repo/stores/utils.js
new file mode 100644
index 00000000000..797c2b1e5b9
--- /dev/null
+++ b/app/assets/javascripts/repo/stores/utils.js
@@ -0,0 +1,108 @@
+export const dataStructure = () => ({
+ id: '',
+ type: '',
+ name: '',
+ url: '',
+ path: '',
+ level: 0,
+ tempFile: false,
+ icon: '',
+ tree: [],
+ loading: false,
+ opened: false,
+ active: false,
+ changed: false,
+ lastCommit: {},
+ tree_url: '',
+ blamePath: '',
+ commitsPath: '',
+ permalink: '',
+ rawPath: '',
+ binary: false,
+ html: '',
+ raw: '',
+ content: '',
+ parentTreeUrl: '',
+ renderError: false,
+ base64: false,
+});
+
+export const decorateData = (entity, projectUrl = '') => {
+ const {
+ id,
+ type,
+ url,
+ name,
+ icon,
+ last_commit,
+ tree_url,
+ path,
+ renderError,
+ content = '',
+ tempFile = false,
+ active = false,
+ opened = false,
+ changed = false,
+ parentTreeUrl = '',
+ level = 0,
+ base64 = false,
+ } = entity;
+
+ return {
+ ...dataStructure(),
+ id,
+ type,
+ name,
+ url,
+ tree_url,
+ path,
+ level,
+ tempFile,
+ icon: `fa-${icon}`,
+ opened,
+ active,
+ parentTreeUrl,
+ changed,
+ renderError,
+ content,
+ base64,
+ // eslint-disable-next-line camelcase
+ lastCommit: last_commit ? {
+ url: `${projectUrl}/commit/${last_commit.id}`,
+ message: last_commit.message,
+ updatedAt: last_commit.committed_date,
+ } : {},
+ };
+};
+
+export const findEntry = (state, type, name) => state.tree.find(
+ f => f.type === type && f.name === name,
+);
+export const findIndexOfFile = (state, file) => state.findIndex(f => f.path === file.path);
+
+export const setPageTitle = (title) => {
+ document.title = title;
+};
+
+export const pushState = (url) => {
+ history.pushState({ url }, '', url);
+};
+
+export const createTemp = ({ name, path, type, level, changed, content, base64 }) => {
+ const treePath = path ? `${path}/${name}` : name;
+
+ return decorateData({
+ id: new Date().getTime().toString(),
+ name,
+ type,
+ tempFile: true,
+ path: treePath,
+ icon: type === 'tree' ? 'folder' : 'file-text-o',
+ changed,
+ content,
+ parentTreeUrl: '',
+ level,
+ base64,
+ renderError: base64,
+ });
+};
diff --git a/app/assets/javascripts/sidebar/components/participants/participants.vue b/app/assets/javascripts/sidebar/components/participants/participants.vue
new file mode 100644
index 00000000000..b8510a6ce3a
--- /dev/null
+++ b/app/assets/javascripts/sidebar/components/participants/participants.vue
@@ -0,0 +1,125 @@
+<script>
+import { __, n__, sprintf } from '../../../locale';
+import loadingIcon from '../../../vue_shared/components/loading_icon.vue';
+import userAvatarImage from '../../../vue_shared/components/user_avatar/user_avatar_image.vue';
+
+export default {
+ props: {
+ loading: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ participants: {
+ type: Array,
+ required: false,
+ default: () => [],
+ },
+ numberOfLessParticipants: {
+ type: Number,
+ required: false,
+ default: 7,
+ },
+ },
+ data() {
+ return {
+ isShowingMoreParticipants: false,
+ };
+ },
+ components: {
+ loadingIcon,
+ userAvatarImage,
+ },
+ computed: {
+ lessParticipants() {
+ return this.participants.slice(0, this.numberOfLessParticipants);
+ },
+ visibleParticipants() {
+ return this.isShowingMoreParticipants ? this.participants : this.lessParticipants;
+ },
+ hasMoreParticipants() {
+ return this.participants.length > this.numberOfLessParticipants;
+ },
+ toggleLabel() {
+ let label = '';
+ if (this.isShowingMoreParticipants) {
+ label = __('- show less');
+ } else {
+ label = sprintf(__('+ %{moreCount} more'), {
+ moreCount: this.participants.length - this.numberOfLessParticipants,
+ });
+ }
+
+ return label;
+ },
+ participantLabel() {
+ return sprintf(
+ n__('%{count} participant', '%{count} participants', this.participants.length),
+ { count: this.loading ? '' : this.participantCount },
+ );
+ },
+ participantCount() {
+ return this.participants.length;
+ },
+ },
+ methods: {
+ toggleMoreParticipants() {
+ this.isShowingMoreParticipants = !this.isShowingMoreParticipants;
+ },
+ },
+};
+</script>
+
+<template>
+ <div>
+ <div class="sidebar-collapsed-icon">
+ <i
+ class="fa fa-users"
+ aria-hidden="true">
+ </i>
+ <loading-icon
+ v-if="loading"
+ class="js-participants-collapsed-loading-icon" />
+ <span
+ v-else
+ class="js-participants-collapsed-count">
+ {{ participantCount }}
+ </span>
+ </div>
+ <div class="title hide-collapsed">
+ <loading-icon
+ v-if="loading"
+ :inline="true"
+ class="js-participants-expanded-loading-icon" />
+ {{ participantLabel }}
+ </div>
+ <div class="participants-list hide-collapsed">
+ <div
+ v-for="participant in visibleParticipants"
+ :key="participant.id"
+ class="participants-author js-participants-author">
+ <a
+ class="author_link"
+ :href="participant.web_url">
+ <user-avatar-image
+ :lazy="true"
+ :img-src="participant.avatar_url"
+ css-classes="avatar-inline"
+ :size="24"
+ :tooltip-text="participant.name"
+ tooltip-placement="bottom" />
+ </a>
+ </div>
+ </div>
+ <div
+ v-if="hasMoreParticipants"
+ class="participants-more hide-collapsed">
+ <button
+ type="button"
+ class="btn-transparent btn-blank js-toggle-participants-button"
+ @click="toggleMoreParticipants">
+ {{ toggleLabel }}
+ </button>
+ </div>
+ </div>
+</template>
diff --git a/app/assets/javascripts/sidebar/components/participants/sidebar_participants.vue b/app/assets/javascripts/sidebar/components/participants/sidebar_participants.vue
new file mode 100644
index 00000000000..c1296b28db7
--- /dev/null
+++ b/app/assets/javascripts/sidebar/components/participants/sidebar_participants.vue
@@ -0,0 +1,26 @@
+<script>
+import Store from '../../stores/sidebar_store';
+import Mediator from '../../sidebar_mediator';
+import participants from './participants.vue';
+
+export default {
+ data() {
+ return {
+ mediator: new Mediator(),
+ store: new Store(),
+ };
+ },
+ components: {
+ participants,
+ },
+};
+</script>
+
+<template>
+ <div class="block participants">
+ <participants
+ :loading="store.isFetching.participants"
+ :participants="store.participants"
+ :number-of-less-participants="7" />
+ </div>
+</template>
diff --git a/app/assets/javascripts/sidebar/components/subscriptions/sidebar_subscriptions.vue b/app/assets/javascripts/sidebar/components/subscriptions/sidebar_subscriptions.vue
new file mode 100644
index 00000000000..4ad3d469f25
--- /dev/null
+++ b/app/assets/javascripts/sidebar/components/subscriptions/sidebar_subscriptions.vue
@@ -0,0 +1,45 @@
+<script>
+import Store from '../../stores/sidebar_store';
+import Mediator from '../../sidebar_mediator';
+import eventHub from '../../event_hub';
+import Flash from '../../../flash';
+import subscriptions from './subscriptions.vue';
+
+export default {
+ data() {
+ return {
+ mediator: new Mediator(),
+ store: new Store(),
+ };
+ },
+
+ components: {
+ subscriptions,
+ },
+
+ methods: {
+ onToggleSubscription() {
+ this.mediator.toggleSubscription()
+ .catch(() => {
+ Flash('Error occurred when toggling the notification subscription');
+ });
+ },
+ },
+
+ created() {
+ eventHub.$on('toggleSubscription', this.onToggleSubscription);
+ },
+
+ beforeDestroy() {
+ eventHub.$off('toggleSubscription', this.onToggleSubscription);
+ },
+};
+</script>
+
+<template>
+ <div class="block subscriptions">
+ <subscriptions
+ :loading="store.isFetching.subscriptions"
+ :subscribed="store.subscribed" />
+ </div>
+</template>
diff --git a/app/assets/javascripts/sidebar/components/subscriptions/subscriptions.vue b/app/assets/javascripts/sidebar/components/subscriptions/subscriptions.vue
new file mode 100644
index 00000000000..a3a8213d63a
--- /dev/null
+++ b/app/assets/javascripts/sidebar/components/subscriptions/subscriptions.vue
@@ -0,0 +1,60 @@
+<script>
+import { __ } from '../../../locale';
+import eventHub from '../../event_hub';
+import loadingButton from '../../../vue_shared/components/loading_button.vue';
+
+export default {
+ props: {
+ loading: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ subscribed: {
+ type: Boolean,
+ required: false,
+ },
+ },
+ components: {
+ loadingButton,
+ },
+ computed: {
+ buttonLabel() {
+ let label;
+ if (this.subscribed === false) {
+ label = __('Subscribe');
+ } else if (this.subscribed === true) {
+ label = __('Unsubscribe');
+ }
+
+ return label;
+ },
+ },
+ methods: {
+ toggleSubscription() {
+ eventHub.$emit('toggleSubscription');
+ },
+ },
+};
+</script>
+
+<template>
+ <div>
+ <div class="sidebar-collapsed-icon">
+ <i
+ class="fa fa-rss"
+ aria-hidden="true">
+ </i>
+ </div>
+ <span class="issuable-header-text hide-collapsed pull-left">
+ {{ __('Notifications') }}
+ </span>
+ <loading-button
+ ref="loadingButton"
+ class="btn btn-default pull-right hide-collapsed js-issuable-subscribe-button"
+ :loading="loading"
+ :label="buttonLabel"
+ @click="toggleSubscription"
+ />
+ </div>
+</template>
diff --git a/app/assets/javascripts/sidebar/services/sidebar_service.js b/app/assets/javascripts/sidebar/services/sidebar_service.js
index 604648407a4..37c97225bfd 100644
--- a/app/assets/javascripts/sidebar/services/sidebar_service.js
+++ b/app/assets/javascripts/sidebar/services/sidebar_service.js
@@ -7,6 +7,7 @@ export default class SidebarService {
constructor(endpointMap) {
if (!SidebarService.singleton) {
this.endpoint = endpointMap.endpoint;
+ this.toggleSubscriptionEndpoint = endpointMap.toggleSubscriptionEndpoint;
this.moveIssueEndpoint = endpointMap.moveIssueEndpoint;
this.projectsAutocompleteEndpoint = endpointMap.projectsAutocompleteEndpoint;
@@ -36,6 +37,10 @@ export default class SidebarService {
});
}
+ toggleSubscription() {
+ return Vue.http.post(this.toggleSubscriptionEndpoint);
+ }
+
moveIssue(moveToProjectId) {
return Vue.http.post(this.moveIssueEndpoint, {
move_to_project_id: moveToProjectId,
diff --git a/app/assets/javascripts/sidebar/sidebar_bundle.js b/app/assets/javascripts/sidebar/sidebar_bundle.js
index 09b9d75c02d..2650bb725d4 100644
--- a/app/assets/javascripts/sidebar/sidebar_bundle.js
+++ b/app/assets/javascripts/sidebar/sidebar_bundle.js
@@ -4,6 +4,8 @@ import SidebarAssignees from './components/assignees/sidebar_assignees';
import ConfidentialIssueSidebar from './components/confidential/confidential_issue_sidebar.vue';
import SidebarMoveIssue from './lib/sidebar_move_issue';
import LockIssueSidebar from './components/lock/lock_issue_sidebar.vue';
+import sidebarParticipants from './components/participants/sidebar_participants.vue';
+import sidebarSubscriptions from './components/subscriptions/sidebar_subscriptions.vue';
import Translate from '../vue_shared/translate';
import Mediator from './sidebar_mediator';
@@ -49,6 +51,36 @@ function mountLockComponent(mediator) {
}).$mount(el);
}
+function mountParticipantsComponent() {
+ const el = document.querySelector('.js-sidebar-participants-entry-point');
+
+ if (!el) return;
+
+ // eslint-disable-next-line no-new
+ new Vue({
+ el,
+ components: {
+ sidebarParticipants,
+ },
+ render: createElement => createElement('sidebar-participants', {}),
+ });
+}
+
+function mountSubscriptionsComponent() {
+ const el = document.querySelector('.js-sidebar-subscriptions-entry-point');
+
+ if (!el) return;
+
+ // eslint-disable-next-line no-new
+ new Vue({
+ el,
+ components: {
+ sidebarSubscriptions,
+ },
+ render: createElement => createElement('sidebar-subscriptions', {}),
+ });
+}
+
function domContentLoaded() {
const sidebarOptions = JSON.parse(document.querySelector('.js-sidebar-options').innerHTML);
const mediator = new Mediator(sidebarOptions);
@@ -63,6 +95,8 @@ function domContentLoaded() {
mountConfidentialComponent(mediator);
mountLockComponent(mediator);
+ mountParticipantsComponent();
+ mountSubscriptionsComponent();
new SidebarMoveIssue(
mediator,
diff --git a/app/assets/javascripts/sidebar/sidebar_mediator.js b/app/assets/javascripts/sidebar/sidebar_mediator.js
index ede3a0de144..2bda5a47791 100644
--- a/app/assets/javascripts/sidebar/sidebar_mediator.js
+++ b/app/assets/javascripts/sidebar/sidebar_mediator.js
@@ -8,6 +8,7 @@ export default class SidebarMediator {
this.store = new Store(options);
this.service = new Service({
endpoint: options.endpoint,
+ toggleSubscriptionEndpoint: options.toggleSubscriptionEndpoint,
moveIssueEndpoint: options.moveIssueEndpoint,
projectsAutocompleteEndpoint: options.projectsAutocompleteEndpoint,
});
@@ -39,10 +40,25 @@ export default class SidebarMediator {
.then((data) => {
this.store.setAssigneeData(data);
this.store.setTimeTrackingData(data);
+ this.store.setParticipantsData(data);
+ this.store.setSubscriptionsData(data);
})
.catch(() => new Flash('Error occurred when fetching sidebar data'));
}
+ toggleSubscription() {
+ this.store.setFetchingState('subscriptions', true);
+ return this.service.toggleSubscription()
+ .then(() => {
+ this.store.setSubscribedState(!this.store.subscribed);
+ this.store.setFetchingState('subscriptions', false);
+ })
+ .catch((err) => {
+ this.store.setFetchingState('subscriptions', false);
+ throw err;
+ });
+ }
+
fetchAutocompleteProjects(searchTerm) {
return this.service.getProjectsAutocomplete(searchTerm)
.then(response => response.json())
diff --git a/app/assets/javascripts/sidebar/stores/sidebar_store.js b/app/assets/javascripts/sidebar/stores/sidebar_store.js
index d5d04103f3f..3150221b685 100644
--- a/app/assets/javascripts/sidebar/stores/sidebar_store.js
+++ b/app/assets/javascripts/sidebar/stores/sidebar_store.js
@@ -12,10 +12,14 @@ export default class SidebarStore {
this.assignees = [];
this.isFetching = {
assignees: true,
+ participants: true,
+ subscriptions: true,
};
this.autocompleteProjects = [];
this.moveToProjectId = 0;
this.isLockDialogOpen = false;
+ this.participants = [];
+ this.subscribed = null;
SidebarStore.singleton = this;
}
@@ -37,6 +41,20 @@ export default class SidebarStore {
this.humanTotalTimeSpent = data.human_total_time_spent;
}
+ setParticipantsData(data) {
+ this.isFetching.participants = false;
+ this.participants = data.participants || [];
+ }
+
+ setSubscriptionsData(data) {
+ this.isFetching.subscriptions = false;
+ this.subscribed = data.subscribed || false;
+ }
+
+ setFetchingState(key, value) {
+ this.isFetching[key] = value;
+ }
+
addAssignee(assignee) {
if (!this.findAssignee(assignee)) {
this.assignees.push(assignee);
@@ -61,6 +79,10 @@ export default class SidebarStore {
this.autocompleteProjects = projects;
}
+ setSubscribedState(subscribed) {
+ this.subscribed = subscribed;
+ }
+
setMoveToProjectId(moveToProjectId) {
this.moveToProjectId = moveToProjectId;
}
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_ready_to_merge.js b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_ready_to_merge.js
index b8a96b23012..be37dd87de9 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_ready_to_merge.js
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_ready_to_merge.js
@@ -286,6 +286,7 @@ export default {
<input
id="remove-source-branch-input"
v-model="removeSourceBranch"
+ class="js-remove-source-branch-checkbox"
:disabled="isRemoveSourceBranchButtonDisabled"
type="checkbox"/> Remove source branch
</label>
@@ -311,8 +312,8 @@ export default {
</button>
</template>
<template v-else>
- <span class="bold">
- The pipeline for this merge request has not succeeded yet
+ <span class="bold js-resolve-mr-widget-items-message">
+ You can only merge once the items above are resolved
</span>
</template>
</div>
diff --git a/app/assets/javascripts/vue_merge_request_widget/services/mr_widget_service.js b/app/assets/javascripts/vue_merge_request_widget/services/mr_widget_service.js
index 79c3d335679..99f5c305df5 100644
--- a/app/assets/javascripts/vue_merge_request_widget/services/mr_widget_service.js
+++ b/app/assets/javascripts/vue_merge_request_widget/services/mr_widget_service.js
@@ -11,7 +11,7 @@ export default class MRWidgetService {
this.removeWIPResource = Vue.resource(endpoints.removeWIPPath);
this.removeSourceBranchResource = Vue.resource(endpoints.sourceBranchPath);
this.deploymentsResource = Vue.resource(endpoints.ciEnvironmentsStatusPath);
- this.pollResource = Vue.resource(`${endpoints.statusPath}?basic=true`);
+ this.pollResource = Vue.resource(`${endpoints.statusPath}?serializer=basic`);
this.mergeActionsContentResource = Vue.resource(endpoints.mergeActionsContentPath);
}
diff --git a/app/assets/javascripts/vue_shared/components/ci_badge_link.vue b/app/assets/javascripts/vue_shared/components/ci_badge_link.vue
index caa28bff6db..5b6c6e8d0b9 100644
--- a/app/assets/javascripts/vue_shared/components/ci_badge_link.vue
+++ b/app/assets/javascripts/vue_shared/components/ci_badge_link.vue
@@ -1,52 +1,64 @@
<script>
-import ciIcon from './ci_icon.vue';
-/**
- * Renders CI Badge link with CI icon and status text based on
- * API response shared between all places where it is used.
- *
- * Receives status object containing:
- * status: {
- * details_path: "/gitlab-org/gitlab-ce/pipelines/8150156" // url
- * group:"running" // used for CSS class
- * icon: "icon_status_running" // used to render the icon
- * label:"running" // used for potential tooltip
- * text:"running" // text rendered
- * }
- *
- * Used in:
- * - Pipelines table - first column
- * - Jobs table - first column
- * - Pipeline show view - header
- * - Job show view - header
- * - MR widget
- */
+ import ciIcon from './ci_icon.vue';
+ import tooltip from '../directives/tooltip';
+ /**
+ * Renders CI Badge link with CI icon and status text based on
+ * API response shared between all places where it is used.
+ *
+ * Receives status object containing:
+ * status: {
+ * details_path: "/gitlab-org/gitlab-ce/pipelines/8150156" // url
+ * group:"running" // used for CSS class
+ * icon: "icon_status_running" // used to render the icon
+ * label:"running" // used for potential tooltip
+ * text:"running" // text rendered
+ * }
+ *
+ * Used in:
+ * - Pipelines table - first column
+ * - Jobs table - first column
+ * - Pipeline show view - header
+ * - Job show view - header
+ * - MR widget
+ */
-export default {
- props: {
- status: {
- type: Object,
- required: true,
+ export default {
+ props: {
+ status: {
+ type: Object,
+ required: true,
+ },
+ showText: {
+ type: Boolean,
+ required: false,
+ default: true,
+ },
},
- },
-
- components: {
- ciIcon,
- },
-
- computed: {
- cssClass() {
- const className = this.status.group;
+ components: {
+ ciIcon,
+ },
+ directives: {
+ tooltip,
+ },
+ computed: {
+ cssClass() {
+ const className = this.status.group;
- return className ? `ci-status ci-${this.status.group}` : 'ci-status';
+ return className ? `ci-status ci-${className}` : 'ci-status';
+ },
},
- },
-};
+ };
</script>
<template>
<a
:href="status.details_path"
- :class="cssClass">
+ :class="cssClass"
+ v-tooltip
+ :title="!showText ? status.text : ''">
<ci-icon :status="status" />
- {{status.text}}
+
+ <template v-if="showText">
+ {{status.text}}
+ </template>
</a>
</template>
diff --git a/app/assets/javascripts/vue_shared/components/commit.vue b/app/assets/javascripts/vue_shared/components/commit.vue
index 50d14282cad..52814de8b2d 100644
--- a/app/assets/javascripts/vue_shared/components/commit.vue
+++ b/app/assets/javascripts/vue_shared/components/commit.vue
@@ -63,14 +63,17 @@
required: false,
default: () => ({}),
},
+ showBranch: {
+ type: Boolean,
+ required: false,
+ default: true,
+ },
},
computed: {
/**
* Used to verify if all the properties needed to render the commit
* ref section were provided.
*
- * TODO: Improve this! Use lodash _.has when we have it.
- *
* @returns {Boolean}
*/
hasCommitRef() {
@@ -80,8 +83,6 @@
* Used to verify if all the properties needed to render the commit
* author section were provided.
*
- * TODO: Improve this! Use lodash _.has when we have it.
- *
* @returns {Boolean}
*/
hasAuthor() {
@@ -114,31 +115,30 @@
</script>
<template>
<div class="branch-commit">
- <div
- v-if="hasCommitRef"
- class="icon-container hidden-xs">
- <i
- v-if="tag"
- class="fa fa-tag"
- aria-hidden="true">
- </i>
- <i
- v-if="!tag"
- class="fa fa-code-fork"
- aria-hidden="true">
- </i>
- </div>
-
- <a
- v-if="hasCommitRef"
- class="ref-name hidden-xs"
- :href="commitRef.ref_url"
- v-tooltip
- data-container="body"
- :title="commitRef.name">
- {{commitRef.name}}
- </a>
+ <template v-if="hasCommitRef && showBranch">
+ <div
+ class="icon-container hidden-xs">
+ <i
+ v-if="tag"
+ class="fa fa-tag"
+ aria-hidden="true">
+ </i>
+ <i
+ v-if="!tag"
+ class="fa fa-code-fork"
+ aria-hidden="true">
+ </i>
+ </div>
+ <a
+ class="ref-name hidden-xs"
+ :href="commitRef.ref_url"
+ v-tooltip
+ data-container="body"
+ :title="commitRef.name">
+ {{commitRef.name}}
+ </a>
+ </template>
<div
v-html="commitIconSvg"
class="commit-icon js-commit-icon">
diff --git a/app/assets/javascripts/vue_shared/components/loading_button.vue b/app/assets/javascripts/vue_shared/components/loading_button.vue
new file mode 100644
index 00000000000..6670b554faf
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/components/loading_button.vue
@@ -0,0 +1,71 @@
+<script>
+
+/* This is a re-usable vue component for rendering a button
+ that will probably be sending off ajax requests and need
+ to show the loading status by setting the `loading` option.
+ This can also be used for initial page load when you don't
+ know the action of the button yet by setting
+ `loading: true, label: undefined`.
+
+ Sample configuration:
+
+ <loading-button
+ :loading="true"
+ :label="Hello"
+ @click="..."
+ />
+
+*/
+
+import loadingIcon from './loading_icon.vue';
+
+export default {
+ props: {
+ loading: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ label: {
+ type: String,
+ required: false,
+ },
+ },
+ components: {
+ loadingIcon,
+ },
+ methods: {
+ onClick(e) {
+ this.$emit('click', e);
+ },
+ },
+};
+</script>
+
+<template>
+ <button
+ class="btn btn-align-content"
+ @click="onClick"
+ type="button"
+ :disabled="loading"
+ >
+ <transition name="fade">
+ <loading-icon
+ v-if="loading"
+ :inline="true"
+ class="js-loading-button-icon"
+ :class="{
+ 'append-right-5': label
+ }"
+ />
+ </transition>
+ <transition name="fade">
+ <span
+ v-if="label"
+ class="js-loading-button-label"
+ >
+ {{ label }}
+ </span>
+ </transition>
+ </button>
+</template>
diff --git a/app/assets/javascripts/notes/components/issue_placeholder_note.vue b/app/assets/javascripts/vue_shared/components/notes/placeholder_note.vue
index 6921d91372f..e467ca56704 100644
--- a/app/assets/javascripts/notes/components/issue_placeholder_note.vue
+++ b/app/assets/javascripts/vue_shared/components/notes/placeholder_note.vue
@@ -1,9 +1,26 @@
<script>
+ /**
+ * Common component to render a placeholder note and user information.
+ *
+ * This component needs to be used with a vuex store.
+ * That vuex store needs to have a `getUserData` getter that contains
+ * {
+ * path: String,
+ * avatar_url: String,
+ * name: String,
+ * username: String,
+ * }
+ *
+ * @example
+ * <placeholder-note
+ * :note="{body: 'This is a note'}"
+ * />
+ */
import { mapGetters } from 'vuex';
- import userAvatarLink from '../../vue_shared/components/user_avatar/user_avatar_link.vue';
+ import userAvatarLink from '../user_avatar/user_avatar_link.vue';
export default {
- name: 'issuePlaceholderNote',
+ name: 'placeholderNote',
props: {
note: {
type: Object,
diff --git a/app/assets/javascripts/notes/components/issue_placeholder_system_note.vue b/app/assets/javascripts/vue_shared/components/notes/placeholder_system_note.vue
index 80a8ef56a83..d805fea8006 100644
--- a/app/assets/javascripts/notes/components/issue_placeholder_system_note.vue
+++ b/app/assets/javascripts/vue_shared/components/notes/placeholder_system_note.vue
@@ -1,4 +1,12 @@
<script>
+ /**
+ * Common component to render a placeholder system note.
+ *
+ * @example
+ * <placeholder-system-note
+ * :note="{ body: 'Commands are being applied'}"
+ * />
+ */
export default {
name: 'placeholderSystemNote',
props: {
diff --git a/app/assets/javascripts/notes/components/issue_system_note.vue b/app/assets/javascripts/vue_shared/components/notes/system_note.vue
index 0cfb6522e77..98f8f32557d 100644
--- a/app/assets/javascripts/notes/components/issue_system_note.vue
+++ b/app/assets/javascripts/vue_shared/components/notes/system_note.vue
@@ -1,6 +1,24 @@
<script>
+ /**
+ * Common component to render a system note, icon and user information.
+ *
+ * This component needs to be used with a vuex store.
+ * That vuex store needs to have a `targetNoteHash` getter
+ *
+ * @example
+ * <system-note
+ * :note="{
+ * id: String,
+ * author: Object,
+ * createdAt: String,
+ * note_html: String,
+ * system_note_icon_name: String
+ * }"
+ * />
+ */
import { mapGetters } from 'vuex';
- import issueNoteHeader from './issue_note_header.vue';
+ import issueNoteHeader from '../../../notes/components/issue_note_header.vue';
+ import { spriteIcon } from '../../../lib/utils/common_utils';
export default {
name: 'systemNote',
@@ -24,7 +42,7 @@
return this.targetNoteHash === this.noteAnchorId;
},
iconHtml() {
- return gl.utils.spriteIcon(this.note.system_note_icon_name);
+ return spriteIcon(this.note.system_note_icon_name);
},
},
};
@@ -46,7 +64,8 @@
:author="note.author"
:created-at="note.created_at"
:note-id="note.id"
- :action-text-html="note.note_html" />
+ :action-text-html="note.note_html"
+ />
</div>
</div>
</div>
diff --git a/app/assets/javascripts/vue_shared/components/popup_dialog.vue b/app/assets/javascripts/vue_shared/components/popup_dialog.vue
index 7d8c5936b7d..9e8c10bdc1a 100644
--- a/app/assets/javascripts/vue_shared/components/popup_dialog.vue
+++ b/app/assets/javascripts/vue_shared/components/popup_dialog.vue
@@ -9,7 +9,7 @@ export default {
},
text: {
type: String,
- required: true,
+ required: false,
},
kind: {
type: String,
@@ -82,14 +82,15 @@ export default {
type="button"
class="btn"
:class="btnCancelKindClass"
- @click="emitSubmit(false)">
- {{closeButtonLabel}}
+ @click="close">
+ {{ closeButtonLabel }}
</button>
- <button type="button"
+ <button
+ type="button"
class="btn"
:class="btnKindClass"
@click="emitSubmit(true)">
- {{primaryButtonLabel}}
+ {{ primaryButtonLabel }}
</button>
</div>
</div>
diff --git a/app/assets/javascripts/vue_shared/components/user_avatar/user_avatar_link.vue b/app/assets/javascripts/vue_shared/components/user_avatar/user_avatar_link.vue
index 95898d54cf7..dc32e783258 100644
--- a/app/assets/javascripts/vue_shared/components/user_avatar/user_avatar_link.vue
+++ b/app/assets/javascripts/vue_shared/components/user_avatar/user_avatar_link.vue
@@ -12,12 +12,14 @@
:img-alt="tooltipText"
:img-size="20"
:tooltip-text="tooltipText"
- tooltip-placement="top"
+ :tooltip-placement="top"
+ :username="username"
/>
*/
import userAvatarImage from './user_avatar_image.vue';
+import tooltip from '../../directives/tooltip';
export default {
name: 'UserAvatarLink',
@@ -60,6 +62,22 @@ export default {
required: false,
default: 'top',
},
+ username: {
+ type: String,
+ required: false,
+ default: '',
+ },
+ },
+ computed: {
+ shouldShowUsername() {
+ return this.username.length > 0;
+ },
+ avatarTooltipText() {
+ return this.shouldShowUsername ? '' : this.tooltipText;
+ },
+ },
+ directives: {
+ tooltip,
},
};
</script>
@@ -73,8 +91,13 @@ export default {
:img-alt="imgAlt"
:css-classes="imgCssClasses"
:size="imgSize"
- :tooltip-text="tooltipText"
+ :tooltip-text="avatarTooltipText"
+ :tooltip-placement="tooltipPlacement"
+ /><span
+ v-if="shouldShowUsername"
+ v-tooltip
+ :title="tooltipText"
:tooltip-placement="tooltipPlacement"
- />
+ >{{username}}</span>
</a>
</template>
diff --git a/app/assets/stylesheets/framework.scss b/app/assets/stylesheets/framework.scss
index aa61ddc6a2c..7b1ef003bb2 100644
--- a/app/assets/stylesheets/framework.scss
+++ b/app/assets/stylesheets/framework.scss
@@ -5,6 +5,7 @@
@import "framework/layout";
@import "framework/animations";
+@import "framework/vue_transitions";
@import "framework/avatar";
@import "framework/asciidoctor";
@import "framework/banner";
@@ -36,7 +37,7 @@
@import "framework/secondary-navigation-elements";
@import "framework/selects";
@import "framework/sidebar";
-@import "framework/new-sidebar";
+@import "framework/contextual-sidebar";
@import "framework/tables";
@import "framework/notes";
@import "framework/tabs";
diff --git a/app/assets/stylesheets/framework/buttons.scss b/app/assets/stylesheets/framework/buttons.scss
index b131e2d57ee..00a0e9cef67 100644
--- a/app/assets/stylesheets/framework/buttons.scss
+++ b/app/assets/stylesheets/framework/buttons.scss
@@ -292,6 +292,11 @@
}
}
+.btn-align-content {
+ display: flex;
+ align-items: center;
+}
+
.btn-group {
&.btn-grouped {
@include btn-with-margin;
diff --git a/app/assets/stylesheets/framework/new-sidebar.scss b/app/assets/stylesheets/framework/contextual-sidebar.scss
index 7a309f2c8a1..fa5d3833f3e 100644
--- a/app/assets/stylesheets/framework/new-sidebar.scss
+++ b/app/assets/stylesheets/framework/contextual-sidebar.scss
@@ -1,24 +1,10 @@
-@import "framework/variables";
-@import 'framework/tw_bootstrap_variables';
-@import "bootstrap/variables";
-
-$active-background: rgba(0, 0, 0, .04);
-$active-hover-background: $active-background;
-$active-hover-color: $gl-text-color;
-$inactive-badge-background: rgba(0, 0, 0, .08);
-$hover-background: rgba(0, 0, 0, .06);
-$hover-color: $gl-text-color;
-$inactive-color: $gl-text-color-secondary;
-$new-sidebar-width: 220px;
-$new-sidebar-collapsed-width: 50px;
-
-.page-with-new-sidebar {
+.page-with-contextual-sidebar {
@media (min-width: $screen-md-min) {
- padding-left: $new-sidebar-collapsed-width;
+ padding-left: $contextual-sidebar-collapsed-width;
}
@media (min-width: $screen-lg-min) {
- padding-left: $new-sidebar-width;
+ padding-left: $contextual-sidebar-width;
}
// Override position: absolute
@@ -34,7 +20,7 @@ $new-sidebar-collapsed-width: 50px;
.page-with-icon-sidebar {
@media (min-width: $screen-sm-min) {
- padding-left: $new-sidebar-collapsed-width;
+ padding-left: $contextual-sidebar-collapsed-width;
}
}
@@ -52,12 +38,12 @@ $new-sidebar-collapsed-width: 50px;
&:hover,
a:hover {
- background-color: $hover-background;
- color: $hover-color;
+ background-color: $link-hover-background;
+ color: $gl-text-color;
.settings-avatar {
svg {
- fill: $hover-color;
+ fill: $gl-text-color;
}
}
}
@@ -85,7 +71,7 @@ $new-sidebar-collapsed-width: 50px;
.nav-sidebar {
position: fixed;
z-index: 400;
- width: $new-sidebar-width;
+ width: $contextual-sidebar-width;
transition: left $sidebar-transition-duration;
top: $header-height;
bottom: 0;
@@ -103,7 +89,7 @@ $new-sidebar-collapsed-width: 50px;
&.sidebar-icons-only {
width: auto;
- min-width: $new-sidebar-collapsed-width;
+ min-width: $contextual-sidebar-collapsed-width;
.nav-sidebar-inner-scroll {
overflow-x: hidden;
@@ -149,11 +135,11 @@ $new-sidebar-collapsed-width: 50px;
display: flex;
align-items: center;
padding: 12px 16px;
- color: $inactive-color;
+ color: $gl-text-color-secondary;
}
svg {
- fill: $inactive-color;
+ fill: $gl-text-color-secondary;
}
}
@@ -168,7 +154,7 @@ $new-sidebar-collapsed-width: 50px;
}
@media (max-width: $screen-xs-max) {
- left: (-$new-sidebar-width);
+ left: (-$contextual-sidebar-width);
}
.nav-icon-container {
@@ -210,8 +196,8 @@ $new-sidebar-collapsed-width: 50px;
&:hover,
&:focus {
- background: $active-hover-background;
- color: $active-hover-color;
+ background: $link-active-background;
+ color: $gl-text-color;
}
}
@@ -220,7 +206,7 @@ $new-sidebar-collapsed-width: 50px;
&,
&:hover,
&:focus {
- background: $active-background;
+ background: $link-active-background;
}
}
}
@@ -308,11 +294,11 @@ $new-sidebar-collapsed-width: 50px;
.badge {
background-color: $inactive-badge-background;
- color: $inactive-color;
+ color: $gl-text-color-secondary;
}
&.active {
- background: $active-background;
+ background: $link-active-background;
> a {
margin-left: 4px;
@@ -330,7 +316,7 @@ $new-sidebar-collapsed-width: 50px;
&.active > a:hover,
&.is-over > a {
- background-color: $hover-background;
+ background-color: $link-hover-background;
}
}
}
@@ -340,7 +326,7 @@ $new-sidebar-collapsed-width: 50px;
.toggle-sidebar-button,
.close-nav-button {
- width: $new-sidebar-width - 2px;
+ width: $contextual-sidebar-width - 2px;
position: fixed;
bottom: 0;
padding: 16px;
@@ -407,7 +393,7 @@ $new-sidebar-collapsed-width: 50px;
}
.toggle-sidebar-button {
- width: $new-sidebar-collapsed-width - 2px;
+ width: $contextual-sidebar-collapsed-width - 2px;
padding: 16px;
.collapse-text,
diff --git a/app/assets/stylesheets/framework/dropdowns.scss b/app/assets/stylesheets/framework/dropdowns.scss
index a9d804e735d..1aa53b8f8cf 100644
--- a/app/assets/stylesheets/framework/dropdowns.scss
+++ b/app/assets/stylesheets/framework/dropdowns.scss
@@ -776,12 +776,15 @@
a,
button,
.menu-item {
+ margin-bottom: 0;
border-radius: 0;
box-shadow: none;
padding: 8px 16px;
text-align: left;
white-space: normal;
width: 100%;
+ font-weight: $gl-font-weight-normal;
+ line-height: normal;
&.dropdown-menu-user-link {
white-space: nowrap;
diff --git a/app/assets/stylesheets/framework/filters.scss b/app/assets/stylesheets/framework/filters.scss
index b2847c348eb..0d80a85d521 100644
--- a/app/assets/stylesheets/framework/filters.scss
+++ b/app/assets/stylesheets/framework/filters.scss
@@ -65,7 +65,7 @@
display: flex;
flex: 1;
-webkit-flex: 1;
- padding-left: 30px;
+ padding-left: 12px;
position: relative;
margin-bottom: 0;
}
@@ -221,10 +221,6 @@
box-shadow: 0 0 4px $search-input-focus-shadow-color;
}
- &.focus .fa-filter {
- color: $common-gray-dark;
- }
-
gl-emoji {
display: inline-block;
font-family: inherit;
@@ -251,13 +247,6 @@
}
}
- .fa-filter {
- position: absolute;
- top: 10px;
- left: 10px;
- color: $gray-darkest;
- }
-
.fa-times {
right: 10px;
color: $gray-darkest;
diff --git a/app/assets/stylesheets/framework/gitlab-theme.scss b/app/assets/stylesheets/framework/gitlab-theme.scss
index 52b87de7a3d..dc591c06c88 100644
--- a/app/assets/stylesheets/framework/gitlab-theme.scss
+++ b/app/assets/stylesheets/framework/gitlab-theme.scss
@@ -216,12 +216,9 @@ body {
color: $theme-gray-900;
}
- &.active > a {
+ &.active > a,
+ &.active > a:hover {
color: $white-light;
-
- &:hover {
- color: $white-light;
- }
}
}
}
diff --git a/app/assets/stylesheets/framework/header.scss b/app/assets/stylesheets/framework/header.scss
index d79444fad79..62ba74ff582 100644
--- a/app/assets/stylesheets/framework/header.scss
+++ b/app/assets/stylesheets/framework/header.scss
@@ -239,10 +239,8 @@
fill: currentColor;
}
- &.header-user-dropdown-toggle {
- .header-user-avatar {
- border-color: $white-light;
- }
+ &.header-user-dropdown-toggle .header-user-avatar {
+ border-color: $white-light;
}
}
}
diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss
index d5ca23ff870..8ab48e4844f 100644
--- a/app/assets/stylesheets/framework/variables.scss
+++ b/app/assets/stylesheets/framework/variables.scss
@@ -9,6 +9,8 @@ $sidebar-transition-duration: .15s;
$sidebar-breakpoint: 1024px;
$default-transition-duration: .15s;
$right-sidebar-transition-duration: .3s;
+$contextual-sidebar-width: 220px;
+$contextual-sidebar-collapsed-width: 50px;
/*
* Color schema
@@ -359,6 +361,13 @@ $filtered-search-term-shadow-color: rgba(0, 0, 0, 0.09);
$dropdown-hover-color: $blue-400;
/*
+* Contextual Sidebar
+*/
+$link-active-background: rgba(0, 0, 0, .04);
+$link-hover-background: rgba(0, 0, 0, .06);
+$inactive-badge-background: rgba(0, 0, 0, .08);
+
+/*
* Buttons
*/
$btn-active-gray: #ececec;
@@ -404,7 +413,6 @@ $note-targe3-inside: #ffffd3;
$note-line2-border: #ddd;
$note-icon-gutter-width: 55px;
-
/*
* Zen
*/
diff --git a/app/assets/stylesheets/framework/vue_transitions.scss b/app/assets/stylesheets/framework/vue_transitions.scss
new file mode 100644
index 00000000000..e07a177e153
--- /dev/null
+++ b/app/assets/stylesheets/framework/vue_transitions.scss
@@ -0,0 +1,9 @@
+.fade-enter-active,
+.fade-leave-active {
+ transition: opacity $sidebar-transition-duration $general-hover-transition-curve;
+}
+
+.fade-enter,
+.fade-leave-to {
+ opacity: 0;
+}
diff --git a/app/assets/stylesheets/pages/boards.scss b/app/assets/stylesheets/pages/boards.scss
index ca61f7a30c3..91296b354a7 100644
--- a/app/assets/stylesheets/pages/boards.scss
+++ b/app/assets/stylesheets/pages/boards.scss
@@ -414,7 +414,7 @@
margin: 5px;
}
-.page-with-new-sidebar.page-with-sidebar .issue-boards-sidebar {
+.page-with-contextual-sidebar.page-with-sidebar .issue-boards-sidebar {
.issuable-sidebar-header {
position: relative;
}
diff --git a/app/assets/stylesheets/pages/issuable.scss b/app/assets/stylesheets/pages/issuable.scss
index 48532503263..88600a0e6d3 100644
--- a/app/assets/stylesheets/pages/issuable.scss
+++ b/app/assets/stylesheets/pages/issuable.scss
@@ -542,7 +542,9 @@
}
.participants-list {
- margin: -5px;
+ display: flex;
+ flex-wrap: wrap;
+ margin: -7px;
}
@@ -553,7 +555,7 @@
.participants-author {
display: inline-block;
- padding: 5px;
+ padding: 7px;
&:nth-of-type(7n) {
padding-right: 0;
diff --git a/app/assets/stylesheets/pages/note_form.scss b/app/assets/stylesheets/pages/note_form.scss
index 04b132415eb..f0cad30f4f3 100644
--- a/app/assets/stylesheets/pages/note_form.scss
+++ b/app/assets/stylesheets/pages/note_form.scss
@@ -249,13 +249,12 @@
width: 100%;
padding-right: 5px;
}
-
}
.discussion-actions {
display: table;
- .new-issue-for-discussion path {
+ .btn-default path {
fill: $gray-darkest;
}
diff --git a/app/assets/stylesheets/pages/notes.scss b/app/assets/stylesheets/pages/notes.scss
index ebad429c2ba..312917bd13a 100644
--- a/app/assets/stylesheets/pages/notes.scss
+++ b/app/assets/stylesheets/pages/notes.scss
@@ -269,7 +269,7 @@ ul.notes {
display: none;
}
- &.system-note-commit-list {
+ &.system-note-commit-list:not(.hide-shade) {
max-height: 70px;
overflow: hidden;
display: block;
@@ -291,16 +291,6 @@ ul.notes {
bottom: 0;
background: linear-gradient(rgba($white-light, 0.1) -100px, $white-light 100%);
}
-
- &.hide-shade {
- max-height: 100%;
- overflow: auto;
-
- &::after {
- display: none;
- background: transparent;
- }
- }
}
}
}
@@ -466,6 +456,10 @@ ul.notes {
float: right;
margin-left: 10px;
color: $gray-darkest;
+
+ .btn-group > .discussion-next-btn {
+ margin-left: -1px;
+ }
}
.note-actions {
diff --git a/app/assets/stylesheets/pages/repo.scss b/app/assets/stylesheets/pages/repo.scss
index ea37ccf5e3d..1bb4e3cc345 100644
--- a/app/assets/stylesheets/pages/repo.scss
+++ b/app/assets/stylesheets/pages/repo.scss
@@ -1,17 +1,3 @@
-.fade-enter-active,
-.fade-leave-active {
- transition: opacity $sidebar-transition-duration;
-}
-
-.monaco-loader {
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- background: $black-transparent;
-}
-
.modal.popup-dialog {
display: block;
background-color: $black-transparent;
@@ -59,6 +45,7 @@
}
.tree-content-holder {
+ display: -webkit-flex;
display: flex;
min-height: 300px;
}
@@ -68,7 +55,9 @@
}
.panel-right {
+ display: -webkit-flex;
display: flex;
+ -webkit-flex-direction: column;
flex-direction: column;
width: 80%;
height: 100%;
@@ -86,10 +75,6 @@
text-decoration: underline;
}
}
-
- .cursor {
- display: none !important;
- }
}
.blob-no-preview {
@@ -99,21 +84,12 @@
}
}
- &.edit-mode {
- .blob-viewer-container {
- overflow: hidden;
- }
-
- .monaco-editor.vs {
- .cursor {
- background: $black;
- border-color: $black;
- display: block !important;
- }
- }
+ &.blob-editor-container {
+ overflow: hidden;
}
.blob-viewer-container {
+ -webkit-flex: 1;
flex: 1;
overflow: auto;
@@ -143,6 +119,7 @@
}
#tabs {
+ position: relative;
flex-shrink: 0;
display: flex;
width: 100%;
@@ -171,6 +148,10 @@
vertical-align: middle;
text-decoration: none;
margin-right: 12px;
+
+ &:focus {
+ outline: none;
+ }
}
.close-btn {
@@ -206,7 +187,7 @@
}
}
- #repo-file-buttons {
+ .repo-file-buttons {
background-color: $white-light;
padding: 5px 10px;
border-top: 1px solid $white-normal;
@@ -317,23 +298,3 @@
width: 100%;
}
}
-
-@keyframes swipeRightAppear {
- 0% {
- transform: scaleX(0.00);
- }
-
- 100% {
- transform: scaleX(1.00);
- }
-}
-
-@keyframes swipeRightDissapear {
- 0% {
- transform: scaleX(1.00);
- }
-
- 100% {
- transform: scaleX(0.00);
- }
-}
diff --git a/app/controllers/confirmations_controller.rb b/app/controllers/confirmations_controller.rb
index 80ab681ed87..bc0948cd3fb 100644
--- a/app/controllers/confirmations_controller.rb
+++ b/app/controllers/confirmations_controller.rb
@@ -10,7 +10,7 @@ class ConfirmationsController < Devise::ConfirmationsController
users_almost_there_path
end
- def after_confirmation_path_for(_resource_name, resource)
+ def after_confirmation_path_for(resource_name, resource)
# incoming resource can either be a :user or an :email
if signed_in?(:user)
after_sign_in(resource)
diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb
index e23a82d01be..bc3e95f1aed 100644
--- a/app/controllers/groups_controller.rb
+++ b/app/controllers/groups_controller.rb
@@ -141,6 +141,17 @@ class GroupsController < Groups::ApplicationController
end
def load_events
+ params[:sort] ||= 'latest_activity_desc'
+
+ options = {}
+ options[:only_owned] = true if params[:shared] == '0'
+ options[:only_shared] = true if params[:shared] == '1'
+
+ @projects = GroupProjectsFinder.new(params: params, group: group, options: options, current_user: current_user)
+ .execute
+ .includes(:namespace)
+ .page(params[:page])
+
@events = EventCollection
.new(@projects, offset: params[:offset].to_i, filter: event_filter)
.to_a
diff --git a/app/controllers/help_controller.rb b/app/controllers/help_controller.rb
index 572915a4930..38f379dbf4f 100644
--- a/app/controllers/help_controller.rb
+++ b/app/controllers/help_controller.rb
@@ -57,6 +57,10 @@ class HelpController < ApplicationController
def shortcuts
end
+ def instance_configuration
+ @instance_configuration = InstanceConfiguration.new
+ end
+
def ui
@user = User.new(id: 0, name: 'John Doe', username: '@johndoe')
end
diff --git a/app/controllers/projects/blob_controller.rb b/app/controllers/projects/blob_controller.rb
index 183a6f88a6a..770381472c5 100644
--- a/app/controllers/projects/blob_controller.rb
+++ b/app/controllers/projects/blob_controller.rb
@@ -205,6 +205,7 @@ class Projects::BlobController < Projects::ApplicationController
tree_path = path_segments.join('/')
render json: json.merge(
+ id: @blob.id,
path: blob.path,
name: blob.name,
extension: blob.extension,
diff --git a/app/controllers/projects/branches_controller.rb b/app/controllers/projects/branches_controller.rb
index 7f03ce07dec..f28df83d5a5 100644
--- a/app/controllers/projects/branches_controller.rb
+++ b/app/controllers/projects/branches_controller.rb
@@ -15,6 +15,8 @@ class Projects::BranchesController < Projects::ApplicationController
respond_to do |format|
format.html do
@refs_pipelines = @project.pipelines.latest_successful_for_refs(@branches.map(&:name))
+ @merged_branch_names =
+ repository.merged_branch_names(@branches.map(&:name))
# n+1: https://gitlab.com/gitlab-org/gitlab-ce/issues/37429
Gitlab::GitalyClient.allow_n_plus_1_calls do
@max_commits = @branches.reduce(0) do |memo, branch|
diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb
index b7a108a0ebd..6a5e4538717 100644
--- a/app/controllers/projects/issues_controller.rb
+++ b/app/controllers/projects/issues_controller.rb
@@ -16,7 +16,7 @@ class Projects::IssuesController < Projects::ApplicationController
before_action :authorize_create_issue!, only: [:new, :create]
# Allow modify issue
- before_action :authorize_update_issue!, only: [:update, :move]
+ before_action :authorize_update_issue!, only: [:edit, :update, :move]
# Allow create a new branch and empty WIP merge request from current issue
before_action :authorize_create_merge_request!, only: [:create_merge_request]
@@ -63,6 +63,10 @@ class Projects::IssuesController < Projects::ApplicationController
respond_with(@issue)
end
+ def edit
+ respond_with(@issue)
+ end
+
def show
@noteable = @issue
@note = @project.notes.new(noteable: @issue)
@@ -70,7 +74,7 @@ class Projects::IssuesController < Projects::ApplicationController
respond_to do |format|
format.html
format.json do
- render json: serializer.represent(@issue)
+ render json: serializer.represent(@issue, serializer: params[:serializer])
end
end
end
@@ -122,6 +126,10 @@ class Projects::IssuesController < Projects::ApplicationController
@issue = Issues::UpdateService.new(project, current_user, update_params).execute(issue)
respond_to do |format|
+ format.html do
+ recaptcha_check_with_fallback { render :edit }
+ end
+
format.json do
render_issue_json
end
diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index c5204080333..2b0294c8387 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -83,7 +83,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
format.json do
Gitlab::PollingInterval.set_header(response, interval: 10_000)
- render json: serializer.represent(@merge_request, basic: params[:basic])
+ render json: serializer.represent(@merge_request, serializer: params[:serializer])
end
format.patch do
diff --git a/app/controllers/projects/milestones_controller.rb b/app/controllers/projects/milestones_controller.rb
index c94384d2a1a..980bbf699b6 100644
--- a/app/controllers/projects/milestones_controller.rb
+++ b/app/controllers/projects/milestones_controller.rb
@@ -2,13 +2,13 @@ class Projects::MilestonesController < Projects::ApplicationController
include MilestoneActions
before_action :check_issuables_available!
- before_action :milestone, only: [:edit, :update, :destroy, :show, :merge_requests, :participants, :labels]
+ before_action :milestone, only: [:edit, :update, :destroy, :show, :merge_requests, :participants, :labels, :promote]
# Allow read any milestone
before_action :authorize_read_milestone!
# Allow admin milestone
- before_action :authorize_admin_milestone!, except: [:index, :show, :merge_requests, :participants, :labels]
+ before_action :authorize_admin_milestone!, except: [:index, :show, :merge_requests, :participants, :labels, :promote]
respond_to :html
@@ -69,6 +69,14 @@ class Projects::MilestonesController < Projects::ApplicationController
end
end
+ def promote
+ promoted_milestone = Milestones::PromoteService.new(project, current_user).execute(milestone)
+ flash[:notice] = "Milestone has been promoted to group milestone."
+ redirect_to group_milestone_path(project.group, promoted_milestone.iid)
+ rescue Milestones::PromoteService::PromoteMilestoneError => error
+ redirect_to milestone, alert: error.message
+ end
+
def destroy
return access_denied! unless can?(current_user, :admin_milestone, @project)
diff --git a/app/controllers/projects/tree_controller.rb b/app/controllers/projects/tree_controller.rb
index 756f7e5df8c..f3719059f88 100644
--- a/app/controllers/projects/tree_controller.rb
+++ b/app/controllers/projects/tree_controller.rb
@@ -36,7 +36,6 @@ class Projects::TreeController < Projects::ApplicationController
format.json do
page_title @path.presence || _("Files"), @ref, @project.name_with_namespace
- response.header['is-root'] = @path.empty?
# n+1: https://gitlab.com/gitlab-org/gitlab-ce/issues/38261
Gitlab::GitalyClient.allow_n_plus_1_calls do
diff --git a/app/finders/branches_finder.rb b/app/finders/branches_finder.rb
index 533076585c0..852eac3647d 100644
--- a/app/finders/branches_finder.rb
+++ b/app/finders/branches_finder.rb
@@ -23,7 +23,7 @@ class BranchesFinder
def filter_by_name(branches)
if search
- branches.select { |branch| branch.name.include?(search) }
+ branches.select { |branch| branch.name.upcase.include?(search.upcase) }
else
branches
end
diff --git a/app/helpers/application_settings_helper.rb b/app/helpers/application_settings_helper.rb
index 1ee8911bb1a..cd1ecaadb85 100644
--- a/app/helpers/application_settings_helper.rb
+++ b/app/helpers/application_settings_helper.rb
@@ -120,6 +120,15 @@ module ApplicationSettingsHelper
message.html_safe
end
+ def circuitbreaker_access_retries_help_text
+ _('The number of attempts GitLab will make to access a storage.')
+ end
+
+ def circuitbreaker_backoff_threshold_help_text
+ _("The number of failures after which GitLab will start temporarily "\
+ "disabling access to a storage shard on a host")
+ end
+
def circuitbreaker_failure_wait_time_help_text
_("When access to a storage fails. GitLab will prevent access to the "\
"storage for the time specified here. This allows the filesystem to "\
@@ -144,6 +153,8 @@ module ApplicationSettingsHelper
:akismet_api_key,
:akismet_enabled,
:auto_devops_enabled,
+ :circuitbreaker_access_retries,
+ :circuitbreaker_backoff_threshold,
:circuitbreaker_failure_count_threshold,
:circuitbreaker_failure_reset_time,
:circuitbreaker_failure_wait_time,
diff --git a/app/helpers/instance_configuration_helper.rb b/app/helpers/instance_configuration_helper.rb
new file mode 100644
index 00000000000..cee319f20bc
--- /dev/null
+++ b/app/helpers/instance_configuration_helper.rb
@@ -0,0 +1,18 @@
+module InstanceConfigurationHelper
+ def instance_configuration_cell_html(value, &block)
+ return '-' unless value.to_s.presence
+
+ block_given? ? yield(value) : value
+ end
+
+ def instance_configuration_host(host)
+ @instance_configuration_host ||= instance_configuration_cell_html(host).capitalize
+ end
+
+ # Value must be in bytes
+ def instance_configuration_human_size_cell(value)
+ instance_configuration_cell_html(value) do |v|
+ number_to_human_size(v, strip_insignificant_zeros: true, significant: false)
+ end
+ end
+end
diff --git a/app/helpers/issuables_helper.rb b/app/helpers/issuables_helper.rb
index baa2d6e375e..d0069cd48cf 100644
--- a/app/helpers/issuables_helper.rb
+++ b/app/helpers/issuables_helper.rb
@@ -33,15 +33,17 @@ module IssuablesHelper
end
def serialize_issuable(issuable)
- case issuable
- when Issue
- IssueSerializer.new(current_user: current_user, project: issuable.project).represent(issuable).to_json
- when MergeRequest
- MergeRequestSerializer
- .new(current_user: current_user, project: issuable.project)
- .represent(issuable)
- .to_json
- end
+ serializer_klass = case issuable
+ when Issue
+ IssueSerializer
+ when MergeRequest
+ MergeRequestSerializer
+ end
+
+ serializer_klass
+ .new(current_user: current_user, project: issuable.project)
+ .represent(issuable)
+ .to_json
end
def template_dropdown_tag(issuable, &block)
@@ -357,7 +359,8 @@ module IssuablesHelper
def issuable_sidebar_options(issuable, can_edit_issuable)
{
- endpoint: "#{issuable_json_path(issuable)}?basic=true",
+ endpoint: "#{issuable_json_path(issuable)}?serializer=sidebar",
+ toggleSubscriptionEndpoint: toggle_subscription_path(issuable),
moveIssueEndpoint: move_namespace_project_issue_path(namespace_id: issuable.project.namespace.to_param, project_id: issuable.project, id: issuable),
projectsAutocompleteEndpoint: autocomplete_projects_path(project_id: @project.id),
editable: can_edit_issuable,
diff --git a/app/helpers/nav_helper.rb b/app/helpers/nav_helper.rb
index a23a43c9f43..8ada746b244 100644
--- a/app/helpers/nav_helper.rb
+++ b/app/helpers/nav_helper.rb
@@ -1,7 +1,7 @@
module NavHelper
def page_with_sidebar_class
class_name = page_gutter_class
- class_name << 'page-with-new-sidebar' if defined?(@left_sidebar) && @left_sidebar
+ class_name << 'page-with-contextual-sidebar' if defined?(@left_sidebar) && @left_sidebar
class_name << 'page-with-icon-sidebar' if collapsed_sidebar? && @left_sidebar
class_name
@@ -19,11 +19,7 @@ module NavHelper
end
elsif current_path?('jobs#show')
%w[page-gutter build-sidebar right-sidebar-expanded]
- elsif current_path?('wikis#show') ||
- current_path?('wikis#edit') ||
- current_path?('wikis#update') ||
- current_path?('wikis#history') ||
- current_path?('wikis#git_access')
+ elsif current_controller?('wikis') && current_action?('show', 'create', 'edit', 'update', 'history', 'git_access')
%w[page-gutter wiki-sidebar right-sidebar-expanded]
else
[]
diff --git a/app/helpers/storage_health_helper.rb b/app/helpers/storage_health_helper.rb
index 544c9efb845..4d2180f7eee 100644
--- a/app/helpers/storage_health_helper.rb
+++ b/app/helpers/storage_health_helper.rb
@@ -16,17 +16,16 @@ module StorageHealthHelper
def message_for_circuit_breaker(circuit_breaker)
maximum_failures = circuit_breaker.failure_count_threshold
current_failures = circuit_breaker.failure_count
- permanently_broken = circuit_breaker.circuit_broken? && current_failures >= maximum_failures
translation_params = { number_of_failures: current_failures,
maximum_failures: maximum_failures,
number_of_seconds: circuit_breaker.failure_wait_time }
- if permanently_broken
+ if circuit_breaker.circuit_broken?
s_("%{number_of_failures} of %{maximum_failures} failures. GitLab will not "\
"retry automatically. Reset storage information when the problem is "\
"resolved.") % translation_params
- elsif circuit_breaker.circuit_broken?
+ elsif circuit_breaker.backing_off?
_("%{number_of_failures} of %{maximum_failures} failures. GitLab will "\
"block access for %{number_of_seconds} seconds.") % translation_params
else
diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb
index 4dda276bb41..5e16badabec 100644
--- a/app/models/application_setting.rb
+++ b/app/models/application_setting.rb
@@ -153,13 +153,25 @@ class ApplicationSetting < ActiveRecord::Base
presence: true,
numericality: { greater_than_or_equal_to: 0 }
- validates :circuitbreaker_failure_count_threshold,
+ validates :circuitbreaker_backoff_threshold,
+ :circuitbreaker_failure_count_threshold,
:circuitbreaker_failure_wait_time,
:circuitbreaker_failure_reset_time,
:circuitbreaker_storage_timeout,
presence: true,
numericality: { only_integer: true, greater_than_or_equal_to: 0 }
+ validates :circuitbreaker_access_retries,
+ presence: true,
+ numericality: { only_integer: true, greater_than_or_equal_to: 1 }
+
+ validates_each :circuitbreaker_backoff_threshold do |record, attr, value|
+ if value.to_i >= record.circuitbreaker_failure_count_threshold
+ record.errors.add(attr, _("The circuitbreaker backoff threshold should be "\
+ "lower than the failure count threshold"))
+ end
+ end
+
SUPPORTED_KEY_TYPES.each do |type|
validates :"#{type}_key_restriction", presence: true, key_restriction: { type: type }
end
@@ -408,7 +420,7 @@ class ApplicationSetting < ActiveRecord::Base
# the enabling/disabling is `performance_bar_allowed_group_id`
# - If `enable` is false, we set `performance_bar_allowed_group_id` to `nil`
def performance_bar_enabled=(enable)
- return if enable
+ return if Gitlab::Utils.to_boolean(enable)
self.performance_bar_allowed_group_id = nil
end
diff --git a/app/models/ci/artifact_blob.rb b/app/models/ci/artifact_blob.rb
index 8b66531ec7b..ec56cc53aea 100644
--- a/app/models/ci/artifact_blob.rb
+++ b/app/models/ci/artifact_blob.rb
@@ -2,7 +2,7 @@ module Ci
class ArtifactBlob
include BlobLike
- EXTENTIONS_SERVED_BY_PAGES = %w[.html .htm .txt .json].freeze
+ EXTENSIONS_SERVED_BY_PAGES = %w[.html .htm .txt .json].freeze
attr_reader :entry
@@ -36,17 +36,22 @@ module Ci
def external_url(project, job)
return unless external_link?(job)
- components = project.full_path_components
- components << "-/jobs/#{job.id}/artifacts/file/#{path}"
- artifact_path = components[1..-1].join('/')
+ full_path_parts = project.full_path_components
+ top_level_group = full_path_parts.shift
- "#{pages_config.protocol}://#{components[0]}.#{pages_config.host}/#{artifact_path}"
+ artifact_path = [
+ '-', *full_path_parts, '-',
+ 'jobs', job.id,
+ 'artifacts', path
+ ].join('/')
+
+ "#{pages_config.protocol}://#{top_level_group}.#{pages_config.host}/#{artifact_path}"
end
def external_link?(job)
pages_config.enabled &&
pages_config.artifacts_server &&
- EXTENTIONS_SERVED_BY_PAGES.include?(File.extname(name)) &&
+ EXTENSIONS_SERVED_BY_PAGES.include?(File.extname(name)) &&
job.project.public?
end
diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb
index cf3ce3c9e54..ca65e81f27a 100644
--- a/app/models/ci/pipeline.rb
+++ b/app/models/ci/pipeline.rb
@@ -249,9 +249,7 @@ module Ci
end
def commit
- @commit ||= project.commit(sha)
- rescue
- nil
+ @commit ||= project.commit_by(oid: sha)
end
def branch?
diff --git a/app/models/concerns/subscribable.rb b/app/models/concerns/subscribable.rb
index 274b38a7708..f478c8ede18 100644
--- a/app/models/concerns/subscribable.rb
+++ b/app/models/concerns/subscribable.rb
@@ -13,6 +13,8 @@ module Subscribable
end
def subscribed?(user, project = nil)
+ return false unless user
+
if subscription = subscriptions.find_by(user: user, project: project)
subscription.subscribed
else
diff --git a/app/models/email.rb b/app/models/email.rb
index 384f38f2db7..2da8b050149 100644
--- a/app/models/email.rb
+++ b/app/models/email.rb
@@ -14,6 +14,8 @@ class Email < ActiveRecord::Base
devise :confirmable
self.reconfirmable = false # currently email can't be changed, no need to reconfirm
+ delegate :username, to: :user
+
def email=(value)
write_attribute(:email, value.downcase.strip)
end
diff --git a/app/models/environment.rb b/app/models/environment.rb
index b6868ccbe8f..e613d21add6 100644
--- a/app/models/environment.rb
+++ b/app/models/environment.rb
@@ -110,7 +110,7 @@ class Environment < ActiveRecord::Base
end
def ref_path
- "refs/#{Repository::REF_ENVIRONMENTS}/#{Shellwords.shellescape(name)}"
+ "refs/#{Repository::REF_ENVIRONMENTS}/#{generate_slug}"
end
def formatted_external_url
diff --git a/app/models/identity.rb b/app/models/identity.rb
index 920a25932b4..ac8094b610e 100644
--- a/app/models/identity.rb
+++ b/app/models/identity.rb
@@ -7,7 +7,10 @@ class Identity < ActiveRecord::Base
validates :extern_uid, allow_blank: true, uniqueness: { scope: :provider }
validates :user_id, uniqueness: { scope: :provider }
- scope :with_extern_uid, ->(provider, extern_uid) { where(extern_uid: extern_uid, provider: provider) }
+ scope :with_extern_uid, ->(provider, extern_uid) do
+ extern_uid = Gitlab::LDAP::Person.normalize_dn(extern_uid) if provider.starts_with?('ldap')
+ where(extern_uid: extern_uid, provider: provider)
+ end
def ldap?
provider.starts_with?('ldap')
diff --git a/app/models/instance_configuration.rb b/app/models/instance_configuration.rb
new file mode 100644
index 00000000000..b30b707e5fe
--- /dev/null
+++ b/app/models/instance_configuration.rb
@@ -0,0 +1,71 @@
+require 'resolv'
+
+class InstanceConfiguration
+ SSH_ALGORITHMS = %w(DSA ECDSA ED25519 RSA).freeze
+ SSH_ALGORITHMS_PATH = '/etc/ssh/'.freeze
+ CACHE_KEY = 'instance_configuration'.freeze
+ EXPIRATION_TIME = 24.hours
+
+ def settings
+ @configuration ||= Rails.cache.fetch(CACHE_KEY, expires_in: EXPIRATION_TIME) do
+ { ssh_algorithms_hashes: ssh_algorithms_hashes,
+ host: host,
+ gitlab_pages: gitlab_pages,
+ gitlab_ci: gitlab_ci }.deep_symbolize_keys
+ end
+ end
+
+ private
+
+ def ssh_algorithms_hashes
+ SSH_ALGORITHMS.map { |algo| ssh_algorithm_hashes(algo) }.compact
+ end
+
+ def host
+ Settings.gitlab.host
+ end
+
+ def gitlab_pages
+ Settings.pages.to_h.merge(ip_address: resolv_dns(Settings.pages.host))
+ end
+
+ def resolv_dns(dns)
+ Resolv.getaddress(dns)
+ rescue Resolv::ResolvError
+ end
+
+ def gitlab_ci
+ Settings.gitlab_ci
+ .to_h
+ .merge(artifacts_max_size: { value: Settings.artifacts.max_size&.megabytes,
+ default: 100.megabytes })
+ end
+
+ def ssh_algorithm_file(algorithm)
+ File.join(SSH_ALGORITHMS_PATH, "ssh_host_#{algorithm.downcase}_key.pub")
+ end
+
+ def ssh_algorithm_hashes(algorithm)
+ content = ssh_algorithm_file_content(algorithm)
+ return unless content.present?
+
+ { name: algorithm,
+ md5: ssh_algorithm_md5(content),
+ sha256: ssh_algorithm_sha256(content) }
+ end
+
+ def ssh_algorithm_file_content(algorithm)
+ file = ssh_algorithm_file(algorithm)
+ return unless File.exist?(file)
+
+ File.read(file)
+ end
+
+ def ssh_algorithm_md5(ssh_file_content)
+ OpenSSL::Digest::MD5.hexdigest(ssh_file_content).scan(/../).join(':')
+ end
+
+ def ssh_algorithm_sha256(ssh_file_content)
+ OpenSSL::Digest::SHA256.hexdigest(ssh_file_content)
+ end
+end
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index c3fae16d109..d45b9c805a4 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -396,6 +396,10 @@ class MergeRequest < ActiveRecord::Base
end
def merge_ongoing?
+ # While the MergeRequest is locked, it should present itself as 'merge ongoing'.
+ # The unlocking process is handled by StuckMergeJobsWorker scheduled in Cron.
+ return true if locked?
+
!!merge_jid && !merged? && Gitlab::SidekiqStatus.running?(merge_jid)
end
@@ -874,7 +878,7 @@ class MergeRequest < ActiveRecord::Base
#
def all_commit_shas
if persisted?
- column_shas = MergeRequestDiffCommit.where(merge_request_diff: merge_request_diffs).pluck('DISTINCT(sha)')
+ column_shas = MergeRequestDiffCommit.where(merge_request_diff: merge_request_diffs).limit(10_000).pluck('sha')
serialised_shas = merge_request_diffs.where.not(st_commits: nil).flat_map(&:commit_shas)
(column_shas + serialised_shas).uniq
diff --git a/app/models/merge_request_diff_commit.rb b/app/models/merge_request_diff_commit.rb
index 670b26d4ca3..b75387e236e 100644
--- a/app/models/merge_request_diff_commit.rb
+++ b/app/models/merge_request_diff_commit.rb
@@ -17,7 +17,9 @@ class MergeRequestDiffCommit < ActiveRecord::Base
commit_hash.merge(
merge_request_diff_id: merge_request_diff_id,
relative_order: index,
- sha: sha_attribute.type_cast_for_database(sha)
+ sha: sha_attribute.type_cast_for_database(sha),
+ authored_date: Gitlab::Database.sanitize_timestamp(commit_hash[:authored_date]),
+ committed_date: Gitlab::Database.sanitize_timestamp(commit_hash[:committed_date])
)
end
diff --git a/app/models/pages_domain.rb b/app/models/pages_domain.rb
index 5d798247863..2e824cda525 100644
--- a/app/models/pages_domain.rb
+++ b/app/models/pages_domain.rb
@@ -16,9 +16,9 @@ class PagesDomain < ActiveRecord::Base
key: Gitlab::Application.secrets.db_key_base,
algorithm: 'aes-256-cbc'
- after_create :update
- after_save :update
- after_destroy :update
+ after_create :update_daemon
+ after_save :update_daemon
+ after_destroy :update_daemon
def to_param
domain
@@ -80,7 +80,7 @@ class PagesDomain < ActiveRecord::Base
private
- def update
+ def update_daemon
::Projects::UpdatePagesConfigurationService.new(project).execute
end
diff --git a/app/models/project.rb b/app/models/project.rb
index 4689b588906..413866b994a 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -26,7 +26,15 @@ class Project < ActiveRecord::Base
NUMBER_OF_PERMITTED_BOARDS = 1
UNKNOWN_IMPORT_URL = 'http://unknown.git'.freeze
- LATEST_STORAGE_VERSION = 1
+ # Hashed Storage versions handle rolling out new storage to project and dependents models:
+ # nil: legacy
+ # 1: repository
+ # 2: attachments
+ LATEST_STORAGE_VERSION = 2
+ HASHED_STORAGE_FEATURES = {
+ repository: 1,
+ attachments: 2
+ }.freeze
cache_markdown_field :description, pipeline: :description
@@ -120,6 +128,7 @@ class Project < ActiveRecord::Base
has_one :mock_deployment_service
has_one :mock_monitoring_service
has_one :microsoft_teams_service
+ has_one :packagist_service
# TODO: replace these relations with the fork network versions
has_one :forked_project_link, foreign_key: "forked_to_project_id"
@@ -540,6 +549,10 @@ class Project < ActiveRecord::Base
repository.commit(ref)
end
+ def commit_by(oid:)
+ repository.commit_by(oid: oid)
+ end
+
# ref can't be HEAD, can only be branch/tag name or SHA
def latest_successful_builds_for(ref = default_branch)
latest_pipeline = pipelines.latest_successful_for(ref)
@@ -553,7 +566,7 @@ class Project < ActiveRecord::Base
def merge_base_commit(first_commit_id, second_commit_id)
sha = repository.merge_base(first_commit_id, second_commit_id)
- repository.commit(sha) if sha
+ commit_by(oid: sha) if sha
end
def saved?
@@ -1079,6 +1092,7 @@ class Project < ActiveRecord::Base
def hook_attrs(backward: true)
attrs = {
+ id: id,
name: name,
description: description,
web_url: web_url,
@@ -1390,6 +1404,19 @@ class Project < ActiveRecord::Base
end
end
+ def after_rename_repo
+ path_before_change = previous_changes['path'].first
+
+ # We need to check if project had been rolled out to move resource to hashed storage or not and decide
+ # if we need execute any take action or no-op.
+
+ unless hashed_storage?(:attachments)
+ Gitlab::UploadsTransfer.new.rename_project(path_before_change, self.path, namespace.full_path)
+ end
+
+ Gitlab::PagesTransfer.new.rename_project(path_before_change, self.path, namespace.full_path)
+ end
+
def rename_repo_notify!
send_move_instructions(full_path_was)
expires_full_path_cache
@@ -1400,13 +1427,6 @@ class Project < ActiveRecord::Base
reload_repository!
end
- def after_rename_repo
- path_before_change = previous_changes['path'].first
-
- Gitlab::UploadsTransfer.new.rename_project(path_before_change, self.path, namespace.full_path)
- Gitlab::PagesTransfer.new.rename_project(path_before_change, self.path, namespace.full_path)
- end
-
def running_or_pending_build_count(force: false)
Rails.cache.fetch(['projects', id, 'running_or_pending_build_count'], force: force) do
builds.running_or_pending.count(:all)
@@ -1596,8 +1616,13 @@ class Project < ActiveRecord::Base
[nil, 0].include?(self.storage_version)
end
- def hashed_storage?
- self.storage_version && self.storage_version >= 1
+ # Check if Hashed Storage is enabled for the project with at least informed feature rolled out
+ #
+ # @param [Symbol] feature that needs to be rolled out for the project (:repository, :attachments)
+ def hashed_storage?(feature)
+ raise ArgumentError, "Invalid feature" unless HASHED_STORAGE_FEATURES.include?(feature)
+
+ self.storage_version && self.storage_version >= HASHED_STORAGE_FEATURES[feature]
end
def renamed?
@@ -1633,7 +1658,7 @@ class Project < ActiveRecord::Base
end
def migrate_to_hashed_storage!
- return if hashed_storage?
+ return if hashed_storage?(:repository)
update!(repository_read_only: true)
@@ -1658,7 +1683,7 @@ class Project < ActiveRecord::Base
def storage
@storage ||=
- if hashed_storage?
+ if hashed_storage?(:repository)
Storage::HashedProject.new(self)
else
Storage::LegacyProject.new(self)
diff --git a/app/models/project_services/jira_service.rb b/app/models/project_services/jira_service.rb
index 9ee3a533c1e..b487378edd2 100644
--- a/app/models/project_services/jira_service.rb
+++ b/app/models/project_services/jira_service.rb
@@ -3,6 +3,8 @@ class JiraService < IssueTrackerService
validates :url, url: true, presence: true, if: :activated?
validates :api_url, url: true, allow_blank: true
+ validates :username, presence: true, if: :activated?
+ validates :password, presence: true, if: :activated?
prop_accessor :username, :password, :url, :api_url, :jira_issue_transition_id, :title, :description
diff --git a/app/models/project_services/kubernetes_service.rb b/app/models/project_services/kubernetes_service.rb
index 8ba07173c74..5c0b3338a62 100644
--- a/app/models/project_services/kubernetes_service.rb
+++ b/app/models/project_services/kubernetes_service.rb
@@ -153,7 +153,10 @@ class KubernetesService < DeploymentService
end
def default_namespace
- "#{project.path}-#{project.id}" if project.present?
+ return unless project
+
+ slug = "#{project.path}-#{project.id}".downcase
+ slug.gsub(/[^-a-z0-9]/, '-').gsub(/^-+/, '')
end
def build_kubeclient!(api_path: 'api', api_version: 'v1')
diff --git a/app/models/project_services/packagist_service.rb b/app/models/project_services/packagist_service.rb
new file mode 100644
index 00000000000..f68a0c1a3c3
--- /dev/null
+++ b/app/models/project_services/packagist_service.rb
@@ -0,0 +1,65 @@
+class PackagistService < Service
+ include HTTParty
+
+ prop_accessor :username, :token, :server
+
+ validates :username, presence: true, if: :activated?
+ validates :token, presence: true, if: :activated?
+
+ default_value_for :push_events, true
+ default_value_for :tag_push_events, true
+
+ after_save :compose_service_hook, if: :activated?
+
+ def title
+ 'Packagist'
+ end
+
+ def description
+ 'Update your project on Packagist, the main Composer repository'
+ end
+
+ def self.to_param
+ 'packagist'
+ end
+
+ def fields
+ [
+ { type: 'text', name: 'username', placeholder: '', required: true },
+ { type: 'text', name: 'token', placeholder: '', required: true },
+ { type: 'text', name: 'server', placeholder: 'https://packagist.org', required: false }
+ ]
+ end
+
+ def self.supported_events
+ %w(push merge_request tag_push)
+ end
+
+ def execute(data)
+ return unless supported_events.include?(data[:object_kind])
+
+ service_hook.execute(data)
+ end
+
+ def test(data)
+ begin
+ result = execute(data)
+ return { success: false, result: result[:message] } if result[:http_status] != 202
+ rescue StandardError => error
+ return { success: false, result: error }
+ end
+
+ { success: true, result: result[:message] }
+ end
+
+ def compose_service_hook
+ hook = service_hook || build_service_hook
+ hook.url = hook_url
+ hook.save
+ end
+
+ def hook_url
+ base_url = server.present? ? server : 'https://packagist.org'
+ "#{base_url}/api/update-package?username=#{username}&apiToken=#{token}"
+ end
+end
diff --git a/app/models/repository.rb b/app/models/repository.rb
index 4324ea46aac..44a1e9ce529 100644
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -76,6 +76,7 @@ class Repository
@full_path = full_path
@disk_path = disk_path || full_path
@project = project
+ @commit_cache = {}
end
def ==(other)
@@ -103,18 +104,17 @@ class Repository
def commit(ref = 'HEAD')
return nil unless exists?
+ return ref if ref.is_a?(::Commit)
- commit =
- if ref.is_a?(Gitlab::Git::Commit)
- ref
- else
- Gitlab::Git::Commit.find(raw_repository, ref)
- end
+ find_commit(ref)
+ end
- commit = ::Commit.new(commit, @project) if commit
- commit
- rescue Rugged::OdbError, Rugged::TreeError
- nil
+ # Finding a commit by the passed SHA
+ # Also takes care of caching, based on the SHA
+ def commit_by(oid:)
+ return @commit_cache[oid] if @commit_cache.key?(oid)
+
+ @commit_cache[oid] = find_commit(oid)
end
def commits(ref, path: nil, limit: nil, offset: nil, skip_merges: false, after: nil, before: nil)
@@ -231,7 +231,7 @@ class Repository
# branches or tags, but we want to keep some of these commits around, for
# example if they have comments or CI builds.
def keep_around(sha)
- return unless sha && commit(sha)
+ return unless sha && commit_by(oid: sha)
return if kept_around?(sha)
@@ -862,22 +862,12 @@ class Repository
end
def ff_merge(user, source, target_branch, merge_request: nil)
- our_commit = rugged.branches[target_branch].target
- their_commit =
- if source.is_a?(Gitlab::Git::Commit)
- source.raw_commit
- else
- rugged.lookup(source)
- end
-
- raise 'Invalid merge target' if our_commit.nil?
- raise 'Invalid merge source' if their_commit.nil?
+ their_commit_id = commit(source)&.id
+ raise 'Invalid merge source' if their_commit_id.nil?
- with_branch(user, target_branch) do |start_commit|
- merge_request&.update(in_progress_merge_commit_sha: their_commit.oid)
+ merge_request&.update(in_progress_merge_commit_sha: their_commit_id)
- their_commit.oid
- end
+ with_cache_hooks { raw.ff_merge(user, their_commit_id, target_branch) }
end
def revert(
@@ -912,18 +902,27 @@ class Repository
end
end
- def merged_to_root_ref?(branch_name)
- branch_commit = commit(branch_name)
- root_ref_commit = commit(root_ref)
+ def merged_to_root_ref?(branch_or_name, pre_loaded_merged_branches = nil)
+ branch = Gitlab::Git::Branch.find(self, branch_or_name)
- if branch_commit
- same_head = branch_commit.id == root_ref_commit.id
- !same_head && ancestor?(branch_commit.id, root_ref_commit.id)
+ if branch
+ root_ref_sha = commit(root_ref).sha
+ same_head = branch.target == root_ref_sha
+ merged =
+ if pre_loaded_merged_branches
+ pre_loaded_merged_branches.include?(branch.name)
+ else
+ ancestor?(branch.target, root_ref_sha)
+ end
+
+ !same_head && merged
else
nil
end
end
+ delegate :merged_branch_names, to: :raw_repository
+
def merge_base(first_commit_id, second_commit_id)
first_commit_id = commit(first_commit_id).try(:id) || first_commit_id
second_commit_id = commit(second_commit_id).try(:id) || second_commit_id
@@ -1031,6 +1030,10 @@ class Repository
if instance_variable_defined?(ivar)
instance_variable_get(ivar)
else
+ # If the repository doesn't exist and a fallback was specified we return
+ # that value inmediately. This saves us Rugged/gRPC invocations.
+ return fallback unless fallback.nil? || exists?
+
begin
value =
if memoize_only
@@ -1040,8 +1043,9 @@ class Repository
end
instance_variable_set(ivar, value)
rescue Rugged::ReferenceError, Gitlab::Git::Repository::NoRepository
- # if e.g. HEAD or the entire repository doesn't exist we want to
- # gracefully handle this and not cache anything.
+ # Even if the above `#exists?` check passes these errors might still
+ # occur (for example because of a non-existing HEAD). We want to
+ # gracefully handle this and not cache anything
fallback
end
end
@@ -1069,6 +1073,18 @@ class Repository
private
+ # TODO Generice finder, later split this on finders by Ref or Oid
+ # gitlab-org/gitlab-ce#39239
+ def find_commit(oid_or_ref)
+ commit = if oid_or_ref.is_a?(Gitlab::Git::Commit)
+ oid_or_ref
+ else
+ Gitlab::Git::Commit.find(raw_repository, oid_or_ref)
+ end
+
+ ::Commit.new(commit, @project) if commit
+ end
+
def blob_data_at(sha, path)
blob = blob_at(sha, path)
return unless blob
@@ -1107,12 +1123,12 @@ class Repository
def last_commit_for_path_by_gitaly(sha, path)
c = raw_repository.gitaly_commit_client.last_commit_for_path(sha, path)
- commit(c)
+ commit_by(oid: c)
end
def last_commit_for_path_by_rugged(sha, path)
sha = last_commit_id_for_path_by_shelling_out(sha, path)
- commit(sha)
+ commit_by(oid: sha)
end
def last_commit_id_for_path_by_shelling_out(sha, path)
diff --git a/app/models/service.rb b/app/models/service.rb
index 6b64079215f..fdd2605e3e3 100644
--- a/app/models/service.rb
+++ b/app/models/service.rb
@@ -238,6 +238,7 @@ class Service < ActiveRecord::Base
kubernetes
mattermost_slash_commands
mattermost
+ packagist
pipelines_email
pivotaltracker
prometheus
diff --git a/app/serializers/issuable_sidebar_entity.rb b/app/serializers/issuable_sidebar_entity.rb
new file mode 100644
index 00000000000..ff23d8bf0c7
--- /dev/null
+++ b/app/serializers/issuable_sidebar_entity.rb
@@ -0,0 +1,16 @@
+class IssuableSidebarEntity < Grape::Entity
+ include RequestAwareEntity
+
+ expose :participants, using: ::API::Entities::UserBasic do |issuable|
+ issuable.participants(request.current_user)
+ end
+
+ expose :subscribed do |issuable|
+ issuable.subscribed?(request.current_user, issuable.project)
+ end
+
+ expose :time_estimate
+ expose :total_time_spent
+ expose :human_time_estimate
+ expose :human_total_time_spent
+end
diff --git a/app/serializers/issue_serializer.rb b/app/serializers/issue_serializer.rb
index 4fff54a9126..2555595379b 100644
--- a/app/serializers/issue_serializer.rb
+++ b/app/serializers/issue_serializer.rb
@@ -1,3 +1,16 @@
class IssueSerializer < BaseSerializer
- entity IssueEntity
+ # This overrided method takes care of which entity should be used
+ # to serialize the `issue` based on `basic` key in `opts` param.
+ # Hence, `entity` doesn't need to be declared on the class scope.
+ def represent(merge_request, opts = {})
+ entity =
+ case opts[:serializer]
+ when 'sidebar'
+ IssueSidebarEntity
+ else
+ IssueEntity
+ end
+
+ super(merge_request, opts, entity)
+ end
end
diff --git a/app/serializers/issue_sidebar_entity.rb b/app/serializers/issue_sidebar_entity.rb
new file mode 100644
index 00000000000..6c823dbfe95
--- /dev/null
+++ b/app/serializers/issue_sidebar_entity.rb
@@ -0,0 +1,3 @@
+class IssueSidebarEntity < IssuableSidebarEntity
+ expose :assignees, using: API::Entities::UserBasic
+end
diff --git a/app/serializers/merge_request_basic_entity.rb b/app/serializers/merge_request_basic_entity.rb
index 8461f158bb5..d54a6516aed 100644
--- a/app/serializers/merge_request_basic_entity.rb
+++ b/app/serializers/merge_request_basic_entity.rb
@@ -1,11 +1,7 @@
-class MergeRequestBasicEntity < Grape::Entity
+class MergeRequestBasicEntity < IssuableSidebarEntity
expose :assignee_id
expose :merge_status
expose :merge_error
expose :state
expose :source_branch_exists?, as: :source_branch_exists
- expose :time_estimate
- expose :total_time_spent
- expose :human_time_estimate
- expose :human_total_time_spent
end
diff --git a/app/serializers/merge_request_serializer.rb b/app/serializers/merge_request_serializer.rb
index f67034ce47a..e9d98d8baca 100644
--- a/app/serializers/merge_request_serializer.rb
+++ b/app/serializers/merge_request_serializer.rb
@@ -3,7 +3,14 @@ class MergeRequestSerializer < BaseSerializer
# to serialize the `merge_request` based on `basic` key in `opts` param.
# Hence, `entity` doesn't need to be declared on the class scope.
def represent(merge_request, opts = {})
- entity = opts[:basic] ? MergeRequestBasicEntity : MergeRequestEntity
+ entity =
+ case opts[:serializer]
+ when 'basic', 'sidebar'
+ MergeRequestBasicEntity
+ else
+ MergeRequestEntity
+ end
+
super(merge_request, opts, entity)
end
end
diff --git a/app/services/issues/reopen_service.rb b/app/services/issues/reopen_service.rb
index 35de4337b15..62b4b4b6a1e 100644
--- a/app/services/issues/reopen_service.rb
+++ b/app/services/issues/reopen_service.rb
@@ -9,6 +9,7 @@ module Issues
notification_service.reopen_issue(issue, current_user)
execute_hooks(issue, 'reopen')
invalidate_cache_counts(issue, users: issue.assignees)
+ issue.update_project_counter_caches
end
issue
diff --git a/app/services/merge_requests/merge_service.rb b/app/services/merge_requests/merge_service.rb
index 8c5821aa870..156e7b2f078 100644
--- a/app/services/merge_requests/merge_service.rb
+++ b/app/services/merge_requests/merge_service.rb
@@ -82,16 +82,9 @@ module MergeRequests
@merge_request.can_remove_source_branch?(branch_deletion_user)
end
- # Logs merge error message and cleans `MergeRequest#merge_jid`.
- #
def handle_merge_error(log_message:, save_message_on_model: false)
Rails.logger.error("MergeService ERROR: #{merge_request_info} - #{log_message}")
-
- if save_message_on_model
- @merge_request.update(merge_error: log_message, merge_jid: nil)
- else
- clean_merge_jid
- end
+ @merge_request.update(merge_error: log_message) if save_message_on_model
end
def merge_request_info
diff --git a/app/services/merge_requests/reopen_service.rb b/app/services/merge_requests/reopen_service.rb
index b9c65be36ec..c599a90f9fe 100644
--- a/app/services/merge_requests/reopen_service.rb
+++ b/app/services/merge_requests/reopen_service.rb
@@ -11,6 +11,7 @@ module MergeRequests
merge_request.reload_diff(current_user)
merge_request.mark_as_unchecked
invalidate_cache_counts(merge_request, users: merge_request.assignees)
+ merge_request.update_project_counter_caches
end
merge_request
diff --git a/app/services/milestones/promote_service.rb b/app/services/milestones/promote_service.rb
new file mode 100644
index 00000000000..bd9cfd4e0ea
--- /dev/null
+++ b/app/services/milestones/promote_service.rb
@@ -0,0 +1,80 @@
+module Milestones
+ class PromoteService < Milestones::BaseService
+ PromoteMilestoneError = Class.new(StandardError)
+
+ def execute(milestone)
+ check_project_milestone!(milestone)
+
+ Milestone.transaction do
+ # Destroy all milestones with same title across projects
+ destroy_old_milestones(milestone)
+
+ group_milestone = clone_project_milestone(milestone)
+
+ move_children_to_group_milestone(group_milestone)
+
+ # Just to be safe
+ unless group_milestone.valid?
+ raise_error(group_milestone.errors.full_messages.to_sentence)
+ end
+
+ group_milestone
+ end
+ end
+
+ private
+
+ def milestone_ids_for_merge(group_milestone)
+ # Pluck need to be used here instead of select so the array of ids
+ # is persistent after old milestones gets deleted.
+ @milestone_ids_for_merge ||= begin
+ search_params = { title: group_milestone.title, project_ids: group_project_ids, state: 'all' }
+ milestones = MilestonesFinder.new(search_params).execute
+ milestones.pluck(:id)
+ end
+ end
+
+ def move_children_to_group_milestone(group_milestone)
+ milestone_ids_for_merge(group_milestone).in_groups_of(100) do |milestone_ids|
+ update_children(group_milestone, milestone_ids)
+ end
+ end
+
+ def check_project_milestone!(milestone)
+ raise_error('Only project milestones can be promoted.') unless milestone.project_milestone?
+ end
+
+ def clone_project_milestone(milestone)
+ params = milestone.slice(:title, :description, :start_date, :due_date, :state_event)
+
+ create_service = CreateService.new(group, current_user, params)
+
+ create_service.execute
+ end
+
+ def update_children(group_milestone, milestone_ids)
+ issues = Issue.where(project_id: group_project_ids, milestone_id: milestone_ids)
+ merge_requests = MergeRequest.where(source_project_id: group_project_ids, milestone_id: milestone_ids)
+
+ [issues, merge_requests].each do |issuable_collection|
+ issuable_collection.update_all(milestone_id: group_milestone.id)
+ end
+ end
+
+ def group
+ @group ||= parent.group || raise_error('Project does not belong to a group.')
+ end
+
+ def destroy_old_milestones(group_milestone)
+ Milestone.where(id: milestone_ids_for_merge(group_milestone)).destroy_all
+ end
+
+ def group_project_ids
+ @group_project_ids ||= group.projects.map(&:id)
+ end
+
+ def raise_error(message)
+ raise PromoteMilestoneError, "Promotion failed - #{message}"
+ end
+ end
+end
diff --git a/app/services/projects/hashed_storage_migration_service.rb b/app/services/projects/hashed_storage_migration_service.rb
index 41259de3a16..f5945f3b87f 100644
--- a/app/services/projects/hashed_storage_migration_service.rb
+++ b/app/services/projects/hashed_storage_migration_service.rb
@@ -10,7 +10,7 @@ module Projects
end
def execute
- return if project.hashed_storage?
+ return if project.hashed_storage?(:repository)
@old_disk_path = project.disk_path
has_wiki = project.wiki.repository_exists?
diff --git a/app/services/system_hooks_service.rb b/app/services/system_hooks_service.rb
index a1c2f8d0180..5d275967821 100644
--- a/app/services/system_hooks_service.rb
+++ b/app/services/system_hooks_service.rb
@@ -83,7 +83,7 @@ class SystemHooksService
project_id: model.id,
owner_name: owner.name,
owner_email: owner.respond_to?(:email) ? owner.email : "",
- project_visibility: Project.visibility_levels.key(model.visibility_level_value).downcase
+ project_visibility: model.visibility.downcase
}
end
diff --git a/app/services/users/last_push_event_service.rb b/app/services/users/last_push_event_service.rb
index f2bfb60604f..57e446d7f30 100644
--- a/app/services/users/last_push_event_service.rb
+++ b/app/services/users/last_push_event_service.rb
@@ -16,8 +16,8 @@ module Users
user_cache_key
]
- if event.project.forked?
- keys << project_cache_key(event.project.forked_from_project)
+ if forked_from = event.project.forked_from_project
+ keys << project_cache_key(forked_from)
end
keys.each { |key| set_key(key, event.id) }
diff --git a/app/uploaders/file_uploader.rb b/app/uploaders/file_uploader.rb
index 7027ac4b5db..d4ba3a028be 100644
--- a/app/uploaders/file_uploader.rb
+++ b/app/uploaders/file_uploader.rb
@@ -30,7 +30,7 @@ class FileUploader < GitlabUploader
#
# Returns a String without a trailing slash
def self.dynamic_path_segment(model)
- File.join(CarrierWave.root, base_dir, model.full_path)
+ File.join(CarrierWave.root, base_dir, model.disk_path)
end
attr_accessor :model
diff --git a/app/views/admin/application_settings/_form.html.haml b/app/views/admin/application_settings/_form.html.haml
index 2b23af9212e..3a4d5ce0b5c 100644
--- a/app/views/admin/application_settings/_form.html.haml
+++ b/app/views/admin/application_settings/_form.html.haml
@@ -533,11 +533,23 @@
%fieldset
%legend Git Storage Circuitbreaker settings
.form-group
- = f.label :circuitbreaker_failure_count_threshold, _('Maximum git storage failures'), class: 'control-label col-sm-2'
+ = f.label :circuitbreaker_access_retries, _('Number of access attempts'), class: 'control-label col-sm-2'
.col-sm-10
- = f.number_field :circuitbreaker_failure_count_threshold, class: 'form-control'
+ = f.number_field :circuitbreaker_access_retries, class: 'form-control'
.help-block
- = circuitbreaker_failure_count_help_text
+ = circuitbreaker_access_retries_help_text
+ .form-group
+ = f.label :circuitbreaker_storage_timeout, _('Seconds to wait for a storage access attempt'), class: 'control-label col-sm-2'
+ .col-sm-10
+ = f.number_field :circuitbreaker_storage_timeout, class: 'form-control'
+ .help-block
+ = circuitbreaker_storage_timeout_help_text
+ .form-group
+ = f.label :circuitbreaker_backoff_threshold, _('Number of failures before backing off'), class: 'control-label col-sm-2'
+ .col-sm-10
+ = f.number_field :circuitbreaker_backoff_threshold, class: 'form-control'
+ .help-block
+ = circuitbreaker_backoff_threshold_help_text
.form-group
= f.label :circuitbreaker_failure_wait_time, _('Seconds to wait after a storage failure'), class: 'control-label col-sm-2'
.col-sm-10
@@ -545,17 +557,17 @@
.help-block
= circuitbreaker_failure_wait_time_help_text
.form-group
- = f.label :circuitbreaker_failure_reset_time, _('Seconds before reseting failure information'), class: 'control-label col-sm-2'
+ = f.label :circuitbreaker_failure_count_threshold, _('Maximum git storage failures'), class: 'control-label col-sm-2'
.col-sm-10
- = f.number_field :circuitbreaker_failure_reset_time, class: 'form-control'
+ = f.number_field :circuitbreaker_failure_count_threshold, class: 'form-control'
.help-block
- = circuitbreaker_failure_reset_time_help_text
+ = circuitbreaker_failure_count_help_text
.form-group
- = f.label :circuitbreaker_storage_timeout, _('Seconds to wait for a storage access attempt'), class: 'control-label col-sm-2'
+ = f.label :circuitbreaker_failure_reset_time, _('Seconds before reseting failure information'), class: 'control-label col-sm-2'
.col-sm-10
- = f.number_field :circuitbreaker_storage_timeout, class: 'form-control'
+ = f.number_field :circuitbreaker_failure_reset_time, class: 'form-control'
.help-block
- = circuitbreaker_storage_timeout_help_text
+ = circuitbreaker_failure_reset_time_help_text
%fieldset
%legend Repository Checks
diff --git a/app/views/dashboard/_projects_head.html.haml b/app/views/dashboard/_projects_head.html.haml
index fd2ba9ac1ca..9038c4fbebd 100644
--- a/app/views/dashboard/_projects_head.html.haml
+++ b/app/views/dashboard/_projects_head.html.haml
@@ -6,13 +6,13 @@
.fade-right= icon('angle-right')
%ul.nav-links.scrolling-tabs
= nav_link(page: [dashboard_projects_path, root_path]) do
- = link_to dashboard_projects_path, title: 'Home', class: 'shortcuts-activity', data: {placement: 'right'} do
+ = link_to dashboard_projects_path, class: 'shortcuts-activity', data: {placement: 'right'} do
Your projects
= nav_link(page: starred_dashboard_projects_path) do
- = link_to starred_dashboard_projects_path, title: 'Starred Projects', data: {placement: 'right'} do
+ = link_to starred_dashboard_projects_path, data: {placement: 'right'} do
Starred projects
= nav_link(page: [explore_root_path, trending_explore_projects_path, starred_explore_projects_path, explore_projects_path]) do
- = link_to explore_root_path, title: 'Explore', data: {placement: 'right'} do
+ = link_to explore_root_path, data: {placement: 'right'} do
Explore projects
.nav-controls
diff --git a/app/views/groups/milestones/_form.html.haml b/app/views/groups/milestones/_form.html.haml
index cc879e5a308..a1be0d3220a 100644
--- a/app/views/groups/milestones/_form.html.haml
+++ b/app/views/groups/milestones/_form.html.haml
@@ -11,7 +11,7 @@
= f.label :description, "Description", class: "control-label"
.col-sm-10
= render layout: 'projects/md_preview', locals: { url: group_preview_markdown_path } do
- = render 'projects/zen', f: f, attr: :description, classes: 'note-textarea', placeholder: 'Write milestone description...'
+ = render 'projects/zen', f: f, attr: :description, classes: 'note-textarea', placeholder: 'Write milestone description...', supports_autocomplete: false
.clearfix
.error-alert
diff --git a/app/views/help/index.html.haml b/app/views/help/index.html.haml
index c25eae63eec..d0c2e0b1d69 100644
--- a/app/views/help/index.html.haml
+++ b/app/views/help/index.html.haml
@@ -11,6 +11,7 @@
%span= Gitlab::VERSION
%small= link_to Gitlab::REVISION, Gitlab::COM_URL + namespace_project_commits_path('gitlab-org', 'gitlab-ce', Gitlab::REVISION)
= version_status_badge
+
%p.slead
GitLab is open source software to collaborate on code.
%br
@@ -23,6 +24,7 @@
Used by more than 100,000 organizations, GitLab is the most popular solution to manage git repositories on-premises.
%br
Read more about GitLab at #{link_to promo_host, promo_url, target: '_blank', rel: 'noopener noreferrer'}.
+ %p= link_to 'Check the current instance configuration ', help_instance_configuration_url
%hr
.row.prepend-top-default
diff --git a/app/views/help/instance_configuration.html.haml b/app/views/help/instance_configuration.html.haml
new file mode 100644
index 00000000000..f09e3825a4b
--- /dev/null
+++ b/app/views/help/instance_configuration.html.haml
@@ -0,0 +1,17 @@
+- page_title 'Instance Configuration'
+.wiki.documentation
+ %h1 Instance Configuration
+
+ %p
+ In this page you will find information about the settings that are used in your current instance.
+
+ = render 'help/instance_configuration/ssh_info'
+ = render 'help/instance_configuration/gitlab_pages'
+ = render 'help/instance_configuration/gitlab_ci'
+ %p
+ %strong Table of contents
+
+ %ul
+ = content_for :table_content
+
+ = content_for :settings_content
diff --git a/app/views/help/instance_configuration/_gitlab_ci.html.haml b/app/views/help/instance_configuration/_gitlab_ci.html.haml
new file mode 100644
index 00000000000..7fa8bd086d4
--- /dev/null
+++ b/app/views/help/instance_configuration/_gitlab_ci.html.haml
@@ -0,0 +1,24 @@
+- content_for :table_content do
+ %li= link_to 'GitLab CI', '#gitlab-ci'
+
+- content_for :settings_content do
+ %h2#gitlab-ci
+ GitLab CI
+
+ %p
+ Below are the current settings regarding
+ = succeed('.') { link_to('GitLab CI', 'https://about.gitlab.com/gitlab-ci', target: '_blank') }
+
+ .table-responsive
+ %table
+ %thead
+ %tr
+ %th Setting
+ %th= instance_configuration_host(@instance_configuration.settings[:host])
+ %th Default
+ %tbody
+ %tr
+ - artifacts_size = @instance_configuration.settings[:gitlab_ci][:artifacts_max_size]
+ %td Artifacts maximum size
+ %td= instance_configuration_human_size_cell(artifacts_size[:value])
+ %td= instance_configuration_human_size_cell(artifacts_size[:default])
diff --git a/app/views/help/instance_configuration/_gitlab_pages.html.haml b/app/views/help/instance_configuration/_gitlab_pages.html.haml
new file mode 100644
index 00000000000..bdd77730dcc
--- /dev/null
+++ b/app/views/help/instance_configuration/_gitlab_pages.html.haml
@@ -0,0 +1,35 @@
+- gitlab_pages = @instance_configuration.settings[:gitlab_pages]
+- content_for :table_content do
+ %li= link_to 'GitLab Pages', '#gitlab-pages'
+
+- content_for :settings_content do
+ %h2#gitlab-pages
+ GitLab Pages
+
+ %p
+ Below are the settings for
+ = succeed('.') { link_to('Gitlab Pages', gitlab_pages[:url], target: '_blank') }
+ .table-responsive
+ %table
+ %thead
+ %tr
+ %th Setting
+ %th= instance_configuration_host(@instance_configuration.settings[:host])
+ %tbody
+ %tr
+ %td Domain Name
+ %td
+ %code= instance_configuration_cell_html(gitlab_pages[:host])
+ %tr
+ %td IP Address
+ %td
+ %code= instance_configuration_cell_html(gitlab_pages[:ip_address])
+ %tr
+ %td Port
+ %td
+ %code= instance_configuration_cell_html(gitlab_pages[:port])
+ %br
+
+ %p
+ The maximum size of your Pages site is regulated by the artifacts maximum
+ size which is part of #{succeed('.') { link_to('GitLab CI', '#gitlab-ci') }}
diff --git a/app/views/help/instance_configuration/_ssh_info.html.haml b/app/views/help/instance_configuration/_ssh_info.html.haml
new file mode 100644
index 00000000000..987cc61b3f6
--- /dev/null
+++ b/app/views/help/instance_configuration/_ssh_info.html.haml
@@ -0,0 +1,27 @@
+- ssh_info = @instance_configuration.settings[:ssh_algorithms_hashes]
+- if ssh_info.any?
+ - content_for :table_content do
+ %li= link_to 'SSH host keys fingerprints', '#ssh-host-keys-fingerprints'
+
+ - content_for :settings_content do
+ %h2#ssh-host-keys-fingerprints
+ SSH host keys fingerprints
+
+ %p
+ Below are the fingerprints for the current instance SSH host keys.
+
+ .table-responsive
+ %table
+ %thead
+ %tr
+ %th Algorithm
+ %th MD5
+ %th SHA256
+ %tbody
+ - ssh_info.each do |algorithm|
+ %tr
+ %td= algorithm[:name]
+ %td
+ %code= instance_configuration_cell_html(algorithm[:md5])
+ %td
+ %code= instance_configuration_cell_html(algorithm[:sha256])
diff --git a/app/views/layouts/nav/sidebar/_project.html.haml b/app/views/layouts/nav/sidebar/_project.html.haml
index f82207559a3..66146e61263 100644
--- a/app/views/layouts/nav/sidebar/_project.html.haml
+++ b/app/views/layouts/nav/sidebar/_project.html.haml
@@ -274,7 +274,7 @@
Members
%ul.sidebar-sub-level-items.is-fly-out-only
= nav_link(path: %w[members#show], html_options: { class: "fly-out-top-item" } ) do
- = link_to project_settings_members_path(@project) do
+ = link_to project_project_members_path(@project) do
%strong.fly-out-top-item-name
#{ _('Members') }
diff --git a/app/views/peek/views/_gitaly.html.haml b/app/views/peek/views/_gitaly.html.haml
new file mode 100644
index 00000000000..a7d040d6821
--- /dev/null
+++ b/app/views/peek/views/_gitaly.html.haml
@@ -0,0 +1,7 @@
+- local_assigns.fetch(:view)
+
+%strong
+ %span{ data: { defer_to: "#{view.defer_key}-duration" } } ...
+ \/
+ %span{ data: { defer_to: "#{view.defer_key}-calls" } } ...
+ Gitaly
diff --git a/app/views/projects/branches/_branch.html.haml b/app/views/projects/branches/_branch.html.haml
index 49101d1efa4..6e02ae6c9cc 100644
--- a/app/views/projects/branches/_branch.html.haml
+++ b/app/views/projects/branches/_branch.html.haml
@@ -1,3 +1,4 @@
+- merged = local_assigns.fetch(:merged, false)
- commit = @repository.commit(branch.dereferenced_target)
- bar_graph_width_factor = @max_commits > 0 ? 100.0/@max_commits : 0
- diverging_commit_counts = @repository.diverging_commit_counts(branch)
@@ -12,7 +13,7 @@
&nbsp;
- if branch.name == @repository.root_ref
%span.label.label-primary default
- - elsif @repository.merged_to_root_ref? branch.name
+ - elsif merged
%span.label.label-info.has-tooltip{ title: s_('Branches|Merged into %{default_branch}') % { default_branch: @repository.root_ref } }
= s_('Branches|merged')
@@ -47,7 +48,7 @@
target: "#modal-delete-branch",
delete_path: project_branch_path(@project, branch.name),
branch_name: branch.name,
- is_merged: ("true" if @repository.merged_to_root_ref?(branch.name)) } }
+ is_merged: ("true" if merged) } }
= icon("trash-o")
- else
%button{ class: "btn btn-remove remove-row js-ajax-loading-spinner has-tooltip disabled",
diff --git a/app/views/projects/branches/index.html.haml b/app/views/projects/branches/index.html.haml
index 7d9645d79e6..aade310236e 100644
--- a/app/views/projects/branches/index.html.haml
+++ b/app/views/projects/branches/index.html.haml
@@ -38,7 +38,7 @@
- if @branches.any?
%ul.content-list.all-branches
- @branches.each do |branch|
- = render "projects/branches/branch", branch: branch
+ = render "projects/branches/branch", branch: branch, merged: @repository.merged_to_root_ref?(branch, @merged_branch_names)
= paginate @branches, theme: 'gitlab'
- else
.nothing-here-block
diff --git a/app/views/projects/clusters/show.html.haml b/app/views/projects/clusters/show.html.haml
index ff76abc3553..b127e06030e 100644
--- a/app/views/projects/clusters/show.html.haml
+++ b/app/views/projects/clusters/show.html.haml
@@ -47,7 +47,7 @@
- if can?(current_user, :update_cluster, @cluster)
.form-group
- = field.submit s_('ClusterIntegration|Save'), class: 'btn btn-success'
+ = field.submit _('Save'), class: 'btn btn-success'
%section.settings#js-cluster-details
.settings-header
@@ -68,7 +68,7 @@
%section.settings#js-cluster-advanced-settings
.settings-header
- %h4= s_('ClusterIntegration|Advanced settings')
+ %h4= _('Advanced settings')
%button.btn.js-settings-toggle
= expanded ? 'Collapse' : 'Expand'
%p= s_('ClusterIntegration|Manage Cluster integration on your GitLab project')
diff --git a/app/views/projects/commit/_commit_box.html.haml b/app/views/projects/commit/_commit_box.html.haml
index 09bcd187e59..ff17372fdd9 100644
--- a/app/views/projects/commit/_commit_box.html.haml
+++ b/app/views/projects/commit/_commit_box.html.haml
@@ -77,5 +77,6 @@
#{ n_(s_('Pipeline|with stage'), s_('Pipeline|with stages'), last_pipeline.stages_count) }
.mr-widget-pipeline-graph
= render 'shared/mini_pipeline_graph', pipeline: last_pipeline, klass: 'js-commit-pipeline-graph'
- in
- = time_interval_in_words last_pipeline.duration
+ - if last_pipeline.duration
+ in
+ = time_interval_in_words last_pipeline.duration
diff --git a/app/views/projects/empty.html.haml b/app/views/projects/empty.html.haml
index c9956183e12..af564b93dc3 100644
--- a/app/views/projects/empty.html.haml
+++ b/app/views/projects/empty.html.haml
@@ -72,6 +72,7 @@
%pre.light-well
:preserve
cd existing_repo
+ git remote rename origin old-origin
git remote add origin #{ content_tag(:span, default_url_to_repo, class: 'clone')}
git push -u origin --all
git push -u origin --tags
diff --git a/app/views/projects/issues/edit.html.haml b/app/views/projects/issues/edit.html.haml
new file mode 100644
index 00000000000..1b7d878c38c
--- /dev/null
+++ b/app/views/projects/issues/edit.html.haml
@@ -0,0 +1,7 @@
+- page_title "Edit", "#{@issue.title} (#{@issue.to_reference})", "Issues"
+
+%h3.page-title
+ Edit Issue ##{@issue.iid}
+%hr
+
+= render "form"
diff --git a/app/views/projects/milestones/show.html.haml b/app/views/projects/milestones/show.html.haml
index a5153df1159..9fc297ab7f6 100644
--- a/app/views/projects/milestones/show.html.haml
+++ b/app/views/projects/milestones/show.html.haml
@@ -23,14 +23,18 @@
= milestone_date_range(@milestone)
.milestone-buttons
- if can?(current_user, :admin_milestone, @project)
+ = link_to edit_project_milestone_path(@project, @milestone), class: "btn btn-grouped btn-nr" do
+ Edit
+
+ - if @project.group
+ = link_to promote_project_milestone_path(@milestone.project, @milestone), title: "Promote to Group Milestone", class: 'btn btn-grouped', data: { confirm: "Promoting this milestone will make it available for all projects inside the group. Existing project milestones with the same name will be merged. Are you sure?", toggle: "tooltip" }, method: :post do
+ Promote
+
- if @milestone.active?
= link_to 'Close milestone', project_milestone_path(@project, @milestone, milestone: {state_event: :close }), method: :put, class: "btn btn-close btn-nr btn-grouped"
- else
= link_to 'Reopen milestone', project_milestone_path(@project, @milestone, milestone: {state_event: :activate }), method: :put, class: "btn btn-reopen btn-nr btn-grouped"
- = link_to edit_project_milestone_path(@project, @milestone), class: "btn btn-grouped btn-nr" do
- Edit
-
= link_to project_milestone_path(@project, @milestone), data: { confirm: 'Are you sure?' }, method: :delete, class: "btn btn-grouped btn-danger" do
Delete
@@ -40,6 +44,7 @@
.detail-page-description.milestone-detail
%h2.title
= markdown_field(@milestone, :title)
+
%div
- if @milestone.description.present?
.description
diff --git a/app/views/projects/tree/_tree_header.html.haml b/app/views/projects/tree/_tree_header.html.haml
index 6cddc38d11a..c02f7ee37ed 100644
--- a/app/views/projects/tree/_tree_header.html.haml
+++ b/app/views/projects/tree/_tree_header.html.haml
@@ -1,13 +1,15 @@
.tree-ref-container
.tree-ref-holder
- = render 'shared/ref_switcher', destination: 'tree', path: @path
+ = render 'shared/ref_switcher', destination: 'tree', path: @path, show_create: true
- - unless show_new_repo?
+ - if show_new_repo? && can_push_branch?(@project, @ref)
+ .js-new-dropdown
+ - else
= render 'projects/tree/old_tree_header'
.tree-controls
- if show_new_repo?
- = render 'shared/repo/editable_mode'
+ .editable-mode
- else
= link_to s_('Commits|History'), project_commits_path(@project, @id), class: 'btn'
diff --git a/app/views/shared/_ref_switcher.html.haml b/app/views/shared/_ref_switcher.html.haml
index 7ad743b3b81..6d7c9633913 100644
--- a/app/views/shared/_ref_switcher.html.haml
+++ b/app/views/shared/_ref_switcher.html.haml
@@ -1,3 +1,4 @@
+- show_new_branch_form = show_new_repo? && show_create && can?(current_user, :push_code, @project)
- dropdown_toggle_text = @ref || @project.default_branch
= form_tag switch_project_refs_path(@project), method: :get, class: "project-refs-form" do
= hidden_field_tag :destination, destination
@@ -7,8 +8,20 @@
= hidden_field_tag key, value, id: nil
.dropdown
= dropdown_toggle dropdown_toggle_text, { toggle: "dropdown", selected: dropdown_toggle_text, ref: @ref, refs_url: refs_project_path(@project), field_name: 'ref', submit_form_on_click: true, visit: true }, { toggle_class: "js-project-refs-dropdown" }
- .dropdown-menu.dropdown-menu-selectable.git-revision-dropdown{ class: ("dropdown-menu-align-right" if local_assigns[:align_right]) }
- = dropdown_title _("Switch branch/tag")
- = dropdown_filter _("Search branches and tags")
- = dropdown_content
- = dropdown_loading
+ .dropdown-menu.dropdown-menu-selectable.git-revision-dropdown.dropdown-menu-paging{ class: ("dropdown-menu-align-right" if local_assigns[:align_right]) }
+ .dropdown-page-one
+ = dropdown_title _("Switch branch/tag")
+ = dropdown_filter _("Search branches and tags")
+ = dropdown_content
+ = dropdown_loading
+ - if show_new_branch_form
+ = dropdown_footer do
+ %ul.dropdown-footer-list
+ %li
+ %a.dropdown-toggle-page{ href: "#" }
+ Create new branch
+ - if show_new_branch_form
+ .dropdown-page-two
+ = dropdown_title("Create new branch", options: { back: true })
+ = dropdown_content do
+ .js-new-branch-dropdown
diff --git a/app/views/shared/issuable/_participants.html.haml b/app/views/shared/issuable/_participants.html.haml
deleted file mode 100644
index d2b62557e03..00000000000
--- a/app/views/shared/issuable/_participants.html.haml
+++ /dev/null
@@ -1,18 +0,0 @@
-- participants_row = 7
-- participants_size = participants.size
-- participants_extra = participants_size - participants_row
-.block.participants
- .sidebar-collapsed-icon
- = icon('users')
- %span
- = participants.count
- .title.hide-collapsed
- = pluralize participants.count, "participant"
- .hide-collapsed.participants-list
- - participants.each do |participant|
- .participants-author.js-participants-author
- = link_to_member(@project, participant, name: false, size: 24, lazy_load: true)
- - if participants_extra > 0
- .hide-collapsed.participants-more
- %a.js-participants-more{ href: "#", data: { original_text: "+ #{participants_size - 7} more", less_text: "- show less" } }
- + #{participants_extra} more
diff --git a/app/views/shared/issuable/_search_bar.html.haml b/app/views/shared/issuable/_search_bar.html.haml
index 161b1c9fd72..fabb17c7340 100644
--- a/app/views/shared/issuable/_search_bar.html.haml
+++ b/app/views/shared/issuable/_search_bar.html.haml
@@ -25,7 +25,6 @@
%ul.tokens-container.list-unstyled
%li.input-token
%input.form-control.filtered-search{ search_filter_input_options(type) }
- = icon('filter')
#js-dropdown-hint.filtered-search-input-dropdown-menu.dropdown-menu.hint-dropdown
%ul{ data: { dropdown: true } }
%li.filter-dropdown-item{ data: { action: 'submit' } }
diff --git a/app/views/shared/issuable/_sidebar.html.haml b/app/views/shared/issuable/_sidebar.html.haml
index 7b7411b1e23..e0009a35b9f 100644
--- a/app/views/shared/issuable/_sidebar.html.haml
+++ b/app/views/shared/issuable/_sidebar.html.haml
@@ -123,17 +123,10 @@
%script#js-lock-issue-data{ type: "application/json" }= { is_locked: issuable.discussion_locked?, is_editable: can_edit_issuable }.to_json.html_safe
#js-lock-entry-point
- = render "shared/issuable/participants", participants: issuable.participants(current_user)
+ .js-sidebar-participants-entry-point
+
- if current_user
- - subscribed = issuable.subscribed?(current_user, @project)
- .block.light.subscription{ data: { url: toggle_subscription_path(issuable) } }
- .sidebar-collapsed-icon
- = icon('rss', 'aria-hidden': 'true')
- %span.issuable-header-text.hide-collapsed.pull-left
- Notifications
- - subscribtion_status = subscribed ? 'subscribed' : 'unsubscribed'
- %button.btn.btn-default.pull-right.js-subscribe-button.issuable-subscribe-button.hide-collapsed{ type: "button" }
- %span= subscribed ? 'Unsubscribe' : 'Subscribe'
+ .js-sidebar-subscriptions-entry-point
- project_ref = cross_project_reference(@project, issuable)
.block.project-reference
diff --git a/app/views/shared/milestones/_milestone.html.haml b/app/views/shared/milestones/_milestone.html.haml
index 305e2542281..7ba8f9d4313 100644
--- a/app/views/shared/milestones/_milestone.html.haml
+++ b/app/views/shared/milestones/_milestone.html.haml
@@ -49,6 +49,13 @@
= link_to edit_project_milestone_path(milestone.project, milestone), class: "btn btn-xs btn-grouped" do
Edit
\
+
+ - if @project.group
+ = link_to promote_project_milestone_path(milestone.project, milestone), title: "Promote to Group Milestone", class: 'btn btn-xs btn-grouped', data: { confirm: "Promoting this milestone will make it available for all projects inside the group. Existing project milestones with the same name will be merged. Are you sure?", toggle: "tooltip" }, method: :post do
+ Promote
+
= link_to 'Close Milestone', project_milestone_path(@project, milestone, milestone: {state_event: :close }), method: :put, remote: true, class: "btn btn-xs btn-close btn-grouped"
+
= link_to project_milestone_path(milestone.project, milestone), data: { confirm: 'Are you sure?' }, method: :delete, class: "btn btn-xs btn-remove btn-grouped" do
Delete
+
diff --git a/app/views/shared/repo/_editable_mode.html.haml b/app/views/shared/repo/_editable_mode.html.haml
deleted file mode 100644
index 73fdb8b523f..00000000000
--- a/app/views/shared/repo/_editable_mode.html.haml
+++ /dev/null
@@ -1,2 +0,0 @@
-.editable-mode
- %repo-edit-button
diff --git a/app/views/shared/repo/_repo.html.haml b/app/views/shared/repo/_repo.html.haml
index 7185f5bcc5b..5867ea58378 100644
--- a/app/views/shared/repo/_repo.html.haml
+++ b/app/views/shared/repo/_repo.html.haml
@@ -1,10 +1,12 @@
#repo{ data: { root: @path.empty?.to_s,
+ root_url: project_tree_path(project),
url: content_url,
+ current_branch: @ref,
+ ref: @commit.id,
project_name: project.name,
- refs_url: refs_project_path(project, format: :json),
project_url: project_path(project),
project_id: project.id,
- blob_url: namespace_project_blob_path(project.namespace, project, '{{branch}}'),
- new_mr_template_url: namespace_project_new_merge_request_path(project.namespace, project, merge_request: { source_branch: '{{source_branch}}' }),
+ new_merge_request_url: namespace_project_new_merge_request_path(project.namespace, project, merge_request: { source_branch: '' }),
can_commit: (!!can_push_branch?(project, @ref)).to_s,
- on_top_of_branch: (!!on_top_of_branch?(project, @ref)).to_s } }
+ on_top_of_branch: (!!on_top_of_branch?(project, @ref)).to_s,
+ current_path: @path } }
diff --git a/app/workers/stuck_merge_jobs_worker.rb b/app/workers/stuck_merge_jobs_worker.rb
index 7843179d77c..a396c0f27b2 100644
--- a/app/workers/stuck_merge_jobs_worker.rb
+++ b/app/workers/stuck_merge_jobs_worker.rb
@@ -23,7 +23,7 @@ class StuckMergeJobsWorker
merge_requests = MergeRequest.where(id: completed_ids)
merge_requests.where.not(merge_commit_sha: nil).update_all(state: :merged)
- merge_requests.where(merge_commit_sha: nil).update_all(state: :opened)
+ merge_requests.where(merge_commit_sha: nil).update_all(state: :opened, merge_jid: nil)
Rails.logger.info("Updated state of locked merge jobs. JIDs: #{completed_jids.join(', ')}")
end
diff --git a/changelogs/unreleased/13637-show-account-confirmation-link-in-e-mail-text.yml b/changelogs/unreleased/13637-show-account-confirmation-link-in-e-mail-text.yml
deleted file mode 100644
index 5f98d0cc766..00000000000
--- a/changelogs/unreleased/13637-show-account-confirmation-link-in-e-mail-text.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Confirmation email shows link as text instead of human readable text
-merge_request: 14243
-author: bitsapien
-type: changed
diff --git a/changelogs/unreleased/13711-allow-same-period-housekeeping.yml b/changelogs/unreleased/13711-allow-same-period-housekeeping.yml
deleted file mode 100644
index 607a8683aff..00000000000
--- a/changelogs/unreleased/13711-allow-same-period-housekeeping.yml
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: Allow to use same periods for different housekeeping tasks (effectively
- skipping the lesser task)
-merge_request: 13711
-author: cernvcs
-type: added
diff --git a/changelogs/unreleased/14395-upgrade-gitlab-markup.yml b/changelogs/unreleased/14395-upgrade-gitlab-markup.yml
deleted file mode 100644
index d1f90fe5eb1..00000000000
--- a/changelogs/unreleased/14395-upgrade-gitlab-markup.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Upgrade gitlab-markup gem
-merge_request: 14395
-author: Markus Koller
-type: other
diff --git a/changelogs/unreleased/14553-missing-space-in-log-msg.yml b/changelogs/unreleased/14553-missing-space-in-log-msg.yml
deleted file mode 100644
index a0420d49770..00000000000
--- a/changelogs/unreleased/14553-missing-space-in-log-msg.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: "Add missing space in Sidekiq memory killer log message"
-merge_request: 14553
-author: Benjamin Drung
-type: fixed
diff --git a/changelogs/unreleased/14970-suggest-rename-remote.yml b/changelogs/unreleased/14970-suggest-rename-remote.yml
new file mode 100644
index 00000000000..68a77eb446d
--- /dev/null
+++ b/changelogs/unreleased/14970-suggest-rename-remote.yml
@@ -0,0 +1,5 @@
+---
+title: Suggest to rename the remote for existing repository instructions
+merge_request: 14970
+author: helmo42
+type: added
diff --git a/changelogs/unreleased/18308-escape-characters.yml b/changelogs/unreleased/18308-escape-characters.yml
deleted file mode 100644
index 8766e971490..00000000000
--- a/changelogs/unreleased/18308-escape-characters.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Escape quotes in git username
-merge_request: 14020
-author: Brandon Everett
-type: fixed
diff --git a/changelogs/unreleased/18608-lock-issues.yml b/changelogs/unreleased/18608-lock-issues.yml
deleted file mode 100644
index 7d907f744f6..00000000000
--- a/changelogs/unreleased/18608-lock-issues.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-title: Discussion lock for issues and merge requests
-merge_request:
-author:
-type: added
diff --git a/changelogs/unreleased/20049-projects-api-forks.yml b/changelogs/unreleased/20049-projects-api-forks.yml
deleted file mode 100644
index c6470620f57..00000000000
--- a/changelogs/unreleased/20049-projects-api-forks.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add an API endpoint to determine the forks of a project
-merge_request:
-author:
-type: added
diff --git a/changelogs/unreleased/20824-scope-users-to-members-in-group-issuable-list.yml b/changelogs/unreleased/20824-scope-users-to-members-in-group-issuable-list.yml
deleted file mode 100644
index 245b8129de8..00000000000
--- a/changelogs/unreleased/20824-scope-users-to-members-in-group-issuable-list.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Return only group's members in user dropdowns on issuables list pages
-merge_request: 14249
-author:
-type: changed
diff --git a/changelogs/unreleased/21331-improve-confusing-compare-page.yml b/changelogs/unreleased/21331-improve-confusing-compare-page.yml
deleted file mode 100644
index 469cc04930b..00000000000
--- a/changelogs/unreleased/21331-improve-confusing-compare-page.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Make the labels in the Compare form less confusing
-merge_request: 14225
-author:
-type: changed
diff --git a/changelogs/unreleased/23000-pages-api.yml b/changelogs/unreleased/23000-pages-api.yml
new file mode 100644
index 00000000000..9f6fa13dd07
--- /dev/null
+++ b/changelogs/unreleased/23000-pages-api.yml
@@ -0,0 +1,5 @@
+---
+title: Add API endpoints for Pages Domains
+merge_request: 13917
+author: Travis Miller
+type: added
diff --git a/changelogs/unreleased/23206-load-participants-async.yml b/changelogs/unreleased/23206-load-participants-async.yml
new file mode 100644
index 00000000000..12ab43fb88f
--- /dev/null
+++ b/changelogs/unreleased/23206-load-participants-async.yml
@@ -0,0 +1,5 @@
+---
+title: Update participants and subscriptions button in issuable sidebar to be async
+merge_request: 14836
+author:
+type: changed
diff --git a/changelogs/unreleased/23888-fix-unsubscription-link-for-snippet-notification.yml b/changelogs/unreleased/23888-fix-unsubscription-link-for-snippet-notification.yml
deleted file mode 100644
index 36bed037160..00000000000
--- a/changelogs/unreleased/23888-fix-unsubscription-link-for-snippet-notification.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Don't show an "Unsubscribe" link in snippet comment notifications
-merge_request: 14764
-author:
-type: fixed
diff --git a/changelogs/unreleased/24121_extract_yet_another_users_finder.yml b/changelogs/unreleased/24121_extract_yet_another_users_finder.yml
deleted file mode 100644
index e43e97303e2..00000000000
--- a/changelogs/unreleased/24121_extract_yet_another_users_finder.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Extract AutocompleteController#users into finder
-merge_request: 13778
-author: Maxim Rydkin, Mayra Cabrera
-type: other
diff --git a/changelogs/unreleased/26890-fix-default-branches-sorting.yml b/changelogs/unreleased/26890-fix-default-branches-sorting.yml
deleted file mode 100644
index cf7060190b3..00000000000
--- a/changelogs/unreleased/26890-fix-default-branches-sorting.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix the default branches sorting to actually be 'Last updated'
-merge_request: 14295
-author:
-type: fixed
diff --git a/changelogs/unreleased/28202_decrease_abc_threshold_step5.yml b/changelogs/unreleased/28202_decrease_abc_threshold_step5.yml
new file mode 100644
index 00000000000..1bff4d6930d
--- /dev/null
+++ b/changelogs/unreleased/28202_decrease_abc_threshold_step5.yml
@@ -0,0 +1,5 @@
+---
+title: Decrease ABC threshold to 54.28
+merge_request: 14920
+author: Maxim Rydkin
+type: other
diff --git a/changelogs/unreleased/31358_decrease_perceived_complexity_threshold_step2.yml b/changelogs/unreleased/31358_decrease_perceived_complexity_threshold_step2.yml
deleted file mode 100644
index 6036e1a43a0..00000000000
--- a/changelogs/unreleased/31358_decrease_perceived_complexity_threshold_step2.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Decrease Perceived Complexity threshold to 15
-merge_request: 14160
-author: Maxim Rydkin
-type: other
diff --git a/changelogs/unreleased/31362_decrease_cyclomatic_complexity_threshold_step4.yml b/changelogs/unreleased/31362_decrease_cyclomatic_complexity_threshold_step4.yml
deleted file mode 100644
index a404456198a..00000000000
--- a/changelogs/unreleased/31362_decrease_cyclomatic_complexity_threshold_step4.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Decrease Cyclomatic Complexity threshold to 13
-merge_request: 14152
-author: Maxim Rydkin
-type: other
diff --git a/changelogs/unreleased/31454-missing-project-id-pipeline-hook-data.yml b/changelogs/unreleased/31454-missing-project-id-pipeline-hook-data.yml
new file mode 100644
index 00000000000..daf7ac715bd
--- /dev/null
+++ b/changelogs/unreleased/31454-missing-project-id-pipeline-hook-data.yml
@@ -0,0 +1,5 @@
+---
+title: Adds project_id to pipeline hook data
+merge_request: 15044
+author: Jacopo Beschi @jacopo-beschi
+type: added
diff --git a/changelogs/unreleased/32163-protected-branch-form-should-have-sane-defaults-for-dropdowns.yml b/changelogs/unreleased/32163-protected-branch-form-should-have-sane-defaults-for-dropdowns.yml
deleted file mode 100644
index 6110e245013..00000000000
--- a/changelogs/unreleased/32163-protected-branch-form-should-have-sane-defaults-for-dropdowns.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Added defaults for protected branches dropdowns on the repository settings
-merge_request: 14278
-author:
-type: changed
diff --git a/changelogs/unreleased/32318-filter-icon.yml b/changelogs/unreleased/32318-filter-icon.yml
new file mode 100644
index 00000000000..71e7c2c4dac
--- /dev/null
+++ b/changelogs/unreleased/32318-filter-icon.yml
@@ -0,0 +1,5 @@
+---
+title: Remove filter icon from search bar
+merge_request:
+author:
+type: other
diff --git a/changelogs/unreleased/33328-usage-ping-for-gitlab-features-and-components.yml b/changelogs/unreleased/33328-usage-ping-for-gitlab-features-and-components.yml
deleted file mode 100644
index d3aac241b75..00000000000
--- a/changelogs/unreleased/33328-usage-ping-for-gitlab-features-and-components.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Adds gitlab features and components to usage ping data.
-merge_request: 14305
-author:
-type: other
diff --git a/changelogs/unreleased/33493-attempt-to-link-saml-users-to-ldap-by-email.yml b/changelogs/unreleased/33493-attempt-to-link-saml-users-to-ldap-by-email.yml
deleted file mode 100644
index 727f3cecd52..00000000000
--- a/changelogs/unreleased/33493-attempt-to-link-saml-users-to-ldap-by-email.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Link SAML users to LDAP by email.
-merge_request: 14216
-author:
-type: changed
diff --git a/changelogs/unreleased/34102-online-view-of-artifacts-fe.yml b/changelogs/unreleased/34102-online-view-of-artifacts-fe.yml
deleted file mode 100644
index ce83b140eb6..00000000000
--- a/changelogs/unreleased/34102-online-view-of-artifacts-fe.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add online view of HTML artifacts for public projects
-merge_request: 14399
-author:
-type: added
diff --git a/changelogs/unreleased/34259-project-denial-of-service-via-gitmodules-fix.yml b/changelogs/unreleased/34259-project-denial-of-service-via-gitmodules-fix.yml
deleted file mode 100644
index 8260f7fa4b2..00000000000
--- a/changelogs/unreleased/34259-project-denial-of-service-via-gitmodules-fix.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fixes project denial of service via gitmodules using Extended ASCII.
-merge_request: 14301
-author:
-type: fixed
diff --git a/changelogs/unreleased/34366-issue-sidebar-don-t-render-participants-in-collapsed-state.yml b/changelogs/unreleased/34366-issue-sidebar-don-t-render-participants-in-collapsed-state.yml
deleted file mode 100644
index d34e685b5f5..00000000000
--- a/changelogs/unreleased/34366-issue-sidebar-don-t-render-participants-in-collapsed-state.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Load sidebar participants avatars only when visible
-merge_request: 14270
-author:
-type: other
diff --git a/changelogs/unreleased/34371-cycle-analitcs-global.yml b/changelogs/unreleased/34371-cycle-analitcs-global.yml
deleted file mode 100644
index 5e9f0a85e9a..00000000000
--- a/changelogs/unreleased/34371-cycle-analitcs-global.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Removes cycle analytics service and store from global namespace
-merge_request:
-author:
-type: other
diff --git a/changelogs/unreleased/34510-board-issues-sql-speedup.yml b/changelogs/unreleased/34510-board-issues-sql-speedup.yml
deleted file mode 100644
index 244ff7e9dfa..00000000000
--- a/changelogs/unreleased/34510-board-issues-sql-speedup.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Optimize the boards' issues fetching.
-merge_request: 14198
-author:
-type: other
diff --git a/changelogs/unreleased/35199-case-insensitive-branches-search.yml b/changelogs/unreleased/35199-case-insensitive-branches-search.yml
new file mode 100644
index 00000000000..da2729e9e55
--- /dev/null
+++ b/changelogs/unreleased/35199-case-insensitive-branches-search.yml
@@ -0,0 +1,5 @@
+---
+title: Case insensitive search for branches
+merge_request: 14995
+author: George Andrinopoulos
+type: fixed
diff --git a/changelogs/unreleased/3523-i18n-autodevops.yml b/changelogs/unreleased/3523-i18n-autodevops.yml
deleted file mode 100644
index 10cb22b42a0..00000000000
--- a/changelogs/unreleased/3523-i18n-autodevops.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Improves i18n for Auto Devops callout
-merge_request:
-author:
-type: other
diff --git a/changelogs/unreleased/35290_allow_public_project_apis.yml b/changelogs/unreleased/35290_allow_public_project_apis.yml
deleted file mode 100644
index 1968eee0a53..00000000000
--- a/changelogs/unreleased/35290_allow_public_project_apis.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: made read-only APIs for public merge requests available without authentication
-merge_request: 13291
-author: haseebeqx
diff --git a/changelogs/unreleased/35580-cannot-import-project-with-milestones.yml b/changelogs/unreleased/35580-cannot-import-project-with-milestones.yml
deleted file mode 100644
index b28105556db..00000000000
--- a/changelogs/unreleased/35580-cannot-import-project-with-milestones.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix the project import with issues and milestones
-merge_request: 14657
-author:
-type: fixed
diff --git a/changelogs/unreleased/35644-refactor-have-http-status-into-have-gitlab-http-status.yml b/changelogs/unreleased/35644-refactor-have-http-status-into-have-gitlab-http-status.yml
new file mode 100644
index 00000000000..b03baab4950
--- /dev/null
+++ b/changelogs/unreleased/35644-refactor-have-http-status-into-have-gitlab-http-status.yml
@@ -0,0 +1,5 @@
+---
+title: Refactor have_http_status into have_gitlab_http_status
+merge_request: 14958
+author: Jacopo Beschi @jacopo-beschi
+type: added
diff --git a/changelogs/unreleased/35917_create_services_for_keys.yml b/changelogs/unreleased/35917_create_services_for_keys.yml
deleted file mode 100644
index e7cad5a11d5..00000000000
--- a/changelogs/unreleased/35917_create_services_for_keys.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: creation of keys moved to services
-merge_request: 13331
-author: haseebeqx
diff --git a/changelogs/unreleased/3612-update-script-template-order-in-vue-files.yml b/changelogs/unreleased/3612-update-script-template-order-in-vue-files.yml
deleted file mode 100644
index cea6cb2e48b..00000000000
--- a/changelogs/unreleased/3612-update-script-template-order-in-vue-files.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Re-arrange <script> tags before <template> tags in .vue files
-merge_request: 14671
-author:
-type: changed
diff --git a/changelogs/unreleased/36255-metrics-that-do-not-have-a-complete-history-are-not-shown-at-all.yml b/changelogs/unreleased/36255-metrics-that-do-not-have-a-complete-history-are-not-shown-at-all.yml
deleted file mode 100644
index a820ecee7d2..00000000000
--- a/changelogs/unreleased/36255-metrics-that-do-not-have-a-complete-history-are-not-shown-at-all.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Allow prometheus graphs to correctly handle NaN values
-merge_request: 14741
-author:
-type: fixed
diff --git a/changelogs/unreleased/36549-circuit-breaker-handles-missing-storages.yml b/changelogs/unreleased/36549-circuit-breaker-handles-missing-storages.yml
deleted file mode 100644
index f5ccb163d98..00000000000
--- a/changelogs/unreleased/36549-circuit-breaker-handles-missing-storages.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Allow the git circuit breaker to correctly handle missing repository storages
-merge_request: 14417
-author:
-type: fixed
diff --git a/changelogs/unreleased/36631-activerecord-statementinvalid-pg-querycanceled-error-canceling-statement-due-to-statement-timeout.yml b/changelogs/unreleased/36631-activerecord-statementinvalid-pg-querycanceled-error-canceling-statement-due-to-statement-timeout.yml
deleted file mode 100644
index a2e1d07158b..00000000000
--- a/changelogs/unreleased/36631-activerecord-statementinvalid-pg-querycanceled-error-canceling-statement-due-to-statement-timeout.yml
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: Reschedule merge request diff background migrations to catch failures from
- 9.5 run
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/36670-remove-edit-form.yml b/changelogs/unreleased/36670-remove-edit-form.yml
deleted file mode 100644
index 4e80b685f67..00000000000
--- a/changelogs/unreleased/36670-remove-edit-form.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Remove the ability to visit the issue edit form directly
-merge_request: 14523
-author:
-type: removed
diff --git a/changelogs/unreleased/3674-hashed-storage-attachments.yml b/changelogs/unreleased/3674-hashed-storage-attachments.yml
new file mode 100644
index 00000000000..41bdb5fa568
--- /dev/null
+++ b/changelogs/unreleased/3674-hashed-storage-attachments.yml
@@ -0,0 +1,5 @@
+---
+title: Hashed Storage support for Attachments
+merge_request: 15068
+author:
+type: added
diff --git a/changelogs/unreleased/36742-hide-close-mr-button-on-merge.yml b/changelogs/unreleased/36742-hide-close-mr-button-on-merge.yml
deleted file mode 100644
index 3d3efcdbcc6..00000000000
--- a/changelogs/unreleased/36742-hide-close-mr-button-on-merge.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Hide close MR button after merge without reloading page
-merge_request: 14122
-author: Jacopo Beschi @jacopo-beschi
-type: added
diff --git a/changelogs/unreleased/36829-add-ability-to-verify-gpg-subkeys.yml b/changelogs/unreleased/36829-add-ability-to-verify-gpg-subkeys.yml
deleted file mode 100644
index ee6a7287e86..00000000000
--- a/changelogs/unreleased/36829-add-ability-to-verify-gpg-subkeys.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add support for GPG subkeys in signature verification
-merge_request: 14517
-author:
-type: added
diff --git a/changelogs/unreleased/36884-gitaly-admin-version.yml b/changelogs/unreleased/36884-gitaly-admin-version.yml
deleted file mode 100644
index 0b3b9a205b5..00000000000
--- a/changelogs/unreleased/36884-gitaly-admin-version.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add Gitaly version to Admin Dashboard
-merge_request: 14313
-author: Jacopo Beschi @jacopo-beschi
-type: added
diff --git a/changelogs/unreleased/36953-add-gitLab-pages-version-to-admin-dashboard.yml b/changelogs/unreleased/36953-add-gitLab-pages-version-to-admin-dashboard.yml
deleted file mode 100644
index 9ac4a0ae7f3..00000000000
--- a/changelogs/unreleased/36953-add-gitLab-pages-version-to-admin-dashboard.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add GitLab-Pages version to Admin Dashboard
-merge_request: 14040
-author: travismiller
-type: added
diff --git a/changelogs/unreleased/37025-error-500-in-non-utf8-branch-names.yml b/changelogs/unreleased/37025-error-500-in-non-utf8-branch-names.yml
deleted file mode 100644
index f3118cf0f2f..00000000000
--- a/changelogs/unreleased/37025-error-500-in-non-utf8-branch-names.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Fixed non-UTF-8 valid branch names from causing an error.
-merge_request: 14090
-type: fixed
diff --git a/changelogs/unreleased/37105-monitoring-graph-axes-labels-are-inaccurate-and-inconsistent.yml b/changelogs/unreleased/37105-monitoring-graph-axes-labels-are-inaccurate-and-inconsistent.yml
deleted file mode 100644
index 3364b1d46b3..00000000000
--- a/changelogs/unreleased/37105-monitoring-graph-axes-labels-are-inaccurate-and-inconsistent.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix incorrect X-axis labels in Prometheus graphs
-merge_request: 14258
-author:
-type: fixed
diff --git a/changelogs/unreleased/37220-es-modules.yml b/changelogs/unreleased/37220-es-modules.yml
deleted file mode 100644
index de81fa9e74d..00000000000
--- a/changelogs/unreleased/37220-es-modules.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Exports common_utils utility functions as modules
-merge_request:
-author:
-type: other
diff --git a/changelogs/unreleased/37229-mr-widget-status-icon.yml b/changelogs/unreleased/37229-mr-widget-status-icon.yml
deleted file mode 100644
index 6d84d1964ca..00000000000
--- a/changelogs/unreleased/37229-mr-widget-status-icon.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: fix merge request widget status icon for failed CI
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/37335-counter-active-state.yml b/changelogs/unreleased/37335-counter-active-state.yml
deleted file mode 100644
index a9632201a89..00000000000
--- a/changelogs/unreleased/37335-counter-active-state.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add active states to nav bar counters
-merge_request:
-author:
-type: changed
diff --git a/changelogs/unreleased/37405-admin-page-runner-tag-help-update.yml b/changelogs/unreleased/37405-admin-page-runner-tag-help-update.yml
deleted file mode 100644
index bec7da26b1a..00000000000
--- a/changelogs/unreleased/37405-admin-page-runner-tag-help-update.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: 'Add help text to runner edit: tags should be separated by commas.'
-merge_request:
-author: Brendan O'Leary
-type: added
diff --git a/changelogs/unreleased/37483-activity-log-show-wrong-number-of-commits-per-push.yml b/changelogs/unreleased/37483-activity-log-show-wrong-number-of-commits-per-push.yml
deleted file mode 100644
index 225ab9acc44..00000000000
--- a/changelogs/unreleased/37483-activity-log-show-wrong-number-of-commits-per-push.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix the number representing the amount of commits related to a push event
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/37552-replace-js-true-with-js.yml b/changelogs/unreleased/37552-replace-js-true-with-js.yml
deleted file mode 100644
index f7b614a8839..00000000000
--- a/changelogs/unreleased/37552-replace-js-true-with-js.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: 'Replace `tag: true` into `:tag` in the specs'
-merge_request: 14653
-author: Jacopo Beschi @jacopo-beschi
-type: added
diff --git a/changelogs/unreleased/37691-subscription-fires-multiple-notifications.yml b/changelogs/unreleased/37691-subscription-fires-multiple-notifications.yml
deleted file mode 100644
index c3c38b35fa7..00000000000
--- a/changelogs/unreleased/37691-subscription-fires-multiple-notifications.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fixed duplicate notifications when added multiple labels on an issue
-merge_request: 14798
-author:
-type: fixed
diff --git a/changelogs/unreleased/37970-ci-sections-tracking.yml b/changelogs/unreleased/37970-ci-sections-tracking.yml
deleted file mode 100644
index a9011b22c6c..00000000000
--- a/changelogs/unreleased/37970-ci-sections-tracking.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Parse and store gitlab-runner timestamped section markers
-merge_request: 14551
-author:
-type: added
diff --git a/changelogs/unreleased/37970-timestamped-ci.yml b/changelogs/unreleased/37970-timestamped-ci.yml
deleted file mode 100644
index 2a4797f069a..00000000000
--- a/changelogs/unreleased/37970-timestamped-ci.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Strip gitlab-runner section markers in build trace HTML view
-merge_request: 14393
-author:
-type: added
diff --git a/changelogs/unreleased/37999-fix-circuit-breaker.yml b/changelogs/unreleased/37999-fix-circuit-breaker.yml
deleted file mode 100644
index a75315c4988..00000000000
--- a/changelogs/unreleased/37999-fix-circuit-breaker.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix the filesystem shard health check to check all configured shards
-merge_request: 14341
-author:
-type: fixed
diff --git a/changelogs/unreleased/38031-monitoring-hover-info-is-clipped.yml b/changelogs/unreleased/38031-monitoring-hover-info-is-clipped.yml
deleted file mode 100644
index 8b3fae2c103..00000000000
--- a/changelogs/unreleased/38031-monitoring-hover-info-is-clipped.yml
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: Move the deployment flag content to the left when deployment marker is near
- the end
-merge_request: 14514
-author:
-type: fixed
diff --git a/changelogs/unreleased/38036-hover-and-legend-data-should-be-linked.yml b/changelogs/unreleased/38036-hover-and-legend-data-should-be-linked.yml
deleted file mode 100644
index 591e542cd17..00000000000
--- a/changelogs/unreleased/38036-hover-and-legend-data-should-be-linked.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Sync up hover and legend data across all graphs for the prometheus dashboard
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/38052-use-simple-api-for-projects.yml b/changelogs/unreleased/38052-use-simple-api-for-projects.yml
deleted file mode 100644
index 49c7485861e..00000000000
--- a/changelogs/unreleased/38052-use-simple-api-for-projects.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Use `simple=true` for projects API in Projects dropdown for better search performance
-merge_request:
-author:
-type: other
diff --git a/changelogs/unreleased/38178-fl-mr-notes-components.yml b/changelogs/unreleased/38178-fl-mr-notes-components.yml
new file mode 100644
index 00000000000..244ccfb3071
--- /dev/null
+++ b/changelogs/unreleased/38178-fl-mr-notes-components.yml
@@ -0,0 +1,6 @@
+---
+title: Moves placeholders components into shared folder with documentation. Makes
+ them easier to reuse in MR and Snippets comments
+merge_request:
+author:
+type: other
diff --git a/changelogs/unreleased/38187-38315-fix-dropdown-open-top-bottom-spacing.yml b/changelogs/unreleased/38187-38315-fix-dropdown-open-top-bottom-spacing.yml
deleted file mode 100644
index 579c247c4c2..00000000000
--- a/changelogs/unreleased/38187-38315-fix-dropdown-open-top-bottom-spacing.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix bottom spacing for dropdowns that open upwards
-merge_request: 14535
-author:
-type: fixed
diff --git a/changelogs/unreleased/38197-fix-ImapAuthenticationCheck.yml b/changelogs/unreleased/38197-fix-ImapAuthenticationCheck.yml
deleted file mode 100644
index df562077fb3..00000000000
--- a/changelogs/unreleased/38197-fix-ImapAuthenticationCheck.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix `rake gitlab:incoming_email:check` and make it report the actual error
-merge_request: 14423
-author:
-type: fixed
diff --git a/changelogs/unreleased/38202-cannot-rename-a-hashed-project.yml b/changelogs/unreleased/38202-cannot-rename-a-hashed-project.yml
deleted file mode 100644
index 768e296fcd7..00000000000
--- a/changelogs/unreleased/38202-cannot-rename-a-hashed-project.yml
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: Does not check if an invariant hashed storage path exists on disk when renaming
- projects.
-merge_request: 14428
-author:
-type: fixed
diff --git a/changelogs/unreleased/38234-reserve-refs-replace.yml b/changelogs/unreleased/38234-reserve-refs-replace.yml
deleted file mode 100644
index 3a5ffbf9db0..00000000000
--- a/changelogs/unreleased/38234-reserve-refs-replace.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Also reserve refs/replace after importing a project
-merge_request: 14436
-author:
-type: fixed
diff --git a/changelogs/unreleased/38389-allow-merge-without-success.yml b/changelogs/unreleased/38389-allow-merge-without-success.yml
deleted file mode 100644
index 6a37bcc55fc..00000000000
--- a/changelogs/unreleased/38389-allow-merge-without-success.yml
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: Allow merge in MR widget with no pipeline but using "Only allow merge requests
- to be merged if the pipeline succeeds"
-merge_request: 14633
-author:
-type: fixed
diff --git a/changelogs/unreleased/38417-use-explicit-boolean-vue-attribute.yml b/changelogs/unreleased/38417-use-explicit-boolean-vue-attribute.yml
deleted file mode 100644
index 419e9295d32..00000000000
--- a/changelogs/unreleased/38417-use-explicit-boolean-vue-attribute.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Use explicit boolean true attribute for show-disabled-button in Vue files
-merge_request: 14672
-author:
-type: fixed
diff --git a/changelogs/unreleased/38432-fix-notes-type-for-import.yml b/changelogs/unreleased/38432-fix-notes-type-for-import.yml
deleted file mode 100644
index db8371f4420..00000000000
--- a/changelogs/unreleased/38432-fix-notes-type-for-import.yml
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: Fix notes type created from import. This should fix some missing notes issues
- from imported projects
-merge_request: 14524
-author:
-type: fixed
diff --git a/changelogs/unreleased/38502-fix-nav-dropdown-close-animation.yml b/changelogs/unreleased/38502-fix-nav-dropdown-close-animation.yml
deleted file mode 100644
index 974adb9ed28..00000000000
--- a/changelogs/unreleased/38502-fix-nav-dropdown-close-animation.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix navigation dropdown close animation on mobile screens
-merge_request: 14649
-author:
-type: fixed
diff --git a/changelogs/unreleased/38534-minigraph.yml b/changelogs/unreleased/38534-minigraph.yml
deleted file mode 100644
index eed240eac2d..00000000000
--- a/changelogs/unreleased/38534-minigraph.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fixes mini pipeline graph in commit view
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/38571-fix-exception-in-raven-report.yml b/changelogs/unreleased/38571-fix-exception-in-raven-report.yml
deleted file mode 100644
index 62e3b8d304c..00000000000
--- a/changelogs/unreleased/38571-fix-exception-in-raven-report.yml
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: Ensure no exception is raised when Raven tries to get the current user in API
- context
-merge_request: 14580
-author:
-type: fixed
diff --git a/changelogs/unreleased/38619-fix-comment-delete-confirm-text.yml b/changelogs/unreleased/38619-fix-comment-delete-confirm-text.yml
deleted file mode 100644
index a203bff8410..00000000000
--- a/changelogs/unreleased/38619-fix-comment-delete-confirm-text.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix comment deletion confirmation dialog typo
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/38635-fix-gitlab-check-git-ssh-config.yml b/changelogs/unreleased/38635-fix-gitlab-check-git-ssh-config.yml
deleted file mode 100644
index 49d0671233a..00000000000
--- a/changelogs/unreleased/38635-fix-gitlab-check-git-ssh-config.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Whitelist authorized_keys.lock in the gitlab:check rake task
-merge_request: 14624
-author:
-type: fixed
diff --git a/changelogs/unreleased/38696-fix-project-snippets-breadcrumb-link.yml b/changelogs/unreleased/38696-fix-project-snippets-breadcrumb-link.yml
deleted file mode 100644
index 18b1645d7a9..00000000000
--- a/changelogs/unreleased/38696-fix-project-snippets-breadcrumb-link.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix project snippets breadcrumb link
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/38775-scrollable-tabs-on-admin.yml b/changelogs/unreleased/38775-scrollable-tabs-on-admin.yml
deleted file mode 100644
index 65a66714bcb..00000000000
--- a/changelogs/unreleased/38775-scrollable-tabs-on-admin.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Make tabs on top scrollable on admin dashboard
-merge_request: 14685
-author: Takuya Noguchi
-type: fixed
diff --git a/changelogs/unreleased/38789-prometheus-graphs-occasionally-have-incorrect-y-scale.yml b/changelogs/unreleased/38789-prometheus-graphs-occasionally-have-incorrect-y-scale.yml
deleted file mode 100644
index bbfe5d49a3e..00000000000
--- a/changelogs/unreleased/38789-prometheus-graphs-occasionally-have-incorrect-y-scale.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix broken Y-axis scaling in some Prometheus graphs
-merge_request: 14693
-author:
-type: fixed
diff --git a/changelogs/unreleased/39017-gitlabusagepingworker-is-not-running-on-gitlab-com.yml b/changelogs/unreleased/39017-gitlabusagepingworker-is-not-running-on-gitlab-com.yml
deleted file mode 100644
index 89506f88637..00000000000
--- a/changelogs/unreleased/39017-gitlabusagepingworker-is-not-running-on-gitlab-com.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Make usage ping scheduling more robust
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/39032-improve-merge-ongoing-check-consistency.yml b/changelogs/unreleased/39032-improve-merge-ongoing-check-consistency.yml
deleted file mode 100644
index 361b6af196a..00000000000
--- a/changelogs/unreleased/39032-improve-merge-ongoing-check-consistency.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Make "merge ongoing" check more consistent
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/39054-activerecord-statementinvalid-pg-querycanceled-error-canceling-statement-due-to-statement-timeout.yml b/changelogs/unreleased/39054-activerecord-statementinvalid-pg-querycanceled-error-canceling-statement-due-to-statement-timeout.yml
new file mode 100644
index 00000000000..47bf30ecb5a
--- /dev/null
+++ b/changelogs/unreleased/39054-activerecord-statementinvalid-pg-querycanceled-error-canceling-statement-due-to-statement-timeout.yml
@@ -0,0 +1,5 @@
+---
+title: Stop merge requests with thousands of commits from timing out
+merge_request: 15063
+author:
+type: performance
diff --git a/changelogs/unreleased/39188-change-default-disabled-merge-message.yml b/changelogs/unreleased/39188-change-default-disabled-merge-message.yml
new file mode 100644
index 00000000000..7de65f5c3f6
--- /dev/null
+++ b/changelogs/unreleased/39188-change-default-disabled-merge-message.yml
@@ -0,0 +1,5 @@
+---
+title: Update default disabled merge request widget message to reflect a general failure
+merge_request: 14960
+author:
+type: changed
diff --git a/changelogs/unreleased/39366-email-confirmation-fails.yml b/changelogs/unreleased/39366-email-confirmation-fails.yml
new file mode 100644
index 00000000000..a5568670c70
--- /dev/null
+++ b/changelogs/unreleased/39366-email-confirmation-fails.yml
@@ -0,0 +1,5 @@
+---
+title: 'Fix bug preventing secondary emails from being confirmed'
+merge_request: 15010
+author:
+type: fixed
diff --git a/changelogs/unreleased/39419-remove-overzealous-tooltips.yml b/changelogs/unreleased/39419-remove-overzealous-tooltips.yml
new file mode 100644
index 00000000000..d6cf60bebfa
--- /dev/null
+++ b/changelogs/unreleased/39419-remove-overzealous-tooltips.yml
@@ -0,0 +1,5 @@
+---
+title: Remove overzealous tooltips in projects page tabs
+merge_request: 15017
+author:
+type: removed
diff --git a/changelogs/unreleased/39441-bring-edit-form-back.yml b/changelogs/unreleased/39441-bring-edit-form-back.yml
new file mode 100644
index 00000000000..025417e4da9
--- /dev/null
+++ b/changelogs/unreleased/39441-bring-edit-form-back.yml
@@ -0,0 +1,5 @@
+---
+title: Fix editing issue description in mobile view
+merge_request:
+author:
+type: fixed
diff --git a/changelogs/unreleased/39495-fix-bitbucket-login.yml b/changelogs/unreleased/39495-fix-bitbucket-login.yml
new file mode 100644
index 00000000000..b48d557108b
--- /dev/null
+++ b/changelogs/unreleased/39495-fix-bitbucket-login.yml
@@ -0,0 +1,5 @@
+---
+title: Fix bitbucket login
+merge_request: 15051
+author:
+type: fixed
diff --git a/changelogs/unreleased/39509-fix-wiki-create-sidebar-overlap.yml b/changelogs/unreleased/39509-fix-wiki-create-sidebar-overlap.yml
new file mode 100644
index 00000000000..aebf6363d97
--- /dev/null
+++ b/changelogs/unreleased/39509-fix-wiki-create-sidebar-overlap.yml
@@ -0,0 +1,5 @@
+---
+title: Fix overlap of right-sidebar and main content when creating a Wiki page
+merge_request:
+author:
+type: fixed
diff --git a/changelogs/unreleased/39570-performance-bar-appears-enabled-even-though-it-won-t-show-up.yml b/changelogs/unreleased/39570-performance-bar-appears-enabled-even-though-it-won-t-show-up.yml
new file mode 100644
index 00000000000..66939d89d69
--- /dev/null
+++ b/changelogs/unreleased/39570-performance-bar-appears-enabled-even-though-it-won-t-show-up.yml
@@ -0,0 +1,5 @@
+---
+title: Allow to disable the Performance Bar
+merge_request: 15084
+author:
+type: fixed
diff --git a/changelogs/unreleased/39580-bump-carrierwave-to-1-2-1.yml b/changelogs/unreleased/39580-bump-carrierwave-to-1-2-1.yml
new file mode 100644
index 00000000000..bda85ac24e0
--- /dev/null
+++ b/changelogs/unreleased/39580-bump-carrierwave-to-1-2-1.yml
@@ -0,0 +1,5 @@
+---
+title: Bump carrierwave to 1.2.1
+merge_request: 15072
+author: Takuya Noguchi
+type: other
diff --git a/changelogs/unreleased/39582-nestingdepth-6.yml b/changelogs/unreleased/39582-nestingdepth-6.yml
new file mode 100644
index 00000000000..efe15f0a5f3
--- /dev/null
+++ b/changelogs/unreleased/39582-nestingdepth-6.yml
@@ -0,0 +1,5 @@
+---
+title: Enable NestingDepth (level 6) on scss-lint
+merge_request: 15073
+author: Takuya Noguchi
+type: other
diff --git a/changelogs/unreleased/39583-reopen-issue-count-cache.yml b/changelogs/unreleased/39583-reopen-issue-count-cache.yml
new file mode 100644
index 00000000000..ee35bcbcdae
--- /dev/null
+++ b/changelogs/unreleased/39583-reopen-issue-count-cache.yml
@@ -0,0 +1,5 @@
+---
+title: Refresh open Issue and Merge Request project counter caches when re-opening.
+merge_request: 15085
+author: Rob Ede @robjtede
+type: fixed
diff --git a/changelogs/unreleased/39593-emails-on-push-are-sent-to-only-the-first-recipient-when-using-aws-ses.yml b/changelogs/unreleased/39593-emails-on-push-are-sent-to-only-the-first-recipient-when-using-aws-ses.yml
new file mode 100644
index 00000000000..9a7109d054e
--- /dev/null
+++ b/changelogs/unreleased/39593-emails-on-push-are-sent-to-only-the-first-recipient-when-using-aws-ses.yml
@@ -0,0 +1,5 @@
+---
+title: Only set Auto-Submitted header once for emails on push
+merge_request:
+author:
+type: fixed
diff --git a/changelogs/unreleased/39619-cancel-merge-when-pipeline-succeeds-from-the-api-fails.yml b/changelogs/unreleased/39619-cancel-merge-when-pipeline-succeeds-from-the-api-fails.yml
new file mode 100644
index 00000000000..95251b46ecc
--- /dev/null
+++ b/changelogs/unreleased/39619-cancel-merge-when-pipeline-succeeds-from-the-api-fails.yml
@@ -0,0 +1,5 @@
+---
+title: Fix namespacing for MergeWhenPipelineSucceedsService in MR API
+merge_request:
+author:
+type: fixed
diff --git a/changelogs/unreleased/39639-clusters-poll.yml b/changelogs/unreleased/39639-clusters-poll.yml
new file mode 100644
index 00000000000..f0a82f58b19
--- /dev/null
+++ b/changelogs/unreleased/39639-clusters-poll.yml
@@ -0,0 +1,5 @@
+---
+title: Adds callback functions for initial request in clusters page
+merge_request:
+author:
+type: fixed
diff --git a/changelogs/unreleased/5836-move-lib-ci-into-gitlab-namespace.yml b/changelogs/unreleased/5836-move-lib-ci-into-gitlab-namespace.yml
deleted file mode 100644
index 44e16512bae..00000000000
--- a/changelogs/unreleased/5836-move-lib-ci-into-gitlab-namespace.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Move `lib/ci` to `lib/gitlab/ci`
-merge_request: 14078
-author: Maxim Rydkin
-type: other
diff --git a/changelogs/unreleased/add-1000-plus-counters-for-jobs-page.yml b/changelogs/unreleased/add-1000-plus-counters-for-jobs-page.yml
deleted file mode 100644
index 5f5a61406da..00000000000
--- a/changelogs/unreleased/add-1000-plus-counters-for-jobs-page.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add 1000+ counters to job page
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/add-ci-builds-index-for-jobscontroller.yml b/changelogs/unreleased/add-ci-builds-index-for-jobscontroller.yml
deleted file mode 100644
index 7f098c8f60c..00000000000
--- a/changelogs/unreleased/add-ci-builds-index-for-jobscontroller.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Change index on ci_builds to optimize Jobs Controller
-merge_request:
-author:
-type: other
diff --git a/changelogs/unreleased/add-composite-index-on-merge-requests-merge-commit-sha.yml b/changelogs/unreleased/add-composite-index-on-merge-requests-merge-commit-sha.yml
deleted file mode 100644
index 9a600282716..00000000000
--- a/changelogs/unreleased/add-composite-index-on-merge-requests-merge-commit-sha.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add index for merge_requests.merge_commit_sha
-merge_request:
-author:
-type: other
diff --git a/changelogs/unreleased/add-labels-template-index.yml b/changelogs/unreleased/add-labels-template-index.yml
deleted file mode 100644
index 5f66c4ce181..00000000000
--- a/changelogs/unreleased/add-labels-template-index.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add (partial) index on Labels.template
-merge_request:
-author:
-type: other
diff --git a/changelogs/unreleased/add-packagist-project-service.yml b/changelogs/unreleased/add-packagist-project-service.yml
new file mode 100644
index 00000000000..a13d00e91f7
--- /dev/null
+++ b/changelogs/unreleased/add-packagist-project-service.yml
@@ -0,0 +1,5 @@
+---
+title: Add Packagist project service
+merge_request: 14493
+author: Matt Coleman
+type: added
diff --git a/changelogs/unreleased/add-shared-vue-loading-button.yml b/changelogs/unreleased/add-shared-vue-loading-button.yml
new file mode 100644
index 00000000000..a8904acc4e7
--- /dev/null
+++ b/changelogs/unreleased/add-shared-vue-loading-button.yml
@@ -0,0 +1,5 @@
+---
+title: Add loading button for new UX paradigm
+merge_request: 14883
+author:
+type: added
diff --git a/changelogs/unreleased/add-view-replaced-file-link.yml b/changelogs/unreleased/add-view-replaced-file-link.yml
deleted file mode 100644
index b5a85f2e0f2..00000000000
--- a/changelogs/unreleased/add-view-replaced-file-link.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add view replaced file link for image diffs
-merge_request:
-author:
-type: changed
diff --git a/changelogs/unreleased/add_closed_at_attribute.yml b/changelogs/unreleased/add_closed_at_attribute.yml
deleted file mode 100644
index 3afb75e8915..00000000000
--- a/changelogs/unreleased/add_closed_at_attribute.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add 'closed_at' attribute to Issues API
-merge_request: 14316
-author: Vitaliy @blackst0ne Klachkov
-type: added
diff --git a/changelogs/unreleased/add_tooltip_for_milestone_in_issues_list.yml b/changelogs/unreleased/add_tooltip_for_milestone_in_issues_list.yml
deleted file mode 100644
index 0470c6519f4..00000000000
--- a/changelogs/unreleased/add_tooltip_for_milestone_in_issues_list.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add tooltip for milestone due date to issue and merge request lists
-merge_request: 14318
-author: Vitaliy @blackst0ne Klachkov
-type: added
diff --git a/changelogs/unreleased/adjusting-tooltips.yml b/changelogs/unreleased/adjusting-tooltips.yml
deleted file mode 100644
index 726b75caecd..00000000000
--- a/changelogs/unreleased/adjusting-tooltips.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Adjust tooltips to adhere to 8px grid and make them more readable
-merge_request:
-author:
-type: changed
diff --git a/changelogs/unreleased/an-popen-deadline.yml b/changelogs/unreleased/an-popen-deadline.yml
deleted file mode 100644
index 4b74c63ed5c..00000000000
--- a/changelogs/unreleased/an-popen-deadline.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Use a timeout on certain git operations
-merge_request: 14872
-author:
-type: security
diff --git a/changelogs/unreleased/api-configure-jira.yml b/changelogs/unreleased/api-configure-jira.yml
new file mode 100644
index 00000000000..3ac52d573b0
--- /dev/null
+++ b/changelogs/unreleased/api-configure-jira.yml
@@ -0,0 +1,5 @@
+---
+title: Validate username/pw for Jiraservice, require them in the API
+merge_request: 15025
+author: Robert Schilling
+type: fixed
diff --git a/changelogs/unreleased/api-doc-group-statistics.yml b/changelogs/unreleased/api-doc-group-statistics.yml
new file mode 100644
index 00000000000..385ff978024
--- /dev/null
+++ b/changelogs/unreleased/api-doc-group-statistics.yml
@@ -0,0 +1,5 @@
+---
+title: Update the groups API documentation
+merge_request: 15024
+author: Robert Schilling
+type: fixed
diff --git a/changelogs/unreleased/breadcrumb-item-links.yml b/changelogs/unreleased/breadcrumb-item-links.yml
deleted file mode 100644
index 9b66456efca..00000000000
--- a/changelogs/unreleased/breadcrumb-item-links.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fixed issue/merge request breadcrumb titles not having links
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/breadcrumbs-line-height-padding.yml b/changelogs/unreleased/breadcrumbs-line-height-padding.yml
deleted file mode 100644
index 3ac56c8b593..00000000000
--- a/changelogs/unreleased/breadcrumbs-line-height-padding.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: breadcrumbs receives padding when double lined
-merge_request:
-author:
-type: changed
diff --git a/changelogs/unreleased/bugfix-graph-friendly-notes-number.yml b/changelogs/unreleased/bugfix-graph-friendly-notes-number.yml
deleted file mode 100644
index 3a99729fb48..00000000000
--- a/changelogs/unreleased/bugfix-graph-friendly-notes-number.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Show notes number more user-friendly in the graph
-merge_request: 13949
-author: Vladislav Kaverin
-type: changed
diff --git a/changelogs/unreleased/bvl-circuitbreaker-backoff.yml b/changelogs/unreleased/bvl-circuitbreaker-backoff.yml
new file mode 100644
index 00000000000..5cb90e7c085
--- /dev/null
+++ b/changelogs/unreleased/bvl-circuitbreaker-backoff.yml
@@ -0,0 +1,6 @@
+---
+title: Make the circuitbreaker more robust by adding higher thresholds, and multiple
+ access attempts.
+merge_request: 14933
+author:
+type: fixed
diff --git a/changelogs/unreleased/bvl-dont-rename-free-names.yml b/changelogs/unreleased/bvl-dont-rename-free-names.yml
new file mode 100644
index 00000000000..60a4ec8afbe
--- /dev/null
+++ b/changelogs/unreleased/bvl-dont-rename-free-names.yml
@@ -0,0 +1,5 @@
+---
+title: Don't rename paths that were freed up when upgrading
+merge_request: 15029
+author:
+type: fixed
diff --git a/changelogs/unreleased/bvl-fix-deleting-forked-projects.yml b/changelogs/unreleased/bvl-fix-deleting-forked-projects.yml
deleted file mode 100644
index 95f56facc4b..00000000000
--- a/changelogs/unreleased/bvl-fix-deleting-forked-projects.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix error when updating a forked project with deleted `ForkedProjectLink`
-merge_request: 14916
-author:
-type: fixed
diff --git a/changelogs/unreleased/bvl-fix-group-atom-feed.yml b/changelogs/unreleased/bvl-fix-group-atom-feed.yml
new file mode 100644
index 00000000000..48f67db7799
--- /dev/null
+++ b/changelogs/unreleased/bvl-fix-group-atom-feed.yml
@@ -0,0 +1,5 @@
+---
+title: Fix the atom feed for group events
+merge_request: 14974
+author:
+type: fixed
diff --git a/changelogs/unreleased/bvl-fix-locale-path.yml b/changelogs/unreleased/bvl-fix-locale-path.yml
deleted file mode 100644
index 97e0e000e3c..00000000000
--- a/changelogs/unreleased/bvl-fix-locale-path.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Correctly render asset path for locales with a region
-merge_request: 14924
-author:
-type: fixed
diff --git a/changelogs/unreleased/bvl-fix-push-event-service-for-forks.yml b/changelogs/unreleased/bvl-fix-push-event-service-for-forks.yml
new file mode 100644
index 00000000000..2a7d80270ac
--- /dev/null
+++ b/changelogs/unreleased/bvl-fix-push-event-service-for-forks.yml
@@ -0,0 +1,5 @@
+---
+title: Only cache last push event for existing projects when pushing to a fork
+merge_request: 14989
+author:
+type: fixed
diff --git a/changelogs/unreleased/bvl-fix-system-hook-project-visibility.yml b/changelogs/unreleased/bvl-fix-system-hook-project-visibility.yml
new file mode 100644
index 00000000000..a17ed51c9b8
--- /dev/null
+++ b/changelogs/unreleased/bvl-fix-system-hook-project-visibility.yml
@@ -0,0 +1,5 @@
+---
+title: Use the correct visibility attribute for projects in system hooks
+merge_request: 15065
+author:
+type: fixed
diff --git a/changelogs/unreleased/bvl-fork-network-schema.yml b/changelogs/unreleased/bvl-fork-network-schema.yml
deleted file mode 100644
index 97b2d5acada..00000000000
--- a/changelogs/unreleased/bvl-fork-network-schema.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Allow creating merge requests across a fork network
-merge_request: 14422
-author:
-type: changed
diff --git a/changelogs/unreleased/cache-issuable-template-names.yml b/changelogs/unreleased/cache-issuable-template-names.yml
deleted file mode 100644
index 858fdff2db2..00000000000
--- a/changelogs/unreleased/cache-issuable-template-names.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Cache issue and MR template names in Redis
-merge_request:
-author:
-type: other
diff --git a/changelogs/unreleased/change-dashed-border-button-color.yml b/changelogs/unreleased/change-dashed-border-button-color.yml
deleted file mode 100644
index 038bea79273..00000000000
--- a/changelogs/unreleased/change-dashed-border-button-color.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: changed dashed border button color to be darker
-merge_request: !14041
-author:
-type: other
diff --git a/changelogs/unreleased/close-issue-by-implements.yml b/changelogs/unreleased/close-issue-by-implements.yml
deleted file mode 100644
index fe36ce3f7aa..00000000000
--- a/changelogs/unreleased/close-issue-by-implements.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: "Add \"implements\" to the default issue closing message regex"
-merge_request: 14612
-author: Guilherme Vieira
-type: added
diff --git a/changelogs/unreleased/commit-row-avatar-align-top.yml b/changelogs/unreleased/commit-row-avatar-align-top.yml
deleted file mode 100644
index aa5ab770bd8..00000000000
--- a/changelogs/unreleased/commit-row-avatar-align-top.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fixed commit avatars being centered vertically
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/consistent-tooltip-direction-on-commits.yml b/changelogs/unreleased/consistent-tooltip-direction-on-commits.yml
deleted file mode 100644
index 9e6a429f6f0..00000000000
--- a/changelogs/unreleased/consistent-tooltip-direction-on-commits.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Tooltips in the commit info box now all face the same direction
-merge_request:
-author: Jedidiah Broadbent
-type: fixed
diff --git a/changelogs/unreleased/content-title-link-hover-bg.yml b/changelogs/unreleased/content-title-link-hover-bg.yml
deleted file mode 100644
index c4c31c2ad06..00000000000
--- a/changelogs/unreleased/content-title-link-hover-bg.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fixed navbar title colors leaking out of the navbar
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/declarative-policy-optimisations.yml b/changelogs/unreleased/declarative-policy-optimisations.yml
deleted file mode 100644
index dc51c89d575..00000000000
--- a/changelogs/unreleased/declarative-policy-optimisations.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Speed up permission checks
-merge_request:
-author:
-type: other
diff --git a/changelogs/unreleased/dm-bitbucket-import-truncated-shas.yml b/changelogs/unreleased/dm-bitbucket-import-truncated-shas.yml
deleted file mode 100644
index 057407b78d9..00000000000
--- a/changelogs/unreleased/dm-bitbucket-import-truncated-shas.yml
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: Fix bug that caused merge requests with diff notes imported from Bitbucket
- to raise errors
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/dm-closing-issue-urls.yml b/changelogs/unreleased/dm-closing-issue-urls.yml
deleted file mode 100644
index 059e406b63d..00000000000
--- a/changelogs/unreleased/dm-closing-issue-urls.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Correctly detect multiple issue URLs after 'Closes...' in MR descriptions
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/dm-copy-parallel-diff.yml b/changelogs/unreleased/dm-copy-parallel-diff.yml
deleted file mode 100644
index 96a65007661..00000000000
--- a/changelogs/unreleased/dm-copy-parallel-diff.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Only copy old/new code when selecting left/right side of parallel diff
-merge_request:
-author:
-type: added
diff --git a/changelogs/unreleased/dm-ldap-identity-normalize-dn.yml b/changelogs/unreleased/dm-ldap-identity-normalize-dn.yml
new file mode 100644
index 00000000000..7ab25f79143
--- /dev/null
+++ b/changelogs/unreleased/dm-ldap-identity-normalize-dn.yml
@@ -0,0 +1,5 @@
+---
+title: Normalize LDAP DN when looking up identity
+merge_request:
+author:
+type: fixed
diff --git a/changelogs/unreleased/dm-pat-revoke.yml b/changelogs/unreleased/dm-pat-revoke.yml
deleted file mode 100644
index 32ac66056d5..00000000000
--- a/changelogs/unreleased/dm-pat-revoke.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Set default scope on PATs that don't have one set to allow them to be revoked
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/dm-simple-project-avatar-url.yml b/changelogs/unreleased/dm-simple-project-avatar-url.yml
deleted file mode 100644
index e517345f5d2..00000000000
--- a/changelogs/unreleased/dm-simple-project-avatar-url.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Expose avatar_url when requesting list of projects from API with simple=true
-merge_request:
-author:
-type: added
diff --git a/changelogs/unreleased/docs-17499-documentation-errors-about-creating-a-new-tag.yml b/changelogs/unreleased/docs-17499-documentation-errors-about-creating-a-new-tag.yml
deleted file mode 100644
index 3dfe4114cc9..00000000000
--- a/changelogs/unreleased/docs-17499-documentation-errors-about-creating-a-new-tag.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix docs for lightweight tag creation via API
-merge_request:
-author:
-type: other
diff --git a/changelogs/unreleased/docs-28814-clarify-artifacts-ref.yml b/changelogs/unreleased/docs-28814-clarify-artifacts-ref.yml
deleted file mode 100644
index 3cdcff8caaf..00000000000
--- a/changelogs/unreleased/docs-28814-clarify-artifacts-ref.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Clarify artifact download via the API only accepts branch or tag name for ref
-merge_request:
-author:
-type: other
diff --git a/changelogs/unreleased/docs-38152-bump-recommended-mysql-version.yml b/changelogs/unreleased/docs-38152-bump-recommended-mysql-version.yml
deleted file mode 100644
index eea679d0814..00000000000
--- a/changelogs/unreleased/docs-38152-bump-recommended-mysql-version.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Change recommended MySQL version to 5.6
-merge_request:
-author:
-type: other
diff --git a/changelogs/unreleased/docs-add-summary-about-project-archiving.yml b/changelogs/unreleased/docs-add-summary-about-project-archiving.yml
deleted file mode 100644
index cc1b48a682d..00000000000
--- a/changelogs/unreleased/docs-add-summary-about-project-archiving.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add documentation to summarise project archiving
-merge_request: 14650
-author:
-type: other
diff --git a/changelogs/unreleased/docs-openid-connect.yml b/changelogs/unreleased/docs-openid-connect.yml
deleted file mode 100644
index 3989ec53cfa..00000000000
--- a/changelogs/unreleased/docs-openid-connect.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add link to OpenID Connect documentation
-merge_request: 14368
-author: Markus Koller
-type: other
diff --git a/changelogs/unreleased/ee-add-project-repository-storages-index.yml b/changelogs/unreleased/ee-add-project-repository-storages-index.yml
deleted file mode 100644
index 8a144783cec..00000000000
--- a/changelogs/unreleased/ee-add-project-repository-storages-index.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Index projects on repository storage
-merge_request: 14414
-author:
-type: other
diff --git a/changelogs/unreleased/expose-last-pipeline-details-in-api-for-single-commit.yml b/changelogs/unreleased/expose-last-pipeline-details-in-api-for-single-commit.yml
deleted file mode 100644
index d16e052cd92..00000000000
--- a/changelogs/unreleased/expose-last-pipeline-details-in-api-for-single-commit.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Expose last pipeline details in API response when getting a single commit
-merge_request: 13521
-author: Mehdi Lahmam (@mehlah)
-type: added
diff --git a/changelogs/unreleased/feature-custom-attributes.yml b/changelogs/unreleased/feature-custom-attributes.yml
deleted file mode 100644
index 98736bc8d72..00000000000
--- a/changelogs/unreleased/feature-custom-attributes.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Support custom attributes on users
-merge_request: 13038
-author: Markus Koller
diff --git a/changelogs/unreleased/feature-sm-35954-create-kubernetes-cluster-on-gke-from-k8s-service.yml b/changelogs/unreleased/feature-sm-35954-create-kubernetes-cluster-on-gke-from-k8s-service.yml
deleted file mode 100644
index 14b35b6daee..00000000000
--- a/changelogs/unreleased/feature-sm-35954-create-kubernetes-cluster-on-gke-from-k8s-service.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Create Kubernetes cluster on GKE from k8s service
-merge_request: 14470
-author:
-type: added
diff --git a/changelogs/unreleased/feature-ssh_host_fingerprint.yml b/changelogs/unreleased/feature-ssh_host_fingerprint.yml
new file mode 100644
index 00000000000..04f9fd1d6ed
--- /dev/null
+++ b/changelogs/unreleased/feature-ssh_host_fingerprint.yml
@@ -0,0 +1,5 @@
+---
+title: Automatic configuration settings page
+merge_request: 13850
+author: Francisco Lopez
+type: added
diff --git a/changelogs/unreleased/feature-verify_secondary_emails.yml b/changelogs/unreleased/feature-verify_secondary_emails.yml
deleted file mode 100644
index e1ecc527f85..00000000000
--- a/changelogs/unreleased/feature-verify_secondary_emails.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: A confirmation email is now sent when adding a secondary email address
-merge_request:
-author: digitalmoksha
-type: added
diff --git a/changelogs/unreleased/ff_port_from_ee.yml b/changelogs/unreleased/ff_port_from_ee.yml
deleted file mode 100644
index e1cb7804a47..00000000000
--- a/changelogs/unreleased/ff_port_from_ee.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Move Custom merge methods from EE
-merge_request:
-author:
-type: added
diff --git a/changelogs/unreleased/fix-500-on-old-merge-requests.yml b/changelogs/unreleased/fix-500-on-old-merge-requests.yml
new file mode 100644
index 00000000000..765d7466819
--- /dev/null
+++ b/changelogs/unreleased/fix-500-on-old-merge-requests.yml
@@ -0,0 +1,5 @@
+---
+title: Fix 500 errors caused by empty diffs in some discussions
+merge_request: 14945
+author: Alexander Popov
+type: fixed
diff --git a/changelogs/unreleased/fix-add-path-attr-to-wiki-file.yml b/changelogs/unreleased/fix-add-path-attr-to-wiki-file.yml
new file mode 100644
index 00000000000..0847b5f6733
--- /dev/null
+++ b/changelogs/unreleased/fix-add-path-attr-to-wiki-file.yml
@@ -0,0 +1,5 @@
+---
+title: Fix broken wiki pages that link to a wiki file
+merge_request: 15019
+author:
+type: fixed
diff --git a/changelogs/unreleased/fix-application-setting-nil-cache.yml b/changelogs/unreleased/fix-application-setting-nil-cache.yml
deleted file mode 100644
index a5f028e3d69..00000000000
--- a/changelogs/unreleased/fix-application-setting-nil-cache.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix application setting to cache nil object
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/fix-edit-project-service-cancel-button-position.yml b/changelogs/unreleased/fix-edit-project-service-cancel-button-position.yml
deleted file mode 100644
index efb993eff71..00000000000
--- a/changelogs/unreleased/fix-edit-project-service-cancel-button-position.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix edit project service cancel button position
-merge_request: 14596
-author: Matt Coleman
-type: fixed
diff --git a/changelogs/unreleased/fix-gpg-case-insensitive.yml b/changelogs/unreleased/fix-gpg-case-insensitive.yml
deleted file mode 100644
index 744ec00a4a8..00000000000
--- a/changelogs/unreleased/fix-gpg-case-insensitive.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Compare email addresses case insensitively when verifying GPG signatures
-merge_request: 14376
-author: Tim Bishop
-type: fixed
diff --git a/changelogs/unreleased/fix-image-diff-swipe-handle.yml b/changelogs/unreleased/fix-image-diff-swipe-handle.yml
deleted file mode 100644
index a4e0c2e8465..00000000000
--- a/changelogs/unreleased/fix-image-diff-swipe-handle.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix image diff swipe handle offset to correctly align with the frame
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/fix-import-issue-assignees.yml b/changelogs/unreleased/fix-import-issue-assignees.yml
new file mode 100644
index 00000000000..063b6afaf08
--- /dev/null
+++ b/changelogs/unreleased/fix-import-issue-assignees.yml
@@ -0,0 +1,5 @@
+---
+title: Fix missing Import/Export issue assignees
+merge_request:
+author:
+type: fixed
diff --git a/changelogs/unreleased/fix-multi-line-hook-output.yml b/changelogs/unreleased/fix-multi-line-hook-output.yml
deleted file mode 100644
index f625ec2ee6c..00000000000
--- a/changelogs/unreleased/fix-multi-line-hook-output.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Display full pre-receive and post-receive hook output in GitLab UI
-merge_request: 14222
-author: Robin Bobbitt
-type: fixed
diff --git a/changelogs/unreleased/fix-non-diff-resolved-discussion.yml b/changelogs/unreleased/fix-non-diff-resolved-discussion.yml
deleted file mode 100644
index 9bff53ea7c9..00000000000
--- a/changelogs/unreleased/fix-non-diff-resolved-discussion.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Force non diff resolved discussion to display when collapse toggled
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/fix-project-select-js-without-button.yml b/changelogs/unreleased/fix-project-select-js-without-button.yml
new file mode 100644
index 00000000000..389ca2394f0
--- /dev/null
+++ b/changelogs/unreleased/fix-project-select-js-without-button.yml
@@ -0,0 +1,5 @@
+---
+title: Use project select dropdown not only as a combobutton
+merge_request: 15043
+author:
+type: fixed
diff --git a/changelogs/unreleased/fix-resolved-side-by-side.yml b/changelogs/unreleased/fix-resolved-side-by-side.yml
deleted file mode 100644
index 424130c3eb0..00000000000
--- a/changelogs/unreleased/fix-resolved-side-by-side.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix resolved discussions not expanding on side by side view
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/fix-sidebar-with-scrollbars.yml b/changelogs/unreleased/fix-sidebar-with-scrollbars.yml
deleted file mode 100644
index e0b3851b97f..00000000000
--- a/changelogs/unreleased/fix-sidebar-with-scrollbars.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fixed the sidebar scrollbar overlapping links
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/fix-tooltip-width-issue-board.yml b/changelogs/unreleased/fix-tooltip-width-issue-board.yml
deleted file mode 100644
index a648953c5bd..00000000000
--- a/changelogs/unreleased/fix-tooltip-width-issue-board.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Issue board tooltips are now the correct width when the column is collapsed
-merge_request:
-author: Jedidiah Broadbent
-type: fixed
diff --git a/changelogs/unreleased/fix-update-doorkeeper-openid-connect.yml b/changelogs/unreleased/fix-update-doorkeeper-openid-connect.yml
deleted file mode 100644
index c57fceec92f..00000000000
--- a/changelogs/unreleased/fix-update-doorkeeper-openid-connect.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Upgrade doorkeeper-openid_connect
-merge_request: 14372
-author: Markus Koller
-type: other
diff --git a/changelogs/unreleased/fl-autodevops-fix.yml b/changelogs/unreleased/fl-autodevops-fix.yml
deleted file mode 100644
index 21b739231a8..00000000000
--- a/changelogs/unreleased/fl-autodevops-fix.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Improve autodevops banner UX and render it only in project page
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/fl-fix-ca-time-component.yml b/changelogs/unreleased/fl-fix-ca-time-component.yml
deleted file mode 100644
index ecd377409ca..00000000000
--- a/changelogs/unreleased/fl-fix-ca-time-component.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix typo in cycle analytics breaking time component
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/force-two-up-view.yml b/changelogs/unreleased/force-two-up-view.yml
deleted file mode 100644
index 1074eb384bb..00000000000
--- a/changelogs/unreleased/force-two-up-view.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Force two up view to load by default for image diffs
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/gem-sm-bump-google-api-client-gem-from-0-8-6-to-0-13-6.yml b/changelogs/unreleased/gem-sm-bump-google-api-client-gem-from-0-8-6-to-0-13-6.yml
deleted file mode 100644
index 13ec113167f..00000000000
--- a/changelogs/unreleased/gem-sm-bump-google-api-client-gem-from-0-8-6-to-0-13-6.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Bump google-api-client Gem from 0.8.6 to 0.13.6
-merge_request:
-author:
-type: other
diff --git a/changelogs/unreleased/gitaly_feature_flag_metadata.yml b/changelogs/unreleased/gitaly_feature_flag_metadata.yml
deleted file mode 100644
index 58e42ef9324..00000000000
--- a/changelogs/unreleased/gitaly_feature_flag_metadata.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add client and call site metadata to Gitaly calls for better traceability
-merge_request: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/14332
-author:
-type: added
diff --git a/changelogs/unreleased/group-milestones-breadcrumb.yml b/changelogs/unreleased/group-milestones-breadcrumb.yml
deleted file mode 100644
index 87085759fda..00000000000
--- a/changelogs/unreleased/group-milestones-breadcrumb.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fixed milestone breadcrumb links
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/group-sort-dropdown-blank.yml b/changelogs/unreleased/group-sort-dropdown-blank.yml
deleted file mode 100644
index dd16892be4d..00000000000
--- a/changelogs/unreleased/group-sort-dropdown-blank.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fixed group sort dropdown defaulting to empty
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/hash-mr-scroll-load.yml b/changelogs/unreleased/hash-mr-scroll-load.yml
deleted file mode 100644
index 7e3965add03..00000000000
--- a/changelogs/unreleased/hash-mr-scroll-load.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fixed notes not being scrolled to in merge requests
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/hashed-storage-migration-path.yml b/changelogs/unreleased/hashed-storage-migration-path.yml
deleted file mode 100644
index 5890eb09c38..00000000000
--- a/changelogs/unreleased/hashed-storage-migration-path.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Script to migrate project's repositories to new Hashed Storage
-merge_request: 14067
-author:
-type: added
diff --git a/changelogs/unreleased/hide-pipeline-zero-duration.yml b/changelogs/unreleased/hide-pipeline-zero-duration.yml
new file mode 100644
index 00000000000..5d7a0983537
--- /dev/null
+++ b/changelogs/unreleased/hide-pipeline-zero-duration.yml
@@ -0,0 +1,5 @@
+---
+title: Hides pipeline duration in commit box when it is zero (nil)
+merge_request: 14979
+author: gvieira37
+type: fixed
diff --git a/changelogs/unreleased/hide-read-registry-scope-when-registry-disabled.yml b/changelogs/unreleased/hide-read-registry-scope-when-registry-disabled.yml
deleted file mode 100644
index 22ac9b9073f..00000000000
--- a/changelogs/unreleased/hide-read-registry-scope-when-registry-disabled.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Hide read_registry scope when registry is disabled on instance
-merge_request: 13314
-author: Robin Bobbitt
diff --git a/changelogs/unreleased/ie-event-polyfill.yml b/changelogs/unreleased/ie-event-polyfill.yml
deleted file mode 100644
index eaab089a47e..00000000000
--- a/changelogs/unreleased/ie-event-polyfill.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Adds Event polyfill for IE11
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/import-sources-fix.yml b/changelogs/unreleased/import-sources-fix.yml
deleted file mode 100644
index 03e23bc617c..00000000000
--- a/changelogs/unreleased/import-sources-fix.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Read import sources from setting at first initialization
-merge_request: 14141
-author: Visay Keo
-type: fixed
diff --git a/changelogs/unreleased/improve_sorting_list.yml b/changelogs/unreleased/improve_sorting_list.yml
deleted file mode 100644
index a3730e23ed1..00000000000
--- a/changelogs/unreleased/improve_sorting_list.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Improve list of sorting options
-merge_request: 14320
-author: Vitaliy @blackst0ne Klachkov
-type: added
diff --git a/changelogs/unreleased/issue_32215.yml b/changelogs/unreleased/issue_32215.yml
deleted file mode 100644
index c608eb6dd28..00000000000
--- a/changelogs/unreleased/issue_32215.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Allow developer role to admin milestones
-merge_request:
-author:
-type: changed
diff --git a/changelogs/unreleased/issue_35873.yml b/changelogs/unreleased/issue_35873.yml
deleted file mode 100644
index 65064b97e56..00000000000
--- a/changelogs/unreleased/issue_35873.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Commenting on image diffs
-merge_request: 14061
-author:
-type: added
diff --git a/changelogs/unreleased/issue_38777.yml b/changelogs/unreleased/issue_38777.yml
new file mode 100644
index 00000000000..5c49b2f7879
--- /dev/null
+++ b/changelogs/unreleased/issue_38777.yml
@@ -0,0 +1,5 @@
+---
+title: Allow promoting project milestones to group milestones
+merge_request:
+author:
+type: added
diff --git a/changelogs/unreleased/italicized_emoji.yml b/changelogs/unreleased/italicized_emoji.yml
deleted file mode 100644
index d3f15f94363..00000000000
--- a/changelogs/unreleased/italicized_emoji.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Update native unicode emojis to always render as normal text (previously could render italicized)
-merge_request:
-author: Branka Martinovic
-type: fixed
diff --git a/changelogs/unreleased/jobs-sort-by-id.yml b/changelogs/unreleased/jobs-sort-by-id.yml
deleted file mode 100644
index ec2c3a17b74..00000000000
--- a/changelogs/unreleased/jobs-sort-by-id.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Sort JobsController by id, not created_at
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/kt-bug-fix-revision-and-size-for-container-registry.yml b/changelogs/unreleased/kt-bug-fix-revision-and-size-for-container-registry.yml
deleted file mode 100644
index acbb24d16fc..00000000000
--- a/changelogs/unreleased/kt-bug-fix-revision-and-size-for-container-registry.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix revision and total size missing for Container Registry
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/lint-changelog-yaml.yml b/changelogs/unreleased/lint-changelog-yaml.yml
deleted file mode 100644
index dcc8bf54827..00000000000
--- a/changelogs/unreleased/lint-changelog-yaml.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Detect when changelog entries are invalid
-merge_request:
-author:
-type: other
diff --git a/changelogs/unreleased/make-merge-jid-handling-less-stateful.yml b/changelogs/unreleased/make-merge-jid-handling-less-stateful.yml
new file mode 100644
index 00000000000..fe945e822fd
--- /dev/null
+++ b/changelogs/unreleased/make-merge-jid-handling-less-stateful.yml
@@ -0,0 +1,5 @@
+---
+title: Fix widget of locked merge requests not being presented
+merge_request:
+author:
+type: fixed
diff --git a/changelogs/unreleased/mentions-in-comments.yml b/changelogs/unreleased/mentions-in-comments.yml
deleted file mode 100644
index 907f455007b..00000000000
--- a/changelogs/unreleased/mentions-in-comments.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Makes @mentions links have a different styling for better separation
-merge_request:
-author:
-type: added
diff --git a/changelogs/unreleased/merge-request-notes-performance.yml b/changelogs/unreleased/merge-request-notes-performance.yml
deleted file mode 100644
index 6cf7a5047df..00000000000
--- a/changelogs/unreleased/merge-request-notes-performance.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Use a UNION ALL for getting merge request notes
-merge_request:
-author:
-type: other
diff --git a/changelogs/unreleased/milestone-avatar-issuable-link.yml b/changelogs/unreleased/milestone-avatar-issuable-link.yml
deleted file mode 100644
index 7915ad60fa8..00000000000
--- a/changelogs/unreleased/milestone-avatar-issuable-link.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fixed milestone issuable assignee link URL
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/mk-clarify-moving-namespaces.yml b/changelogs/unreleased/mk-clarify-moving-namespaces.yml
deleted file mode 100644
index 8d89c296f61..00000000000
--- a/changelogs/unreleased/mk-clarify-moving-namespaces.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Expand docs for changing username or group path
-merge_request: 13914
-author:
-type: other
diff --git a/changelogs/unreleased/mk-normalize-ldap-user-dns.yml b/changelogs/unreleased/mk-normalize-ldap-user-dns.yml
deleted file mode 100644
index 5a128d6acc1..00000000000
--- a/changelogs/unreleased/mk-normalize-ldap-user-dns.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Search or compare LDAP DNs case-insensitively and ignore excess whitespace
-merge_request: 14697
-author:
-type: fixed
diff --git a/changelogs/unreleased/mr-14642.yml b/changelogs/unreleased/mr-14642.yml
new file mode 100644
index 00000000000..048cc79e323
--- /dev/null
+++ b/changelogs/unreleased/mr-14642.yml
@@ -0,0 +1,6 @@
+---
+title: Auto Devops kubernetes default namespace is now correctly built out of gitlab
+ project group-name
+merge_request: 14642
+author: Mircea Danila Dumitrescu
+type: fixed
diff --git a/changelogs/unreleased/mr-side-by-side-breadcrumbs-container.yml b/changelogs/unreleased/mr-side-by-side-breadcrumbs-container.yml
deleted file mode 100644
index 39b636bdfda..00000000000
--- a/changelogs/unreleased/mr-side-by-side-breadcrumbs-container.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fixed breadcrumbs container expanding in side-by-side diff view
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/mr-widget-merged-date-tooltip.yml b/changelogs/unreleased/mr-widget-merged-date-tooltip.yml
deleted file mode 100644
index ea22993ff52..00000000000
--- a/changelogs/unreleased/mr-widget-merged-date-tooltip.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fixed merge request widget merged & closed date tooltip text
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/ph-multi-file-upload-file.yml b/changelogs/unreleased/ph-multi-file-upload-file.yml
new file mode 100644
index 00000000000..a2bd3cfe459
--- /dev/null
+++ b/changelogs/unreleased/ph-multi-file-upload-file.yml
@@ -0,0 +1,5 @@
+---
+title: Allow files to uploaded in the multi-file editor
+merge_request:
+author:
+type: added
diff --git a/changelogs/unreleased/prevent-creating-multiple-application-settings.yml b/changelogs/unreleased/prevent-creating-multiple-application-settings.yml
deleted file mode 100644
index fd49028b9e9..00000000000
--- a/changelogs/unreleased/prevent-creating-multiple-application-settings.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Prevent creating multiple ApplicationSetting instances
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/project-page-clearer.yml b/changelogs/unreleased/project-page-clearer.yml
deleted file mode 100644
index 7db01373360..00000000000
--- a/changelogs/unreleased/project-page-clearer.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Added tabs to dashboard/projects to easily switch to personal projects
-merge_request:
-author:
-type: added
diff --git a/changelogs/unreleased/rc-fix-gh-import-branches-performance.yml b/changelogs/unreleased/rc-fix-gh-import-branches-performance.yml
deleted file mode 100644
index af359ce96b4..00000000000
--- a/changelogs/unreleased/rc-fix-gh-import-branches-performance.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Improve GitHub import performance
-merge_request: 14445
-author:
-type: other
diff --git a/changelogs/unreleased/rd-fix-case-sensative-email-conf-signup.yml b/changelogs/unreleased/rd-fix-case-sensative-email-conf-signup.yml
deleted file mode 100644
index 69695e403a9..00000000000
--- a/changelogs/unreleased/rd-fix-case-sensative-email-conf-signup.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix case sensitive email confirmation on signup
-merge_request: 14606
-author: robdel12
-type: fixed
diff --git a/changelogs/unreleased/refactor-animate-js.yml b/changelogs/unreleased/refactor-animate-js.yml
deleted file mode 100644
index ec32d68bbdd..00000000000
--- a/changelogs/unreleased/refactor-animate-js.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Remove animate.js and label animation.
-merge_request:
-author:
-type: removed
diff --git a/changelogs/unreleased/refactor-monitoring-service.yml b/changelogs/unreleased/refactor-monitoring-service.yml
deleted file mode 100644
index 685397cadb8..00000000000
--- a/changelogs/unreleased/refactor-monitoring-service.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Perform prometheus data endpoint requests in parallel
-merge_request: 14003
-author:
-type: fixed
diff --git a/changelogs/unreleased/remote_user.yml b/changelogs/unreleased/remote_user.yml
deleted file mode 100644
index 75a941fa95f..00000000000
--- a/changelogs/unreleased/remote_user.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Add username as GL_USERNAME in hooks
-merge_request:
-author:
diff --git a/changelogs/unreleased/remove-temporary-ci-index.yml b/changelogs/unreleased/remove-temporary-ci-index.yml
deleted file mode 100644
index a319f7fff7f..00000000000
--- a/changelogs/unreleased/remove-temporary-ci-index.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Remove an index on ci_builds meant to be only temporary
-merge_request:
-author:
-type: other
diff --git a/changelogs/unreleased/remove-use-key-worker.yml b/changelogs/unreleased/remove-use-key-worker.yml
deleted file mode 100644
index a39bcae66bc..00000000000
--- a/changelogs/unreleased/remove-use-key-worker.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Stop using Sidekiq for updating Key#last_used_at
-merge_request:
-author:
-type: changed
diff --git a/changelogs/unreleased/remove_repo_prefix_from_api.yml b/changelogs/unreleased/remove_repo_prefix_from_api.yml
deleted file mode 100644
index bf2075e529c..00000000000
--- a/changelogs/unreleased/remove_repo_prefix_from_api.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Remove 'Repo' prefix from API entites
-merge_request: 14694
-author: Vitaliy @blackst0ne Klachkov
-type: other
diff --git a/changelogs/unreleased/replace_emails-feature.yml b/changelogs/unreleased/replace_emails-feature.yml
deleted file mode 100644
index d7f1a7a7ba9..00000000000
--- a/changelogs/unreleased/replace_emails-feature.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Replace the profile/emails.feature spinach test with an rspec analog
-merge_request: 14172
-author: Vitaliy @blackst0ne Klachkov
-type: other
diff --git a/changelogs/unreleased/replace_group_links-feature.yml b/changelogs/unreleased/replace_group_links-feature.yml
deleted file mode 100644
index 7dd157632c9..00000000000
--- a/changelogs/unreleased/replace_group_links-feature.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Replace project/group_links.feature spinach test with an rspec analog
-merge_request: 14169
-author: Vitaliy @blackst0ne Klachkov
-type: other
diff --git a/changelogs/unreleased/replace_milestone-feature.yml b/changelogs/unreleased/replace_milestone-feature.yml
deleted file mode 100644
index effe6d65645..00000000000
--- a/changelogs/unreleased/replace_milestone-feature.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Replace the project/milestone.feature spinach test with an rspec analog
-merge_request: 14171
-author: Vitaliy @blackst0ne Klachkov
-type: other
diff --git a/changelogs/unreleased/replace_profile_active_tab-feature.yml b/changelogs/unreleased/replace_profile_active_tab-feature.yml
deleted file mode 100644
index e911396a2b9..00000000000
--- a/changelogs/unreleased/replace_profile_active_tab-feature.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Replace the 'profile/active_tab.feature' spinach test with an rspec analog
-merge_request: 14239
-author: Vitaliy @blackst0ne Klachkov
-type: other
diff --git a/changelogs/unreleased/replace_project_archived-feature.yml b/changelogs/unreleased/replace_project_archived-feature.yml
deleted file mode 100644
index d0697347aa0..00000000000
--- a/changelogs/unreleased/replace_project_archived-feature.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Replace the 'project/archived.feature' spinach test with an rspec analog
-merge_request: 14322
-author: Vitaliy @blackst0ne Klachkov
-type: other
diff --git a/changelogs/unreleased/replace_project_builds_summary-feature.yml b/changelogs/unreleased/replace_project_builds_summary-feature.yml
deleted file mode 100644
index 48652b39b7e..00000000000
--- a/changelogs/unreleased/replace_project_builds_summary-feature.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Replace the 'project/builds/summary.feature' spinach test with an rspec analog
-merge_request: 14177
-author: Vitaliy @blackst0ne Klachkov
-type: other
diff --git a/changelogs/unreleased/replace_project_commits_revert-feature.yml b/changelogs/unreleased/replace_project_commits_revert-feature.yml
deleted file mode 100644
index 7fc9fcf3580..00000000000
--- a/changelogs/unreleased/replace_project_commits_revert-feature.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Replace the 'project/commits/revert.feature' spinach test with an rspec analog
-merge_request: 14325
-author: Vitaliy @blackst0ne Klachkov
-type: other
diff --git a/changelogs/unreleased/replace_project_issues_award_emoji-feature.yml b/changelogs/unreleased/replace_project_issues_award_emoji-feature.yml
deleted file mode 100644
index a4a7435d4fa..00000000000
--- a/changelogs/unreleased/replace_project_issues_award_emoji-feature.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Replace the 'project/issues/award_emoji.feature' spinach test with an rspec analog
-merge_request: 14202
-author: Vitaliy @blackst0ne Klachkov
-type: other
diff --git a/changelogs/unreleased/replace_project_merge_requests-feature.yml b/changelogs/unreleased/replace_project_merge_requests-feature.yml
deleted file mode 100644
index 082c922a32b..00000000000
--- a/changelogs/unreleased/replace_project_merge_requests-feature.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Replace the 'project/merge_requests.feature' spinach test with an rspec analog
-merge_request: 14621
-author: Vitaliy @blackst0ne Klachkov
-type: other
diff --git a/changelogs/unreleased/replace_project_merge_requests_accept-feature.yml b/changelogs/unreleased/replace_project_merge_requests_accept-feature.yml
deleted file mode 100644
index 03562d6025e..00000000000
--- a/changelogs/unreleased/replace_project_merge_requests_accept-feature.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Replace the 'project/merge_requests/accept.feature' spinach test with an rspec analog
-merge_request: 14176
-author: Vitaliy @blackst0ne Klachkov
-type: other
diff --git a/changelogs/unreleased/replace_project_merge_requests_revert-feature.yml b/changelogs/unreleased/replace_project_merge_requests_revert-feature.yml
deleted file mode 100644
index 7d1ab4566b6..00000000000
--- a/changelogs/unreleased/replace_project_merge_requests_revert-feature.yml
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: Replace the 'project/merge_requests/revert.feature' spinach test with an rspec
- analog
-merge_request: 14201
-author: Vitaliy @blackst0ne Klachkov
-type: other
diff --git a/changelogs/unreleased/replace_project_service-feature.yml b/changelogs/unreleased/replace_project_service-feature.yml
deleted file mode 100644
index 11814732a9b..00000000000
--- a/changelogs/unreleased/replace_project_service-feature.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Replace the 'project/service.feature' spinach test with an rspec analog
-merge_request: 14432
-author: Vitaliy @blackst0ne Klachkov
-type: other
diff --git a/changelogs/unreleased/replace_project_shortcuts-feature.yml b/changelogs/unreleased/replace_project_shortcuts-feature.yml
deleted file mode 100644
index 89e47a7a983..00000000000
--- a/changelogs/unreleased/replace_project_shortcuts-feature.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Replace the 'project/shortcuts.feature' spinach test with an rspec analog
-merge_request: 14431
-author: Vitaliy @blackst0ne Klachkov
-type: other
diff --git a/changelogs/unreleased/replace_project_snippets-feature.yml b/changelogs/unreleased/replace_project_snippets-feature.yml
deleted file mode 100644
index 4fdee70008a..00000000000
--- a/changelogs/unreleased/replace_project_snippets-feature.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Replace the 'project/snippets.feature' spinach test with an rspec analog
-merge_request: 14326
-author: Vitaliy @blackst0ne Klachkov
-type: other
diff --git a/changelogs/unreleased/replace_search-feature.yml b/changelogs/unreleased/replace_search-feature.yml
deleted file mode 100644
index 487f602ba30..00000000000
--- a/changelogs/unreleased/replace_search-feature.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Replace the 'search.feature' spinach test with an rspec analog
-merge_request: 14248
-author: Vitaliy @blackst0ne Klachkov
-type: other
diff --git a/changelogs/unreleased/replace_spinach_wiki-feature.yml b/changelogs/unreleased/replace_spinach_wiki-feature.yml
deleted file mode 100644
index a1801f1b58d..00000000000
--- a/changelogs/unreleased/replace_spinach_wiki-feature.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Replace 'project/wiki.feature' spinach test with an rspec analog
-merge_request: 13856
-author: Vitaliy @blackst0ne Klachkov
-type: other
diff --git a/changelogs/unreleased/replace_team_management-feature.yml b/changelogs/unreleased/replace_team_management-feature.yml
deleted file mode 100644
index bc2bb17faf1..00000000000
--- a/changelogs/unreleased/replace_team_management-feature.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Replace the project/team_management.feature spinach test with an rspec analog
-merge_request: 14173
-author: Vitaliy @blackst0ne Klachkov
-type: other
diff --git a/changelogs/unreleased/rotated_profile_image.yml b/changelogs/unreleased/rotated_profile_image.yml
deleted file mode 100644
index 1e221e47379..00000000000
--- a/changelogs/unreleased/rotated_profile_image.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix profile image orientation based on EXIF data gvieira37
-merge_request: 14461
-author: gvieira37
-type: fixed
diff --git a/changelogs/unreleased/save-a-query-on-todos-with-no-filters.yml b/changelogs/unreleased/save-a-query-on-todos-with-no-filters.yml
deleted file mode 100644
index c9fb042aa37..00000000000
--- a/changelogs/unreleased/save-a-query-on-todos-with-no-filters.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Remove a SQL query from the todos index page
-merge_request:
-author:
-type: other
diff --git a/changelogs/unreleased/sh-fix-broken-redirection-relative-url-root.yml b/changelogs/unreleased/sh-fix-broken-redirection-relative-url-root.yml
new file mode 100644
index 00000000000..96e5195d247
--- /dev/null
+++ b/changelogs/unreleased/sh-fix-broken-redirection-relative-url-root.yml
@@ -0,0 +1,5 @@
+---
+title: Fix broken Members link when relative URL root paths are used
+merge_request:
+author:
+type: fixed
diff --git a/changelogs/unreleased/sh-fix-container-registry-destroy.yml b/changelogs/unreleased/sh-fix-container-registry-destroy.yml
new file mode 100644
index 00000000000..21a463da62a
--- /dev/null
+++ b/changelogs/unreleased/sh-fix-container-registry-destroy.yml
@@ -0,0 +1,5 @@
+---
+title: Fix deletion of container registry or images returning an error
+merge_request:
+author:
+type: fixed
diff --git a/changelogs/unreleased/sh-fix-environment-write-ref.yml b/changelogs/unreleased/sh-fix-environment-write-ref.yml
new file mode 100644
index 00000000000..8f291843ebe
--- /dev/null
+++ b/changelogs/unreleased/sh-fix-environment-write-ref.yml
@@ -0,0 +1,5 @@
+---
+title: Fix the writing of invalid environment refs
+merge_request:
+author:
+type: fixed
diff --git a/changelogs/unreleased/sh-fix-username-logging.yml b/changelogs/unreleased/sh-fix-username-logging.yml
deleted file mode 100644
index dadf3fb6729..00000000000
--- a/changelogs/unreleased/sh-fix-username-logging.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix username and ID not logging in production_json.log for Git activity
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/sh-memoize-logger.yml b/changelogs/unreleased/sh-memoize-logger.yml
new file mode 100644
index 00000000000..1b6567ce72f
--- /dev/null
+++ b/changelogs/unreleased/sh-memoize-logger.yml
@@ -0,0 +1,5 @@
+---
+title: Memoize GitLab logger to reduce open file descriptors
+merge_request:
+author:
+type: fixed
diff --git a/changelogs/unreleased/sh-show-all-slack-names.yml b/changelogs/unreleased/sh-show-all-slack-names.yml
deleted file mode 100644
index f970cd0fb15..00000000000
--- a/changelogs/unreleased/sh-show-all-slack-names.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Include GitLab full name in Slack messages
-merge_request:
-author:
-type: changed
diff --git a/changelogs/unreleased/sh-thread-safe-markdown.yml b/changelogs/unreleased/sh-thread-safe-markdown.yml
deleted file mode 100644
index af7d9d58a9f..00000000000
--- a/changelogs/unreleased/sh-thread-safe-markdown.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Make Redcarpet Markdown renderer thread-safe
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/tag-link-size.yml b/changelogs/unreleased/tag-link-size.yml
deleted file mode 100644
index d94e415ba1f..00000000000
--- a/changelogs/unreleased/tag-link-size.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Adjusts tag link to avoid underlining spaces
-merge_request: 14544
-author: Guilherme Vieira
-type: fixed
diff --git a/changelogs/unreleased/tc-geo-read-only-idea.yml b/changelogs/unreleased/tc-geo-read-only-idea.yml
deleted file mode 100644
index e1b52eef2ca..00000000000
--- a/changelogs/unreleased/tc-geo-read-only-idea.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Create idea of read-only database
-merge_request: 14688
-author:
-type: changed
diff --git a/changelogs/unreleased/uipolish-fix-2factor-warning.yml b/changelogs/unreleased/uipolish-fix-2factor-warning.yml
deleted file mode 100644
index 9f55207d309..00000000000
--- a/changelogs/unreleased/uipolish-fix-2factor-warning.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Two factor auth messages in settings no longer overlap the button
-merge_request:
-author: Jedidiah Broadbent
-type: fixed
diff --git a/changelogs/unreleased/uipolish-fix-remember-me-checkbox.yml b/changelogs/unreleased/uipolish-fix-remember-me-checkbox.yml
deleted file mode 100644
index 34aa3d0db6f..00000000000
--- a/changelogs/unreleased/uipolish-fix-remember-me-checkbox.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Made the "remember me" check boxes have consistent styles and alignment
-merge_request:
-author: Jedidiah Broadbent
-type: fixed
diff --git a/changelogs/unreleased/update-fe-i18n-guide.yml b/changelogs/unreleased/update-fe-i18n-guide.yml
new file mode 100644
index 00000000000..10bcf7836c6
--- /dev/null
+++ b/changelogs/unreleased/update-fe-i18n-guide.yml
@@ -0,0 +1,5 @@
+---
+title: Update i18n section in FE docs for marking and interpolation
+merge_request:
+author:
+type: changed
diff --git a/changelogs/unreleased/update-pages-0-6.yml b/changelogs/unreleased/update-pages-0-6.yml
deleted file mode 100644
index 507bb4d78e9..00000000000
--- a/changelogs/unreleased/update-pages-0-6.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Update GitLab Pages to v0.6.0
-merge_request: 14630
-author:
-type: other
diff --git a/changelogs/unreleased/use-git-branch-merged.yml b/changelogs/unreleased/use-git-branch-merged.yml
new file mode 100644
index 00000000000..24ec226250c
--- /dev/null
+++ b/changelogs/unreleased/use-git-branch-merged.yml
@@ -0,0 +1,5 @@
+---
+title: Improve branch listing page performance
+merge_request: 14729
+author:
+type: performance
diff --git a/changelogs/unreleased/valid-branch-name-dash-bug.yml b/changelogs/unreleased/valid-branch-name-dash-bug.yml
deleted file mode 100644
index 89e4578b3e5..00000000000
--- a/changelogs/unreleased/valid-branch-name-dash-bug.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Prevent branches or tags from starting with invalid characters (e.g. -, .)
-merge_request:
-author:
-type: fixed
diff --git a/changelogs/unreleased/voogsgerd-gitlab-ce-daniel-legacy-config.yml b/changelogs/unreleased/voogsgerd-gitlab-ce-daniel-legacy-config.yml
deleted file mode 100644
index faa5d3303c6..00000000000
--- a/changelogs/unreleased/voogsgerd-gitlab-ce-daniel-legacy-config.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Removed two legacy config options
-merge_request:
-author: Daniel Voogsgerd
-type: deprecated
diff --git a/changelogs/unreleased/winh-delete-account-modal.yml b/changelogs/unreleased/winh-delete-account-modal.yml
deleted file mode 100644
index f1e2710fdcc..00000000000
--- a/changelogs/unreleased/winh-delete-account-modal.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Show confirmation modal before deleting account
-merge_request: 14360
-author:
-type: changed
diff --git a/changelogs/unreleased/winh-indeterminate-dropdown.yml b/changelogs/unreleased/winh-indeterminate-dropdown.yml
deleted file mode 100644
index 61205d1643e..00000000000
--- a/changelogs/unreleased/winh-indeterminate-dropdown.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix alignment for indeterminate marker in dropdowns
-merge_request: 14809
-author:
-type: fixed
diff --git a/changelogs/unreleased/winh-protected-branch-modal-merged.yml b/changelogs/unreleased/winh-protected-branch-modal-merged.yml
deleted file mode 100644
index 63f1f424a5d..00000000000
--- a/changelogs/unreleased/winh-protected-branch-modal-merged.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Display whether branch has been merged when deleting protected branch
-merge_request: 14220
-author:
-type: changed
diff --git a/changelogs/unreleased/winh-sprintf.yml b/changelogs/unreleased/winh-sprintf.yml
deleted file mode 100644
index f8ae5932ae4..00000000000
--- a/changelogs/unreleased/winh-sprintf.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Add basic sprintf implementation to JavaScript
-merge_request: 14506
-author:
-type: other
diff --git a/changelogs/unreleased/zj-commit-cache.yml b/changelogs/unreleased/zj-commit-cache.yml
new file mode 100644
index 00000000000..e3afe0ea7ef
--- /dev/null
+++ b/changelogs/unreleased/zj-commit-cache.yml
@@ -0,0 +1,5 @@
+---
+title: Cache commits fetched from the repository
+merge_request:
+author:
+type: performance
diff --git a/changelogs/unreleased/zj-peek-gitaly.yml b/changelogs/unreleased/zj-peek-gitaly.yml
new file mode 100644
index 00000000000..bd2f2a07540
--- /dev/null
+++ b/changelogs/unreleased/zj-peek-gitaly.yml
@@ -0,0 +1,5 @@
+---
+title: Add Gitaly metrics to the performance bar
+merge_request:
+author:
+type: other
diff --git a/changelogs/unreleased/zj-ruby-2-3-5.yml b/changelogs/unreleased/zj-ruby-2-3-5.yml
new file mode 100644
index 00000000000..09ec02417aa
--- /dev/null
+++ b/changelogs/unreleased/zj-ruby-2-3-5.yml
@@ -0,0 +1,5 @@
+---
+title: Upgrade Ruby to 2.3.5 to include security patches
+merge_request: 15099
+author:
+type: security
diff --git a/config/initializers/peek.rb b/config/initializers/peek.rb
index a54d53cbbe2..1cff355346c 100644
--- a/config/initializers/peek.rb
+++ b/config/initializers/peek.rb
@@ -16,6 +16,7 @@ Peek.into Peek::Views::Redis
Peek.into Peek::Views::Sidekiq
Peek.into Peek::Views::Rblineprof
Peek.into Peek::Views::GC
+Peek.into Peek::Views::Gitaly
# rubocop:disable Style/ClassAndModuleCamelCase
class PEEK_DB_CLIENT
diff --git a/config/routes/ci.rb b/config/routes/ci.rb
index cbd4c2db852..60c1724bc05 100644
--- a/config/routes/ci.rb
+++ b/config/routes/ci.rb
@@ -1,5 +1,5 @@
namespace :ci do
resource :lint, only: [:show, :create]
- root to: redirect('/')
+ root to: redirect('')
end
diff --git a/config/routes/group.rb b/config/routes/group.rb
index 702df5b7b5a..f4d520a2518 100644
--- a/config/routes/group.rb
+++ b/config/routes/group.rb
@@ -4,51 +4,51 @@ resources :groups, only: [:index, :new, :create] do
post :preview_markdown
end
-scope(path: 'groups/*group_id',
- module: :groups,
- as: :group,
- constraints: { group_id: Gitlab::PathRegex.full_namespace_route_regex }) do
- resources :group_members, only: [:index, :create, :update, :destroy], concerns: :access_requestable do
- post :resend_invite, on: :member
- delete :leave, on: :collection
+constraints(GroupUrlConstrainer.new) do
+ scope(path: 'groups/*id',
+ controller: :groups,
+ constraints: { id: Gitlab::PathRegex.full_namespace_route_regex, format: /(html|json|atom)/ }) do
+ get :edit, as: :edit_group
+ get :issues, as: :issues_group
+ get :merge_requests, as: :merge_requests_group
+ get :projects, as: :projects_group
+ get :activity, as: :activity_group
+ get '/', action: :show, as: :group_canonical
end
- resource :avatar, only: [:destroy]
- resources :milestones, constraints: { id: /[^\/]+/ }, only: [:index, :show, :edit, :update, :new, :create] do
- member do
- get :merge_requests
- get :participants
- get :labels
+ scope(path: 'groups/*group_id',
+ module: :groups,
+ as: :group,
+ constraints: { group_id: Gitlab::PathRegex.full_namespace_route_regex }) do
+ resources :group_members, only: [:index, :create, :update, :destroy], concerns: :access_requestable do
+ post :resend_invite, on: :member
+ delete :leave, on: :collection
end
- end
- resources :labels, except: [:show] do
- post :toggle_subscription, on: :member
- end
+ resource :avatar, only: [:destroy]
+ resources :milestones, constraints: { id: /[^\/]+/ }, only: [:index, :show, :edit, :update, :new, :create] do
+ member do
+ get :merge_requests
+ get :participants
+ get :labels
+ end
+ end
- scope path: '-' do
- namespace :settings do
- resource :ci_cd, only: [:show], controller: 'ci_cd'
+ resources :labels, except: [:show] do
+ post :toggle_subscription, on: :member
end
- resources :variables, only: [:index, :show, :update, :create, :destroy]
+ scope path: '-' do
+ namespace :settings do
+ resource :ci_cd, only: [:show], controller: 'ci_cd'
+ end
- resources :children, only: [:index]
- end
-end
+ resources :variables, only: [:index, :show, :update, :create, :destroy]
-scope(path: 'groups/*id',
- controller: :groups,
- constraints: { id: Gitlab::PathRegex.full_namespace_route_regex, format: /(html|json|atom)/ }) do
- get :edit, as: :edit_group
- get :issues, as: :issues_group
- get :merge_requests, as: :merge_requests_group
- get :projects, as: :projects_group
- get :activity, as: :activity_group
- get '/', action: :show, as: :group_canonical
-end
+ resources :children, only: [:index]
+ end
+ end
-constraints(GroupUrlConstrainer.new) do
scope(path: '*id',
as: :group,
constraints: { id: Gitlab::PathRegex.full_namespace_route_regex, format: /(html|json|atom)/ },
diff --git a/config/routes/help.rb b/config/routes/help.rb
index d53822da9ec..2ea8bfd7aed 100644
--- a/config/routes/help.rb
+++ b/config/routes/help.rb
@@ -1,4 +1,5 @@
-get 'help' => 'help#index'
-get 'help/shortcuts' => 'help#shortcuts'
-get 'help/ui' => 'help#ui'
-get 'help/*path' => 'help#show', as: :help_page
+get 'help' => 'help#index'
+get 'help/shortcuts' => 'help#shortcuts'
+get 'help/ui' => 'help#ui'
+get 'help/instance_configuration' => 'help#instance_configuration'
+get 'help/*path' => 'help#show', as: :help_page
diff --git a/config/routes/project.rb b/config/routes/project.rb
index d05fe11f233..746c0c46677 100644
--- a/config/routes/project.rb
+++ b/config/routes/project.rb
@@ -293,6 +293,7 @@ constraints(ProjectUrlConstrainer.new) do
resources :milestones, constraints: { id: /\d+/ } do
member do
+ post :promote
put :sort_issues
put :sort_merge_requests
get :merge_requests
@@ -393,7 +394,7 @@ constraints(ProjectUrlConstrainer.new) do
end
end
namespace :settings do
- get :members, to: redirect('/%{namespace_id}/%{project_id}/project_members')
+ get :members, to: redirect("%{namespace_id}/%{project_id}/project_members")
resource :ci_cd, only: [:show], controller: 'ci_cd'
resource :integrations, only: [:show]
resource :repository, only: [:show], controller: :repository
diff --git a/config/routes/snippets.rb b/config/routes/snippets.rb
index 0a4ebac3ca3..81bc890d86b 100644
--- a/config/routes/snippets.rb
+++ b/config/routes/snippets.rb
@@ -17,5 +17,5 @@ resources :snippets, concerns: :awardable do
end
end
-get '/s/:username', to: redirect('/u/%{username}/snippets'),
+get '/s/:username', to: redirect('u/%{username}/snippets'),
constraints: { username: /[a-zA-Z.0-9_\-]+(?<!\.atom)/ }
diff --git a/config/routes/user.rb b/config/routes/user.rb
index e682dcd6663..733a3f6ce9a 100644
--- a/config/routes/user.rb
+++ b/config/routes/user.rb
@@ -22,17 +22,17 @@ scope(constraints: { username: Gitlab::PathRegex.root_namespace_route_regex }) d
get :contributed, as: :contributed_projects
get :snippets
get :exists
- get '/', to: redirect('/%{username}'), as: nil
+ get '/', to: redirect('%{username}'), as: nil
end
# Compatibility with old routing
# TODO (dzaporozhets): remove in 10.0
- get '/u/:username', to: redirect('/%{username}')
+ get '/u/:username', to: redirect('%{username}')
# TODO (dzaporozhets): remove in 9.0
- get '/u/:username/groups', to: redirect('/users/%{username}/groups')
- get '/u/:username/projects', to: redirect('/users/%{username}/projects')
- get '/u/:username/snippets', to: redirect('/users/%{username}/snippets')
- get '/u/:username/contributed', to: redirect('/users/%{username}/contributed')
+ get '/u/:username/groups', to: redirect('users/%{username}/groups')
+ get '/u/:username/projects', to: redirect('users/%{username}/projects')
+ get '/u/:username/snippets', to: redirect('users/%{username}/snippets')
+ get '/u/:username/contributed', to: redirect('users/%{username}/contributed')
end
constraints(UserUrlConstrainer.new) do
diff --git a/db/migrate/20171017145932_add_new_circuitbreaker_settings_to_application_settings.rb b/db/migrate/20171017145932_add_new_circuitbreaker_settings_to_application_settings.rb
new file mode 100644
index 00000000000..07eb25c0b0f
--- /dev/null
+++ b/db/migrate/20171017145932_add_new_circuitbreaker_settings_to_application_settings.rb
@@ -0,0 +1,16 @@
+class AddNewCircuitbreakerSettingsToApplicationSettings < ActiveRecord::Migration
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ def change
+ add_column :application_settings,
+ :circuitbreaker_access_retries,
+ :integer,
+ default: 3
+ add_column :application_settings,
+ :circuitbreaker_backoff_threshold,
+ :integer,
+ default: 80
+ end
+end
diff --git a/db/post_migrate/20170525140254_rename_all_reserved_paths_again.rb b/db/post_migrate/20170525140254_rename_all_reserved_paths_again.rb
index 9441b236c8d..2125cc046e5 100644
--- a/db/post_migrate/20170525140254_rename_all_reserved_paths_again.rb
+++ b/db/post_migrate/20170525140254_rename_all_reserved_paths_again.rb
@@ -13,7 +13,6 @@ class RenameAllReservedPathsAgain < ActiveRecord::Migration
.well-known
abuse_reports
admin
- all
api
assets
autocomplete
@@ -24,29 +23,20 @@ class RenameAllReservedPathsAgain < ActiveRecord::Migration
groups
health_check
help
- hooks
import
invites
- issues
jwt
koding
- member
- merge_requests
- new
- notes
notification_settings
oauth
profile
projects
public
- repository
robots.txt
s
search
sent_notifications
- services
snippets
- teams
u
unicorn_test
unsubscribes
@@ -94,7 +84,6 @@ class RenameAllReservedPathsAgain < ActiveRecord::Migration
notification_setting
pipeline_quota
projects
- subgroups
].freeze
def up
diff --git a/db/schema.rb b/db/schema.rb
index c2c04873d4d..530f08022be 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 20171012101043) do
+ActiveRecord::Schema.define(version: 20171017145932) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -138,6 +138,8 @@ ActiveRecord::Schema.define(version: 20171012101043) do
t.integer "circuitbreaker_failure_wait_time", default: 30
t.integer "circuitbreaker_failure_reset_time", default: 1800
t.integer "circuitbreaker_storage_timeout", default: 30
+ t.integer "circuitbreaker_access_retries", default: 3
+ t.integer "circuitbreaker_backoff_threshold", default: 80
end
create_table "audit_events", force: :cascade do |t|
diff --git a/doc/README.md b/doc/README.md
index c6500a37aa9..5eabc126b95 100644
--- a/doc/README.md
+++ b/doc/README.md
@@ -85,7 +85,7 @@ Manage your [repositories](user/project/repository/index.md) from the UI (user i
### Issues and Merge Requests (MRs)
-- [Discussions](user/discussions/index.md) Threads, comments, and resolvable discussions in issues, commits, and merge requests.
+- [Discussions](user/discussions/index.md): Threads, comments, and resolvable discussions in issues, commits, and merge requests.
- [Issues](user/project/issues/index.md)
- [Project issue Board](user/project/issue_board.md)
- [Issues and merge requests templates](user/project/description_templates.md): Create templates for submitting new issues and merge requests.
@@ -155,7 +155,7 @@ have access to GitLab administration tools and settings.
- [Git LFS configuration](workflow/lfs/lfs_administration.md): Learn how to use LFS under GitLab.
- [GitLab Pages configuration](administration/pages/index.md): Configure GitLab Pages.
- [High Availability](administration/high_availability/README.md): Configure multiple servers for scaling or high availability.
-- [User cohorts](user/admin_area/user_cohorts.md) View user activity over time.
+- [User cohorts](user/admin_area/user_cohorts.md): View user activity over time.
- [Web terminals](administration/integration/terminal.md): Provide terminal access to environments from within GitLab.
- GitLab CI
- [CI admin settings](user/admin_area/settings/continuous_integration.md): Define max artifacts size and expiration time.
diff --git a/doc/administration/img/circuitbreaker_config.png b/doc/administration/img/circuitbreaker_config.png
index 9250d38297c..e811d173634 100644
--- a/doc/administration/img/circuitbreaker_config.png
+++ b/doc/administration/img/circuitbreaker_config.png
Binary files differ
diff --git a/doc/administration/monitoring/performance/performance_bar.md b/doc/administration/monitoring/performance/performance_bar.md
index 68efe0aae5c..b9464945cea 100644
--- a/doc/administration/monitoring/performance/performance_bar.md
+++ b/doc/administration/monitoring/performance/performance_bar.md
@@ -28,6 +28,12 @@ will be allowed to display the Performance Bar.
Make sure _Enable the Performance Bar_ is checked and hit
**Save** to save the changes.
+Once the Performance Bar is enabled, you will need to press the [<kbd>p</kbd> +
+<kbd>b</kbd> keyboard shortcut](../../../workflow/shortcuts.md) to actually
+display it.
+
+You can toggle the Bar using the same shortcut.
+
---
![GitLab Performance Bar Admin Settings](img/performance_bar_configuration_settings.png)
diff --git a/doc/administration/monitoring/prometheus/gitlab_metrics.md b/doc/administration/monitoring/prometheus/gitlab_metrics.md
index 6baae20d16a..11d5e077a36 100644
--- a/doc/administration/monitoring/prometheus/gitlab_metrics.md
+++ b/doc/administration/monitoring/prometheus/gitlab_metrics.md
@@ -20,7 +20,7 @@ it, the client IP needs to be [included in a whitelist][whitelist].
Currently the embedded Prometheus server is not automatically configured to
collect metrics from this endpoint. We recommend setting up another Prometheus
server, because the embedded server configuration is overwritten once every
-[reconfigure of GitLab][reconfigure]. In the future this will not be required.
+[reconfigure of GitLab][reconfigure]. In the future this will not be required.
## Metrics available
@@ -45,6 +45,8 @@ In this experimental phase, only a few metrics are available:
| redis_ping_success | Gauge | 9.4 | Whether or not the last redis ping succeeded |
| redis_ping_latency_seconds | Gauge | 9.4 | Round trip time of the redis ping |
| user_session_logins_total | Counter | 9.4 | Counter of how many users have logged in |
+| filesystem_circuitbreaker_latency_seconds | Histogram | 9.5 | Latency of the stat check the circuitbreaker uses to probe a shard |
+| filesystem_circuitbreaker | Gauge | 9.5 | Wether or not the circuit for a certain shard is broken or not |
## Metrics shared directory
diff --git a/doc/administration/repository_storage_paths.md b/doc/administration/repository_storage_paths.md
index efcabd69822..96f436fa7c3 100644
--- a/doc/administration/repository_storage_paths.md
+++ b/doc/administration/repository_storage_paths.md
@@ -109,6 +109,11 @@ This can be configured from the admin interface:
![circuitbreaker configuration](img/circuitbreaker_config.png)
+**Number of access attempts**: The number of attempts GitLab will make to access a
+storage when probing a shard.
+
+**Number of failures before backing off**: The number of failures after which
+GitLab will start temporarily disabling access to a storage shard on a host.
**Maximum git storage failures:** The number of failures of after which GitLab will
completely prevent access to the storage. The number of failures can be reset in
@@ -126,6 +131,15 @@ mount is reset.
**Seconds to wait for a storage access attempt:** The time in seconds GitLab will
try to access storage. After this time a timeout error will be raised.
+To enable the circuitbreaker for repository storage you can flip the feature flag from a rails console:
+
+```
+Feature.enable('git_storage_circuit_breaker')
+```
+
+Alternatively it can be enabled by setting `true` in the `GIT_STORAGE_CIRCUIT_BREAKER` environment variable.
+This approach would be used when enabling the circuit breaker on a single host.
+
When storage failures occur, this will be visible in the admin interface like this:
![failing storage](img/failing_storage.png)
diff --git a/doc/administration/repository_storage_types.md b/doc/administration/repository_storage_types.md
index fa882bbe28a..0cb2648cc1e 100644
--- a/doc/administration/repository_storage_types.md
+++ b/doc/administration/repository_storage_types.md
@@ -25,7 +25,10 @@ Any change in the URL will need to be reflected on disk (when groups / users or
of load in big installations, and can be even worst if they are using any type of network based filesystem.
Last, for GitLab Geo, this storage type means we have to synchronize the disk state, replicate renames in the correct
-order or we may end-up with wrong repository or missing data temporarily.
+order or we may end-up with wrong repository or missing data temporarily.
+
+This pattern also exists in other objects stored in GitLab, like issue Attachments, GitLab Pages artifacts,
+Docker Containers for the integrated Registry, etc.
## Hashed Storage
@@ -67,3 +70,23 @@ To migrate your existing projects to the new storage type, check the specific [r
[ce-28283]: https://gitlab.com/gitlab-org/gitlab-ce/issues/28283
[rake tasks]: raketasks/storage.md#migrate-existing-projects-to-hashed-storage
[storage-paths]: repository_storage_types.md
+
+### Hashed Storage coverage
+
+We are incrementally moving every storable object in GitLab to the Hashed Storage pattern. You can check the current
+coverage status below.
+
+Not that things stored in S3 compatible endpoint, will not have the downsides mentioned earlier, if they are not
+prefixed with `#{namespace}/#{project_name}`, which is true for CI Cache and LFS Objects.
+
+| Storable Object | Legacy Storage | Hashed Storage | S3 Compatible | GitLab Version |
+| ----------------| -------------- | -------------- | ------------- | -------------- |
+| Repository | Yes | Yes | - | 10.0 |
+| Attachments | Yes | Yes | - | 10.2 |
+| Avatars | Yes | No | - | - |
+| Pages | Yes | No | - | - |
+| Docker Registry | Yes | No | - | - |
+| CI Build Logs | No | No | - | - |
+| CI Artifacts | No | No | - | - |
+| CI Cache | No | No | Yes | - |
+| LFS Objects | Yes | No | Yes (EEP) | - |
diff --git a/doc/api/README.md b/doc/api/README.md
index de0fe79b3d6..89ffe9d7868 100644
--- a/doc/api/README.md
+++ b/doc/api/README.md
@@ -37,6 +37,7 @@ following locations:
- [Notes](notes.md) (comments)
- [Notification settings](notification_settings.md)
- [Open source license templates](templates/licenses.md)
+- [Pages Domains](pages_domains.md)
- [Pipelines](pipelines.md)
- [Pipeline Triggers](pipeline_triggers.md)
- [Pipeline Schedules](pipeline_schedules.md)
@@ -458,7 +459,7 @@ Content-Type: application/json
## Encoding `+` in ISO 8601 dates
If you need to include a `+` in a query parameter, you may need to use `%2B` instead due
-a [W3 recommendation]((http://www.w3.org/Addressing/URL/4_URI_Recommentations.html) that
+a [W3 recommendation](http://www.w3.org/Addressing/URL/4_URI_Recommentations.html) that
causes a `+` to be interpreted as a space. For example, in an ISO 8601 date, you may want to pass
a time in Mountain Standard Time, such as:
diff --git a/doc/api/groups.md b/doc/api/groups.md
index c2daa8bc029..99d200c9c93 100644
--- a/doc/api/groups.md
+++ b/doc/api/groups.md
@@ -40,6 +40,38 @@ GET /groups
]
```
+When adding the parameter `statistics=true` and the authenticated user is an admin, additional group statistics are returned.
+
+```
+GET /groups?statistics=true
+```
+
+```json
+[
+ {
+ "id": 1,
+ "name": "Foobar Group",
+ "path": "foo-bar",
+ "description": "An interesting group",
+ "visibility": "public",
+ "lfs_enabled": true,
+ "avatar_url": "http://localhost:3000/uploads/group/avatar/1/foo.jpg",
+ "web_url": "http://localhost:3000/groups/foo-bar",
+ "request_access_enabled": false,
+ "full_name": "Foobar Group",
+ "full_path": "foo-bar",
+ "parent_id": null,
+ "statistics": {
+ "storage_size" : 212,
+ "repository_size" : 33,
+ "lfs_objects_size" : 123,
+ "job_artifacts_size" : 57
+
+ }
+ }
+]
+```
+
You can search for groups by name or path, see below.
## List a group's projects
diff --git a/doc/api/pages_domains.md b/doc/api/pages_domains.md
new file mode 100644
index 00000000000..51962595e33
--- /dev/null
+++ b/doc/api/pages_domains.md
@@ -0,0 +1,170 @@
+# Pages domains API
+
+Endpoints for connecting custom domain(s) and TLS certificates in [GitLab Pages](https://about.gitlab.com/features/pages/).
+
+The GitLab Pages feature must be enabled to use these endpoints. Find out more about [administering](../administration/pages/index.md) and [using](../user/project/pages/index.md) the feature.
+
+## List pages domains
+
+Get a list of project pages domains. The user must have permissions to view pages domains.
+
+```http
+GET /projects/:id/pages/domains
+```
+
+| Attribute | Type | Required | Description |
+| --------- | -------------- | -------- | ---------------------------------------- |
+| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
+
+```bash
+curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/5/pages/domains
+```
+
+```json
+[
+ {
+ "domain": "www.domain.example",
+ "url": "http://www.domain.example"
+ },
+ {
+ "domain": "ssl.domain.example",
+ "url": "https://ssl.domain.example",
+ "certificate": {
+ "subject": "/O=Example, Inc./OU=Example Origin CA/CN=Example Origin Certificate",
+ "expired": false,
+ "certificate": "-----BEGIN CERTIFICATE-----\n … \n-----END CERTIFICATE-----",
+ "certificate_text": "Certificate:\n … \n"
+ }
+ }
+]
+```
+
+## Single pages domain
+
+Get a single project pages domain. The user must have permissions to view pages domains.
+
+```http
+GET /projects/:id/pages/domains/:domain
+```
+
+| Attribute | Type | Required | Description |
+| --------- | -------------- | -------- | ---------------------------------------- |
+| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
+| `domain` | string | yes | The domain |
+
+```bash
+curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/5/pages/domains/www.domain.example
+```
+
+```json
+{
+ "domain": "www.domain.example",
+ "url": "http://www.domain.example"
+}
+```
+
+```bash
+curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/5/pages/domains/ssl.domain.example
+```
+
+```json
+{
+ "domain": "ssl.domain.example",
+ "url": "https://ssl.domain.example",
+ "certificate": {
+ "subject": "/O=Example, Inc./OU=Example Origin CA/CN=Example Origin Certificate",
+ "expired": false,
+ "certificate": "-----BEGIN CERTIFICATE-----\n … \n-----END CERTIFICATE-----",
+ "certificate_text": "Certificate:\n … \n"
+ }
+}
+```
+
+## Create new pages domain
+
+Creates a new pages domain. The user must have permissions to create new pages domains.
+
+```http
+POST /projects/:id/pages/domains
+```
+
+| Attribute | Type | Required | Description |
+| ------------- | -------------- | -------- | ---------------------------------------- |
+| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
+| `domain` | string | yes | The domain |
+| `certificate` | file/string | no | The certificate in PEM format with intermediates following in most specific to least specific order.|
+| `key` | file/string | no | The certificate key in PEM format. |
+
+```bash
+curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" --form="domain=ssl.domain.example" --form="certificate=@/path/to/cert.pem" --form="key=@/path/to/key.pem" https://gitlab.example.com/api/v4/projects/5/pages/domains
+```
+
+```bash
+curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" --form="domain=ssl.domain.example" --form="certificate=$CERT_PEM" --form="key=$KEY_PEM" https://gitlab.example.com/api/v4/projects/5/pages/domains
+```
+
+```json
+{
+ "domain": "ssl.domain.example",
+ "url": "https://ssl.domain.example",
+ "certificate": {
+ "subject": "/O=Example, Inc./OU=Example Origin CA/CN=Example Origin Certificate",
+ "expired": false,
+ "certificate": "-----BEGIN CERTIFICATE-----\n … \n-----END CERTIFICATE-----",
+ "certificate_text": "Certificate:\n … \n"
+ }
+}
+```
+
+## Update pages domain
+
+Updates an existing project pages domain. The user must have permissions to change an existing pages domains.
+
+```http
+PUT /projects/:id/pages/domains/:domain
+```
+
+| Attribute | Type | Required | Description |
+| ------------- | -------------- | -------- | ---------------------------------------- |
+| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
+| `domain` | string | yes | The domain |
+| `certificate` | file/string | no | The certificate in PEM format with intermediates following in most specific to least specific order.|
+| `key` | file/string | no | The certificate key in PEM format. |
+
+```bash
+curl --request PUT --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" --form="certificate=@/path/to/cert.pem" --form="key=@/path/to/key.pem" https://gitlab.example.com/api/v4/projects/5/pages/domains/ssl.domain.example
+```
+
+```bash
+curl --request PUT --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" --form="certificate=$CERT_PEM" --form="key=$KEY_PEM" https://gitlab.example.com/api/v4/projects/5/pages/domains/ssl.domain.example
+```
+
+```json
+{
+ "domain": "ssl.domain.example",
+ "url": "https://ssl.domain.example",
+ "certificate": {
+ "subject": "/O=Example, Inc./OU=Example Origin CA/CN=Example Origin Certificate",
+ "expired": false,
+ "certificate": "-----BEGIN CERTIFICATE-----\n … \n-----END CERTIFICATE-----",
+ "certificate_text": "Certificate:\n … \n"
+ }
+}
+```
+
+## Delete pages domain
+
+Deletes an existing project pages domain.
+
+```http
+DELETE /projects/:id/pages/domains/:domain
+```
+
+| Attribute | Type | Required | Description |
+| --------- | -------------- | -------- | ---------------------------------------- |
+| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
+| `domain` | string | yes | The domain |
+
+```bash
+curl --request DELETE --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/5/pages/domains/ssl.domain.example
+```
diff --git a/doc/api/pipelines.md b/doc/api/pipelines.md
index 890945cfc7e..a6631cab8c3 100644
--- a/doc/api/pipelines.md
+++ b/doc/api/pipelines.md
@@ -57,7 +57,7 @@ GET /projects/:id/pipelines/:pipeline_id
| `pipeline_id` | integer | yes | The ID of a pipeline |
```
-curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v4/projects/1/pipeline/46"
+curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v4/projects/1/pipelines/46"
```
Example of response
diff --git a/doc/api/services.md b/doc/api/services.md
index 49b87a4228c..e642ec964de 100644
--- a/doc/api/services.md
+++ b/doc/api/services.md
@@ -478,8 +478,8 @@ PUT /projects/:id/services/jira
| --------- | ---- | -------- | ----------- |
| `url` | string | yes | The URL to the JIRA project which is being linked to this GitLab project, e.g., `https://jira.example.com`. |
| `project_key` | string | yes | The short identifier for your JIRA project, all uppercase, e.g., `PROJ`. |
-| `username` | string | no | The username of the user created to be used with GitLab/JIRA. |
-| `password` | string | no | The password of the user created to be used with GitLab/JIRA. |
+| `username` | string | yes | The username of the user created to be used with GitLab/JIRA. |
+| `password` | string | yes | The password of the user created to be used with GitLab/JIRA. |
| `jira_issue_transition_id` | integer | no | The ID of a transition that moves issues to a closed state. You can find this number under the JIRA workflow administration (**Administration > Issues > Workflows**) by selecting **View** under **Operations** of the desired workflow of your project. The ID of each state can be found inside the parenthesis of each transition name under the **Transitions (id)** column ([see screenshot][trans]). By default, this ID is set to `2`. |
### Delete JIRA service
@@ -582,6 +582,40 @@ Delete Mattermost slash command service for a project.
DELETE /projects/:id/services/mattermost-slash-commands
```
+## Packagist
+
+Update your project on Packagist, the main Composer repository, when commits or tags are pushed to GitLab.
+
+### Create/Edit Packagist service
+
+Set Packagist service for a project.
+
+```
+PUT /projects/:id/services/packagist
+```
+
+Parameters:
+
+- `username` (**required**)
+- `token` (**required**)
+- `server` (optional)
+
+### Delete Packagist service
+
+Delete Packagist service for a project.
+
+```
+DELETE /projects/:id/services/packagist
+```
+
+### Get Packagist service settings
+
+Get Packagist service settings for a project.
+
+```
+GET /projects/:id/services/packagist
+```
+
## Pipeline-Emails
Get emails for GitLab CI pipelines.
diff --git a/doc/api/settings.md b/doc/api/settings.md
index 664f3ef7b77..4e24e4bbfc3 100644
--- a/doc/api/settings.md
+++ b/doc/api/settings.md
@@ -69,6 +69,8 @@ PUT /application/settings
| `after_sign_up_text` | string | no | Text shown to the user after signing up |
| `akismet_api_key` | string | no | API key for akismet spam protection |
| `akismet_enabled` | boolean | no | Enable or disable akismet spam protection |
+| `circuitbreaker_access_retries | integer | no | The number of attempts GitLab will make to access a storage. |
+| `circuitbreaker_backoff_threshold | integer | no | The number of failures after which GitLab will start temporarily disabling access to a storage shard on a host. |
| `circuitbreaker_failure_count_threshold` | integer | no | The number of failures of after which GitLab will completely prevent access to the storage. |
| `circuitbreaker_failure_reset_time` | integer | no | Time in seconds GitLab will keep storage failure information. When no failures occur during this time, the failure information is reset. |
| `circuitbreaker_failure_wait_time` | integer | no | Time in seconds GitLab will block access to a failing storage to allow it to recover. |
diff --git a/doc/ci/docker/using_docker_images.md b/doc/ci/docker/using_docker_images.md
index fa823ea4721..f7493794b6a 100644
--- a/doc/ci/docker/using_docker_images.md
+++ b/doc/ci/docker/using_docker_images.md
@@ -327,10 +327,6 @@ means, that when starting the container without additional options, it will run
the database's process, while Runner expects that the image will have no
entrypoint or at least will start with a shell as its entrypoint.
-Previously we would need to create our own image based on the
-`super/sql:experimental` image, set the entrypoint to a shell, and then use
-it in job's configuration, e.g.:
-
Before the new extended Docker configuration options, you would need to create
your own image based on the `super/sql:experimental` image, set the entrypoint
to a shell and then use it in job's configuration, like:
diff --git a/doc/ci/variables/README.md b/doc/ci/variables/README.md
index 17839cbaef1..73568757aaa 100644
--- a/doc/ci/variables/README.md
+++ b/doc/ci/variables/README.md
@@ -43,6 +43,7 @@ future GitLab releases.**
| **CI_COMMIT_TAG** | 9.0 | 0.5 | The commit tag name. Present only when building tags. |
| **CI_CONFIG_PATH** | 9.4 | 0.5 | The path to CI config file. Defaults to `.gitlab-ci.yml` |
| **CI_DEBUG_TRACE** | all | 1.7 | Whether [debug tracing](#debug-tracing) is enabled |
+| **CI_DISPOSABLE_ENVIRONMENT** | all | 10.1 | Mark that job is executed in a disposable environment (something that is created only for this job and disposed of/destroyed after the execution - all executors except `shell` and `ssh`). If the environment is disposable, it is set to true, otherwise it is not defined at all. |
| **CI_ENVIRONMENT_NAME** | 8.15 | all | The name of the environment for this job |
| **CI_ENVIRONMENT_SLUG** | 8.15 | all | A simplified version of the environment name, suitable for inclusion in DNS, URLs, Kubernetes labels, etc. |
| **CI_ENVIRONMENT_URL** | 9.3 | all | The URL of the environment for this job |
@@ -73,6 +74,7 @@ future GitLab releases.**
| **CI_SERVER_NAME** | all | all | The name of CI server that is used to coordinate jobs |
| **CI_SERVER_REVISION** | all | all | GitLab revision that is used to schedule jobs |
| **CI_SERVER_VERSION** | all | all | GitLab version that is used to schedule jobs |
+| **CI_SHARED_ENVIRONMENT** | all | 10.1 | Mark that job is executed in a shared environment (something that is persisted across CI invocations like `shell` or `ssh` executor). If the environment is shared, it is set to true, otherwise it is not defined at all. |
| **ARTIFACT_DOWNLOAD_ATTEMPTS** | 8.15 | 1.9 | Number of attempts to download artifacts running a job |
| **GET_SOURCES_ATTEMPTS** | 8.15 | 1.9 | Number of attempts to fetch sources running a job |
| **GITLAB_CI** | all | all | Mark that job is executed in GitLab CI environment |
diff --git a/doc/development/ee_features.md b/doc/development/ee_features.md
new file mode 100644
index 00000000000..932a44f65e4
--- /dev/null
+++ b/doc/development/ee_features.md
@@ -0,0 +1,382 @@
+# Guidelines for implementing Enterprise Edition feature
+
+- **Write the code and the tests.**: As with any code, EE features should have
+ good test coverage to prevent regressions.
+- **Write documentation.**: Add documentation to the `doc/` directory. Describe
+ the feature and include screenshots, if applicable.
+- **Submit a MR to the `www-gitlab-com` project.**: Add the new feature to the
+ [EE features list][ee-features-list].
+
+## Act as CE when unlicensed
+
+Since the implementation of [GitLab CE features to work with unlicensed EE instance][ee-as-ce]
+GitLab Enterprise Edition should work like GitLab Community Edition
+when no license is active. So EE features always should be guarded by
+`project.feature_available?` or `group.feature_available?` (or
+`License.feature_available?` if it is a system-wide feature).
+
+CE specs should remain untouched as much as possible and extra specs
+should be added for EE. Licensed features can be stubbed using the
+spec helper `stub_licensed_features` in `EE::LicenseHelpers`.
+
+[ee-as-ce]: https://gitlab.com/gitlab-org/gitlab-ee/issues/2500
+
+## Separation of EE code
+
+We want a [single code base][] eventually, but before we reach the goal,
+we still need to merge changes from GitLab CE to EE. To help us get there,
+we should make sure that we no longer edit CE files in place in order to
+implement EE features.
+
+Instead, all EE codes should be put inside the `ee/` top-level directory, and
+tests should be put inside `spec/ee/`. We don't use `ee/spec` for now due to
+technical limitation. The rest of codes should be as close as to the CE files.
+
+[single code base]: https://gitlab.com/gitlab-org/gitlab-ee/issues/2952#note_41016454
+
+### EE-only features
+
+If the feature being developed is not present in any form in CE, we don't
+need to put the codes under `EE` namespace. For example, an EE model could
+go into: `ee/app/models/awesome.rb` using `Awesome` as the class name. This
+is applied not only to models. Here's a list of other examples:
+
+- `ee/app/controllers/foos_controller.rb`
+- `ee/app/finders/foos_finder.rb`
+- `ee/app/helpers/foos_helper.rb`
+- `ee/app/mailers/foos_mailer.rb`
+- `ee/app/models/foo.rb`
+- `ee/app/policies/foo_policy.rb`
+- `ee/app/serializers/foo_entity.rb`
+- `ee/app/serializers/foo_serializer.rb`
+- `ee/app/services/foo/create_service.rb`
+- `ee/app/validators/foo_attr_validator.rb`
+- `ee/app/workers/foo_worker.rb`
+
+### EE features based on CE features
+
+For features that build on existing CE features, write a module in the
+`EE` namespace and `prepend` it in the CE class. This makes conflicts
+less likely to happen during CE to EE merges because only one line is
+added to the CE class - the `prepend` line.
+
+Since the module would require an `EE` namespace, the file should also be
+put in an `ee/` sub-directory. For example, we want to extend the user model
+in EE, so we have a module called `::EE::User` put inside
+`ee/app/models/ee/user.rb`.
+
+This is also not just applied to models. Here's a list of other examples:
+
+- `ee/app/controllers/ee/foos_controller.rb`
+- `ee/app/finders/ee/foos_finder.rb`
+- `ee/app/helpers/ee/foos_helper.rb`
+- `ee/app/mailers/ee/foos_mailer.rb`
+- `ee/app/models/ee/foo.rb`
+- `ee/app/policies/ee/foo_policy.rb`
+- `ee/app/serializers/ee/foo_entity.rb`
+- `ee/app/serializers/ee/foo_serializer.rb`
+- `ee/app/services/ee/foo/create_service.rb`
+- `ee/app/validators/ee/foo_attr_validator.rb`
+- `ee/app/workers/ee/foo_worker.rb`
+
+#### Overriding CE methods
+
+To override a method present in the CE codebase, use `prepend`. It
+lets you override a method in a class with a method from a module, while
+still having access the class's implementation with `super`.
+
+There are a few gotchas with it:
+
+- you should always add a `raise NotImplementedError unless defined?(super)`
+ guard clause in the "overrider" method to ensure that if the method gets
+ renamed in CE, the EE override won't be silently forgotten.
+- when the "overrider" would add a line in the middle of the CE
+ implementation, you should refactor the CE method and split it in
+ smaller methods. Or create a "hook" method that is empty in CE,
+ and with the EE-specific implementation in EE.
+- when the original implementation contains a guard clause (e.g.
+ `return unless condition`), we cannot easily extend the behaviour by
+ overriding the method, because we can't know when the overridden method
+ (i.e. calling `super` in the overriding method) would want to stop early.
+ In this case, we shouldn't just override it, but update the original method
+ to make it call the other method we want to extend, like a [template method
+ pattern](https://en.wikipedia.org/wiki/Template_method_pattern).
+ For example, given this base:
+ ``` ruby
+ class Base
+ def execute
+ return unless enabled?
+
+ # ...
+ # ...
+ end
+ end
+ ```
+ Instead of just overriding `Base#execute`, we should update it and extract
+ the behaviour into another method:
+ ``` ruby
+ class Base
+ def execute
+ return unless enabled?
+
+ do_something
+ end
+
+ private
+
+ def do_something
+ # ...
+ # ...
+ end
+ end
+ ```
+ Then we're free to override that `do_something` without worrying about the
+ guards:
+ ``` ruby
+ module EE::Base
+ def do_something
+ # Follow the above pattern to call super and extend it
+ end
+ end
+ ```
+ This would require updating CE first, or make sure this is back ported to CE.
+
+When prepending, place them in the `ee/` specific sub-directory, and
+wrap class or module in `module EE` to avoid naming conflicts.
+
+For example to override the CE implementation of
+`ApplicationController#after_sign_out_path_for`:
+
+```ruby
+def after_sign_out_path_for(resource)
+ current_application_settings.after_sign_out_path.presence || new_user_session_path
+end
+```
+
+Instead of modifying the method in place, you should add `prepend` to
+the existing file:
+
+```ruby
+class ApplicationController < ActionController::Base
+ prepend EE::ApplicationController
+ # ...
+
+ def after_sign_out_path_for(resource)
+ current_application_settings.after_sign_out_path.presence || new_user_session_path
+ end
+
+ # ...
+end
+```
+
+And create a new file in the `ee/` sub-directory with the altered
+implementation:
+
+```ruby
+module EE
+ class ApplicationController
+ def after_sign_out_path_for(resource)
+ raise NotImplementedError unless defined?(super)
+
+ if Gitlab::Geo.secondary?
+ Gitlab::Geo.primary_node.oauth_logout_url(@geo_logout_state)
+ else
+ super
+ end
+ end
+ end
+end
+```
+
+#### Use self-descriptive wrapper methods
+
+When it's not possible/logical to modify the implementation of a
+method. Wrap it in a self-descriptive method and use that method.
+
+For example, in CE only an `admin` is allowed to access all private
+projects/groups, but in EE also an `auditor` has full private
+access. It would be incorrect to override the implementation of
+`User#admin?`, so instead add a method `full_private_access?` to
+`app/models/users.rb`. The implementation in CE will be:
+
+```ruby
+def full_private_access?
+ admin?
+end
+```
+
+In EE, the implementation `ee/app/models/ee/users.rb` would be:
+
+```ruby
+def full_private_access?
+ raise NotImplementedError unless defined?(super)
+ super || auditor?
+end
+```
+
+In `lib/gitlab/visibility_level.rb` this method is used to return the
+allowed visibilty levels:
+
+```ruby
+def levels_for_user(user = nil)
+ if user.full_private_access?
+ [PRIVATE, INTERNAL, PUBLIC]
+ elsif # ...
+end
+```
+
+See [CE MR][ce-mr-full-private] and [EE MR][ee-mr-full-private] for
+full implementation details.
+
+[ce-mr-full-private]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/12373
+[ee-mr-full-private]: https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/2199
+
+### Code in `app/controllers/`
+
+In controllers, the most common type of conflict is with `before_action` that
+has a list of actions in CE but EE adds some actions to that list.
+
+The same problem often occurs for `params.require` / `params.permit` calls.
+
+**Mitigations**
+
+Separate CE and EE actions/keywords. For instance for `params.require` in
+`ProjectsController`:
+
+```ruby
+def project_params
+ params.require(:project).permit(project_params_attributes)
+end
+
+# Always returns an array of symbols, created however best fits the use case.
+# It _should_ be sorted alphabetically.
+def project_params_attributes
+ %i[
+ description
+ name
+ path
+ ]
+end
+
+```
+
+In the `EE::ProjectsController` module:
+
+```ruby
+def project_params_attributes
+ super + project_params_attributes_ee
+end
+
+def project_params_attributes_ee
+ %i[
+ approvals_before_merge
+ approver_group_ids
+ approver_ids
+ ...
+ ]
+end
+```
+
+### Code in `app/models/`
+
+EE-specific models should `extend EE::Model`.
+
+For example, if EE has a specific `Tanuki` model, you would
+place it in `ee/app/models/ee/tanuki.rb`.
+
+### Code in `app/views/`
+
+It's a very frequent problem that EE is adding some specific view code in a CE
+view. For instance the approval code in the project's settings page.
+
+**Mitigations**
+
+Blocks of code that are EE-specific should be moved to partials. This
+avoids conflicts with big chunks of HAML code that that are not fun to
+resolve when you add the indentation to the equation.
+
+EE-specific views should be placed in `ee/app/views/ee/`, using extra
+sub-directories if appropriate.
+
+### Code in `lib/`
+
+Place EE-specific logic in the top-level `EE` module namespace. Namespace the
+class beneath the `EE` module just as you would normally.
+
+For example, if CE has LDAP classes in `lib/gitlab/ldap/` then you would place
+EE-specific LDAP classes in `ee/lib/ee/gitlab/ldap`.
+
+### Code in `spec/`
+
+When you're testing EE-only features, avoid adding examples to the
+existing CE specs. Also do no change existing CE examples, since they
+should remain working as-is when EE is running without a license.
+
+Instead place EE specs in the `spec/ee/spec` folder.
+
+## JavaScript code in `assets/javascripts/`
+
+To separate EE-specific JS-files we can also move the files into an `ee` folder.
+
+For example there can be an
+`app/assets/javascripts/protected_branches/protected_branches_bundle.js` and an
+EE counterpart
+`ee/app/assets/javascripts/protected_branches/protected_branches_bundle.js`.
+
+That way we can create a separate webpack bundle in `webpack.config.js`:
+
+```javascript
+ protected_branches: '~/protected_branches',
+ ee_protected_branches: 'ee/protected_branches/protected_branches_bundle.js',
+```
+
+With the separate bundle in place, we can decide which bundle to load inside the
+view, using the `page_specific_javascript_bundle_tag` helper.
+
+```haml
+- content_for :page_specific_javascripts do
+ = page_specific_javascript_bundle_tag('protected_branches')
+```
+
+## SCSS code in `assets/stylesheets`
+
+To separate EE-specific styles in SCSS files, if a component you're adding styles for
+is limited to only EE, it is better to have a separate SCSS file in appropriate directory
+within `app/assets/stylesheets`.
+
+In some cases, this is not entirely possible or creating dedicated SCSS file is an overkill,
+e.g. a text style of some component is different for EE. In such cases,
+styles are usually kept in stylesheet that is common for both CE and EE, and it is wise
+to isolate such ruleset from rest of CE rules (along with adding comment describing the same)
+to avoid conflicts during CE to EE merge.
+
+#### Bad
+```scss
+.section-body {
+ .section-title {
+ background: $gl-header-color;
+ }
+
+ &.ee-section-body {
+ .section-title {
+ background: $gl-header-color-cyan;
+ }
+ }
+}
+```
+
+#### Good
+```scss
+.section-body {
+ .section-title {
+ background: $gl-header-color;
+ }
+}
+
+/* EE-specific styles */
+.section-body.ee-section-body {
+ .section-title {
+ background: $gl-header-color-cyan;
+ }
+}
+```
diff --git a/doc/development/fe_guide/index.md b/doc/development/fe_guide/index.md
index c0e1bfc12a1..8f956681693 100644
--- a/doc/development/fe_guide/index.md
+++ b/doc/development/fe_guide/index.md
@@ -71,6 +71,9 @@ Vue specific design patterns and practices.
---
+## [Vue Resource](vue_resource.md)
+Vue resource specific practices and gotchas.
+
## [Icons](icons.md)
How we use SVG for our Icons.
@@ -103,6 +106,10 @@ Frontend security practices.
## [Accessibility](accessibility.md)
Our accessibility standards and resources.
+## [Internationalization (i18n) and Translations](../i18n/externalization.md)
+Frontend internationalization support is described in [this document](../i18n/).
+The [externalization part of the guide](../i18n/externalization.md) explains the helpers/methods available.
+
[rails]: http://rubyonrails.org/
[haml]: http://haml.info/
diff --git a/doc/development/fe_guide/vue.md b/doc/development/fe_guide/vue.md
index 277e0cd5f00..f88f0753687 100644
--- a/doc/development/fe_guide/vue.md
+++ b/doc/development/fe_guide/vue.md
@@ -179,6 +179,7 @@ itself, please read this guide: [State Management][state-management]
The Service is a class used only to communicate with the server.
It does not store or manipulate any data. It is not aware of the store or the components.
We use [vue-resource][vue-resource-repo] to communicate with the server.
+Refer to [vue resource](vue_resource.md) for more details.
Vue Resource should only be imported in the service file.
@@ -189,55 +190,6 @@ Vue Resource should only be imported in the service file.
Vue.use(VueResource);
```
-#### Vue-resource gotchas
-#### Headers
-Headers are being parsed into a plain object in an interceptor.
-In Vue-resource 1.x `headers` object was changed into an `Headers` object. In order to not change all old code, an interceptor was added.
-
-If you need to write a unit test that takes the headers in consideration, you need to include an interceptor to parse the headers after your test interceptor.
-You can see an example in `spec/javascripts/environments/environment_spec.js`:
- ```javascript
- import { headersInterceptor } from './helpers/vue_resource_helper';
-
- beforeEach(() => {
- Vue.http.interceptors.push(myInterceptor);
- Vue.http.interceptors.push(headersInterceptor);
- });
-
- afterEach(() => {
- Vue.http.interceptors = _.without(Vue.http.interceptors, myInterceptor);
- Vue.http.interceptors = _.without(Vue.http.interceptors, headersInterceptor);
- });
- ```
-
-#### `.json()`
-When making a request to the server, you will most likely need to access the body of the response.
-Use `.json()` to convert. Because `.json()` returns a Promise the follwoing structure should be used:
-
- ```javascript
- service.get('url')
- .then(resp => resp.json())
- .then((data) => {
- this.store.storeData(data);
- })
- .catch(() => new Flash('Something went wrong'));
- ```
-
-When using `Poll` (`app/assets/javascripts/lib/utils/poll.js`), the `successCallback` needs to handle `.json()` as a Promise:
- ```javascript
- successCallback: (response) => {
- return response.json().then((data) => {
- // handle the response
- });
- }
- ```
-
-#### CSRF token
-We use a Vue Resource interceptor to manage the CSRF token.
-`app/assets/javascripts/vue_shared/vue_resource_interceptor.js` holds all our common interceptors.
-Note: You don't need to load `app/assets/javascripts/vue_shared/vue_resource_interceptor.js`
-since it's already being loaded by `common_vue.js`.
-
### End Result
The following example shows an application:
@@ -769,7 +721,6 @@ describe('component', () => {
[component-system]: https://vuejs.org/v2/guide/#Composing-with-Components
[state-management]: https://vuejs.org/v2/guide/state-management.html#Simple-State-Management-from-Scratch
[one-way-data-flow]: https://vuejs.org/v2/guide/components.html#One-Way-Data-Flow
-[vue-resource-repo]: https://github.com/pagekit/vue-resource
[vue-resource-interceptor]: https://github.com/pagekit/vue-resource/blob/develop/docs/http.md#interceptors
[vue-test]: https://vuejs.org/v2/guide/unit-testing.html
[issue-boards-service]: https://gitlab.com/gitlab-org/gitlab-ce/blob/master/app/assets/javascripts/boards/services/board_service.js.es6
diff --git a/doc/development/fe_guide/vue_resource.md b/doc/development/fe_guide/vue_resource.md
new file mode 100644
index 00000000000..c376c5c32bf
--- /dev/null
+++ b/doc/development/fe_guide/vue_resource.md
@@ -0,0 +1,72 @@
+# Vue Resouce
+In Vue applications we use [vue-resource][vue-resource-repo] to communicate with the server.
+
+## HTTP Status Codes
+
+### `.json()`
+When making a request to the server, you will most likely need to access the body of the response.
+Use `.json()` to convert. Because `.json()` returns a Promise the follwoing structure should be used:
+
+ ```javascript
+ service.get('url')
+ .then(resp => resp.json())
+ .then((data) => {
+ this.store.storeData(data);
+ })
+ .catch(() => new Flash('Something went wrong'));
+ ```
+
+
+When using `Poll` (`app/assets/javascripts/lib/utils/poll.js`), the `successCallback` needs to handle `.json()` as a Promise:
+ ```javascript
+ successCallback: (response) => {
+ return response.json().then((data) => {
+ // handle the response
+ });
+ }
+ ```
+
+### 204
+Some endpoints - usually `delete` endpoints - return `204` as the success response.
+When handling `204 - No Content` responses, we cannot use `.json()` since it tries to parse the non-existant body content.
+
+When handling `204` responses, do not use `.json`, otherwise the promise will throw an error and will enter the `catch` statement:
+
+```javascript
+ Vue.http.delete('path')
+ .then(() => {
+ // success!
+ })
+ .catch(() => {
+ // handle error
+ })
+```
+
+## Headers
+Headers are being parsed into a plain object in an interceptor.
+In Vue-resource 1.x `headers` object was changed into an `Headers` object. In order to not change all old code, an interceptor was added.
+
+If you need to write a unit test that takes the headers in consideration, you need to include an interceptor to parse the headers after your test interceptor.
+You can see an example in `spec/javascripts/environments/environment_spec.js`:
+ ```javascript
+ import { headersInterceptor } from './helpers/vue_resource_helper';
+
+ beforeEach(() => {
+ Vue.http.interceptors.push(myInterceptor);
+ Vue.http.interceptors.push(headersInterceptor);
+ });
+
+ afterEach(() => {
+ Vue.http.interceptors = _.without(Vue.http.interceptors, myInterceptor);
+ Vue.http.interceptors = _.without(Vue.http.interceptors, headersInterceptor);
+ });
+ ```
+
+## CSRF token
+We use a Vue Resource interceptor to manage the CSRF token.
+`app/assets/javascripts/vue_shared/vue_resource_interceptor.js` holds all our common interceptors.
+Note: You don't need to load `app/assets/javascripts/vue_shared/vue_resource_interceptor.js`
+since it's already being loaded by `common_vue.js`.
+
+
+[vue-resource-repo]: https://github.com/pagekit/vue-resource
diff --git a/doc/development/i18n/externalization.md b/doc/development/i18n/externalization.md
index 167260b6e0e..7c38260406d 100644
--- a/doc/development/i18n/externalization.md
+++ b/doc/development/i18n/externalization.md
@@ -180,15 +180,43 @@ aren't in the message with id `1 pipeline`.
## Working with special content
+
+### Just marking content for parsing
+
+- In Ruby/HAML:
+
+ ```ruby
+ _('Subscribe')
+ ```
+
+- In JavaScript:
+
+ ```js
+ import { __ } from '../../../locale';
+ const label = __('Subscribe');
+ ```
+
+
+Sometimes there are some dynamic translations that can't be found by the
+parser when running `bundle exec rake gettext:find`. For these scenarios you can
+use the [`_N` method](https://github.com/grosser/gettext_i18n_rails/blob/c09e38d481e0899ca7d3fc01786834fa8e7aab97/Readme.md#unfound-translations-with-rake-gettextfind).
+
+There is also and alternative method to [translate messages from validation errors](https://github.com/grosser/gettext_i18n_rails/blob/c09e38d481e0899ca7d3fc01786834fa8e7aab97/Readme.md#option-a).
+
### Interpolation
- In Ruby/HAML:
```ruby
- _("Hello %{name}") % { name: 'Joe' }
+ _("Hello %{name}") % { name: 'Joe' } => 'Hello Joe'
```
-- In JavaScript: Not supported at this moment.
+- In JavaScript:
+
+ ```js
+ import { __, sprintf } from '../../../locale';
+ sprintf(__('Hello %{username}'), { username: 'Joe' }) => 'Hello Joe'
+ ```
### Plurals
@@ -234,14 +262,6 @@ Sometimes you need to add some context to the text that you want to translate
s__('OpenedNDaysAgo|Opened')
```
-### Just marking content for parsing
-
-Sometimes there are some dynamic translations that can't be found by the
-parser when running `bundle exec rake gettext:find`. For these scenarios you can
-use the [`_N` method](https://github.com/grosser/gettext_i18n_rails/blob/c09e38d481e0899ca7d3fc01786834fa8e7aab97/Readme.md#unfound-translations-with-rake-gettextfind).
-
-There is also and alternative method to [translate messages from validation errors](https://github.com/grosser/gettext_i18n_rails/blob/c09e38d481e0899ca7d3fc01786834fa8e7aab97/Readme.md#option-a).
-
## Adding a new language
Let's suppose you want to add translations for a new language, let's say French.
diff --git a/doc/gitlab-basics/add-merge-request.md b/doc/gitlab-basics/add-merge-request.md
index bf01fe51dc3..5cc014419ad 100644
--- a/doc/gitlab-basics/add-merge-request.md
+++ b/doc/gitlab-basics/add-merge-request.md
@@ -3,31 +3,28 @@
Merge requests are useful to integrate separate changes that you've made to a
project, on different branches. This is a brief guide on how to create a merge
request. For more information, check the
-[merge requests documentation](../user/project/merge_requests.md).
+[merge requests documentation](../user/project/merge_requests/index.md).
---
1. Before you start, you should have already [created a branch](create-branch.md)
and [pushed your changes](basic-git-commands.md) to GitLab.
-
-1. You can then go to the project where you'd like to merge your changes and
- click on the **Merge requests** tab.
-
- ![Merge requests](img/project_navbar.png)
-
+1. Go to the project where you'd like to merge your changes and click on the
+ **Merge requests** tab.
1. Click on **New merge request** on the right side of the screen.
-
- ![New Merge Request](img/merge_request_new.png)
-
-1. Select a source branch and click on the **Compare branches and continue** button.
+1. From there on, you have the option to select the source branch and the target
+ branch you'd like to compare to. The default target project is the upstream
+ repository, but you can choose to compare across any of its forks.
![Select a branch](img/merge_request_select_branch.png)
+1. When ready, click on the **Compare branches and continue** button.
1. At a minimum, add a title and a description to your merge request. Optionally,
select a user to review your merge request and to accept or close it. You may
also select a milestone and labels.
![New merge request page](img/merge_request_page.png)
-1. When ready, click on the **Submit merge request** button. Your merge request
- will be ready to be approved and published.
+1. When ready, click on the **Submit merge request** button.
+
+Your merge request will be ready to be approved and merged.
diff --git a/doc/gitlab-basics/img/merge_request_new.png b/doc/gitlab-basics/img/merge_request_new.png
deleted file mode 100644
index 6fcd7bebada..00000000000
--- a/doc/gitlab-basics/img/merge_request_new.png
+++ /dev/null
Binary files differ
diff --git a/doc/gitlab-basics/img/merge_request_select_branch.png b/doc/gitlab-basics/img/merge_request_select_branch.png
index 9f6b93943a9..57ea0e65f34 100644
--- a/doc/gitlab-basics/img/merge_request_select_branch.png
+++ b/doc/gitlab-basics/img/merge_request_select_branch.png
Binary files differ
diff --git a/doc/gitlab-basics/img/project_navbar.png b/doc/gitlab-basics/img/project_navbar.png
deleted file mode 100644
index be6f38ede32..00000000000
--- a/doc/gitlab-basics/img/project_navbar.png
+++ /dev/null
Binary files differ
diff --git a/doc/integration/saml.md b/doc/integration/saml.md
index b5b245c626f..3ae98adc465 100644
--- a/doc/integration/saml.md
+++ b/doc/integration/saml.md
@@ -132,14 +132,17 @@ On the sign in page there should now be a SAML button below the regular sign in
Click the icon to begin the authentication process. If everything goes well the user
will be returned to GitLab and will be signed in.
-## External Groups
+## Marking Users as External based on SAML Groups
>**Note:**
This setting is only available on GitLab 8.7 and above.
-SAML login includes support for external groups. You can define in the SAML
-settings which groups, to which your users belong in your IdP, you wish to be
-marked as [external](../user/permissions.md).
+SAML login includes support for automatically identifying whether a user should
+be considered an [external](../user/permissions.md) user based on the user's group
+membership in the SAML identity provider. This feature **does not** allow you to
+automatically add users to GitLab [Groups](../user/group/index.md), it simply
+allows you to mark users as External if they are members of certain groups in the
+Identity Provider.
### Requirements
diff --git a/doc/integration/trello_power_up.md b/doc/integration/trello_power_up.md
index d264486a872..834d63d1166 100644
--- a/doc/integration/trello_power_up.md
+++ b/doc/integration/trello_power_up.md
@@ -39,4 +39,4 @@ Learn more about generating a personal access token in the
[Personal Access Token Documentation][personal-access-token-documentation].
Don't forget to check the API scope checkbox!
-[personal-access-token-documentation]: ../user/profile/personal_access_tokens.html
+[personal-access-token-documentation]: ../user/profile/personal_access_tokens.md
diff --git a/doc/policy/maintenance.md b/doc/policy/maintenance.md
index 7ab56c89014..8d0afa9e692 100644
--- a/doc/policy/maintenance.md
+++ b/doc/policy/maintenance.md
@@ -19,24 +19,30 @@ For example, for GitLab version 10.5.7:
* `5` represents minor version
* `7` represents patch number
-## Security releases
+## Patch releases
-The current stable release will receive security patches and bug fixes
-(eg. `8.9.0` -> `8.9.1`).
+Patch releases usually only include bug fixes and are only done for the current
+stable release. That said, in some cases, we may backport it to previous stable
+release, depending on the severity of the bug.
-Feature releases will mark the next supported stable
-release where the minor version is increased numerically by increments of one
-(eg. `8.9 -> 8.10`).
+For instance, if we release `10.1.1` with a fix for a severe bug introduced in
+`10.0.0`, we could backport the fix to a new `10.0.x` patch release.
-Our current policy is to support one stable release at any given time.
-For medium-level security issues, we may consider backporting to the previous two
+### Security releases
+
+Security releases are a special kind of patch release that only include security
+fixes and patches (see below).
+
+Our current policy is to support one stable release at any given time, but for
+medium-level security issues, we may backport security fixes to the previous two
monthly releases.
-For very serious security issues, there is [precedent](https://about.gitlab.com/2016/05/02/cve-2016-4340-patches/)
-to backport security fixes to even more monthly releases of GitLab. This decision
-is made on a case-by-case basis.
+For very serious security issues, there is
+[precedent](https://about.gitlab.com/2016/05/02/cve-2016-4340-patches/)
+to backport security fixes to even more monthly releases of GitLab.
+This decision is made on a case-by-case basis.
-## Version support
+## Upgrade recommendations
We encourage everyone to run the latest stable release to ensure that you can
easily upgrade to the most secure and feature-rich GitLab experience. In order
@@ -70,7 +76,6 @@ Please see the table below for some examples:
| -------------- | ------------ | ------------------------ | ---------------- |
| 9.4.5 | 8.13.4 | `8.13.4` -> `8.17.7` -> `9.4.5` | `8.17.7` is the last version in version `8` |
| 10.1.4 | 8.13.4 | `8.13.4` -> `8.17.7` -> `9.5.8` -> `10.1.4` | `8.17.7` is the last version in version `8`, `9.5.8` is the last version in version `9` |
-|
More information about the release procedures can be found in our
[release-tools documentation][rel]. You may also want to read our
diff --git a/doc/raketasks/backup_restore.md b/doc/raketasks/backup_restore.md
index e4c09b2b507..54c3e20d61d 100644
--- a/doc/raketasks/backup_restore.md
+++ b/doc/raketasks/backup_restore.md
@@ -136,44 +136,54 @@ In the example below we use Amazon S3 for storage, but Fog also lets you use
for AWS, Google, OpenStack Swift, Rackspace and Aliyun as well. A local driver is
[also available](#uploading-to-locally-mounted-shares).
-For omnibus packages, add the following to `/etc/gitlab/gitlab.rb`:
+#### Using Amazon S3
-```ruby
-gitlab_rails['backup_upload_connection'] = {
- 'provider' => 'AWS',
- 'region' => 'eu-west-1',
- 'aws_access_key_id' => 'AKIAKIAKI',
- 'aws_secret_access_key' => 'secret123'
- # If using an IAM Profile, don't configure aws_access_key_id & aws_secret_access_key
- # 'use_iam_profile' => true
-}
-gitlab_rails['backup_upload_remote_directory'] = 'my.s3.bucket'
-```
+For Omnibus GitLab packages:
+
+1. Add the following to `/etc/gitlab/gitlab.rb`:
+
+ ```ruby
+ gitlab_rails['backup_upload_connection'] = {
+ 'provider' => 'AWS',
+ 'region' => 'eu-west-1',
+ 'aws_access_key_id' => 'AKIAKIAKI',
+ 'aws_secret_access_key' => 'secret123'
+ # If using an IAM Profile, don't configure aws_access_key_id & aws_secret_access_key
+ # 'use_iam_profile' => true
+ }
+ gitlab_rails['backup_upload_remote_directory'] = 'my.s3.bucket'
+ ```
+
+1. [Reconfigure GitLab] for the changes to take effect
-Make sure to run `sudo gitlab-ctl reconfigure` after editing `/etc/gitlab/gitlab.rb` to reflect the changes.
+---
For installations from source:
-```yaml
- backup:
- # snip
- upload:
- # Fog storage connection settings, see http://fog.io/storage/ .
- connection:
- provider: AWS
- region: eu-west-1
- aws_access_key_id: AKIAKIAKI
- aws_secret_access_key: 'secret123'
- # If using an IAM Profile, leave aws_access_key_id & aws_secret_access_key empty
- # ie. aws_access_key_id: ''
- # use_iam_profile: 'true'
- # The remote 'directory' to store your backups. For S3, this would be the bucket name.
- remote_directory: 'my.s3.bucket'
- # Turns on AWS Server-Side Encryption with Amazon S3-Managed Keys for backups, this is optional
- # encryption: 'AES256'
- # Specifies Amazon S3 storage class to use for backups, this is optional
- # storage_class: 'STANDARD'
-```
+1. Edit `home/git/gitlab/config/gitlab.yml`:
+
+ ```yaml
+ backup:
+ # snip
+ upload:
+ # Fog storage connection settings, see http://fog.io/storage/ .
+ connection:
+ provider: AWS
+ region: eu-west-1
+ aws_access_key_id: AKIAKIAKI
+ aws_secret_access_key: 'secret123'
+ # If using an IAM Profile, leave aws_access_key_id & aws_secret_access_key empty
+ # ie. aws_access_key_id: ''
+ # use_iam_profile: 'true'
+ # The remote 'directory' to store your backups. For S3, this would be the bucket name.
+ remote_directory: 'my.s3.bucket'
+ # Turns on AWS Server-Side Encryption with Amazon S3-Managed Keys for backups, this is optional
+ # encryption: 'AES256'
+ # Specifies Amazon S3 storage class to use for backups, this is optional
+ # storage_class: 'STANDARD'
+ ```
+
+1. [Restart GitLab] for the changes to take effect
If you are uploading your backups to S3 you will probably want to create a new
IAM user with restricted access rights. To give the upload user access only for
@@ -226,6 +236,50 @@ with the name of your bucket:
}
```
+#### Using Google Cloud Storage
+
+If you want to use Google Cloud Storage to save backups, you'll have to create
+an access key from the Google console first:
+
+1. Go to the storage settings page https://console.cloud.google.com/storage/settings
+1. Select "Interoperability" and create an access key
+1. Make note of the "Access Key" and "Secret" and replace them in the
+ configurations below
+1. Make sure you already have a bucket created
+
+For Omnibus GitLab packages:
+
+1. Edit `/etc/gitlab/gitlab.rb`:
+
+ ```ruby
+ gitlab_rails['backup_upload_connection'] = {
+ 'provider' => 'Google',
+ 'google_storage_access_key_id' => 'Access Key',
+ 'google_storage_secret_access_key' => 'Secret'
+ }
+ gitlab_rails['backup_upload_remote_directory'] = 'my.google.bucket'
+ ```
+
+1. [Reconfigure GitLab] for the changes to take effect
+
+---
+
+For installations from source:
+
+1. Edit `home/git/gitlab/config/gitlab.yml`:
+
+ ```yaml
+ backup:
+ upload:
+ connection:
+ provider: 'Google'
+ google_storage_access_key_id: 'Access Key'
+ google_storage_secret_access_key: 'Secret'
+ remote_directory: 'my.google.bucket'
+ ```
+
+1. [Restart GitLab] for the changes to take effect
+
### Uploading to locally mounted shares
You may also send backups to a mounted share (`NFS` / `CIFS` / `SMB` / etc.) by
@@ -554,3 +608,6 @@ The rake task runs this as the `gitlab` user which does not have the superuser a
Those objects have no influence on the database backup/restore but they give this annoying warning.
For more information see similar questions on postgresql issue tracker[here](http://www.postgresql.org/message-id/201110220712.30886.adrian.klaver@gmail.com) and [here](http://www.postgresql.org/message-id/2039.1177339749@sss.pgh.pa.us) as well as [stack overflow](http://stackoverflow.com/questions/4368789/error-must-be-owner-of-language-plpgsql).
+
+[reconfigure GitLab]: ../administration/restart_gitlab.md#omnibus-gitlab-reconfigure
+[restart GitLab]: ../administration/restart_gitlab.md#installations-from-source
diff --git a/doc/user/project/import/index.md b/doc/user/project/import/index.md
index 8da6e2a8207..e2b285678c3 100644
--- a/doc/user/project/import/index.md
+++ b/doc/user/project/import/index.md
@@ -4,7 +4,7 @@
1. [From ClearCase](clearcase.md)
1. [From CVS](cvs.md)
1. [From FogBugz](fogbugz.md)
-1. [From GitHub.com of GitHub Enterprise](github.md)
+1. [From GitHub.com or GitHub Enterprise](github.md)
1. [From GitLab.com](gitlab_com.md)
1. [From Gitea](gitea.md)
1. [From Perforce](perforce.md)
diff --git a/doc/user/project/integrations/project_services.md b/doc/user/project/integrations/project_services.md
index 51989ccaaea..a0405161495 100644
--- a/doc/user/project/integrations/project_services.md
+++ b/doc/user/project/integrations/project_services.md
@@ -43,6 +43,7 @@ Click on the service links to see further configuration instructions and details
| [Mattermost slash commands](mattermost_slash_commands.md) | Mattermost chat and ChatOps slash commands |
| [Mattermost Notifications](mattermost.md) | Receive event notifications in Mattermost |
| [Microsoft teams](microsoft_teams.md) | Receive notifications for actions that happen on GitLab into a room on Microsoft Teams using Office 365 Connectors |
+| Packagist | Update your project on Packagist, the main Composer repository |
| Pipelines emails | Email the pipeline status to a list of recipients |
| [Slack Notifications](slack.md) | Send GitLab events (e.g. issue created) to Slack as notifications |
| [Slack slash commands](slack_slash_commands.md) | Use slash commands in Slack to control GitLab |
diff --git a/doc/user/project/integrations/webhooks.md b/doc/user/project/integrations/webhooks.md
index 7abc600a680..df75e25e12b 100644
--- a/doc/user/project/integrations/webhooks.md
+++ b/doc/user/project/integrations/webhooks.md
@@ -76,6 +76,7 @@ X-Gitlab-Event: Push Hook
"user_avatar": "https://s.gravatar.com/avatar/d4c74594d841139328695756648b6bd6?s=8://s.gravatar.com/avatar/d4c74594d841139328695756648b6bd6?s=80",
"project_id": 15,
"project":{
+ "id": 15,
"name":"Diaspora",
"description":"",
"web_url":"http://example.com/mike/diaspora",
@@ -156,6 +157,7 @@ X-Gitlab-Event: Tag Push Hook
"user_avatar": "https://s.gravatar.com/avatar/d4c74594d841139328695756648b6bd6?s=8://s.gravatar.com/avatar/d4c74594d841139328695756648b6bd6?s=80",
"project_id": 1,
"project":{
+ "id": 1,
"name":"Example",
"description":"",
"web_url":"http://example.com/jsmith/example",
@@ -206,6 +208,7 @@ X-Gitlab-Event: Issue Hook
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon"
},
"project": {
+ "id": 1,
"name":"Gitlab Test",
"description":"Aut reprehenderit ut est.",
"web_url":"http://example.com/gitlabhq/gitlab-test",
@@ -335,6 +338,7 @@ X-Gitlab-Event: Note Hook
},
"project_id": 5,
"project":{
+ "id": 5,
"name":"Gitlab Test",
"description":"Aut reprehenderit ut est.",
"web_url":"http://example.com/gitlabhq/gitlab-test",
@@ -414,6 +418,7 @@ X-Gitlab-Event: Note Hook
},
"project_id": 5,
"project":{
+ "id": 5,
"name":"Gitlab Test",
"description":"Aut reprehenderit ut est.",
"web_url":"http://example.com/gitlab-org/gitlab-test",
@@ -540,6 +545,7 @@ X-Gitlab-Event: Note Hook
},
"project_id": 5,
"project":{
+ "id": 5,
"name":"Gitlab Test",
"description":"Aut reprehenderit ut est.",
"web_url":"http://example.com/gitlab-org/gitlab-test",
@@ -618,6 +624,7 @@ X-Gitlab-Event: Note Hook
},
"project_id": 5,
"project":{
+ "id": 5,
"name":"Gitlab Test",
"description":"Aut reprehenderit ut est.",
"web_url":"http://example.com/gitlab-org/gitlab-test",
@@ -692,6 +699,7 @@ X-Gitlab-Event: Merge Request Hook
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon"
},
"project": {
+ "id": 1,
"name":"Gitlab Test",
"description":"Aut reprehenderit ut est.",
"web_url":"http://example.com/gitlabhq/gitlab-test",
@@ -848,6 +856,7 @@ X-Gitlab-Event: Wiki Page Hook
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon"
},
"project": {
+ "id": 1,
"name": "awesome-project",
"description": "This is awesome",
"web_url": "http://example.com/root/awesome-project",
@@ -919,6 +928,7 @@ X-Gitlab-Event: Pipeline Hook
"avatar_url": "http://www.gravatar.com/avatar/e32bd13e2add097461cb96824b7a829c?s=80\u0026d=identicon"
},
"project":{
+ "id": 1,
"name": "Gitlab Test",
"description": "Atque in sunt eos similique dolores voluptatem.",
"web_url": "http://192.168.64.1:3005/gitlab-org/gitlab-test",
diff --git a/doc/user/project/merge_requests/index.md b/doc/user/project/merge_requests/index.md
index 6289fcf3c2b..4b2e042251b 100644
--- a/doc/user/project/merge_requests/index.md
+++ b/doc/user/project/merge_requests/index.md
@@ -34,7 +34,6 @@ With **[GitLab Enterprise Edition][ee]**, you can also:
- View the deployment process across projects with [Multi-Project Pipeline Graphs](https://docs.gitlab.com/ee/ci/multi_project_pipeline_graphs.html#multi-project-pipeline-graphs) (available only in GitLab Enterprise Edition Premium)
- Request [approvals](https://docs.gitlab.com/ee/user/project/merge_requests/merge_request_approvals.html) from your managers (available in GitLab Enterprise Edition Starter)
- [Squash and merge](https://docs.gitlab.com/ee/user/project/merge_requests/squash_and_merge.html) for a cleaner commit history (available in GitLab Enterprise Edition Starter)
-- Enable [semi-linear history merge requests](https://docs.gitlab.com/ee/user/project/merge_requests/index.html#semi-linear-history-merge-requests) as another security layer to guarantee the pipeline is passing in the target branch (available in GitLab Enterprise Edition Starter)
- Analise the impact of your changes with [Code Quality reports](https://docs.gitlab.com/ee/user/project/merge_requests/code_quality_diff.html) (available in GitLab Enterprise Edition Starter)
## Use cases
diff --git a/doc/user/project/milestones/index.md b/doc/user/project/milestones/index.md
index 876b98a4dc5..83adbd8cce2 100644
--- a/doc/user/project/milestones/index.md
+++ b/doc/user/project/milestones/index.md
@@ -29,7 +29,8 @@ In addition to that you will be able to filter issues or merge requests by group
## Milestone promotion
-You will be able to promote a project milestone to a group milestone [in the future](https://gitlab.com/gitlab-org/gitlab-ce/issues/35833).
+Project milestones can be promoted to group milestones if its project belongs to a group. When a milestone is promoted all other milestones across the group projects with the same title will be merged into it, which means all milestone's children like issues, merge requests and boards will be moved into the new promoted milestone.
+The promote button can be found in the milestone view or milestones list.
## Special milestone filters
diff --git a/doc/user/project/pages/introduction.md b/doc/user/project/pages/introduction.md
index 4fcdfa7b281..3ab88948fbd 100644
--- a/doc/user/project/pages/introduction.md
+++ b/doc/user/project/pages/introduction.md
@@ -3,7 +3,7 @@
> **Notes:**
> - This feature was [introduced][ee-80] in GitLab EE 8.3.
> - Custom CNAMEs with TLS support were [introduced][ee-173] in GitLab EE 8.5.
-> - GitLab Pages [were ported][ce-14605] to Community Edition in GitLab 8.17.
+> - GitLab Pages [was ported][ce-14605] to Community Edition in GitLab 8.17.
> - This document is about the user guide. To learn how to enable GitLab Pages
> across your GitLab instance, visit the [administrator documentation](../../../administration/pages/index.md).
@@ -174,7 +174,7 @@ job, the contents of the `public` directory will be served by GitLab Pages.
#### How `.gitlab-ci.yml` looks like when the static content is in your repository
-Supposedly your repository contained the following files:
+Supposed your repository contained the following files:
```
├── index.html
@@ -419,7 +419,7 @@ You can only create the highest level group website.
## Redirects in GitLab Pages
Since you cannot use any custom server configuration files, like `.htaccess` or
-any `.conf` file for that matter, if you want to redirect a web page to another
+any `.conf` file, if you want to redirect a page to another
location, you can use the [HTTP meta refresh tag][metarefresh].
Some static site generators provide plugins for that functionality so that you
@@ -434,7 +434,7 @@ Sure. All you need to do is download the artifacts archive from the job page.
### Can I use GitLab Pages if my project is private?
-Yes. GitLab Pages don't care whether you set your project's visibility level
+Yes. GitLab Pages doesn't care whether you set your project's visibility level
to private, internal or public.
### Do I need to create a user/group website before creating a project website?
diff --git a/doc/user/project/repository/branches/index.md b/doc/user/project/repository/branches/index.md
index e1d3aebb8b3..26c55891b3c 100644
--- a/doc/user/project/repository/branches/index.md
+++ b/doc/user/project/repository/branches/index.md
@@ -37,7 +37,7 @@ This feature allows merged branches to be deleted in bulk. Only branches that
have been merged and [are not protected][protected] will be deleted as part of
this operation.
-It's particularly useful to clean up old branches that were not deleting
+It's particularly useful to clean up old branches that were not deleted
automatically when a merge request was merged.
[ce-6449]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/6449 "Add button to delete all merged branches"
diff --git a/doc/user/project/repository/web_editor.md b/doc/user/project/repository/web_editor.md
index d47a3acdbe9..db0c3ed9d59 100644
--- a/doc/user/project/repository/web_editor.md
+++ b/doc/user/project/repository/web_editor.md
@@ -105,7 +105,7 @@ merge request.
Once you click it, a new branch will be created that diverges from the default
branch of your project, by default `master`. The branch name will be based on
-the title of the issue and as suffix it will have its ID. Thus, the example
+the title of the issue and as a prefix, it will have its internal ID. Thus, the example
screenshot above will yield a branch named
`2-et-cum-et-sed-expedita-repellat-consequatur-ut-assumenda-numquam-rerum`.
diff --git a/doc/workflow/shortcuts.md b/doc/workflow/shortcuts.md
index 87416008e98..2e1bd6bfe5c 100644
--- a/doc/workflow/shortcuts.md
+++ b/doc/workflow/shortcuts.md
@@ -9,7 +9,7 @@ You can see GitLab's keyboard shortcuts by using 'shift + ?'
| <kbd>n</kbd> | Main navigation |
| <kbd>s</kbd> | Focus search |
| <kbd>f</kbd> | Focus filter |
-| <kbd>p b</kbd> | Show/hide the Performance Bar |
+| <kbd>p</kbd> + <kbd>b</kbd> | Show/hide the Performance Bar |
| <kbd>?</kbd> | Show/hide this dialog |
| <kbd>⌘</kbd> + <kbd>shift</kbd> + <kbd>p</kbd> | Toggle markdown preview |
| <kbd>↑</kbd> | Edit last comment (when focused on an empty textarea) |
diff --git a/features/steps/project/issues/issues.rb b/features/steps/project/issues/issues.rb
index 2c3ef2efd52..3843374678c 100644
--- a/features/steps/project/issues/issues.rb
+++ b/features/steps/project/issues/issues.rb
@@ -20,11 +20,13 @@ class Spinach::Features::ProjectIssues < Spinach::FeatureSteps
end
step 'I should see that I am subscribed' do
- expect(find('.issuable-subscribe-button span')).to have_content 'Unsubscribe'
+ wait_for_requests
+ expect(find('.js-issuable-subscribe-button span')).to have_content 'Unsubscribe'
end
step 'I should see that I am unsubscribed' do
- expect(find('.issuable-subscribe-button span')).to have_content 'Subscribe'
+ wait_for_requests
+ expect(find('.js-issuable-subscribe-button span')).to have_content 'Subscribe'
end
step 'I click link "Closed"' do
diff --git a/lib/additional_email_headers_interceptor.rb b/lib/additional_email_headers_interceptor.rb
index 2358fa6bbfd..3cb1694b9f1 100644
--- a/lib/additional_email_headers_interceptor.rb
+++ b/lib/additional_email_headers_interceptor.rb
@@ -1,8 +1,6 @@
class AdditionalEmailHeadersInterceptor
def self.delivering_email(message)
- message.headers(
- 'Auto-Submitted' => 'auto-generated',
- 'X-Auto-Response-Suppress' => 'All'
- )
+ message.header['Auto-Submitted'] ||= 'auto-generated'
+ message.header['X-Auto-Response-Suppress'] ||= 'All'
end
end
diff --git a/lib/api/api.rb b/lib/api/api.rb
index 99fcc59ba04..7db18e25a5f 100644
--- a/lib/api/api.rb
+++ b/lib/api/api.rb
@@ -131,6 +131,7 @@ module API
mount ::API::Namespaces
mount ::API::Notes
mount ::API::NotificationSettings
+ mount ::API::PagesDomains
mount ::API::Pipelines
mount ::API::PipelineSchedules
mount ::API::ProjectHooks
diff --git a/lib/api/entities.rb b/lib/api/entities.rb
index 5f0bad14839..efe874b2e6b 100644
--- a/lib/api/entities.rb
+++ b/lib/api/entities.rb
@@ -1043,5 +1043,22 @@ module API
expose :key
expose :value
end
+
+ class PagesDomainCertificate < Grape::Entity
+ expose :subject
+ expose :expired?, as: :expired
+ expose :certificate
+ expose :certificate_text
+ end
+
+ class PagesDomain < Grape::Entity
+ expose :domain
+ expose :url
+ expose :certificate,
+ if: ->(pages_domain, _) { pages_domain.certificate? },
+ using: PagesDomainCertificate do |pages_domain|
+ pages_domain
+ end
+ end
end
end
diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb
index 2b316b58ed9..7a2ec865860 100644
--- a/lib/api/helpers.rb
+++ b/lib/api/helpers.rb
@@ -184,6 +184,10 @@ module API
end
end
+ def require_pages_enabled!
+ not_found! unless user_project.pages_available?
+ end
+
def can?(object, action, subject = :global)
Ability.allowed?(object, action, subject)
end
diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb
index be843ec8251..726f09e3669 100644
--- a/lib/api/merge_requests.rb
+++ b/lib/api/merge_requests.rb
@@ -295,7 +295,7 @@ module API
unauthorized! unless merge_request.can_cancel_merge_when_pipeline_succeeds?(current_user)
- ::MergeRequest::MergeWhenPipelineSucceedsService
+ ::MergeRequests::MergeWhenPipelineSucceedsService
.new(merge_request.target_project, current_user)
.cancel(merge_request)
end
diff --git a/lib/api/pages_domains.rb b/lib/api/pages_domains.rb
new file mode 100644
index 00000000000..259f3f34068
--- /dev/null
+++ b/lib/api/pages_domains.rb
@@ -0,0 +1,117 @@
+module API
+ class PagesDomains < Grape::API
+ include PaginationParams
+
+ before do
+ authenticate!
+ require_pages_enabled!
+ end
+
+ after_validation do
+ normalize_params_file_to_string
+ end
+
+ helpers do
+ def find_pages_domain!
+ user_project.pages_domains.find_by(domain: params[:domain]) || not_found!('PagesDomain')
+ end
+
+ def pages_domain
+ @pages_domain ||= find_pages_domain!
+ end
+
+ def normalize_params_file_to_string
+ params.each do |k, v|
+ if v.is_a?(Hash) && v.key?(:tempfile)
+ params[k] = v[:tempfile].to_a.join('')
+ end
+ end
+ end
+ end
+
+ params do
+ requires :id, type: String, desc: 'The ID of a project'
+ end
+ resource :projects, requirements: { id: %r{[^/]+} } do
+ desc 'Get all pages domains' do
+ success Entities::PagesDomain
+ end
+ params do
+ use :pagination
+ end
+ get ":id/pages/domains" do
+ authorize! :read_pages, user_project
+
+ present paginate(user_project.pages_domains.order(:domain)), with: Entities::PagesDomain
+ end
+
+ desc 'Get a single pages domain' do
+ success Entities::PagesDomain
+ end
+ params do
+ requires :domain, type: String, desc: 'The domain'
+ end
+ get ":id/pages/domains/:domain", requirements: { domain: %r{[^/]+} } do
+ authorize! :read_pages, user_project
+
+ present pages_domain, with: Entities::PagesDomain
+ end
+
+ desc 'Create a new pages domain' do
+ success Entities::PagesDomain
+ end
+ params do
+ requires :domain, type: String, desc: 'The domain'
+ optional :certificate, allow_blank: false, types: [File, String], desc: 'The certificate'
+ optional :key, allow_blank: false, types: [File, String], desc: 'The key'
+ all_or_none_of :certificate, :key
+ end
+ post ":id/pages/domains" do
+ authorize! :update_pages, user_project
+
+ pages_domain_params = declared(params, include_parent_namespaces: false)
+ pages_domain = user_project.pages_domains.create(pages_domain_params)
+
+ if pages_domain.persisted?
+ present pages_domain, with: Entities::PagesDomain
+ else
+ render_validation_error!(pages_domain)
+ end
+ end
+
+ desc 'Updates a pages domain'
+ params do
+ requires :domain, type: String, desc: 'The domain'
+ optional :certificate, allow_blank: false, types: [File, String], desc: 'The certificate'
+ optional :key, allow_blank: false, types: [File, String], desc: 'The key'
+ end
+ put ":id/pages/domains/:domain", requirements: { domain: %r{[^/]+} } do
+ authorize! :update_pages, user_project
+
+ pages_domain_params = declared(params, include_parent_namespaces: false)
+
+ # Remove empty private key if certificate is not empty.
+ if pages_domain_params[:certificate] && !pages_domain_params[:key]
+ pages_domain_params.delete(:key)
+ end
+
+ if pages_domain.update(pages_domain_params)
+ present pages_domain, with: Entities::PagesDomain
+ else
+ render_validation_error!(pages_domain)
+ end
+ end
+
+ desc 'Delete a pages domain'
+ params do
+ requires :domain, type: String, desc: 'The domain'
+ end
+ delete ":id/pages/domains/:domain", requirements: { domain: %r{[^/]+} } do
+ authorize! :update_pages, user_project
+
+ status 204
+ pages_domain.destroy
+ end
+ end
+ end
+end
diff --git a/lib/api/services.rb b/lib/api/services.rb
index 2cbd0517dc3..6454e475036 100644
--- a/lib/api/services.rb
+++ b/lib/api/services.rb
@@ -313,13 +313,13 @@ module API
desc: 'The base URL to the JIRA instance API. Web URL value will be used if not set. E.g., https://jira-api.example.com'
},
{
- required: false,
+ required: true,
name: :username,
type: String,
desc: 'The username of the user created to be used with GitLab/JIRA'
},
{
- required: false,
+ required: true,
name: :password,
type: String,
desc: 'The password of the user created to be used with GitLab/JIRA'
@@ -374,6 +374,26 @@ module API
desc: 'The Slack token'
}
],
+ 'packagist' => [
+ {
+ required: true,
+ name: :username,
+ type: String,
+ desc: 'The username'
+ },
+ {
+ required: true,
+ name: :token,
+ type: String,
+ desc: 'The Packagist API token'
+ },
+ {
+ required: false,
+ name: :server,
+ type: String,
+ desc: 'The server'
+ }
+ ],
'pipelines-email' => [
{
required: true,
@@ -551,6 +571,7 @@ module API
KubernetesService,
MattermostSlashCommandsService,
SlackSlashCommandsService,
+ PackagistService,
PipelinesEmailService,
PivotaltrackerService,
PrometheusService,
diff --git a/lib/api/v3/services.rb b/lib/api/v3/services.rb
index 2d13d6fabfd..44ed94d2869 100644
--- a/lib/api/v3/services.rb
+++ b/lib/api/v3/services.rb
@@ -395,6 +395,26 @@ module API
desc: 'The Slack token'
}
],
+ 'packagist' => [
+ {
+ required: true,
+ name: :username,
+ type: String,
+ desc: 'The username'
+ },
+ {
+ required: true,
+ name: :token,
+ type: String,
+ desc: 'The Packagist API token'
+ },
+ {
+ required: false,
+ name: :server,
+ type: String,
+ desc: 'The server'
+ }
+ ],
'pipelines-email' => [
{
required: true,
diff --git a/lib/backup/manager.rb b/lib/backup/manager.rb
index 092e82bd4d1..05aa79dc160 100644
--- a/lib/backup/manager.rb
+++ b/lib/backup/manager.rb
@@ -137,10 +137,12 @@ module Backup
# restoring mismatching backups can lead to unexpected problems
if settings[:gitlab_version] != Gitlab::VERSION
- $progress.puts 'GitLab version mismatch:'.color(:red)
- $progress.puts " Your current GitLab version (#{Gitlab::VERSION}) differs from the GitLab version in the backup!".color(:red)
- $progress.puts ' Please switch to the following version and try again:'.color(:red)
- $progress.puts " version: #{settings[:gitlab_version]}".color(:red)
+ $progress.puts(<<~HEREDOC.color(:red))
+ GitLab version mismatch:
+ Your current GitLab version (#{Gitlab::VERSION}) differs from the GitLab version in the backup!
+ Please switch to the following version and try again:
+ version: #{settings[:gitlab_version]}
+ HEREDOC
$progress.puts
$progress.puts "Hint: git checkout v#{settings[:gitlab_version]}"
exit 1
diff --git a/lib/gitlab/database.rb b/lib/gitlab/database.rb
index 357f16936c6..43a00d6cedb 100644
--- a/lib/gitlab/database.rb
+++ b/lib/gitlab/database.rb
@@ -4,6 +4,10 @@ module Gitlab
# https://www.postgresql.org/docs/9.2/static/datatype-numeric.html
# http://dev.mysql.com/doc/refman/5.7/en/integer-types.html
MAX_INT_VALUE = 2147483647
+ # The max value between MySQL's TIMESTAMP and PostgreSQL's timestampz:
+ # https://www.postgresql.org/docs/9.1/static/datatype-datetime.html
+ # https://dev.mysql.com/doc/refman/5.7/en/datetime.html
+ MAX_TIMESTAMP_VALUE = Time.at((1 << 31) - 1).freeze
def self.config
ActiveRecord::Base.configurations[Rails.env]
@@ -120,6 +124,10 @@ module Gitlab
EOF
end
+ def self.sanitize_timestamp(timestamp)
+ MAX_TIMESTAMP_VALUE > timestamp ? timestamp : MAX_TIMESTAMP_VALUE.dup
+ end
+
# pool_size - The size of the DB pool.
# host - An optional host name to use instead of the default one.
def self.create_connection_pool(pool_size, host = nil)
diff --git a/lib/gitlab/diff/position.rb b/lib/gitlab/diff/position.rb
index bd0a9502a5e..ccfb908bcca 100644
--- a/lib/gitlab/diff/position.rb
+++ b/lib/gitlab/diff/position.rb
@@ -94,7 +94,9 @@ module Gitlab
end
def diff_file(repository)
- @diff_file ||= begin
+ return @diff_file if defined?(@diff_file)
+
+ @diff_file = begin
if RequestStore.active?
key = {
project_id: repository.project.id,
@@ -122,8 +124,8 @@ module Gitlab
def find_diff_file(repository)
return unless diff_refs.complete?
-
- diff_refs.compare_in(repository.project).diffs(paths: paths, expanded: true).diff_files.first
+ return unless comparison = diff_refs.compare_in(repository.project)
+ comparison.diffs(paths: paths, expanded: true).diff_files.first
end
def get_formatter_class(type)
diff --git a/lib/gitlab/git/branch.rb b/lib/gitlab/git/branch.rb
index c53882787f1..3487e099381 100644
--- a/lib/gitlab/git/branch.rb
+++ b/lib/gitlab/git/branch.rb
@@ -3,6 +3,14 @@
module Gitlab
module Git
class Branch < Ref
+ def self.find(repo, branch_name)
+ if branch_name.is_a?(Gitlab::Git::Branch)
+ branch_name
+ else
+ repo.find_branch(branch_name)
+ end
+ end
+
def initialize(repository, name, target, target_commit)
super(repository, name, target, target_commit)
end
diff --git a/lib/gitlab/git/commit.rb b/lib/gitlab/git/commit.rb
index 1957c254c28..23ae37ff71e 100644
--- a/lib/gitlab/git/commit.rb
+++ b/lib/gitlab/git/commit.rb
@@ -72,7 +72,8 @@ module Gitlab
decorate(repo, commit) if commit
rescue Rugged::ReferenceError, Rugged::InvalidError, Rugged::ObjectError,
- Gitlab::Git::CommandError, Gitlab::Git::Repository::NoRepository
+ Gitlab::Git::CommandError, Gitlab::Git::Repository::NoRepository,
+ Rugged::OdbError, Rugged::TreeError
nil
end
diff --git a/lib/gitlab/git/hooks_service.rb b/lib/gitlab/git/hooks_service.rb
index c327e9b1616..f302b852b35 100644
--- a/lib/gitlab/git/hooks_service.rb
+++ b/lib/gitlab/git/hooks_service.rb
@@ -8,7 +8,7 @@ module Gitlab
def execute(pusher, repository, oldrev, newrev, ref)
@repository = repository
@gl_id = pusher.gl_id
- @gl_username = pusher.name
+ @gl_username = pusher.username
@oldrev = oldrev
@newrev = newrev
@ref = ref
diff --git a/lib/gitlab/git/repository.rb b/lib/gitlab/git/repository.rb
index 59a54b48ed9..fc8af38d4d9 100644
--- a/lib/gitlab/git/repository.rb
+++ b/lib/gitlab/git/repository.rb
@@ -166,7 +166,7 @@ module Gitlab
end
def local_branches(sort_by: nil)
- gitaly_migrate(:local_branches) do |is_enabled|
+ gitaly_migrate(:local_branches, status: Gitlab::GitalyClient::MigrationStatus::OPT_OUT) do |is_enabled|
if is_enabled
gitaly_ref_client.local_branches(sort_by: sort_by)
else
@@ -511,6 +511,10 @@ module Gitlab
gitaly_commit_client.ancestor?(from, to)
end
+ def merged_branch_names(branch_names = [])
+ Set.new(git_merged_branch_names(branch_names))
+ end
+
# Return an array of Diff objects that represent the diff
# between +from+ and +to+. See Diff::filter_diff_options for the allowed
# diff options. The +options+ hash can also include :break_rewrites to
@@ -745,6 +749,16 @@ module Gitlab
nil
end
+ def ff_merge(user, source_sha, target_branch)
+ OperationService.new(user, self).with_branch(target_branch) do |our_commit|
+ raise ArgumentError, 'Invalid merge target' unless our_commit
+
+ source_sha
+ end
+ rescue Rugged::ReferenceError
+ raise ArgumentError, 'Invalid merge source'
+ end
+
def revert(user:, commit:, branch_name:, message:, start_branch_name:, start_repository:)
OperationService.new(user, self).with_branch(
branch_name,
@@ -1180,6 +1194,13 @@ module Gitlab
sort_branches(branches, sort_by)
end
+ def git_merged_branch_names(branch_names = [])
+ lines = run_git(['branch', '--merged', root_ref] + branch_names)
+ .first.lines
+
+ lines.map(&:strip)
+ end
+
def log_using_shell?(options)
options[:path].present? ||
options[:disable_walk] ||
diff --git a/lib/gitlab/git/storage.rb b/lib/gitlab/git/storage.rb
index 08e6c29abad..99518c9b1e4 100644
--- a/lib/gitlab/git/storage.rb
+++ b/lib/gitlab/git/storage.rb
@@ -12,6 +12,7 @@ module Gitlab
CircuitOpen = Class.new(Inaccessible)
Misconfiguration = Class.new(Inaccessible)
+ Failing = Class.new(Inaccessible)
REDIS_KEY_PREFIX = 'storage_accessible:'.freeze
diff --git a/lib/gitlab/git/storage/circuit_breaker.rb b/lib/gitlab/git/storage/circuit_breaker.rb
index 0456ad9a1f3..be7598ef011 100644
--- a/lib/gitlab/git/storage/circuit_breaker.rb
+++ b/lib/gitlab/git/storage/circuit_breaker.rb
@@ -54,7 +54,7 @@ module Gitlab
end
def perform
- return yield unless Feature.enabled?('git_storage_circuit_breaker')
+ return yield unless enabled?
check_storage_accessible!
@@ -64,10 +64,27 @@ module Gitlab
def circuit_broken?
return false if no_failures?
+ failure_count > failure_count_threshold
+ end
+
+ def backing_off?
+ return false if no_failures?
+
recent_failure = last_failure > failure_wait_time.seconds.ago
- too_many_failures = failure_count > failure_count_threshold
+ too_many_failures = failure_count > backoff_threshold
- recent_failure || too_many_failures
+ recent_failure && too_many_failures
+ end
+
+ private
+
+ # The circuitbreaker can be enabled for the entire fleet using a Feature
+ # flag.
+ #
+ # Enabling it for a single host can be done setting the
+ # `GIT_STORAGE_CIRCUIT_BREAKER` environment variable.
+ def enabled?
+ ENV['GIT_STORAGE_CIRCUIT_BREAKER'].present? || Feature.enabled?('git_storage_circuit_breaker')
end
def failure_info
@@ -83,7 +100,7 @@ module Gitlab
return @storage_available if @storage_available
if @storage_available = Gitlab::Git::Storage::ForkedStorageCheck
- .storage_available?(storage_path, storage_timeout)
+ .storage_available?(storage_path, storage_timeout, access_retries)
track_storage_accessible
else
track_storage_inaccessible
@@ -94,7 +111,11 @@ module Gitlab
def check_storage_accessible!
if circuit_broken?
- raise Gitlab::Git::Storage::CircuitOpen.new("Circuit for #{storage} is broken", failure_wait_time)
+ raise Gitlab::Git::Storage::CircuitOpen.new("Circuit for #{storage} is broken", failure_reset_time)
+ end
+
+ if backing_off?
+ raise Gitlab::Git::Storage::Failing.new("Backing off access to #{storage}", failure_wait_time)
end
unless storage_available?
@@ -131,12 +152,6 @@ module Gitlab
end
end
- def cache_key
- @cache_key ||= "#{Gitlab::Git::Storage::REDIS_KEY_PREFIX}#{storage}:#{hostname}"
- end
-
- private
-
def get_failure_info
last_failure, failure_count = Gitlab::Git::Storage.redis.with do |redis|
redis.hmget(cache_key, :last_failure, :failure_count)
@@ -146,6 +161,10 @@ module Gitlab
FailureInfo.new(last_failure, failure_count.to_i)
end
+
+ def cache_key
+ @cache_key ||= "#{Gitlab::Git::Storage::REDIS_KEY_PREFIX}#{storage}:#{hostname}"
+ end
end
end
end
diff --git a/lib/gitlab/git/storage/circuit_breaker_settings.rb b/lib/gitlab/git/storage/circuit_breaker_settings.rb
index d2313fe7c1b..257fe8cd8f0 100644
--- a/lib/gitlab/git/storage/circuit_breaker_settings.rb
+++ b/lib/gitlab/git/storage/circuit_breaker_settings.rb
@@ -18,6 +18,14 @@ module Gitlab
application_settings.circuitbreaker_storage_timeout
end
+ def access_retries
+ application_settings.circuitbreaker_access_retries
+ end
+
+ def backoff_threshold
+ application_settings.circuitbreaker_backoff_threshold
+ end
+
private
def application_settings
diff --git a/lib/gitlab/git/storage/forked_storage_check.rb b/lib/gitlab/git/storage/forked_storage_check.rb
index 91d8241f17b..1307f400700 100644
--- a/lib/gitlab/git/storage/forked_storage_check.rb
+++ b/lib/gitlab/git/storage/forked_storage_check.rb
@@ -4,8 +4,17 @@ module Gitlab
module ForkedStorageCheck
extend self
- def storage_available?(path, timeout_seconds = 5)
- status = timeout_check(path, timeout_seconds)
+ def storage_available?(path, timeout_seconds = 5, retries = 1)
+ partial_timeout = timeout_seconds / retries
+ status = timeout_check(path, partial_timeout)
+
+ # If the status check did not succeed the first time, we retry a few
+ # more times to avoid one-off failures
+ current_attempts = 1
+ while current_attempts < retries && !status.success?
+ status = timeout_check(path, partial_timeout)
+ current_attempts += 1
+ end
status.success?
end
diff --git a/lib/gitlab/git/storage/null_circuit_breaker.rb b/lib/gitlab/git/storage/null_circuit_breaker.rb
index 60c6791a7e4..a12d52d295f 100644
--- a/lib/gitlab/git/storage/null_circuit_breaker.rb
+++ b/lib/gitlab/git/storage/null_circuit_breaker.rb
@@ -25,6 +25,10 @@ module Gitlab
!!@error
end
+ def backing_off?
+ false
+ end
+
def last_failure
circuit_broken? ? Time.now : nil
end
diff --git a/lib/gitlab/git/user.rb b/lib/gitlab/git/user.rb
index da74719ae87..e6b61417de1 100644
--- a/lib/gitlab/git/user.rb
+++ b/lib/gitlab/git/user.rb
@@ -7,9 +7,8 @@ module Gitlab
new(gitlab_user.username, gitlab_user.name, gitlab_user.email, Gitlab::GlId.gl_id(gitlab_user))
end
- # TODO support the username field in Gitaly https://gitlab.com/gitlab-org/gitaly/issues/628
def self.from_gitaly(gitaly_user)
- new('', gitaly_user.name, gitaly_user.email, gitaly_user.gl_id)
+ new(gitaly_user.gl_username, gitaly_user.name, gitaly_user.email, gitaly_user.gl_id)
end
def initialize(username, name, email, gl_id)
@@ -22,6 +21,10 @@ module Gitlab
def ==(other)
[username, name, email, gl_id] == [other.username, other.name, other.email, other.gl_id]
end
+
+ def to_gitaly
+ Gitaly::User.new(gl_username: username, gl_id: gl_id, name: name, email: email)
+ end
end
end
end
diff --git a/lib/gitlab/git/wiki.rb b/lib/gitlab/git/wiki.rb
index e7b2f52a552..549d22adde5 100644
--- a/lib/gitlab/git/wiki.rb
+++ b/lib/gitlab/git/wiki.rb
@@ -8,6 +8,7 @@ module Gitlab
{ name: name, email: email, message: message }
end
end
+ PageBlob = Struct.new(:name)
def self.default_ref
'master'
@@ -34,10 +35,14 @@ module Gitlab
end
def delete_page(page_path, commit_details)
- assert_type!(commit_details, CommitDetails)
-
- gollum_wiki.delete_page(gollum_page_by_path(page_path), commit_details.to_h)
- nil
+ @repository.gitaly_migrate(:wiki_delete_page) do |is_enabled|
+ if is_enabled
+ gitaly_delete_page(page_path, commit_details)
+ gollum_wiki.clear_cache
+ else
+ gollum_delete_page(page_path, commit_details)
+ end
+ end
end
def update_page(page_path, title, format, content, commit_details)
@@ -53,14 +58,13 @@ module Gitlab
end
def page(title:, version: nil, dir: nil)
- if version
- version = Gitlab::Git::Commit.find(@repository, version).id
+ @repository.gitaly_migrate(:wiki_find_page) do |is_enabled|
+ if is_enabled
+ gitaly_find_page(title: title, version: version, dir: dir)
+ else
+ gollum_find_page(title: title, version: version, dir: dir)
+ end
end
-
- gollum_page = gollum_wiki.page(title, version, dir)
- return unless gollum_page
-
- new_page(gollum_page)
end
def file(name, version)
@@ -80,7 +84,15 @@ module Gitlab
end
def preview_slug(title, format)
- gollum_wiki.preview_page(title, '', format).url_path
+ # Adapted from gollum gem (Gollum::Wiki#preview_page) to avoid
+ # using Rugged through a Gollum::Wiki instance
+ page_class = Gollum::Page
+ page = page_class.new(nil)
+ ext = page_class.format_to_ext(format.to_sym)
+ name = page_class.cname(title) + '.' + ext
+ blob = PageBlob.new(name)
+ page.populate(blob)
+ page.url_path
end
private
@@ -126,9 +138,38 @@ module Gitlab
raise Gitlab::Git::Wiki::DuplicatePageError, e.message
end
+ def gollum_delete_page(page_path, commit_details)
+ assert_type!(commit_details, CommitDetails)
+
+ gollum_wiki.delete_page(gollum_page_by_path(page_path), commit_details.to_h)
+ nil
+ end
+
+ def gollum_find_page(title:, version: nil, dir: nil)
+ if version
+ version = Gitlab::Git::Commit.find(@repository, version).id
+ end
+
+ gollum_page = gollum_wiki.page(title, version, dir)
+ return unless gollum_page
+
+ new_page(gollum_page)
+ end
+
def gitaly_write_page(name, format, content, commit_details)
gitaly_wiki_client.write_page(name, format, content, commit_details)
end
+
+ def gitaly_delete_page(page_path, commit_details)
+ gitaly_wiki_client.delete_page(page_path, commit_details)
+ end
+
+ def gitaly_find_page(title:, version: nil, dir: nil)
+ wiki_page, version = gitaly_wiki_client.find_page(title: title, version: version, dir: dir)
+ return unless wiki_page
+
+ Gitlab::Git::WikiPage.new(wiki_page, version)
+ end
end
end
end
diff --git a/lib/gitlab/git/wiki_file.rb b/lib/gitlab/git/wiki_file.rb
index 527f2a44dea..84335aca4bc 100644
--- a/lib/gitlab/git/wiki_file.rb
+++ b/lib/gitlab/git/wiki_file.rb
@@ -1,7 +1,7 @@
module Gitlab
module Git
class WikiFile
- attr_reader :mime_type, :raw_data, :name
+ attr_reader :mime_type, :raw_data, :name, :path
# This class is meant to be serializable so that it can be constructed
# by Gitaly and sent over the network to GitLab.
@@ -13,6 +13,7 @@ module Gitlab
@mime_type = gollum_file.mime_type
@raw_data = gollum_file.raw_data
@name = gollum_file.name
+ @path = gollum_file.path
end
end
end
diff --git a/lib/gitlab/git_access.rb b/lib/gitlab/git_access.rb
index 42b59c106e2..8998c4b1a83 100644
--- a/lib/gitlab/git_access.rb
+++ b/lib/gitlab/git_access.rb
@@ -215,10 +215,6 @@ module Gitlab
).exec
end
- def matching_merge_request?(newrev, branch_name)
- Checks::MatchingMergeRequest.new(newrev, branch_name, project).match?
- end
-
def deploy_key
actor if deploy_key?
end
diff --git a/lib/gitlab/gitaly_client.rb b/lib/gitlab/gitaly_client.rb
index 6c1ae19ff11..6868be26758 100644
--- a/lib/gitlab/gitaly_client.rb
+++ b/lib/gitlab/gitaly_client.rb
@@ -33,6 +33,12 @@ module Gitlab
MUTEX = Mutex.new
private_constant :MUTEX
+ class << self
+ attr_accessor :query_time
+ end
+
+ self.query_time = 0
+
def self.stub(name, storage)
MUTEX.synchronize do
@stubs ||= {}
@@ -83,11 +89,14 @@ module Gitlab
# end
#
def self.call(storage, service, rpc, request)
+ start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
enforce_gitaly_request_limits(:call)
kwargs = request_kwargs(storage)
kwargs = yield(kwargs) if block_given?
stub(service, storage).__send__(rpc, request, kwargs) # rubocop:disable GitlabSecurity/PublicSend
+ ensure
+ self.query_time += Process.clock_gettime(Process::CLOCK_MONOTONIC) - start
end
def self.request_kwargs(storage)
diff --git a/lib/gitlab/gitaly_client/operation_service.rb b/lib/gitlab/gitaly_client/operation_service.rb
index 91f34011f6e..adaf255f24b 100644
--- a/lib/gitlab/gitaly_client/operation_service.rb
+++ b/lib/gitlab/gitaly_client/operation_service.rb
@@ -10,7 +10,7 @@ module Gitlab
request = Gitaly::UserDeleteTagRequest.new(
repository: @gitaly_repo,
tag_name: GitalyClient.encode(tag_name),
- user: Util.gitaly_user(user)
+ user: Gitlab::Git::User.from_gitlab(user).to_gitaly
)
response = GitalyClient.call(@repository.storage, :operation_service, :user_delete_tag, request)
@@ -23,7 +23,7 @@ module Gitlab
def add_tag(tag_name, user, target, message)
request = Gitaly::UserCreateTagRequest.new(
repository: @gitaly_repo,
- user: Util.gitaly_user(user),
+ user: Gitlab::Git::User.from_gitlab(user).to_gitaly,
tag_name: GitalyClient.encode(tag_name),
target_revision: GitalyClient.encode(target),
message: GitalyClient.encode(message.to_s)
@@ -45,7 +45,7 @@ module Gitlab
request = Gitaly::UserCreateBranchRequest.new(
repository: @gitaly_repo,
branch_name: GitalyClient.encode(branch_name),
- user: Util.gitaly_user(user),
+ user: Gitlab::Git::User.from_gitlab(user).to_gitaly,
start_point: GitalyClient.encode(start_point)
)
response = GitalyClient.call(@repository.storage, :operation_service,
@@ -65,7 +65,7 @@ module Gitlab
request = Gitaly::UserDeleteBranchRequest.new(
repository: @gitaly_repo,
branch_name: GitalyClient.encode(branch_name),
- user: Util.gitaly_user(user)
+ user: Gitlab::Git::User.from_gitlab(user).to_gitaly
)
response = GitalyClient.call(@repository.storage, :operation_service, :user_delete_branch, request)
@@ -87,7 +87,7 @@ module Gitlab
request_enum.push(
Gitaly::UserMergeBranchRequest.new(
repository: @gitaly_repo,
- user: Util.gitaly_user(user),
+ user: Gitlab::Git::User.from_gitlab(user).to_gitaly,
commit_id: source_sha,
branch: GitalyClient.encode(target_branch),
message: GitalyClient.encode(message)
diff --git a/lib/gitlab/gitaly_client/util.rb b/lib/gitlab/gitaly_client/util.rb
index a1222a7e718..b1a033280b4 100644
--- a/lib/gitlab/gitaly_client/util.rb
+++ b/lib/gitlab/gitaly_client/util.rb
@@ -18,16 +18,6 @@ module Gitlab
)
end
- def gitaly_user(gitlab_user)
- return unless gitlab_user
-
- Gitaly::User.new(
- gl_id: Gitlab::GlId.gl_id(gitlab_user),
- name: GitalyClient.encode(gitlab_user.name),
- email: GitalyClient.encode(gitlab_user.email)
- )
- end
-
def gitlab_tag_from_gitaly_tag(repository, gitaly_tag)
if gitaly_tag.target_commit.present?
commit = Gitlab::Git::Commit.decorate(repository, gitaly_tag.target_commit)
diff --git a/lib/gitlab/gitaly_client/wiki_page.rb b/lib/gitlab/gitaly_client/wiki_page.rb
new file mode 100644
index 00000000000..8226278d5f6
--- /dev/null
+++ b/lib/gitlab/gitaly_client/wiki_page.rb
@@ -0,0 +1,25 @@
+module Gitlab
+ module GitalyClient
+ class WikiPage
+ FIELDS = %i(title format url_path path name historical raw_data).freeze
+
+ attr_accessor(*FIELDS)
+
+ def initialize(params)
+ params = params.with_indifferent_access
+
+ FIELDS.each do |field|
+ instance_variable_set("@#{field}", params[field])
+ end
+ end
+
+ def historical?
+ @historical
+ end
+
+ def format
+ @format.to_sym
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/gitaly_client/wiki_service.rb b/lib/gitlab/gitaly_client/wiki_service.rb
index 03afcce81f0..5d7930f5ff9 100644
--- a/lib/gitlab/gitaly_client/wiki_service.rb
+++ b/lib/gitlab/gitaly_client/wiki_service.rb
@@ -15,11 +15,7 @@ module Gitlab
repository: @gitaly_repo,
name: GitalyClient.encode(name),
format: format.to_s,
- commit_details: Gitaly::WikiCommitDetails.new(
- name: GitalyClient.encode(commit_details.name),
- email: GitalyClient.encode(commit_details.email),
- message: GitalyClient.encode(commit_details.message)
- )
+ commit_details: gitaly_commit_details(commit_details)
)
strio = StringIO.new(content)
@@ -40,6 +36,59 @@ module Gitlab
raise Gitlab::Git::Wiki::DuplicatePageError, error
end
end
+
+ def delete_page(page_path, commit_details)
+ request = Gitaly::WikiDeletePageRequest.new(
+ repository: @gitaly_repo,
+ page_path: GitalyClient.encode(page_path),
+ commit_details: gitaly_commit_details(commit_details)
+ )
+
+ GitalyClient.call(@repository.storage, :wiki_service, :wiki_delete_page, request)
+ end
+
+ def find_page(title:, version: nil, dir: nil)
+ request = Gitaly::WikiFindPageRequest.new(
+ repository: @gitaly_repo,
+ title: GitalyClient.encode(title),
+ revision: GitalyClient.encode(version),
+ directory: GitalyClient.encode(dir)
+ )
+
+ response = GitalyClient.call(@repository.storage, :wiki_service, :wiki_find_page, request)
+ wiki_page = version = nil
+
+ response.each do |message|
+ page = message.page
+ next unless page
+
+ if wiki_page
+ wiki_page.raw_data << page.raw_data
+ else
+ wiki_page = GitalyClient::WikiPage.new(page.to_h)
+ # All gRPC strings in a response are frozen, so we get
+ # an unfrozen version here so appending in the else clause below doesn't blow up.
+ wiki_page.raw_data = wiki_page.raw_data.dup
+
+ version = Gitlab::Git::WikiPageVersion.new(
+ Gitlab::Git::Commit.decorate(@repository, page.version.commit),
+ page.version.format
+ )
+ end
+ end
+
+ [wiki_page, version]
+ end
+
+ private
+
+ def gitaly_commit_details(commit_details)
+ Gitaly::WikiCommitDetails.new(
+ name: GitalyClient.encode(commit_details.name),
+ email: GitalyClient.encode(commit_details.email),
+ message: GitalyClient.encode(commit_details.message)
+ )
+ end
end
end
end
diff --git a/lib/gitlab/import_export/import_export.yml b/lib/gitlab/import_export/import_export.yml
index dec8b4c5acd..e68761066d8 100644
--- a/lib/gitlab/import_export/import_export.yml
+++ b/lib/gitlab/import_export/import_export.yml
@@ -19,6 +19,7 @@ project_tree:
- milestone:
- events:
- :push_event_payload
+ - :issue_assignees
- snippets:
- :award_emoji
- notes:
diff --git a/lib/gitlab/ldap/auth_hash.rb b/lib/gitlab/ldap/auth_hash.rb
index 3123da17fd9..1bd0965679a 100644
--- a/lib/gitlab/ldap/auth_hash.rb
+++ b/lib/gitlab/ldap/auth_hash.rb
@@ -4,7 +4,7 @@ module Gitlab
module LDAP
class AuthHash < Gitlab::OAuth::AuthHash
def uid
- Gitlab::LDAP::Person.normalize_dn(super)
+ @uid ||= Gitlab::LDAP::Person.normalize_dn(super)
end
private
diff --git a/lib/gitlab/ldap/user.rb b/lib/gitlab/ldap/user.rb
index 1793097363e..4d5c67ed892 100644
--- a/lib/gitlab/ldap/user.rb
+++ b/lib/gitlab/ldap/user.rb
@@ -9,10 +9,11 @@ module Gitlab
class User < Gitlab::OAuth::User
class << self
def find_by_uid_and_provider(uid, provider)
- # LDAP distinguished name is case-insensitive
+ uid = Gitlab::LDAP::Person.normalize_dn(uid)
+
identity = ::Identity
.where(provider: provider)
- .iwhere(extern_uid: uid).last
+ .where(extern_uid: uid).last
identity && identity.user
end
end
diff --git a/lib/gitlab/logger.rb b/lib/gitlab/logger.rb
index 6bffd410ed0..a42e312b5d3 100644
--- a/lib/gitlab/logger.rb
+++ b/lib/gitlab/logger.rb
@@ -13,7 +13,7 @@ module Gitlab
end
def self.read_latest
- path = Rails.root.join("log", file_name)
+ path = self.full_log_path
return [] unless File.readable?(path)
@@ -22,7 +22,15 @@ module Gitlab
end
def self.build
- new(Rails.root.join("log", file_name))
+ RequestStore[self.cache_key] ||= new(self.full_log_path)
+ end
+
+ def self.full_log_path
+ Rails.root.join("log", file_name)
+ end
+
+ def self.cache_key
+ 'logger:'.freeze + self.full_log_path.to_s
end
end
end
diff --git a/lib/gitlab/performance_bar/peek_query_tracker.rb b/lib/gitlab/performance_bar/peek_query_tracker.rb
index 67fee8c227d..69e117f1da9 100644
--- a/lib/gitlab/performance_bar/peek_query_tracker.rb
+++ b/lib/gitlab/performance_bar/peek_query_tracker.rb
@@ -36,8 +36,8 @@ module Gitlab
end
def track_query(raw_query, bindings, start, finish)
- query = Gitlab::Sherlock::Query.new(raw_query, start, finish)
- query_info = { duration: query.duration.round(3), sql: query.formatted_query }
+ duration = finish - start
+ query_info = { duration: duration.round(3), sql: raw_query }
PEEK_DB_CLIENT.query_details << query_info
end
diff --git a/lib/omni_auth/strategies/bitbucket.rb b/lib/omni_auth/strategies/bitbucket.rb
index 5a7d67c2390..ce1bdfe6ee4 100644
--- a/lib/omni_auth/strategies/bitbucket.rb
+++ b/lib/omni_auth/strategies/bitbucket.rb
@@ -36,6 +36,10 @@ module OmniAuth
email_response = access_token.get('api/2.0/user/emails').parsed
@emails ||= email_response && email_response['values'] || nil
end
+
+ def callback_url
+ options[:redirect_uri] || (full_host + script_name + callback_path)
+ end
end
end
end
diff --git a/lib/peek/views/gitaly.rb b/lib/peek/views/gitaly.rb
new file mode 100644
index 00000000000..d519d8e86fa
--- /dev/null
+++ b/lib/peek/views/gitaly.rb
@@ -0,0 +1,34 @@
+module Peek
+ module Views
+ class Gitaly < View
+ def duration
+ ::Gitlab::GitalyClient.query_time
+ end
+
+ def calls
+ ::Gitlab::GitalyClient.get_request_count
+ end
+
+ def results
+ { duration: formatted_duration, calls: calls }
+ end
+
+ private
+
+ def formatted_duration
+ ms = duration * 1000
+ if ms >= 1000
+ "%.2fms" % ms
+ else
+ "%.0fms" % ms
+ end
+ end
+
+ def setup_subscribers
+ subscribe 'start_processing.action_controller' do
+ ::Gitlab::GitalyClient.query_time = 0
+ end
+ end
+ end
+ end
+end
diff --git a/lib/system_check/app/ruby_version_check.rb b/lib/system_check/app/ruby_version_check.rb
index 08a2c495bd4..57bbabece1f 100644
--- a/lib/system_check/app/ruby_version_check.rb
+++ b/lib/system_check/app/ruby_version_check.rb
@@ -5,7 +5,7 @@ module SystemCheck
set_check_pass -> { "yes (#{self.current_version})" }
def self.required_version
- @required_version ||= Gitlab::VersionInfo.new(2, 3, 3)
+ @required_version ||= Gitlab::VersionInfo.new(2, 3, 5)
end
def self.current_version
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 1f356a231b0..08f6212d997 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -8,8 +8,8 @@ msgid ""
msgstr ""
"Project-Id-Version: gitlab 1.0.0\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2017-10-10 17:50+0200\n"
-"PO-Revision-Date: 2017-10-10 17:50+0200\n"
+"POT-Creation-Date: 2017-10-22 16:40+0300\n"
+"PO-Revision-Date: 2017-10-22 16:40+0300\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
@@ -106,6 +106,12 @@ msgstr ""
msgid "Add new directory"
msgstr ""
+msgid "AdminHealthPageLink|health page"
+msgstr ""
+
+msgid "Advanced settings"
+msgstr ""
+
msgid "All"
msgstr ""
@@ -127,6 +133,9 @@ msgstr ""
msgid "Are you sure you want to discard your changes?"
msgstr ""
+msgid "Are you sure you want to leave this group?"
+msgstr ""
+
msgid "Are you sure you want to reset registration token?"
msgstr ""
@@ -160,18 +169,21 @@ msgstr ""
msgid "AutoDevOps|Auto DevOps (Beta)"
msgstr ""
-msgid "AutoDevOps|Auto DevOps can be activated for this project. It will automatically build, test, and deploy your application based on a predefined CI/CD configuration."
-msgstr ""
-
msgid "AutoDevOps|Auto DevOps documentation"
msgstr ""
msgid "AutoDevOps|Enable in settings"
msgstr ""
+msgid "AutoDevOps|It will automatically build, test, and deploy your application based on a predefined CI/CD configuration."
+msgstr ""
+
msgid "AutoDevOps|Learn more in the %{link_to_documentation}"
msgstr ""
+msgid "AutoDevOps|You can activate %{link_to_settings} for this project."
+msgstr ""
+
msgid "Branch"
msgid_plural "Branches"
msgstr[0] ""
@@ -180,6 +192,9 @@ msgstr[1] ""
msgid "Branch <strong>%{branch_name}</strong> was created. To set up auto deploy, choose a GitLab CI Yaml template and commit your changes. %{link_to_autodeploy_doc}"
msgstr ""
+msgid "Branch has changed"
+msgstr ""
+
msgid "BranchSwitcherPlaceholder|Search branches"
msgstr ""
@@ -375,6 +390,9 @@ msgstr ""
msgid "CiStatus|running"
msgstr ""
+msgid "CircuitBreakerApiLink|circuitbreaker api"
+msgstr ""
+
msgid "Clone repository"
msgstr ""
@@ -384,6 +402,9 @@ msgstr ""
msgid "ClusterIntegration|A %{link_to_container_project} must have been created under this account"
msgstr ""
+msgid "ClusterIntegration|Cluster details"
+msgstr ""
+
msgid "ClusterIntegration|Cluster integration"
msgstr ""
@@ -435,6 +456,9 @@ msgstr ""
msgid "ClusterIntegration|Make sure your account %{link_to_requirements} to create clusters"
msgstr ""
+msgid "ClusterIntegration|Manage Cluster integration on your GitLab project"
+msgstr ""
+
msgid "ClusterIntegration|Manage your cluster by visiting %{link_gke}"
msgstr ""
@@ -459,7 +483,7 @@ msgstr ""
msgid "ClusterIntegration|Removing cluster integration will remove the cluster configuration you have added to this project. It will not delete your project."
msgstr ""
-msgid "ClusterIntegration|Save"
+msgid "ClusterIntegration|See and edit the details for your cluster"
msgstr ""
msgid "ClusterIntegration|See machine types"
@@ -614,6 +638,9 @@ msgstr ""
msgid "Create merge request"
msgstr ""
+msgid "Create new branch"
+msgstr ""
+
msgid "Create new..."
msgstr ""
@@ -1021,6 +1048,9 @@ msgstr ""
msgid "Login"
msgstr ""
+msgid "Maximum git storage failures"
+msgstr ""
+
msgid "Median"
msgstr ""
@@ -1347,6 +1377,9 @@ msgstr ""
msgid "Profiles|your account"
msgstr ""
+msgid "Project '%{project_name}' is in the process of being deleted."
+msgstr ""
+
msgid "Project '%{project_name}' queued for deletion."
msgstr ""
@@ -1356,9 +1389,6 @@ msgstr ""
msgid "Project '%{project_name}' was successfully updated."
msgstr ""
-msgid "Project '%{project_name}' will be deleted."
-msgstr ""
-
msgid "Project access must be granted explicitly to each user."
msgstr ""
@@ -1494,6 +1524,9 @@ msgstr ""
msgid "SSH Keys"
msgstr ""
+msgid "Save"
+msgstr ""
+
msgid "Save changes"
msgstr ""
@@ -1512,6 +1545,15 @@ msgstr ""
msgid "Search branches and tags"
msgstr ""
+msgid "Seconds before reseting failure information"
+msgstr ""
+
+msgid "Seconds to wait after a storage failure"
+msgstr ""
+
+msgid "Seconds to wait for a storage access attempt"
+msgstr ""
+
msgid "Select Archive Format"
msgstr ""
@@ -1714,6 +1756,9 @@ msgstr ""
msgid "The issue stage shows the time it takes from creating an issue to assigning the issue to a milestone, or add the issue to a list on your Issue Board. Begin creating issues to see data for this stage."
msgstr ""
+msgid "The number of failures of after which GitLab will completely prevent access to the storage. The number of failures can be reset in the admin interface: %{link_to_health_page} or using the %{api_documentation_link}."
+msgstr ""
+
msgid "The phase of the development lifecycle."
msgstr ""
@@ -1744,6 +1789,12 @@ msgstr ""
msgid "The testing stage shows the time GitLab CI takes to run every pipeline for the related merge request. The data will automatically be added after your first pipeline finishes running."
msgstr ""
+msgid "The time in seconds GitLab will keep failure information. When no failures occur during this time, information about the mount is reset."
+msgstr ""
+
+msgid "The time in seconds GitLab will try to access storage. After this time a timeout error will be raised."
+msgstr ""
+
msgid "The time taken by each data entry gathered by that stage."
msgstr ""
@@ -1753,6 +1804,9 @@ msgstr ""
msgid "There are problems accessing Git storage: "
msgstr ""
+msgid "This branch has changed since you started editing. Would you like to create a new branch?"
+msgstr ""
+
msgid "This is a confidential issue."
msgstr ""
@@ -1976,6 +2030,9 @@ msgstr ""
msgid "We don't have enough data to show this stage."
msgstr ""
+msgid "When access to a storage fails. GitLab will prevent access to the storage for the time specified here. This allows the filesystem to recover. Repositories on failing shards are temporarly unavailable"
+msgstr ""
+
msgid "Wiki"
msgstr ""
diff --git a/package.json b/package.json
index 057cd8f7bc7..0a1f5c8d081 100644
--- a/package.json
+++ b/package.json
@@ -13,6 +13,7 @@
"webpack-prod": "NODE_ENV=production webpack --config config/webpack.config.js"
},
"dependencies": {
+ "autosize": "^4.0.0",
"axios": "^0.16.2",
"babel-core": "^6.22.1",
"babel-eslint": "^7.2.1",
@@ -35,6 +36,7 @@
"eslint-plugin-html": "^2.0.1",
"exports-loader": "^0.6.4",
"file-loader": "^0.11.1",
+ "fuzzaldrin-plus": "^0.5.0",
"imports-loader": "^0.7.1",
"jed": "^1.1.1",
"jquery": "^2.2.1",
diff --git a/qa/qa/page/group/show.rb b/qa/qa/page/group/show.rb
index 6987c1f8f85..8080deda675 100644
--- a/qa/qa/page/group/show.rb
+++ b/qa/qa/page/group/show.rb
@@ -2,10 +2,6 @@ module QA
module Page
module Group
class Show < Page::Base
- def go_to_subgroups
- click_link 'Subgroups'
- end
-
def go_to_subgroup(name)
click_link name
end
@@ -15,11 +11,19 @@ module QA
end
def go_to_new_subgroup
- click_on 'New Subgroup'
+ within '.new-project-subgroup' do
+ find('.dropdown-toggle').click
+ find("li[data-value='new-subgroup']").click
+ end
+ find("input[data-action='new-subgroup']").click
end
def go_to_new_project
- click_on 'New Project'
+ within '.new-project-subgroup' do
+ find('.dropdown-toggle').click
+ find("li[data-value='new-project']").click
+ end
+ find("input[data-action='new-project']").click
end
end
end
diff --git a/qa/qa/scenario/gitlab/project/create.rb b/qa/qa/scenario/gitlab/project/create.rb
index 7b614bfdd94..bb3b9e19c0f 100644
--- a/qa/qa/scenario/gitlab/project/create.rb
+++ b/qa/qa/scenario/gitlab/project/create.rb
@@ -15,8 +15,6 @@ module QA
Scenario::Gitlab::Sandbox::Prepare.perform
Page::Group::Show.perform do |page|
- page.go_to_subgroups
-
if page.has_subgroup?(Runtime::Namespace.name)
page.go_to_subgroup(Runtime::Namespace.name)
else
diff --git a/spec/controllers/admin/hooks_controller_spec.rb b/spec/controllers/admin/hooks_controller_spec.rb
index 1d1070e90f4..e6ba596117a 100644
--- a/spec/controllers/admin/hooks_controller_spec.rb
+++ b/spec/controllers/admin/hooks_controller_spec.rb
@@ -20,7 +20,7 @@ describe Admin::HooksController do
post :create, hook: hook_params
- expect(response).to have_http_status(302)
+ expect(response).to have_gitlab_http_status(302)
expect(SystemHook.all.size).to eq(1)
expect(SystemHook.first).to have_attributes(hook_params)
end
diff --git a/spec/controllers/admin/impersonations_controller_spec.rb b/spec/controllers/admin/impersonations_controller_spec.rb
index 8f1f0ba89ff..944680b3f42 100644
--- a/spec/controllers/admin/impersonations_controller_spec.rb
+++ b/spec/controllers/admin/impersonations_controller_spec.rb
@@ -22,7 +22,7 @@ describe Admin::ImpersonationsController do
it "responds with status 404" do
delete :destroy
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it "doesn't sign us in" do
@@ -46,7 +46,7 @@ describe Admin::ImpersonationsController do
it "responds with status 404" do
delete :destroy
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it "doesn't sign us in as the impersonator" do
@@ -65,7 +65,7 @@ describe Admin::ImpersonationsController do
it "responds with status 404" do
delete :destroy
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it "doesn't sign us in as the impersonator" do
diff --git a/spec/controllers/admin/projects_controller_spec.rb b/spec/controllers/admin/projects_controller_spec.rb
index 373260b3978..d5a3c250f31 100644
--- a/spec/controllers/admin/projects_controller_spec.rb
+++ b/spec/controllers/admin/projects_controller_spec.rb
@@ -27,7 +27,7 @@ describe Admin::ProjectsController do
get :index
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response.body).not_to match(pending_delete_project.name)
expect(response.body).to match(project.name)
end
diff --git a/spec/controllers/admin/runners_controller_spec.rb b/spec/controllers/admin/runners_controller_spec.rb
index b5fe40d0510..312dbdd0624 100644
--- a/spec/controllers/admin/runners_controller_spec.rb
+++ b/spec/controllers/admin/runners_controller_spec.rb
@@ -11,7 +11,7 @@ describe Admin::RunnersController do
it 'lists all runners' do
get :index
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
end
@@ -19,13 +19,13 @@ describe Admin::RunnersController do
it 'shows a particular runner' do
get :show, id: runner.id
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it 'shows 404 for unknown runner' do
get :show, id: 0
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -39,7 +39,7 @@ describe Admin::RunnersController do
runner.reload
- expect(response).to have_http_status(302)
+ expect(response).to have_gitlab_http_status(302)
expect(runner.description).to eq(new_desc)
end
end
@@ -48,7 +48,7 @@ describe Admin::RunnersController do
it 'destroys the runner' do
delete :destroy, id: runner.id
- expect(response).to have_http_status(302)
+ expect(response).to have_gitlab_http_status(302)
expect(Ci::Runner.find_by(id: runner.id)).to be_nil
end
end
@@ -63,7 +63,7 @@ describe Admin::RunnersController do
runner.reload
- expect(response).to have_http_status(302)
+ expect(response).to have_gitlab_http_status(302)
expect(runner.active).to eq(true)
end
end
@@ -78,7 +78,7 @@ describe Admin::RunnersController do
runner.reload
- expect(response).to have_http_status(302)
+ expect(response).to have_gitlab_http_status(302)
expect(runner.active).to eq(false)
end
end
diff --git a/spec/controllers/admin/services_controller_spec.rb b/spec/controllers/admin/services_controller_spec.rb
index 249bd948847..701211c2586 100644
--- a/spec/controllers/admin/services_controller_spec.rb
+++ b/spec/controllers/admin/services_controller_spec.rb
@@ -20,7 +20,7 @@ describe Admin::ServicesController do
it 'successfully displays the template' do
get :edit, id: service.id
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
end
end
@@ -46,7 +46,7 @@ describe Admin::ServicesController do
put :update, id: service.id, service: { active: true }
- expect(response).to have_http_status(302)
+ expect(response).to have_gitlab_http_status(302)
end
it 'does not call the propagation worker when service is not active' do
@@ -54,7 +54,7 @@ describe Admin::ServicesController do
put :update, id: service.id, service: { properties: {} }
- expect(response).to have_http_status(302)
+ expect(response).to have_gitlab_http_status(302)
end
end
end
diff --git a/spec/controllers/admin/spam_logs_controller_spec.rb b/spec/controllers/admin/spam_logs_controller_spec.rb
index 585ca31389d..7a96ef6a5cc 100644
--- a/spec/controllers/admin/spam_logs_controller_spec.rb
+++ b/spec/controllers/admin/spam_logs_controller_spec.rb
@@ -14,7 +14,7 @@ describe Admin::SpamLogsController do
it 'lists all spam logs' do
get :index
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
end
@@ -22,14 +22,14 @@ describe Admin::SpamLogsController do
it 'removes only the spam log when removing log' do
expect { delete :destroy, id: first_spam.id }.to change { SpamLog.count }.by(-1)
expect(User.find(user.id)).to be_truthy
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it 'removes user and his spam logs when removing the user' do
delete :destroy, id: first_spam.id, remove_user: true
expect(flash[:notice]).to eq "User #{user.username} was successfully removed."
- expect(response).to have_http_status(302)
+ expect(response).to have_gitlab_http_status(302)
expect(SpamLog.count).to eq(0)
expect { User.find(user.id) }.to raise_error(ActiveRecord::RecordNotFound)
end
@@ -42,7 +42,7 @@ describe Admin::SpamLogsController do
it 'submits the log as ham' do
post :mark_as_ham, id: first_spam.id
- expect(response).to have_http_status(302)
+ expect(response).to have_gitlab_http_status(302)
expect(SpamLog.find(first_spam.id).submitted_as_ham).to be_truthy
end
end
diff --git a/spec/controllers/admin/users_controller_spec.rb b/spec/controllers/admin/users_controller_spec.rb
index 25fe547ff37..f044a068938 100644
--- a/spec/controllers/admin/users_controller_spec.rb
+++ b/spec/controllers/admin/users_controller_spec.rb
@@ -19,7 +19,7 @@ describe Admin::UsersController do
it 'deletes user and ghosts their contributions' do
delete :destroy, id: user.username, format: :json
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(User.exists?(user.id)).to be_falsy
expect(issue.reload.author).to be_ghost
end
@@ -27,7 +27,7 @@ describe Admin::UsersController do
it 'deletes the user and their contributions when hard delete is specified' do
delete :destroy, id: user.username, hard_delete: true, format: :json
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(User.exists?(user.id)).to be_falsy
expect(Issue.exists?(issue.id)).to be_falsy
end
diff --git a/spec/controllers/application_controller_spec.rb b/spec/controllers/application_controller_spec.rb
index 0a3a0f7da18..6802b839eaa 100644
--- a/spec/controllers/application_controller_spec.rb
+++ b/spec/controllers/application_controller_spec.rb
@@ -61,7 +61,7 @@ describe ApplicationController do
context "when the 'private_token' param is populated with the private token" do
it "logs the user in" do
get :index, private_token: user.private_token
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response.body).to eq("authenticated")
end
end
@@ -70,7 +70,7 @@ describe ApplicationController do
it "logs the user in" do
@request.headers['PRIVATE-TOKEN'] = user.private_token
get :index
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response.body).to eq("authenticated")
end
end
@@ -95,7 +95,7 @@ describe ApplicationController do
context "when the 'personal_access_token' param is populated with the personal access token" do
it "logs the user in" do
get :index, private_token: personal_access_token.token
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response.body).to eq('authenticated')
end
end
@@ -104,7 +104,7 @@ describe ApplicationController do
it "logs the user in" do
@request.headers["PRIVATE-TOKEN"] = personal_access_token.token
get :index
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response.body).to eq('authenticated')
end
end
@@ -158,7 +158,7 @@ describe ApplicationController do
it 'returns 200 response' do
get :index, private_token: user.private_token, format: requested_format
- expect(response).to have_http_status 200
+ expect(response).to have_gitlab_http_status 200
end
end
@@ -166,7 +166,7 @@ describe ApplicationController do
it 'returns 404 response' do
get :index, private_token: user.private_token
- expect(response).to have_http_status 404
+ expect(response).to have_gitlab_http_status 404
end
end
end
@@ -183,7 +183,7 @@ describe ApplicationController do
context 'when the request format is atom' do
it "logs the user in" do
get :index, rss_token: user.rss_token, format: :atom
- expect(response).to have_http_status 200
+ expect(response).to have_gitlab_http_status 200
expect(response.body).to eq 'authenticated'
end
end
@@ -191,7 +191,7 @@ describe ApplicationController do
context 'when the request format is not atom' do
it "doesn't log the user in" do
get :index, rss_token: user.rss_token
- expect(response.status).not_to have_http_status 200
+ expect(response.status).not_to have_gitlab_http_status 200
expect(response.body).not_to eq 'authenticated'
end
end
diff --git a/spec/controllers/autocomplete_controller_spec.rb b/spec/controllers/autocomplete_controller_spec.rb
index be27bbb4283..73fff6eb5ca 100644
--- a/spec/controllers/autocomplete_controller_spec.rb
+++ b/spec/controllers/autocomplete_controller_spec.rb
@@ -30,7 +30,7 @@ describe AutocompleteController do
get(:users, project_id: 'unknown')
end
- it { expect(response).to have_http_status(404) }
+ it { expect(response).to have_gitlab_http_status(404) }
end
end
@@ -59,7 +59,7 @@ describe AutocompleteController do
get(:users, group_id: 'unknown')
end
- it { expect(response).to have_http_status(404) }
+ it { expect(response).to have_gitlab_http_status(404) }
end
end
@@ -138,7 +138,7 @@ describe AutocompleteController do
get(:users, project_id: project.id)
end
- it { expect(response).to have_http_status(404) }
+ it { expect(response).to have_gitlab_http_status(404) }
end
describe 'GET #users with unknown project' do
@@ -146,7 +146,7 @@ describe AutocompleteController do
get(:users, project_id: 'unknown')
end
- it { expect(response).to have_http_status(404) }
+ it { expect(response).to have_gitlab_http_status(404) }
end
describe 'GET #users with inaccessible group' do
@@ -155,7 +155,7 @@ describe AutocompleteController do
get(:users, group_id: user.namespace.id)
end
- it { expect(response).to have_http_status(404) }
+ it { expect(response).to have_gitlab_http_status(404) }
end
describe 'GET #users with no project' do
diff --git a/spec/controllers/boards/issues_controller_spec.rb b/spec/controllers/boards/issues_controller_spec.rb
index 5163099cd98..44d504d5852 100644
--- a/spec/controllers/boards/issues_controller_spec.rb
+++ b/spec/controllers/boards/issues_controller_spec.rb
@@ -24,7 +24,7 @@ describe Boards::IssuesController do
it 'returns a not found 404 response' do
list_issues user: user, board: 999, list: list2
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -62,7 +62,7 @@ describe Boards::IssuesController do
it 'returns a not found 404 response' do
list_issues user: user, board: board, list: 999
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -93,7 +93,7 @@ describe Boards::IssuesController do
it 'returns a forbidden 403 response' do
list_issues user: user, board: board, list: list2
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -116,7 +116,7 @@ describe Boards::IssuesController do
it 'returns a successful 200 response' do
create_issue user: user, board: board, list: list1, title: 'New issue'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it 'returns the created issue' do
@@ -131,7 +131,7 @@ describe Boards::IssuesController do
it 'returns an unprocessable entity 422 response' do
create_issue user: user, board: board, list: list1, title: nil
- expect(response).to have_http_status(422)
+ expect(response).to have_gitlab_http_status(422)
end
end
@@ -141,7 +141,7 @@ describe Boards::IssuesController do
create_issue user: user, board: board, list: list, title: 'New issue'
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -149,7 +149,7 @@ describe Boards::IssuesController do
it 'returns a not found 404 response' do
create_issue user: user, board: 999, list: list1, title: 'New issue'
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -157,7 +157,7 @@ describe Boards::IssuesController do
it 'returns a not found 404 response' do
create_issue user: user, board: board, list: 999, title: 'New issue'
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -166,7 +166,7 @@ describe Boards::IssuesController do
it 'returns a forbidden 403 response' do
create_issue user: guest, board: board, list: list1, title: 'New issue'
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -187,7 +187,7 @@ describe Boards::IssuesController do
it 'returns a successful 200 response' do
move user: user, board: board, issue: issue, from_list_id: list1.id, to_list_id: list2.id
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it 'moves issue to the desired list' do
@@ -201,19 +201,19 @@ describe Boards::IssuesController do
it 'returns a unprocessable entity 422 response for invalid lists' do
move user: user, board: board, issue: issue, from_list_id: nil, to_list_id: nil
- expect(response).to have_http_status(422)
+ expect(response).to have_gitlab_http_status(422)
end
it 'returns a not found 404 response for invalid board id' do
move user: user, board: 999, issue: issue, from_list_id: list1.id, to_list_id: list2.id
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'returns a not found 404 response for invalid issue id' do
move user: user, board: board, issue: double(id: 999), from_list_id: list1.id, to_list_id: list2.id
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -227,7 +227,7 @@ describe Boards::IssuesController do
it 'returns a forbidden 403 response' do
move user: guest, board: board, issue: issue, from_list_id: list1.id, to_list_id: list2.id
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
diff --git a/spec/controllers/boards/lists_controller_spec.rb b/spec/controllers/boards/lists_controller_spec.rb
index b11fce0fa58..a2b432af23a 100644
--- a/spec/controllers/boards/lists_controller_spec.rb
+++ b/spec/controllers/boards/lists_controller_spec.rb
@@ -15,7 +15,7 @@ describe Boards::ListsController do
it 'returns a successful 200 response' do
read_board_list user: user, board: board
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response.content_type).to eq 'application/json'
end
@@ -39,7 +39,7 @@ describe Boards::ListsController do
it 'returns a forbidden 403 response' do
read_board_list user: user, board: board
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -60,7 +60,7 @@ describe Boards::ListsController do
it 'returns a successful 200 response' do
create_board_list user: user, board: board, label_id: label.id
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it 'returns the created list' do
@@ -75,7 +75,7 @@ describe Boards::ListsController do
it 'returns a not found 404 response' do
create_board_list user: user, board: board, label_id: nil
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -85,7 +85,7 @@ describe Boards::ListsController do
create_board_list user: user, board: board, label_id: label.id
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -96,7 +96,7 @@ describe Boards::ListsController do
create_board_list user: guest, board: board, label_id: label.id
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -119,7 +119,7 @@ describe Boards::ListsController do
it 'returns a successful 200 response' do
move user: user, board: board, list: planning, position: 1
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it 'moves the list to the desired position' do
@@ -133,7 +133,7 @@ describe Boards::ListsController do
it 'returns an unprocessable entity 422 response' do
move user: user, board: board, list: planning, position: 6
- expect(response).to have_http_status(422)
+ expect(response).to have_gitlab_http_status(422)
end
end
@@ -141,7 +141,7 @@ describe Boards::ListsController do
it 'returns a not found 404 response' do
move user: user, board: board, list: 999, position: 1
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -149,7 +149,7 @@ describe Boards::ListsController do
it 'returns a forbidden 403 response' do
move user: guest, board: board, list: planning, position: 6
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -172,7 +172,7 @@ describe Boards::ListsController do
it 'returns a successful 200 response' do
remove_board_list user: user, board: board, list: planning
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it 'removes list from board' do
@@ -184,7 +184,7 @@ describe Boards::ListsController do
it 'returns a not found 404 response' do
remove_board_list user: user, board: board, list: 999
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -192,7 +192,7 @@ describe Boards::ListsController do
it 'returns a forbidden 403 response' do
remove_board_list user: guest, board: board, list: planning
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -212,7 +212,7 @@ describe Boards::ListsController do
it 'returns a successful 200 response' do
generate_default_lists user: user, board: board
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it 'returns the defaults lists' do
@@ -228,7 +228,7 @@ describe Boards::ListsController do
generate_default_lists user: user, board: board
- expect(response).to have_http_status(422)
+ expect(response).to have_gitlab_http_status(422)
end
end
@@ -236,7 +236,7 @@ describe Boards::ListsController do
it 'returns a forbidden 403 response' do
generate_default_lists user: guest, board: board
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
diff --git a/spec/controllers/dashboard/milestones_controller_spec.rb b/spec/controllers/dashboard/milestones_controller_spec.rb
index 2dcb67d50f4..2f3d7be9abe 100644
--- a/spec/controllers/dashboard/milestones_controller_spec.rb
+++ b/spec/controllers/dashboard/milestones_controller_spec.rb
@@ -32,7 +32,7 @@ describe Dashboard::MilestonesController do
it 'shows milestone page' do
view_milestone
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
end
end
diff --git a/spec/controllers/dashboard/todos_controller_spec.rb b/spec/controllers/dashboard/todos_controller_spec.rb
index 9df4ebf2fa0..d862e1447e3 100644
--- a/spec/controllers/dashboard/todos_controller_spec.rb
+++ b/spec/controllers/dashboard/todos_controller_spec.rb
@@ -18,19 +18,19 @@ describe Dashboard::TodosController do
get :index, project_id: unauthorized_project.id
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'renders 404 when given project does not exists' do
get :index, project_id: 999
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'renders 200 when filtering for "any project" todos' do
get :index, project_id: ''
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it 'renders 200 when user has access on given project' do
@@ -38,7 +38,7 @@ describe Dashboard::TodosController do
get :index, project_id: authorized_project.id
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
end
@@ -61,7 +61,7 @@ describe Dashboard::TodosController do
get :index, page: last_page
expect(assigns(:todos).current_page).to eq(last_page)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it 'does not redirect to external sites when provided a host field' do
@@ -104,7 +104,7 @@ describe Dashboard::TodosController do
patch :restore, id: todo.id
expect(todo.reload).to be_pending
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to eq({ "count" => "1", "done_count" => "0" })
end
end
@@ -118,7 +118,7 @@ describe Dashboard::TodosController do
todos.each do |todo|
expect(todo.reload).to be_pending
end
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to eq({ 'count' => '2', 'done_count' => '0' })
end
end
diff --git a/spec/controllers/groups/group_members_controller_spec.rb b/spec/controllers/groups/group_members_controller_spec.rb
index cce53f6697c..9c6d584f59b 100644
--- a/spec/controllers/groups/group_members_controller_spec.rb
+++ b/spec/controllers/groups/group_members_controller_spec.rb
@@ -8,7 +8,7 @@ describe Groups::GroupMembersController do
it 'renders index with 200 status code' do
get :index, group_id: group
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to render_template(:index)
end
end
@@ -30,7 +30,7 @@ describe Groups::GroupMembersController do
user_ids: group_user.id,
access_level: Gitlab::Access::GUEST
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
expect(group.users).not_to include group_user
end
end
@@ -73,7 +73,7 @@ describe Groups::GroupMembersController do
it 'returns 403' do
delete :destroy, group_id: group, id: 42
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -86,7 +86,7 @@ describe Groups::GroupMembersController do
it 'returns 403' do
delete :destroy, group_id: group, id: member
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
expect(group.members).to include member
end
end
@@ -123,7 +123,7 @@ describe Groups::GroupMembersController do
it 'returns 404' do
delete :leave, group_id: group
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -144,7 +144,7 @@ describe Groups::GroupMembersController do
it 'supports json request' do
delete :leave, group_id: group, format: :json
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['notice']).to eq "You left the \"#{group.name}\" group."
end
end
@@ -157,7 +157,7 @@ describe Groups::GroupMembersController do
it 'cannot removes himself from the group' do
delete :leave, group_id: group
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -204,7 +204,7 @@ describe Groups::GroupMembersController do
it 'returns 403' do
post :approve_access_request, group_id: group, id: 42
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -217,7 +217,7 @@ describe Groups::GroupMembersController do
it 'returns 403' do
post :approve_access_request, group_id: group, id: member
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
expect(group.members).not_to include member
end
end
diff --git a/spec/controllers/groups/labels_controller_spec.rb b/spec/controllers/groups/labels_controller_spec.rb
index 899d8ebd12b..da54aa9054c 100644
--- a/spec/controllers/groups/labels_controller_spec.rb
+++ b/spec/controllers/groups/labels_controller_spec.rb
@@ -16,7 +16,7 @@ describe Groups::LabelsController do
post :toggle_subscription, group_id: group.to_param, id: label.to_param
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
end
end
diff --git a/spec/controllers/groups/milestones_controller_spec.rb b/spec/controllers/groups/milestones_controller_spec.rb
index fbbc67f3ae0..c1aba46be04 100644
--- a/spec/controllers/groups/milestones_controller_spec.rb
+++ b/spec/controllers/groups/milestones_controller_spec.rb
@@ -35,7 +35,7 @@ describe Groups::MilestonesController do
it 'shows group milestones page' do
get :index, group_id: group.to_param
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
context 'as JSON' do
@@ -51,7 +51,7 @@ describe Groups::MilestonesController do
expect(milestones.count).to eq(2)
expect(milestones.first["title"]).to eq("group milestone")
expect(milestones.second["title"]).to eq("legacy")
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response.content_type).to eq 'application/json'
end
end
@@ -153,7 +153,7 @@ describe Groups::MilestonesController do
it 'does not redirect' do
get :index, group_id: group.to_param
- expect(response).not_to have_http_status(301)
+ expect(response).not_to have_gitlab_http_status(301)
end
end
@@ -172,7 +172,7 @@ describe Groups::MilestonesController do
it 'does not redirect' do
get :show, group_id: group.to_param, id: title
- expect(response).not_to have_http_status(301)
+ expect(response).not_to have_gitlab_http_status(301)
end
end
@@ -242,7 +242,7 @@ describe Groups::MilestonesController do
group_id: group.to_param,
milestone: { title: title }
- expect(response).not_to have_http_status(404)
+ expect(response).not_to have_gitlab_http_status(404)
end
it 'does not redirect to the correct casing' do
@@ -250,7 +250,7 @@ describe Groups::MilestonesController do
group_id: group.to_param,
milestone: { title: title }
- expect(response).not_to have_http_status(301)
+ expect(response).not_to have_gitlab_http_status(301)
end
end
@@ -262,7 +262,7 @@ describe Groups::MilestonesController do
group_id: redirect_route.path,
milestone: { title: title }
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
diff --git a/spec/controllers/groups/settings/ci_cd_controller_spec.rb b/spec/controllers/groups/settings/ci_cd_controller_spec.rb
index 2e0efb57c74..e9f0924caba 100644
--- a/spec/controllers/groups/settings/ci_cd_controller_spec.rb
+++ b/spec/controllers/groups/settings/ci_cd_controller_spec.rb
@@ -13,7 +13,7 @@ describe Groups::Settings::CiCdController do
it 'renders show with 200 status code' do
get :show, group_id: group
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to render_template(:show)
end
end
diff --git a/spec/controllers/groups/variables_controller_spec.rb b/spec/controllers/groups/variables_controller_spec.rb
index 02f2fa46047..8ea98cd9e8f 100644
--- a/spec/controllers/groups/variables_controller_spec.rb
+++ b/spec/controllers/groups/variables_controller_spec.rb
@@ -48,7 +48,7 @@ describe Groups::VariablesController do
post :update, group_id: group,
id: variable.id, variable: { key: '?', value: variable.value }
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to render_template :show
end
end
diff --git a/spec/controllers/groups_controller_spec.rb b/spec/controllers/groups_controller_spec.rb
index e7631d4d709..a9cfd964dd5 100644
--- a/spec/controllers/groups_controller_spec.rb
+++ b/spec/controllers/groups_controller_spec.rb
@@ -32,6 +32,31 @@ describe GroupsController do
end
end
+ describe 'GET #show' do
+ before do
+ sign_in(user)
+ project
+ end
+
+ context 'as html' do
+ it 'assigns whether or not a group has children' do
+ get :show, id: group.to_param
+
+ expect(assigns(:has_children)).to be_truthy
+ end
+ end
+
+ context 'as atom' do
+ it 'assigns events for all the projects in the group' do
+ create(:event, project: project)
+
+ get :show, id: group.to_param, format: :atom
+
+ expect(assigns(:events)).not_to be_empty
+ end
+ end
+ end
+
describe 'GET #new' do
context 'when creating subgroups', :nested_groups do
[true, false].each do |can_create_group_status|
@@ -238,7 +263,7 @@ describe GroupsController do
it 'updates the path successfully' do
post :update, id: group.to_param, group: { path: 'new_path' }
- expect(response).to have_http_status(302)
+ expect(response).to have_gitlab_http_status(302)
expect(controller).to set_flash[:notice]
end
@@ -309,7 +334,7 @@ describe GroupsController do
it 'does not redirect' do
get :issues, id: group.to_param
- expect(response).not_to have_http_status(301)
+ expect(response).not_to have_gitlab_http_status(301)
end
end
@@ -328,7 +353,7 @@ describe GroupsController do
it 'does not redirect' do
get :show, id: group.to_param
- expect(response).not_to have_http_status(301)
+ expect(response).not_to have_gitlab_http_status(301)
end
end
@@ -395,13 +420,13 @@ describe GroupsController do
it 'does not 404' do
post :update, id: group.to_param.upcase, group: { path: 'new_path' }
- expect(response).not_to have_http_status(404)
+ expect(response).not_to have_gitlab_http_status(404)
end
it 'does not redirect to the correct casing' do
post :update, id: group.to_param.upcase, group: { path: 'new_path' }
- expect(response).not_to have_http_status(301)
+ expect(response).not_to have_gitlab_http_status(301)
end
end
@@ -411,7 +436,7 @@ describe GroupsController do
it 'returns not found' do
post :update, id: redirect_route.path, group: { path: 'new_path' }
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -421,13 +446,13 @@ describe GroupsController do
it 'does not 404' do
delete :destroy, id: group.to_param.upcase
- expect(response).not_to have_http_status(404)
+ expect(response).not_to have_gitlab_http_status(404)
end
it 'does not redirect to the correct casing' do
delete :destroy, id: group.to_param.upcase
- expect(response).not_to have_http_status(301)
+ expect(response).not_to have_gitlab_http_status(301)
end
end
@@ -437,7 +462,7 @@ describe GroupsController do
it 'returns not found' do
delete :destroy, id: redirect_route.path
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
diff --git a/spec/controllers/health_check_controller_spec.rb b/spec/controllers/health_check_controller_spec.rb
index 03da6287774..2cead1770c9 100644
--- a/spec/controllers/health_check_controller_spec.rb
+++ b/spec/controllers/health_check_controller_spec.rb
@@ -100,7 +100,7 @@ describe HealthCheckController do
it 'supports failure plaintext response' do
get :index
- expect(response).to have_http_status(500)
+ expect(response).to have_gitlab_http_status(500)
expect(response.content_type).to eq 'text/plain'
expect(response.body).to include('The server is on fire')
end
@@ -108,7 +108,7 @@ describe HealthCheckController do
it 'supports failure json response' do
get :index, format: :json
- expect(response).to have_http_status(500)
+ expect(response).to have_gitlab_http_status(500)
expect(response.content_type).to eq 'application/json'
expect(json_response['healthy']).to be false
expect(json_response['message']).to include('The server is on fire')
@@ -117,7 +117,7 @@ describe HealthCheckController do
it 'supports failure xml response' do
get :index, format: :xml
- expect(response).to have_http_status(500)
+ expect(response).to have_gitlab_http_status(500)
expect(response.content_type).to eq 'application/xml'
expect(xml_response['healthy']).to be false
expect(xml_response['message']).to include('The server is on fire')
@@ -126,7 +126,7 @@ describe HealthCheckController do
it 'supports failure responses for specific checks' do
get :index, checks: 'email', format: :json
- expect(response).to have_http_status(500)
+ expect(response).to have_gitlab_http_status(500)
expect(response.content_type).to eq 'application/json'
expect(json_response['healthy']).to be false
expect(json_response['message']).to include('Email is on fire')
diff --git a/spec/controllers/help_controller_spec.rb b/spec/controllers/help_controller_spec.rb
index d3489324a9c..f75048f422c 100644
--- a/spec/controllers/help_controller_spec.rb
+++ b/spec/controllers/help_controller_spec.rb
@@ -100,7 +100,7 @@ describe HelpController do
context 'for UI Development Kit' do
it 'renders found' do
get :ui
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
end
end
diff --git a/spec/controllers/invites_controller_spec.rb b/spec/controllers/invites_controller_spec.rb
index e00403118a0..6c09ca7dc66 100644
--- a/spec/controllers/invites_controller_spec.rb
+++ b/spec/controllers/invites_controller_spec.rb
@@ -15,7 +15,7 @@ describe InvitesController do
get :accept, id: token
member.reload
- expect(response).to have_http_status(302)
+ expect(response).to have_gitlab_http_status(302)
expect(member.user).to eq(user)
expect(flash[:notice]).to include 'You have been granted'
end
@@ -26,7 +26,7 @@ describe InvitesController do
get :decline, id: token
expect {member.reload}.to raise_error ActiveRecord::RecordNotFound
- expect(response).to have_http_status(302)
+ expect(response).to have_gitlab_http_status(302)
expect(flash[:notice]).to include 'You have declined the invitation to join'
end
end
diff --git a/spec/controllers/notification_settings_controller_spec.rb b/spec/controllers/notification_settings_controller_spec.rb
index bef815ee1f7..9014b8b5084 100644
--- a/spec/controllers/notification_settings_controller_spec.rb
+++ b/spec/controllers/notification_settings_controller_spec.rb
@@ -110,7 +110,7 @@ describe NotificationSettingsController do
project_id: private_project.id,
notification_setting: { level: :participating }
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -172,7 +172,7 @@ describe NotificationSettingsController do
id: notification_setting,
notification_setting: { level: :participating }
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
diff --git a/spec/controllers/oauth/applications_controller_spec.rb b/spec/controllers/oauth/applications_controller_spec.rb
index 552899eb36c..b38652e7ab9 100644
--- a/spec/controllers/oauth/applications_controller_spec.rb
+++ b/spec/controllers/oauth/applications_controller_spec.rb
@@ -12,7 +12,7 @@ describe Oauth::ApplicationsController do
it 'shows list of applications' do
get :index
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it 'redirects back to profile page if OAuth applications are disabled' do
@@ -21,7 +21,7 @@ describe Oauth::ApplicationsController do
get :index
- expect(response).to have_http_status(302)
+ expect(response).to have_gitlab_http_status(302)
expect(response).to redirect_to(profile_path)
end
end
diff --git a/spec/controllers/oauth/authorizations_controller_spec.rb b/spec/controllers/oauth/authorizations_controller_spec.rb
index ac7f73c6e81..004b463e745 100644
--- a/spec/controllers/oauth/authorizations_controller_spec.rb
+++ b/spec/controllers/oauth/authorizations_controller_spec.rb
@@ -28,7 +28,7 @@ describe Oauth::AuthorizationsController do
it 'returns 200 code and renders error view' do
get :new
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to render_template('doorkeeper/authorizations/error')
end
end
@@ -37,7 +37,7 @@ describe Oauth::AuthorizationsController do
it 'returns 200 code and renders view' do
get :new, params
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to render_template('doorkeeper/authorizations/new')
end
@@ -48,7 +48,7 @@ describe Oauth::AuthorizationsController do
get :new, params
expect(request.session['user_return_to']).to be_nil
- expect(response).to have_http_status(302)
+ expect(response).to have_gitlab_http_status(302)
end
end
end
diff --git a/spec/controllers/passwords_controller_spec.rb b/spec/controllers/passwords_controller_spec.rb
index cdaa88bbf5d..8778bff1190 100644
--- a/spec/controllers/passwords_controller_spec.rb
+++ b/spec/controllers/passwords_controller_spec.rb
@@ -12,7 +12,7 @@ describe PasswordsController do
post :create
- expect(response).to have_http_status(302)
+ expect(response).to have_gitlab_http_status(302)
end
end
diff --git a/spec/controllers/profiles/accounts_controller_spec.rb b/spec/controllers/profiles/accounts_controller_spec.rb
index d387aba227b..f8d9d7e39ee 100644
--- a/spec/controllers/profiles/accounts_controller_spec.rb
+++ b/spec/controllers/profiles/accounts_controller_spec.rb
@@ -11,7 +11,7 @@ describe Profiles::AccountsController do
it 'renders 404 if someone tries to unlink a non existent provider' do
delete :unlink, provider: 'github'
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
[:saml, :cas3].each do |provider|
@@ -23,7 +23,7 @@ describe Profiles::AccountsController do
delete :unlink, provider: provider.to_s
- expect(response).to have_http_status(302)
+ expect(response).to have_gitlab_http_status(302)
expect(user.reload.identities).to include(identity)
end
end
@@ -38,7 +38,7 @@ describe Profiles::AccountsController do
delete :unlink, provider: provider.to_s
- expect(response).to have_http_status(302)
+ expect(response).to have_gitlab_http_status(302)
expect(user.reload.identities).not_to include(identity)
end
end
diff --git a/spec/controllers/projects/artifacts_controller_spec.rb b/spec/controllers/projects/artifacts_controller_spec.rb
index d0992719171..d1051741430 100644
--- a/spec/controllers/projects/artifacts_controller_spec.rb
+++ b/spec/controllers/projects/artifacts_controller_spec.rb
@@ -60,7 +60,7 @@ describe Projects::ArtifactsController do
it 'renders the file view' do
get :file, namespace_id: project.namespace, project_id: project, job_id: job, path: 'ci_artifacts.txt'
- expect(response).to have_http_status(302)
+ expect(response).to have_gitlab_http_status(302)
end
end
@@ -78,7 +78,7 @@ describe Projects::ArtifactsController do
it 'renders the file view' do
get :file, namespace_id: project.namespace, project_id: project, job_id: job, path: 'ci_artifacts.txt'
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
expect(response).to render_template('projects/artifacts/file')
end
end
@@ -106,7 +106,7 @@ describe Projects::ArtifactsController do
it 'does not redirect the request' do
get :file, namespace_id: private_project.namespace, project_id: private_project, job_id: job, path: 'ci_artifacts.txt'
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
expect(response).to render_template('projects/artifacts/file')
end
end
@@ -143,7 +143,7 @@ describe Projects::ArtifactsController do
context 'cannot find the job' do
shared_examples 'not found' do
- it { expect(response).to have_http_status(:not_found) }
+ it { expect(response).to have_gitlab_http_status(:not_found) }
end
context 'has no such ref' do
diff --git a/spec/controllers/projects/badges_controller_spec.rb b/spec/controllers/projects/badges_controller_spec.rb
index d68200164e4..e7cddf8cfbf 100644
--- a/spec/controllers/projects/badges_controller_spec.rb
+++ b/spec/controllers/projects/badges_controller_spec.rb
@@ -13,13 +13,13 @@ describe Projects::BadgesController do
it 'requests the pipeline badge successfully' do
get_badge(:pipeline)
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
end
it 'requests the coverage badge successfully' do
get_badge(:coverage)
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
end
def get_badge(badge)
diff --git a/spec/controllers/projects/blame_controller_spec.rb b/spec/controllers/projects/blame_controller_spec.rb
index c086b386381..54282aa4001 100644
--- a/spec/controllers/projects/blame_controller_spec.rb
+++ b/spec/controllers/projects/blame_controller_spec.rb
@@ -28,7 +28,7 @@ describe Projects::BlameController do
context "invalid file" do
let(:id) { 'master/files/ruby/missing_file.rb'}
- it { expect(response).to have_http_status(404) }
+ it { expect(response).to have_gitlab_http_status(404) }
end
end
end
diff --git a/spec/controllers/projects/blob_controller_spec.rb b/spec/controllers/projects/blob_controller_spec.rb
index fb76b7fdf38..6a1c07b4a0b 100644
--- a/spec/controllers/projects/blob_controller_spec.rb
+++ b/spec/controllers/projects/blob_controller_spec.rb
@@ -153,7 +153,7 @@ describe Projects::BlobController do
end
it 'redirects to blob show' do
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
end
@@ -167,7 +167,7 @@ describe Projects::BlobController do
end
it 'redirects to blob show' do
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
end
end
diff --git a/spec/controllers/projects/boards_controller_spec.rb b/spec/controllers/projects/boards_controller_spec.rb
index 9e2e9a39481..84cde33d944 100644
--- a/spec/controllers/projects/boards_controller_spec.rb
+++ b/spec/controllers/projects/boards_controller_spec.rb
@@ -45,7 +45,7 @@ describe Projects::BoardsController do
it 'returns a not found 404 response' do
list_boards
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -85,7 +85,7 @@ describe Projects::BoardsController do
it 'returns a not found 404 response' do
read_board board: board
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -95,7 +95,7 @@ describe Projects::BoardsController do
read_board board: another_board
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
diff --git a/spec/controllers/projects/branches_controller_spec.rb b/spec/controllers/projects/branches_controller_spec.rb
index 3b3b63444c7..973d6fed288 100644
--- a/spec/controllers/projects/branches_controller_spec.rb
+++ b/spec/controllers/projects/branches_controller_spec.rb
@@ -128,7 +128,7 @@ describe Projects::BranchesController do
issue_iid: issue.iid
expect(response.location).to include(project_new_blob_path(project, branch))
- expect(response).to have_http_status(302)
+ expect(response).to have_gitlab_http_status(302)
end
end
@@ -161,7 +161,7 @@ describe Projects::BranchesController do
it 'returns a successful 200 response' do
create_branch name: 'my-branch', ref: 'master'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it 'returns the created branch' do
@@ -175,7 +175,7 @@ describe Projects::BranchesController do
it 'returns an unprocessable entity 422 response' do
create_branch name: "<script>alert('merge');</script>", ref: "<script>alert('ref');</script>"
- expect(response).to have_http_status(422)
+ expect(response).to have_gitlab_http_status(422)
end
end
@@ -202,7 +202,7 @@ describe Projects::BranchesController do
namespace_id: project.namespace,
project_id: project
- expect(response).to have_http_status(303)
+ expect(response).to have_gitlab_http_status(303)
end
end
@@ -226,28 +226,28 @@ describe Projects::BranchesController do
context "valid branch name, valid source" do
let(:branch) { "feature" }
- it { expect(response).to have_http_status(200) }
+ it { expect(response).to have_gitlab_http_status(200) }
it { expect(response.body).to be_blank }
end
context "valid branch name with unencoded slashes" do
let(:branch) { "improve/awesome" }
- it { expect(response).to have_http_status(200) }
+ it { expect(response).to have_gitlab_http_status(200) }
it { expect(response.body).to be_blank }
end
context "valid branch name with encoded slashes" do
let(:branch) { "improve%2Fawesome" }
- it { expect(response).to have_http_status(200) }
+ it { expect(response).to have_gitlab_http_status(200) }
it { expect(response.body).to be_blank }
end
context "invalid branch name, valid ref" do
let(:branch) { "no-branch" }
- it { expect(response).to have_http_status(404) }
+ it { expect(response).to have_gitlab_http_status(404) }
it { expect(response.body).to be_blank }
end
end
@@ -263,7 +263,7 @@ describe Projects::BranchesController do
expect(json_response).to eql("message" => 'Branch was removed')
end
- it { expect(response).to have_http_status(200) }
+ it { expect(response).to have_gitlab_http_status(200) }
end
context 'valid branch name with unencoded slashes' do
@@ -273,7 +273,7 @@ describe Projects::BranchesController do
expect(json_response).to eql('message' => 'Branch was removed')
end
- it { expect(response).to have_http_status(200) }
+ it { expect(response).to have_gitlab_http_status(200) }
end
context "valid branch name with encoded slashes" do
@@ -283,7 +283,7 @@ describe Projects::BranchesController do
expect(json_response).to eql('message' => 'Branch was removed')
end
- it { expect(response).to have_http_status(200) }
+ it { expect(response).to have_gitlab_http_status(200) }
end
context 'invalid branch name, valid ref' do
@@ -293,7 +293,7 @@ describe Projects::BranchesController do
expect(json_response).to eql('message' => 'No such branch')
end
- it { expect(response).to have_http_status(404) }
+ it { expect(response).to have_gitlab_http_status(404) }
end
end
@@ -341,7 +341,7 @@ describe Projects::BranchesController do
it 'responds with status 404' do
destroy_all_merged
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -379,7 +379,7 @@ describe Projects::BranchesController do
project_id: project,
format: :html
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
end
end
diff --git a/spec/controllers/projects/clusters_controller_spec.rb b/spec/controllers/projects/clusters_controller_spec.rb
index 7985028d73b..bd924a1c7be 100644
--- a/spec/controllers/projects/clusters_controller_spec.rb
+++ b/spec/controllers/projects/clusters_controller_spec.rb
@@ -169,7 +169,7 @@ describe Projects::ClustersController do
it "responds with matching schema" do
subject
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
expect(response).to match_response_schema('cluster_status')
end
end
@@ -189,14 +189,14 @@ describe Projects::ClustersController do
it "allows to update cluster" do
subject
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
expect(response.body).to include("Save")
end
it "allows remove integration" do
subject
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
expect(response.body).to include("Remove integration")
end
end
@@ -207,7 +207,7 @@ describe Projects::ClustersController do
it "does not allow to access page" do
subject
- expect(response).to have_http_status(:not_found)
+ expect(response).to have_gitlab_http_status(:not_found)
end
end
end
@@ -251,7 +251,7 @@ describe Projects::ClustersController do
it "rejects changes" do
subject
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
expect(response).to render_template(:show)
end
end
@@ -263,7 +263,7 @@ describe Projects::ClustersController do
it "does not allow to update cluster" do
subject
- expect(response).to have_http_status(:not_found)
+ expect(response).to have_gitlab_http_status(:not_found)
end
end
end
@@ -292,7 +292,7 @@ describe Projects::ClustersController do
it "does not allow to destroy cluster" do
subject
- expect(response).to have_http_status(:not_found)
+ expect(response).to have_gitlab_http_status(:not_found)
end
end
end
diff --git a/spec/controllers/projects/commit_controller_spec.rb b/spec/controllers/projects/commit_controller_spec.rb
index df53863482d..4612fc6e441 100644
--- a/spec/controllers/projects/commit_controller_spec.rb
+++ b/spec/controllers/projects/commit_controller_spec.rb
@@ -157,7 +157,7 @@ describe Projects::CommitController do
id: commit.id)
expect(response).not_to be_success
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -206,7 +206,7 @@ describe Projects::CommitController do
id: master_pickable_commit.id)
expect(response).not_to be_success
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -286,7 +286,7 @@ describe Projects::CommitController do
end
it 'returns a 404' do
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -298,7 +298,7 @@ describe Projects::CommitController do
end
it 'returns a 404' do
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -309,7 +309,7 @@ describe Projects::CommitController do
end
it 'returns a 404' do
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -356,7 +356,7 @@ describe Projects::CommitController do
end
it 'returns a 404' do
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
diff --git a/spec/controllers/projects/compare_controller_spec.rb b/spec/controllers/projects/compare_controller_spec.rb
index b4f9fd9b7a2..fe5818da0bc 100644
--- a/spec/controllers/projects/compare_controller_spec.rb
+++ b/spec/controllers/projects/compare_controller_spec.rb
@@ -133,7 +133,7 @@ describe Projects::CompareController do
end
it 'returns a 404' do
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -145,7 +145,7 @@ describe Projects::CompareController do
end
it 'returns a 404' do
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -156,7 +156,7 @@ describe Projects::CompareController do
end
it 'returns a 404' do
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -166,7 +166,7 @@ describe Projects::CompareController do
end
it 'returns a 404' do
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
diff --git a/spec/controllers/projects/deployments_controller_spec.rb b/spec/controllers/projects/deployments_controller_spec.rb
index 3daff1eeea3..3164fd5c143 100644
--- a/spec/controllers/projects/deployments_controller_spec.rb
+++ b/spec/controllers/projects/deployments_controller_spec.rb
@@ -67,7 +67,7 @@ describe Projects::DeploymentsController do
it 'returns a empty response 204 resposne' do
get :metrics, deployment_params(id: deployment.id)
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
expect(response.body).to eq('')
end
end
@@ -142,7 +142,7 @@ describe Projects::DeploymentsController do
it 'returns a empty response 204 response' do
get :additional_metrics, deployment_params(id: deployment.id, format: :json)
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
expect(response.body).to eq('')
end
end
diff --git a/spec/controllers/projects/discussions_controller_spec.rb b/spec/controllers/projects/discussions_controller_spec.rb
index fe62898fa9b..3bf676637a2 100644
--- a/spec/controllers/projects/discussions_controller_spec.rb
+++ b/spec/controllers/projects/discussions_controller_spec.rb
@@ -25,7 +25,7 @@ describe Projects::DiscussionsController do
it "returns status 404" do
post :resolve, request_params
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -42,7 +42,7 @@ describe Projects::DiscussionsController do
it "returns status 404" do
post :resolve, request_params
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -69,7 +69,7 @@ describe Projects::DiscussionsController do
it "returns status 200" do
post :resolve, request_params
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
end
end
@@ -86,7 +86,7 @@ describe Projects::DiscussionsController do
it "returns status 404" do
delete :unresolve, request_params
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -103,7 +103,7 @@ describe Projects::DiscussionsController do
it "returns status 404" do
delete :unresolve, request_params
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -117,7 +117,7 @@ describe Projects::DiscussionsController do
it "returns status 200" do
delete :unresolve, request_params
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
end
end
diff --git a/spec/controllers/projects/environments_controller_spec.rb b/spec/controllers/projects/environments_controller_spec.rb
index 5a95f4f6199..ff9ab53d8c3 100644
--- a/spec/controllers/projects/environments_controller_spec.rb
+++ b/spec/controllers/projects/environments_controller_spec.rb
@@ -19,7 +19,7 @@ describe Projects::EnvironmentsController do
it 'responds with status code 200' do
get :index, environment_params
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
end
end
@@ -59,7 +59,7 @@ describe Projects::EnvironmentsController do
end
it 'sets the polling interval header' do
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
expect(response.headers['Poll-Interval']).to eq("3000")
end
end
@@ -137,7 +137,7 @@ describe Projects::EnvironmentsController do
params[:id] = 12345
get :show, params
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -155,7 +155,7 @@ describe Projects::EnvironmentsController do
patch_params = environment_params.merge(environment: { external_url: 'https://git.gitlab.com' })
patch :update, patch_params
- expect(response).to have_http_status(302)
+ expect(response).to have_gitlab_http_status(302)
end
end
@@ -166,7 +166,7 @@ describe Projects::EnvironmentsController do
patch :stop, environment_params(format: :json)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -179,7 +179,7 @@ describe Projects::EnvironmentsController do
patch :stop, environment_params(format: :json)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to eq(
{ 'redirect_url' =>
project_job_url(project, action) })
@@ -193,7 +193,7 @@ describe Projects::EnvironmentsController do
patch :stop, environment_params(format: :json)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to eq(
{ 'redirect_url' =>
project_environment_url(project, environment) })
@@ -206,7 +206,7 @@ describe Projects::EnvironmentsController do
it 'responds with a status code 200' do
get :terminal, environment_params
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it 'loads the terminals for the enviroment' do
@@ -220,7 +220,7 @@ describe Projects::EnvironmentsController do
it 'responds with a status code 404' do
get :terminal, environment_params(id: 666)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -244,7 +244,7 @@ describe Projects::EnvironmentsController do
get :terminal_websocket_authorize, environment_params
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response.headers["Content-Type"]).to eq(Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE)
expect(response.body).to eq('{"workhorse":"response"}')
end
@@ -254,7 +254,7 @@ describe Projects::EnvironmentsController do
it 'returns 404' do
get :terminal_websocket_authorize, environment_params(id: 666)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -290,7 +290,7 @@ describe Projects::EnvironmentsController do
it 'returns a metrics JSON document' do
get :metrics, environment_params(format: :json)
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
expect(json_response).to eq({})
end
end
@@ -330,7 +330,7 @@ describe Projects::EnvironmentsController do
it 'returns a metrics JSON document' do
get :additional_metrics, environment_params(format: :json)
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
expect(json_response).to eq({})
end
end
diff --git a/spec/controllers/projects/forks_controller_spec.rb b/spec/controllers/projects/forks_controller_spec.rb
index dc8290c438e..1bedb8ebdff 100644
--- a/spec/controllers/projects/forks_controller_spec.rb
+++ b/spec/controllers/projects/forks_controller_spec.rb
@@ -89,7 +89,7 @@ describe Projects::ForksController do
get_new
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
end
@@ -118,7 +118,7 @@ describe Projects::ForksController do
post_create
- expect(response).to have_http_status(302)
+ expect(response).to have_gitlab_http_status(302)
expect(response).to redirect_to(namespace_project_import_path(user.namespace, project))
end
end
diff --git a/spec/controllers/projects/issues_controller_spec.rb b/spec/controllers/projects/issues_controller_spec.rb
index ed8088a46f0..aecdfb50759 100644
--- a/spec/controllers/projects/issues_controller_spec.rb
+++ b/spec/controllers/projects/issues_controller_spec.rb
@@ -20,7 +20,7 @@ describe Projects::IssuesController do
get :index, namespace_id: project.namespace, project_id: project
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -28,7 +28,7 @@ describe Projects::IssuesController do
it 'renders the "index" template' do
get :index, namespace_id: project.namespace, project_id: project
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to render_template(:index)
end
end
@@ -45,7 +45,7 @@ describe Projects::IssuesController do
it "returns index" do
get :index, namespace_id: project.namespace, project_id: project
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it "returns 301 if request path doesn't match project path" do
@@ -59,7 +59,7 @@ describe Projects::IssuesController do
project.save!
get :index, namespace_id: project.namespace, project_id: project
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -89,7 +89,7 @@ describe Projects::IssuesController do
page: last_page.to_param
expect(assigns(:issues).current_page).to eq(last_page)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it 'does not redirect to external sites when provided a host field' do
@@ -166,7 +166,7 @@ describe Projects::IssuesController do
get :new, namespace_id: project.namespace, project_id: project
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -174,7 +174,7 @@ describe Projects::IssuesController do
it 'renders the "new" template' do
get :new, namespace_id: project.namespace, project_id: project
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to render_template(:new)
end
end
@@ -224,7 +224,7 @@ describe Projects::IssuesController do
it 'moves issue to another project' do
move_issue
- expect(response).to have_http_status :ok
+ expect(response).to have_gitlab_http_status :ok
expect(another_project.issues).not_to be_empty
end
end
@@ -233,7 +233,7 @@ describe Projects::IssuesController do
it 'responds with 404' do
move_issue
- expect(response).to have_http_status :not_found
+ expect(response).to have_gitlab_http_status :not_found
end
end
@@ -329,14 +329,14 @@ describe Projects::IssuesController do
sign_out(:user)
go(id: unescaped_parameter_value.to_param)
- expect(response).to have_http_status :not_found
+ expect(response).to have_gitlab_http_status :not_found
end
it 'returns 404 for non project members' do
sign_in(non_member)
go(id: unescaped_parameter_value.to_param)
- expect(response).to have_http_status :not_found
+ expect(response).to have_gitlab_http_status :not_found
end
it 'returns 404 for project members with guest role' do
@@ -344,21 +344,21 @@ describe Projects::IssuesController do
project.team << [member, :guest]
go(id: unescaped_parameter_value.to_param)
- expect(response).to have_http_status :not_found
+ expect(response).to have_gitlab_http_status :not_found
end
it "returns #{http_status[:success]} for author" do
sign_in(author)
go(id: unescaped_parameter_value.to_param)
- expect(response).to have_http_status http_status[:success]
+ expect(response).to have_gitlab_http_status http_status[:success]
end
it "returns #{http_status[:success]} for assignee" do
sign_in(assignee)
go(id: request_forgery_timing_attack.to_param)
- expect(response).to have_http_status http_status[:success]
+ expect(response).to have_gitlab_http_status http_status[:success]
end
it "returns #{http_status[:success]} for project members" do
@@ -366,14 +366,14 @@ describe Projects::IssuesController do
project.team << [member, :developer]
go(id: unescaped_parameter_value.to_param)
- expect(response).to have_http_status http_status[:success]
+ expect(response).to have_gitlab_http_status http_status[:success]
end
it "returns #{http_status[:success]} for admin" do
sign_in(admin)
go(id: unescaped_parameter_value.to_param)
- expect(response).to have_http_status http_status[:success]
+ expect(response).to have_gitlab_http_status http_status[:success]
end
end
@@ -475,7 +475,7 @@ describe Projects::IssuesController do
it 'returns 422 status' do
update_issue
- expect(response).to have_http_status(422)
+ expect(response).to have_gitlab_http_status(422)
end
end
@@ -495,7 +495,7 @@ describe Projects::IssuesController do
end
it 'returns 200 status' do
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it 'accepts an issue after recaptcha is verified' do
@@ -553,10 +553,33 @@ describe Projects::IssuesController do
it 'returns 200' do
go(id: issue.iid)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
end
end
+
+ describe 'GET #edit' do
+ it_behaves_like 'restricted action', success: 200
+
+ def go(id:)
+ get :edit,
+ namespace_id: project.namespace.to_param,
+ project_id: project,
+ id: id
+ end
+ end
+
+ describe 'PUT #update' do
+ it_behaves_like 'restricted action', success: 302
+
+ def go(id:)
+ put :update,
+ namespace_id: project.namespace.to_param,
+ project_id: project,
+ id: id,
+ issue: { title: 'New title' }
+ end
+ end
end
describe 'POST #create' do
@@ -778,7 +801,7 @@ describe Projects::IssuesController do
it "rejects a developer to destroy an issue" do
delete :destroy, namespace_id: project.namespace, project_id: project, id: issue.iid
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -794,7 +817,7 @@ describe Projects::IssuesController do
it "deletes the issue" do
delete :destroy, namespace_id: project.namespace, project_id: project, id: issue.iid
- expect(response).to have_http_status(302)
+ expect(response).to have_gitlab_http_status(302)
expect(controller).to set_flash[:notice].to(/The issue was successfully deleted\./)
end
@@ -818,7 +841,7 @@ describe Projects::IssuesController do
project_id: project, id: issue.iid, name: "thumbsup")
end.to change { issue.award_emoji.count }.by(1)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
end
diff --git a/spec/controllers/projects/jobs_controller_spec.rb b/spec/controllers/projects/jobs_controller_spec.rb
index d01339a0b88..f9688949a19 100644
--- a/spec/controllers/projects/jobs_controller_spec.rb
+++ b/spec/controllers/projects/jobs_controller_spec.rb
@@ -20,7 +20,7 @@ describe Projects::JobsController do
end
it 'has only pending builds' do
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
expect(assigns(:builds).first.status).to eq('pending')
end
end
@@ -33,7 +33,7 @@ describe Projects::JobsController do
end
it 'has only running jobs' do
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
expect(assigns(:builds).first.status).to eq('running')
end
end
@@ -46,7 +46,7 @@ describe Projects::JobsController do
end
it 'has only finished jobs' do
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
expect(assigns(:builds).first.status).to eq('success')
end
end
@@ -62,7 +62,7 @@ describe Projects::JobsController do
end
it 'redirects to the page' do
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
expect(assigns(:builds).current_page).to eq(last_page)
end
end
@@ -107,7 +107,7 @@ describe Projects::JobsController do
end
it 'has a job' do
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
expect(assigns(:build).id).to eq(job.id)
end
end
@@ -118,7 +118,7 @@ describe Projects::JobsController do
end
it 'renders not_found' do
- expect(response).to have_http_status(:not_found)
+ expect(response).to have_gitlab_http_status(:not_found)
end
end
end
@@ -136,7 +136,7 @@ describe Projects::JobsController do
end
it 'exposes needed information' do
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
expect(json_response['raw_path']).to match(/jobs\/\d+\/raw\z/)
expect(json_response.dig('merge_request', 'path')).to match(/merge_requests\/\d+\z/)
expect(json_response['new_issue_path'])
@@ -163,7 +163,7 @@ describe Projects::JobsController do
let(:job) { create(:ci_build, :trace, pipeline: pipeline) }
it 'returns a trace' do
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
expect(json_response['id']).to eq job.id
expect(json_response['status']).to eq job.status
expect(json_response['html']).to eq('BUILD TRACE')
@@ -174,7 +174,7 @@ describe Projects::JobsController do
let(:job) { create(:ci_build, pipeline: pipeline) }
it 'returns no traces' do
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
expect(json_response['id']).to eq job.id
expect(json_response['status']).to eq job.status
expect(json_response['html']).to be_nil
@@ -185,7 +185,7 @@ describe Projects::JobsController do
let(:job) { create(:ci_build, :unicode_trace, pipeline: pipeline) }
it 'returns a trace with Unicode' do
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
expect(json_response['id']).to eq job.id
expect(json_response['status']).to eq job.status
expect(json_response['html']).to include("ヾ(´༎ຶД༎ຶ`)ノ")
@@ -212,7 +212,7 @@ describe Projects::JobsController do
end
it 'return a detailed job status in json' do
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
expect(json_response['text']).to eq status.text
expect(json_response['label']).to eq status.label
expect(json_response['icon']).to eq status.icon
@@ -232,7 +232,7 @@ describe Projects::JobsController do
let(:job) { create(:ci_build, :retryable, pipeline: pipeline) }
it 'redirects to the retried job page' do
- expect(response).to have_http_status(:found)
+ expect(response).to have_gitlab_http_status(:found)
expect(response).to redirect_to(namespace_project_job_path(id: Ci::Build.last.id))
end
end
@@ -241,7 +241,7 @@ describe Projects::JobsController do
let(:job) { create(:ci_build, pipeline: pipeline) }
it 'renders unprocessable_entity' do
- expect(response).to have_http_status(:unprocessable_entity)
+ expect(response).to have_gitlab_http_status(:unprocessable_entity)
end
end
@@ -268,7 +268,7 @@ describe Projects::JobsController do
let(:job) { create(:ci_build, :playable, pipeline: pipeline) }
it 'redirects to the played job page' do
- expect(response).to have_http_status(:found)
+ expect(response).to have_gitlab_http_status(:found)
expect(response).to redirect_to(namespace_project_job_path(id: job.id))
end
@@ -281,7 +281,7 @@ describe Projects::JobsController do
let(:job) { create(:ci_build, pipeline: pipeline) }
it 'renders unprocessable_entity' do
- expect(response).to have_http_status(:unprocessable_entity)
+ expect(response).to have_gitlab_http_status(:unprocessable_entity)
end
end
@@ -304,7 +304,7 @@ describe Projects::JobsController do
let(:job) { create(:ci_build, :cancelable, pipeline: pipeline) }
it 'redirects to the canceled job page' do
- expect(response).to have_http_status(:found)
+ expect(response).to have_gitlab_http_status(:found)
expect(response).to redirect_to(namespace_project_job_path(id: job.id))
end
@@ -317,7 +317,7 @@ describe Projects::JobsController do
let(:job) { create(:ci_build, :canceled, pipeline: pipeline) }
it 'returns unprocessable_entity' do
- expect(response).to have_http_status(:unprocessable_entity)
+ expect(response).to have_gitlab_http_status(:unprocessable_entity)
end
end
@@ -342,7 +342,7 @@ describe Projects::JobsController do
end
it 'redirects to a index page' do
- expect(response).to have_http_status(:found)
+ expect(response).to have_gitlab_http_status(:found)
expect(response).to redirect_to(namespace_project_jobs_path)
end
@@ -359,7 +359,7 @@ describe Projects::JobsController do
end
it 'redirects to a index page' do
- expect(response).to have_http_status(:found)
+ expect(response).to have_gitlab_http_status(:found)
expect(response).to redirect_to(namespace_project_jobs_path)
end
end
@@ -382,7 +382,7 @@ describe Projects::JobsController do
let(:job) { create(:ci_build, :erasable, :trace, pipeline: pipeline) }
it 'redirects to the erased job page' do
- expect(response).to have_http_status(:found)
+ expect(response).to have_gitlab_http_status(:found)
expect(response).to redirect_to(namespace_project_job_path(id: job.id))
end
@@ -400,7 +400,7 @@ describe Projects::JobsController do
let(:job) { create(:ci_build, :erased, pipeline: pipeline) }
it 'returns unprocessable_entity' do
- expect(response).to have_http_status(:unprocessable_entity)
+ expect(response).to have_gitlab_http_status(:unprocessable_entity)
end
end
@@ -420,7 +420,7 @@ describe Projects::JobsController do
let(:job) { create(:ci_build, :trace, pipeline: pipeline) }
it 'send a trace file' do
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
expect(response.content_type).to eq 'text/plain; charset=utf-8'
expect(response.body).to eq 'BUILD TRACE'
end
@@ -430,7 +430,7 @@ describe Projects::JobsController do
let(:job) { create(:ci_build, pipeline: pipeline) }
it 'returns not_found' do
- expect(response).to have_http_status(:not_found)
+ expect(response).to have_gitlab_http_status(:not_found)
end
end
diff --git a/spec/controllers/projects/labels_controller_spec.rb b/spec/controllers/projects/labels_controller_spec.rb
index f4e2dca883d..cf83f2f3265 100644
--- a/spec/controllers/projects/labels_controller_spec.rb
+++ b/spec/controllers/projects/labels_controller_spec.rb
@@ -78,7 +78,7 @@ describe Projects::LabelsController do
it 'creates labels' do
post :generate, namespace_id: personal_project.namespace.to_param, project_id: personal_project
- expect(response).to have_http_status(302)
+ expect(response).to have_gitlab_http_status(302)
end
end
@@ -86,7 +86,7 @@ describe Projects::LabelsController do
it 'creates labels' do
post :generate, namespace_id: project.namespace.to_param, project_id: project
- expect(response).to have_http_status(302)
+ expect(response).to have_gitlab_http_status(302)
end
end
end
@@ -97,7 +97,7 @@ describe Projects::LabelsController do
toggle_subscription(label)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it 'allows user to toggle subscription on group labels' do
@@ -105,7 +105,7 @@ describe Projects::LabelsController do
toggle_subscription(group_label)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
def toggle_subscription(label)
@@ -121,7 +121,7 @@ describe Projects::LabelsController do
it 'denies access' do
post :promote, namespace_id: project.namespace.to_param, project_id: project, id: label_1.to_param
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -170,7 +170,7 @@ describe Projects::LabelsController do
it 'does not redirect' do
get :index, namespace_id: project.namespace, project_id: project.to_param
- expect(response).not_to have_http_status(301)
+ expect(response).not_to have_gitlab_http_status(301)
end
end
@@ -203,13 +203,13 @@ describe Projects::LabelsController do
it 'does not 404' do
post :generate, namespace_id: project.namespace, project_id: project
- expect(response).not_to have_http_status(404)
+ expect(response).not_to have_gitlab_http_status(404)
end
it 'does not redirect to the correct casing' do
post :generate, namespace_id: project.namespace, project_id: project
- expect(response).not_to have_http_status(301)
+ expect(response).not_to have_gitlab_http_status(301)
end
end
@@ -219,7 +219,7 @@ describe Projects::LabelsController do
it 'returns not found' do
post :generate, namespace_id: project.namespace, project_id: project.to_param + 'old'
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
diff --git a/spec/controllers/projects/mattermosts_controller_spec.rb b/spec/controllers/projects/mattermosts_controller_spec.rb
index 4eea7041d29..33d48ff94d1 100644
--- a/spec/controllers/projects/mattermosts_controller_spec.rb
+++ b/spec/controllers/projects/mattermosts_controller_spec.rb
@@ -20,7 +20,7 @@ describe Projects::MattermostsController do
namespace_id: project.namespace.to_param,
project_id: project)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
end
diff --git a/spec/controllers/projects/merge_requests/conflicts_controller_spec.rb b/spec/controllers/projects/merge_requests/conflicts_controller_spec.rb
index c6d50c28106..2d7647a6e12 100644
--- a/spec/controllers/projects/merge_requests/conflicts_controller_spec.rb
+++ b/spec/controllers/projects/merge_requests/conflicts_controller_spec.rb
@@ -28,7 +28,7 @@ describe Projects::MergeRequests::ConflictsController do
end
it 'returns a 200 status code' do
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
end
it 'returns JSON with a message' do
@@ -116,7 +116,7 @@ describe Projects::MergeRequests::ConflictsController do
end
it 'returns a 404 status code' do
- expect(response).to have_http_status(:not_found)
+ expect(response).to have_gitlab_http_status(:not_found)
end
end
@@ -126,7 +126,7 @@ describe Projects::MergeRequests::ConflictsController do
end
it 'returns a 404 status code' do
- expect(response).to have_http_status(:not_found)
+ expect(response).to have_gitlab_http_status(:not_found)
end
end
@@ -138,7 +138,7 @@ describe Projects::MergeRequests::ConflictsController do
end
it 'returns a 200 status code' do
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
end
it 'returns the file in JSON format' do
@@ -198,7 +198,7 @@ describe Projects::MergeRequests::ConflictsController do
end
it 'returns an OK response' do
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
end
end
@@ -224,7 +224,7 @@ describe Projects::MergeRequests::ConflictsController do
end
it 'returns a 400 error' do
- expect(response).to have_http_status(:bad_request)
+ expect(response).to have_gitlab_http_status(:bad_request)
end
it 'has a message with the name of the first missing section' do
@@ -254,7 +254,7 @@ describe Projects::MergeRequests::ConflictsController do
end
it 'returns a 400 error' do
- expect(response).to have_http_status(:bad_request)
+ expect(response).to have_gitlab_http_status(:bad_request)
end
it 'has a message with the name of the missing file' do
@@ -292,7 +292,7 @@ describe Projects::MergeRequests::ConflictsController do
end
it 'returns a 400 error' do
- expect(response).to have_http_status(:bad_request)
+ expect(response).to have_gitlab_http_status(:bad_request)
end
it 'has a message with the path of the problem file' do
diff --git a/spec/controllers/projects/merge_requests/creations_controller_spec.rb b/spec/controllers/projects/merge_requests/creations_controller_spec.rb
index fc4cec53374..7fdddc02fd3 100644
--- a/spec/controllers/projects/merge_requests/creations_controller_spec.rb
+++ b/spec/controllers/projects/merge_requests/creations_controller_spec.rb
@@ -112,7 +112,7 @@ describe Projects::MergeRequests::CreationsController do
end
it 'returns a 404' do
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
diff --git a/spec/controllers/projects/merge_requests/diffs_controller_spec.rb b/spec/controllers/projects/merge_requests/diffs_controller_spec.rb
index 7260350d5fb..18a70bec103 100644
--- a/spec/controllers/projects/merge_requests/diffs_controller_spec.rb
+++ b/spec/controllers/projects/merge_requests/diffs_controller_spec.rb
@@ -119,7 +119,7 @@ describe Projects::MergeRequests::DiffsController do
end
it 'returns a 404' do
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -131,7 +131,7 @@ describe Projects::MergeRequests::DiffsController do
end
it 'returns a 404' do
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -142,7 +142,7 @@ describe Projects::MergeRequests::DiffsController do
end
it 'returns a 404' do
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -155,7 +155,7 @@ describe Projects::MergeRequests::DiffsController do
end
it 'returns a 404' do
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
diff --git a/spec/controllers/projects/merge_requests_controller_spec.rb b/spec/controllers/projects/merge_requests_controller_spec.rb
index 707e7c32283..52ef8c6a589 100644
--- a/spec/controllers/projects/merge_requests_controller_spec.rb
+++ b/spec/controllers/projects/merge_requests_controller_spec.rb
@@ -83,15 +83,15 @@ describe Projects::MergeRequestsController do
end
describe 'as json' do
- context 'with basic param' do
+ context 'with basic serializer param' do
it 'renders basic MR entity as json' do
- go(basic: true, format: :json)
+ go(serializer: 'basic', format: :json)
expect(response).to match_response_schema('entities/merge_request_basic')
end
end
- context 'without basic param' do
+ context 'without basic serializer param' do
it 'renders the merge request in the json format' do
go(format: :json)
@@ -143,7 +143,7 @@ describe Projects::MergeRequestsController do
get_merge_requests(last_page)
expect(assigns(:merge_requests).current_page).to eq(last_page)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it 'does not redirect to external sites when provided a host field' do
@@ -278,7 +278,7 @@ describe Projects::MergeRequestsController do
end
it 'returns 404' do
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -434,7 +434,7 @@ describe Projects::MergeRequestsController do
it "denies access to users unless they're admin or project owner" do
delete :destroy, namespace_id: project.namespace, project_id: project, id: merge_request.iid
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
context "when the user is owner" do
@@ -449,7 +449,7 @@ describe Projects::MergeRequestsController do
it "deletes the merge request" do
delete :destroy, namespace_id: project.namespace, project_id: project, id: merge_request.iid
- expect(response).to have_http_status(302)
+ expect(response).to have_gitlab_http_status(302)
expect(controller).to set_flash[:notice].to(/The merge request was successfully deleted\./)
end
@@ -539,7 +539,7 @@ describe Projects::MergeRequestsController do
subject
end
- it { is_expected.to have_http_status(:success) }
+ it { is_expected.to have_gitlab_http_status(:success) }
it 'renders MergeRequest as JSON' do
subject
@@ -636,7 +636,7 @@ describe Projects::MergeRequestsController do
end
it 'return a detailed head_pipeline status in json' do
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
expect(json_response['text']).to eq status.text
expect(json_response['label']).to eq status.label
expect(json_response['icon']).to eq status.icon
@@ -650,7 +650,7 @@ describe Projects::MergeRequestsController do
end
it 'return empty' do
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
expect(json_response).to be_empty
end
end
diff --git a/spec/controllers/projects/milestones_controller_spec.rb b/spec/controllers/projects/milestones_controller_spec.rb
index 62f1fb1f697..209979e642d 100644
--- a/spec/controllers/projects/milestones_controller_spec.rb
+++ b/spec/controllers/projects/milestones_controller_spec.rb
@@ -27,7 +27,7 @@ describe Projects::MilestonesController do
it 'shows milestone page' do
view_milestone
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
end
@@ -86,4 +86,32 @@ describe Projects::MilestonesController do
expect(last_note).to eq('removed milestone')
end
end
+
+ describe '#promote' do
+ context 'promotion succeeds' do
+ before do
+ group = create(:group)
+ group.add_developer(user)
+ milestone.project.update(namespace: group)
+ end
+
+ it 'shows group milestone' do
+ post :promote, namespace_id: project.namespace.id, project_id: project.id, id: milestone.iid
+
+ group_milestone = assigns(:milestone)
+
+ expect(response).to redirect_to(group_milestone_path(project.group, group_milestone.iid))
+ expect(flash[:notice]).to eq('Milestone has been promoted to group milestone.')
+ end
+ end
+
+ context 'promotion fails' do
+ it 'shows project milestone' do
+ post :promote, namespace_id: project.namespace.id, project_id: project.id, id: milestone.iid
+
+ expect(response).to redirect_to(project_milestone_path(project, milestone))
+ expect(flash[:alert]).to eq('Promotion failed - Project does not belong to a group.')
+ end
+ end
+ end
end
diff --git a/spec/controllers/projects/notes_controller_spec.rb b/spec/controllers/projects/notes_controller_spec.rb
index 135fd6449ff..1184c55e540 100644
--- a/spec/controllers/projects/notes_controller_spec.rb
+++ b/spec/controllers/projects/notes_controller_spec.rb
@@ -180,13 +180,13 @@ describe Projects::NotesController do
it "returns status 302 for html" do
post :create, request_params
- expect(response).to have_http_status(302)
+ expect(response).to have_gitlab_http_status(302)
end
it "returns status 200 for json" do
post :create, request_params.merge(format: :json)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
context 'when merge_request_diff_head_sha present' do
@@ -205,7 +205,7 @@ describe Projects::NotesController do
it "returns status 302 for html" do
post :create, request_params
- expect(response).to have_http_status(302)
+ expect(response).to have_gitlab_http_status(302)
end
end
@@ -240,7 +240,7 @@ describe Projects::NotesController do
it 'returns a 404' do
post_create(note_project_id: Project.maximum(:id).succ)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -248,7 +248,7 @@ describe Projects::NotesController do
it 'returns a 404' do
post_create
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -278,7 +278,7 @@ describe Projects::NotesController do
request_params[:note][:noteable_id] = 9999
post :create, request_params.merge(format: :json)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -286,13 +286,13 @@ describe Projects::NotesController do
it 'returns 302 status for html' do
post :create, request_params
- expect(response).to have_http_status(302)
+ expect(response).to have_gitlab_http_status(302)
end
it 'returns 200 status for json' do
post :create, request_params.merge(format: :json)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it 'creates a new note' do
@@ -308,7 +308,7 @@ describe Projects::NotesController do
it 'returns 404 status' do
post :create, request_params
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'does not create a new note' do
@@ -337,7 +337,7 @@ describe Projects::NotesController do
it "returns status 200 for html" do
delete :destroy, request_params
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it "deletes the note" do
@@ -354,7 +354,7 @@ describe Projects::NotesController do
it "returns status 404" do
delete :destroy, request_params
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -370,7 +370,7 @@ describe Projects::NotesController do
post(:toggle_award_emoji, request_params.merge(name: "thumbsup"))
end.to change { note.award_emoji.count }.by(1)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it "removes the already awarded emoji" do
@@ -380,7 +380,7 @@ describe Projects::NotesController do
post(:toggle_award_emoji, request_params.merge(name: "thumbsup"))
end.to change { AwardEmoji.count }.by(-1)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
end
@@ -398,7 +398,7 @@ describe Projects::NotesController do
it "returns status 404" do
post :resolve, request_params
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -415,7 +415,7 @@ describe Projects::NotesController do
it "returns status 404" do
post :resolve, request_params
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -442,7 +442,7 @@ describe Projects::NotesController do
it "returns status 200" do
post :resolve, request_params
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
end
end
@@ -459,7 +459,7 @@ describe Projects::NotesController do
it "returns status 404" do
delete :unresolve, request_params
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -476,7 +476,7 @@ describe Projects::NotesController do
it "returns status 404" do
delete :unresolve, request_params
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -490,7 +490,7 @@ describe Projects::NotesController do
it "returns status 200" do
delete :unresolve, request_params
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
end
end
diff --git a/spec/controllers/projects/pages_controller_spec.rb b/spec/controllers/projects/pages_controller_spec.rb
index 83c7744a231..4705c50de7e 100644
--- a/spec/controllers/projects/pages_controller_spec.rb
+++ b/spec/controllers/projects/pages_controller_spec.rb
@@ -21,7 +21,7 @@ describe Projects::PagesController do
it 'returns 200 status' do
get :show, request_params
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
context 'when the project is in a subgroup' do
@@ -31,7 +31,7 @@ describe Projects::PagesController do
it 'returns a 404 status code' do
get :show, request_params
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -40,7 +40,7 @@ describe Projects::PagesController do
it 'returns 302 status' do
delete :destroy, request_params
- expect(response).to have_http_status(302)
+ expect(response).to have_gitlab_http_status(302)
end
end
@@ -53,7 +53,7 @@ describe Projects::PagesController do
it 'returns 404 status' do
get :show, request_params
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -61,7 +61,7 @@ describe Projects::PagesController do
it 'returns 404 status' do
delete :destroy, request_params
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
diff --git a/spec/controllers/projects/pages_domains_controller_spec.rb b/spec/controllers/projects/pages_domains_controller_spec.rb
index ad4d7da3bdd..e9e7d357d9c 100644
--- a/spec/controllers/projects/pages_domains_controller_spec.rb
+++ b/spec/controllers/projects/pages_domains_controller_spec.rb
@@ -26,7 +26,7 @@ describe Projects::PagesDomainsController do
it "displays the 'show' page" do
get(:show, request_params.merge(id: pages_domain.domain))
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to render_template('show')
end
end
@@ -35,7 +35,7 @@ describe Projects::PagesDomainsController do
it "displays the 'new' page" do
get(:new, request_params)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to render_template('new')
end
end
@@ -69,7 +69,7 @@ describe Projects::PagesDomainsController do
it 'returns 404 status' do
get(:show, request_params.merge(id: pages_domain.domain))
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -77,7 +77,7 @@ describe Projects::PagesDomainsController do
it 'returns 404 status' do
get :new, request_params
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -85,7 +85,7 @@ describe Projects::PagesDomainsController do
it "returns 404 status" do
post(:create, request_params.merge(pages_domain: pages_domain_params))
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -93,7 +93,7 @@ describe Projects::PagesDomainsController do
it "deletes the pages domain" do
delete(:destroy, request_params.merge(id: pages_domain.domain))
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
diff --git a/spec/controllers/projects/pipeline_schedules_controller_spec.rb b/spec/controllers/projects/pipeline_schedules_controller_spec.rb
index 4ac0559c679..4e52e261920 100644
--- a/spec/controllers/projects/pipeline_schedules_controller_spec.rb
+++ b/spec/controllers/projects/pipeline_schedules_controller_spec.rb
@@ -15,7 +15,7 @@ describe Projects::PipelineSchedulesController do
it 'renders the index view' do
visit_pipelines_schedules
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
expect(response).to render_template(:index)
end
@@ -35,7 +35,7 @@ describe Projects::PipelineSchedulesController do
end
it 'only shows active pipeline schedules' do
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
expect(assigns(:schedules)).to include(pipeline_schedule)
expect(assigns(:schedules)).not_to include(inactive_pipeline_schedule)
end
@@ -57,7 +57,7 @@ describe Projects::PipelineSchedulesController do
it 'initializes a pipeline schedule model' do
get :new, namespace_id: project.namespace.to_param, project_id: project
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
expect(assigns(:schedule)).to be_a_new(Ci::PipelineSchedule)
end
end
@@ -87,7 +87,7 @@ describe Projects::PipelineSchedulesController do
.to change { Ci::PipelineSchedule.count }.by(1)
.and change { Ci::PipelineScheduleVariable.count }.by(1)
- expect(response).to have_http_status(:found)
+ expect(response).to have_gitlab_http_status(:found)
Ci::PipelineScheduleVariable.last.tap do |v|
expect(v.key).to eq("AAA")
@@ -158,7 +158,7 @@ describe Projects::PipelineSchedulesController do
expect { go }.to change { Ci::PipelineScheduleVariable.count }.by(1)
pipeline_schedule.reload
- expect(response).to have_http_status(:found)
+ expect(response).to have_gitlab_http_status(:found)
expect(pipeline_schedule.variables.last.key).to eq('AAA')
expect(pipeline_schedule.variables.last.value).to eq('AAA123')
end
@@ -324,7 +324,7 @@ describe Projects::PipelineSchedulesController do
it 'loads the pipeline schedule' do
get :edit, namespace_id: project.namespace.to_param, project_id: project, id: pipeline_schedule.id
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
expect(assigns(:schedule)).to eq(pipeline_schedule)
end
end
@@ -376,7 +376,7 @@ describe Projects::PipelineSchedulesController do
end
it 'does not delete the pipeline schedule' do
- expect(response).to have_http_status(:not_found)
+ expect(response).to have_gitlab_http_status(:not_found)
end
end
@@ -391,7 +391,7 @@ describe Projects::PipelineSchedulesController do
delete :destroy, namespace_id: project.namespace.to_param, project_id: project, id: pipeline_schedule.id
end.to change { project.pipeline_schedules.count }.by(-1)
- expect(response).to have_http_status(302)
+ expect(response).to have_gitlab_http_status(302)
end
end
end
diff --git a/spec/controllers/projects/pipelines_controller_spec.rb b/spec/controllers/projects/pipelines_controller_spec.rb
index 67b53d2acce..1604a2da485 100644
--- a/spec/controllers/projects/pipelines_controller_spec.rb
+++ b/spec/controllers/projects/pipelines_controller_spec.rb
@@ -33,7 +33,7 @@ describe Projects::PipelinesController do
it 'returns JSON with serialized pipelines' do
subject
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
expect(response).to match_response_schema('pipeline')
expect(json_response).to include('pipelines')
@@ -46,7 +46,7 @@ describe Projects::PipelinesController do
context 'when performing gitaly calls', :request_store do
it 'limits the Gitaly requests' do
- expect { subject }.to change { Gitlab::GitalyClient.get_request_count }.by(10)
+ expect { subject }.to change { Gitlab::GitalyClient.get_request_count }.by(8)
end
end
end
@@ -57,7 +57,7 @@ describe Projects::PipelinesController do
it 'returns the pipeline' do
get_pipeline_json
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
expect(json_response).not_to be_an(Array)
expect(json_response['id']).to be(pipeline.id)
expect(json_response['details']).to have_key 'stages'
@@ -111,7 +111,7 @@ describe Projects::PipelinesController do
end
it 'returns html source for stage dropdown' do
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
expect(response).to render_template('projects/pipelines/_stage')
expect(json_response).to include('html')
end
@@ -123,7 +123,7 @@ describe Projects::PipelinesController do
end
it 'responds with not found' do
- expect(response).to have_http_status(:not_found)
+ expect(response).to have_gitlab_http_status(:not_found)
end
end
@@ -148,7 +148,7 @@ describe Projects::PipelinesController do
end
it 'return a detailed pipeline status in json' do
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
expect(json_response['text']).to eq status.text
expect(json_response['label']).to eq status.label
expect(json_response['icon']).to eq status.icon
@@ -171,14 +171,14 @@ describe Projects::PipelinesController do
let(:feature) { ProjectFeature::ENABLED }
it 'retries a pipeline without returning any content' do
- expect(response).to have_http_status(:no_content)
+ expect(response).to have_gitlab_http_status(:no_content)
expect(build.reload).to be_retried
end
end
context 'when builds are disabled' do
it 'fails to retry pipeline' do
- expect(response).to have_http_status(:not_found)
+ expect(response).to have_gitlab_http_status(:not_found)
end
end
end
@@ -198,14 +198,14 @@ describe Projects::PipelinesController do
let(:feature) { ProjectFeature::ENABLED }
it 'cancels a pipeline without returning any content' do
- expect(response).to have_http_status(:no_content)
+ expect(response).to have_gitlab_http_status(:no_content)
expect(pipeline.reload).to be_canceled
end
end
context 'when builds are disabled' do
it 'fails to retry pipeline' do
- expect(response).to have_http_status(:not_found)
+ expect(response).to have_gitlab_http_status(:not_found)
end
end
end
diff --git a/spec/controllers/projects/pipelines_settings_controller_spec.rb b/spec/controllers/projects/pipelines_settings_controller_spec.rb
index ee46ad00947..21b6a6d45f5 100644
--- a/spec/controllers/projects/pipelines_settings_controller_spec.rb
+++ b/spec/controllers/projects/pipelines_settings_controller_spec.rb
@@ -25,7 +25,7 @@ describe Projects::PipelinesSettingsController do
let(:params) { { enabled: '', domain: 'mepmep.md' } }
it 'redirects to the settings page' do
- expect(response).to have_http_status(302)
+ expect(response).to have_gitlab_http_status(302)
expect(flash[:notice]).to eq("Pipelines settings for '#{project.name}' were successfully updated.")
end
diff --git a/spec/controllers/projects/project_members_controller_spec.rb b/spec/controllers/projects/project_members_controller_spec.rb
index 3cb1bec5ea2..a34dc27a5ed 100644
--- a/spec/controllers/projects/project_members_controller_spec.rb
+++ b/spec/controllers/projects/project_members_controller_spec.rb
@@ -8,7 +8,7 @@ describe Projects::ProjectMembersController do
it 'should have the project_members address with a 200 status code' do
get :index, namespace_id: project.namespace, project_id: project
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
end
@@ -30,7 +30,7 @@ describe Projects::ProjectMembersController do
user_ids: project_user.id,
access_level: Gitlab::Access::GUEST
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(project.users).not_to include project_user
end
end
@@ -79,7 +79,7 @@ describe Projects::ProjectMembersController do
project_id: project,
id: 42
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -94,7 +94,7 @@ describe Projects::ProjectMembersController do
project_id: project,
id: member
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(project.members).to include member
end
end
@@ -137,7 +137,7 @@ describe Projects::ProjectMembersController do
delete :leave, namespace_id: project.namespace,
project_id: project
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -168,7 +168,7 @@ describe Projects::ProjectMembersController do
delete :leave, namespace_id: project.namespace,
project_id: project
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -221,7 +221,7 @@ describe Projects::ProjectMembersController do
project_id: project,
id: 42
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -236,7 +236,7 @@ describe Projects::ProjectMembersController do
project_id: project,
id: member
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(project.members).not_to include member
end
end
diff --git a/spec/controllers/projects/prometheus_controller_spec.rb b/spec/controllers/projects/prometheus_controller_spec.rb
index 8407a53272a..bbfe78d305a 100644
--- a/spec/controllers/projects/prometheus_controller_spec.rb
+++ b/spec/controllers/projects/prometheus_controller_spec.rb
@@ -24,7 +24,7 @@ describe Projects::PrometheusController do
it 'returns no content response' do
get :active_metrics, project_params(format: :json)
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
end
end
@@ -38,7 +38,7 @@ describe Projects::PrometheusController do
it 'returns no content response' do
get :active_metrics, project_params(format: :json)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to eq(sample_response.deep_stringify_keys)
end
end
@@ -47,7 +47,7 @@ describe Projects::PrometheusController do
it 'returns not found response' do
get :active_metrics, project_params
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
diff --git a/spec/controllers/projects/raw_controller_spec.rb b/spec/controllers/projects/raw_controller_spec.rb
index b4eaab29fed..3a0c3faa7b4 100644
--- a/spec/controllers/projects/raw_controller_spec.rb
+++ b/spec/controllers/projects/raw_controller_spec.rb
@@ -13,7 +13,7 @@ describe Projects::RawController do
project_id: public_project,
id: id)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response.header['Content-Type']).to eq('text/plain; charset=utf-8')
expect(response.header['Content-Disposition'])
.to eq('inline')
@@ -30,7 +30,7 @@ describe Projects::RawController do
project_id: public_project,
id: id)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response.header['Content-Type']).to eq('image/jpeg')
expect(response.header[Gitlab::Workhorse::SEND_DATA_HEADER]).to start_with('git-blob:')
end
@@ -59,7 +59,7 @@ describe Projects::RawController do
project_id: public_project,
id: id)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
end
@@ -70,7 +70,7 @@ describe Projects::RawController do
project_id: public_project,
id: id)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -86,7 +86,7 @@ describe Projects::RawController do
project_id: public_project,
id: id)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response.header['Content-Type']).to eq('text/plain; charset=utf-8')
expect(response.header['Content-Disposition'])
.to eq('inline')
diff --git a/spec/controllers/projects/registry/repositories_controller_spec.rb b/spec/controllers/projects/registry/repositories_controller_spec.rb
index 5d9d5351687..17769a14def 100644
--- a/spec/controllers/projects/registry/repositories_controller_spec.rb
+++ b/spec/controllers/projects/registry/repositories_controller_spec.rb
@@ -35,7 +35,7 @@ describe Projects::Registry::RepositoriesController do
it 'successfully renders container repositories' do
go_to_index
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
end
it 'creates a root container repository' do
@@ -46,7 +46,7 @@ describe Projects::Registry::RepositoriesController do
it 'json has a list of projects' do
go_to_index(format: :json)
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
expect(response).to match_response_schema('registry/repositories')
end
end
@@ -59,7 +59,7 @@ describe Projects::Registry::RepositoriesController do
it 'successfully renders container repositories' do
go_to_index
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
end
it 'does not ensure root container repository' do
@@ -69,7 +69,7 @@ describe Projects::Registry::RepositoriesController do
it 'responds with json if asked' do
go_to_index(format: :json)
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
expect(json_response).to be_kind_of(Array)
end
end
@@ -89,7 +89,7 @@ describe Projects::Registry::RepositoriesController do
it 'deletes a repository' do
expect { delete_repository(repository) }.to change { ContainerRepository.all.count }.by(-1)
- expect(response).to have_http_status(:no_content)
+ expect(response).to have_gitlab_http_status(:no_content)
end
end
end
@@ -100,7 +100,7 @@ describe Projects::Registry::RepositoriesController do
it 'responds with 404' do
go_to_index
- expect(response).to have_http_status(:not_found)
+ expect(response).to have_gitlab_http_status(:not_found)
end
it 'does not ensure root container repository' do
diff --git a/spec/controllers/projects/registry/tags_controller_spec.rb b/spec/controllers/projects/registry/tags_controller_spec.rb
index bb702ebeb23..7fee8fd44ff 100644
--- a/spec/controllers/projects/registry/tags_controller_spec.rb
+++ b/spec/controllers/projects/registry/tags_controller_spec.rb
@@ -30,7 +30,7 @@ describe Projects::Registry::TagsController do
it 'receive a list of tags' do
get_tags
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
expect(response).to match_response_schema('registry/tags')
expect(response).to include_pagination_headers
end
@@ -44,7 +44,7 @@ describe Projects::Registry::TagsController do
it 'receive a list of tags' do
get_tags
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
expect(response).to match_response_schema('registry/tags')
expect(response).to include_pagination_headers
end
@@ -58,7 +58,7 @@ describe Projects::Registry::TagsController do
it 'does not receive a list of tags' do
get_tags
- expect(response).to have_http_status(:not_found)
+ expect(response).to have_gitlab_http_status(:not_found)
end
end
diff --git a/spec/controllers/projects/repositories_controller_spec.rb b/spec/controllers/projects/repositories_controller_spec.rb
index f712d1e0d63..8b777eb68ca 100644
--- a/spec/controllers/projects/repositories_controller_spec.rb
+++ b/spec/controllers/projects/repositories_controller_spec.rb
@@ -35,7 +35,7 @@ describe Projects::RepositoriesController do
it "renders Not Found" do
get :archive, namespace_id: project.namespace, project_id: project, ref: "master", format: "zip"
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
diff --git a/spec/controllers/projects/runners_controller_spec.rb b/spec/controllers/projects/runners_controller_spec.rb
index 2b6f988fd9c..89a13f3c976 100644
--- a/spec/controllers/projects/runners_controller_spec.rb
+++ b/spec/controllers/projects/runners_controller_spec.rb
@@ -29,7 +29,7 @@ describe Projects::RunnersController do
runner.reload
- expect(response).to have_http_status(302)
+ expect(response).to have_gitlab_http_status(302)
expect(runner.description).to eq(new_desc)
end
end
@@ -38,7 +38,7 @@ describe Projects::RunnersController do
it 'destroys the runner' do
delete :destroy, params
- expect(response).to have_http_status(302)
+ expect(response).to have_gitlab_http_status(302)
expect(Ci::Runner.find_by(id: runner.id)).to be_nil
end
end
@@ -53,7 +53,7 @@ describe Projects::RunnersController do
runner.reload
- expect(response).to have_http_status(302)
+ expect(response).to have_gitlab_http_status(302)
expect(runner.active).to eq(true)
end
end
@@ -68,7 +68,7 @@ describe Projects::RunnersController do
runner.reload
- expect(response).to have_http_status(302)
+ expect(response).to have_gitlab_http_status(302)
expect(runner.active).to eq(false)
end
end
diff --git a/spec/controllers/projects/services_controller_spec.rb b/spec/controllers/projects/services_controller_spec.rb
index efba9cc7306..a907da2b60f 100644
--- a/spec/controllers/projects/services_controller_spec.rb
+++ b/spec/controllers/projects/services_controller_spec.rb
@@ -19,7 +19,7 @@ describe Projects::ServicesController do
put :test, namespace_id: project.namespace, project_id: project, id: service.to_param
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
diff --git a/spec/controllers/projects/settings/ci_cd_controller_spec.rb b/spec/controllers/projects/settings/ci_cd_controller_spec.rb
index a8f4b79b64c..b8fe0f46f57 100644
--- a/spec/controllers/projects/settings/ci_cd_controller_spec.rb
+++ b/spec/controllers/projects/settings/ci_cd_controller_spec.rb
@@ -13,7 +13,7 @@ describe Projects::Settings::CiCdController do
it 'renders show with 200 status code' do
get :show, namespace_id: project.namespace, project_id: project
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to render_template(:show)
end
end
diff --git a/spec/controllers/projects/settings/integrations_controller_spec.rb b/spec/controllers/projects/settings/integrations_controller_spec.rb
index e0f9a5b24a6..3068837f394 100644
--- a/spec/controllers/projects/settings/integrations_controller_spec.rb
+++ b/spec/controllers/projects/settings/integrations_controller_spec.rb
@@ -13,7 +13,7 @@ describe Projects::Settings::IntegrationsController do
it 'renders show with 200 status code' do
get :show, namespace_id: project.namespace, project_id: project
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to render_template(:show)
end
end
diff --git a/spec/controllers/projects/settings/repository_controller_spec.rb b/spec/controllers/projects/settings/repository_controller_spec.rb
index f73471f8ca8..3a4014b7768 100644
--- a/spec/controllers/projects/settings/repository_controller_spec.rb
+++ b/spec/controllers/projects/settings/repository_controller_spec.rb
@@ -13,7 +13,7 @@ describe Projects::Settings::RepositoryController do
it 'renders show with 200 status code' do
get :show, namespace_id: project.namespace, project_id: project
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to render_template(:show)
end
end
diff --git a/spec/controllers/projects/snippets_controller_spec.rb b/spec/controllers/projects/snippets_controller_spec.rb
index 3a1550aa730..e7c0b484ede 100644
--- a/spec/controllers/projects/snippets_controller_spec.rb
+++ b/spec/controllers/projects/snippets_controller_spec.rb
@@ -29,7 +29,7 @@ describe Projects::SnippetsController do
project_id: project, page: last_page.to_param
expect(assigns(:snippets).current_page).to eq(last_page)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
end
@@ -41,7 +41,7 @@ describe Projects::SnippetsController do
get :index, namespace_id: project.namespace, project_id: project
expect(assigns(:snippets)).not_to include(project_snippet)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
end
@@ -54,7 +54,7 @@ describe Projects::SnippetsController do
get :index, namespace_id: project.namespace, project_id: project
expect(assigns(:snippets)).to include(project_snippet)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
end
@@ -67,7 +67,7 @@ describe Projects::SnippetsController do
get :index, namespace_id: project.namespace, project_id: project
expect(assigns(:snippets)).to include(project_snippet)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
end
end
@@ -316,7 +316,7 @@ describe Projects::SnippetsController do
it 'responds with status 404' do
get action, namespace_id: project.namespace, project_id: project, id: project_snippet.to_param
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -329,7 +329,7 @@ describe Projects::SnippetsController do
get action, namespace_id: project.namespace, project_id: project, id: project_snippet.to_param
expect(assigns(:snippet)).to eq(project_snippet)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
end
@@ -342,7 +342,7 @@ describe Projects::SnippetsController do
get action, namespace_id: project.namespace, project_id: project, id: project_snippet.to_param
expect(assigns(:snippet)).to eq(project_snippet)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
end
end
@@ -352,7 +352,7 @@ describe Projects::SnippetsController do
it 'responds with status 404' do
get action, namespace_id: project.namespace, project_id: project, id: 42
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -364,7 +364,7 @@ describe Projects::SnippetsController do
it 'responds with status 404' do
get action, namespace_id: project.namespace, project_id: project, id: 42
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
diff --git a/spec/controllers/projects/todos_controller_spec.rb b/spec/controllers/projects/todos_controller_spec.rb
index 41d211ed1bb..4622e27e60f 100644
--- a/spec/controllers/projects/todos_controller_spec.rb
+++ b/spec/controllers/projects/todos_controller_spec.rb
@@ -28,13 +28,13 @@ describe Projects::TodosController do
go
end.to change { user.todos.count }.by(1)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it 'returns todo path and pending count' do
go
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['count']).to eq 1
expect(json_response['delete_path']).to match(/\/dashboard\/todos\/\d{1}/)
end
@@ -47,7 +47,7 @@ describe Projects::TodosController do
go
end.to change { user.todos.count }.by(0)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'does not create todo for issue when user not logged in' do
@@ -55,7 +55,7 @@ describe Projects::TodosController do
go
end.to change { user.todos.count }.by(0)
- expect(response).to have_http_status(302)
+ expect(response).to have_gitlab_http_status(302)
end
end
@@ -68,7 +68,7 @@ describe Projects::TodosController do
it "doesn't create todo" do
expect { go }.not_to change { user.todos.count }
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -96,13 +96,13 @@ describe Projects::TodosController do
go
end.to change { user.todos.count }.by(1)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it 'returns todo path and pending count' do
go
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['count']).to eq 1
expect(json_response['delete_path']).to match(/\/dashboard\/todos\/\d{1}/)
end
@@ -115,7 +115,7 @@ describe Projects::TodosController do
go
end.to change { user.todos.count }.by(0)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'does not create todo for merge request user has no access to' do
@@ -123,7 +123,7 @@ describe Projects::TodosController do
go
end.to change { user.todos.count }.by(0)
- expect(response).to have_http_status(302)
+ expect(response).to have_gitlab_http_status(302)
end
end
@@ -136,7 +136,7 @@ describe Projects::TodosController do
it "doesn't create todo" do
expect { go }.not_to change { user.todos.count }
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
diff --git a/spec/controllers/projects/tree_controller_spec.rb b/spec/controllers/projects/tree_controller_spec.rb
index 775f3998f5d..65b821c9486 100644
--- a/spec/controllers/projects/tree_controller_spec.rb
+++ b/spec/controllers/projects/tree_controller_spec.rb
@@ -64,7 +64,7 @@ describe Projects::TreeController do
context "valid SHA commit ID with path" do
let(:id) { '6d39438/.gitignore' }
- it { expect(response).to have_http_status(302) }
+ it { expect(response).to have_gitlab_http_status(302) }
end
end
diff --git a/spec/controllers/projects/uploads_controller_spec.rb b/spec/controllers/projects/uploads_controller_spec.rb
index 488bcf31371..c2550b1efa7 100644
--- a/spec/controllers/projects/uploads_controller_spec.rb
+++ b/spec/controllers/projects/uploads_controller_spec.rb
@@ -18,7 +18,7 @@ describe Projects::UploadsController do
namespace_id: project.namespace.to_param,
project_id: project,
format: :json
- expect(response).to have_http_status(422)
+ expect(response).to have_gitlab_http_status(422)
end
end
@@ -90,7 +90,7 @@ describe Projects::UploadsController do
it "responds with status 200" do
go
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
end
@@ -98,7 +98,7 @@ describe Projects::UploadsController do
it "responds with status 404" do
go
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -117,7 +117,7 @@ describe Projects::UploadsController do
it "responds with status 200" do
go
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
end
@@ -125,7 +125,7 @@ describe Projects::UploadsController do
it "responds with status 404" do
go
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -151,7 +151,7 @@ describe Projects::UploadsController do
it "responds with status 200" do
go
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
end
@@ -192,7 +192,7 @@ describe Projects::UploadsController do
it "responds with status 200" do
go
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
end
@@ -200,7 +200,7 @@ describe Projects::UploadsController do
it "responds with status 404" do
go
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -220,7 +220,7 @@ describe Projects::UploadsController do
it "responds with status 200" do
go
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
end
@@ -228,7 +228,7 @@ describe Projects::UploadsController do
it "responds with status 404" do
go
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -237,7 +237,7 @@ describe Projects::UploadsController do
it "responds with status 404" do
go
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
diff --git a/spec/controllers/projects/variables_controller_spec.rb b/spec/controllers/projects/variables_controller_spec.rb
index 6957fb43c19..d065cd00d00 100644
--- a/spec/controllers/projects/variables_controller_spec.rb
+++ b/spec/controllers/projects/variables_controller_spec.rb
@@ -50,7 +50,7 @@ describe Projects::VariablesController do
post :update, namespace_id: project.namespace.to_param, project_id: project,
id: variable.id, variable: { key: '?', value: variable.value }
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to render_template :show
end
end
diff --git a/spec/controllers/projects_controller_spec.rb b/spec/controllers/projects_controller_spec.rb
index 7569052c3aa..b1d7157e447 100644
--- a/spec/controllers/projects_controller_spec.rb
+++ b/spec/controllers/projects_controller_spec.rb
@@ -24,7 +24,7 @@ describe ProjectsController do
get :new, namespace_id: group.id
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to render_template('new')
end
end
@@ -33,7 +33,7 @@ describe ProjectsController do
it 'responds with status 404' do
get :new, namespace_id: group.id
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(response).not_to render_template('new')
end
end
@@ -152,7 +152,7 @@ describe ProjectsController do
it 'renders a 503' do
get :show, namespace_id: project.namespace, id: project
- expect(response).to have_http_status(503)
+ expect(response).to have_gitlab_http_status(503)
end
end
@@ -257,7 +257,7 @@ describe ProjectsController do
get :show, namespace_id: project.namespace, id: project, format: :git
- expect(response).to have_http_status(302)
+ expect(response).to have_gitlab_http_status(302)
expect(response).to redirect_to(namespace_project_path)
end
end
@@ -280,7 +280,7 @@ describe ProjectsController do
expect(project.path).to include 'renamed_path'
expect(assigns(:repository).path).to include project.path
- expect(response).to have_http_status(302)
+ expect(response).to have_gitlab_http_status(302)
end
end
@@ -296,7 +296,7 @@ describe ProjectsController do
.not_to change { project.reload.path }
expect(controller).to set_flash[:alert].to(/container registry tags/)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
end
@@ -312,7 +312,7 @@ describe ProjectsController do
id: project.id,
project: params
- expect(response).to have_http_status(302)
+ expect(response).to have_gitlab_http_status(302)
params.each do |param, value|
expect(project.public_send(param)).to eq(value)
end
@@ -345,7 +345,7 @@ describe ProjectsController do
project.reload
expect(project.namespace).to eq(new_namespace)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
context 'when new namespace is empty' do
@@ -364,7 +364,7 @@ describe ProjectsController do
project.reload
expect(project.namespace).to eq(old_namespace)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(flash[:alert]).to eq 'Please select a new namespace for your project.'
end
end
@@ -381,7 +381,7 @@ describe ProjectsController do
delete :destroy, namespace_id: project.namespace, id: project
expect { Project.find(orig_id) }.to raise_error(ActiveRecord::RecordNotFound)
- expect(response).to have_http_status(302)
+ expect(response).to have_gitlab_http_status(302)
expect(response).to redirect_to(dashboard_projects_path)
end
@@ -420,7 +420,7 @@ describe ProjectsController do
end
it 'has http status 200' do
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it 'changes the user incoming email token' do
@@ -496,7 +496,7 @@ describe ProjectsController do
delete(:remove_fork,
namespace_id: project.namespace,
id: project, format: :js)
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
@@ -544,7 +544,7 @@ describe ProjectsController do
get :show, namespace_id: public_project.namespace, id: public_project
expect(assigns(:project)).to eq(public_project)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
end
@@ -583,13 +583,13 @@ describe ProjectsController do
it 'does not 404' do
post :toggle_star, namespace_id: public_project.namespace, id: public_project.path.upcase
- expect(response).not_to have_http_status(404)
+ expect(response).not_to have_gitlab_http_status(404)
end
it 'does not redirect to the correct casing' do
post :toggle_star, namespace_id: public_project.namespace, id: public_project.path.upcase
- expect(response).not_to have_http_status(301)
+ expect(response).not_to have_gitlab_http_status(301)
end
end
@@ -599,7 +599,7 @@ describe ProjectsController do
it 'returns not found' do
post :toggle_star, namespace_id: 'foo', id: 'bar'
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -613,13 +613,13 @@ describe ProjectsController do
it 'does not 404' do
delete :destroy, namespace_id: project.namespace, id: project.path.upcase
- expect(response).not_to have_http_status(404)
+ expect(response).not_to have_gitlab_http_status(404)
end
it 'does not redirect to the correct casing' do
delete :destroy, namespace_id: project.namespace, id: project.path.upcase
- expect(response).not_to have_http_status(301)
+ expect(response).not_to have_gitlab_http_status(301)
end
end
@@ -629,7 +629,7 @@ describe ProjectsController do
it 'returns not found' do
delete :destroy, namespace_id: 'foo', id: 'bar'
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -646,7 +646,7 @@ describe ProjectsController do
it 'returns 302' do
get :export, namespace_id: project.namespace, id: project
- expect(response).to have_http_status(302)
+ expect(response).to have_gitlab_http_status(302)
end
end
@@ -658,7 +658,7 @@ describe ProjectsController do
it 'returns 404' do
get :export, namespace_id: project.namespace, id: project
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -674,7 +674,7 @@ describe ProjectsController do
it 'returns 302' do
get :download_export, namespace_id: project.namespace, id: project
- expect(response).to have_http_status(302)
+ expect(response).to have_gitlab_http_status(302)
end
end
@@ -686,7 +686,7 @@ describe ProjectsController do
it 'returns 404' do
get :download_export, namespace_id: project.namespace, id: project
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -702,7 +702,7 @@ describe ProjectsController do
it 'returns 302' do
post :remove_export, namespace_id: project.namespace, id: project
- expect(response).to have_http_status(302)
+ expect(response).to have_gitlab_http_status(302)
end
end
@@ -714,7 +714,7 @@ describe ProjectsController do
it 'returns 404' do
post :remove_export, namespace_id: project.namespace, id: project
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -730,7 +730,7 @@ describe ProjectsController do
it 'returns 302' do
post :generate_new_export, namespace_id: project.namespace, id: project
- expect(response).to have_http_status(302)
+ expect(response).to have_gitlab_http_status(302)
end
end
@@ -742,7 +742,7 @@ describe ProjectsController do
it 'returns 404' do
post :generate_new_export, namespace_id: project.namespace, id: project
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
diff --git a/spec/controllers/sent_notifications_controller_spec.rb b/spec/controllers/sent_notifications_controller_spec.rb
index 31593ce7311..54a9af92f07 100644
--- a/spec/controllers/sent_notifications_controller_spec.rb
+++ b/spec/controllers/sent_notifications_controller_spec.rb
@@ -69,7 +69,7 @@ describe SentNotificationsController do
end
it 'returns a 404' do
- expect(response).to have_http_status(:not_found)
+ expect(response).to have_gitlab_http_status(:not_found)
end
end
diff --git a/spec/controllers/sessions_controller_spec.rb b/spec/controllers/sessions_controller_spec.rb
index a22fd8eaf9b..55bd4352bd3 100644
--- a/spec/controllers/sessions_controller_spec.rb
+++ b/spec/controllers/sessions_controller_spec.rb
@@ -19,7 +19,7 @@ describe SessionsController do
it 'redirects to :omniauth_authorize_path' do
get(:new)
- expect(response).to have_http_status(302)
+ expect(response).to have_gitlab_http_status(302)
expect(response).to redirect_to('/saml')
end
end
@@ -28,7 +28,7 @@ describe SessionsController do
it 'responds with 200' do
get(:new, auto_sign_in: 'false')
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
end
end
diff --git a/spec/controllers/snippets/notes_controller_spec.rb b/spec/controllers/snippets/notes_controller_spec.rb
index 225753333ee..e6148ea1734 100644
--- a/spec/controllers/snippets/notes_controller_spec.rb
+++ b/spec/controllers/snippets/notes_controller_spec.rb
@@ -20,7 +20,7 @@ describe Snippets::NotesController do
end
it "returns status 200" do
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it "returns not empty array of notes" do
@@ -37,7 +37,7 @@ describe Snippets::NotesController do
it "returns status 404" do
get :index, { snippet_id: internal_snippet }
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -49,7 +49,7 @@ describe Snippets::NotesController do
it "returns status 200" do
get :index, { snippet_id: internal_snippet }
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
end
end
@@ -63,7 +63,7 @@ describe Snippets::NotesController do
it "returns status 404" do
get :index, { snippet_id: private_snippet }
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -75,7 +75,7 @@ describe Snippets::NotesController do
it "returns status 404" do
get :index, { snippet_id: private_snippet }
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -89,7 +89,7 @@ describe Snippets::NotesController do
it "returns status 200" do
get :index, { snippet_id: private_snippet }
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it "returns 1 note" do
@@ -134,7 +134,7 @@ describe Snippets::NotesController do
it "returns status 200" do
delete :destroy, request_params
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it "deletes the note" do
@@ -162,7 +162,7 @@ describe Snippets::NotesController do
it "returns status 404" do
delete :destroy, request_params
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it "does not update the note" do
@@ -182,7 +182,7 @@ describe Snippets::NotesController do
it "toggles the award emoji" do
expect { subject }.to change { note.award_emoji.count }.by(1)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it "removes the already awarded emoji when it exists" do
@@ -190,7 +190,7 @@ describe Snippets::NotesController do
expect { subject }.to change { AwardEmoji.count }.by(-1)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
end
end
diff --git a/spec/controllers/snippets_controller_spec.rb b/spec/controllers/snippets_controller_spec.rb
index be273acb69b..9effe47ab05 100644
--- a/spec/controllers/snippets_controller_spec.rb
+++ b/spec/controllers/snippets_controller_spec.rb
@@ -40,7 +40,7 @@ describe SnippetsController do
it 'responds with status 200' do
get :new
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
end
@@ -69,7 +69,7 @@ describe SnippetsController do
it 'responds with status 404' do
get :show, id: other_personal_snippet.to_param
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -78,7 +78,7 @@ describe SnippetsController do
get :show, id: personal_snippet.to_param
expect(assigns(:snippet)).to eq(personal_snippet)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
end
end
@@ -104,7 +104,7 @@ describe SnippetsController do
get :show, id: personal_snippet.to_param
expect(assigns(:snippet)).to eq(personal_snippet)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
end
@@ -129,7 +129,7 @@ describe SnippetsController do
get :show, id: personal_snippet.to_param
expect(assigns(:snippet)).to eq(personal_snippet)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
end
@@ -138,7 +138,7 @@ describe SnippetsController do
get :show, id: personal_snippet.to_param
expect(assigns(:snippet)).to eq(personal_snippet)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
end
end
@@ -152,7 +152,7 @@ describe SnippetsController do
it 'responds with status 404' do
get :show, id: 'doesntexist'
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -432,7 +432,7 @@ describe SnippetsController do
it 'responds with status 404' do
get :raw, id: other_personal_snippet.to_param
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -443,7 +443,7 @@ describe SnippetsController do
it 'responds with status 200' do
expect(assigns(:snippet)).to eq(personal_snippet)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it 'has expected headers' do
@@ -475,7 +475,7 @@ describe SnippetsController do
get :raw, id: personal_snippet.to_param
expect(assigns(:snippet)).to eq(personal_snippet)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
end
@@ -500,7 +500,7 @@ describe SnippetsController do
get :raw, id: personal_snippet.to_param
expect(assigns(:snippet)).to eq(personal_snippet)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
context 'CRLF line ending' do
@@ -527,7 +527,7 @@ describe SnippetsController do
get :raw, id: personal_snippet.to_param
expect(assigns(:snippet)).to eq(personal_snippet)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
end
end
@@ -541,7 +541,7 @@ describe SnippetsController do
it 'responds with status 404' do
get :raw, id: 'doesntexist'
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
diff --git a/spec/controllers/uploads_controller_spec.rb b/spec/controllers/uploads_controller_spec.rb
index b29f3d861be..7e42e43345c 100644
--- a/spec/controllers/uploads_controller_spec.rb
+++ b/spec/controllers/uploads_controller_spec.rb
@@ -18,7 +18,7 @@ describe UploadsController do
it "returns 401 when the user is not logged in" do
post :create, model: model, id: snippet.id, format: :json
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
it "returns 404 when user can't comment on a snippet" do
@@ -27,7 +27,7 @@ describe UploadsController do
sign_in(user)
post :create, model: model, id: private_snippet.id, format: :json
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -39,7 +39,7 @@ describe UploadsController do
it "returns an error without file" do
post :create, model: model, id: snippet.id, format: :json
- expect(response).to have_http_status(422)
+ expect(response).to have_gitlab_http_status(422)
end
it "returns an error with invalid model" do
@@ -50,7 +50,7 @@ describe UploadsController do
it "returns 404 status when object not found" do
post :create, model: model, id: 9999, format: :json
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
context 'with valid image' do
@@ -174,7 +174,7 @@ describe UploadsController do
it "responds with status 200" do
get :show, model: "user", mounted_as: "avatar", id: user.id, filename: "image.png"
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it_behaves_like 'content not cached without revalidation' do
@@ -190,7 +190,7 @@ describe UploadsController do
it "responds with status 200" do
get :show, model: "user", mounted_as: "avatar", id: user.id, filename: "image.png"
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it_behaves_like 'content not cached without revalidation' do
@@ -214,7 +214,7 @@ describe UploadsController do
it "responds with status 200" do
get :show, model: "project", mounted_as: "avatar", id: project.id, filename: "image.png"
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it_behaves_like 'content not cached without revalidation' do
@@ -233,7 +233,7 @@ describe UploadsController do
it "responds with status 200" do
get :show, model: "project", mounted_as: "avatar", id: project.id, filename: "image.png"
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it_behaves_like 'content not cached without revalidation' do
@@ -285,7 +285,7 @@ describe UploadsController do
it "responds with status 200" do
get :show, model: "project", mounted_as: "avatar", id: project.id, filename: "image.png"
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it_behaves_like 'content not cached without revalidation' do
@@ -301,7 +301,7 @@ describe UploadsController do
it "responds with status 404" do
get :show, model: "project", mounted_as: "avatar", id: project.id, filename: "image.png"
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -316,7 +316,7 @@ describe UploadsController do
it "responds with status 200" do
get :show, model: "group", mounted_as: "avatar", id: group.id, filename: "image.png"
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it_behaves_like 'content not cached without revalidation' do
@@ -335,7 +335,7 @@ describe UploadsController do
it "responds with status 200" do
get :show, model: "group", mounted_as: "avatar", id: group.id, filename: "image.png"
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it_behaves_like 'content not cached without revalidation' do
@@ -378,7 +378,7 @@ describe UploadsController do
it "responds with status 200" do
get :show, model: "group", mounted_as: "avatar", id: group.id, filename: "image.png"
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it_behaves_like 'content not cached without revalidation' do
@@ -394,7 +394,7 @@ describe UploadsController do
it "responds with status 404" do
get :show, model: "group", mounted_as: "avatar", id: group.id, filename: "image.png"
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -414,7 +414,7 @@ describe UploadsController do
it "responds with status 200" do
get :show, model: "note", mounted_as: "attachment", id: note.id, filename: "image.png"
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it_behaves_like 'content not cached without revalidation' do
@@ -433,7 +433,7 @@ describe UploadsController do
it "responds with status 200" do
get :show, model: "note", mounted_as: "attachment", id: note.id, filename: "image.png"
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it_behaves_like 'content not cached without revalidation' do
@@ -485,7 +485,7 @@ describe UploadsController do
it "responds with status 200" do
get :show, model: "note", mounted_as: "attachment", id: note.id, filename: "image.png"
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it_behaves_like 'content not cached without revalidation' do
@@ -501,7 +501,7 @@ describe UploadsController do
it "responds with status 404" do
get :show, model: "note", mounted_as: "attachment", id: note.id, filename: "image.png"
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -516,7 +516,7 @@ describe UploadsController do
it 'responds with status 200' do
get :show, model: 'appearance', mounted_as: 'header_logo', id: appearance.id, filename: 'dk.png'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it_behaves_like 'content not cached without revalidation' do
@@ -535,7 +535,7 @@ describe UploadsController do
it 'responds with status 200' do
get :show, model: 'appearance', mounted_as: 'logo', id: appearance.id, filename: 'dk.png'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it_behaves_like 'content not cached without revalidation' do
diff --git a/spec/controllers/users_controller_spec.rb b/spec/controllers/users_controller_spec.rb
index 2cecd2646fc..01ab59aa363 100644
--- a/spec/controllers/users_controller_spec.rb
+++ b/spec/controllers/users_controller_spec.rb
@@ -24,7 +24,7 @@ describe UsersController do
it 'renders the show template' do
get :show, username: user.username
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to render_template('show')
end
end
@@ -49,7 +49,7 @@ describe UsersController do
it 'renders show' do
get :show, username: user.username
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to render_template('show')
end
end
@@ -70,7 +70,7 @@ describe UsersController do
it 'renders 404' do
get :show, username: 'nonexistent'
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -82,7 +82,7 @@ describe UsersController do
get :calendar, username: user.username, format: :json
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
context 'forked project' do
@@ -139,7 +139,7 @@ describe UsersController do
context 'format html' do
it 'renders snippets page' do
get :snippets, username: user.username
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to render_template('show')
end
end
@@ -147,7 +147,7 @@ describe UsersController do
context 'format json' do
it 'response with snippets json data' do
get :snippets, username: user.username, format: :json
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(JSON.parse(response.body)).to have_key('html')
end
end
diff --git a/spec/factories/ci/builds.rb b/spec/factories/ci/builds.rb
index c2b59239af9..cf38066dedc 100644
--- a/spec/factories/ci/builds.rb
+++ b/spec/factories/ci/builds.rb
@@ -119,7 +119,7 @@ FactoryGirl.define do
finished_at nil
end
- factory :ci_build_tag do
+ trait :tag do
tag true
end
diff --git a/spec/factories/instance_configuration.rb b/spec/factories/instance_configuration.rb
new file mode 100644
index 00000000000..406c7c3caf1
--- /dev/null
+++ b/spec/factories/instance_configuration.rb
@@ -0,0 +1,5 @@
+FactoryGirl.define do
+ factory :instance_configuration do
+ skip_create
+ end
+end
diff --git a/spec/factories/services.rb b/spec/factories/services.rb
index c2674ce2d11..ccf63f3ffa4 100644
--- a/spec/factories/services.rb
+++ b/spec/factories/services.rb
@@ -38,6 +38,8 @@ FactoryGirl.define do
active true
properties(
url: 'https://jira.example.com',
+ username: 'jira_user',
+ password: 'my-secret-password',
project_key: 'jira-key'
)
end
diff --git a/spec/features/admin/admin_settings_spec.rb b/spec/features/admin/admin_settings_spec.rb
index c490dce7ab0..85561511101 100644
--- a/spec/features/admin/admin_settings_spec.rb
+++ b/spec/features/admin/admin_settings_spec.rb
@@ -95,6 +95,29 @@ feature 'Admin updates settings' do
expect(find_field('ED25519 SSH keys').value).to eq(forbidden)
end
+ scenario 'Change Performance Bar settings' do
+ group = create(:group)
+
+ check 'Enable the Performance Bar'
+ fill_in 'Allowed group', with: group.path
+
+ click_on 'Save'
+
+ expect(page).to have_content 'Application settings saved successfully'
+
+ expect(find_field('Enable the Performance Bar')).to be_checked
+ expect(find_field('Allowed group').value).to eq group.path
+
+ uncheck 'Enable the Performance Bar'
+
+ click_on 'Save'
+
+ expect(page).to have_content 'Application settings saved successfully'
+
+ expect(find_field('Enable the Performance Bar')).not_to be_checked
+ expect(find_field('Allowed group').value).to be_nil
+ end
+
def check_all_events
page.check('Active')
page.check('Push')
diff --git a/spec/features/boards/boards_spec.rb b/spec/features/boards/boards_spec.rb
index 60ed17c0c81..ebe6939df4c 100644
--- a/spec/features/boards/boards_spec.rb
+++ b/spec/features/boards/boards_spec.rb
@@ -538,7 +538,7 @@ describe 'Issue Boards', :js do
end
it 'does not show create new list' do
- expect(page).not_to have_selector('.js-new-board-list')
+ expect(page).not_to have_button('.js-new-board-list')
end
it 'does not allow dragging' do
diff --git a/spec/features/groups/milestone_spec.rb b/spec/features/groups/milestone_spec.rb
index 12aa54a3da1..1b41b3842c8 100644
--- a/spec/features/groups/milestone_spec.rb
+++ b/spec/features/groups/milestone_spec.rb
@@ -19,9 +19,9 @@ feature 'Group milestones', :js do
end
it 'renders description preview' do
- form = find('.gfm-form')
+ description = find('.note-textarea')
- form.fill_in(:milestone_description, with: '')
+ description.native.send_keys('')
click_link('Preview')
@@ -31,7 +31,7 @@ feature 'Group milestones', :js do
click_link('Write')
- form.fill_in(:milestone_description, with: ':+1: Nice')
+ description.native.send_keys(':+1: Nice')
click_link('Preview')
@@ -51,6 +51,13 @@ feature 'Group milestones', :js do
expect(find('.start_date')).to have_content(Date.today.at_beginning_of_month.strftime('%b %-d, %Y'))
end
+
+ it 'description input does not support autocomplete' do
+ description = find('.note-textarea')
+ description.native.send_keys('!')
+
+ expect(page).not_to have_selector('.atwho-view')
+ end
end
context 'milestones list' do
diff --git a/spec/features/issues/form_spec.rb b/spec/features/issues/form_spec.rb
index 8ce470fc288..2db6f9a2982 100644
--- a/spec/features/issues/form_spec.rb
+++ b/spec/features/issues/form_spec.rb
@@ -218,15 +218,54 @@ describe 'New/edit issue', :js do
context 'edit issue' do
before do
- visit project_issue_path(project, issue)
- page.within('.content .issuable-actions') do
- click_on 'Edit'
+ visit edit_project_issue_path(project, issue)
+ end
+
+ it 'allows user to update issue' do
+ expect(find('input[name="issue[assignee_ids][]"]', visible: false).value).to match(user.id.to_s)
+ expect(find('input[name="issue[milestone_id]"]', visible: false).value).to match(milestone.id.to_s)
+ expect(find('a', text: 'Assign to me', visible: false)).not_to be_visible
+
+ page.within '.js-user-search' do
+ expect(page).to have_content user.name
+ end
+
+ page.within '.js-milestone-select' do
+ expect(page).to have_content milestone.title
+ end
+
+ click_button 'Labels'
+ page.within '.dropdown-menu-labels' do
+ click_link label.title
+ click_link label2.title
+ end
+ page.within '.js-label-select' do
+ expect(page).to have_content label.title
+ end
+ expect(page.all('input[name="issue[label_ids][]"]', visible: false)[1].value).to match(label.id.to_s)
+ expect(page.all('input[name="issue[label_ids][]"]', visible: false)[2].value).to match(label2.id.to_s)
+
+ click_button 'Save changes'
+
+ page.within '.issuable-sidebar' do
+ page.within '.assignee' do
+ expect(page).to have_content user.name
+ end
+
+ page.within '.milestone' do
+ expect(page).to have_content milestone.title
+ end
+
+ page.within '.labels' do
+ expect(page).to have_content label.title
+ expect(page).to have_content label2.title
+ end
end
end
it 'description has autocomplete' do
- find_field('issue-description').native.send_keys('')
- fill_in 'issue-description', with: '@'
+ find('#issue_description').native.send_keys('')
+ fill_in 'issue_description', with: '@'
expect(page).to have_selector('.atwho-view')
end
diff --git a/spec/features/issues_spec.rb b/spec/features/issues_spec.rb
index 25e99774575..d4fd3a50008 100644
--- a/spec/features/issues_spec.rb
+++ b/spec/features/issues_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe 'Issues', :js do
+describe 'Issues' do
include DropzoneHelper
include IssueHelpers
include SortingHelper
@@ -24,15 +24,109 @@ describe 'Issues', :js do
end
before do
- visit project_issue_path(project, issue)
- page.within('.content .issuable-actions') do
- find('.issuable-edit').click
- end
- find('.issue-details .content-block .js-zen-enter').click
+ visit edit_project_issue_path(project, issue)
+ find('.js-zen-enter').click
end
it 'opens new issue popup' do
- expect(page).to have_content(issue.description)
+ expect(page).to have_content("Issue ##{issue.iid}")
+ end
+ end
+
+ describe 'Editing issue assignee' do
+ let!(:issue) do
+ create(:issue,
+ author: user,
+ assignees: [user],
+ project: project)
+ end
+
+ it 'allows user to select unassigned', :js do
+ visit edit_project_issue_path(project, issue)
+
+ expect(page).to have_content "Assignee #{user.name}"
+
+ first('.js-user-search').click
+ click_link 'Unassigned'
+
+ click_button 'Save changes'
+
+ page.within('.assignee') do
+ expect(page).to have_content 'No assignee - assign yourself'
+ end
+
+ expect(issue.reload.assignees).to be_empty
+ end
+ end
+
+ describe 'due date', :js do
+ context 'on new form' do
+ before do
+ visit new_project_issue_path(project)
+ end
+
+ it 'saves with due date' do
+ date = Date.today.at_beginning_of_month
+
+ fill_in 'issue_title', with: 'bug 345'
+ fill_in 'issue_description', with: 'bug description'
+ find('#issuable-due-date').click
+
+ page.within '.pika-single' do
+ click_button date.day
+ end
+
+ expect(find('#issuable-due-date').value).to eq date.to_s
+
+ click_button 'Submit issue'
+
+ page.within '.issuable-sidebar' do
+ expect(page).to have_content date.to_s(:medium)
+ end
+ end
+ end
+
+ context 'on edit form' do
+ let(:issue) { create(:issue, author: user, project: project, due_date: Date.today.at_beginning_of_month.to_s) }
+
+ before do
+ visit edit_project_issue_path(project, issue)
+ end
+
+ it 'saves with due date' do
+ date = Date.today.at_beginning_of_month
+
+ expect(find('#issuable-due-date').value).to eq date.to_s
+
+ date = date.tomorrow
+
+ fill_in 'issue_title', with: 'bug 345'
+ fill_in 'issue_description', with: 'bug description'
+ find('#issuable-due-date').click
+
+ page.within '.pika-single' do
+ click_button date.day
+ end
+
+ expect(find('#issuable-due-date').value).to eq date.to_s
+
+ click_button 'Save changes'
+
+ page.within '.issuable-sidebar' do
+ expect(page).to have_content date.to_s(:medium)
+ end
+ end
+
+ it 'warns about version conflict' do
+ issue.update(title: "New title")
+
+ fill_in 'issue_title', with: 'bug 345'
+ fill_in 'issue_description', with: 'bug description'
+
+ click_button 'Save changes'
+
+ expect(page).to have_content 'Someone edited the issue the same time you did'
+ end
end
end
diff --git a/spec/features/merge_requests/created_from_fork_spec.rb b/spec/features/merge_requests/created_from_fork_spec.rb
index d03ddfece74..ca2225318cd 100644
--- a/spec/features/merge_requests/created_from_fork_spec.rb
+++ b/spec/features/merge_requests/created_from_fork_spec.rb
@@ -83,7 +83,6 @@ feature 'Merge request created from fork' do
page.within('.merge-request-tabs') { click_link 'Pipelines' }
page.within('.ci-table') do
- expect(page).to have_content pipeline.status
expect(page).to have_content pipeline.id
end
end
diff --git a/spec/features/profiles/chat_names_spec.rb b/spec/features/profiles/chat_names_spec.rb
index 35793539e0e..5c959acbbc9 100644
--- a/spec/features/profiles/chat_names_spec.rb
+++ b/spec/features/profiles/chat_names_spec.rb
@@ -33,7 +33,7 @@ feature 'Profile > Chat' do
scenario 'second use of link is denied' do
visit authorize_path
- expect(page).to have_http_status(:not_found)
+ expect(page).to have_gitlab_http_status(:not_found)
end
end
@@ -51,7 +51,7 @@ feature 'Profile > Chat' do
scenario 'second use of link is denied' do
visit authorize_path
- expect(page).to have_http_status(:not_found)
+ expect(page).to have_gitlab_http_status(:not_found)
end
end
end
diff --git a/spec/features/profiles/password_spec.rb b/spec/features/profiles/password_spec.rb
index 225d4c16841..fb4355074df 100644
--- a/spec/features/profiles/password_spec.rb
+++ b/spec/features/profiles/password_spec.rb
@@ -58,7 +58,7 @@ describe 'Profile > Password' do
visit edit_profile_password_path
- expect(page).to have_http_status(200)
+ expect(page).to have_gitlab_http_status(200)
end
end
@@ -68,7 +68,7 @@ describe 'Profile > Password' do
it 'renders 404' do
visit edit_profile_password_path
- expect(page).to have_http_status(404)
+ expect(page).to have_gitlab_http_status(404)
end
end
end
diff --git a/spec/features/projects/badges/coverage_spec.rb b/spec/features/projects/badges/coverage_spec.rb
index 368a046f741..c68e10a2563 100644
--- a/spec/features/projects/badges/coverage_spec.rb
+++ b/spec/features/projects/badges/coverage_spec.rb
@@ -50,7 +50,7 @@ feature 'test coverage badge' do
scenario 'user requests test coverage badge image' do
show_test_coverage_badge
- expect(page).to have_http_status(404)
+ expect(page).to have_gitlab_http_status(404)
end
end
diff --git a/spec/features/projects/commit/builds_spec.rb b/spec/features/projects/commit/builds_spec.rb
index 9c57626ea1d..79e84a4f0a6 100644
--- a/spec/features/projects/commit/builds_spec.rb
+++ b/spec/features/projects/commit/builds_spec.rb
@@ -20,7 +20,6 @@ feature 'project commit pipelines', :js do
visit pipelines_project_commit_path(project, project.commit.sha)
page.within('.table-holder') do
- expect(page).to have_content project.pipelines[0].status # pipeline status
expect(page).to have_content project.pipelines[0].id # pipeline ids
end
end
diff --git a/spec/features/projects/environments/environment_spec.rb b/spec/features/projects/environments/environment_spec.rb
index 56addd64056..0fe1eb4c293 100644
--- a/spec/features/projects/environments/environment_spec.rb
+++ b/spec/features/projects/environments/environment_spec.rb
@@ -198,7 +198,7 @@ feature 'Environment' do
end
it 'renders a correct environment folder' do
- expect(page).to have_http_status(:ok)
+ expect(page).to have_gitlab_http_status(:ok)
expect(page).to have_content('Environments / staging-1.0')
end
end
diff --git a/spec/features/projects/jobs_spec.rb b/spec/features/projects/jobs_spec.rb
index 576870ea0f3..b095c3e6f7b 100644
--- a/spec/features/projects/jobs_spec.rb
+++ b/spec/features/projects/jobs_spec.rb
@@ -396,7 +396,7 @@ feature 'Jobs' do
end
it 'shows the right status and buttons', :js do
- expect(page).to have_http_status(200)
+ expect(page).to have_gitlab_http_status(200)
page.within('aside.right-sidebar') do
expect(page).to have_content 'Cancel'
end
diff --git a/spec/features/projects/members/share_with_group_spec.rb b/spec/features/projects/members/share_with_group_spec.rb
index 3b368f8e25d..63b5df5a8f5 100644
--- a/spec/features/projects/members/share_with_group_spec.rb
+++ b/spec/features/projects/members/share_with_group_spec.rb
@@ -149,7 +149,7 @@ feature 'Project > Members > Share with Group', :js do
create(:group).add_owner(master)
visit project_settings_members_path(project)
- execute_script 'GroupsSelect.PER_PAGE = 1;'
+ execute_script 'GROUP_SELECT_PER_PAGE = 1;'
open_select2 '#link_group_id'
end
diff --git a/spec/features/projects/merge_requests/user_manages_subscription_spec.rb b/spec/features/projects/merge_requests/user_manages_subscription_spec.rb
index 30a80f8e652..4ca435491cb 100644
--- a/spec/features/projects/merge_requests/user_manages_subscription_spec.rb
+++ b/spec/features/projects/merge_requests/user_manages_subscription_spec.rb
@@ -13,7 +13,7 @@ describe 'User manages subscription', :js do
end
it 'toggles subscription' do
- subscribe_button = find('.issuable-subscribe-button span')
+ subscribe_button = find('.js-issuable-subscribe-button')
expect(subscribe_button).to have_content('Subscribe')
diff --git a/spec/features/projects/pipelines/pipelines_spec.rb b/spec/features/projects/pipelines/pipelines_spec.rb
index c35b0840248..ae888fd4343 100644
--- a/spec/features/projects/pipelines/pipelines_spec.rb
+++ b/spec/features/projects/pipelines/pipelines_spec.rb
@@ -525,7 +525,7 @@ describe 'Pipelines', :js do
let(:project) { create(:project, :public, :repository) }
it { expect(page).to have_content 'Build with confidence' }
- it { expect(page).to have_http_status(:success) }
+ it { expect(page).to have_gitlab_http_status(:success) }
end
context 'when project is private' do
diff --git a/spec/features/projects/ref_switcher_spec.rb b/spec/features/projects/ref_switcher_spec.rb
index f8695403857..50c0bfd580d 100644
--- a/spec/features/projects/ref_switcher_spec.rb
+++ b/spec/features/projects/ref_switcher_spec.rb
@@ -6,6 +6,7 @@ feature 'Ref switcher', :js do
before do
project.team << [user, :master]
+ page.driver.set_cookie('new_repo', 'true')
sign_in(user)
visit project_tree_path(project, 'master')
end
@@ -40,4 +41,38 @@ feature 'Ref switcher', :js do
expect(page).to have_title "'test'"
end
+
+ context "create branch" do
+ let(:input) { find('.js-new-branch-name') }
+
+ before do
+ click_button 'master'
+ wait_for_requests
+
+ page.within '.project-refs-form' do
+ find(".dropdown-footer-list a").click
+ end
+ end
+
+ it "shows error message for the invalid branch name" do
+ input.set 'foo bar'
+ click_button('Create')
+ wait_for_requests
+ expect(page).to have_content 'Branch name is invalid'
+ end
+
+ it "should create new branch properly" do
+ input.set 'new-branch-name'
+ click_button('Create')
+ wait_for_requests
+ expect(find('.js-project-refs-dropdown')).to have_content 'new-branch-name'
+ end
+
+ it "should create new branch by Enter key" do
+ input.set 'new-branch-name-2'
+ input.native.send_keys :enter
+ wait_for_requests
+ expect(find('.js-project-refs-dropdown')).to have_content 'new-branch-name-2'
+ end
+ end
end
diff --git a/spec/features/projects/services/user_activates_packagist_spec.rb b/spec/features/projects/services/user_activates_packagist_spec.rb
new file mode 100644
index 00000000000..b0cc818f093
--- /dev/null
+++ b/spec/features/projects/services/user_activates_packagist_spec.rb
@@ -0,0 +1,24 @@
+require 'spec_helper'
+
+describe 'User activates Packagist' do
+ let(:project) { create(:project) }
+ let(:user) { create(:user) }
+
+ before do
+ project.add_master(user)
+ sign_in(user)
+
+ visit(project_settings_integrations_path(project))
+
+ click_link('Packagist')
+ end
+
+ it 'activates service' do
+ check('Active')
+ fill_in('Username', with: 'theUser')
+ fill_in('Token', with: 'verySecret')
+ click_button('Save')
+
+ expect(page).to have_content('Packagist activated.')
+ end
+end
diff --git a/spec/features/projects/services/user_views_services_spec.rb b/spec/features/projects/services/user_views_services_spec.rb
index f86591c2633..5c5e8b66642 100644
--- a/spec/features/projects/services/user_views_services_spec.rb
+++ b/spec/features/projects/services/user_views_services_spec.rb
@@ -21,5 +21,6 @@ describe 'User views services' do
expect(page).to have_content('JetBrains TeamCity')
expect(page).to have_content('Asana')
expect(page).to have_content('Irker (IRC gateway)')
+ expect(page).to have_content('Packagist')
end
end
diff --git a/spec/features/projects/tree/create_directory_spec.rb b/spec/features/projects/tree/create_directory_spec.rb
new file mode 100644
index 00000000000..4c1fa5a666e
--- /dev/null
+++ b/spec/features/projects/tree/create_directory_spec.rb
@@ -0,0 +1,43 @@
+require 'spec_helper'
+
+feature 'Multi-file editor new directory', :js do
+ include WaitForRequests
+
+ let(:user) { create(:user) }
+ let(:project) { create(:project, :repository) }
+
+ before do
+ project.add_master(user)
+ sign_in(user)
+
+ page.driver.set_cookie('new_repo', 'true')
+
+ visit project_tree_path(project, :master)
+
+ wait_for_requests
+ end
+
+ it 'creates directory in current directory' do
+ find('.add-to-tree').click
+
+ click_link('New directory')
+
+ page.within('.popup-dialog') do
+ find('.form-control').set('foldername')
+
+ click_button('Create directory')
+ end
+
+ fill_in('commit-message', with: 'commit message')
+
+ click_button('Commit 1 file')
+
+ expect(page).to have_content('Your changes have been committed')
+ expect(page).to have_selector('td', text: 'commit message')
+
+ click_link('foldername')
+
+ expect(page).to have_selector('td', text: 'commit message', count: 2)
+ expect(page).to have_selector('td', text: '.gitkeep')
+ end
+end
diff --git a/spec/features/projects/tree/create_file_spec.rb b/spec/features/projects/tree/create_file_spec.rb
new file mode 100644
index 00000000000..ed3b52a5790
--- /dev/null
+++ b/spec/features/projects/tree/create_file_spec.rb
@@ -0,0 +1,38 @@
+require 'spec_helper'
+
+feature 'Multi-file editor new file', :js do
+ include WaitForRequests
+
+ let(:user) { create(:user) }
+ let(:project) { create(:project, :repository) }
+
+ before do
+ project.add_master(user)
+ sign_in(user)
+
+ page.driver.set_cookie('new_repo', 'true')
+
+ visit project_tree_path(project, :master)
+
+ wait_for_requests
+ end
+
+ it 'creates file in current directory' do
+ find('.add-to-tree').click
+
+ click_link('New file')
+
+ page.within('.popup-dialog') do
+ find('.form-control').set('filename')
+
+ click_button('Create file')
+ end
+
+ fill_in('commit-message', with: 'commit message')
+
+ click_button('Commit 1 file')
+
+ expect(page).to have_content('Your changes have been committed')
+ expect(page).to have_selector('td', text: 'commit message')
+ end
+end
diff --git a/spec/features/projects/tree/upload_file_spec.rb b/spec/features/projects/tree/upload_file_spec.rb
new file mode 100644
index 00000000000..7dbe4fd0aa5
--- /dev/null
+++ b/spec/features/projects/tree/upload_file_spec.rb
@@ -0,0 +1,48 @@
+require 'spec_helper'
+
+feature 'Multi-file editor upload file', :js do
+ include WaitForRequests
+
+ let(:user) { create(:user) }
+ let(:project) { create(:project, :repository) }
+ let(:txt_file) { File.join(Rails.root, 'spec', 'fixtures', 'doc_sample.txt') }
+ let(:img_file) { File.join(Rails.root, 'spec', 'fixtures', 'dk.png') }
+
+ before do
+ project.add_master(user)
+ sign_in(user)
+
+ page.driver.set_cookie('new_repo', 'true')
+
+ visit project_tree_path(project, :master)
+
+ wait_for_requests
+ end
+
+ it 'uploads text file' do
+ find('.add-to-tree').click
+
+ # make the field visible so capybara can use it
+ execute_script('document.querySelector("#file-upload").classList.remove("hidden")')
+ attach_file('file-upload', txt_file)
+
+ find('.add-to-tree').click
+
+ expect(page).to have_selector('.repo-tab', text: 'doc_sample.txt')
+ expect(page).to have_content(File.open(txt_file, &:readline))
+ end
+
+ it 'uploads image file' do
+ find('.add-to-tree').click
+
+ # make the field visible so capybara can use it
+ execute_script('document.querySelector("#file-upload").classList.remove("hidden")')
+ attach_file('file-upload', img_file)
+
+ find('.add-to-tree').click
+
+ expect(page).to have_selector('.repo-tab', text: 'dk.png')
+ expect(page).not_to have_selector('.monaco-editor')
+ expect(page).to have_content('The source could not be displayed for this temporary file.')
+ end
+end
diff --git a/spec/features/security/project/internal_access_spec.rb b/spec/features/security/project/internal_access_spec.rb
index d70cf1527e7..a7928857b7d 100644
--- a/spec/features/security/project/internal_access_spec.rb
+++ b/spec/features/security/project/internal_access_spec.rb
@@ -181,6 +181,21 @@ describe "Internal Project Access" do
it { is_expected.to be_denied_for(:visitor) }
end
+ describe "GET /:project_path/issues/:id/edit" do
+ let(:issue) { create(:issue, project: project) }
+ subject { edit_project_issue_path(project, issue) }
+
+ it { is_expected.to be_allowed_for(:admin) }
+ it { is_expected.to be_allowed_for(:owner).of(project) }
+ it { is_expected.to be_allowed_for(:master).of(project) }
+ it { is_expected.to be_allowed_for(:developer).of(project) }
+ it { is_expected.to be_allowed_for(:reporter).of(project) }
+ it { is_expected.to be_denied_for(:guest).of(project) }
+ it { is_expected.to be_denied_for(:user) }
+ it { is_expected.to be_denied_for(:external) }
+ it { is_expected.to be_denied_for(:visitor) }
+ end
+
describe "GET /:project_path/snippets" do
subject { project_snippets_path(project) }
diff --git a/spec/features/security/project/private_access_spec.rb b/spec/features/security/project/private_access_spec.rb
index ea130606545..a4396b20afd 100644
--- a/spec/features/security/project/private_access_spec.rb
+++ b/spec/features/security/project/private_access_spec.rb
@@ -181,6 +181,21 @@ describe "Private Project Access" do
it { is_expected.to be_denied_for(:visitor) }
end
+ describe "GET /:project_path/issues/:id/edit" do
+ let(:issue) { create(:issue, project: project) }
+ subject { edit_project_issue_path(project, issue) }
+
+ it { is_expected.to be_allowed_for(:admin) }
+ it { is_expected.to be_allowed_for(:owner).of(project) }
+ it { is_expected.to be_allowed_for(:master).of(project) }
+ it { is_expected.to be_allowed_for(:developer).of(project) }
+ it { is_expected.to be_allowed_for(:reporter).of(project) }
+ it { is_expected.to be_denied_for(:guest).of(project) }
+ it { is_expected.to be_denied_for(:user) }
+ it { is_expected.to be_denied_for(:external) }
+ it { is_expected.to be_denied_for(:visitor) }
+ end
+
describe "GET /:project_path/snippets" do
subject { project_snippets_path(project) }
diff --git a/spec/features/security/project/public_access_spec.rb b/spec/features/security/project/public_access_spec.rb
index d15f5af66c9..fccdeb0e5b7 100644
--- a/spec/features/security/project/public_access_spec.rb
+++ b/spec/features/security/project/public_access_spec.rb
@@ -394,6 +394,21 @@ describe "Public Project Access" do
it { is_expected.to be_allowed_for(:visitor) }
end
+ describe "GET /:project_path/issues/:id/edit" do
+ let(:issue) { create(:issue, project: project) }
+ subject { edit_project_issue_path(project, issue) }
+
+ it { is_expected.to be_allowed_for(:admin) }
+ it { is_expected.to be_allowed_for(:owner).of(project) }
+ it { is_expected.to be_allowed_for(:master).of(project) }
+ it { is_expected.to be_allowed_for(:developer).of(project) }
+ it { is_expected.to be_allowed_for(:reporter).of(project) }
+ it { is_expected.to be_denied_for(:guest).of(project) }
+ it { is_expected.to be_denied_for(:user) }
+ it { is_expected.to be_denied_for(:external) }
+ it { is_expected.to be_denied_for(:visitor) }
+ end
+
describe "GET /:project_path/snippets" do
subject { project_snippets_path(project) }
diff --git a/spec/finders/branches_finder_spec.rb b/spec/finders/branches_finder_spec.rb
index 91f34973ba5..9e3f2c69606 100644
--- a/spec/finders/branches_finder_spec.rb
+++ b/spec/finders/branches_finder_spec.rb
@@ -46,6 +46,15 @@ describe BranchesFinder do
expect(result.count).to eq(1)
end
+ it 'filters branches by name ignoring letter case' do
+ branches_finder = described_class.new(repository, { search: 'FiX' })
+
+ result = branches_finder.execute
+
+ expect(result.first.name).to eq('fix')
+ expect(result.count).to eq(1)
+ end
+
it 'does not find any branch with that name' do
branches_finder = described_class.new(repository, { search: 'random' })
diff --git a/spec/fixtures/api/schemas/entities/issue.json b/spec/fixtures/api/schemas/entities/issue.json
new file mode 100644
index 00000000000..3d3329a3406
--- /dev/null
+++ b/spec/fixtures/api/schemas/entities/issue.json
@@ -0,0 +1,44 @@
+{
+ "type": "object",
+ "properties" : {
+ "id": { "type": "integer" },
+ "iid": { "type": "integer" },
+ "author_id": { "type": "integer" },
+ "description": { "type": ["string", "null"] },
+ "lock_version": { "type": ["string", "null"] },
+ "milestone_id": { "type": ["string", "null"] },
+ "title": { "type": "string" },
+ "moved_to_id": { "type": ["integer", "null"] },
+ "project_id": { "type": "integer" },
+ "web_url": { "type": "string" },
+ "state": { "type": "string" },
+ "create_note_path": { "type": "string" },
+ "preview_note_path": { "type": "string" },
+ "current_user": {
+ "type": "object",
+ "properties": {
+ "can_create_note": { "type": "boolean" },
+ "can_update": { "type": "boolean" }
+ }
+ },
+ "created_at": { "type": "date-time" },
+ "updated_at": { "type": "date-time" },
+ "branch_name": { "type": ["string", "null"] },
+ "due_date": { "type": "date" },
+ "confidential": { "type": "boolean" },
+ "discussion_locked": { "type": ["boolean", "null"] },
+ "updated_by_id": { "type": ["string", "null"] },
+ "deleted_at": { "type": ["string", "null"] },
+ "time_estimate": { "type": "integer" },
+ "total_time_spent": { "type": "integer" },
+ "human_time_estimate": { "type": ["integer", "null"] },
+ "human_total_time_spent": { "type": ["integer", "null"] },
+ "milestone": { "type": ["object", "null"] },
+ "labels": {
+ "type": "array",
+ "items": { "$ref": "label.json" }
+ },
+ "assignees": { "type": ["array", "null"] }
+ },
+ "additionalProperties": false
+}
diff --git a/spec/fixtures/api/schemas/entities/issue_sidebar.json b/spec/fixtures/api/schemas/entities/issue_sidebar.json
new file mode 100644
index 00000000000..682e345d5f5
--- /dev/null
+++ b/spec/fixtures/api/schemas/entities/issue_sidebar.json
@@ -0,0 +1,21 @@
+{
+ "type": "object",
+ "properties" : {
+ "id": { "type": "integer" },
+ "iid": { "type": "integer" },
+ "subscribed": { "type": "boolean" },
+ "time_estimate": { "type": "integer" },
+ "total_time_spent": { "type": "integer" },
+ "human_time_estimate": { "type": ["integer", "null"] },
+ "human_total_time_spent": { "type": ["integer", "null"] },
+ "participants": {
+ "type": "array",
+ "items": { "$ref": "../public_api/v4/user/basic.json" }
+ },
+ "assignees": {
+ "type": "array",
+ "items": { "$ref": "../public_api/v4/user/basic.json" }
+ }
+ },
+ "additionalProperties": false
+}
diff --git a/spec/fixtures/api/schemas/entities/label.json b/spec/fixtures/api/schemas/entities/label.json
new file mode 100644
index 00000000000..40dff764c17
--- /dev/null
+++ b/spec/fixtures/api/schemas/entities/label.json
@@ -0,0 +1,26 @@
+{
+ "type": "object",
+ "required": [
+ "id",
+ "color",
+ "description",
+ "title",
+ "priority"
+ ],
+ "properties": {
+ "id": { "type": "integer" },
+ "color": {
+ "type": "string",
+ "pattern": "^#[0-9A-Fa-f]{3}{1,2}$"
+ },
+ "description": { "type": ["string", "null"] },
+ "text_color": {
+ "type": "string",
+ "pattern": "^#[0-9A-Fa-f]{3}{1,2}$"
+ },
+ "type": { "type": "string" },
+ "title": { "type": "string" },
+ "priority": { "type": ["integer", "null"] }
+ },
+ "additionalProperties": false
+} \ No newline at end of file
diff --git a/spec/fixtures/api/schemas/entities/merge_request_basic.json b/spec/fixtures/api/schemas/entities/merge_request_basic.json
index 6b14188582a..995f13381ad 100644
--- a/spec/fixtures/api/schemas/entities/merge_request_basic.json
+++ b/spec/fixtures/api/schemas/entities/merge_request_basic.json
@@ -9,7 +9,9 @@
"human_time_estimate": { "type": ["string", "null"] },
"human_total_time_spent": { "type": ["string", "null"] },
"merge_error": { "type": ["string", "null"] },
- "assignee_id": { "type": ["integer", "null"] }
+ "assignee_id": { "type": ["integer", "null"] },
+ "subscribed": { "type": ["boolean", "null"] },
+ "participants": { "type": "array" }
},
"additionalProperties": false
}
diff --git a/spec/fixtures/api/schemas/issue.json b/spec/fixtures/api/schemas/issue.json
index e1f62508933..a55ecaa5697 100644
--- a/spec/fixtures/api/schemas/issue.json
+++ b/spec/fixtures/api/schemas/issue.json
@@ -19,32 +19,7 @@
},
"labels": {
"type": "array",
- "items": {
- "type": "object",
- "required": [
- "id",
- "color",
- "description",
- "title",
- "priority"
- ],
- "properties": {
- "id": { "type": "integer" },
- "color": {
- "type": "string",
- "pattern": "^#[0-9A-Fa-f]{3}{1,2}+$"
- },
- "description": { "type": ["string", "null"] },
- "text_color": {
- "type": "string",
- "pattern": "^#[0-9A-Fa-f]{3}{1,2}+$"
- },
- "type": { "type": "string" },
- "title": { "type": "string" },
- "priority": { "type": ["integer", "null"] }
- },
- "additionalProperties": false
- }
+ "items": { "$ref": "entities/label.json" }
},
"assignee": {
"id": { "type": "integet" },
diff --git a/spec/fixtures/api/schemas/public_api/v4/pages_domains.json b/spec/fixtures/api/schemas/public_api/v4/pages_domains.json
new file mode 100644
index 00000000000..0de1d0f1228
--- /dev/null
+++ b/spec/fixtures/api/schemas/public_api/v4/pages_domains.json
@@ -0,0 +1,23 @@
+{
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "domain": { "type": "string" },
+ "url": { "type": "uri" },
+ "certificate": {
+ "type": "object",
+ "properties": {
+ "subject": { "type": "string" },
+ "expired": { "type": "boolean" },
+ "certificate": { "type": "string" },
+ "certificate_text": { "type": "string" }
+ },
+ "required": ["subject", "expired"],
+ "additionalProperties": false
+ }
+ },
+ "required": ["domain", "url"],
+ "additionalProperties": false
+ }
+}
diff --git a/spec/fixtures/ssh_host_example_key.pub b/spec/fixtures/ssh_host_example_key.pub
new file mode 100644
index 00000000000..6bac42b3ad0
--- /dev/null
+++ b/spec/fixtures/ssh_host_example_key.pub
@@ -0,0 +1 @@
+random content
diff --git a/spec/helpers/instance_configuration_helper_spec.rb b/spec/helpers/instance_configuration_helper_spec.rb
new file mode 100644
index 00000000000..5d716b9191d
--- /dev/null
+++ b/spec/helpers/instance_configuration_helper_spec.rb
@@ -0,0 +1,51 @@
+require 'spec_helper'
+
+describe InstanceConfigurationHelper do
+ describe '#instance_configuration_cell_html' do
+ describe 'if not block is passed' do
+ it 'returns the parameter if present' do
+ expect(helper.instance_configuration_cell_html('gitlab')).to eq('gitlab')
+ end
+
+ it 'returns "-" if the parameter is blank' do
+ expect(helper.instance_configuration_cell_html(nil)).to eq('-')
+ expect(helper.instance_configuration_cell_html('')).to eq('-')
+ end
+ end
+
+ describe 'if a block is passed' do
+ let(:upcase_block) { ->(value) { value.upcase } }
+
+ it 'returns the result of the block' do
+ expect(helper.instance_configuration_cell_html('gitlab', &upcase_block)).to eq('GITLAB')
+ expect(helper.instance_configuration_cell_html('gitlab') { |v| v.upcase }).to eq('GITLAB')
+ end
+
+ it 'returns "-" if the parameter is blank' do
+ expect(helper.instance_configuration_cell_html(nil, &upcase_block)).to eq('-')
+ expect(helper.instance_configuration_cell_html(nil) { |v| v.upcase }).to eq('-')
+ expect(helper.instance_configuration_cell_html('', &upcase_block)).to eq('-')
+ end
+ end
+
+ it 'boolean are valid values to display' do
+ expect(helper.instance_configuration_cell_html(true)).to eq(true)
+ expect(helper.instance_configuration_cell_html(false)).to eq(false)
+ end
+ end
+
+ describe '#instance_configuration_human_size_cell' do
+ it 'returns "-" if the parameter is blank' do
+ expect(helper.instance_configuration_human_size_cell(nil)).to eq('-')
+ expect(helper.instance_configuration_human_size_cell('')).to eq('-')
+ end
+
+ it 'accepts the value in bytes' do
+ expect(helper.instance_configuration_human_size_cell(1024)).to eq('1 KB')
+ end
+
+ it 'returns the value in human size readable format' do
+ expect(helper.instance_configuration_human_size_cell(1048576)).to eq('1 MB')
+ end
+ end
+end
diff --git a/spec/javascripts/gl_form_spec.js b/spec/javascripts/gl_form_spec.js
index 124fc030774..5a8009e57fd 100644
--- a/spec/javascripts/gl_form_spec.js
+++ b/spec/javascripts/gl_form_spec.js
@@ -1,9 +1,9 @@
-import autosize from 'vendor/autosize';
+import Autosize from 'autosize';
import GLForm from '~/gl_form';
import '~/lib/utils/text_utility';
import '~/lib/utils/common_utils';
-window.autosize = autosize;
+window.autosize = Autosize;
describe('GLForm', () => {
describe('when instantiated', function () {
diff --git a/spec/javascripts/header_spec.js b/spec/javascripts/header_spec.js
index 4751eb868a4..2443ffd48f3 100644
--- a/spec/javascripts/header_spec.js
+++ b/spec/javascripts/header_spec.js
@@ -1,4 +1,4 @@
-import '~/header';
+import initTodoToggle from '~/header';
describe('Header', function () {
const todosPendingCount = '.todos-count';
@@ -14,6 +14,7 @@ describe('Header', function () {
preloadFixtures(fixtureTemplate);
beforeEach(() => {
+ initTodoToggle();
loadFixtures(fixtureTemplate);
});
diff --git a/spec/javascripts/helpers/vue_mount_component_helper.js b/spec/javascripts/helpers/vue_mount_component_helper.js
index d7a2e86771c..34acdfbfba9 100644
--- a/spec/javascripts/helpers/vue_mount_component_helper.js
+++ b/spec/javascripts/helpers/vue_mount_component_helper.js
@@ -1,4 +1,8 @@
-export default (Component, props = {}) => new Component({
- propsData: props,
-}).$mount();
+export const createComponentWithStore = (Component, store, propsData = {}) => new Component({
+ store,
+ propsData,
+});
+export default (Component, props = {}, el = null) => new Component({
+ propsData: props,
+}).$mount(el);
diff --git a/spec/javascripts/issuable_context_spec.js b/spec/javascripts/issuable_context_spec.js
deleted file mode 100644
index bcb2b7b24a0..00000000000
--- a/spec/javascripts/issuable_context_spec.js
+++ /dev/null
@@ -1,34 +0,0 @@
-/* global IssuableContext */
-import '~/issuable_context';
-import $ from 'jquery';
-
-describe('IssuableContext', () => {
- describe('toggleHiddenParticipants', () => {
- const event = jasmine.createSpyObj('event', ['preventDefault']);
-
- beforeEach(() => {
- spyOn($.fn, 'data').and.returnValue('data');
- spyOn($.fn, 'text').and.returnValue('data');
- });
-
- afterEach(() => {
- gl.lazyLoader = undefined;
- });
-
- it('calls loadCheck if lazyLoader is set', () => {
- gl.lazyLoader = jasmine.createSpyObj('lazyLoader', ['loadCheck']);
-
- IssuableContext.prototype.toggleHiddenParticipants(event);
-
- expect(gl.lazyLoader.loadCheck).toHaveBeenCalled();
- });
-
- it('does not throw if lazyLoader is not defined', () => {
- gl.lazyLoader = undefined;
-
- const toggle = IssuableContext.prototype.toggleHiddenParticipants.bind(null, event);
-
- expect(toggle).not.toThrow();
- });
- });
-});
diff --git a/spec/javascripts/issuable_spec.js b/spec/javascripts/issuable_spec.js
index 45f55395d3a..ceee08d47c5 100644
--- a/spec/javascripts/issuable_spec.js
+++ b/spec/javascripts/issuable_spec.js
@@ -1,80 +1,44 @@
-/* global IssuableIndex */
-
-import '~/lib/utils/url_utility';
-import '~/issuable_index';
-
-(() => {
- const BASE_URL = '/user/project/issues?scope=all&state=closed';
- const DEFAULT_PARAMS = '&utf8=%E2%9C%93';
-
- function updateForm(formValues, form) {
- $.each(formValues, (id, value) => {
- $(`#${id}`, form).val(value);
- });
- }
-
- function resetForm(form) {
- $('input[name!="utf8"]', form).each((index, input) => {
- input.setAttribute('value', '');
+import IssuableIndex from '~/issuable_index';
+
+describe('Issuable', () => {
+ let Issuable;
+ describe('initBulkUpdate', () => {
+ it('should not set bulkUpdateSidebar', () => {
+ Issuable = new IssuableIndex('issue_');
+ expect(Issuable.bulkUpdateSidebar).not.toBeDefined();
});
- }
- describe('Issuable', () => {
- preloadFixtures('static/issuable_filter.html.raw');
+ it('should set bulkUpdateSidebar', () => {
+ const element = document.createElement('div');
+ element.classList.add('issues-bulk-update');
+ document.body.appendChild(element);
- beforeEach(() => {
- loadFixtures('static/issuable_filter.html.raw');
- IssuableIndex.init();
- });
-
- it('should be defined', () => {
- expect(window.IssuableIndex).toBeDefined();
+ Issuable = new IssuableIndex('issue_');
+ expect(Issuable.bulkUpdateSidebar).toBeDefined();
});
+ });
- describe('filtering', () => {
- let $filtersForm;
-
- beforeEach(() => {
- $filtersForm = $('.js-filter-form');
- loadFixtures('static/issuable_filter.html.raw');
- resetForm($filtersForm);
- });
-
- it('should contain only the default parameters', () => {
- spyOn(gl.utils, 'visitUrl');
-
- IssuableIndex.filterResults($filtersForm);
-
- expect(gl.utils.visitUrl).toHaveBeenCalledWith(BASE_URL + DEFAULT_PARAMS);
- });
-
- it('should filter for the phrase "broken"', () => {
- spyOn(gl.utils, 'visitUrl');
-
- updateForm({ search: 'broken' }, $filtersForm);
- IssuableIndex.filterResults($filtersForm);
- const params = `${DEFAULT_PARAMS}&search=broken`;
-
- expect(gl.utils.visitUrl).toHaveBeenCalledWith(BASE_URL + params);
- });
-
- it('should keep query parameters after modifying filter', () => {
- spyOn(gl.utils, 'visitUrl');
+ describe('resetIncomingEmailToken', () => {
+ beforeEach(() => {
+ const element = document.createElement('a');
+ element.classList.add('incoming-email-token-reset');
+ element.setAttribute('href', 'foo');
+ document.body.appendChild(element);
- // initial filter
- updateForm({ milestone_title: 'v1.0' }, $filtersForm);
+ const input = document.createElement('input');
+ input.setAttribute('id', 'issue_email');
+ document.body.appendChild(input);
- IssuableIndex.filterResults($filtersForm);
- let params = `${DEFAULT_PARAMS}&milestone_title=v1.0`;
- expect(gl.utils.visitUrl).toHaveBeenCalledWith(BASE_URL + params);
+ Issuable = new IssuableIndex('issue_');
+ });
- // update filter
- updateForm({ label_name: 'Frontend' }, $filtersForm);
+ it('should send request to reset email token', () => {
+ spyOn(jQuery, 'ajax').and.callThrough();
+ document.querySelector('.incoming-email-token-reset').click();
- IssuableIndex.filterResults($filtersForm);
- params = `${DEFAULT_PARAMS}&milestone_title=v1.0&label_name=Frontend`;
- expect(gl.utils.visitUrl).toHaveBeenCalledWith(BASE_URL + params);
- });
+ expect(jQuery.ajax).toHaveBeenCalled();
+ expect(jQuery.ajax.calls.argsFor(0)[0].url).toEqual('foo');
});
});
-})();
+});
+
diff --git a/spec/javascripts/labels_issue_sidebar_spec.js b/spec/javascripts/labels_issue_sidebar_spec.js
index e47adc49224..4e66304e0ad 100644
--- a/spec/javascripts/labels_issue_sidebar_spec.js
+++ b/spec/javascripts/labels_issue_sidebar_spec.js
@@ -1,12 +1,11 @@
/* eslint-disable no-new */
-/* global IssuableContext */
+import IssuableContext from '~/issuable_context';
/* global LabelsSelect */
import '~/gl_dropdown';
import 'select2';
import '~/api';
import '~/create_label';
-import '~/issuable_context';
import '~/users_select';
import '~/labels_select';
diff --git a/spec/javascripts/merge_request_notes_spec.js b/spec/javascripts/merge_request_notes_spec.js
index ac6ace48108..6054b75d0b8 100644
--- a/spec/javascripts/merge_request_notes_spec.js
+++ b/spec/javascripts/merge_request_notes_spec.js
@@ -1,6 +1,6 @@
/* global Notes */
-import 'vendor/autosize';
+import 'autosize';
import '~/gl_form';
import '~/lib/utils/text_utility';
import '~/render_gfm';
diff --git a/spec/javascripts/merge_request_tabs_spec.js b/spec/javascripts/merge_request_tabs_spec.js
index 18916c5aa97..e441d1153ed 100644
--- a/spec/javascripts/merge_request_tabs_spec.js
+++ b/spec/javascripts/merge_request_tabs_spec.js
@@ -5,8 +5,7 @@ import '~/merge_request_tabs';
import '~/commit/pipelines/pipelines_bundle';
import '~/breakpoints';
import '~/lib/utils/common_utils';
-import '~/diff';
-import '~/files_comment_button';
+import Diff from '~/diff';
import '~/notes';
import 'vendor/jquery.scrollTo';
@@ -225,7 +224,7 @@ import 'vendor/jquery.scrollTo';
describe('with "Side-by-side"/parallel diff view', () => {
beforeEach(function () {
this.class.diffViewType = () => 'parallel';
- gl.Diff.prototype.diffViewType = () => 'parallel';
+ Diff.prototype.diffViewType = () => 'parallel';
});
it('maintains `container-limited` for pipelines tab', function (done) {
diff --git a/spec/javascripts/notes/components/issue_comment_form_spec.js b/spec/javascripts/notes/components/issue_comment_form_spec.js
index 3f659af5c3b..a26fc8f63cc 100644
--- a/spec/javascripts/notes/components/issue_comment_form_spec.js
+++ b/spec/javascripts/notes/components/issue_comment_form_spec.js
@@ -1,5 +1,5 @@
import Vue from 'vue';
-import autosize from 'vendor/autosize';
+import Autosize from 'autosize';
import store from '~/notes/stores';
import issueCommentForm from '~/notes/components/issue_comment_form.vue';
import { loggedOutIssueData, notesDataMock, userDataMock, issueDataMock } from '../mock_data';
@@ -97,14 +97,14 @@ describe('issue_comment_form component', () => {
});
it('should resize textarea after note discarded', (done) => {
- spyOn(autosize, 'update');
+ spyOn(Autosize, 'update');
spyOn(vm, 'discard').and.callThrough();
vm.note = 'foo';
vm.discard();
Vue.nextTick(() => {
- expect(autosize.update).toHaveBeenCalled();
+ expect(Autosize.update).toHaveBeenCalled();
done();
});
});
diff --git a/spec/javascripts/notes/components/issue_placeholder_system_note_spec.js b/spec/javascripts/notes/components/issue_placeholder_system_note_spec.js
deleted file mode 100644
index d508a49f710..00000000000
--- a/spec/javascripts/notes/components/issue_placeholder_system_note_spec.js
+++ /dev/null
@@ -1,24 +0,0 @@
-import Vue from 'vue';
-import placeholderSystemNote from '~/notes/components/issue_placeholder_system_note.vue';
-
-describe('issue placeholder system note component', () => {
- let mountComponent;
- beforeEach(() => {
- const PlaceholderSystemNote = Vue.extend(placeholderSystemNote);
-
- mountComponent = props => new PlaceholderSystemNote({
- propsData: {
- note: {
- body: props,
- },
- },
- }).$mount();
- });
-
- it('should render system note placeholder with plain text', () => {
- const vm = mountComponent('This is a placeholder');
-
- expect(vm.$el.tagName).toEqual('LI');
- expect(vm.$el.querySelector('.timeline-content em').textContent.trim()).toEqual('This is a placeholder');
- });
-});
diff --git a/spec/javascripts/notes_spec.js b/spec/javascripts/notes_spec.js
index 66c52611614..53d8faae911 100644
--- a/spec/javascripts/notes_spec.js
+++ b/spec/javascripts/notes_spec.js
@@ -1,7 +1,7 @@
/* eslint-disable space-before-function-paren, no-unused-expressions, no-var, object-shorthand, comma-dangle, max-len */
/* global Notes */
-import 'vendor/autosize';
+import 'autosize';
import '~/gl_form';
import '~/lib/utils/text_utility';
import '~/render_gfm';
@@ -103,6 +103,16 @@ import '~/notes';
$('.js-comment-button').click();
expect(this.autoSizeSpy).toHaveBeenTriggered();
});
+
+ it('should not place escaped text in the comment box in case of error', function() {
+ const deferred = $.Deferred();
+ spyOn($, 'ajax').and.returnValue(deferred.promise());
+ $(textarea).text('A comment with `markup`.');
+
+ deferred.reject();
+ $('.js-comment-button').click();
+ expect($(textarea).val()).toEqual('A comment with `markup`.');
+ });
});
describe('updateNote', () => {
diff --git a/spec/javascripts/pipelines/pipelines_table_row_spec.js b/spec/javascripts/pipelines/pipelines_table_row_spec.js
index d7456a48bc1..a9126d2f4e9 100644
--- a/spec/javascripts/pipelines/pipelines_table_row_spec.js
+++ b/spec/javascripts/pipelines/pipelines_table_row_spec.js
@@ -10,6 +10,7 @@ describe('Pipelines Table Row', () => {
propsData: {
pipeline,
autoDevopsHelpPath: 'foo',
+ viewType: 'root',
},
}).$mount();
};
diff --git a/spec/javascripts/pipelines/pipelines_table_spec.js b/spec/javascripts/pipelines/pipelines_table_spec.js
index 4f5eb42eb35..ca2f9163313 100644
--- a/spec/javascripts/pipelines/pipelines_table_spec.js
+++ b/spec/javascripts/pipelines/pipelines_table_spec.js
@@ -23,6 +23,7 @@ describe('Pipelines Table', () => {
propsData: {
pipelines: [],
autoDevopsHelpPath: 'foo',
+ viewType: 'root',
},
}).$mount();
});
@@ -49,6 +50,7 @@ describe('Pipelines Table', () => {
propsData: {
pipelines: [],
autoDevopsHelpPath: 'foo',
+ viewType: 'root',
},
}).$mount();
expect(component.$el.querySelectorAll('.commit.gl-responsive-table-row').length).toEqual(0);
@@ -61,6 +63,7 @@ describe('Pipelines Table', () => {
propsData: {
pipelines: [pipeline],
autoDevopsHelpPath: 'foo',
+ viewType: 'root',
},
}).$mount();
diff --git a/spec/javascripts/repo/components/new_branch_form_spec.js b/spec/javascripts/repo/components/new_branch_form_spec.js
new file mode 100644
index 00000000000..9a705a1f0ed
--- /dev/null
+++ b/spec/javascripts/repo/components/new_branch_form_spec.js
@@ -0,0 +1,114 @@
+import Vue from 'vue';
+import store from '~/repo/stores';
+import newBranchForm from '~/repo/components/new_branch_form.vue';
+import { createComponentWithStore } from '../../helpers/vue_mount_component_helper';
+import { resetStore } from '../helpers';
+
+describe('Multi-file editor new branch form', () => {
+ let vm;
+
+ beforeEach(() => {
+ const Component = Vue.extend(newBranchForm);
+
+ vm = createComponentWithStore(Component, store);
+
+ vm.$store.state.currentBranch = 'master';
+
+ vm.$mount();
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+
+ resetStore(vm.$store);
+ });
+
+ describe('template', () => {
+ it('renders submit as disabled', () => {
+ expect(vm.$el.querySelector('.btn').getAttribute('disabled')).toBe('disabled');
+ });
+
+ it('enables the submit button when branch is not empty', (done) => {
+ vm.branchName = 'testing';
+
+ Vue.nextTick(() => {
+ expect(vm.$el.querySelector('.btn').getAttribute('disabled')).toBeNull();
+
+ done();
+ });
+ });
+
+ it('displays current branch creating from', (done) => {
+ Vue.nextTick(() => {
+ expect(vm.$el.querySelector('p').textContent.replace(/\s+/g, ' ').trim()).toBe('Create from: master');
+
+ done();
+ });
+ });
+ });
+
+ describe('submitNewBranch', () => {
+ beforeEach(() => {
+ spyOn(vm, 'createNewBranch').and.returnValue(Promise.resolve());
+ });
+
+ it('sets to loading', () => {
+ vm.submitNewBranch();
+
+ expect(vm.loading).toBeTruthy();
+ });
+
+ it('hides current flash element', (done) => {
+ vm.$refs.flashContainer.innerHTML = '<div class="flash-alert"></div>';
+
+ vm.submitNewBranch();
+
+ Vue.nextTick(() => {
+ expect(vm.$el.querySelector('.flash-alert')).toBeNull();
+
+ done();
+ });
+ });
+
+ it('calls createdNewBranch with branchName', () => {
+ vm.branchName = 'testing';
+
+ vm.submitNewBranch();
+
+ expect(vm.createNewBranch).toHaveBeenCalledWith('testing');
+ });
+ });
+
+ describe('submitNewBranch with error', () => {
+ beforeEach(() => {
+ spyOn(vm, 'createNewBranch').and.returnValue(Promise.reject({
+ json: () => Promise.resolve({
+ message: 'error message',
+ }),
+ }));
+ });
+
+ it('sets loading to false', (done) => {
+ vm.loading = true;
+
+ vm.submitNewBranch();
+
+ setTimeout(() => {
+ expect(vm.loading).toBeFalsy();
+
+ done();
+ });
+ });
+
+ it('creates flash element', (done) => {
+ vm.submitNewBranch();
+
+ setTimeout(() => {
+ expect(vm.$el.querySelector('.flash-alert')).not.toBeNull();
+ expect(vm.$el.querySelector('.flash-alert').textContent.trim()).toBe('error message');
+
+ done();
+ });
+ });
+ });
+});
diff --git a/spec/javascripts/repo/components/new_dropdown/index_spec.js b/spec/javascripts/repo/components/new_dropdown/index_spec.js
new file mode 100644
index 00000000000..93b10fc1fee
--- /dev/null
+++ b/spec/javascripts/repo/components/new_dropdown/index_spec.js
@@ -0,0 +1,71 @@
+import Vue from 'vue';
+import store from '~/repo/stores';
+import newDropdown from '~/repo/components/new_dropdown/index.vue';
+import { createComponentWithStore } from '../../../helpers/vue_mount_component_helper';
+import { resetStore } from '../../helpers';
+
+describe('new dropdown component', () => {
+ let vm;
+
+ beforeEach(() => {
+ const component = Vue.extend(newDropdown);
+
+ vm = createComponentWithStore(component, store);
+
+ vm.$store.state.path = '';
+
+ vm.$mount();
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+
+ resetStore(vm.$store);
+ });
+
+ it('renders new file and new directory links', () => {
+ expect(vm.$el.querySelectorAll('a')[0].textContent.trim()).toBe('New file');
+ expect(vm.$el.querySelectorAll('a')[1].textContent.trim()).toBe('New directory');
+ });
+
+ describe('createNewItem', () => {
+ it('sets modalType to blob when new file is clicked', () => {
+ vm.$el.querySelectorAll('a')[0].click();
+
+ expect(vm.modalType).toBe('blob');
+ });
+
+ it('sets modalType to tree when new directory is clicked', () => {
+ vm.$el.querySelectorAll('a')[1].click();
+
+ expect(vm.modalType).toBe('tree');
+ });
+
+ it('opens modal when link is clicked', (done) => {
+ vm.$el.querySelectorAll('a')[0].click();
+
+ Vue.nextTick(() => {
+ expect(vm.$el.querySelector('.modal')).not.toBeNull();
+
+ done();
+ });
+ });
+ });
+
+ describe('toggleModalOpen', () => {
+ it('closes modal after toggling', (done) => {
+ vm.toggleModalOpen();
+
+ Vue.nextTick()
+ .then(() => {
+ expect(vm.$el.querySelector('.modal')).not.toBeNull();
+ })
+ .then(vm.toggleModalOpen)
+ .then(() => {
+ expect(vm.$el.querySelector('.modal')).toBeNull();
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+ });
+});
diff --git a/spec/javascripts/repo/components/new_dropdown/modal_spec.js b/spec/javascripts/repo/components/new_dropdown/modal_spec.js
new file mode 100644
index 00000000000..1ff7590ec79
--- /dev/null
+++ b/spec/javascripts/repo/components/new_dropdown/modal_spec.js
@@ -0,0 +1,198 @@
+import Vue from 'vue';
+import store from '~/repo/stores';
+import modal from '~/repo/components/new_dropdown/modal.vue';
+import { createComponentWithStore } from '../../../helpers/vue_mount_component_helper';
+import { file, resetStore } from '../../helpers';
+
+describe('new file modal component', () => {
+ const Component = Vue.extend(modal);
+ let vm;
+
+ afterEach(() => {
+ vm.$destroy();
+
+ resetStore(vm.$store);
+ });
+
+ ['tree', 'blob'].forEach((type) => {
+ describe(type, () => {
+ beforeEach(() => {
+ vm = createComponentWithStore(Component, store, {
+ type,
+ path: '',
+ }).$mount();
+
+ vm.entryName = 'testing';
+ });
+
+ it(`sets modal title as ${type}`, () => {
+ const title = type === 'tree' ? 'directory' : 'file';
+
+ expect(vm.$el.querySelector('.modal-title').textContent.trim()).toBe(`Create new ${title}`);
+ });
+
+ it(`sets button label as ${type}`, () => {
+ const title = type === 'tree' ? 'directory' : 'file';
+
+ expect(vm.$el.querySelector('.btn-success').textContent.trim()).toBe(`Create ${title}`);
+ });
+
+ it(`sets form label as ${type}`, () => {
+ const title = type === 'tree' ? 'Directory' : 'File';
+
+ expect(vm.$el.querySelector('.label-light').textContent.trim()).toBe(`${title} name`);
+ });
+
+ describe('createEntryInStore', () => {
+ it('calls createTempEntry', () => {
+ spyOn(vm, 'createTempEntry');
+
+ vm.createEntryInStore();
+
+ expect(vm.createTempEntry).toHaveBeenCalledWith({
+ name: 'testing',
+ type,
+ });
+ });
+
+ it('sets editMode to true', (done) => {
+ vm.createEntryInStore();
+
+ setTimeout(() => {
+ expect(vm.$store.state.editMode).toBeTruthy();
+
+ done();
+ });
+ });
+
+ it('toggles blob view', (done) => {
+ vm.createEntryInStore();
+
+ setTimeout(() => {
+ expect(vm.$store.state.currentBlobView).toBe('repo-editor');
+
+ done();
+ });
+ });
+
+ it('opens newly created file', (done) => {
+ vm.createEntryInStore();
+
+ setTimeout(() => {
+ expect(vm.$store.state.openFiles.length).toBe(1);
+ expect(vm.$store.state.openFiles[0].name).toBe(type === 'blob' ? 'testing' : '.gitkeep');
+
+ done();
+ });
+ });
+
+ it(`creates ${type} in the current stores path`, (done) => {
+ vm.$store.state.path = 'app';
+
+ vm.createEntryInStore();
+
+ setTimeout(() => {
+ expect(vm.$store.state.tree[0].path).toBe('app/testing');
+ expect(vm.$store.state.tree[0].name).toBe('testing');
+
+ if (type === 'tree') {
+ expect(vm.$store.state.tree[0].tree.length).toBe(1);
+ }
+
+ done();
+ });
+ });
+
+ if (type === 'blob') {
+ it('creates new file', (done) => {
+ vm.createEntryInStore();
+
+ setTimeout(() => {
+ expect(vm.$store.state.tree.length).toBe(1);
+ expect(vm.$store.state.tree[0].name).toBe('testing');
+ expect(vm.$store.state.tree[0].type).toBe('blob');
+ expect(vm.$store.state.tree[0].tempFile).toBeTruthy();
+
+ done();
+ });
+ });
+
+ it('does not create temp file when file already exists', (done) => {
+ vm.$store.state.tree.push(file('testing', '1', type));
+
+ vm.createEntryInStore();
+
+ setTimeout(() => {
+ expect(vm.$store.state.tree.length).toBe(1);
+ expect(vm.$store.state.tree[0].name).toBe('testing');
+ expect(vm.$store.state.tree[0].type).toBe('blob');
+ expect(vm.$store.state.tree[0].tempFile).toBeFalsy();
+
+ done();
+ });
+ });
+ } else {
+ it('creates new tree', () => {
+ vm.createEntryInStore();
+
+ expect(vm.$store.state.tree.length).toBe(1);
+ expect(vm.$store.state.tree[0].name).toBe('testing');
+ expect(vm.$store.state.tree[0].type).toBe('tree');
+ expect(vm.$store.state.tree[0].tempFile).toBeTruthy();
+ expect(vm.$store.state.tree[0].tree.length).toBe(1);
+ expect(vm.$store.state.tree[0].tree[0].name).toBe('.gitkeep');
+ });
+
+ it('creates multiple trees when entryName has slashes', () => {
+ vm.entryName = 'app/test';
+ vm.createEntryInStore();
+
+ expect(vm.$store.state.tree.length).toBe(1);
+ expect(vm.$store.state.tree[0].name).toBe('app');
+ expect(vm.$store.state.tree[0].tree[0].name).toBe('test');
+ expect(vm.$store.state.tree[0].tree[0].tree[0].name).toBe('.gitkeep');
+ });
+
+ it('creates tree in existing tree', () => {
+ vm.$store.state.tree.push(file('app', '1', 'tree'));
+
+ vm.entryName = 'app/test';
+ vm.createEntryInStore();
+
+ expect(vm.$store.state.tree.length).toBe(1);
+ expect(vm.$store.state.tree[0].name).toBe('app');
+ expect(vm.$store.state.tree[0].tempFile).toBeFalsy();
+ expect(vm.$store.state.tree[0].tree[0].tempFile).toBeTruthy();
+ expect(vm.$store.state.tree[0].tree[0].name).toBe('test');
+ expect(vm.$store.state.tree[0].tree[0].tree[0].name).toBe('.gitkeep');
+ });
+
+ it('does not create new tree when already exists', () => {
+ vm.$store.state.tree.push(file('app', '1', 'tree'));
+
+ vm.entryName = 'app';
+ vm.createEntryInStore();
+
+ expect(vm.$store.state.tree.length).toBe(1);
+ expect(vm.$store.state.tree[0].name).toBe('app');
+ expect(vm.$store.state.tree[0].tempFile).toBeFalsy();
+ expect(vm.$store.state.tree[0].tree.length).toBe(0);
+ });
+ }
+ });
+ });
+ });
+
+ it('focuses field on mount', () => {
+ document.body.innerHTML += '<div class="js-test"></div>';
+
+ vm = createComponentWithStore(Component, store, {
+ type: 'tree',
+ path: '',
+ }).$mount('.js-test');
+
+ expect(document.activeElement).toBe(vm.$refs.fieldName);
+
+ vm.$el.remove();
+ });
+});
diff --git a/spec/javascripts/repo/components/new_dropdown/upload_spec.js b/spec/javascripts/repo/components/new_dropdown/upload_spec.js
new file mode 100644
index 00000000000..bf7893029b1
--- /dev/null
+++ b/spec/javascripts/repo/components/new_dropdown/upload_spec.js
@@ -0,0 +1,103 @@
+import Vue from 'vue';
+import upload from '~/repo/components/new_dropdown/upload.vue';
+import store from '~/repo/stores';
+import { createComponentWithStore } from '../../../helpers/vue_mount_component_helper';
+import { resetStore } from '../../helpers';
+
+describe('new dropdown upload', () => {
+ let vm;
+
+ beforeEach(() => {
+ const Component = Vue.extend(upload);
+
+ vm = createComponentWithStore(Component, store, {
+ path: '',
+ });
+
+ vm.$mount();
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+
+ resetStore(vm.$store);
+ });
+
+ describe('readFile', () => {
+ beforeEach(() => {
+ spyOn(FileReader.prototype, 'readAsText');
+ spyOn(FileReader.prototype, 'readAsDataURL');
+ });
+
+ it('calls readAsText for text files', () => {
+ const file = {
+ type: 'text/html',
+ };
+
+ vm.readFile(file);
+
+ expect(FileReader.prototype.readAsText).toHaveBeenCalledWith(file);
+ });
+
+ it('calls readAsDataURL for non-text files', () => {
+ const file = {
+ type: 'images/png',
+ };
+
+ vm.readFile(file);
+
+ expect(FileReader.prototype.readAsDataURL).toHaveBeenCalledWith(file);
+ });
+ });
+
+ describe('createFile', () => {
+ const target = {
+ result: 'content',
+ };
+ const binaryTarget = {
+ result: 'base64,base64content',
+ };
+ const file = {
+ name: 'file',
+ };
+
+ it('creates new file', (done) => {
+ vm.createFile(target, file, true);
+
+ vm.$nextTick(() => {
+ expect(vm.$store.state.tree.length).toBe(1);
+ expect(vm.$store.state.tree[0].name).toBe(file.name);
+ expect(vm.$store.state.tree[0].content).toBe(target.result);
+
+ done();
+ });
+ });
+
+ it('creates new file in path', (done) => {
+ vm.$store.state.path = 'testing';
+ vm.createFile(target, file, true);
+
+ vm.$nextTick(() => {
+ expect(vm.$store.state.tree.length).toBe(1);
+ expect(vm.$store.state.tree[0].name).toBe(file.name);
+ expect(vm.$store.state.tree[0].content).toBe(target.result);
+ expect(vm.$store.state.tree[0].path).toBe(`testing/${file.name}`);
+
+ done();
+ });
+ });
+
+ it('splits content on base64 if binary', (done) => {
+ vm.createFile(binaryTarget, file, false);
+
+ vm.$nextTick(() => {
+ expect(vm.$store.state.tree.length).toBe(1);
+ expect(vm.$store.state.tree[0].name).toBe(file.name);
+ expect(vm.$store.state.tree[0].content).toBe(binaryTarget.result.split('base64,')[1]);
+ expect(vm.$store.state.tree[0].base64).toBe(true);
+
+ done();
+ });
+ });
+ });
+});
diff --git a/spec/javascripts/repo/components/repo_commit_section_spec.js b/spec/javascripts/repo/components/repo_commit_section_spec.js
index e09d593f04c..0f991e1b727 100644
--- a/spec/javascripts/repo/components/repo_commit_section_spec.js
+++ b/spec/javascripts/repo/components/repo_commit_section_spec.js
@@ -1,56 +1,43 @@
import Vue from 'vue';
+import store from '~/repo/stores';
+import service from '~/repo/services';
import repoCommitSection from '~/repo/components/repo_commit_section.vue';
-import RepoStore from '~/repo/stores/repo_store';
-import RepoService from '~/repo/services/repo_service';
import getSetTimeoutPromise from '../../helpers/set_timeout_promise_helper';
+import { file, resetStore } from '../helpers';
describe('RepoCommitSection', () => {
- const branch = 'master';
- const projectUrl = 'projectUrl';
- let changedFiles;
- let openedFiles;
+ let vm;
- RepoStore.projectUrl = projectUrl;
-
- function createComponent(el) {
+ function createComponent() {
const RepoCommitSection = Vue.extend(repoCommitSection);
- return new RepoCommitSection().$mount(el);
+ const comp = new RepoCommitSection({
+ store,
+ }).$mount();
+
+ comp.$store.state.currentBranch = 'master';
+ comp.$store.state.openFiles = [file(), file()];
+ comp.$store.state.openFiles.forEach(f => Object.assign(f, {
+ changed: true,
+ content: 'testing',
+ }));
+
+ return comp.$mount();
}
beforeEach(() => {
- // Create a copy for each test because these can get modified directly
- changedFiles = [{
- id: 0,
- changed: true,
- url: `/namespace/${projectUrl}/blob/${branch}/dir/file0.ext`,
- path: 'dir/file0.ext',
- newContent: 'a',
- }, {
- id: 1,
- changed: true,
- url: `/namespace/${projectUrl}/blob/${branch}/dir/file1.ext`,
- path: 'dir/file1.ext',
- newContent: 'b',
- }];
- openedFiles = changedFiles.concat([{
- id: 2,
- url: `/namespace/${projectUrl}/blob/${branch}/dir/file2.ext`,
- path: 'dir/file2.ext',
- changed: false,
- }]);
+ vm = createComponent();
});
- it('renders a commit section', () => {
- RepoStore.isCommitable = true;
- RepoStore.currentBranch = branch;
- RepoStore.targetBranch = branch;
- RepoStore.openedFiles = openedFiles;
+ afterEach(() => {
+ vm.$destroy();
+
+ resetStore(vm.$store);
+ });
- const vm = createComponent();
+ it('renders a commit section', () => {
const changedFileElements = [...vm.$el.querySelectorAll('.changed-files > li')];
- const commitMessage = vm.$el.querySelector('#commit-message');
- const submitCommit = vm.$refs.submitCommit;
+ const submitCommit = vm.$el.querySelector('.btn');
const targetBranch = vm.$el.querySelector('.target-branch');
expect(vm.$el.querySelector(':scope > form')).toBeTruthy();
@@ -58,160 +45,70 @@ describe('RepoCommitSection', () => {
expect(changedFileElements.length).toEqual(2);
changedFileElements.forEach((changedFile, i) => {
- expect(changedFile.textContent.trim()).toEqual(changedFiles[i].path);
+ expect(changedFile.textContent.trim()).toEqual(vm.$store.getters.changedFiles[i].path);
});
- expect(commitMessage.tagName).toEqual('TEXTAREA');
- expect(commitMessage.name).toEqual('commit-message');
- expect(submitCommit.type).toEqual('submit');
expect(submitCommit.disabled).toBeTruthy();
expect(submitCommit.querySelector('.fa-spinner.fa-spin')).toBeFalsy();
expect(vm.$el.querySelector('.commit-summary').textContent.trim()).toEqual('Commit 2 files');
expect(targetBranch.querySelector(':scope > label').textContent.trim()).toEqual('Target branch');
- expect(targetBranch.querySelector('.help-block').textContent.trim()).toEqual(branch);
- });
-
- it('does not render if not isCommitable', () => {
- RepoStore.isCommitable = false;
- RepoStore.openedFiles = [{
- id: 0,
- changed: true,
- }];
-
- const vm = createComponent();
-
- expect(vm.$el.innerHTML).toBeFalsy();
- });
-
- it('does not render if no changedFiles', () => {
- RepoStore.isCommitable = true;
- RepoStore.openedFiles = [];
-
- const vm = createComponent();
-
- expect(vm.$el.innerHTML).toBeFalsy();
+ expect(targetBranch.querySelector('.help-block').textContent.trim()).toEqual('master');
});
describe('when submitting', () => {
- let el;
- let vm;
- const projectId = 'projectId';
- const commitMessage = 'commitMessage';
-
- beforeEach((done) => {
- RepoStore.isCommitable = true;
- RepoStore.currentBranch = branch;
- RepoStore.targetBranch = branch;
- RepoStore.openedFiles = openedFiles;
- RepoStore.projectId = projectId;
-
- // We need to append to body to get form `submit` events working
- // Otherwise we run into, "Form submission canceled because the form is not connected"
- // See https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#form-submission-algorithm
- el = document.createElement('div');
- document.body.appendChild(el);
-
- vm = createComponent(el);
- vm.commitMessage = commitMessage;
-
- spyOn(vm, 'tryCommit').and.callThrough();
- spyOn(vm, 'redirectToNewMr').and.stub();
- spyOn(vm, 'redirectToBranch').and.stub();
- spyOn(RepoService, 'commitFiles').and.returnValue(Promise.resolve());
- spyOn(RepoService, 'getBranch').and.returnValue(Promise.resolve({
- commit: {
- id: 1,
- short_id: 1,
- },
- }));
-
- // Wait for the vm data to be in place
- Vue.nextTick(() => {
- done();
- });
- });
+ let changedFiles;
- afterEach(() => {
- vm.$destroy();
- el.remove();
- RepoStore.openedFiles = [];
- });
+ beforeEach(() => {
+ vm.commitMessage = 'testing';
+ changedFiles = JSON.parse(JSON.stringify(vm.$store.getters.changedFiles));
- it('shows commit message', () => {
- const commitMessageEl = vm.$el.querySelector('#commit-message');
- expect(commitMessageEl.value).toBe(commitMessage);
+ spyOn(service, 'commit').and.returnValue(Promise.resolve({
+ short_id: '1',
+ stats: {},
+ }));
});
it('allows you to submit', () => {
- const submitCommit = vm.$refs.submitCommit;
- expect(submitCommit.disabled).toBeFalsy();
+ expect(vm.$el.querySelector('.btn').disabled).toBeTruthy();
});
- it('shows commit submit and summary if commitMessage and spinner if submitCommitsLoading', (done) => {
- const submitCommit = vm.$refs.submitCommit;
- submitCommit.click();
+ it('submits commit', (done) => {
+ vm.makeCommit();
// Wait for the branch check to finish
getSetTimeoutPromise()
.then(() => Vue.nextTick())
.then(() => {
- expect(vm.tryCommit).toHaveBeenCalled();
- expect(submitCommit.querySelector('.js-commit-loading-icon')).toBeTruthy();
- expect(vm.redirectToBranch).toHaveBeenCalled();
-
- const args = RepoService.commitFiles.calls.allArgs()[0];
- const { commit_message, actions, branch: payloadBranch } = args[0];
+ const args = service.commit.calls.allArgs()[0];
+ const { commit_message, actions, branch: payloadBranch } = args[1];
- expect(commit_message).toBe(commitMessage);
+ expect(commit_message).toBe('testing');
expect(actions.length).toEqual(2);
- expect(payloadBranch).toEqual(branch);
+ expect(payloadBranch).toEqual('master');
expect(actions[0].action).toEqual('update');
expect(actions[1].action).toEqual('update');
- expect(actions[0].content).toEqual(openedFiles[0].newContent);
- expect(actions[1].content).toEqual(openedFiles[1].newContent);
- expect(actions[0].file_path).toEqual(openedFiles[0].path);
- expect(actions[1].file_path).toEqual(openedFiles[1].path);
+ expect(actions[0].content).toEqual(changedFiles[0].content);
+ expect(actions[1].content).toEqual(changedFiles[1].content);
+ expect(actions[0].file_path).toEqual(changedFiles[0].path);
+ expect(actions[1].file_path).toEqual(changedFiles[1].path);
})
.then(done)
.catch(done.fail);
});
it('redirects to MR creation page if start new MR checkbox checked', (done) => {
+ spyOn(gl.utils, 'visitUrl');
vm.startNewMR = true;
- Vue.nextTick()
- .then(() => {
- const submitCommit = vm.$refs.submitCommit;
- submitCommit.click();
- })
- // Wait for the branch check to finish
- .then(() => getSetTimeoutPromise())
+ vm.makeCommit();
+
+ getSetTimeoutPromise()
+ .then(() => Vue.nextTick())
.then(() => {
- expect(vm.redirectToNewMr).toHaveBeenCalled();
+ expect(gl.utils.visitUrl).toHaveBeenCalled();
})
.then(done)
.catch(done.fail);
});
});
-
- describe('methods', () => {
- describe('resetCommitState', () => {
- it('should reset store vars and scroll to top', () => {
- const vm = {
- submitCommitsLoading: true,
- changedFiles: new Array(10),
- openedFiles: new Array(3),
- commitMessage: 'commitMessage',
- editMode: true,
- };
-
- repoCommitSection.methods.resetCommitState.call(vm);
-
- expect(vm.submitCommitsLoading).toEqual(false);
- expect(vm.changedFiles).toEqual([]);
- expect(vm.commitMessage).toEqual('');
- expect(vm.editMode).toEqual(false);
- });
- });
- });
});
diff --git a/spec/javascripts/repo/components/repo_edit_button_spec.js b/spec/javascripts/repo/components/repo_edit_button_spec.js
index dff2fac191d..44018464b35 100644
--- a/spec/javascripts/repo/components/repo_edit_button_spec.js
+++ b/spec/javascripts/repo/components/repo_edit_button_spec.js
@@ -1,45 +1,83 @@
import Vue from 'vue';
+import store from '~/repo/stores';
import repoEditButton from '~/repo/components/repo_edit_button.vue';
-import RepoStore from '~/repo/stores/repo_store';
+import { file, resetStore } from '../helpers';
describe('RepoEditButton', () => {
- function createComponent() {
+ let vm;
+
+ beforeEach(() => {
+ const f = file();
const RepoEditButton = Vue.extend(repoEditButton);
- return new RepoEditButton().$mount();
- }
+ vm = new RepoEditButton({
+ store,
+ });
+
+ f.active = true;
+ vm.$store.dispatch('setInitialData', {
+ canCommit: true,
+ onTopOfBranch: true,
+ });
+ vm.$store.state.openFiles.push(f);
+ });
afterEach(() => {
- RepoStore.openedFiles = [];
+ vm.$destroy();
+
+ resetStore(vm.$store);
});
- it('renders an edit button that toggles the view state', (done) => {
- RepoStore.isCommitable = true;
- RepoStore.changedFiles = [];
- RepoStore.binary = false;
- RepoStore.openedFiles = [{}, {}];
+ it('renders an edit button', () => {
+ vm.$mount();
+
+ expect(vm.$el.querySelector('.btn')).not.toBeNull();
+ expect(vm.$el.querySelector('.btn').textContent.trim()).toBe('Edit');
+ });
- const vm = createComponent();
+ it('renders edit button with cancel text', () => {
+ vm.$store.state.editMode = true;
- expect(vm.$el.tagName).toEqual('BUTTON');
- expect(vm.$el.textContent).toMatch('Edit');
+ vm.$mount();
- spyOn(vm, 'editCancelClicked').and.callThrough();
+ expect(vm.$el.querySelector('.btn')).not.toBeNull();
+ expect(vm.$el.querySelector('.btn').textContent.trim()).toBe('Cancel edit');
+ });
- vm.$el.click();
+ it('toggles edit mode on click', (done) => {
+ vm.$mount();
+
+ vm.$el.querySelector('.btn').click();
+
+ vm.$nextTick(() => {
+ expect(vm.$el.querySelector('.btn').textContent.trim()).toBe('Cancel edit');
- Vue.nextTick(() => {
- expect(vm.editCancelClicked).toHaveBeenCalled();
- expect(vm.$el.textContent).toMatch('Cancel edit');
done();
});
});
- it('does not render if not isCommitable', () => {
- RepoStore.isCommitable = false;
+ describe('discardPopupOpen', () => {
+ beforeEach(() => {
+ vm.$store.state.discardPopupOpen = true;
+ vm.$store.state.editMode = true;
+ vm.$store.state.openFiles[0].changed = true;
+
+ vm.$mount();
+ });
+
+ it('renders popup', () => {
+ expect(vm.$el.querySelector('.modal')).not.toBeNull();
+ });
+
+ it('removes all changed files', (done) => {
+ vm.$el.querySelector('.btn-warning').click();
- const vm = createComponent();
+ vm.$nextTick(() => {
+ expect(vm.$store.getters.changedFiles.length).toBe(0);
+ expect(vm.$el.querySelector('.modal')).toBeNull();
- expect(vm.$el.innerHTML).toBeUndefined();
+ done();
+ });
+ });
});
});
diff --git a/spec/javascripts/repo/components/repo_editor_spec.js b/spec/javascripts/repo/components/repo_editor_spec.js
index a25a600b3be..82f914b7c9d 100644
--- a/spec/javascripts/repo/components/repo_editor_spec.js
+++ b/spec/javascripts/repo/components/repo_editor_spec.js
@@ -1,52 +1,46 @@
import Vue from 'vue';
-import RepoStore from '~/repo/stores/repo_store';
+import store from '~/repo/stores';
import repoEditor from '~/repo/components/repo_editor.vue';
+import { file, resetStore } from '../helpers';
describe('RepoEditor', () => {
+ let vm;
+
beforeEach(() => {
+ const f = file();
const RepoEditor = Vue.extend(repoEditor);
- this.vm = new RepoEditor().$mount();
+ vm = new RepoEditor({
+ store,
+ });
+
+ f.active = true;
+ f.tempFile = true;
+ vm.$store.state.openFiles.push(f);
+ vm.monaco = true;
+
+ vm.$mount();
});
afterEach(() => {
- RepoStore.openedFiles = [];
+ vm.$destroy();
+
+ resetStore(vm.$store);
});
it('renders an ide container', (done) => {
- this.vm.openedFiles = ['idiidid'];
- this.vm.binary = false;
-
Vue.nextTick(() => {
- expect(this.vm.shouldHideEditor).toBe(false);
- expect(this.vm.$el.id).toEqual('ide');
- expect(this.vm.$el.tagName).toBe('DIV');
+ expect(vm.shouldHideEditor).toBeFalsy();
done();
});
});
- describe('when there are no open files', () => {
- it('does not render the ide', (done) => {
- this.vm.openedFiles = [];
-
- Vue.nextTick(() => {
- expect(this.vm.shouldHideEditor).toBe(true);
- expect(this.vm.$el.tagName).not.toBeDefined();
- done();
- });
- });
- });
-
describe('when open file is binary and not raw', () => {
it('does not render the IDE', (done) => {
- this.vm.binary = true;
- this.vm.activeFile = {
- raw: false,
- };
+ vm.$store.getters.activeFile.binary = true;
Vue.nextTick(() => {
- expect(this.vm.shouldHideEditor).toBe(true);
- expect(this.vm.$el.tagName).not.toBeDefined();
+ expect(vm.shouldHideEditor).toBeTruthy();
done();
});
});
diff --git a/spec/javascripts/repo/components/repo_file_buttons_spec.js b/spec/javascripts/repo/components/repo_file_buttons_spec.js
index 701c260224f..d6e255e4810 100644
--- a/spec/javascripts/repo/components/repo_file_buttons_spec.js
+++ b/spec/javascripts/repo/components/repo_file_buttons_spec.js
@@ -1,79 +1,49 @@
import Vue from 'vue';
+import store from '~/repo/stores';
import repoFileButtons from '~/repo/components/repo_file_buttons.vue';
-import RepoStore from '~/repo/stores/repo_store';
+import { file, resetStore } from '../helpers';
describe('RepoFileButtons', () => {
+ const activeFile = file();
+ let vm;
+
function createComponent() {
const RepoFileButtons = Vue.extend(repoFileButtons);
- return new RepoFileButtons().$mount();
+ activeFile.rawPath = 'test';
+ activeFile.blamePath = 'test';
+ activeFile.commitsPath = 'test';
+ activeFile.active = true;
+ store.state.openFiles.push(activeFile);
+
+ return new RepoFileButtons({
+ store,
+ }).$mount();
}
afterEach(() => {
- RepoStore.openedFiles = [];
- });
-
- it('renders Raw, Blame, History, Permalink and Preview toggle', () => {
- const activeFile = {
- extension: 'md',
- url: 'url',
- raw_path: 'raw_path',
- blame_path: 'blame_path',
- commits_path: 'commits_path',
- permalink: 'permalink',
- };
- const activeFileLabel = 'activeFileLabel';
- RepoStore.openedFiles = new Array(1);
- RepoStore.activeFile = activeFile;
- RepoStore.activeFileLabel = activeFileLabel;
- RepoStore.editMode = true;
- RepoStore.binary = false;
-
- const vm = createComponent();
- const raw = vm.$el.querySelector('.raw');
- const blame = vm.$el.querySelector('.blame');
- const history = vm.$el.querySelector('.history');
+ vm.$destroy();
- expect(vm.$el.id).toEqual('repo-file-buttons');
- expect(raw.href).toMatch(`/${activeFile.raw_path}`);
- expect(raw.textContent.trim()).toEqual('Raw');
- expect(blame.href).toMatch(`/${activeFile.blame_path}`);
- expect(blame.textContent.trim()).toEqual('Blame');
- expect(history.href).toMatch(`/${activeFile.commits_path}`);
- expect(history.textContent.trim()).toEqual('History');
- expect(vm.$el.querySelector('.permalink').textContent.trim()).toEqual('Permalink');
- expect(vm.$el.querySelector('.preview').textContent.trim()).toEqual(activeFileLabel);
+ resetStore(vm.$store);
});
- it('triggers rawPreviewToggle on preview click', () => {
- const activeFile = {
- extension: 'md',
- url: 'url',
- };
- RepoStore.openedFiles = new Array(1);
- RepoStore.activeFile = activeFile;
- RepoStore.editMode = true;
-
- const vm = createComponent();
- const preview = vm.$el.querySelector('.preview');
-
- spyOn(vm, 'rawPreviewToggle');
-
- preview.click();
-
- expect(vm.rawPreviewToggle).toHaveBeenCalled();
- });
+ it('renders Raw, Blame, History, Permalink and Preview toggle', (done) => {
+ vm = createComponent();
- it('does not render preview toggle if not canPreview', () => {
- const activeFile = {
- extension: 'abcd',
- url: 'url',
- };
- RepoStore.openedFiles = new Array(1);
- RepoStore.activeFile = activeFile;
+ vm.$nextTick(() => {
+ const raw = vm.$el.querySelector('.raw');
+ const blame = vm.$el.querySelector('.blame');
+ const history = vm.$el.querySelector('.history');
- const vm = createComponent();
+ expect(raw.href).toMatch(`/${activeFile.rawPath}`);
+ expect(raw.textContent.trim()).toEqual('Raw');
+ expect(blame.href).toMatch(`/${activeFile.blamePath}`);
+ expect(blame.textContent.trim()).toEqual('Blame');
+ expect(history.href).toMatch(`/${activeFile.commitsPath}`);
+ expect(history.textContent.trim()).toEqual('History');
+ expect(vm.$el.querySelector('.permalink').textContent.trim()).toEqual('Permalink');
- expect(vm.$el.querySelector('.preview')).toBeFalsy();
+ done();
+ });
});
});
diff --git a/spec/javascripts/repo/components/repo_file_spec.js b/spec/javascripts/repo/components/repo_file_spec.js
index 107f6797f8a..c45f8a18d1f 100644
--- a/spec/javascripts/repo/components/repo_file_spec.js
+++ b/spec/javascripts/repo/components/repo_file_spec.js
@@ -1,31 +1,29 @@
import Vue from 'vue';
+import store from '~/repo/stores';
import repoFile from '~/repo/components/repo_file.vue';
-import RepoStore from '~/repo/stores/repo_store';
-import eventHub from '~/repo/event_hub';
-import { file } from '../mock_data';
+import { file, resetStore } from '../helpers';
describe('RepoFile', () => {
const updated = 'updated';
- const otherFile = {
- html: '<p class="file-content">html</p>',
- pageTitle: 'otherpageTitle',
- };
+ let vm;
function createComponent(propsData) {
const RepoFile = Vue.extend(repoFile);
return new RepoFile({
+ store,
propsData,
}).$mount();
}
- beforeEach(() => {
- RepoStore.openedFiles = [];
+ afterEach(() => {
+ resetStore(vm.$store);
});
it('renders link, icon, name and last commit details', () => {
const RepoFile = Vue.extend(repoFile);
- const vm = new RepoFile({
+ vm = new RepoFile({
+ store,
propsData: {
file: file(),
},
@@ -46,23 +44,17 @@ describe('RepoFile', () => {
});
it('does render if hasFiles is true and is loading tree', () => {
- const vm = createComponent({
+ vm = createComponent({
file: file(),
});
expect(vm.$el.querySelector('.fa-spin.fa-spinner')).toBeFalsy();
});
- it('sets the document title correctly', () => {
- RepoStore.setActiveFiles(otherFile);
-
- expect(document.title.trim()).toEqual(otherFile.pageTitle);
- });
-
it('renders a spinner if the file is loading', () => {
const f = file();
f.loading = true;
- const vm = createComponent({
+ vm = createComponent({
file: f,
});
@@ -70,32 +62,34 @@ describe('RepoFile', () => {
expect(vm.$el.querySelector('.fa-spin.fa-spinner').style.marginLeft).toEqual(`${vm.file.level * 16}px`);
});
- it('does not render commit message and datetime if mini', () => {
- RepoStore.openedFiles.push(file());
-
- const vm = createComponent({
+ it('does not render commit message and datetime if mini', (done) => {
+ vm = createComponent({
file: file(),
});
+ vm.$store.state.openFiles.push(vm.file);
- expect(vm.$el.querySelector('.commit-message')).toBeFalsy();
- expect(vm.$el.querySelector('.commit-update')).toBeFalsy();
+ vm.$nextTick(() => {
+ expect(vm.$el.querySelector('.commit-message')).toBeFalsy();
+ expect(vm.$el.querySelector('.commit-update')).toBeFalsy();
+
+ done();
+ });
});
- it('fires linkClicked when the link is clicked', () => {
- const vm = createComponent({
+ it('fires clickedTreeRow when the link is clicked', () => {
+ vm = createComponent({
file: file(),
});
- spyOn(vm, 'linkClicked');
+ spyOn(vm, 'clickedTreeRow');
vm.$el.click();
- expect(vm.linkClicked).toHaveBeenCalledWith(vm.file);
+ expect(vm.clickedTreeRow).toHaveBeenCalledWith(vm.file);
});
describe('submodule', () => {
let f;
- let vm;
beforeEach(() => {
f = file('submodule name', '123456789');
@@ -118,20 +112,4 @@ describe('RepoFile', () => {
expect(vm.$el.querySelector('td').textContent.replace(/\s+/g, ' ')).toContain('submodule name @ 12345678');
});
});
-
- describe('methods', () => {
- describe('linkClicked', () => {
- it('$emits fileNameClicked with file obj', () => {
- spyOn(eventHub, '$emit');
-
- const vm = createComponent({
- file: file(),
- });
-
- vm.linkClicked(vm.file);
-
- expect(eventHub.$emit).toHaveBeenCalledWith('fileNameClicked', vm.file);
- });
- });
- });
});
diff --git a/spec/javascripts/repo/components/repo_loading_file_spec.js b/spec/javascripts/repo/components/repo_loading_file_spec.js
index e9f95a02028..031f2a9c0b2 100644
--- a/spec/javascripts/repo/components/repo_loading_file_spec.js
+++ b/spec/javascripts/repo/components/repo_loading_file_spec.js
@@ -1,13 +1,16 @@
import Vue from 'vue';
-import RepoStore from '~/repo/stores/repo_store';
+import store from '~/repo/stores';
import repoLoadingFile from '~/repo/components/repo_loading_file.vue';
+import { resetStore } from '../helpers';
describe('RepoLoadingFile', () => {
- function createComponent(propsData) {
+ let vm;
+
+ function createComponent() {
const RepoLoadingFile = Vue.extend(repoLoadingFile);
return new RepoLoadingFile({
- propsData,
+ store,
}).$mount();
}
@@ -30,33 +33,30 @@ describe('RepoLoadingFile', () => {
}
afterEach(() => {
- RepoStore.openedFiles = [];
+ vm.$destroy();
+
+ resetStore(vm.$store);
});
it('renders 3 columns of animated LoC', () => {
- const vm = createComponent({
- loading: {
- tree: true,
- },
- hasFiles: false,
- });
+ vm = createComponent();
const columns = [...vm.$el.querySelectorAll('td')];
expect(columns.length).toEqual(3);
assertColumns(columns);
});
- it('renders 1 column of animated LoC if isMini', () => {
- RepoStore.openedFiles = new Array(1);
- const vm = createComponent({
- loading: {
- tree: true,
- },
- hasFiles: false,
- });
- const columns = [...vm.$el.querySelectorAll('td')];
+ it('renders 1 column of animated LoC if isMini', (done) => {
+ vm = createComponent();
+ vm.$store.state.openFiles.push('test');
- expect(columns.length).toEqual(1);
- assertColumns(columns);
+ vm.$nextTick(() => {
+ const columns = [...vm.$el.querySelectorAll('td')];
+
+ expect(columns.length).toEqual(1);
+ assertColumns(columns);
+
+ done();
+ });
});
});
diff --git a/spec/javascripts/repo/components/repo_prev_directory_spec.js b/spec/javascripts/repo/components/repo_prev_directory_spec.js
index 4c064f21084..7f82ae36a64 100644
--- a/spec/javascripts/repo/components/repo_prev_directory_spec.js
+++ b/spec/javascripts/repo/components/repo_prev_directory_spec.js
@@ -1,47 +1,45 @@
import Vue from 'vue';
+import store from '~/repo/stores';
import repoPrevDirectory from '~/repo/components/repo_prev_directory.vue';
-import eventHub from '~/repo/event_hub';
+import { resetStore } from '../helpers';
describe('RepoPrevDirectory', () => {
- function createComponent(propsData) {
+ let vm;
+ const parentLink = 'parent';
+ function createComponent() {
const RepoPrevDirectory = Vue.extend(repoPrevDirectory);
- return new RepoPrevDirectory({
- propsData,
- }).$mount();
- }
-
- it('renders a prev dir link', () => {
- const prevUrl = 'prevUrl';
- const vm = createComponent({
- prevUrl,
+ const comp = new RepoPrevDirectory({
+ store,
});
- const link = vm.$el.querySelector('a');
- spyOn(vm, 'linkClicked');
+ comp.$store.state.parentTreeUrl = parentLink;
- expect(link.href).toMatch(`/${prevUrl}`);
- expect(link.textContent).toEqual('...');
+ return comp.$mount();
+ }
+
+ beforeEach(() => {
+ vm = createComponent();
+ });
- link.click();
+ afterEach(() => {
+ vm.$destroy();
- expect(vm.linkClicked).toHaveBeenCalledWith(prevUrl);
+ resetStore(vm.$store);
});
- describe('methods', () => {
- describe('linkClicked', () => {
- it('$emits linkclicked with prevUrl', () => {
- const prevUrl = 'prevUrl';
- const vm = createComponent({
- prevUrl,
- });
+ it('renders a prev dir link', () => {
+ const link = vm.$el.querySelector('a');
- spyOn(eventHub, '$emit');
+ expect(link.href).toMatch(`/${parentLink}`);
+ expect(link.textContent).toEqual('...');
+ });
- vm.linkClicked(prevUrl);
+ it('clicking row triggers getTreeData', () => {
+ spyOn(vm, 'getTreeData');
- expect(eventHub.$emit).toHaveBeenCalledWith('goToPreviousDirectoryClicked', prevUrl);
- });
- });
+ vm.$el.querySelector('td').click();
+
+ expect(vm.getTreeData).toHaveBeenCalledWith({ endpoint: parentLink });
});
});
diff --git a/spec/javascripts/repo/components/repo_preview_spec.js b/spec/javascripts/repo/components/repo_preview_spec.js
index 4920cf02083..8d1a87494cf 100644
--- a/spec/javascripts/repo/components/repo_preview_spec.js
+++ b/spec/javascripts/repo/components/repo_preview_spec.js
@@ -1,23 +1,37 @@
import Vue from 'vue';
+import store from '~/repo/stores';
import repoPreview from '~/repo/components/repo_preview.vue';
-import RepoStore from '~/repo/stores/repo_store';
+import { file, resetStore } from '../helpers';
describe('RepoPreview', () => {
+ let vm;
+
function createComponent() {
+ const f = file();
const RepoPreview = Vue.extend(repoPreview);
- return new RepoPreview().$mount();
+ const comp = new RepoPreview({
+ store,
+ });
+
+ f.active = true;
+ f.html = 'test';
+
+ comp.$store.state.openFiles.push(f);
+
+ return comp.$mount();
}
- it('renders a div with the activeFile html', () => {
- const activeFile = {
- html: '<p class="file-content">html</p>',
- };
- RepoStore.activeFile = activeFile;
+ afterEach(() => {
+ vm.$destroy();
+
+ resetStore(vm.$store);
+ });
- const vm = createComponent();
+ it('renders a div with the activeFile html', () => {
+ vm = createComponent();
expect(vm.$el.tagName).toEqual('DIV');
- expect(vm.$el.innerHTML).toContain(activeFile.html);
+ expect(vm.$el.innerHTML).toContain('test');
});
});
diff --git a/spec/javascripts/repo/components/repo_sidebar_spec.js b/spec/javascripts/repo/components/repo_sidebar_spec.js
index 148f275e03d..7cb4dace491 100644
--- a/spec/javascripts/repo/components/repo_sidebar_spec.js
+++ b/spec/javascripts/repo/components/repo_sidebar_spec.js
@@ -1,32 +1,31 @@
import Vue from 'vue';
-import Helper from '~/repo/helpers/repo_helper';
-import RepoService from '~/repo/services/repo_service';
-import RepoStore from '~/repo/stores/repo_store';
+import store from '~/repo/stores';
import repoSidebar from '~/repo/components/repo_sidebar.vue';
-import { file } from '../mock_data';
+import { file, resetStore } from '../helpers';
describe('RepoSidebar', () => {
let vm;
- function createComponent() {
+ beforeEach(() => {
const RepoSidebar = Vue.extend(repoSidebar);
- return new RepoSidebar().$mount();
- }
+ vm = new RepoSidebar({
+ store,
+ });
+
+ vm.$store.state.isRoot = true;
+ vm.$store.state.tree.push(file());
+
+ vm.$mount();
+ });
afterEach(() => {
vm.$destroy();
- RepoStore.files = [];
- RepoStore.openedFiles = [];
+ resetStore(vm.$store);
});
it('renders a sidebar', () => {
- RepoStore.files = [file()];
- RepoStore.openedFiles = [];
- RepoStore.isRoot = true;
-
- vm = createComponent();
const thead = vm.$el.querySelector('thead');
const tbody = vm.$el.querySelector('tbody');
@@ -41,139 +40,36 @@ describe('RepoSidebar', () => {
expect(tbody.querySelector('.file')).toBeTruthy();
});
- it('does not render a thead, renders repo-file-options and sets sidebar-mini class if isMini', () => {
- RepoStore.openedFiles = [{
- id: 0,
- }];
- vm = createComponent();
-
- expect(vm.$el.classList.contains('sidebar-mini')).toBeTruthy();
- expect(vm.$el.querySelector('thead')).toBeTruthy();
- expect(vm.$el.querySelector('thead .repo-file-options')).toBeTruthy();
- });
-
- it('renders 5 loading files if tree is loading and not hasFiles', () => {
- RepoStore.loading.tree = true;
- RepoStore.files = [];
- vm = createComponent();
+ it('does not render a thead, renders repo-file-options and sets sidebar-mini class if isMini', (done) => {
+ vm.$store.state.openFiles.push(vm.$store.state.tree[0]);
- expect(vm.$el.querySelectorAll('tbody .loading-file').length).toEqual(5);
- });
-
- it('renders a prev directory if is not root', () => {
- RepoStore.files = [file()];
- RepoStore.isRoot = false;
- RepoStore.loading.tree = false;
- vm = createComponent();
-
- expect(vm.$el.querySelector('tbody .prev-directory')).toBeTruthy();
- });
+ Vue.nextTick(() => {
+ expect(vm.$el.classList.contains('sidebar-mini')).toBeTruthy();
+ expect(vm.$el.querySelector('thead')).toBeTruthy();
+ expect(vm.$el.querySelector('thead .repo-file-options')).toBeTruthy();
- describe('flattendFiles', () => {
- it('returns a flattend array of files', () => {
- const f = file();
- f.files.push(file('testing 123'));
- const files = [f, file()];
- vm = createComponent();
- vm.files = files;
-
- expect(vm.flattendFiles.length).toBe(3);
- expect(vm.flattendFiles[1].name).toBe('testing 123');
+ done();
});
});
- describe('methods', () => {
- describe('fileClicked', () => {
- it('should fetch data for new file', () => {
- spyOn(Helper, 'getContent').and.callThrough();
- RepoStore.files = [file()];
- RepoStore.isRoot = true;
- vm = createComponent();
-
- vm.fileClicked(RepoStore.files[0]);
-
- expect(Helper.getContent).toHaveBeenCalledWith(RepoStore.files[0]);
- });
-
- it('should not fetch data for already opened files', () => {
- const f = file();
- spyOn(Helper, 'getFileFromPath').and.returnValue(f);
- spyOn(RepoStore, 'setActiveFiles');
- vm = createComponent();
- vm.fileClicked(f);
+ it('renders 5 loading files if tree is loading', (done) => {
+ vm.$store.state.tree = [];
+ vm.$store.state.loading = true;
- expect(RepoStore.setActiveFiles).toHaveBeenCalledWith(f);
- });
+ Vue.nextTick(() => {
+ expect(vm.$el.querySelectorAll('tbody .loading-file').length).toEqual(5);
- it('should hide files in directory if already open', () => {
- spyOn(Helper, 'setDirectoryToClosed').and.callThrough();
- const f = file();
- f.opened = true;
- f.type = 'tree';
- RepoStore.files = [f];
- vm = createComponent();
-
- vm.fileClicked(RepoStore.files[0]);
-
- expect(Helper.setDirectoryToClosed).toHaveBeenCalledWith(RepoStore.files[0]);
- });
-
- describe('submodule', () => {
- it('opens submodule project URL', () => {
- spyOn(gl.utils, 'visitUrl');
-
- const f = file();
- f.type = 'submodule';
-
- vm = createComponent();
-
- vm.fileClicked(f);
-
- expect(gl.utils.visitUrl).toHaveBeenCalledWith('url');
- });
- });
- });
-
- describe('goToPreviousDirectoryClicked', () => {
- it('should hide files in directory if already open', () => {
- const prevUrl = 'foo/bar';
- vm = createComponent();
-
- vm.goToPreviousDirectoryClicked(prevUrl);
-
- expect(RepoService.url).toEqual(prevUrl);
- });
+ done();
});
+ });
- describe('back button', () => {
- beforeEach(() => {
- const f = file();
- const file2 = Object.assign({}, file());
- file2.url = 'test';
- RepoStore.files = [f, file2];
- RepoStore.openedFiles = [];
- RepoStore.isRoot = true;
-
- vm = createComponent();
- });
-
- it('render previous file when using back button', () => {
- spyOn(Helper, 'getContent').and.callThrough();
-
- vm.fileClicked(RepoStore.files[1]);
- expect(Helper.getContent).toHaveBeenCalledWith(RepoStore.files[1]);
-
- history.pushState({
- key: Math.random(),
- }, '', RepoStore.files[1].url);
- const popEvent = document.createEvent('Event');
- popEvent.initEvent('popstate', true, true);
- window.dispatchEvent(popEvent);
+ it('renders a prev directory if is not root', (done) => {
+ vm.$store.state.isRoot = false;
- expect(Helper.getContent.calls.mostRecent().args[0].url).toContain(RepoStore.files[1].url);
+ Vue.nextTick(() => {
+ expect(vm.$el.querySelector('tbody .prev-directory')).toBeTruthy();
- window.history.pushState({}, null, '/');
- });
+ done();
});
});
});
diff --git a/spec/javascripts/repo/components/repo_spec.js b/spec/javascripts/repo/components/repo_spec.js
new file mode 100644
index 00000000000..b32d2c13af8
--- /dev/null
+++ b/spec/javascripts/repo/components/repo_spec.js
@@ -0,0 +1,35 @@
+import Vue from 'vue';
+import store from '~/repo/stores';
+import repo from '~/repo/components/repo.vue';
+import { createComponentWithStore } from '../../helpers/vue_mount_component_helper';
+import { file, resetStore } from '../helpers';
+
+describe('repo component', () => {
+ let vm;
+
+ beforeEach(() => {
+ const Component = Vue.extend(repo);
+
+ vm = createComponentWithStore(Component, store).$mount();
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+
+ resetStore(vm.$store);
+ });
+
+ it('does not render panel right when no files open', () => {
+ expect(vm.$el.querySelector('.panel-right')).toBeNull();
+ });
+
+ it('renders panel right when files are open', (done) => {
+ vm.$store.state.tree.push(file());
+
+ Vue.nextTick(() => {
+ expect(vm.$el.querySelector('.panel-right')).toBeNull();
+
+ done();
+ });
+ });
+});
diff --git a/spec/javascripts/repo/components/repo_tab_spec.js b/spec/javascripts/repo/components/repo_tab_spec.js
index 37e297437f0..df0ca55aafc 100644
--- a/spec/javascripts/repo/components/repo_tab_spec.js
+++ b/spec/javascripts/repo/components/repo_tab_spec.js
@@ -1,47 +1,64 @@
import Vue from 'vue';
+import store from '~/repo/stores';
import repoTab from '~/repo/components/repo_tab.vue';
-import RepoStore from '~/repo/stores/repo_store';
+import { file, resetStore } from '../helpers';
describe('RepoTab', () => {
+ let vm;
+
function createComponent(propsData) {
const RepoTab = Vue.extend(repoTab);
return new RepoTab({
+ store,
propsData,
}).$mount();
}
+ afterEach(() => {
+ resetStore(vm.$store);
+ });
+
it('renders a close link and a name link', () => {
- const tab = {
- url: 'url',
- name: 'name',
- };
- const vm = createComponent({
- tab,
+ vm = createComponent({
+ tab: file(),
});
+ vm.$store.state.openFiles.push(vm.tab);
const close = vm.$el.querySelector('.close-btn');
- const name = vm.$el.querySelector(`a[title="${tab.url}"]`);
-
- spyOn(vm, 'closeTab');
- spyOn(vm, 'tabClicked');
+ const name = vm.$el.querySelector(`a[title="${vm.tab.url}"]`);
expect(close.querySelector('.fa-times')).toBeTruthy();
- expect(name.textContent.trim()).toEqual(tab.name);
+ expect(name.textContent.trim()).toEqual(vm.tab.name);
+ });
- close.click();
- name.click();
+ it('calls setFileActive when clicking tab', () => {
+ vm = createComponent({
+ tab: file(),
+ });
+
+ spyOn(vm, 'setFileActive');
+
+ vm.$el.click();
- expect(vm.closeTab).toHaveBeenCalledWith(tab);
- expect(vm.tabClicked).toHaveBeenCalledWith(tab);
+ expect(vm.setFileActive).toHaveBeenCalledWith(vm.tab);
+ });
+
+ it('calls closeFile when clicking close button', () => {
+ vm = createComponent({
+ tab: file(),
+ });
+
+ spyOn(vm, 'closeFile');
+
+ vm.$el.querySelector('.close-btn').click();
+
+ expect(vm.closeFile).toHaveBeenCalledWith({ file: vm.tab });
});
it('renders an fa-circle icon if tab is changed', () => {
- const tab = {
- url: 'url',
- name: 'name',
- changed: true,
- };
- const vm = createComponent({
+ const tab = file();
+ tab.changed = true;
+ vm = createComponent({
tab,
});
@@ -50,38 +67,41 @@ describe('RepoTab', () => {
describe('methods', () => {
describe('closeTab', () => {
- it('returns undefined and does not $emit if file is changed', () => {
- const tab = {
- url: 'url',
- name: 'name',
- changed: true,
- };
- const vm = createComponent({
+ it('does not close tab if is changed', (done) => {
+ const tab = file();
+ tab.changed = true;
+ tab.opened = true;
+ vm = createComponent({
tab,
});
-
- spyOn(RepoStore, 'removeFromOpenedFiles');
+ vm.$store.state.openFiles.push(tab);
+ vm.$store.dispatch('setFileActive', tab);
vm.$el.querySelector('.close-btn').click();
- expect(RepoStore.removeFromOpenedFiles).not.toHaveBeenCalled();
+ vm.$nextTick(() => {
+ expect(tab.opened).toBeTruthy();
+
+ done();
+ });
});
- it('$emits tabclosed event with file obj', () => {
- const tab = {
- url: 'url',
- name: 'name',
- changed: false,
- };
- const vm = createComponent({
+ it('closes tab when clicking close btn', (done) => {
+ const tab = file('lose');
+ tab.opened = true;
+ vm = createComponent({
tab,
});
-
- spyOn(RepoStore, 'removeFromOpenedFiles');
+ vm.$store.state.openFiles.push(tab);
+ vm.$store.dispatch('setFileActive', tab);
vm.$el.querySelector('.close-btn').click();
- expect(RepoStore.removeFromOpenedFiles).toHaveBeenCalledWith(tab);
+ vm.$nextTick(() => {
+ expect(tab.opened).toBeFalsy();
+
+ done();
+ });
});
});
});
diff --git a/spec/javascripts/repo/components/repo_tabs_spec.js b/spec/javascripts/repo/components/repo_tabs_spec.js
index 431129bc866..d0246cc72e6 100644
--- a/spec/javascripts/repo/components/repo_tabs_spec.js
+++ b/spec/javascripts/repo/components/repo_tabs_spec.js
@@ -1,35 +1,38 @@
import Vue from 'vue';
-import RepoStore from '~/repo/stores/repo_store';
+import store from '~/repo/stores';
import repoTabs from '~/repo/components/repo_tabs.vue';
+import { file, resetStore } from '../helpers';
describe('RepoTabs', () => {
- const openedFiles = [{
- id: 0,
- active: true,
- }, {
- id: 1,
- }];
+ const openedFiles = [file(), file()];
+ let vm;
function createComponent() {
const RepoTabs = Vue.extend(repoTabs);
- return new RepoTabs().$mount();
+ return new RepoTabs({
+ store,
+ }).$mount();
}
afterEach(() => {
- RepoStore.openedFiles = [];
+ resetStore(vm.$store);
});
- it('renders a list of tabs', () => {
- RepoStore.openedFiles = openedFiles;
+ it('renders a list of tabs', (done) => {
+ vm = createComponent();
+ openedFiles[0].active = true;
+ vm.$store.state.openFiles = openedFiles;
- const vm = createComponent();
- const tabs = [...vm.$el.querySelectorAll(':scope > li')];
+ vm.$nextTick(() => {
+ const tabs = [...vm.$el.querySelectorAll(':scope > li')];
- expect(vm.$el.id).toEqual('tabs');
- expect(tabs.length).toEqual(3);
- expect(tabs[0].classList.contains('active')).toBeTruthy();
- expect(tabs[1].classList.contains('active')).toBeFalsy();
- expect(tabs[2].classList.contains('tabs-divider')).toBeTruthy();
+ expect(tabs.length).toEqual(3);
+ expect(tabs[0].classList.contains('active')).toBeTruthy();
+ expect(tabs[1].classList.contains('active')).toBeFalsy();
+ expect(tabs[2].classList.contains('tabs-divider')).toBeTruthy();
+
+ done();
+ });
});
});
diff --git a/spec/javascripts/repo/helpers.js b/spec/javascripts/repo/helpers.js
new file mode 100644
index 00000000000..376c291c64b
--- /dev/null
+++ b/spec/javascripts/repo/helpers.js
@@ -0,0 +1,20 @@
+import { decorateData } from '~/repo/stores/utils';
+import state from '~/repo/stores/state';
+
+export const resetStore = (store) => {
+ store.replaceState(state());
+};
+
+export const file = (name = 'name', id = name, type = '') => decorateData({
+ id,
+ type,
+ icon: 'icon',
+ url: 'url',
+ name,
+ path: name,
+ last_commit: {
+ id: '123',
+ message: 'test',
+ committed_date: new Date().toISOString(),
+ },
+});
diff --git a/spec/javascripts/repo/mock_data.js b/spec/javascripts/repo/mock_data.js
deleted file mode 100644
index 71e275caf09..00000000000
--- a/spec/javascripts/repo/mock_data.js
+++ /dev/null
@@ -1,14 +0,0 @@
-import RepoHelper from '~/repo/helpers/repo_helper';
-
-// eslint-disable-next-line import/prefer-default-export
-export const file = (name = 'name', id = name) => RepoHelper.serializeRepoEntity('blob', {
- id,
- icon: 'icon',
- url: 'url',
- name,
- last_commit: {
- id: '123',
- message: 'test',
- committed_date: new Date().toISOString(),
- },
-});
diff --git a/spec/javascripts/repo/services/repo_service_spec.js b/spec/javascripts/repo/services/repo_service_spec.js
deleted file mode 100644
index 6f530770525..00000000000
--- a/spec/javascripts/repo/services/repo_service_spec.js
+++ /dev/null
@@ -1,171 +0,0 @@
-import axios from 'axios';
-import RepoService from '~/repo/services/repo_service';
-import RepoStore from '~/repo/stores/repo_store';
-import Api from '~/api';
-
-describe('RepoService', () => {
- it('has default json format param', () => {
- expect(RepoService.options.params.format).toBe('json');
- });
-
- describe('buildParams', () => {
- let newParams;
- const url = 'url';
-
- beforeEach(() => {
- newParams = {};
-
- spyOn(Object, 'assign').and.returnValue(newParams);
- });
-
- it('clones params', () => {
- const params = RepoService.buildParams(url);
-
- expect(Object.assign).toHaveBeenCalledWith({}, RepoService.options.params);
-
- expect(params).toBe(newParams);
- });
-
- it('sets and returns viewer params to richif urlIsRichBlob is true', () => {
- spyOn(RepoService, 'urlIsRichBlob').and.returnValue(true);
-
- const params = RepoService.buildParams(url);
-
- expect(params.viewer).toEqual('rich');
- });
-
- it('returns params urlIsRichBlob is false', () => {
- spyOn(RepoService, 'urlIsRichBlob').and.returnValue(false);
-
- const params = RepoService.buildParams(url);
-
- expect(params.viewer).toBeUndefined();
- });
-
- it('calls urlIsRichBlob with the objects url prop if no url arg is provided', () => {
- spyOn(RepoService, 'urlIsRichBlob');
- RepoService.url = url;
-
- RepoService.buildParams();
-
- expect(RepoService.urlIsRichBlob).toHaveBeenCalledWith(url);
- });
- });
-
- describe('urlIsRichBlob', () => {
- it('returns true for md extension', () => {
- const isRichBlob = RepoService.urlIsRichBlob('url.md');
-
- expect(isRichBlob).toBeTruthy();
- });
-
- it('returns false for js extension', () => {
- const isRichBlob = RepoService.urlIsRichBlob('url.js');
-
- expect(isRichBlob).toBeFalsy();
- });
- });
-
- describe('getContent', () => {
- const params = {};
- const url = 'url';
- const requestPromise = Promise.resolve();
-
- beforeEach(() => {
- spyOn(RepoService, 'buildParams').and.returnValue(params);
- spyOn(axios, 'get').and.returnValue(requestPromise);
- });
-
- it('calls buildParams and axios.get', () => {
- const request = RepoService.getContent(url);
-
- expect(RepoService.buildParams).toHaveBeenCalledWith(url);
- expect(axios.get).toHaveBeenCalledWith(url, {
- params,
- });
- expect(request).toBe(requestPromise);
- });
-
- it('uses object url prop if no url arg is provided', () => {
- RepoService.url = url;
-
- RepoService.getContent();
-
- expect(axios.get).toHaveBeenCalledWith(url, {
- params,
- });
- });
- });
-
- describe('getBase64Content', () => {
- const url = 'url';
- const response = { data: 'data' };
-
- beforeEach(() => {
- spyOn(RepoService, 'bufferToBase64');
- spyOn(axios, 'get').and.returnValue(Promise.resolve(response));
- });
-
- it('calls axios.get and bufferToBase64 on completion', (done) => {
- const request = RepoService.getBase64Content(url);
-
- expect(axios.get).toHaveBeenCalledWith(url, {
- responseType: 'arraybuffer',
- });
- expect(request).toEqual(jasmine.any(Promise));
-
- request.then(() => {
- expect(RepoService.bufferToBase64).toHaveBeenCalledWith(response.data);
- done();
- }).catch(done.fail);
- });
- });
-
- describe('commitFiles', () => {
- it('calls commitMultiple and .then commitFlash', (done) => {
- const projectId = 'projectId';
- const payload = {};
- RepoStore.projectId = projectId;
-
- spyOn(Api, 'commitMultiple').and.returnValue(Promise.resolve());
- spyOn(RepoService, 'commitFlash');
-
- const apiPromise = RepoService.commitFiles(payload);
-
- expect(Api.commitMultiple).toHaveBeenCalledWith(projectId, payload);
-
- apiPromise.then(() => {
- expect(RepoService.commitFlash).toHaveBeenCalled();
- done();
- }).catch(done.fail);
- });
- });
-
- describe('commitFlash', () => {
- it('calls Flash with data.message', () => {
- const data = {
- message: 'message',
- };
- spyOn(window, 'Flash');
-
- RepoService.commitFlash(data);
-
- expect(window.Flash).toHaveBeenCalledWith(data.message);
- });
-
- it('calls Flash with success string if short_id and stats', () => {
- const data = {
- short_id: 'short_id',
- stats: {
- additions: '4',
- deletions: '5',
- },
- };
- spyOn(window, 'Flash');
-
- RepoService.commitFlash(data);
-
- expect(window.Flash).toHaveBeenCalledWith(`Your changes have been committed. Commit ${data.short_id} with ${data.stats.additions} additions, ${data.stats.deletions} deletions.`, 'notice');
- });
- });
-});
diff --git a/spec/javascripts/search_autocomplete_spec.js b/spec/javascripts/search_autocomplete_spec.js
index cf811af3d6c..5e55a5d2686 100644
--- a/spec/javascripts/search_autocomplete_spec.js
+++ b/spec/javascripts/search_autocomplete_spec.js
@@ -3,7 +3,6 @@
import '~/gl_dropdown';
import '~/search_autocomplete';
import '~/lib/utils/common_utils';
-import 'vendor/fuzzaldrin-plus';
(function() {
var assertLinks, dashboardIssuesPath, dashboardMRsPath, groupIssuesPath, groupMRsPath, groupName, mockDashboardOptions, mockGroupOptions, mockProjectOptions, projectIssuesPath, projectMRsPath, projectName, userId, widget;
diff --git a/spec/javascripts/sidebar/mock_data.js b/spec/javascripts/sidebar/mock_data.js
index e2b6bcabc98..0682b463043 100644
--- a/spec/javascripts/sidebar/mock_data.js
+++ b/spec/javascripts/sidebar/mock_data.js
@@ -109,12 +109,14 @@ const sidebarMockData = {
labels: [],
web_url: '/root/some-project/issues/5',
},
+ '/gitlab-org/gitlab-shell/issues/5/toggle_subscription': {},
},
};
export default {
mediator: {
endpoint: '/gitlab-org/gitlab-shell/issues/5.json',
+ toggleSubscriptionEndpoint: '/gitlab-org/gitlab-shell/issues/5/toggle_subscription',
moveIssueEndpoint: '/gitlab-org/gitlab-shell/issues/5/move',
projectsAutocompleteEndpoint: '/autocomplete/projects?project_id=15',
editable: true,
diff --git a/spec/javascripts/sidebar/participants_spec.js b/spec/javascripts/sidebar/participants_spec.js
new file mode 100644
index 00000000000..30cc549c7c0
--- /dev/null
+++ b/spec/javascripts/sidebar/participants_spec.js
@@ -0,0 +1,174 @@
+import Vue from 'vue';
+import participants from '~/sidebar/components/participants/participants.vue';
+import mountComponent from '../helpers/vue_mount_component_helper';
+
+const PARTICIPANT = {
+ id: 1,
+ state: 'active',
+ username: 'marcene',
+ name: 'Allie Will',
+ web_url: 'foo.com',
+ avatar_url: 'gravatar.com/avatar/xxx',
+};
+
+const PARTICIPANT_LIST = [
+ PARTICIPANT,
+ { ...PARTICIPANT, id: 2 },
+ { ...PARTICIPANT, id: 3 },
+];
+
+describe('Participants', function () {
+ let vm;
+ let Participants;
+
+ beforeEach(() => {
+ Participants = Vue.extend(participants);
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ describe('collapsed sidebar state', () => {
+ it('shows loading spinner when loading', () => {
+ vm = mountComponent(Participants, {
+ loading: true,
+ });
+
+ expect(vm.$el.querySelector('.js-participants-collapsed-loading-icon')).toBeDefined();
+ });
+
+ it('shows participant count when given', () => {
+ vm = mountComponent(Participants, {
+ loading: false,
+ participants: PARTICIPANT_LIST,
+ });
+ const countEl = vm.$el.querySelector('.js-participants-collapsed-count');
+
+ expect(countEl.textContent.trim()).toBe(`${PARTICIPANT_LIST.length}`);
+ });
+
+ it('shows full participant count when there are hidden participants', () => {
+ vm = mountComponent(Participants, {
+ loading: false,
+ participants: PARTICIPANT_LIST,
+ numberOfLessParticipants: 1,
+ });
+ const countEl = vm.$el.querySelector('.js-participants-collapsed-count');
+
+ expect(countEl.textContent.trim()).toBe(`${PARTICIPANT_LIST.length}`);
+ });
+ });
+
+ describe('expanded sidebar state', () => {
+ it('shows loading spinner when loading', () => {
+ vm = mountComponent(Participants, {
+ loading: true,
+ });
+
+ expect(vm.$el.querySelector('.js-participants-expanded-loading-icon')).toBeDefined();
+ });
+
+ it('when only showing visible participants, shows an avatar only for each participant under the limit', (done) => {
+ const numberOfLessParticipants = 2;
+ vm = mountComponent(Participants, {
+ loading: false,
+ participants: PARTICIPANT_LIST,
+ numberOfLessParticipants,
+ });
+ vm.isShowingMoreParticipants = false;
+
+ Vue.nextTick()
+ .then(() => {
+ const participantEls = vm.$el.querySelectorAll('.js-participants-author');
+
+ expect(participantEls.length).toBe(numberOfLessParticipants);
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+
+ it('when only showing all participants, each has an avatar', (done) => {
+ const numberOfLessParticipants = 2;
+ vm = mountComponent(Participants, {
+ loading: false,
+ participants: PARTICIPANT_LIST,
+ numberOfLessParticipants,
+ });
+ vm.isShowingMoreParticipants = true;
+
+ Vue.nextTick()
+ .then(() => {
+ const participantEls = vm.$el.querySelectorAll('.js-participants-author');
+
+ expect(participantEls.length).toBe(PARTICIPANT_LIST.length);
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+
+ it('does not have more participants link when they can all be shown', () => {
+ const numberOfLessParticipants = 100;
+ vm = mountComponent(Participants, {
+ loading: false,
+ participants: PARTICIPANT_LIST,
+ numberOfLessParticipants,
+ });
+ const moreParticipantLink = vm.$el.querySelector('.js-toggle-participants-button');
+
+ expect(PARTICIPANT_LIST.length).toBeLessThan(numberOfLessParticipants);
+ expect(moreParticipantLink).toBeNull();
+ });
+
+ it('when too many participants, has more participants link to show more', (done) => {
+ vm = mountComponent(Participants, {
+ loading: false,
+ participants: PARTICIPANT_LIST,
+ numberOfLessParticipants: 2,
+ });
+ vm.isShowingMoreParticipants = false;
+
+ Vue.nextTick()
+ .then(() => {
+ const moreParticipantLink = vm.$el.querySelector('.js-toggle-participants-button');
+
+ expect(moreParticipantLink.textContent.trim()).toBe('+ 1 more');
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+
+ it('when too many participants and already showing them, has more participants link to show less', (done) => {
+ vm = mountComponent(Participants, {
+ loading: false,
+ participants: PARTICIPANT_LIST,
+ numberOfLessParticipants: 2,
+ });
+ vm.isShowingMoreParticipants = true;
+
+ Vue.nextTick()
+ .then(() => {
+ const moreParticipantLink = vm.$el.querySelector('.js-toggle-participants-button');
+
+ expect(moreParticipantLink.textContent.trim()).toBe('- show less');
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+
+ it('clicking more participants link emits event', () => {
+ vm = mountComponent(Participants, {
+ loading: false,
+ participants: PARTICIPANT_LIST,
+ numberOfLessParticipants: 2,
+ });
+ const moreParticipantLink = vm.$el.querySelector('.js-toggle-participants-button');
+
+ expect(vm.isShowingMoreParticipants).toBe(false);
+
+ moreParticipantLink.click();
+
+ expect(vm.isShowingMoreParticipants).toBe(true);
+ });
+ });
+});
diff --git a/spec/javascripts/sidebar/sidebar_mediator_spec.js b/spec/javascripts/sidebar/sidebar_mediator_spec.js
index 3aa8ca5db0d..7deb1fd2118 100644
--- a/spec/javascripts/sidebar/sidebar_mediator_spec.js
+++ b/spec/javascripts/sidebar/sidebar_mediator_spec.js
@@ -57,8 +57,8 @@ describe('Sidebar mediator', () => {
.then(() => {
expect(this.mediator.service.getProjectsAutocomplete).toHaveBeenCalledWith(searchTerm);
expect(this.mediator.store.setAutocompleteProjects).toHaveBeenCalled();
- done();
})
+ .then(done)
.catch(done.fail);
});
@@ -72,8 +72,21 @@ describe('Sidebar mediator', () => {
.then(() => {
expect(this.mediator.service.moveIssue).toHaveBeenCalledWith(moveToProjectId);
expect(gl.utils.visitUrl).toHaveBeenCalledWith('/root/some-project/issues/5');
- done();
})
+ .then(done)
+ .catch(done.fail);
+ });
+
+ it('toggle subscription', (done) => {
+ this.mediator.store.setSubscribedState(false);
+ spyOn(this.mediator.service, 'toggleSubscription').and.callThrough();
+
+ this.mediator.toggleSubscription()
+ .then(() => {
+ expect(this.mediator.service.toggleSubscription).toHaveBeenCalled();
+ expect(this.mediator.store.subscribed).toEqual(true);
+ })
+ .then(done)
.catch(done.fail);
});
});
diff --git a/spec/javascripts/sidebar/sidebar_service_spec.js b/spec/javascripts/sidebar/sidebar_service_spec.js
index a4bd8ba8d88..7324d34d84a 100644
--- a/spec/javascripts/sidebar/sidebar_service_spec.js
+++ b/spec/javascripts/sidebar/sidebar_service_spec.js
@@ -7,6 +7,7 @@ describe('Sidebar service', () => {
Vue.http.interceptors.push(Mock.sidebarMockInterceptor);
this.service = new SidebarService({
endpoint: '/gitlab-org/gitlab-shell/issues/5.json',
+ toggleSubscriptionEndpoint: '/gitlab-org/gitlab-shell/issues/5/toggle_subscription',
moveIssueEndpoint: '/gitlab-org/gitlab-shell/issues/5/move',
projectsAutocompleteEndpoint: '/autocomplete/projects?project_id=15',
});
@@ -23,6 +24,7 @@ describe('Sidebar service', () => {
expect(resp).toBeDefined();
done();
})
+ .then(done)
.catch(done.fail);
});
@@ -30,8 +32,8 @@ describe('Sidebar service', () => {
this.service.update('issue[assignee_ids]', [1])
.then((resp) => {
expect(resp).toBeDefined();
- done();
})
+ .then(done)
.catch(done.fail);
});
@@ -39,8 +41,8 @@ describe('Sidebar service', () => {
this.service.getProjectsAutocomplete()
.then((resp) => {
expect(resp).toBeDefined();
- done();
})
+ .then(done)
.catch(done.fail);
});
@@ -48,8 +50,17 @@ describe('Sidebar service', () => {
this.service.moveIssue(123)
.then((resp) => {
expect(resp).toBeDefined();
- done();
})
+ .then(done)
+ .catch(done.fail);
+ });
+
+ it('toggles the subscription', (done) => {
+ this.service.toggleSubscription()
+ .then((resp) => {
+ expect(resp).toBeDefined();
+ })
+ .then(done)
.catch(done.fail);
});
});
diff --git a/spec/javascripts/sidebar/sidebar_store_spec.js b/spec/javascripts/sidebar/sidebar_store_spec.js
index 69eb3839d67..51dee64fb93 100644
--- a/spec/javascripts/sidebar/sidebar_store_spec.js
+++ b/spec/javascripts/sidebar/sidebar_store_spec.js
@@ -2,21 +2,36 @@ import SidebarStore from '~/sidebar/stores/sidebar_store';
import Mock from './mock_data';
import UsersMockHelper from '../helpers/user_mock_data_helper';
-describe('Sidebar store', () => {
- const assignee = {
- id: 2,
- name: 'gitlab user 2',
- username: 'gitlab2',
- avatar_url: 'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
- };
-
- const anotherAssignee = {
- id: 3,
- name: 'gitlab user 3',
- username: 'gitlab3',
- avatar_url: 'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
- };
+const ASSIGNEE = {
+ id: 2,
+ name: 'gitlab user 2',
+ username: 'gitlab2',
+ avatar_url: 'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
+};
+
+const ANOTHER_ASSINEE = {
+ id: 3,
+ name: 'gitlab user 3',
+ username: 'gitlab3',
+ avatar_url: 'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
+};
+
+const PARTICIPANT = {
+ id: 1,
+ state: 'active',
+ username: 'marcene',
+ name: 'Allie Will',
+ web_url: 'foo.com',
+ avatar_url: 'gravatar.com/avatar/xxx',
+};
+
+const PARTICIPANT_LIST = [
+ PARTICIPANT,
+ { ...PARTICIPANT, id: 2 },
+ { ...PARTICIPANT, id: 3 },
+];
+describe('Sidebar store', () => {
beforeEach(() => {
this.store = new SidebarStore({
currentUser: {
@@ -40,23 +55,23 @@ describe('Sidebar store', () => {
});
it('adds a new assignee', () => {
- this.store.addAssignee(assignee);
+ this.store.addAssignee(ASSIGNEE);
expect(this.store.assignees.length).toEqual(1);
});
it('removes an assignee', () => {
- this.store.removeAssignee(assignee);
+ this.store.removeAssignee(ASSIGNEE);
expect(this.store.assignees.length).toEqual(0);
});
it('finds an existent assignee', () => {
let foundAssignee;
- this.store.addAssignee(assignee);
- foundAssignee = this.store.findAssignee(assignee);
+ this.store.addAssignee(ASSIGNEE);
+ foundAssignee = this.store.findAssignee(ASSIGNEE);
expect(foundAssignee).toBeDefined();
- expect(foundAssignee).toEqual(assignee);
- foundAssignee = this.store.findAssignee(anotherAssignee);
+ expect(foundAssignee).toEqual(ASSIGNEE);
+ foundAssignee = this.store.findAssignee(ANOTHER_ASSINEE);
expect(foundAssignee).toBeUndefined();
});
@@ -65,6 +80,28 @@ describe('Sidebar store', () => {
expect(this.store.assignees.length).toEqual(0);
});
+ it('sets participants data', () => {
+ expect(this.store.participants.length).toEqual(0);
+
+ this.store.setParticipantsData({
+ participants: PARTICIPANT_LIST,
+ });
+
+ expect(this.store.isFetching.participants).toEqual(false);
+ expect(this.store.participants.length).toEqual(PARTICIPANT_LIST.length);
+ });
+
+ it('sets subcriptions data', () => {
+ expect(this.store.subscribed).toEqual(null);
+
+ this.store.setSubscriptionsData({
+ subscribed: true,
+ });
+
+ expect(this.store.isFetching.subscriptions).toEqual(false);
+ expect(this.store.subscribed).toEqual(true);
+ });
+
it('set assigned data', () => {
const users = {
assignees: UsersMockHelper.createNumberRandomUsers(3),
@@ -75,6 +112,14 @@ describe('Sidebar store', () => {
expect(this.store.assignees.length).toEqual(3);
});
+ it('sets fetching state', () => {
+ expect(this.store.isFetching.participants).toEqual(true);
+
+ this.store.setFetchingState('participants', false);
+
+ expect(this.store.isFetching.participants).toEqual(false);
+ });
+
it('set time tracking data', () => {
this.store.setTimeTrackingData(Mock.time);
expect(this.store.timeEstimate).toEqual(Mock.time.time_estimate);
@@ -90,6 +135,14 @@ describe('Sidebar store', () => {
expect(this.store.autocompleteProjects).toEqual(projects);
});
+ it('sets subscribed state', () => {
+ expect(this.store.subscribed).toEqual(null);
+
+ this.store.setSubscribedState(true);
+
+ expect(this.store.subscribed).toEqual(true);
+ });
+
it('set move to project ID', () => {
const projectId = 7;
this.store.setMoveToProjectId(projectId);
diff --git a/spec/javascripts/sidebar/sidebar_subscriptions_spec.js b/spec/javascripts/sidebar/sidebar_subscriptions_spec.js
new file mode 100644
index 00000000000..7adf22b0f1f
--- /dev/null
+++ b/spec/javascripts/sidebar/sidebar_subscriptions_spec.js
@@ -0,0 +1,36 @@
+import Vue from 'vue';
+import sidebarSubscriptions from '~/sidebar/components/subscriptions/sidebar_subscriptions.vue';
+import SidebarMediator from '~/sidebar/sidebar_mediator';
+import SidebarService from '~/sidebar/services/sidebar_service';
+import SidebarStore from '~/sidebar/stores/sidebar_store';
+import eventHub from '~/sidebar/event_hub';
+import mountComponent from '../helpers/vue_mount_component_helper';
+import Mock from './mock_data';
+
+describe('Sidebar Subscriptions', function () {
+ let vm;
+ let SidebarSubscriptions;
+
+ beforeEach(() => {
+ SidebarSubscriptions = Vue.extend(sidebarSubscriptions);
+ // Setup the stores, services, etc
+ // eslint-disable-next-line no-new
+ new SidebarMediator(Mock.mediator);
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+ SidebarService.singleton = null;
+ SidebarStore.singleton = null;
+ SidebarMediator.singleton = null;
+ });
+
+ it('calls the mediator toggleSubscription on event', () => {
+ spyOn(SidebarMediator.prototype, 'toggleSubscription').and.returnValue(Promise.resolve());
+ vm = mountComponent(SidebarSubscriptions, {});
+
+ eventHub.$emit('toggleSubscription');
+
+ expect(SidebarMediator.prototype.toggleSubscription).toHaveBeenCalled();
+ });
+});
diff --git a/spec/javascripts/sidebar/subscriptions_spec.js b/spec/javascripts/sidebar/subscriptions_spec.js
new file mode 100644
index 00000000000..9b33dd02fb9
--- /dev/null
+++ b/spec/javascripts/sidebar/subscriptions_spec.js
@@ -0,0 +1,42 @@
+import Vue from 'vue';
+import subscriptions from '~/sidebar/components/subscriptions/subscriptions.vue';
+import mountComponent from '../helpers/vue_mount_component_helper';
+
+describe('Subscriptions', function () {
+ let vm;
+ let Subscriptions;
+
+ beforeEach(() => {
+ Subscriptions = Vue.extend(subscriptions);
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ it('shows loading spinner when loading', () => {
+ vm = mountComponent(Subscriptions, {
+ loading: true,
+ subscribed: undefined,
+ });
+
+ expect(vm.$refs.loadingButton.loading).toBe(true);
+ expect(vm.$refs.loadingButton.label).toBeUndefined();
+ });
+
+ it('has "Subscribe" text when currently not subscribed', () => {
+ vm = mountComponent(Subscriptions, {
+ subscribed: false,
+ });
+
+ expect(vm.$refs.loadingButton.label).toBe('Subscribe');
+ });
+
+ it('has "Unsubscribe" text when currently not subscribed', () => {
+ vm = mountComponent(Subscriptions, {
+ subscribed: true,
+ });
+
+ expect(vm.$refs.loadingButton.label).toBe('Unsubscribe');
+ });
+});
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js
index d7019ea408b..df3d29ee1f9 100644
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js
+++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js
@@ -43,6 +43,10 @@ describe('MRWidgetReadyToMerge', () => {
vm = createComponent();
});
+ afterEach(() => {
+ vm.$destroy();
+ });
+
describe('props', () => {
it('should have props', () => {
const { mr, service } = readyToMergeComponent.props;
@@ -495,6 +499,48 @@ describe('MRWidgetReadyToMerge', () => {
});
});
+ describe('Merge controls', () => {
+ describe('when allowed to merge', () => {
+ beforeEach(() => {
+ vm = createComponent({
+ mr: { isMergeAllowed: true },
+ });
+ });
+
+ it('shows remove source branch checkbox', () => {
+ expect(vm.$el.querySelector('.js-remove-source-branch-checkbox')).toBeDefined();
+ });
+
+ it('shows modify commit message button', () => {
+ expect(vm.$el.querySelector('.js-modify-commit-message-button')).toBeDefined();
+ });
+
+ it('does not show message about needing to resolve items', () => {
+ expect(vm.$el.querySelector('.js-resolve-mr-widget-items-message')).toBeNull();
+ });
+ });
+
+ describe('when not allowed to merge', () => {
+ beforeEach(() => {
+ vm = createComponent({
+ mr: { isMergeAllowed: false },
+ });
+ });
+
+ it('does not show remove source branch checkbox', () => {
+ expect(vm.$el.querySelector('.js-remove-source-branch-checkbox')).toBeNull();
+ });
+
+ it('does not show modify commit message button', () => {
+ expect(vm.$el.querySelector('.js-modify-commit-message-button')).toBeNull();
+ });
+
+ it('shows message to resolve all items before being allowed to merge', () => {
+ expect(vm.$el.querySelector('.js-resolve-mr-widget-items-message')).toBeDefined();
+ });
+ });
+ });
+
describe('Commit message area', () => {
it('when using merge commits, should show "Modify commit message" button', () => {
const customVm = createComponent({
diff --git a/spec/javascripts/vue_shared/components/ci_badge_link_spec.js b/spec/javascripts/vue_shared/components/ci_badge_link_spec.js
index daed4da3e15..ba303738f71 100644
--- a/spec/javascripts/vue_shared/components/ci_badge_link_spec.js
+++ b/spec/javascripts/vue_shared/components/ci_badge_link_spec.js
@@ -1,8 +1,10 @@
import Vue from 'vue';
import ciBadge from '~/vue_shared/components/ci_badge_link.vue';
+import mountComponent from '../../helpers/vue_mount_component_helper';
describe('CI Badge Link Component', () => {
let CIBadge;
+ let vm;
const statuses = {
canceled: {
@@ -70,15 +72,17 @@ describe('CI Badge Link Component', () => {
},
};
- it('should render each status badge', () => {
+ beforeEach(() => {
CIBadge = Vue.extend(ciBadge);
- Object.keys(statuses).map((status) => {
- const vm = new CIBadge({
- propsData: {
- status: statuses[status],
- },
- }).$mount();
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+ it('should render each status badge', () => {
+ Object.keys(statuses).map((status) => {
+ vm = mountComponent(CIBadge, { status: statuses[status] });
expect(vm.$el.getAttribute('href')).toEqual(statuses[status].details_path);
expect(vm.$el.textContent.trim()).toEqual(statuses[status].text);
expect(vm.$el.getAttribute('class')).toEqual(`ci-status ci-${statuses[status].group}`);
@@ -86,4 +90,9 @@ describe('CI Badge Link Component', () => {
return vm;
});
});
+
+ it('should not render label', () => {
+ vm = mountComponent(CIBadge, { status: statuses.canceled, showText: false });
+ expect(vm.$el.textContent.trim()).toEqual('');
+ });
});
diff --git a/spec/javascripts/vue_shared/components/loading_button_spec.js b/spec/javascripts/vue_shared/components/loading_button_spec.js
new file mode 100644
index 00000000000..97c8a08fcdd
--- /dev/null
+++ b/spec/javascripts/vue_shared/components/loading_button_spec.js
@@ -0,0 +1,93 @@
+import Vue from 'vue';
+import loadingButton from '~/vue_shared/components/loading_button.vue';
+import mountComponent from '../../helpers/vue_mount_component_helper';
+
+const LABEL = 'Hello';
+
+describe('LoadingButton', function () {
+ let vm;
+ let LoadingButton;
+
+ beforeEach(() => {
+ LoadingButton = Vue.extend(loadingButton);
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ describe('loading spinner', () => {
+ it('shown when loading', () => {
+ vm = mountComponent(LoadingButton, {
+ loading: true,
+ });
+
+ expect(vm.$el.querySelector('.js-loading-button-icon')).toBeDefined();
+ });
+ });
+
+ describe('disabled state', () => {
+ it('disabled when loading', () => {
+ vm = mountComponent(LoadingButton, {
+ loading: true,
+ });
+
+ expect(vm.$el.disabled).toEqual(true);
+ });
+
+ it('not disabled when normal', () => {
+ vm = mountComponent(LoadingButton, {
+ loading: false,
+ });
+
+ expect(vm.$el.disabled).toEqual(false);
+ });
+ });
+
+ describe('label', () => {
+ it('shown when normal', () => {
+ vm = mountComponent(LoadingButton, {
+ loading: false,
+ label: LABEL,
+ });
+ const label = vm.$el.querySelector('.js-loading-button-label');
+
+ expect(label.textContent.trim()).toEqual(LABEL);
+ });
+
+ it('shown when loading', () => {
+ vm = mountComponent(LoadingButton, {
+ loading: true,
+ label: LABEL,
+ });
+ const label = vm.$el.querySelector('.js-loading-button-label');
+
+ expect(label.textContent.trim()).toEqual(LABEL);
+ });
+ });
+
+ describe('click callback prop', () => {
+ it('calls given callback when normal', () => {
+ vm = mountComponent(LoadingButton, {
+ loading: false,
+ });
+ spyOn(vm, '$emit');
+
+ vm.$el.click();
+
+ expect(vm.$emit).toHaveBeenCalledWith('click', jasmine.any(Object));
+ });
+
+ it('does not call given callback when disabled because of loading', () => {
+ vm = mountComponent(LoadingButton, {
+ loading: true,
+ indeterminate: true,
+ });
+ spyOn(vm, '$emit');
+
+ vm.$el.click();
+
+ expect(vm.$emit).not.toHaveBeenCalled();
+ });
+ });
+});
diff --git a/spec/javascripts/notes/components/issue_placeholder_note_spec.js b/spec/javascripts/vue_shared/components/notes/placeholder_note_spec.js
index 6e5275087f3..ba8ab0b2cd7 100644
--- a/spec/javascripts/notes/components/issue_placeholder_note_spec.js
+++ b/spec/javascripts/vue_shared/components/notes/placeholder_note_spec.js
@@ -1,7 +1,7 @@
import Vue from 'vue';
-import issuePlaceholderNote from '~/notes/components/issue_placeholder_note.vue';
+import issuePlaceholderNote from '~/vue_shared/components/notes/placeholder_note.vue';
import store from '~/notes/stores';
-import { userDataMock } from '../mock_data';
+import { userDataMock } from '../../../notes/mock_data';
describe('issue placeholder system note component', () => {
let vm;
diff --git a/spec/javascripts/vue_shared/components/notes/placeholder_system_note_spec.js b/spec/javascripts/vue_shared/components/notes/placeholder_system_note_spec.js
new file mode 100644
index 00000000000..7b8e6c330c2
--- /dev/null
+++ b/spec/javascripts/vue_shared/components/notes/placeholder_system_note_spec.js
@@ -0,0 +1,25 @@
+import Vue from 'vue';
+import placeholderSystemNote from '~/vue_shared/components/notes/placeholder_system_note.vue';
+import mountComponent from '../../../helpers/vue_mount_component_helper';
+
+describe('placeholder system note component', () => {
+ let PlaceholderSystemNote;
+ let vm;
+
+ beforeEach(() => {
+ PlaceholderSystemNote = Vue.extend(placeholderSystemNote);
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ it('should render system note placeholder with plain text', () => {
+ vm = mountComponent(PlaceholderSystemNote, {
+ note: { body: 'This is a placeholder' },
+ });
+
+ expect(vm.$el.tagName).toEqual('LI');
+ expect(vm.$el.querySelector('.timeline-content em').textContent.trim()).toEqual('This is a placeholder');
+ });
+});
diff --git a/spec/javascripts/notes/components/issue_system_note_spec.js b/spec/javascripts/vue_shared/components/notes/system_note_spec.js
index c317ce32716..36aaf0a6c2e 100644
--- a/spec/javascripts/notes/components/issue_system_note_spec.js
+++ b/spec/javascripts/vue_shared/components/notes/system_note_spec.js
@@ -1,5 +1,5 @@
import Vue from 'vue';
-import issueSystemNote from '~/notes/components/issue_system_note.vue';
+import issueSystemNote from '~/vue_shared/components/notes/system_note.vue';
import store from '~/notes/stores';
describe('issue system note', () => {
@@ -33,6 +33,10 @@ describe('issue system note', () => {
}).$mount();
});
+ afterEach(() => {
+ vm.$destroy();
+ });
+
it('should render a list item with correct id', () => {
expect(vm.$el.getAttribute('id')).toEqual(`note_${props.note.id}`);
});
diff --git a/spec/javascripts/vue_shared/components/user_avatar/user_avatar_link_spec.js b/spec/javascripts/vue_shared/components/user_avatar/user_avatar_link_spec.js
index 52e450e9ba5..8450ad9dbcb 100644
--- a/spec/javascripts/vue_shared/components/user_avatar/user_avatar_link_spec.js
+++ b/spec/javascripts/vue_shared/components/user_avatar/user_avatar_link_spec.js
@@ -11,6 +11,7 @@ describe('User Avatar Link Component', function () {
imgCssClasses: 'myextraavatarclass',
tooltipText: 'tooltip text',
tooltipPlacement: 'bottom',
+ username: 'username',
};
const UserAvatarLinkComponent = Vue.extend(UserAvatarLink);
@@ -47,4 +48,42 @@ describe('User Avatar Link Component', function () {
expect(this.userAvatarLink[key]).toBeDefined();
});
});
+
+ describe('no username', function () {
+ beforeEach(function (done) {
+ this.userAvatarLink.username = '';
+
+ Vue.nextTick(done);
+ });
+
+ it('should only render image tag in link', function () {
+ const childElements = this.userAvatarLink.$el.childNodes;
+ expect(childElements[0].tagName).toBe('IMG');
+
+ // Vue will render the hidden component as <!---->
+ expect(childElements[1].tagName).toBeUndefined();
+ });
+
+ it('should render avatar image tooltip', function () {
+ expect(this.userAvatarLink.$el.querySelector('img').dataset.originalTitle).toEqual(this.propsData.tooltipText);
+ });
+ });
+
+ describe('username', function () {
+ it('should not render avatar image tooltip', function () {
+ expect(this.userAvatarLink.$el.querySelector('img').dataset.originalTitle).toEqual('');
+ });
+
+ it('should render username prop in <span>', function () {
+ expect(this.userAvatarLink.$el.querySelector('span').innerText.trim()).toEqual(this.propsData.username);
+ });
+
+ it('should render text tooltip for <span>', function () {
+ expect(this.userAvatarLink.$el.querySelector('span').dataset.originalTitle).toEqual(this.propsData.tooltipText);
+ });
+
+ it('should render text tooltip placement for <span>', function () {
+ expect(this.userAvatarLink.$el.querySelector('span').getAttribute('tooltip-placement')).toEqual(this.propsData.tooltipPlacement);
+ });
+ });
});
diff --git a/spec/lib/additional_email_headers_interceptor_spec.rb b/spec/lib/additional_email_headers_interceptor_spec.rb
index 580450eef1e..b5c1a360ba9 100644
--- a/spec/lib/additional_email_headers_interceptor_spec.rb
+++ b/spec/lib/additional_email_headers_interceptor_spec.rb
@@ -1,12 +1,29 @@
require 'spec_helper'
describe AdditionalEmailHeadersInterceptor do
- it 'adds Auto-Submitted header' do
- mail = ActionMailer::Base.mail(to: 'test@mail.com', from: 'info@mail.com', body: 'hello').deliver
+ let(:mail) do
+ ActionMailer::Base.mail(to: 'test@mail.com', from: 'info@mail.com', body: 'hello')
+ end
+
+ before do
+ mail.deliver_now
+ end
+ it 'adds Auto-Submitted header' do
expect(mail.header['To'].value).to eq('test@mail.com')
expect(mail.header['From'].value).to eq('info@mail.com')
expect(mail.header['Auto-Submitted'].value).to eq('auto-generated')
expect(mail.header['X-Auto-Response-Suppress'].value).to eq('All')
end
+
+ context 'when the same mail object is sent twice' do
+ before do
+ mail.deliver_now
+ end
+
+ it 'does not add the Auto-Submitted header twice' do
+ expect(mail.header['Auto-Submitted'].value).to eq('auto-generated')
+ expect(mail.header['X-Auto-Response-Suppress'].value).to eq('All')
+ end
+ end
end
diff --git a/spec/lib/banzai/filter/gollum_tags_filter_spec.rb b/spec/lib/banzai/filter/gollum_tags_filter_spec.rb
index 97d612e6347..ca76d6f0881 100644
--- a/spec/lib/banzai/filter/gollum_tags_filter_spec.rb
+++ b/spec/lib/banzai/filter/gollum_tags_filter_spec.rb
@@ -15,9 +15,13 @@ describe Banzai::Filter::GollumTagsFilter do
context 'linking internal images' do
it 'creates img tag if image exists' do
- file = Gollum::File.new(project_wiki.wiki)
- expect(file).to receive(:path).and_return('images/image.jpg')
- expect(project_wiki).to receive(:find_file).with('images/image.jpg').and_return(file)
+ gollum_file_double = double('Gollum::File',
+ mime_type: 'image/jpeg',
+ name: 'images/image.jpg',
+ path: 'images/image.jpg',
+ raw_data: '')
+ wiki_file = Gitlab::Git::WikiFile.new(gollum_file_double)
+ expect(project_wiki).to receive(:find_file).with('images/image.jpg').and_return(wiki_file)
tag = '[[images/image.jpg]]'
doc = filter("See #{tag}", project_wiki: project_wiki)
diff --git a/spec/lib/gitlab/app_logger_spec.rb b/spec/lib/gitlab/app_logger_spec.rb
new file mode 100644
index 00000000000..c86d30ce6df
--- /dev/null
+++ b/spec/lib/gitlab/app_logger_spec.rb
@@ -0,0 +1,12 @@
+require 'spec_helper'
+
+describe Gitlab::AppLogger, :request_store do
+ subject { described_class }
+
+ it 'builds a logger once' do
+ expect(::Logger).to receive(:new).and_call_original
+
+ subject.info('hello world')
+ subject.error('hello again')
+ end
+end
diff --git a/spec/lib/gitlab/database_spec.rb b/spec/lib/gitlab/database_spec.rb
index 5fa94999d25..7aeb85b8f5a 100644
--- a/spec/lib/gitlab/database_spec.rb
+++ b/spec/lib/gitlab/database_spec.rb
@@ -256,4 +256,26 @@ describe Gitlab::Database do
expect(described_class.false_value).to eq 0
end
end
+
+ describe '#sanitize_timestamp' do
+ let(:max_timestamp) { Time.at((1 << 31) - 1) }
+
+ subject { described_class.sanitize_timestamp(timestamp) }
+
+ context 'with a timestamp smaller than MAX_TIMESTAMP_VALUE' do
+ let(:timestamp) { max_timestamp - 10.years }
+
+ it 'returns the given timestamp' do
+ expect(subject).to eq(timestamp)
+ end
+ end
+
+ context 'with a timestamp larger than MAX_TIMESTAMP_VALUE' do
+ let(:timestamp) { max_timestamp + 1.second }
+
+ it 'returns MAX_TIMESTAMP_VALUE' do
+ expect(subject).to eq(max_timestamp)
+ end
+ end
+ end
end
diff --git a/spec/lib/gitlab/diff/position_spec.rb b/spec/lib/gitlab/diff/position_spec.rb
index 245f24e96d4..677eb373d22 100644
--- a/spec/lib/gitlab/diff/position_spec.rb
+++ b/spec/lib/gitlab/diff/position_spec.rb
@@ -364,6 +364,43 @@ describe Gitlab::Diff::Position do
end
end
+ describe "position for a missing ref" do
+ let(:diff_refs) do
+ Gitlab::Diff::DiffRefs.new(
+ base_sha: "not_existing_sha",
+ head_sha: "existing_sha"
+ )
+ end
+
+ subject do
+ described_class.new(
+ old_path: "files/ruby/feature.rb",
+ new_path: "files/ruby/feature.rb",
+ old_line: 3,
+ new_line: nil,
+ diff_refs: diff_refs
+ )
+ end
+
+ describe "#diff_file" do
+ it "does not raise exception" do
+ expect { subject.diff_file(project.repository) }.not_to raise_error
+ end
+ end
+
+ describe "#diff_line" do
+ it "does not raise exception" do
+ expect { subject.diff_line(project.repository) }.not_to raise_error
+ end
+ end
+
+ describe "#line_code" do
+ it "does not raise exception" do
+ expect { subject.line_code(project.repository) }.not_to raise_error
+ end
+ end
+ end
+
describe "position for a file in the initial commit" do
let(:commit) { project.commit("1a0b36b3cdad1d2ee32457c102a8c0b7056fa863") }
diff --git a/spec/lib/gitlab/git/branch_spec.rb b/spec/lib/gitlab/git/branch_spec.rb
index 318a7b7a332..708870060e7 100644
--- a/spec/lib/gitlab/git/branch_spec.rb
+++ b/spec/lib/gitlab/git/branch_spec.rb
@@ -7,6 +7,38 @@ describe Gitlab::Git::Branch, seed_helper: true do
it { is_expected.to be_kind_of Array }
+ describe '.find' do
+ subject { described_class.find(repository, branch) }
+
+ before do
+ allow(repository).to receive(:find_branch).with(branch)
+ .and_call_original
+ end
+
+ context 'when finding branch via branch name' do
+ let(:branch) { 'master' }
+
+ it 'returns a branch object' do
+ expect(subject).to be_a(described_class)
+ expect(subject.name).to eq(branch)
+
+ expect(repository).to have_received(:find_branch).with(branch)
+ end
+ end
+
+ context 'when the branch is already a branch' do
+ let(:commit) { repository.commit('master') }
+ let(:branch) { described_class.new(repository, 'master', commit.sha, commit) }
+
+ it 'returns a branch object' do
+ expect(subject).to be_a(described_class)
+ expect(subject).to eq(branch)
+
+ expect(repository).not_to have_received(:find_branch).with(branch)
+ end
+ end
+ end
+
describe '#size' do
subject { super().size }
it { is_expected.to eq(SeedRepo::Repo::BRANCHES.size) }
diff --git a/spec/lib/gitlab/git/hooks_service_spec.rb b/spec/lib/gitlab/git/hooks_service_spec.rb
index 51e4e3fdad1..3ed3feb4c74 100644
--- a/spec/lib/gitlab/git/hooks_service_spec.rb
+++ b/spec/lib/gitlab/git/hooks_service_spec.rb
@@ -1,24 +1,26 @@
require 'spec_helper'
describe Gitlab::Git::HooksService, seed_helper: true do
- let(:user) { Gitlab::Git::User.new('janedoe', 'Jane Doe', 'janedoe@example.com', 'user-456') }
+ let(:gl_id) { 'user-456' }
+ let(:gl_username) { 'janedoe' }
+ let(:user) { Gitlab::Git::User.new(gl_username, 'Jane Doe', 'janedoe@example.com', gl_id) }
let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH, 'project-123') }
let(:service) { described_class.new }
-
- before do
- @blankrev = Gitlab::Git::BLANK_SHA
- @oldrev = SeedRepo::Commit::PARENT_ID
- @newrev = SeedRepo::Commit::ID
- @ref = 'refs/heads/feature'
- end
+ let(:blankrev) { Gitlab::Git::BLANK_SHA }
+ let(:oldrev) { SeedRepo::Commit::PARENT_ID }
+ let(:newrev) { SeedRepo::Commit::ID }
+ let(:ref) { 'refs/heads/feature' }
describe '#execute' do
context 'when receive hooks were successful' do
- it 'calls post-receive hook' do
- hook = double(trigger: [true, nil])
+ let(:hook) { double(:hook) }
+
+ it 'calls all three hooks' do
expect(Gitlab::Git::Hook).to receive(:new).exactly(3).times.and_return(hook)
+ expect(hook).to receive(:trigger).with(gl_id, gl_username, blankrev, newrev, ref)
+ .exactly(3).times.and_return([true, nil])
- service.execute(user, repository, @blankrev, @newrev, @ref) { }
+ service.execute(user, repository, blankrev, newrev, ref) { }
end
end
@@ -28,7 +30,7 @@ describe Gitlab::Git::HooksService, seed_helper: true do
expect(service).not_to receive(:run_hook).with('post-receive')
expect do
- service.execute(user, repository, @blankrev, @newrev, @ref)
+ service.execute(user, repository, blankrev, newrev, ref)
end.to raise_error(Gitlab::Git::HooksService::PreReceiveError)
end
end
@@ -40,7 +42,7 @@ describe Gitlab::Git::HooksService, seed_helper: true do
expect(service).not_to receive(:run_hook).with('post-receive')
expect do
- service.execute(user, repository, @blankrev, @newrev, @ref)
+ service.execute(user, repository, blankrev, newrev, ref)
end.to raise_error(Gitlab::Git::HooksService::PreReceiveError)
end
end
diff --git a/spec/lib/gitlab/git/repository_spec.rb b/spec/lib/gitlab/git/repository_spec.rb
index b2d2f770e3d..b161d25b96c 100644
--- a/spec/lib/gitlab/git/repository_spec.rb
+++ b/spec/lib/gitlab/git/repository_spec.rb
@@ -1135,6 +1135,32 @@ describe Gitlab::Git::Repository, seed_helper: true do
end
end
+ describe '#merged_branch_names' do
+ context 'when branch names are passed' do
+ it 'only returns the names we are asking' do
+ names = repository.merged_branch_names(%w[merge-test])
+
+ expect(names).to contain_exactly('merge-test')
+ end
+
+ it 'does not return unmerged branch names' do
+ names = repository.merged_branch_names(%w[feature])
+
+ expect(names).to be_empty
+ end
+ end
+
+ context 'when no branch names are specified' do
+ it 'returns all merged branch names' do
+ names = repository.merged_branch_names
+
+ expect(names).to include('merge-test')
+ expect(names).to include('fix-mode')
+ expect(names).not_to include('feature')
+ end
+ end
+ end
+
describe "#ls_files" do
let(:master_file_paths) { repository.ls_files("master") }
let(:not_existed_branch) { repository.ls_files("not_existed_branch") }
@@ -1564,6 +1590,60 @@ describe Gitlab::Git::Repository, seed_helper: true do
end
end
+ describe '#ff_merge' do
+ let(:repository) do
+ Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH, '')
+ end
+ let(:branch_head) { '6d394385cf567f80a8fd85055db1ab4c5295806f' }
+ let(:source_sha) { 'cfe32cf61b73a0d5e9f13e774abde7ff789b1660' }
+ let(:user) { build(:user) }
+ let(:target_branch) { 'test-ff-target-branch' }
+
+ before do
+ repository.create_branch(target_branch, branch_head)
+ end
+
+ after do
+ ensure_seeds
+ end
+
+ subject { repository.ff_merge(user, source_sha, target_branch) }
+
+ it 'performs a ff_merge' do
+ expect(subject.newrev).to eq(source_sha)
+ expect(subject.repo_created).to be(false)
+ expect(subject.branch_created).to be(false)
+
+ expect(repository.commit(target_branch).id).to eq(source_sha)
+ end
+
+ context 'with a non-existing target branch' do
+ subject { repository.ff_merge(user, source_sha, 'this-isnt-real') }
+
+ it 'throws an ArgumentError' do
+ expect { subject }.to raise_error(ArgumentError)
+ end
+ end
+
+ context 'with a non-existing source commit' do
+ let(:source_sha) { 'f001' }
+
+ it 'throws an ArgumentError' do
+ expect { subject }.to raise_error(ArgumentError)
+ end
+ end
+
+ context 'when the source sha is not a descendant of the branch head' do
+ let(:source_sha) { '1a0b36b3cdad1d2ee32457c102a8c0b7056fa863' }
+
+ it "doesn't perform the ff_merge" do
+ expect { subject }.to raise_error(Gitlab::Git::CommitError)
+
+ expect(repository.commit(target_branch).id).to eq(branch_head)
+ end
+ end
+ end
+
def create_remote_branch(repository, remote_name, branch_name, source_branch_name)
source_branch = repository.branches.find { |branch| branch.name == source_branch_name }
rugged = repository.rugged
diff --git a/spec/lib/gitlab/git/storage/circuit_breaker_spec.rb b/spec/lib/gitlab/git/storage/circuit_breaker_spec.rb
index c8d532df059..72dabca793a 100644
--- a/spec/lib/gitlab/git/storage/circuit_breaker_spec.rb
+++ b/spec/lib/gitlab/git/storage/circuit_breaker_spec.rb
@@ -79,7 +79,9 @@ describe Gitlab::Git::Storage::CircuitBreaker, clean_gitlab_redis_shared_state:
stub_application_setting(circuitbreaker_failure_count_threshold: 0,
circuitbreaker_failure_wait_time: 1,
circuitbreaker_failure_reset_time: 2,
- circuitbreaker_storage_timeout: 3)
+ circuitbreaker_storage_timeout: 3,
+ circuitbreaker_access_retries: 4,
+ circuitbreaker_backoff_threshold: 5)
end
describe '#failure_count_threshold' do
@@ -105,14 +107,43 @@ describe Gitlab::Git::Storage::CircuitBreaker, clean_gitlab_redis_shared_state:
expect(circuit_breaker.storage_timeout).to eq(3)
end
end
+
+ describe '#access_retries' do
+ it 'reads the value from settings' do
+ expect(circuit_breaker.access_retries).to eq(4)
+ end
+ end
+
+ describe '#backoff_threshold' do
+ it 'reads the value from settings' do
+ expect(circuit_breaker.backoff_threshold).to eq(5)
+ end
+ end
end
describe '#perform' do
- it 'raises an exception with retry time when the circuit is open' do
- allow(circuit_breaker).to receive(:circuit_broken?).and_return(true)
+ it 'raises the correct exception when the circuit is open' do
+ set_in_redis(:last_failure, 1.day.ago.to_f)
+ set_in_redis(:failure_count, 999)
expect { |b| circuit_breaker.perform(&b) }
- .to raise_error(Gitlab::Git::Storage::CircuitOpen)
+ .to raise_error do |exception|
+ expect(exception).to be_kind_of(Gitlab::Git::Storage::CircuitOpen)
+ expect(exception.retry_after).to eq(1800)
+ end
+ end
+
+ it 'raises the correct exception when backing off' do
+ Timecop.freeze do
+ set_in_redis(:last_failure, 1.second.ago.to_f)
+ set_in_redis(:failure_count, 90)
+
+ expect { |b| circuit_breaker.perform(&b) }
+ .to raise_error do |exception|
+ expect(exception).to be_kind_of(Gitlab::Git::Storage::Failing)
+ expect(exception.retry_after).to eq(30)
+ end
+ end
end
it 'yields the block' do
@@ -122,6 +153,7 @@ describe Gitlab::Git::Storage::CircuitBreaker, clean_gitlab_redis_shared_state:
it 'checks if the storage is available' do
expect(circuit_breaker).to receive(:check_storage_accessible!)
+ .and_call_original
circuit_breaker.perform { 'hello world' }
end
@@ -137,201 +169,124 @@ describe Gitlab::Git::Storage::CircuitBreaker, clean_gitlab_redis_shared_state:
.to raise_error(Rugged::OSError)
end
- context 'with the feature disabled' do
- it 'returns the block without checking accessibility' do
- stub_feature_flags(git_storage_circuit_breaker: false)
-
- expect(circuit_breaker).not_to receive(:circuit_broken?)
+ it 'tracks that the storage was accessible' do
+ set_in_redis(:failure_count, 10)
+ set_in_redis(:last_failure, Time.now.to_f)
- result = circuit_breaker.perform { 'hello' }
+ circuit_breaker.perform { '' }
- expect(result).to eq('hello')
- end
+ expect(value_from_redis(:failure_count).to_i).to eq(0)
+ expect(value_from_redis(:last_failure)).to be_empty
+ expect(circuit_breaker.failure_count).to eq(0)
+ expect(circuit_breaker.last_failure).to be_nil
end
- end
- describe '#circuit_broken?' do
- it 'is working when there is no last failure' do
- set_in_redis(:last_failure, nil)
- set_in_redis(:failure_count, 0)
+ it 'only performs the accessibility check once' do
+ expect(Gitlab::Git::Storage::ForkedStorageCheck)
+ .to receive(:storage_available?).once.and_call_original
- expect(circuit_breaker.circuit_broken?).to be_falsey
+ 2.times { circuit_breaker.perform { '' } }
end
- it 'is broken when there was a recent failure' do
- Timecop.freeze do
- set_in_redis(:last_failure, 1.second.ago.to_f)
- set_in_redis(:failure_count, 1)
+ it 'calls the check with the correct arguments' do
+ stub_application_setting(circuitbreaker_storage_timeout: 30,
+ circuitbreaker_access_retries: 3)
- expect(circuit_breaker.circuit_broken?).to be_truthy
- end
- end
+ expect(Gitlab::Git::Storage::ForkedStorageCheck)
+ .to receive(:storage_available?).with(TestEnv.repos_path, 30, 3)
+ .and_call_original
- it 'is broken when there are too many failures' do
- set_in_redis(:last_failure, 1.day.ago.to_f)
- set_in_redis(:failure_count, 200)
-
- expect(circuit_breaker.circuit_broken?).to be_truthy
+ circuit_breaker.perform { '' }
end
- context 'the `failure_wait_time` is set to 0' do
+ context 'with the feature disabled' do
before do
- stub_application_setting(circuitbreaker_failure_wait_time: 0)
- end
-
- it 'is working even when there is a recent failure' do
- Timecop.freeze do
- set_in_redis(:last_failure, 0.seconds.ago.to_f)
- set_in_redis(:failure_count, 1)
-
- expect(circuit_breaker.circuit_broken?).to be_falsey
- end
+ stub_feature_flags(git_storage_circuit_breaker: false)
end
- end
- end
- describe "storage_available?" do
- context 'the storage is available' do
- it 'tracks that the storage was accessible an raises the error' do
- expect(circuit_breaker).to receive(:track_storage_accessible)
-
- circuit_breaker.storage_available?
- end
+ it 'returns the block without checking accessibility' do
+ expect(circuit_breaker).not_to receive(:check_storage_accessible!)
- it 'only performs the check once' do
- expect(Gitlab::Git::Storage::ForkedStorageCheck)
- .to receive(:storage_available?).once.and_call_original
+ result = circuit_breaker.perform { 'hello' }
- 2.times { circuit_breaker.storage_available? }
+ expect(result).to eq('hello')
end
- end
-
- context 'storage is not available' do
- let(:storage_name) { 'broken' }
-
- it 'tracks that the storage was inaccessible' do
- expect(circuit_breaker).to receive(:track_storage_inaccessible)
- circuit_breaker.storage_available?
- end
- end
- end
+ it 'allows enabling the feature using an ENV var' do
+ stub_env('GIT_STORAGE_CIRCUIT_BREAKER', 'true')
+ expect(circuit_breaker).to receive(:check_storage_accessible!)
- describe '#check_storage_accessible!' do
- it 'raises an exception with retry time when the circuit is open' do
- allow(circuit_breaker).to receive(:circuit_broken?).and_return(true)
+ result = circuit_breaker.perform { 'hello' }
- expect { circuit_breaker.check_storage_accessible! }
- .to raise_error do |exception|
- expect(exception).to be_kind_of(Gitlab::Git::Storage::CircuitOpen)
- expect(exception.retry_after).to eq(30)
+ expect(result).to eq('hello')
end
end
context 'the storage is not available' do
let(:storage_name) { 'broken' }
- it 'raises an error' do
+ it 'raises the correct exception' do
expect(circuit_breaker).to receive(:track_storage_inaccessible)
- expect { circuit_breaker.check_storage_accessible! }
+ expect { circuit_breaker.perform { '' } }
.to raise_error do |exception|
expect(exception).to be_kind_of(Gitlab::Git::Storage::Inaccessible)
expect(exception.retry_after).to eq(30)
end
end
- end
- end
-
- describe '#track_storage_inaccessible' do
- around do |example|
- Timecop.freeze { example.run }
- end
-
- it 'records the failure time in redis' do
- circuit_breaker.track_storage_inaccessible
-
- failure_time = value_from_redis(:last_failure)
- expect(Time.at(failure_time.to_i)).to be_within(1.second).of(Time.now)
- end
-
- it 'sets the failure time on the breaker without reloading' do
- circuit_breaker.track_storage_inaccessible
-
- expect(circuit_breaker).not_to receive(:get_failure_info)
- expect(circuit_breaker.last_failure).to eq(Time.now)
- end
-
- it 'increments the failure count in redis' do
- set_in_redis(:failure_count, 10)
-
- circuit_breaker.track_storage_inaccessible
-
- expect(value_from_redis(:failure_count).to_i).to be(11)
- end
-
- it 'increments the failure count on the breaker without reloading' do
- set_in_redis(:failure_count, 10)
-
- circuit_breaker.track_storage_inaccessible
+ it 'tracks that the storage was inaccessible' do
+ Timecop.freeze do
+ expect { circuit_breaker.perform { '' } }.to raise_error(Gitlab::Git::Storage::Inaccessible)
- expect(circuit_breaker).not_to receive(:get_failure_info)
- expect(circuit_breaker.failure_count).to eq(11)
+ expect(value_from_redis(:failure_count).to_i).to eq(1)
+ expect(value_from_redis(:last_failure)).not_to be_empty
+ expect(circuit_breaker.failure_count).to eq(1)
+ expect(circuit_breaker.last_failure).to be_within(1.second).of(Time.now)
+ end
+ end
end
end
- describe '#track_storage_accessible' do
- it 'sets the failure count to zero in redis' do
- set_in_redis(:failure_count, 10)
-
- circuit_breaker.track_storage_accessible
-
- expect(value_from_redis(:failure_count).to_i).to be(0)
- end
-
- it 'sets the failure count to zero on the breaker without reloading' do
- set_in_redis(:failure_count, 10)
-
- circuit_breaker.track_storage_accessible
+ describe '#circuit_broken?' do
+ it 'is working when there is no last failure' do
+ set_in_redis(:last_failure, nil)
+ set_in_redis(:failure_count, 0)
- expect(circuit_breaker).not_to receive(:get_failure_info)
- expect(circuit_breaker.failure_count).to eq(0)
+ expect(circuit_breaker.circuit_broken?).to be_falsey
end
- it 'removes the last failure time from redis' do
- set_in_redis(:last_failure, Time.now.to_i)
-
- circuit_breaker.track_storage_accessible
+ it 'is broken when there are too many failures' do
+ set_in_redis(:last_failure, 1.day.ago.to_f)
+ set_in_redis(:failure_count, 200)
- expect(circuit_breaker).not_to receive(:get_failure_info)
- expect(circuit_breaker.last_failure).to be_nil
+ expect(circuit_breaker.circuit_broken?).to be_truthy
end
+ end
- it 'removes the last failure time from the breaker without reloading' do
- set_in_redis(:last_failure, Time.now.to_i)
-
- circuit_breaker.track_storage_accessible
+ describe '#backing_off?' do
+ it 'is true when there was a recent failure' do
+ Timecop.freeze do
+ set_in_redis(:last_failure, 1.second.ago.to_f)
+ set_in_redis(:failure_count, 90)
- expect(value_from_redis(:last_failure)).to be_empty
+ expect(circuit_breaker.backing_off?).to be_truthy
+ end
end
- it 'wont connect to redis when there are no failures' do
- expect(Gitlab::Git::Storage.redis).to receive(:with).once
- .and_call_original
- expect(circuit_breaker).to receive(:track_storage_accessible)
- .and_call_original
-
- circuit_breaker.track_storage_accessible
- end
- end
+ context 'the `failure_wait_time` is set to 0' do
+ before do
+ stub_application_setting(circuitbreaker_failure_wait_time: 0)
+ end
- describe '#no_failures?' do
- it 'is false when a failure was tracked' do
- set_in_redis(:last_failure, Time.now.to_i)
- set_in_redis(:failure_count, 1)
+ it 'is working even when there are failures' do
+ Timecop.freeze do
+ set_in_redis(:last_failure, 0.seconds.ago.to_f)
+ set_in_redis(:failure_count, 90)
- expect(circuit_breaker.no_failures?).to be_falsey
+ expect(circuit_breaker.backing_off?).to be_falsey
+ end
+ end
end
end
@@ -351,10 +306,4 @@ describe Gitlab::Git::Storage::CircuitBreaker, clean_gitlab_redis_shared_state:
expect(circuit_breaker.failure_count).to eq(7)
end
end
-
- describe '#cache_key' do
- it 'includes storage and host' do
- expect(circuit_breaker.cache_key).to eq(cache_key)
- end
- end
end
diff --git a/spec/lib/gitlab/git/storage/forked_storage_check_spec.rb b/spec/lib/gitlab/git/storage/forked_storage_check_spec.rb
index c708b15853a..39a5d020bb4 100644
--- a/spec/lib/gitlab/git/storage/forked_storage_check_spec.rb
+++ b/spec/lib/gitlab/git/storage/forked_storage_check_spec.rb
@@ -33,6 +33,21 @@ describe Gitlab::Git::Storage::ForkedStorageCheck, broken_storage: true, skip_da
expect(runtime).to be < 1.0
end
+ it 'will try the specified amount of times before failing' do
+ allow(described_class).to receive(:check_filesystem_in_process) do
+ Process.spawn("sleep 10")
+ end
+
+ expect(Process).to receive(:spawn).with('sleep 10').twice
+ .and_call_original
+
+ runtime = Benchmark.realtime do
+ described_class.storage_available?(existing_path, 0.5, 2)
+ end
+
+ expect(runtime).to be < 1.0
+ end
+
describe 'when using paths with spaces' do
let(:test_dir) { Rails.root.join('tmp', 'tests', 'storage_check') }
let(:path_with_spaces) { File.join(test_dir, 'path with spaces') }
diff --git a/spec/lib/gitlab/git/storage/null_circuit_breaker_spec.rb b/spec/lib/gitlab/git/storage/null_circuit_breaker_spec.rb
index 7ee6d2f3709..5db37f55e03 100644
--- a/spec/lib/gitlab/git/storage/null_circuit_breaker_spec.rb
+++ b/spec/lib/gitlab/git/storage/null_circuit_breaker_spec.rb
@@ -65,17 +65,6 @@ describe Gitlab::Git::Storage::NullCircuitBreaker do
ours = described_class.public_instance_methods
theirs = Gitlab::Git::Storage::CircuitBreaker.public_instance_methods
- # These methods are not part of the public API, but are public to allow the
- # CircuitBreaker specs to operate. They should be made private over time.
- exceptions = %i[
- cache_key
- check_storage_accessible!
- no_failures?
- storage_available?
- track_storage_accessible
- track_storage_inaccessible
- ]
-
- expect(theirs - ours).to contain_exactly(*exceptions)
+ expect(theirs - ours).to be_empty
end
end
diff --git a/spec/lib/gitlab/git/user_spec.rb b/spec/lib/gitlab/git/user_spec.rb
index 31d5f59a562..eb8db819045 100644
--- a/spec/lib/gitlab/git/user_spec.rb
+++ b/spec/lib/gitlab/git/user_spec.rb
@@ -5,14 +5,20 @@ describe Gitlab::Git::User do
let(:name) { 'Jane Doe' }
let(:email) { 'janedoe@example.com' }
let(:gl_id) { 'user-123' }
+ let(:user) do
+ described_class.new(username, name, email, gl_id)
+ end
subject { described_class.new(username, name, email, gl_id) }
describe '.from_gitaly' do
- let(:gitaly_user) { Gitaly::User.new(name: name, email: email, gl_id: gl_id) }
+ let(:gitaly_user) do
+ Gitaly::User.new(gl_username: username, name: name, email: email, gl_id: gl_id)
+ end
+
subject { described_class.from_gitaly(gitaly_user) }
- it { expect(subject).to eq(described_class.new('', name, email, gl_id)) }
+ it { expect(subject).to eq(user) }
end
describe '.from_gitlab' do
@@ -35,4 +41,16 @@ describe Gitlab::Git::User do
it { expect(subject).not_to eq_other(username, name, email + 'x', gl_id) }
it { expect(subject).not_to eq_other(username, name, email, gl_id + 'x') }
end
+
+ describe '#to_gitaly' do
+ subject { user.to_gitaly }
+
+ it 'creates a Gitaly::User with the correct data' do
+ expect(subject).to be_a(Gitaly::User)
+ expect(subject.gl_username).to eq(username)
+ expect(subject.name).to eq(name)
+ expect(subject.email).to eq(email)
+ expect(subject.gl_id).to eq(gl_id)
+ end
+ end
end
diff --git a/spec/lib/gitlab/gitaly_client/operation_service_spec.rb b/spec/lib/gitlab/gitaly_client/operation_service_spec.rb
index 7bd6a7fa842..e144e28b5d8 100644
--- a/spec/lib/gitlab/gitaly_client/operation_service_spec.rb
+++ b/spec/lib/gitlab/gitaly_client/operation_service_spec.rb
@@ -5,7 +5,7 @@ describe Gitlab::GitalyClient::OperationService do
let(:repository) { project.repository.raw }
let(:client) { described_class.new(repository) }
let(:user) { create(:user) }
- let(:gitaly_user) { Gitlab::GitalyClient::Util.gitaly_user(user) }
+ let(:gitaly_user) { Gitlab::Git::User.from_gitlab(user).to_gitaly }
describe '#user_create_branch' do
let(:branch_name) { 'new' }
diff --git a/spec/lib/gitlab/gitaly_client/util_spec.rb b/spec/lib/gitlab/gitaly_client/util_spec.rb
index c0c29552494..d1e0136f8c1 100644
--- a/spec/lib/gitlab/gitaly_client/util_spec.rb
+++ b/spec/lib/gitlab/gitaly_client/util_spec.rb
@@ -26,18 +26,4 @@ describe Gitlab::GitalyClient::Util do
expect(subject.git_alternate_object_directories).to eq(git_alternate_object_directory)
end
end
-
- describe '.gitaly_user' do
- let(:user) { create(:user) }
- let(:gl_id) { Gitlab::GlId.gl_id(user) }
-
- subject { described_class.gitaly_user(user) }
-
- it 'creates a Gitaly::User from a GitLab user' do
- expect(subject).to be_a(Gitaly::User)
- expect(subject.name).to eq(user.name)
- expect(subject.email).to eq(user.email)
- expect(subject.gl_id).to eq(gl_id)
- end
- end
end
diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml
index 29baa70d5ae..6c6b9154a0a 100644
--- a/spec/lib/gitlab/import_export/all_models.yml
+++ b/spec/lib/gitlab/import_export/all_models.yml
@@ -195,6 +195,7 @@ project:
- mattermost_slash_commands_service
- slack_slash_commands_service
- irker_service
+- packagist_service
- pivotaltracker_service
- prometheus_service
- hipchat_service
@@ -286,3 +287,6 @@ timelogs:
- user
push_event_payload:
- event
+issue_assignees:
+- issue
+- assignee \ No newline at end of file
diff --git a/spec/lib/gitlab/import_export/project.json b/spec/lib/gitlab/import_export/project.json
index 1115fb218d6..9a68bbb379c 100644
--- a/spec/lib/gitlab/import_export/project.json
+++ b/spec/lib/gitlab/import_export/project.json
@@ -43,7 +43,7 @@
"issues": [
{
"id": 40,
- "title": "Voluptatem amet doloribus deleniti eos maxime repudiandae molestias.",
+ "title": "Voluptatem",
"assignee_id": 1,
"author_id": 22,
"project_id": 5,
@@ -60,6 +60,12 @@
"due_date": null,
"moved_to_id": null,
"test_ee_field": "test",
+ "issue_assignees": [
+ {
+ "user_id": 1,
+ "issue_id": 1
+ }
+ ],
"milestone": {
"id": 1,
"title": "test milestone",
diff --git a/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb b/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb
index 4301eee17dc..76b01b6a1ec 100644
--- a/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb
+++ b/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb
@@ -63,6 +63,10 @@ describe Gitlab::ImportExport::ProjectTreeRestorer do
expect(issue.reload.updated_at.to_s).to eq('2016-06-14 15:02:47 UTC')
end
+ it 'has issue assignees' do
+ expect(Issue.where(title: 'Voluptatem').first.issue_assignees).not_to be_empty
+ end
+
it 'contains the merge access levels on a protected branch' do
expect(ProtectedBranch.first.merge_access_levels).not_to be_empty
end
diff --git a/spec/lib/gitlab/import_export/project_tree_saver_spec.rb b/spec/lib/gitlab/import_export/project_tree_saver_spec.rb
index d9b86e1bf34..8da768ebd07 100644
--- a/spec/lib/gitlab/import_export/project_tree_saver_spec.rb
+++ b/spec/lib/gitlab/import_export/project_tree_saver_spec.rb
@@ -77,6 +77,10 @@ describe Gitlab::ImportExport::ProjectTreeSaver do
expect(saved_project_json['issues'].first['notes']).not_to be_empty
end
+ it 'has issue assignees' do
+ expect(saved_project_json['issues'].first['issue_assignees']).not_to be_empty
+ end
+
it 'has author on issue comments' do
expect(saved_project_json['issues'].first['notes'].first['author']).not_to be_empty
end
diff --git a/spec/lib/gitlab/import_export/safe_model_attributes.yml b/spec/lib/gitlab/import_export/safe_model_attributes.yml
index 121c0ed04ed..89d30407077 100644
--- a/spec/lib/gitlab/import_export/safe_model_attributes.yml
+++ b/spec/lib/gitlab/import_export/safe_model_attributes.yml
@@ -506,3 +506,6 @@ ProjectAutoDevops:
- project_id
- created_at
- updated_at
+IssueAssignee:
+- user_id
+- issue_id \ No newline at end of file
diff --git a/spec/lib/gitlab/ldap/authentication_spec.rb b/spec/lib/gitlab/ldap/authentication_spec.rb
index 01b6282af0c..9d57a46c12b 100644
--- a/spec/lib/gitlab/ldap/authentication_spec.rb
+++ b/spec/lib/gitlab/ldap/authentication_spec.rb
@@ -1,8 +1,8 @@
require 'spec_helper'
describe Gitlab::LDAP::Authentication do
- let(:user) { create(:omniauth_user, extern_uid: dn) }
- let(:dn) { 'uid=john,ou=people,dc=example,dc=com' }
+ let(:dn) { 'uid=John Smith, ou=People, dc=example, dc=com' }
+ let(:user) { create(:omniauth_user, extern_uid: Gitlab::LDAP::Person.normalize_dn(dn)) }
let(:login) { 'john' }
let(:password) { 'password' }
diff --git a/spec/lib/gitlab/ldap/user_spec.rb b/spec/lib/gitlab/ldap/user_spec.rb
index 9a4705d1cee..260df6e4dae 100644
--- a/spec/lib/gitlab/ldap/user_spec.rb
+++ b/spec/lib/gitlab/ldap/user_spec.rb
@@ -44,23 +44,25 @@ describe Gitlab::LDAP::User do
end
describe '.find_by_uid_and_provider' do
+ let(:dn) { 'CN=John Åström, CN=Users, DC=Example, DC=com' }
+
it 'retrieves the correct user' do
special_info = {
name: 'John Åström',
email: 'john@example.com',
nickname: 'jastrom'
}
- special_hash = OmniAuth::AuthHash.new(uid: 'CN=John Åström,CN=Users,DC=Example,DC=com', provider: 'ldapmain', info: special_info)
+ special_hash = OmniAuth::AuthHash.new(uid: dn, provider: 'ldapmain', info: special_info)
special_chars_user = described_class.new(special_hash)
user = special_chars_user.save
- expect(described_class.find_by_uid_and_provider(special_hash.uid, special_hash.provider)).to eq user
+ expect(described_class.find_by_uid_and_provider(dn, 'ldapmain')).to eq user
end
end
describe 'find or create' do
it "finds the user if already existing" do
- create(:omniauth_user, extern_uid: 'uid=John Smith,ou=People,dc=example,dc=com', provider: 'ldapmain')
+ create(:omniauth_user, extern_uid: 'uid=john smith,ou=people,dc=example,dc=com', provider: 'ldapmain')
expect { ldap_user.save }.not_to change { User.count }
end
diff --git a/spec/lib/gitlab/o_auth/user_spec.rb b/spec/lib/gitlab/o_auth/user_spec.rb
index db26e16e3b2..c7471a21fda 100644
--- a/spec/lib/gitlab/o_auth/user_spec.rb
+++ b/spec/lib/gitlab/o_auth/user_spec.rb
@@ -4,7 +4,7 @@ describe Gitlab::OAuth::User do
let(:oauth_user) { described_class.new(auth_hash) }
let(:gl_user) { oauth_user.gl_user }
let(:uid) { 'my-uid' }
- let(:dn) { 'uid=user1,ou=People,dc=example' }
+ let(:dn) { 'uid=user1,ou=people,dc=example' }
let(:provider) { 'my-provider' }
let(:auth_hash) { OmniAuth::AuthHash.new(uid: uid, provider: provider, info: info_hash) }
let(:info_hash) do
diff --git a/spec/lib/gitlab/saml/user_spec.rb b/spec/lib/gitlab/saml/user_spec.rb
index 1c23fb5f285..1765980e977 100644
--- a/spec/lib/gitlab/saml/user_spec.rb
+++ b/spec/lib/gitlab/saml/user_spec.rb
@@ -7,7 +7,7 @@ describe Gitlab::Saml::User do
let(:saml_user) { described_class.new(auth_hash) }
let(:gl_user) { saml_user.gl_user }
let(:uid) { 'my-uid' }
- let(:dn) { 'uid=user1,ou=People,dc=example' }
+ let(:dn) { 'uid=user1,ou=people,dc=example' }
let(:provider) { 'saml' }
let(:raw_info_attr) { { 'groups' => %w(Developers Freelancers Designers) } }
let(:auth_hash) { OmniAuth::AuthHash.new(uid: uid, provider: provider, info: info_hash, extra: { raw_info: OneLogin::RubySaml::Attributes.new(raw_info_attr) }) }
diff --git a/spec/models/application_setting_spec.rb b/spec/models/application_setting_spec.rb
index 30495fd4f5e..47b7150d36f 100644
--- a/spec/models/application_setting_spec.rb
+++ b/spec/models/application_setting_spec.rb
@@ -115,7 +115,8 @@ describe ApplicationSetting do
end
context 'circuitbreaker settings' do
- [:circuitbreaker_failure_count_threshold,
+ [:circuitbreaker_backoff_threshold,
+ :circuitbreaker_failure_count_threshold,
:circuitbreaker_failure_wait_time,
:circuitbreaker_failure_reset_time,
:circuitbreaker_storage_timeout].each do |field|
@@ -125,6 +126,16 @@ describe ApplicationSetting do
.is_greater_than_or_equal_to(0)
end
end
+
+ it 'requires the `backoff_threshold` to be lower than the `failure_count_threshold`' do
+ setting.circuitbreaker_failure_count_threshold = 10
+ setting.circuitbreaker_backoff_threshold = 15
+ failure_message = "The circuitbreaker backoff threshold should be lower "\
+ "than the failure count threshold"
+
+ expect(setting).not_to be_valid
+ expect(setting.errors[:circuitbreaker_backoff_threshold]).to include(failure_message)
+ end
end
context 'repository storages' do
diff --git a/spec/models/ci/artifact_blob_spec.rb b/spec/models/ci/artifact_blob_spec.rb
index d5ba088af53..4e72d9d748e 100644
--- a/spec/models/ci/artifact_blob_spec.rb
+++ b/spec/models/ci/artifact_blob_spec.rb
@@ -56,15 +56,14 @@ describe Ci::ArtifactBlob do
end
context 'txt extensions' do
- let(:entry) { build.artifacts_metadata_entry('other_artifacts_0.1.2/doc_sample.txt') }
+ let(:path) { 'other_artifacts_0.1.2/doc_sample.txt' }
+ let(:entry) { build.artifacts_metadata_entry(path) }
it 'returns a URL' do
url = subject.external_url(build.project, build)
expect(url).not_to be_nil
- expect(url).to start_with("http")
- expect(url).to match Gitlab.config.pages.host
- expect(url).to end_with(entry.path)
+ expect(url).to eq("http://#{project.namespace.path}.#{Gitlab.config.pages.host}/-/#{project.path}/-/jobs/#{build.id}/artifacts/#{path}")
end
end
end
diff --git a/spec/models/concerns/subscribable_spec.rb b/spec/models/concerns/subscribable_spec.rb
index 28ff8158e0e..45dfb136aea 100644
--- a/spec/models/concerns/subscribable_spec.rb
+++ b/spec/models/concerns/subscribable_spec.rb
@@ -6,6 +6,12 @@ describe Subscribable, 'Subscribable' do
let(:user_1) { create(:user) }
describe '#subscribed?' do
+ context 'without user' do
+ it 'returns false' do
+ expect(resource.subscribed?(nil, project)).to be_falsey
+ end
+ end
+
context 'without project' do
it 'returns false when no subscription exists' do
expect(resource.subscribed?(user_1)).to be_falsey
diff --git a/spec/models/email_spec.rb b/spec/models/email_spec.rb
index b32dd31ae6d..47eb0717c0c 100644
--- a/spec/models/email_spec.rb
+++ b/spec/models/email_spec.rb
@@ -40,4 +40,12 @@ describe Email do
expect(user.emails.confirmed.count).to eq 1
end
end
+
+ describe 'delegation' do
+ let(:user) { create(:user) }
+
+ it 'delegates to :user' do
+ expect(build(:email, user: user).username).to eq user.username
+ end
+ end
end
diff --git a/spec/models/environment_spec.rb b/spec/models/environment_spec.rb
index 25e5d155894..e1be23541e8 100644
--- a/spec/models/environment_spec.rb
+++ b/spec/models/environment_spec.rb
@@ -575,6 +575,16 @@ describe Environment do
end
end
+ describe '#ref_path' do
+ subject(:environment) do
+ create(:environment, name: 'staging / review-1')
+ end
+
+ it 'returns a path that uses the slug and does not have spaces' do
+ expect(environment.ref_path).to start_with('refs/environments/staging-review-1-')
+ end
+ end
+
describe '#external_url_for' do
let(:source_path) { 'source/file.html' }
let(:sha) { RepoHelpers.sample_commit.id }
diff --git a/spec/models/identity_spec.rb b/spec/models/identity_spec.rb
index 4ca6556d0f4..3ed048744de 100644
--- a/spec/models/identity_spec.rb
+++ b/spec/models/identity_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-RSpec.describe Identity do
+describe Identity do
describe 'relations' do
it { is_expected.to belong_to(:user) }
end
@@ -22,4 +22,16 @@ RSpec.describe Identity do
expect(other_identity.ldap?).to be_falsey
end
end
+
+ describe '.with_extern_uid' do
+ context 'LDAP identity' do
+ let!(:ldap_identity) { create(:identity, provider: 'ldapmain', extern_uid: 'uid=john smith,ou=people,dc=example,dc=com') }
+
+ it 'finds the identity when the DN is formatted differently' do
+ identity = described_class.with_extern_uid('ldapmain', 'uid=John Smith, ou=People, dc=example, dc=com').first
+
+ expect(identity).to eq(ldap_identity)
+ end
+ end
+ end
end
diff --git a/spec/models/instance_configuration_spec.rb b/spec/models/instance_configuration_spec.rb
new file mode 100644
index 00000000000..8548fff5c76
--- /dev/null
+++ b/spec/models/instance_configuration_spec.rb
@@ -0,0 +1,109 @@
+require 'spec_helper'
+
+RSpec.describe InstanceConfiguration do
+ context 'without cache' do
+ describe '#settings' do
+ describe '#ssh_algorithms_hashes' do
+ let(:md5) { '54:e0:f8:70:d6:4f:4c:b1:b3:02:44:77:cf:cd:0d:fc' }
+ let(:sha256) { '9327f0d15a48c4d9f6a3aee65a1825baf9a3412001c98169c5fd022ac27762fc' }
+
+ it 'does not return anything if file does not exist' do
+ stub_pub_file(exist: false)
+
+ expect(subject.settings[:ssh_algorithms_hashes]).to be_empty
+ end
+
+ it 'does not return anything if file is empty' do
+ stub_pub_file
+
+ allow(File).to receive(:read).and_return('')
+
+ expect(subject.settings[:ssh_algorithms_hashes]).to be_empty
+ end
+
+ it 'returns the md5 and sha256 if file valid and exists' do
+ stub_pub_file
+
+ result = subject.settings[:ssh_algorithms_hashes].select { |o| o[:md5] == md5 && o[:sha256] == sha256 }
+
+ expect(result.size).to eq(InstanceConfiguration::SSH_ALGORITHMS.size)
+ end
+
+ def stub_pub_file(exist: true)
+ path = 'spec/fixtures/ssh_host_example_key.pub'
+ path << 'random' unless exist
+ allow(subject).to receive(:ssh_algorithm_file).and_return(Rails.root.join(path))
+ end
+ end
+
+ describe '#host' do
+ it 'returns current instance host' do
+ allow(Settings.gitlab).to receive(:host).and_return('exampledomain')
+
+ expect(subject.settings[:host]).to eq(Settings.gitlab.host)
+ end
+ end
+
+ describe '#gitlab_pages' do
+ let(:gitlab_pages) { subject.settings[:gitlab_pages] }
+ it 'returns Settings.pages' do
+ gitlab_pages.delete(:ip_address)
+
+ expect(gitlab_pages).to eq(Settings.pages.symbolize_keys)
+ end
+
+ it 'returns the Gitlab\'s pages host ip address' do
+ expect(gitlab_pages.keys).to include(:ip_address)
+ end
+
+ it 'returns the ip address as nil if the domain is invalid' do
+ allow(Settings.pages).to receive(:host).and_return('exampledomain')
+
+ expect(gitlab_pages[:ip_address]).to eq nil
+ end
+
+ it 'returns the ip address of the domain' do
+ allow(Settings.pages).to receive(:host).and_return('localhost')
+
+ expect(gitlab_pages[:ip_address]).to eq('127.0.0.1').or eq('::1')
+ end
+ end
+
+ describe '#gitlab_ci' do
+ let(:gitlab_ci) { subject.settings[:gitlab_ci] }
+ it 'returns Settings.gitalb_ci' do
+ gitlab_ci.delete(:artifacts_max_size)
+
+ expect(gitlab_ci).to eq(Settings.gitlab_ci.symbolize_keys)
+ end
+
+ it 'returns the key artifacts_max_size' do
+ expect(gitlab_ci.keys).to include(:artifacts_max_size)
+ end
+ end
+ end
+ end
+
+ context 'with cache', :use_clean_rails_memory_store_caching do
+ it 'caches settings content' do
+ expect(Rails.cache.read(described_class::CACHE_KEY)).to be_nil
+
+ settings = subject.settings
+
+ expect(Rails.cache.read(described_class::CACHE_KEY)).to eq(settings)
+ end
+
+ describe 'cached settings' do
+ before do
+ subject.settings
+ end
+
+ it 'expires after EXPIRATION_TIME' do
+ allow(Time).to receive(:now).and_return(Time.now + described_class::EXPIRATION_TIME)
+ Rails.cache.cleanup
+
+ expect(Rails.cache.read(described_class::CACHE_KEY)).to eq(nil)
+ end
+ end
+ end
+end
diff --git a/spec/models/merge_request_diff_commit_spec.rb b/spec/models/merge_request_diff_commit_spec.rb
index 9d4a0ecf8c0..7709cf43200 100644
--- a/spec/models/merge_request_diff_commit_spec.rb
+++ b/spec/models/merge_request_diff_commit_spec.rb
@@ -2,14 +2,93 @@ require 'rails_helper'
describe MergeRequestDiffCommit do
let(:merge_request) { create(:merge_request) }
- subject { merge_request.commits.first }
+ let(:project) { merge_request.project }
describe '#to_hash' do
+ subject { merge_request.commits.first }
+
it 'returns the same results as Commit#to_hash, except for parent_ids' do
- commit_from_repo = merge_request.project.repository.commit(subject.sha)
+ commit_from_repo = project.repository.commit(subject.sha)
commit_from_repo_hash = commit_from_repo.to_hash.merge(parent_ids: [])
expect(subject.to_hash).to eq(commit_from_repo_hash)
end
end
+
+ describe '.create_bulk' do
+ let(:sha_attribute) { Gitlab::Database::ShaAttribute.new }
+ let(:merge_request_diff_id) { merge_request.merge_request_diff.id }
+ let(:commits) do
+ [
+ project.commit('5937ac0a7beb003549fc5fd26fc247adbce4a52e'),
+ project.commit('570e7b2abdd848b95f2f578043fc23bd6f6fd24d')
+ ]
+ end
+ let(:rows) do
+ [
+ {
+ "message": "Add submodule from gitlab.com\n\nSigned-off-by: Dmitriy Zaporozhets \u003cdmitriy.zaporozhets@gmail.com\u003e\n",
+ "authored_date": "2014-02-27T10:01:38.000+01:00".to_time,
+ "author_name": "Dmitriy Zaporozhets",
+ "author_email": "dmitriy.zaporozhets@gmail.com",
+ "committed_date": "2014-02-27T10:01:38.000+01:00".to_time,
+ "committer_name": "Dmitriy Zaporozhets",
+ "committer_email": "dmitriy.zaporozhets@gmail.com",
+ "merge_request_diff_id": merge_request_diff_id,
+ "relative_order": 0,
+ "sha": sha_attribute.type_cast_for_database('5937ac0a7beb003549fc5fd26fc247adbce4a52e')
+ },
+ {
+ "message": "Change some files\n\nSigned-off-by: Dmitriy Zaporozhets \u003cdmitriy.zaporozhets@gmail.com\u003e\n",
+ "authored_date": "2014-02-27T09:57:31.000+01:00".to_time,
+ "author_name": "Dmitriy Zaporozhets",
+ "author_email": "dmitriy.zaporozhets@gmail.com",
+ "committed_date": "2014-02-27T09:57:31.000+01:00".to_time,
+ "committer_name": "Dmitriy Zaporozhets",
+ "committer_email": "dmitriy.zaporozhets@gmail.com",
+ "merge_request_diff_id": merge_request_diff_id,
+ "relative_order": 1,
+ "sha": sha_attribute.type_cast_for_database('570e7b2abdd848b95f2f578043fc23bd6f6fd24d')
+ }
+ ]
+ end
+
+ subject { described_class.create_bulk(merge_request_diff_id, commits) }
+
+ it 'inserts the commits into the database en masse' do
+ expect(Gitlab::Database).to receive(:bulk_insert)
+ .with(described_class.table_name, rows)
+
+ subject
+ end
+
+ context 'with dates larger than the DB limit' do
+ let(:commits) do
+ # This commit's date is "Sun Aug 17 07:12:55 292278994 +0000"
+ [project.commit('ba3343bc4fa403a8dfbfcab7fc1a8c29ee34bd69')]
+ end
+ let(:timestamp) { Time.at((1 << 31) - 1) }
+ let(:rows) do
+ [{
+ "message": "Weird commit date\n",
+ "authored_date": timestamp,
+ "author_name": "Alejandro Rodríguez",
+ "author_email": "alejorro70@gmail.com",
+ "committed_date": timestamp,
+ "committer_name": "Alejandro Rodríguez",
+ "committer_email": "alejorro70@gmail.com",
+ "merge_request_diff_id": merge_request_diff_id,
+ "relative_order": 0,
+ "sha": sha_attribute.type_cast_for_database('ba3343bc4fa403a8dfbfcab7fc1a8c29ee34bd69')
+ }]
+ end
+
+ it 'uses a sanitized date' do
+ expect(Gitlab::Database).to receive(:bulk_insert)
+ .with(described_class.table_name, rows)
+
+ subject
+ end
+ end
+ end
end
diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb
index 73e038b61ed..476a2697605 100644
--- a/spec/models/merge_request_spec.rb
+++ b/spec/models/merge_request_spec.rb
@@ -86,7 +86,7 @@ describe MergeRequest do
context 'when the target branch does not exist' do
before do
- project.repository.raw_repository.delete_branch(subject.target_branch)
+ project.repository.rm_branch(subject.author, subject.target_branch)
end
it 'returns nil' do
@@ -1388,7 +1388,7 @@ describe MergeRequest do
context 'when the target branch does not exist' do
before do
- subject.project.repository.raw_repository.delete_branch(subject.target_branch)
+ subject.project.repository.rm_branch(subject.author, subject.target_branch)
end
it 'returns nil' do
@@ -1460,6 +1460,12 @@ describe MergeRequest do
end
describe '#merge_ongoing?' do
+ it 'returns true when the merge request is locked' do
+ merge_request = build_stubbed(:merge_request, state: :locked)
+
+ expect(merge_request.merge_ongoing?).to be(true)
+ end
+
it 'returns true when merge_id, MR is not merged and it has no running job' do
merge_request = build_stubbed(:merge_request, state: :open, merge_jid: 'foo')
allow(Gitlab::SidekiqStatus).to receive(:running?).with('foo') { true }
diff --git a/spec/models/project_services/jira_service_spec.rb b/spec/models/project_services/jira_service_spec.rb
index 63bf131cfc5..ad22fb2a386 100644
--- a/spec/models/project_services/jira_service_spec.rb
+++ b/spec/models/project_services/jira_service_spec.rb
@@ -24,6 +24,8 @@ describe JiraService do
end
it { is_expected.not_to validate_presence_of(:url) }
+ it { is_expected.not_to validate_presence_of(:username) }
+ it { is_expected.not_to validate_presence_of(:password) }
end
context 'validating urls' do
@@ -54,6 +56,18 @@ describe JiraService do
expect(service).not_to be_valid
end
+ it 'is not valid when username is missing' do
+ service.username = nil
+
+ expect(service).not_to be_valid
+ end
+
+ it 'is not valid when password is missing' do
+ service.password = nil
+
+ expect(service).not_to be_valid
+ end
+
it 'is valid when api url is a valid url' do
service.api_url = 'http://jira.test.com/api'
diff --git a/spec/models/project_services/kubernetes_service_spec.rb b/spec/models/project_services/kubernetes_service_spec.rb
index 2298dcab55f..00de536a18b 100644
--- a/spec/models/project_services/kubernetes_service_spec.rb
+++ b/spec/models/project_services/kubernetes_service_spec.rb
@@ -99,45 +99,34 @@ describe KubernetesService, :use_clean_rails_memory_store_caching do
describe '#actual_namespace' do
subject { service.actual_namespace }
- it "returns the default namespace" do
- is_expected.to eq(service.send(:default_namespace))
- end
-
- context 'when namespace is specified' do
- before do
- service.namespace = 'my-namespace'
+ shared_examples 'a correctly formatted namespace' do
+ it 'returns a valid Kubernetes namespace name' do
+ expect(subject).to match(Gitlab::Regex.kubernetes_namespace_regex)
+ expect(subject).to eq(expected_namespace)
end
+ end
- it "returns the user-namespace" do
- is_expected.to eq('my-namespace')
- end
+ it_behaves_like 'a correctly formatted namespace' do
+ let(:expected_namespace) { service.send(:default_namespace) }
end
- context 'when service is not assigned to project' do
+ context 'when the project path contains forbidden characters' do
before do
- service.project = nil
+ project.path = '-a_Strange.Path--forSure'
end
- it "does not return namespace" do
- is_expected.to be_nil
+ it_behaves_like 'a correctly formatted namespace' do
+ let(:expected_namespace) { "a-strange-path--forsure-#{project.id}" }
end
end
- end
-
- describe '#actual_namespace' do
- subject { service.actual_namespace }
-
- it "returns the default namespace" do
- is_expected.to eq(service.send(:default_namespace))
- end
context 'when namespace is specified' do
before do
service.namespace = 'my-namespace'
end
- it "returns the user-namespace" do
- is_expected.to eq('my-namespace')
+ it_behaves_like 'a correctly formatted namespace' do
+ let(:expected_namespace) { 'my-namespace' }
end
end
@@ -146,7 +135,7 @@ describe KubernetesService, :use_clean_rails_memory_store_caching do
service.project = nil
end
- it "does not return namespace" do
+ it 'does not return namespace' do
is_expected.to be_nil
end
end
diff --git a/spec/models/project_services/packagist_service_spec.rb b/spec/models/project_services/packagist_service_spec.rb
new file mode 100644
index 00000000000..6acee311700
--- /dev/null
+++ b/spec/models/project_services/packagist_service_spec.rb
@@ -0,0 +1,46 @@
+require 'spec_helper'
+
+describe PackagistService do
+ describe "Associations" do
+ it { is_expected.to belong_to :project }
+ it { is_expected.to have_one :service_hook }
+ end
+
+ let(:project) { create(:project) }
+
+ let(:packagist_server) { 'https://packagist.example.com' }
+ let(:packagist_username) { 'theUser' }
+ let(:packagist_token) { 'verySecret' }
+ let(:packagist_hook_url) do
+ "#{packagist_server}/api/update-package?username=#{packagist_username}&apiToken=#{packagist_token}"
+ end
+
+ let(:packagist_params) do
+ {
+ active: true,
+ project: project,
+ properties: {
+ username: packagist_username,
+ token: packagist_token,
+ server: packagist_server
+ }
+ }
+ end
+
+ describe '#execute' do
+ let(:user) { create(:user) }
+ let(:project) { create(:project, :repository) }
+ let(:push_sample_data) { Gitlab::DataBuilder::Push.build_sample(project, user) }
+ let(:packagist_service) { described_class.create(packagist_params) }
+
+ before do
+ stub_request(:post, packagist_hook_url)
+ end
+
+ it 'calls Packagist API' do
+ packagist_service.execute(push_sample_data)
+
+ expect(a_request(:post, packagist_hook_url)).to have_been_made.once
+ end
+ end
+end
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index 74eba7e33f6..ed6e42d476e 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -24,6 +24,7 @@ describe Project do
it { is_expected.to have_one(:slack_service) }
it { is_expected.to have_one(:microsoft_teams_service) }
it { is_expected.to have_one(:mattermost_service) }
+ it { is_expected.to have_one(:packagist_service) }
it { is_expected.to have_one(:pushover_service) }
it { is_expected.to have_one(:asana_service) }
it { is_expected.to have_many(:boards) }
@@ -2452,6 +2453,7 @@ describe Project do
context 'legacy storage' do
let(:project) { create(:project, :repository) }
let(:gitlab_shell) { Gitlab::Shell.new }
+ let(:project_storage) { project.send(:storage) }
before do
allow(project).to receive(:gitlab_shell).and_return(gitlab_shell)
@@ -2493,7 +2495,7 @@ describe Project do
describe '#hashed_storage?' do
it 'returns false' do
- expect(project.hashed_storage?).to be_falsey
+ expect(project.hashed_storage?(:repository)).to be_falsey
end
end
@@ -2546,6 +2548,30 @@ describe Project do
it { expect { subject }.to raise_error(StandardError) }
end
+
+ context 'gitlab pages' do
+ before do
+ expect(project_storage).to receive(:rename_repo) { true }
+ end
+
+ it 'moves pages folder to new location' do
+ expect_any_instance_of(Gitlab::PagesTransfer).to receive(:rename_project)
+
+ project.rename_repo
+ end
+ end
+
+ context 'attachments' do
+ before do
+ expect(project_storage).to receive(:rename_repo) { true }
+ end
+
+ it 'moves uploads folder to new location' do
+ expect_any_instance_of(Gitlab::UploadsTransfer).to receive(:rename_project)
+
+ project.rename_repo
+ end
+ end
end
describe '#pages_path' do
@@ -2605,8 +2631,14 @@ describe Project do
end
describe '#hashed_storage?' do
- it 'returns true' do
- expect(project.hashed_storage?).to be_truthy
+ it 'returns true if rolled out' do
+ expect(project.hashed_storage?(:attachments)).to be_truthy
+ end
+
+ it 'returns false when not rolled out yet' do
+ project.storage_version = 1
+
+ expect(project.hashed_storage?(:attachments)).to be_falsey
end
end
@@ -2649,10 +2681,6 @@ describe Project do
.to receive(:execute_hooks_for)
.with(project, :rename)
- expect_any_instance_of(Gitlab::UploadsTransfer)
- .to receive(:rename_project)
- .with('foo', project.path, project.namespace.full_path)
-
expect(project).to receive(:expire_caches_before_rename)
expect(project).to receive(:expires_full_path_cache)
@@ -2673,6 +2701,32 @@ describe Project do
it { expect { subject }.to raise_error(StandardError) }
end
+
+ context 'gitlab pages' do
+ it 'moves pages folder to new location' do
+ expect_any_instance_of(Gitlab::PagesTransfer).to receive(:rename_project)
+
+ project.rename_repo
+ end
+ end
+
+ context 'attachments' do
+ it 'keeps uploads folder location unchanged' do
+ expect_any_instance_of(Gitlab::UploadsTransfer).not_to receive(:rename_project)
+
+ project.rename_repo
+ end
+
+ context 'when not rolled out' do
+ let(:project) { create(:project, :repository, storage_version: 1) }
+
+ it 'moves pages folder to new location' do
+ expect_any_instance_of(Gitlab::UploadsTransfer).to receive(:rename_project)
+
+ project.rename_repo
+ end
+ end
+ end
end
describe '#pages_path' do
diff --git a/spec/models/project_wiki_spec.rb b/spec/models/project_wiki_spec.rb
index f10d9383ae2..52a2b4b2850 100644
--- a/spec/models/project_wiki_spec.rb
+++ b/spec/models/project_wiki_spec.rb
@@ -117,31 +117,41 @@ describe ProjectWiki do
end
describe "#find_page" do
- before do
- create_page("index page", "This is an awesome Gollum Wiki")
- end
+ shared_examples 'finding a wiki page' do
+ before do
+ create_page("index page", "This is an awesome Gollum Wiki")
+ end
- after do
- destroy_page(subject.pages.first.page)
- end
+ after do
+ destroy_page(subject.pages.first.page)
+ end
- it "returns the latest version of the page if it exists" do
- page = subject.find_page("index page")
- expect(page.title).to eq("index page")
- end
+ it "returns the latest version of the page if it exists" do
+ page = subject.find_page("index page")
+ expect(page.title).to eq("index page")
+ end
- it "returns nil if the page does not exist" do
- expect(subject.find_page("non-existant")).to eq(nil)
+ it "returns nil if the page does not exist" do
+ expect(subject.find_page("non-existant")).to eq(nil)
+ end
+
+ it "can find a page by slug" do
+ page = subject.find_page("index-page")
+ expect(page.title).to eq("index page")
+ end
+
+ it "returns a WikiPage instance" do
+ page = subject.find_page("index page")
+ expect(page).to be_a WikiPage
+ end
end
- it "can find a page by slug" do
- page = subject.find_page("index-page")
- expect(page.title).to eq("index page")
+ context 'when Gitaly wiki_find_page is enabled' do
+ it_behaves_like 'finding a wiki page'
end
- it "returns a WikiPage instance" do
- page = subject.find_page("index page")
- expect(page).to be_a WikiPage
+ context 'when Gitaly wiki_find_page is disabled', :skip_gitaly_mock do
+ it_behaves_like 'finding a wiki page'
end
end
@@ -265,23 +275,33 @@ describe ProjectWiki do
end
describe "#delete_page" do
- before do
- create_page("index", "some content")
- @page = subject.wiki.page(title: "index")
- end
+ shared_examples 'deleting a wiki page' do
+ before do
+ create_page("index", "some content")
+ @page = subject.wiki.page(title: "index")
+ end
- it "deletes the page" do
- subject.delete_page(@page)
- expect(subject.pages.count).to eq(0)
- end
+ it "deletes the page" do
+ subject.delete_page(@page)
+ expect(subject.pages.count).to eq(0)
+ end
- it 'updates project activity' do
- subject.delete_page(@page)
+ it 'updates project activity' do
+ subject.delete_page(@page)
- project.reload
+ project.reload
- expect(project.last_activity_at).to be_within(1.minute).of(Time.now)
- expect(project.last_repository_updated_at).to be_within(1.minute).of(Time.now)
+ expect(project.last_activity_at).to be_within(1.minute).of(Time.now)
+ expect(project.last_repository_updated_at).to be_within(1.minute).of(Time.now)
+ end
+ end
+
+ context 'when Gitaly wiki_delete_page is enabled' do
+ it_behaves_like 'deleting a wiki page'
+ end
+
+ context 'when Gitaly wiki_delete_page is disabled', :skip_gitaly_mock do
+ it_behaves_like 'deleting a wiki page'
end
end
@@ -343,6 +363,6 @@ describe ProjectWiki do
end
def destroy_page(page)
- subject.delete_page(page, commit_details)
+ subject.delete_page(page, "test commit")
end
end
diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb
index 39d188f18af..d7c07676911 100644
--- a/spec/models/repository_spec.rb
+++ b/spec/models/repository_spec.rb
@@ -299,6 +299,24 @@ describe Repository do
it { is_expected.to be_falsey }
end
+
+ context 'when pre-loaded merged branches are provided' do
+ using RSpec::Parameterized::TableSyntax
+
+ where(:branch, :pre_loaded, :expected) do
+ 'not-merged-branch' | ['branch-merged'] | false
+ 'branch-merged' | ['not-merged-branch'] | false
+ 'branch-merged' | ['branch-merged'] | true
+ 'not-merged-branch' | ['not-merged-branch'] | false
+ 'master' | ['master'] | false
+ end
+
+ with_them do
+ subject { repository.merged_to_root_ref?(branch, pre_loaded) }
+
+ it { is_expected.to eq(expected) }
+ end
+ end
end
describe '#can_be_merged?' do
@@ -2110,19 +2128,41 @@ describe Repository do
end
describe '#cache_method_output', :use_clean_rails_memory_store_caching do
+ let(:fallback) { 10 }
+
context 'with a non-existing repository' do
- let(:value) do
- repository.cache_method_output(:cats, fallback: 10) do
- raise Rugged::ReferenceError
+ let(:project) { create(:project) } # No repository
+
+ subject do
+ repository.cache_method_output(:cats, fallback: fallback) do
+ repository.cats_call_stub
end
end
- it 'returns a fallback value' do
- expect(value).to eq(10)
+ it 'returns the fallback value' do
+ expect(subject).to eq(fallback)
+ end
+
+ it 'avoids calling the original method' do
+ expect(repository).not_to receive(:cats_call_stub)
+
+ subject
+ end
+ end
+
+ context 'with a method throwing a non-existing-repository error' do
+ subject do
+ repository.cache_method_output(:cats, fallback: fallback) do
+ raise Gitlab::Git::Repository::NoRepository
+ end
+ end
+
+ it 'returns the fallback value' do
+ expect(subject).to eq(fallback)
end
it 'does not cache the data' do
- value
+ subject
expect(repository.instance_variable_defined?(:@cats)).to eq(false)
expect(repository.send(:cache).exist?(:cats)).to eq(false)
@@ -2238,4 +2278,24 @@ describe Repository do
end
end
end
+
+ describe 'commit cache' do
+ set(:project) { create(:project, :repository) }
+
+ it 'caches based on SHA' do
+ # Gets the commit oid, and warms the cache
+ oid = project.commit.id
+
+ expect(Gitlab::Git::Commit).not_to receive(:find).once
+
+ project.commit_by(oid: oid)
+ end
+
+ it 'caches nil values' do
+ expect(Gitlab::Git::Commit).to receive(:find).once
+
+ project.commit_by(oid: '1' * 40)
+ project.commit_by(oid: '1' * 40)
+ end
+ end
end
diff --git a/spec/models/wiki_page_spec.rb b/spec/models/wiki_page_spec.rb
index 1f14d06997e..a7227b38850 100644
--- a/spec/models/wiki_page_spec.rb
+++ b/spec/models/wiki_page_spec.rb
@@ -402,7 +402,7 @@ describe WikiPage do
def destroy_page(title)
page = wiki.wiki.page(title: title)
- wiki.delete_page(page, commit_details)
+ wiki.delete_page(page, "test commit")
end
def get_slugs(page_or_dir)
diff --git a/spec/requests/api/access_requests_spec.rb b/spec/requests/api/access_requests_spec.rb
index 50d0f72f6bc..35ca3635a9d 100644
--- a/spec/requests/api/access_requests_spec.rb
+++ b/spec/requests/api/access_requests_spec.rb
@@ -35,7 +35,7 @@ describe API::AccessRequests do
user = public_send(type)
get api("/#{source_type.pluralize}/#{source.id}/access_requests", user)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
end
@@ -45,7 +45,7 @@ describe API::AccessRequests do
it 'returns access requesters' do
get api("/#{source_type.pluralize}/#{source.id}/access_requests", master)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.size).to eq(1)
@@ -68,7 +68,7 @@ describe API::AccessRequests do
user = public_send(type)
post api("/#{source_type.pluralize}/#{source.id}/access_requests", user)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end.not_to change { source.requesters.count }
end
end
@@ -80,7 +80,7 @@ describe API::AccessRequests do
expect do
post api("/#{source_type.pluralize}/#{source.id}/access_requests", access_requester)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end.not_to change { source.requesters.count }
end
end
@@ -95,7 +95,7 @@ describe API::AccessRequests do
expect do
post api("/#{source_type.pluralize}/#{source.id}/access_requests", stranger)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end.not_to change { source.requesters.count }
end
end
@@ -104,7 +104,7 @@ describe API::AccessRequests do
expect do
post api("/#{source_type.pluralize}/#{source.id}/access_requests", stranger)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
end.to change { source.requesters.count }.by(1)
# User attributes
@@ -135,7 +135,7 @@ describe API::AccessRequests do
user = public_send(type)
put api("/#{source_type.pluralize}/#{source.id}/access_requests/#{access_requester.id}/approve", user)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
end
@@ -147,7 +147,7 @@ describe API::AccessRequests do
put api("/#{source_type.pluralize}/#{source.id}/access_requests/#{access_requester.id}/approve", master),
access_level: Member::MASTER
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
end.to change { source.members.count }.by(1)
# User attributes
expect(json_response['id']).to eq(access_requester.id)
@@ -166,7 +166,7 @@ describe API::AccessRequests do
expect do
put api("/#{source_type.pluralize}/#{source.id}/access_requests/#{stranger.id}/approve", master)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end.not_to change { source.members.count }
end
end
@@ -187,7 +187,7 @@ describe API::AccessRequests do
user = public_send(type)
delete api("/#{source_type.pluralize}/#{source.id}/access_requests/#{access_requester.id}", user)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
end
@@ -198,7 +198,7 @@ describe API::AccessRequests do
expect do
delete api("/#{source_type.pluralize}/#{source.id}/access_requests/#{access_requester.id}", access_requester)
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
end.to change { source.requesters.count }.by(-1)
end
end
@@ -208,7 +208,7 @@ describe API::AccessRequests do
expect do
delete api("/#{source_type.pluralize}/#{source.id}/access_requests/#{access_requester.id}", master)
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
end.to change { source.requesters.count }.by(-1)
end
@@ -217,7 +217,7 @@ describe API::AccessRequests do
expect do
delete api("/#{source_type.pluralize}/#{source.id}/access_requests/#{developer.id}", master)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end.not_to change { source.requesters.count }
end
end
@@ -227,7 +227,7 @@ describe API::AccessRequests do
expect do
delete api("/#{source_type.pluralize}/#{source.id}/access_requests/#{stranger.id}", master)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end.not_to change { source.requesters.count }
end
end
diff --git a/spec/requests/api/award_emoji_spec.rb b/spec/requests/api/award_emoji_spec.rb
index 7a0765c1fae..eaf12f71421 100644
--- a/spec/requests/api/award_emoji_spec.rb
+++ b/spec/requests/api/award_emoji_spec.rb
@@ -18,7 +18,7 @@ describe API::AwardEmoji do
it "returns an array of award_emoji" do
get api("/projects/#{project.id}/issues/#{issue.iid}/award_emoji", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.first['name']).to eq(award_emoji.name)
end
@@ -26,7 +26,7 @@ describe API::AwardEmoji do
it "returns a 404 error when issue id not found" do
get api("/projects/#{project.id}/issues/12345/award_emoji", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -34,7 +34,7 @@ describe API::AwardEmoji do
it "returns an array of award_emoji" do
get api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/award_emoji", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.first['name']).to eq(downvote.name)
@@ -48,7 +48,7 @@ describe API::AwardEmoji do
it 'returns the awarded emoji' do
get api("/projects/#{project.id}/snippets/#{snippet.id}/award_emoji", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.first['name']).to eq(award.name)
end
@@ -60,7 +60,7 @@ describe API::AwardEmoji do
get api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/award_emoji", user1)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -71,7 +71,7 @@ describe API::AwardEmoji do
it 'returns an array of award emoji' do
get api("/projects/#{project.id}/issues/#{issue.iid}/notes/#{note.id}/award_emoji", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.first['name']).to eq(rocket.name)
end
@@ -82,7 +82,7 @@ describe API::AwardEmoji do
it "returns the award emoji" do
get api("/projects/#{project.id}/issues/#{issue.iid}/award_emoji/#{award_emoji.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['name']).to eq(award_emoji.name)
expect(json_response['awardable_id']).to eq(issue.id)
expect(json_response['awardable_type']).to eq("Issue")
@@ -91,7 +91,7 @@ describe API::AwardEmoji do
it "returns a 404 error if the award is not found" do
get api("/projects/#{project.id}/issues/#{issue.iid}/award_emoji/12345", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -99,7 +99,7 @@ describe API::AwardEmoji do
it 'returns the award emoji' do
get api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/award_emoji/#{downvote.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['name']).to eq(downvote.name)
expect(json_response['awardable_id']).to eq(merge_request.id)
expect(json_response['awardable_type']).to eq("MergeRequest")
@@ -113,7 +113,7 @@ describe API::AwardEmoji do
it 'returns the awarded emoji' do
get api("/projects/#{project.id}/snippets/#{snippet.id}/award_emoji/#{award.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['name']).to eq(award.name)
expect(json_response['awardable_id']).to eq(snippet.id)
expect(json_response['awardable_type']).to eq("Snippet")
@@ -126,7 +126,7 @@ describe API::AwardEmoji do
get api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/award_emoji/#{downvote.id}", user1)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -137,7 +137,7 @@ describe API::AwardEmoji do
it 'returns an award emoji' do
get api("/projects/#{project.id}/issues/#{issue.iid}/notes/#{note.id}/award_emoji/#{rocket.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).not_to be_an Array
expect(json_response['name']).to eq(rocket.name)
end
@@ -150,7 +150,7 @@ describe API::AwardEmoji do
it "creates a new award emoji" do
post api("/projects/#{project.id}/issues/#{issue.iid}/award_emoji", user), name: 'blowfish'
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['name']).to eq('blowfish')
expect(json_response['user']['username']).to eq(user.username)
end
@@ -158,19 +158,19 @@ describe API::AwardEmoji do
it "returns a 400 bad request error if the name is not given" do
post api("/projects/#{project.id}/issues/#{issue.iid}/award_emoji", user)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it "returns a 401 unauthorized error if the user is not authenticated" do
post api("/projects/#{project.id}/issues/#{issue.iid}/award_emoji"), name: 'thumbsup'
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
it "returns a 404 error if the user authored issue" do
post api("/projects/#{project.id}/issues/#{issue2.id}/award_emoji", user), name: 'thumbsup'
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it "normalizes +1 as thumbsup award" do
@@ -184,7 +184,7 @@ describe API::AwardEmoji do
post api("/projects/#{project.id}/issues/#{issue.iid}/award_emoji", user), name: 'thumbsup'
post api("/projects/#{project.id}/issues/#{issue.iid}/award_emoji", user), name: 'thumbsup'
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response["message"]).to match("has already been taken")
end
end
@@ -196,7 +196,7 @@ describe API::AwardEmoji do
post api("/projects/#{project.id}/snippets/#{snippet.id}/award_emoji", user), name: 'blowfish'
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['name']).to eq('blowfish')
expect(json_response['user']['username']).to eq(user.username)
end
@@ -211,14 +211,14 @@ describe API::AwardEmoji do
post api("/projects/#{project.id}/issues/#{issue.iid}/notes/#{note.id}/award_emoji", user), name: 'rocket'
end.to change { note.award_emoji.count }.from(0).to(1)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['user']['username']).to eq(user.username)
end
it "it returns 404 error when user authored note" do
post api("/projects/#{project.id}/issues/#{issue.iid}/notes/#{note2.id}/award_emoji", user), name: 'thumbsup'
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it "normalizes +1 as thumbsup award" do
@@ -232,7 +232,7 @@ describe API::AwardEmoji do
post api("/projects/#{project.id}/issues/#{issue.iid}/notes/#{note.id}/award_emoji", user), name: 'rocket'
post api("/projects/#{project.id}/issues/#{issue.iid}/notes/#{note.id}/award_emoji", user), name: 'rocket'
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response["message"]).to match("has already been taken")
end
end
@@ -244,14 +244,14 @@ describe API::AwardEmoji do
expect do
delete api("/projects/#{project.id}/issues/#{issue.iid}/award_emoji/#{award_emoji.id}", user)
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
end.to change { issue.award_emoji.count }.from(1).to(0)
end
it 'returns a 404 error when the award emoji can not be found' do
delete api("/projects/#{project.id}/issues/#{issue.iid}/award_emoji/12345", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it_behaves_like '412 response' do
@@ -264,14 +264,14 @@ describe API::AwardEmoji do
expect do
delete api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/award_emoji/#{downvote.id}", user)
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
end.to change { merge_request.award_emoji.count }.from(1).to(0)
end
it 'returns a 404 error when note id not found' do
delete api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/notes/12345", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it_behaves_like '412 response' do
@@ -287,7 +287,7 @@ describe API::AwardEmoji do
expect do
delete api("/projects/#{project.id}/snippets/#{snippet.id}/award_emoji/#{award.id}", user)
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
end.to change { snippet.award_emoji.count }.from(1).to(0)
end
@@ -304,7 +304,7 @@ describe API::AwardEmoji do
expect do
delete api("/projects/#{project.id}/issues/#{issue.iid}/notes/#{note.id}/award_emoji/#{rocket.id}", user)
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
end.to change { note.award_emoji.count }.from(1).to(0)
end
diff --git a/spec/requests/api/boards_spec.rb b/spec/requests/api/boards_spec.rb
index fcfa4ddfbfe..546a1697e56 100644
--- a/spec/requests/api/boards_spec.rb
+++ b/spec/requests/api/boards_spec.rb
@@ -44,7 +44,7 @@ describe API::Boards do
it "returns authentication error" do
get api(base_url)
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
@@ -52,7 +52,7 @@ describe API::Boards do
it "returns the project issue board" do
get api(base_url, user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
@@ -70,7 +70,7 @@ describe API::Boards do
it 'returns issue board lists' do
get api(base_url, user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(2)
@@ -80,7 +80,7 @@ describe API::Boards do
it 'returns 404 if board not found' do
get api("/projects/#{project.id}/boards/22343/lists", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -90,7 +90,7 @@ describe API::Boards do
it 'returns a list' do
get api("#{base_url}/#{dev_list.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['id']).to eq(dev_list.id)
expect(json_response['label']['name']).to eq(dev_label.title)
expect(json_response['position']).to eq(1)
@@ -99,7 +99,7 @@ describe API::Boards do
it 'returns 404 if list not found' do
get api("#{base_url}/5324", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -113,7 +113,7 @@ describe API::Boards do
post api(base_url, user), label_id: group_label.id
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['label']['name']).to eq(group_label.title)
expect(json_response['position']).to eq(3)
end
@@ -121,7 +121,7 @@ describe API::Boards do
it 'creates a new issue board list for project labels' do
post api(base_url, user), label_id: ux_label.id
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['label']['name']).to eq(ux_label.title)
expect(json_response['position']).to eq(3)
end
@@ -129,13 +129,13 @@ describe API::Boards do
it 'returns 400 when creating a new list if label_id is invalid' do
post api(base_url, user), label_id: 23423
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it 'returns 403 for project members with guest role' do
put api("#{base_url}/#{test_list.id}", guest), position: 1
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -146,7 +146,7 @@ describe API::Boards do
put api("#{base_url}/#{test_list.id}", user),
position: 1
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['position']).to eq(1)
end
@@ -154,14 +154,14 @@ describe API::Boards do
put api("#{base_url}/44444", user),
position: 1
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it "returns 403 for project members with guest role" do
put api("#{base_url}/#{test_list.id}", guest),
position: 1
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -171,19 +171,19 @@ describe API::Boards do
it "rejects a non member from deleting a list" do
delete api("#{base_url}/#{dev_list.id}", non_member)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
it "rejects a user with guest role from deleting a list" do
delete api("#{base_url}/#{dev_list.id}", guest)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
it "returns 404 error if list id not found" do
delete api("#{base_url}/44444", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
context "when the user is project owner" do
@@ -196,7 +196,7 @@ describe API::Boards do
it "deletes the list if an admin requests it" do
delete api("#{base_url}/#{dev_list.id}", owner)
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
end
it_behaves_like '412 response' do
diff --git a/spec/requests/api/broadcast_messages_spec.rb b/spec/requests/api/broadcast_messages_spec.rb
index eacc575d97f..fe8a14fae9e 100644
--- a/spec/requests/api/broadcast_messages_spec.rb
+++ b/spec/requests/api/broadcast_messages_spec.rb
@@ -9,13 +9,13 @@ describe API::BroadcastMessages do
it 'returns a 401 for anonymous users' do
get api('/broadcast_messages')
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
it 'returns a 403 for users' do
get api('/broadcast_messages', user)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
it 'returns an Array of BroadcastMessages for admins' do
@@ -23,7 +23,7 @@ describe API::BroadcastMessages do
get api('/broadcast_messages', admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_kind_of(Array)
expect(json_response.first.keys)
@@ -35,19 +35,19 @@ describe API::BroadcastMessages do
it 'returns a 401 for anonymous users' do
get api("/broadcast_messages/#{message.id}")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
it 'returns a 403 for users' do
get api("/broadcast_messages/#{message.id}", user)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
it 'returns the specified message for admins' do
get api("/broadcast_messages/#{message.id}", admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['id']).to eq message.id
expect(json_response.keys)
.to match_array(%w(id message starts_at ends_at color font active))
@@ -58,13 +58,13 @@ describe API::BroadcastMessages do
it 'returns a 401 for anonymous users' do
post api('/broadcast_messages'), attributes_for(:broadcast_message)
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
it 'returns a 403 for users' do
post api('/broadcast_messages', user), attributes_for(:broadcast_message)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
context 'as an admin' do
@@ -74,7 +74,7 @@ describe API::BroadcastMessages do
post api('/broadcast_messages', admin), attrs
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['error']).to eq 'message is missing'
end
@@ -83,7 +83,7 @@ describe API::BroadcastMessages do
travel_to(time) do
post api('/broadcast_messages', admin), message: 'Test message'
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['starts_at']).to eq '2016-07-02T10:11:12.000Z'
expect(json_response['ends_at']).to eq '2016-07-02T11:11:12.000Z'
end
@@ -94,7 +94,7 @@ describe API::BroadcastMessages do
post api('/broadcast_messages', admin), attrs
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['color']).to eq attrs[:color]
expect(json_response['font']).to eq attrs[:font]
end
@@ -106,14 +106,14 @@ describe API::BroadcastMessages do
put api("/broadcast_messages/#{message.id}"),
attributes_for(:broadcast_message)
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
it 'returns a 403 for users' do
put api("/broadcast_messages/#{message.id}", user),
attributes_for(:broadcast_message)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
context 'as an admin' do
@@ -122,7 +122,7 @@ describe API::BroadcastMessages do
put api("/broadcast_messages/#{message.id}", admin), attrs
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['color']).to eq attrs[:color]
expect(json_response['font']).to eq attrs[:font]
end
@@ -134,7 +134,7 @@ describe API::BroadcastMessages do
put api("/broadcast_messages/#{message.id}", admin), attrs
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['starts_at']).to eq '2016-07-02T10:11:12.000Z'
expect(json_response['ends_at']).to eq '2016-07-02T13:11:12.000Z'
end
@@ -145,7 +145,7 @@ describe API::BroadcastMessages do
put api("/broadcast_messages/#{message.id}", admin), attrs
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect { message.reload }.to change { message.message }.to('new message')
end
end
@@ -156,14 +156,14 @@ describe API::BroadcastMessages do
delete api("/broadcast_messages/#{message.id}"),
attributes_for(:broadcast_message)
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
it 'returns a 403 for users' do
delete api("/broadcast_messages/#{message.id}", user),
attributes_for(:broadcast_message)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
it_behaves_like '412 response' do
@@ -174,7 +174,7 @@ describe API::BroadcastMessages do
expect do
delete api("/broadcast_messages/#{message.id}", admin)
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
end.to change { BroadcastMessage.count }.by(-1)
end
end
diff --git a/spec/requests/api/circuit_breakers_spec.rb b/spec/requests/api/circuit_breakers_spec.rb
index 76521e55994..3b858c40fd6 100644
--- a/spec/requests/api/circuit_breakers_spec.rb
+++ b/spec/requests/api/circuit_breakers_spec.rb
@@ -8,13 +8,13 @@ describe API::CircuitBreakers do
it 'returns a 401 for anonymous users' do
get api('/circuit_breakers/repository_storage')
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
it 'returns a 403 for users' do
get api('/circuit_breakers/repository_storage', user)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
it 'returns an Array of storages' do
@@ -24,7 +24,7 @@ describe API::CircuitBreakers do
get api('/circuit_breakers/repository_storage', admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_kind_of(Array)
expect(json_response.first['storage_name']).to eq('broken')
expect(json_response.first['failing_on_hosts']).to eq(['web01'])
@@ -39,7 +39,7 @@ describe API::CircuitBreakers do
get api('/circuit_breakers/repository_storage/failing', admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_kind_of(Array)
end
end
@@ -51,7 +51,7 @@ describe API::CircuitBreakers do
delete api('/circuit_breakers/repository_storage', admin)
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
end
end
end
diff --git a/spec/requests/api/commit_statuses_spec.rb b/spec/requests/api/commit_statuses_spec.rb
index e4c73583545..ffa17d296e8 100644
--- a/spec/requests/api/commit_statuses_spec.rb
+++ b/spec/requests/api/commit_statuses_spec.rb
@@ -39,7 +39,7 @@ describe API::CommitStatuses do
end
it 'returns latest commit statuses' do
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
@@ -55,7 +55,7 @@ describe API::CommitStatuses do
end
it 'returns all commit statuses' do
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(statuses_id).to contain_exactly(status1.id, status2.id,
@@ -70,7 +70,7 @@ describe API::CommitStatuses do
end
it 'returns latest commit statuses for specific ref' do
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(statuses_id).to contain_exactly(status3.id, status5.id)
@@ -83,7 +83,7 @@ describe API::CommitStatuses do
end
it 'return latest commit statuses for specific name' do
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(statuses_id).to contain_exactly(status4.id, status5.id)
@@ -110,7 +110,7 @@ describe API::CommitStatuses do
end
it "does not return project commits" do
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -120,7 +120,7 @@ describe API::CommitStatuses do
end
it "does not return project commits" do
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
end
@@ -135,7 +135,7 @@ describe API::CommitStatuses do
it 'creates commit status' do
post api(post_url, developer), state: status
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['sha']).to eq(commit.id)
expect(json_response['status']).to eq(status)
expect(json_response['name']).to eq('default')
@@ -159,7 +159,7 @@ describe API::CommitStatuses do
it "to #{status}" do
expect { post api(post_url, developer), state: status }.not_to change { CommitStatus.count }
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['status']).to eq(status)
end
end
@@ -181,7 +181,7 @@ describe API::CommitStatuses do
it 'creates commit status' do
subject
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['sha']).to eq(commit.id)
expect(json_response['status']).to eq('success')
expect(json_response['name']).to eq('coverage')
@@ -197,7 +197,7 @@ describe API::CommitStatuses do
it 'sets head pipeline' do
subject
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(merge_request.reload.head_pipeline).not_to be_nil
end
end
@@ -224,7 +224,7 @@ describe API::CommitStatuses do
end
it 'updates a commit status' do
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['sha']).to eq(commit.id)
expect(json_response['status']).to eq('success')
expect(json_response['name']).to eq('coverage')
@@ -250,7 +250,7 @@ describe API::CommitStatuses do
end
it 'correctly posts a new commit status' do
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['sha']).to eq(commit.id)
expect(json_response['status']).to eq('success')
end
@@ -268,7 +268,7 @@ describe API::CommitStatuses do
end
it 'does not create commit status' do
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
end
@@ -278,7 +278,7 @@ describe API::CommitStatuses do
end
it 'does not create commit status' do
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
end
@@ -290,7 +290,7 @@ describe API::CommitStatuses do
end
it 'returns not found error' do
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -301,7 +301,7 @@ describe API::CommitStatuses do
end
it 'responds with bad request status and validation errors' do
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['message']['target_url'])
.to include 'must be a valid URL'
end
@@ -314,7 +314,7 @@ describe API::CommitStatuses do
end
it 'does not create commit status' do
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -324,7 +324,7 @@ describe API::CommitStatuses do
end
it 'does not create commit status' do
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -334,7 +334,7 @@ describe API::CommitStatuses do
end
it 'does not create commit status' do
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
end
diff --git a/spec/requests/api/commits_spec.rb b/spec/requests/api/commits_spec.rb
index 94462b4572d..0d2bd3207c0 100644
--- a/spec/requests/api/commits_spec.rb
+++ b/spec/requests/api/commits_spec.rb
@@ -24,7 +24,7 @@ describe API::Commits do
get api(route, current_user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to match_response_schema('public_api/v4/commits')
expect(json_response.first['id']).to eq(commit.id)
expect(json_response.first['committer_name']).to eq(commit.committer_name)
@@ -119,7 +119,7 @@ describe API::Commits do
it "returns an invalid parameter error message" do
get api("/projects/#{project_id}/repository/commits?since=invalid-date", user)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['error']).to eq('since is invalid')
end
end
@@ -198,13 +198,13 @@ describe API::Commits do
it 'returns a 403 unauthorized for user without permissions' do
post api(url, guest)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
it 'returns a 400 bad request if no params are given' do
post api(url, user)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
describe 'create' do
@@ -248,7 +248,7 @@ describe API::Commits do
it 'returns a 400 bad request if file exists' do
post api(url, user), invalid_c_params
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
context 'with project path containing a dot in URL' do
@@ -257,7 +257,7 @@ describe API::Commits do
it 'a new file in project repo' do
post api(url, user), valid_c_params
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
end
end
end
@@ -292,14 +292,14 @@ describe API::Commits do
it 'an existing file in project repo' do
post api(url, user), valid_d_params
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['title']).to eq(message)
end
it 'returns a 400 bad request if file does not exist' do
post api(url, user), invalid_d_params
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
end
@@ -337,14 +337,14 @@ describe API::Commits do
it 'an existing file in project repo' do
post api(url, user), valid_m_params
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['title']).to eq(message)
end
it 'returns a 400 bad request if file does not exist' do
post api(url, user), invalid_m_params
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
end
@@ -380,14 +380,14 @@ describe API::Commits do
it 'an existing file in project repo' do
post api(url, user), valid_u_params
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['title']).to eq(message)
end
it 'returns a 400 bad request if file does not exist' do
post api(url, user), invalid_u_params
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
end
@@ -453,14 +453,14 @@ describe API::Commits do
it 'are commited as one in project repo' do
post api(url, user), valid_mo_params
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['title']).to eq(message)
end
it 'return a 400 bad request if there are any issues' do
post api(url, user), invalid_mo_params
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
end
end
@@ -571,7 +571,7 @@ describe API::Commits do
it 'includes a "created" status' do
get api(route, current_user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to match_response_schema('public_api/v4/commit/detail')
expect(json_response['status']).to eq('created')
expect(json_response['last_pipeline']['id']).to eq(pipeline.id)
@@ -588,7 +588,7 @@ describe API::Commits do
it 'includes a "success" status' do
get api(route, current_user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to match_response_schema('public_api/v4/commit/detail')
expect(json_response['status']).to eq('success')
end
diff --git a/spec/requests/api/deploy_keys_spec.rb b/spec/requests/api/deploy_keys_spec.rb
index 684877c33c0..1f1e6ea17e4 100644
--- a/spec/requests/api/deploy_keys_spec.rb
+++ b/spec/requests/api/deploy_keys_spec.rb
@@ -48,7 +48,7 @@ describe API::DeployKeys do
it 'returns array of ssh keys' do
get api("/projects/#{project.id}/deploy_keys", admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.first['title']).to eq(deploy_key.title)
@@ -59,14 +59,14 @@ describe API::DeployKeys do
it 'returns a single key' do
get api("/projects/#{project.id}/deploy_keys/#{deploy_key.id}", admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['title']).to eq(deploy_key.title)
end
it 'returns 404 Not Found with invalid ID' do
get api("/projects/#{project.id}/deploy_keys/404", admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -74,14 +74,14 @@ describe API::DeployKeys do
it 'does not create an invalid ssh key' do
post api("/projects/#{project.id}/deploy_keys", admin), { title: 'invalid key' }
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['error']).to eq('key is missing')
end
it 'does not create a key without title' do
post api("/projects/#{project.id}/deploy_keys", admin), key: 'some key'
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['error']).to eq('title is missing')
end
@@ -98,7 +98,7 @@ describe API::DeployKeys do
post api("/projects/#{project.id}/deploy_keys", admin), { key: deploy_key.key, title: deploy_key.title }
end.not_to change { project.deploy_keys.count }
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
end
it 'joins an existing ssh key to a new project' do
@@ -106,7 +106,7 @@ describe API::DeployKeys do
post api("/projects/#{project2.id}/deploy_keys", admin), { key: deploy_key.key, title: deploy_key.title }
end.to change { project2.deploy_keys.count }.by(1)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
end
it 'accepts can_push parameter' do
@@ -114,7 +114,7 @@ describe API::DeployKeys do
post api("/projects/#{project.id}/deploy_keys", admin), key_attrs
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['can_push']).to eq(true)
end
end
@@ -130,7 +130,7 @@ describe API::DeployKeys do
put api("/projects/#{project.id}/deploy_keys/#{deploy_key.id}", admin), { title: 'new title' }
end.not_to change(deploy_key, :title)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it 'does not update a public deploy key as non admin' do
@@ -138,7 +138,7 @@ describe API::DeployKeys do
put api("/projects/#{project.id}/deploy_keys/#{deploy_key.id}", user), { title: 'new title' }
end.not_to change(deploy_key, :title)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'does not update a private key with invalid title' do
@@ -148,7 +148,7 @@ describe API::DeployKeys do
put api("/projects/#{project.id}/deploy_keys/#{private_deploy_key.id}", admin), { title: '' }
end.not_to change(deploy_key, :title)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it 'updates a private ssh key with correct attributes' do
@@ -181,14 +181,14 @@ describe API::DeployKeys do
expect do
delete api("/projects/#{project.id}/deploy_keys/#{deploy_key.id}", admin)
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
end.to change { project.deploy_keys.count }.by(-1)
end
it 'returns 404 Not Found with invalid ID' do
delete api("/projects/#{project.id}/deploy_keys/404", admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it_behaves_like '412 response' do
@@ -205,7 +205,7 @@ describe API::DeployKeys do
post api("/projects/#{project2.id}/deploy_keys/#{deploy_key.id}/enable", admin)
end.to change { project2.deploy_keys.count }.from(0).to(1)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['id']).to eq(deploy_key.id)
end
end
@@ -214,7 +214,7 @@ describe API::DeployKeys do
it 'returns a 404 error' do
post api("/projects/#{project2.id}/deploy_keys/#{deploy_key.id}/enable", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
diff --git a/spec/requests/api/deployments_spec.rb b/spec/requests/api/deployments_spec.rb
index 90d78d060ca..c7977e624ff 100644
--- a/spec/requests/api/deployments_spec.rb
+++ b/spec/requests/api/deployments_spec.rb
@@ -15,7 +15,7 @@ describe API::Deployments do
it 'returns projects deployments' do
get api("/projects/#{project.id}/deployments", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.size).to eq(1)
@@ -28,7 +28,7 @@ describe API::Deployments do
it 'returns a 404 status code' do
get api("/projects/#{project.id}/deployments", non_member)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -38,7 +38,7 @@ describe API::Deployments do
it 'returns the projects deployment' do
get api("/projects/#{project.id}/deployments/#{deployment.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['sha']).to match /\A\h{40}\z/
expect(json_response['id']).to eq(deployment.id)
end
@@ -48,7 +48,7 @@ describe API::Deployments do
it 'returns a 404 status code' do
get api("/projects/#{project.id}/deployments/#{deployment.id}", non_member)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
diff --git a/spec/requests/api/doorkeeper_access_spec.rb b/spec/requests/api/doorkeeper_access_spec.rb
index 868fef65c1c..de7ce848a31 100644
--- a/spec/requests/api/doorkeeper_access_spec.rb
+++ b/spec/requests/api/doorkeeper_access_spec.rb
@@ -8,7 +8,7 @@ describe 'doorkeeper access' do
describe "unauthenticated" do
it "returns authentication success" do
get api("/user"), access_token: token.token
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
include_examples 'user login request with unique ip limit' do
@@ -21,14 +21,14 @@ describe 'doorkeeper access' do
describe "when token invalid" do
it "returns authentication error" do
get api("/user"), access_token: "123a"
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
describe "authorization by private token" do
it "returns authentication success" do
get api("/user", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
include_examples 'user login request with unique ip limit' do
@@ -43,7 +43,7 @@ describe 'doorkeeper access' do
user.block
get api("/user"), access_token: token.token
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
@@ -52,7 +52,7 @@ describe 'doorkeeper access' do
user.ldap_block
get api("/user"), access_token: token.token
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
end
diff --git a/spec/requests/api/environments_spec.rb b/spec/requests/api/environments_spec.rb
index f8cd529a06c..3665cfd7241 100644
--- a/spec/requests/api/environments_spec.rb
+++ b/spec/requests/api/environments_spec.rb
@@ -25,7 +25,7 @@ describe API::Environments do
get api("/projects/#{project.id}/environments", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.size).to eq(1)
@@ -39,7 +39,7 @@ describe API::Environments do
it 'returns a 404 status code' do
get api("/projects/#{project.id}/environments", non_member)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -49,7 +49,7 @@ describe API::Environments do
it 'creates a environment with valid params' do
post api("/projects/#{project.id}/environments", user), name: "mepmep"
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['name']).to eq('mepmep')
expect(json_response['slug']).to eq('mepmep')
expect(json_response['external']).to be nil
@@ -58,19 +58,19 @@ describe API::Environments do
it 'requires name to be passed' do
post api("/projects/#{project.id}/environments", user), external_url: 'test.gitlab.com'
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it 'returns a 400 if environment already exists' do
post api("/projects/#{project.id}/environments", user), name: environment.name
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it 'returns a 400 if slug is specified' do
post api("/projects/#{project.id}/environments", user), name: "foo", slug: "foo"
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response["error"]).to eq("slug is automatically generated and cannot be changed")
end
end
@@ -79,7 +79,7 @@ describe API::Environments do
it 'rejects the request' do
post api("/projects/#{project.id}/environments", non_member), name: 'gitlab.com'
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'returns a 400 when the required params are missing' do
@@ -94,7 +94,7 @@ describe API::Environments do
put api("/projects/#{project.id}/environments/#{environment.id}", user),
name: 'Mepmep', external_url: url
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['name']).to eq('Mepmep')
expect(json_response['external_url']).to eq(url)
end
@@ -104,7 +104,7 @@ describe API::Environments do
api_url = api("/projects/#{project.id}/environments/#{environment.id}", user)
put api_url, slug: slug + "-foo"
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response["error"]).to eq("slug is automatically generated and cannot be changed")
end
@@ -113,7 +113,7 @@ describe API::Environments do
put api("/projects/#{project.id}/environments/#{environment.id}", user),
name: 'Mepmep'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['name']).to eq('Mepmep')
expect(json_response['external_url']).to eq(url)
end
@@ -121,7 +121,7 @@ describe API::Environments do
it 'returns a 404 if the environment does not exist' do
put api("/projects/#{project.id}/environments/12345", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -130,13 +130,13 @@ describe API::Environments do
it 'returns a 200 for an existing environment' do
delete api("/projects/#{project.id}/environments/#{environment.id}", user)
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
end
it 'returns a 404 for non existing id' do
delete api("/projects/#{project.id}/environments/12345", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 Not found')
end
@@ -149,7 +149,7 @@ describe API::Environments do
it 'rejects the request' do
delete api("/projects/#{project.id}/environments/#{environment.id}", non_member)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -164,7 +164,7 @@ describe API::Environments do
end
it 'returns a 200' do
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it 'actually stops the environment' do
@@ -175,7 +175,7 @@ describe API::Environments do
it 'returns a 404 for non existing id' do
post api("/projects/#{project.id}/environments/12345/stop", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 Not found')
end
end
@@ -184,7 +184,7 @@ describe API::Environments do
it 'rejects the request' do
post api("/projects/#{project.id}/environments/#{environment.id}/stop", non_member)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
diff --git a/spec/requests/api/events_spec.rb b/spec/requests/api/events_spec.rb
index a23d28994ce..962c845f36d 100644
--- a/spec/requests/api/events_spec.rb
+++ b/spec/requests/api/events_spec.rb
@@ -14,7 +14,7 @@ describe API::Events do
it 'returns authentication error' do
get api('/events')
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
@@ -22,7 +22,7 @@ describe API::Events do
it 'returns users events' do
get api('/events?action=closed&target_type=issue&after=2016-12-1&before=2016-12-31', user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.size).to eq(1)
@@ -35,7 +35,7 @@ describe API::Events do
it 'returns no events' do
get api("/users/#{user.id}/events", other_user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_empty
end
end
@@ -44,7 +44,7 @@ describe API::Events do
it 'accepts a username' do
get api("/users/#{user.username}/events", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.size).to eq(1)
@@ -53,7 +53,7 @@ describe API::Events do
it 'returns the events' do
get api("/users/#{user.id}/events", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.size).to eq(1)
@@ -72,7 +72,7 @@ describe API::Events do
end
it 'responds with HTTP 200 OK' do
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it 'includes the push payload as a Hash' do
@@ -120,7 +120,7 @@ describe API::Events do
it 'returns a 404 error if not found' do
get api('/users/42/events', user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 User Not Found')
end
end
@@ -130,7 +130,7 @@ describe API::Events do
it 'returns 404 for private project' do
get api("/projects/#{private_project.id}/events")
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'returns 200 status for a public project' do
@@ -138,7 +138,7 @@ describe API::Events do
get api("/projects/#{public_project.id}/events")
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
end
@@ -146,7 +146,7 @@ describe API::Events do
it 'returns 404' do
get api("/projects/#{private_project.id}/events", non_member)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -154,7 +154,7 @@ describe API::Events do
it 'returns project events' do
get api("/projects/#{private_project.id}/events?action=closed&target_type=issue&after=2016-12-1&before=2016-12-31", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.size).to eq(1)
@@ -163,7 +163,7 @@ describe API::Events do
it 'returns 404 if project does not exist' do
get api("/projects/1234/events", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
diff --git a/spec/requests/api/features_spec.rb b/spec/requests/api/features_spec.rb
index 7e21006b254..267058d98ee 100644
--- a/spec/requests/api/features_spec.rb
+++ b/spec/requests/api/features_spec.rb
@@ -44,19 +44,19 @@ describe API::Features do
it 'returns a 401 for anonymous users' do
get api('/features')
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
it 'returns a 403 for users' do
get api('/features', user)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
it 'returns the feature list for admins' do
get api('/features', admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to match_array(expected_features)
end
end
@@ -68,20 +68,20 @@ describe API::Features do
it 'returns a 401 for anonymous users' do
post api("/features/#{feature_name}")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
it 'returns a 403 for users' do
post api("/features/#{feature_name}", user)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
context 'when passed value=true' do
it 'creates an enabled feature' do
post api("/features/#{feature_name}", admin), value: 'true'
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response).to eq(
'name' => 'my_feature',
'state' => 'on',
@@ -91,7 +91,7 @@ describe API::Features do
it 'creates an enabled feature for the given Flipper group when passed feature_group=perf_team' do
post api("/features/#{feature_name}", admin), value: 'true', feature_group: 'perf_team'
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response).to eq(
'name' => 'my_feature',
'state' => 'conditional',
@@ -104,7 +104,7 @@ describe API::Features do
it 'creates an enabled feature for the given user when passed user=username' do
post api("/features/#{feature_name}", admin), value: 'true', user: user.username
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response).to eq(
'name' => 'my_feature',
'state' => 'conditional',
@@ -117,7 +117,7 @@ describe API::Features do
it 'creates an enabled feature for the given user and feature group when passed user=username and feature_group=perf_team' do
post api("/features/#{feature_name}", admin), value: 'true', user: user.username, feature_group: 'perf_team'
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response).to eq(
'name' => 'my_feature',
'state' => 'conditional',
@@ -132,7 +132,7 @@ describe API::Features do
it 'creates a feature with the given percentage if passed an integer' do
post api("/features/#{feature_name}", admin), value: '50'
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response).to eq(
'name' => 'my_feature',
'state' => 'conditional',
@@ -154,7 +154,7 @@ describe API::Features do
it 'enables the feature' do
post api("/features/#{feature_name}", admin), value: 'true'
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response).to eq(
'name' => 'my_feature',
'state' => 'on',
@@ -164,7 +164,7 @@ describe API::Features do
it 'enables the feature for the given Flipper group when passed feature_group=perf_team' do
post api("/features/#{feature_name}", admin), value: 'true', feature_group: 'perf_team'
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response).to eq(
'name' => 'my_feature',
'state' => 'conditional',
@@ -177,7 +177,7 @@ describe API::Features do
it 'enables the feature for the given user when passed user=username' do
post api("/features/#{feature_name}", admin), value: 'true', user: user.username
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response).to eq(
'name' => 'my_feature',
'state' => 'conditional',
@@ -195,7 +195,7 @@ describe API::Features do
post api("/features/#{feature_name}", admin), value: 'false'
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response).to eq(
'name' => 'my_feature',
'state' => 'off',
@@ -208,7 +208,7 @@ describe API::Features do
post api("/features/#{feature_name}", admin), value: 'false', feature_group: 'perf_team'
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response).to eq(
'name' => 'my_feature',
'state' => 'off',
@@ -221,7 +221,7 @@ describe API::Features do
post api("/features/#{feature_name}", admin), value: 'false', user: user.username
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response).to eq(
'name' => 'my_feature',
'state' => 'off',
@@ -237,7 +237,7 @@ describe API::Features do
it 'updates the percentage of time if passed an integer' do
post api("/features/#{feature_name}", admin), value: '30'
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response).to eq(
'name' => 'my_feature',
'state' => 'conditional',
diff --git a/spec/requests/api/files_spec.rb b/spec/requests/api/files_spec.rb
index 114019441a3..5d8338a3fb7 100644
--- a/spec/requests/api/files_spec.rb
+++ b/spec/requests/api/files_spec.rb
@@ -26,7 +26,7 @@ describe API::Files do
it 'returns file attributes as json' do
get api(route(file_path), current_user), params
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['file_path']).to eq(CGI.unescape(file_path))
expect(json_response['file_name']).to eq('popen.rb')
expect(json_response['last_commit_id']).to eq('570e7b2abdd848b95f2f578043fc23bd6f6fd24d')
@@ -38,7 +38,7 @@ describe API::Files do
get api(route(file_path), current_user), params
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response.content_type).to eq('application/json')
end
@@ -49,7 +49,7 @@ describe API::Files do
get api(route(file_path), current_user), params
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['file_name']).to eq('commit.js.coffee')
expect(Base64.decode64(json_response['content']).lines.first).to eq("class Commit\n")
end
@@ -60,7 +60,7 @@ describe API::Files do
get api(url, current_user), params
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
context 'when mandatory params are not given' do
@@ -122,7 +122,7 @@ describe API::Files do
get api(url, current_user), params
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it 'returns raw file info for files with dots' do
@@ -131,7 +131,7 @@ describe API::Files do
get api(url, current_user), params
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it 'returns file by commit sha' do
@@ -142,7 +142,7 @@ describe API::Files do
get api(route(file_path) + "/raw", current_user), params
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
context 'when mandatory params are not given' do
@@ -209,7 +209,7 @@ describe API::Files do
it "creates a new file in project repo" do
post api(route(file_path), user), valid_params
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response["file_path"]).to eq(CGI.unescape(file_path))
last_commit = project.repository.commit.raw
expect(last_commit.author_email).to eq(user.email)
@@ -219,7 +219,7 @@ describe API::Files do
it "returns a 400 bad request if no mandatory params given" do
post api(route("any%2Etxt"), user)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it "returns a 400 if editor fails to create file" do
@@ -228,7 +228,7 @@ describe API::Files do
post api(route("any%2Etxt"), user), valid_params
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
context "when specifying an author" do
@@ -237,7 +237,7 @@ describe API::Files do
post api(route("new_file_with_author%2Etxt"), user), valid_params
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(response.content_type).to eq('application/json')
last_commit = project.repository.commit.raw
expect(last_commit.author_email).to eq(author_email)
@@ -251,7 +251,7 @@ describe API::Files do
it "creates a new file in project repo" do
post api(route("newfile%2Erb"), user), valid_params
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['file_path']).to eq('newfile.rb')
last_commit = project.repository.commit.raw
expect(last_commit.author_email).to eq(user.email)
@@ -272,7 +272,7 @@ describe API::Files do
it "updates existing file in project repo" do
put api(route(file_path), user), valid_params
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['file_path']).to eq(CGI.unescape(file_path))
last_commit = project.repository.commit.raw
expect(last_commit.author_email).to eq(user.email)
@@ -284,7 +284,7 @@ describe API::Files do
put api(route(file_path), user), params_with_stale_id
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['message']).to eq('You are attempting to update a file that has changed since you started editing it.')
end
@@ -295,13 +295,13 @@ describe API::Files do
put api(route(file_path), user), params_with_correct_id
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it "returns a 400 bad request if no params given" do
put api(route(file_path), user)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
context "when specifying an author" do
@@ -310,7 +310,7 @@ describe API::Files do
put api(route(file_path), user), valid_params
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
last_commit = project.repository.commit.raw
expect(last_commit.author_email).to eq(author_email)
expect(last_commit.author_name).to eq(author_name)
@@ -329,13 +329,13 @@ describe API::Files do
it "deletes existing file in project repo" do
delete api(route(file_path), user), valid_params
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
end
it "returns a 400 bad request if no params given" do
delete api(route(file_path), user)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it "returns a 400 if fails to delete file" do
@@ -343,7 +343,7 @@ describe API::Files do
delete api(route(file_path), user), valid_params
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
context "when specifying an author" do
@@ -352,7 +352,7 @@ describe API::Files do
delete api(route(file_path), user), valid_params
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
end
end
end
@@ -380,7 +380,7 @@ describe API::Files do
it "remains unchanged" do
get api(route(file_path), user), get_params
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['file_path']).to eq(CGI.unescape(file_path))
expect(json_response['file_name']).to eq(CGI.unescape(file_path))
expect(json_response['content']).to eq(put_params[:content])
diff --git a/spec/requests/api/group_variables_spec.rb b/spec/requests/api/group_variables_spec.rb
index 93b9cf85c1d..a4f198eb5c9 100644
--- a/spec/requests/api/group_variables_spec.rb
+++ b/spec/requests/api/group_variables_spec.rb
@@ -15,7 +15,7 @@ describe API::GroupVariables do
it 'returns group variables' do
get api("/groups/#{group.id}/variables", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_a(Array)
end
end
@@ -24,7 +24,7 @@ describe API::GroupVariables do
it 'does not return group variables' do
get api("/groups/#{group.id}/variables", user)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -32,7 +32,7 @@ describe API::GroupVariables do
it 'does not return group variables' do
get api("/groups/#{group.id}/variables")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
end
@@ -48,7 +48,7 @@ describe API::GroupVariables do
it 'returns group variable details' do
get api("/groups/#{group.id}/variables/#{variable.key}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['value']).to eq(variable.value)
expect(json_response['protected']).to eq(variable.protected?)
end
@@ -56,7 +56,7 @@ describe API::GroupVariables do
it 'responds with 404 Not Found if requesting non-existing variable' do
get api("/groups/#{group.id}/variables/non_existing_variable", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -64,7 +64,7 @@ describe API::GroupVariables do
it 'does not return group variable details' do
get api("/groups/#{group.id}/variables/#{variable.key}", user)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -72,7 +72,7 @@ describe API::GroupVariables do
it 'does not return group variable details' do
get api("/groups/#{group.id}/variables/#{variable.key}")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
end
@@ -90,7 +90,7 @@ describe API::GroupVariables do
post api("/groups/#{group.id}/variables", user), key: 'TEST_VARIABLE_2', value: 'VALUE_2', protected: true
end.to change {group.variables.count}.by(1)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['key']).to eq('TEST_VARIABLE_2')
expect(json_response['value']).to eq('VALUE_2')
expect(json_response['protected']).to be_truthy
@@ -101,7 +101,7 @@ describe API::GroupVariables do
post api("/groups/#{group.id}/variables", user), key: 'TEST_VARIABLE_2', value: 'VALUE_2'
end.to change {group.variables.count}.by(1)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['key']).to eq('TEST_VARIABLE_2')
expect(json_response['value']).to eq('VALUE_2')
expect(json_response['protected']).to be_falsey
@@ -112,7 +112,7 @@ describe API::GroupVariables do
post api("/groups/#{group.id}/variables", user), key: variable.key, value: 'VALUE_2'
end.to change {group.variables.count}.by(0)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
end
@@ -120,7 +120,7 @@ describe API::GroupVariables do
it 'does not create variable' do
post api("/groups/#{group.id}/variables", user)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -128,7 +128,7 @@ describe API::GroupVariables do
it 'does not create variable' do
post api("/groups/#{group.id}/variables")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
end
@@ -149,7 +149,7 @@ describe API::GroupVariables do
updated_variable = group.variables.first
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(value_before).to eq(variable.value)
expect(updated_variable.value).to eq('VALUE_1_UP')
expect(updated_variable).to be_protected
@@ -158,7 +158,7 @@ describe API::GroupVariables do
it 'responds with 404 Not Found if requesting non-existing variable' do
put api("/groups/#{group.id}/variables/non_existing_variable", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -166,7 +166,7 @@ describe API::GroupVariables do
it 'does not update variable' do
put api("/groups/#{group.id}/variables/#{variable.key}", user)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -174,7 +174,7 @@ describe API::GroupVariables do
it 'does not update variable' do
put api("/groups/#{group.id}/variables/#{variable.key}")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
end
@@ -191,14 +191,14 @@ describe API::GroupVariables do
expect do
delete api("/groups/#{group.id}/variables/#{variable.key}", user)
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
end.to change {group.variables.count}.by(-1)
end
it 'responds with 404 Not Found if requesting non-existing variable' do
delete api("/groups/#{group.id}/variables/non_existing_variable", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it_behaves_like '412 response' do
@@ -210,7 +210,7 @@ describe API::GroupVariables do
it 'does not delete variable' do
delete api("/groups/#{group.id}/variables/#{variable.key}", user)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -218,7 +218,7 @@ describe API::GroupVariables do
it 'does not delete variable' do
delete api("/groups/#{group.id}/variables/#{variable.key}")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
end
diff --git a/spec/requests/api/groups_spec.rb b/spec/requests/api/groups_spec.rb
index 1671a046fdf..8ce9fcc80bf 100644
--- a/spec/requests/api/groups_spec.rb
+++ b/spec/requests/api/groups_spec.rb
@@ -23,7 +23,7 @@ describe API::Groups do
it "returns public groups" do
get api("/groups")
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
@@ -36,7 +36,7 @@ describe API::Groups do
it "normal user: returns an array of groups of user1" do
get api("/groups", user1)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
@@ -47,7 +47,7 @@ describe API::Groups do
it "does not include statistics" do
get api("/groups", user1), statistics: true
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.first).not_to include 'statistics'
@@ -58,7 +58,7 @@ describe API::Groups do
it "admin: returns an array of all groups" do
get api("/groups", admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(2)
@@ -67,7 +67,7 @@ describe API::Groups do
it "does not include statistics by default" do
get api("/groups", admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.first).not_to include('statistics')
@@ -87,7 +87,7 @@ describe API::Groups do
get api("/groups", admin), statistics: true
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response)
@@ -99,7 +99,7 @@ describe API::Groups do
it "returns all groups excluding skipped groups" do
get api("/groups", admin), skip_groups: [group2.id]
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
@@ -114,7 +114,7 @@ describe API::Groups do
get api("/groups", user1), all_available: true
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(response_groups).to contain_exactly(public_group.name, group1.name)
@@ -132,7 +132,7 @@ describe API::Groups do
it "sorts by name ascending by default" do
get api("/groups", user1)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(response_groups).to eq([group3.name, group1.name])
@@ -141,7 +141,7 @@ describe API::Groups do
it "sorts in descending order when passed" do
get api("/groups", user1), sort: "desc"
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(response_groups).to eq([group1.name, group3.name])
@@ -150,7 +150,7 @@ describe API::Groups do
it "sorts by the order_by param" do
get api("/groups", user1), order_by: "path"
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(response_groups).to eq([group1.name, group3.name])
@@ -163,7 +163,7 @@ describe API::Groups do
get api('/groups', user2), owned: true
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
@@ -176,12 +176,12 @@ describe API::Groups do
context 'when unauthenticated' do
it 'returns 404 for a private group' do
get api("/groups/#{group2.id}")
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'returns 200 for a public group' do
get api("/groups/#{group1.id}")
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
end
@@ -192,7 +192,7 @@ describe API::Groups do
get api("/groups/#{group1.id}", user1)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['id']).to eq(group1.id)
expect(json_response['name']).to eq(group1.name)
expect(json_response['path']).to eq(group1.path)
@@ -214,13 +214,13 @@ describe API::Groups do
it "does not return a non existing group" do
get api("/groups/1328", user1)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it "does not return a group not attached to user1" do
get api("/groups/#{group2.id}", user1)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -228,14 +228,14 @@ describe API::Groups do
it "returns any existing group" do
get api("/groups/#{group2.id}", admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['name']).to eq(group2.name)
end
it "does not return a non existing group" do
get api("/groups/1328", admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -243,20 +243,20 @@ describe API::Groups do
it 'returns any existing group' do
get api("/groups/#{group1.path}", admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['name']).to eq(group1.name)
end
it 'does not return a non existing group' do
get api('/groups/unknown', admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'does not return a group not attached to user1' do
get api("/groups/#{group2.path}", user1)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -268,7 +268,7 @@ describe API::Groups do
it 'updates the group' do
put api("/groups/#{group1.id}", user1), name: new_group_name, request_access_enabled: true
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['name']).to eq(new_group_name)
expect(json_response['request_access_enabled']).to eq(true)
end
@@ -276,7 +276,7 @@ describe API::Groups do
it 'returns 404 for a non existing group' do
put api('/groups/1328', user1), name: new_group_name
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -284,7 +284,7 @@ describe API::Groups do
it 'updates the group' do
put api("/groups/#{group1.id}", admin), name: new_group_name
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['name']).to eq(new_group_name)
end
end
@@ -293,7 +293,7 @@ describe API::Groups do
it 'does not updates the group' do
put api("/groups/#{group1.id}", user2), name: new_group_name
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -301,7 +301,7 @@ describe API::Groups do
it 'returns 404 when trying to update the group' do
put api("/groups/#{group2.id}", user1), name: new_group_name
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -311,7 +311,7 @@ describe API::Groups do
it "returns the group's projects" do
get api("/groups/#{group1.id}/projects", user1)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response.length).to eq(2)
project_names = json_response.map { |proj| proj['name'] }
@@ -322,7 +322,7 @@ describe API::Groups do
it "returns the group's projects with simple representation" do
get api("/groups/#{group1.id}/projects", user1), simple: true
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response.length).to eq(2)
project_names = json_response.map { |proj| proj['name'] }
@@ -335,7 +335,7 @@ describe API::Groups do
get api("/groups/#{group1.id}/projects", user1), visibility: 'public'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an(Array)
expect(json_response.length).to eq(1)
@@ -345,13 +345,13 @@ describe API::Groups do
it "does not return a non existing group" do
get api("/groups/1328/projects", user1)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it "does not return a group not attached to user1" do
get api("/groups/#{group2.id}/projects", user1)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it "only returns projects to which user has access" do
@@ -359,7 +359,7 @@ describe API::Groups do
get api("/groups/#{group1.id}/projects", user3)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response.length).to eq(1)
expect(json_response.first['name']).to eq(project3.name)
@@ -370,7 +370,7 @@ describe API::Groups do
get api("/groups/#{project2.group.id}/projects", user3), owned: true
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response.length).to eq(1)
expect(json_response.first['name']).to eq(project2.name)
end
@@ -380,7 +380,7 @@ describe API::Groups do
get api("/groups/#{group1.id}/projects", user1), starred: true
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response.length).to eq(1)
expect(json_response.first['name']).to eq(project1.name)
end
@@ -390,7 +390,7 @@ describe API::Groups do
it "returns any existing group" do
get api("/groups/#{group2.id}/projects", admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response.length).to eq(1)
expect(json_response.first['name']).to eq(project2.name)
@@ -399,7 +399,7 @@ describe API::Groups do
it "does not return a non existing group" do
get api("/groups/1328/projects", admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -407,7 +407,7 @@ describe API::Groups do
it 'returns any existing group' do
get api("/groups/#{group1.path}/projects", admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
project_names = json_response.map { |proj| proj['name'] }
expect(project_names).to match_array([project1.name, project3.name])
@@ -416,13 +416,13 @@ describe API::Groups do
it 'does not return a non existing group' do
get api('/groups/unknown/projects', admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'does not return a group not attached to user1' do
get api("/groups/#{group2.path}/projects", user1)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -432,7 +432,7 @@ describe API::Groups do
it "does not create group" do
post api("/groups", user1), attributes_for(:group)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
context 'as owner', :nested_groups do
@@ -443,7 +443,7 @@ describe API::Groups do
it 'can create subgroups' do
post api("/groups", user1), parent_id: group2.id, name: 'foo', path: 'foo'
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
end
end
@@ -455,7 +455,7 @@ describe API::Groups do
it 'cannot create subgroups' do
post api("/groups", user1), parent_id: group2.id, name: 'foo', path: 'foo'
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
end
@@ -466,7 +466,7 @@ describe API::Groups do
post api("/groups", user3), group
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response["name"]).to eq(group[:name])
expect(json_response["path"]).to eq(group[:path])
@@ -481,7 +481,7 @@ describe API::Groups do
post api("/groups", user3), group
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response["full_path"]).to eq("#{parent.path}/#{group[:path]}")
expect(json_response["parent_id"]).to eq(parent.id)
@@ -490,20 +490,20 @@ describe API::Groups do
it "does not create group, duplicate" do
post api("/groups", user3), { name: 'Duplicate Test', path: group2.path }
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(response.message).to eq("Bad Request")
end
it "returns 400 bad request error if name not given" do
post api("/groups", user3), { path: group2.path }
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it "returns 400 bad request error if path not given" do
post api("/groups", user3), { name: 'test' }
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
end
end
@@ -513,7 +513,7 @@ describe API::Groups do
it "removes group" do
delete api("/groups/#{group1.id}", user1)
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
end
it_behaves_like '412 response' do
@@ -526,19 +526,19 @@ describe API::Groups do
delete api("/groups/#{group1.id}", user3)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
it "does not remove a non existing group" do
delete api("/groups/1328", user1)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it "does not remove a group not attached to user1" do
delete api("/groups/#{group2.id}", user1)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -546,13 +546,13 @@ describe API::Groups do
it "removes any existing group" do
delete api("/groups/#{group2.id}", admin)
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
end
it "does not remove a non existing group" do
delete api("/groups/1328", admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -570,7 +570,7 @@ describe API::Groups do
it "does not transfer project to group" do
post api("/groups/#{group1.id}/projects/#{project.id}", user2)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -578,7 +578,7 @@ describe API::Groups do
it "transfers project to group" do
post api("/groups/#{group1.id}/projects/#{project.id}", admin)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
end
context 'when using project path in URL' do
@@ -586,7 +586,7 @@ describe API::Groups do
it "transfers project to group" do
post api("/groups/#{group1.id}/projects/#{project_path}", admin)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
end
end
@@ -594,7 +594,7 @@ describe API::Groups do
it "does not transfer project to group" do
post api("/groups/#{group1.id}/projects/nogroup%2Fnoproject", admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -604,7 +604,7 @@ describe API::Groups do
it "transfers project to group" do
post api("/groups/#{group1.path}/projects/#{project_path}", admin)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
end
end
@@ -612,7 +612,7 @@ describe API::Groups do
it "does not transfer project to group" do
post api("/groups/noexist/projects/#{project_path}", admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
diff --git a/spec/requests/api/internal_spec.rb b/spec/requests/api/internal_spec.rb
index 1274e66bb4c..d919899282d 100644
--- a/spec/requests/api/internal_spec.rb
+++ b/spec/requests/api/internal_spec.rb
@@ -14,7 +14,7 @@ describe API::Internal do
get api("/internal/check"), secret_token: secret_token
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['api_version']).to eq(API::API.version)
expect(json_response['redis']).to be(true)
end
@@ -35,7 +35,7 @@ describe API::Internal do
it 'returns one broadcast message' do
get api('/internal/broadcast_message'), secret_token: secret_token
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['message']).to eq(broadcast_message.message)
end
end
@@ -44,7 +44,7 @@ describe API::Internal do
it 'returns nothing' do
get api('/internal/broadcast_message'), secret_token: secret_token
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_empty
end
end
@@ -55,7 +55,7 @@ describe API::Internal do
get api('/internal/broadcast_message'), secret_token: secret_token
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_empty
end
end
@@ -68,7 +68,7 @@ describe API::Internal do
it 'returns active broadcast message(s)' do
get api('/internal/broadcast_messages'), secret_token: secret_token
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response[0]['message']).to eq(broadcast_message.message)
end
end
@@ -77,7 +77,7 @@ describe API::Internal do
it 'returns nothing' do
get api('/internal/broadcast_messages'), secret_token: secret_token
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_empty
end
end
@@ -154,7 +154,7 @@ describe API::Internal do
it 'returns the correct information about the key' do
lfs_auth(key.id, project)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['username']).to eq(user.username)
expect(json_response['lfs_token']).to eq(Gitlab::LfsToken.new(key).token)
@@ -164,7 +164,7 @@ describe API::Internal do
it 'returns a 404 when the wrong key is provided' do
lfs_auth(nil, project)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -174,7 +174,7 @@ describe API::Internal do
it 'returns the correct information about the key' do
lfs_auth(key.id, project)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['username']).to eq("lfs+deploy-key-#{key.id}")
expect(json_response['lfs_token']).to eq(Gitlab::LfsToken.new(key).token)
expect(json_response['repository_http_path']).to eq(project.http_url_to_repo)
@@ -186,7 +186,7 @@ describe API::Internal do
it do
get(api("/internal/discover"), key_id: key.id, secret_token: secret_token)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['name']).to eq(user.name)
end
@@ -214,7 +214,7 @@ describe API::Internal do
GIT_ALTERNATE_OBJECT_DIRECTORIES: 'bar'
}.to_json)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
end
@@ -222,7 +222,7 @@ describe API::Internal do
it 'responds with success' do
push(key, project.wiki)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response["status"]).to be_truthy
expect(json_response["repository_path"]).to eq(project.wiki.repository.path_to_repo)
expect(json_response["gl_repository"]).to eq("wiki-#{project.id}")
@@ -234,7 +234,7 @@ describe API::Internal do
it 'responds with success' do
pull(key, project.wiki)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response["status"]).to be_truthy
expect(json_response["repository_path"]).to eq(project.wiki.repository.path_to_repo)
expect(json_response["gl_repository"]).to eq("wiki-#{project.id}")
@@ -248,7 +248,7 @@ describe API::Internal do
allow(Gitlab::GitalyClient).to receive(:feature_enabled?).with(:ssh_upload_pack).and_return(false)
pull(key, project)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response["status"]).to be_truthy
expect(json_response["repository_path"]).to eq(project.repository.path_to_repo)
expect(json_response["gl_repository"]).to eq("project-#{project.id}")
@@ -262,7 +262,7 @@ describe API::Internal do
allow(Gitlab::GitalyClient).to receive(:feature_enabled?).with(:ssh_upload_pack).and_return(true)
pull(key, project)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response["status"]).to be_truthy
expect(json_response["repository_path"]).to eq(project.repository.path_to_repo)
expect(json_response["gl_repository"]).to eq("project-#{project.id}")
@@ -283,7 +283,7 @@ describe API::Internal do
allow(Gitlab::GitalyClient).to receive(:feature_enabled?).with(:ssh_receive_pack).and_return(false)
push(key, project)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response["status"]).to be_truthy
expect(json_response["repository_path"]).to eq(project.repository.path_to_repo)
expect(json_response["gl_repository"]).to eq("project-#{project.id}")
@@ -297,7 +297,7 @@ describe API::Internal do
allow(Gitlab::GitalyClient).to receive(:feature_enabled?).with(:ssh_receive_pack).and_return(true)
push(key, project)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response["status"]).to be_truthy
expect(json_response["repository_path"]).to eq(project.repository.path_to_repo)
expect(json_response["gl_repository"]).to eq("project-#{project.id}")
@@ -315,7 +315,7 @@ describe API::Internal do
it do
pull(key, project_with_repo_path('/' + project.full_path))
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response["status"]).to be_truthy
expect(json_response["repository_path"]).to eq(project.repository.path_to_repo)
expect(json_response["gl_repository"]).to eq("project-#{project.id}")
@@ -326,7 +326,7 @@ describe API::Internal do
it do
pull(key, project_with_repo_path(project.full_path))
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response["status"]).to be_truthy
expect(json_response["repository_path"]).to eq(project.repository.path_to_repo)
expect(json_response["gl_repository"]).to eq("project-#{project.id}")
@@ -344,7 +344,7 @@ describe API::Internal do
it do
pull(key, project)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response["status"]).to be_falsey
expect(user).not_to have_an_activity_record
end
@@ -354,7 +354,7 @@ describe API::Internal do
it do
push(key, project)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response["status"]).to be_falsey
expect(user).not_to have_an_activity_record
end
@@ -372,7 +372,7 @@ describe API::Internal do
it do
pull(key, personal_project)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response["status"]).to be_falsey
expect(user).not_to have_an_activity_record
end
@@ -382,7 +382,7 @@ describe API::Internal do
it do
push(key, personal_project)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response["status"]).to be_falsey
expect(user).not_to have_an_activity_record
end
@@ -399,7 +399,7 @@ describe API::Internal do
it do
pull(key, project)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response["status"]).to be_truthy
end
end
@@ -408,7 +408,7 @@ describe API::Internal do
it do
push(key, project)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response["status"]).to be_falsey
end
end
@@ -425,7 +425,7 @@ describe API::Internal do
it do
archive(key, project)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response["status"]).to be_truthy
end
end
@@ -434,7 +434,7 @@ describe API::Internal do
it do
archive(key, project)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response["status"]).to be_falsey
end
end
@@ -444,7 +444,7 @@ describe API::Internal do
it do
pull(key, project_with_repo_path('gitlab/notexist'))
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response["status"]).to be_falsey
end
end
@@ -453,7 +453,7 @@ describe API::Internal do
it do
pull(OpenStruct.new(id: 0), project)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response["status"]).to be_falsey
end
end
@@ -535,7 +535,7 @@ describe API::Internal do
it 'rejects the push' do
push_with_path(key, old_path_to_repo)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['status']).to be_falsey
expect(json_response['message']).to eq(project_moved_message)
end
@@ -543,7 +543,7 @@ describe API::Internal do
it 'rejects the SSH pull' do
pull_with_path(key, old_path_to_repo)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['status']).to be_falsey
expect(json_response['message']).to eq(project_moved_message)
end
@@ -614,7 +614,7 @@ describe API::Internal do
#
# post api("/internal/notify_post_receive"), valid_params
#
- # expect(response).to have_http_status(200)
+ # expect(response).to have_gitlab_http_status(200)
# end
#
# it "calls the Gitaly client with the wiki's repository if it's a wiki" do
@@ -626,7 +626,7 @@ describe API::Internal do
#
# post api("/internal/notify_post_receive"), valid_wiki_params
#
- # expect(response).to have_http_status(200)
+ # expect(response).to have_gitlab_http_status(200)
# end
#
# it "returns 500 if the gitaly call fails" do
@@ -635,7 +635,7 @@ describe API::Internal do
#
# post api("/internal/notify_post_receive"), valid_params
#
- # expect(response).to have_http_status(500)
+ # expect(response).to have_gitlab_http_status(500)
# end
#
# context 'with a gl_repository parameter' do
@@ -656,7 +656,7 @@ describe API::Internal do
#
# post api("/internal/notify_post_receive"), valid_params
#
- # expect(response).to have_http_status(200)
+ # expect(response).to have_gitlab_http_status(200)
# end
#
# it "calls the Gitaly client with the wiki's repository if it's a wiki" do
@@ -668,7 +668,7 @@ describe API::Internal do
#
# post api("/internal/notify_post_receive"), valid_wiki_params
#
- # expect(response).to have_http_status(200)
+ # expect(response).to have_gitlab_http_status(200)
# end
# end
# end
@@ -734,7 +734,7 @@ describe API::Internal do
it 'returns one broadcast message' do
post api("/internal/post_receive"), valid_params
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['broadcast_message']).to eq(broadcast_message.message)
end
end
@@ -743,7 +743,7 @@ describe API::Internal do
it 'returns empty string' do
post api("/internal/post_receive"), valid_params
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['broadcast_message']).to eq(nil)
end
end
@@ -754,7 +754,7 @@ describe API::Internal do
post api("/internal/post_receive"), valid_params
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['broadcast_message']).to eq(nil)
end
end
diff --git a/spec/requests/api/issues_spec.rb b/spec/requests/api/issues_spec.rb
index 972e57bc373..99525cd0a6a 100644
--- a/spec/requests/api/issues_spec.rb
+++ b/spec/requests/api/issues_spec.rb
@@ -67,7 +67,7 @@ describe API::Issues, :mailer do
it "returns authentication error" do
get api("/issues")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
context "when authenticated" do
@@ -297,7 +297,7 @@ describe API::Issues, :mailer do
it 'matches V4 response schema' do
get api('/issues', user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to match_response_schema('public_api/v4/issues')
end
end
@@ -474,7 +474,7 @@ describe API::Issues, :mailer do
it 'returns an array of issues with no milestone' do
get api("#{base_url}?milestone=#{no_milestone_title}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect_paginated_array_response(size: 1)
expect(json_response.first['id']).to eq(group_confidential_issue.id)
@@ -535,7 +535,7 @@ describe API::Issues, :mailer do
it 'returns 404 when project does not exist' do
get api('/projects/1000/issues', non_member)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it "returns 404 on private projects for other users" do
@@ -544,7 +544,7 @@ describe API::Issues, :mailer do
get api("/projects/#{private_project.id}/issues", non_member)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'returns no issues when user has access to project but not issues' do
@@ -732,7 +732,7 @@ describe API::Issues, :mailer do
it 'exposes known attributes' do
get api("/projects/#{project.id}/issues/#{issue.iid}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['id']).to eq(issue.id)
expect(json_response['iid']).to eq(issue.iid)
expect(json_response['project_id']).to eq(issue.project.id)
@@ -753,7 +753,7 @@ describe API::Issues, :mailer do
it "exposes the 'closed_at' attribute" do
get api("/projects/#{project.id}/issues/#{closed_issue.iid}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['closed_at']).to be_present
end
@@ -773,39 +773,39 @@ describe API::Issues, :mailer do
it "returns a project issue by internal id" do
get api("/projects/#{project.id}/issues/#{issue.iid}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['title']).to eq(issue.title)
expect(json_response['iid']).to eq(issue.iid)
end
it "returns 404 if issue id not found" do
get api("/projects/#{project.id}/issues/54321", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it "returns 404 if the issue ID is used" do
get api("/projects/#{project.id}/issues/#{issue.id}", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
context 'confidential issues' do
it "returns 404 for non project members" do
get api("/projects/#{project.id}/issues/#{confidential_issue.iid}", non_member)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it "returns 404 for project members with guest role" do
get api("/projects/#{project.id}/issues/#{confidential_issue.iid}", guest)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it "returns confidential issue for project members" do
get api("/projects/#{project.id}/issues/#{confidential_issue.iid}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['title']).to eq(confidential_issue.title)
expect(json_response['iid']).to eq(confidential_issue.iid)
end
@@ -813,7 +813,7 @@ describe API::Issues, :mailer do
it "returns confidential issue for author" do
get api("/projects/#{project.id}/issues/#{confidential_issue.iid}", author)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['title']).to eq(confidential_issue.title)
expect(json_response['iid']).to eq(confidential_issue.iid)
end
@@ -821,7 +821,7 @@ describe API::Issues, :mailer do
it "returns confidential issue for assignee" do
get api("/projects/#{project.id}/issues/#{confidential_issue.iid}", assignee)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['title']).to eq(confidential_issue.title)
expect(json_response['iid']).to eq(confidential_issue.iid)
end
@@ -829,7 +829,7 @@ describe API::Issues, :mailer do
it "returns confidential issue for admin" do
get api("/projects/#{project.id}/issues/#{confidential_issue.iid}", admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['title']).to eq(confidential_issue.title)
expect(json_response['iid']).to eq(confidential_issue.iid)
end
@@ -842,7 +842,7 @@ describe API::Issues, :mailer do
post api("/projects/#{project.id}/issues", user),
title: 'new issue', assignee_id: user2.id
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['title']).to eq('new issue')
expect(json_response['assignee']['name']).to eq(user2.name)
expect(json_response['assignees'].first['name']).to eq(user2.name)
@@ -854,7 +854,7 @@ describe API::Issues, :mailer do
post api("/projects/#{project.id}/issues", user),
title: 'new issue', assignee_ids: [user2.id, guest.id]
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['title']).to eq('new issue')
expect(json_response['assignees'].count).to eq(1)
end
@@ -865,7 +865,7 @@ describe API::Issues, :mailer do
title: 'new issue', labels: 'label, label2', weight: 3,
assignee_ids: [user2.id]
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['title']).to eq('new issue')
expect(json_response['description']).to be_nil
expect(json_response['labels']).to eq(%w(label label2))
@@ -878,7 +878,7 @@ describe API::Issues, :mailer do
post api("/projects/#{project.id}/issues", user),
title: 'new issue', confidential: true
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['title']).to eq('new issue')
expect(json_response['confidential']).to be_truthy
end
@@ -887,7 +887,7 @@ describe API::Issues, :mailer do
post api("/projects/#{project.id}/issues", user),
title: 'new issue', confidential: 'y'
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['title']).to eq('new issue')
expect(json_response['confidential']).to be_truthy
end
@@ -896,7 +896,7 @@ describe API::Issues, :mailer do
post api("/projects/#{project.id}/issues", user),
title: 'new issue', confidential: false
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['title']).to eq('new issue')
expect(json_response['confidential']).to be_falsy
end
@@ -905,7 +905,7 @@ describe API::Issues, :mailer do
post api("/projects/#{project.id}/issues", user),
title: 'new issue', confidential: 'foo'
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['error']).to eq('confidential is invalid')
end
@@ -923,7 +923,7 @@ describe API::Issues, :mailer do
it "returns a 400 bad request if title not given" do
post api("/projects/#{project.id}/issues", user), labels: 'label, label2'
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it 'allows special label names' do
@@ -941,7 +941,7 @@ describe API::Issues, :mailer do
it 'returns 400 if title is too long' do
post api("/projects/#{project.id}/issues", user),
title: 'g' * 256
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['message']['title']).to eq([
'is too long (maximum is 255 characters)'
])
@@ -985,7 +985,7 @@ describe API::Issues, :mailer do
post api("/projects/#{project.id}/issues", user),
title: 'new issue', due_date: due_date
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['title']).to eq('new issue')
expect(json_response['description']).to be_nil
expect(json_response['due_date']).to eq(due_date)
@@ -998,7 +998,7 @@ describe API::Issues, :mailer do
post api("/projects/#{project.id}/issues", user),
title: 'new issue', labels: 'label, label2', created_at: creation_time
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(Time.parse(json_response['created_at'])).to be_like_time(creation_time)
end
end
@@ -1028,7 +1028,7 @@ describe API::Issues, :mailer do
it "does not create a new project issue" do
expect { post api("/projects/#{project.id}/issues", user), params }.not_to change(Issue, :count)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['message']).to eq({ "error" => "Spam detected" })
spam_logs = SpamLog.all
@@ -1044,7 +1044,7 @@ describe API::Issues, :mailer do
it "updates a project issue" do
put api("/projects/#{project.id}/issues/#{issue.iid}", user),
title: 'updated title'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['title']).to eq('updated title')
end
@@ -1052,13 +1052,13 @@ describe API::Issues, :mailer do
it "returns 404 error if issue iid not found" do
put api("/projects/#{project.id}/issues/44444", user),
title: 'updated title'
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it "returns 404 error if issue id is used instead of the iid" do
put api("/projects/#{project.id}/issues/#{issue.id}", user),
title: 'updated title'
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'allows special label names' do
@@ -1078,33 +1078,33 @@ describe API::Issues, :mailer do
it "returns 403 for non project members" do
put api("/projects/#{project.id}/issues/#{confidential_issue.iid}", non_member),
title: 'updated title'
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
it "returns 403 for project members with guest role" do
put api("/projects/#{project.id}/issues/#{confidential_issue.iid}", guest),
title: 'updated title'
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
it "updates a confidential issue for project members" do
put api("/projects/#{project.id}/issues/#{confidential_issue.iid}", user),
title: 'updated title'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['title']).to eq('updated title')
end
it "updates a confidential issue for author" do
put api("/projects/#{project.id}/issues/#{confidential_issue.iid}", author),
title: 'updated title'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['title']).to eq('updated title')
end
it "updates a confidential issue for admin" do
put api("/projects/#{project.id}/issues/#{confidential_issue.iid}", admin),
title: 'updated title'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['title']).to eq('updated title')
end
@@ -1112,7 +1112,7 @@ describe API::Issues, :mailer do
put api("/projects/#{project.id}/issues/#{issue.iid}", user),
confidential: true
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['confidential']).to be_truthy
end
@@ -1120,7 +1120,7 @@ describe API::Issues, :mailer do
put api("/projects/#{project.id}/issues/#{confidential_issue.iid}", user),
confidential: false
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['confidential']).to be_falsy
end
@@ -1128,7 +1128,7 @@ describe API::Issues, :mailer do
put api("/projects/#{project.id}/issues/#{confidential_issue.iid}", user),
confidential: 'foo'
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['error']).to eq('confidential is invalid')
end
end
@@ -1149,7 +1149,7 @@ describe API::Issues, :mailer do
put api("/projects/#{project.id}/issues/#{issue.iid}", user), params
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['message']).to eq({ "error" => "Spam detected" })
spam_logs = SpamLog.all
@@ -1167,7 +1167,7 @@ describe API::Issues, :mailer do
put api("/projects/#{project.id}/issues/#{issue.iid}", user),
assignee_id: 0
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['assignee']).to be_nil
end
@@ -1176,7 +1176,7 @@ describe API::Issues, :mailer do
put api("/projects/#{project.id}/issues/#{issue.iid}", user),
assignee_id: user2.id
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['assignee']['name']).to eq(user2.name)
end
@@ -1186,7 +1186,7 @@ describe API::Issues, :mailer do
put api("/projects/#{project.id}/issues/#{issue.iid}", user),
assignee_ids: [0]
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['assignees']).to be_empty
end
@@ -1195,7 +1195,7 @@ describe API::Issues, :mailer do
put api("/projects/#{project.id}/issues/#{issue.iid}", user),
assignee_ids: [user2.id]
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['assignees'].first['name']).to eq(user2.name)
end
@@ -1205,7 +1205,7 @@ describe API::Issues, :mailer do
put api("/projects/#{project.id}/issues/#{issue.iid}", user),
assignee_ids: [user2.id, guest.id]
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['assignees'].size).to eq(1)
end
@@ -1219,7 +1219,7 @@ describe API::Issues, :mailer do
it 'does not update labels if not present' do
put api("/projects/#{project.id}/issues/#{issue.iid}", user),
title: 'updated title'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['labels']).to eq([label.title])
end
@@ -1238,14 +1238,14 @@ describe API::Issues, :mailer do
it 'removes all labels' do
put api("/projects/#{project.id}/issues/#{issue.iid}", user), labels: ''
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['labels']).to eq([])
end
it 'updates labels' do
put api("/projects/#{project.id}/issues/#{issue.iid}", user),
labels: 'foo,bar'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['labels']).to include 'foo'
expect(json_response['labels']).to include 'bar'
end
@@ -1267,7 +1267,7 @@ describe API::Issues, :mailer do
it 'returns 400 if title is too long' do
put api("/projects/#{project.id}/issues/#{issue.iid}", user),
title: 'g' * 256
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['message']['title']).to eq([
'is too long (maximum is 255 characters)'
])
@@ -1278,7 +1278,7 @@ describe API::Issues, :mailer do
it "updates a project issue" do
put api("/projects/#{project.id}/issues/#{issue.iid}", user),
labels: 'label2', state_event: "close"
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['labels']).to include 'label2'
expect(json_response['state']).to eq "closed"
@@ -1287,7 +1287,7 @@ describe API::Issues, :mailer do
it 'reopens a project isssue' do
put api("/projects/#{project.id}/issues/#{closed_issue.iid}", user), state_event: 'reopen'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['state']).to eq 'opened'
end
@@ -1297,7 +1297,7 @@ describe API::Issues, :mailer do
put api("/projects/#{project.id}/issues/#{issue.iid}", user),
labels: 'label3', state_event: 'close', updated_at: update_time
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['labels']).to include 'label3'
expect(Time.parse(json_response['updated_at'])).to be_like_time(update_time)
end
@@ -1310,7 +1310,7 @@ describe API::Issues, :mailer do
put api("/projects/#{project.id}/issues/#{issue.iid}", user), due_date: due_date
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['due_date']).to eq(due_date)
end
end
@@ -1318,12 +1318,12 @@ describe API::Issues, :mailer do
describe "DELETE /projects/:id/issues/:issue_iid" do
it "rejects a non member from deleting an issue" do
delete api("/projects/#{project.id}/issues/#{issue.iid}", non_member)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
it "rejects a developer from deleting an issue" do
delete api("/projects/#{project.id}/issues/#{issue.iid}", author)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
context "when the user is project owner" do
@@ -1333,7 +1333,7 @@ describe API::Issues, :mailer do
it "deletes the issue if an admin requests it" do
delete api("/projects/#{project.id}/issues/#{issue.iid}", owner)
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
end
it_behaves_like '412 response' do
@@ -1345,14 +1345,14 @@ describe API::Issues, :mailer do
it 'returns 404 when trying to move an issue' do
delete api("/projects/#{project.id}/issues/123", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
it 'returns 404 when using the issue ID instead of IID' do
delete api("/projects/#{project.id}/issues/#{issue.id}", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -1364,7 +1364,7 @@ describe API::Issues, :mailer do
post api("/projects/#{project.id}/issues/#{issue.iid}/move", user),
to_project_id: target_project.id
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['project_id']).to eq(target_project.id)
end
@@ -1373,7 +1373,7 @@ describe API::Issues, :mailer do
post api("/projects/#{project.id}/issues/#{issue.iid}/move", user),
to_project_id: project.id
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['message']).to eq('Cannot move issue to project it originates from!')
end
end
@@ -1383,7 +1383,7 @@ describe API::Issues, :mailer do
post api("/projects/#{project.id}/issues/#{issue.iid}/move", user),
to_project_id: target_project2.id
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['message']).to eq('Cannot move issue due to insufficient permissions!')
end
end
@@ -1392,7 +1392,7 @@ describe API::Issues, :mailer do
post api("/projects/#{project.id}/issues/#{issue.iid}/move", admin),
to_project_id: target_project2.id
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['project_id']).to eq(target_project2.id)
end
@@ -1401,7 +1401,7 @@ describe API::Issues, :mailer do
post api("/projects/#{project.id}/issues/#{issue.id}/move", user),
to_project_id: target_project.id
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 Issue Not Found')
end
end
@@ -1411,7 +1411,7 @@ describe API::Issues, :mailer do
post api("/projects/#{project.id}/issues/123/move", user),
to_project_id: target_project.id
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 Issue Not Found')
end
end
@@ -1421,7 +1421,7 @@ describe API::Issues, :mailer do
post api("/projects/123/issues/#{issue.iid}/move", user),
to_project_id: target_project.id
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 Project Not Found')
end
end
@@ -1431,7 +1431,7 @@ describe API::Issues, :mailer do
post api("/projects/#{project.id}/issues/#{issue.iid}/move", user),
to_project_id: 123
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -1440,32 +1440,32 @@ describe API::Issues, :mailer do
it 'subscribes to an issue' do
post api("/projects/#{project.id}/issues/#{issue.iid}/subscribe", user2)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['subscribed']).to eq(true)
end
it 'returns 304 if already subscribed' do
post api("/projects/#{project.id}/issues/#{issue.iid}/subscribe", user)
- expect(response).to have_http_status(304)
+ expect(response).to have_gitlab_http_status(304)
end
it 'returns 404 if the issue is not found' do
post api("/projects/#{project.id}/issues/123/subscribe", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'returns 404 if the issue ID is used instead of the iid' do
post api("/projects/#{project.id}/issues/#{issue.id}/subscribe", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'returns 404 if the issue is confidential' do
post api("/projects/#{project.id}/issues/#{confidential_issue.iid}/subscribe", non_member)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -1473,32 +1473,32 @@ describe API::Issues, :mailer do
it 'unsubscribes from an issue' do
post api("/projects/#{project.id}/issues/#{issue.iid}/unsubscribe", user)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['subscribed']).to eq(false)
end
it 'returns 304 if not subscribed' do
post api("/projects/#{project.id}/issues/#{issue.iid}/unsubscribe", user2)
- expect(response).to have_http_status(304)
+ expect(response).to have_gitlab_http_status(304)
end
it 'returns 404 if the issue is not found' do
post api("/projects/#{project.id}/issues/123/unsubscribe", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'returns 404 if using the issue ID instead of iid' do
post api("/projects/#{project.id}/issues/#{issue.id}/unsubscribe", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'returns 404 if the issue is confidential' do
post api("/projects/#{project.id}/issues/#{confidential_issue.iid}/unsubscribe", non_member)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -1539,7 +1539,7 @@ describe API::Issues, :mailer do
it "returns 404 when issue doesn't exists" do
get api("/projects/#{project.id}/issues/9999/closed_by", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -1549,7 +1549,7 @@ describe API::Issues, :mailer do
it 'exposes known attributes' do
get api("/projects/#{project.id}/issues/#{issue.iid}/user_agent_detail", admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['user_agent']).to eq(user_agent_detail.user_agent)
expect(json_response['ip_address']).to eq(user_agent_detail.ip_address)
expect(json_response['akismet_submitted']).to eq(user_agent_detail.submitted)
@@ -1558,12 +1558,12 @@ describe API::Issues, :mailer do
it "returns unautorized for non-admin users" do
get api("/projects/#{project.id}/issues/#{issue.iid}/user_agent_detail", user)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
def expect_paginated_array_response(size: nil)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(size) if size
diff --git a/spec/requests/api/jobs_spec.rb b/spec/requests/api/jobs_spec.rb
index 2d7cc1a1798..3b7b9c889e7 100644
--- a/spec/requests/api/jobs_spec.rb
+++ b/spec/requests/api/jobs_spec.rb
@@ -31,7 +31,7 @@ describe API::Jobs do
context 'authorized user' do
it 'returns project jobs' do
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
end
@@ -55,7 +55,7 @@ describe API::Jobs do
let(:query) { { 'scope' => 'pending' } }
it do
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
end
end
@@ -64,7 +64,7 @@ describe API::Jobs do
let(:query) { { scope: %w(pending running) } }
it do
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
end
end
@@ -72,7 +72,7 @@ describe API::Jobs do
context 'respond 400 when scope contains invalid state' do
let(:query) { { scope: %w(unknown running) } }
- it { expect(response).to have_http_status(400) }
+ it { expect(response).to have_gitlab_http_status(400) }
end
end
@@ -80,7 +80,7 @@ describe API::Jobs do
let(:api_user) { nil }
it 'does not return project jobs' do
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
end
@@ -94,7 +94,7 @@ describe API::Jobs do
context 'authorized user' do
it 'returns pipeline jobs' do
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
end
@@ -118,7 +118,7 @@ describe API::Jobs do
let(:query) { { 'scope' => 'pending' } }
it do
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
end
end
@@ -127,7 +127,7 @@ describe API::Jobs do
let(:query) { { scope: %w(pending running) } }
it do
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
end
end
@@ -135,7 +135,7 @@ describe API::Jobs do
context 'respond 400 when scope contains invalid state' do
let(:query) { { scope: %w(unknown running) } }
- it { expect(response).to have_http_status(400) }
+ it { expect(response).to have_gitlab_http_status(400) }
end
context 'jobs in different pipelines' do
@@ -152,7 +152,7 @@ describe API::Jobs do
let(:api_user) { nil }
it 'does not return jobs' do
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
end
@@ -164,7 +164,7 @@ describe API::Jobs do
context 'authorized user' do
it 'returns specific job data' do
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['name']).to eq('test')
end
@@ -183,7 +183,7 @@ describe API::Jobs do
let(:api_user) { nil }
it 'does not return specific job data' do
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
end
@@ -207,7 +207,7 @@ describe API::Jobs do
get_artifact_file(artifact)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
end
@@ -219,7 +219,7 @@ describe API::Jobs do
get_artifact_file(artifact)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -231,7 +231,7 @@ describe API::Jobs do
get_artifact_file(artifact)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -244,7 +244,7 @@ describe API::Jobs do
get_artifact_file(artifact)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response.headers)
.to include('Content-Type' => 'application/json',
'Gitlab-Workhorse-Send-Data' => /artifacts-entry/)
@@ -256,7 +256,7 @@ describe API::Jobs do
it 'does not return job artifact file' do
get_artifact_file('some/artifact')
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -281,7 +281,7 @@ describe API::Jobs do
end
it 'returns specific job artifacts' do
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response.headers).to include(download_headers)
expect(response.body).to match_file(job.artifacts_file.file.file)
end
@@ -292,13 +292,13 @@ describe API::Jobs do
it 'hides artifacts and rejects request' do
expect(project).to be_private
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
it 'does not return job artifacts if not uploaded' do
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -323,7 +323,7 @@ describe API::Jobs do
it 'does not find a resource in a private project' do
expect(project).to be_private
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -335,13 +335,13 @@ describe API::Jobs do
end
it 'gives 403' do
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
context 'non-existing job' do
shared_examples 'not found' do
- it { expect(response).to have_http_status(:not_found) }
+ it { expect(response).to have_gitlab_http_status(:not_found) }
end
context 'has no such ref' do
@@ -369,7 +369,7 @@ describe API::Jobs do
"attachment; filename=#{job.artifacts_file.filename}" }
end
- it { expect(response).to have_http_status(200) }
+ it { expect(response).to have_gitlab_http_status(200) }
it { expect(response.headers).to include(download_headers) }
end
@@ -410,7 +410,7 @@ describe API::Jobs do
context 'authorized user' do
it 'returns specific job trace' do
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response.body).to eq(job.trace.raw)
end
end
@@ -419,7 +419,7 @@ describe API::Jobs do
let(:api_user) { nil }
it 'does not return specific job trace' do
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
end
@@ -432,7 +432,7 @@ describe API::Jobs do
context 'authorized user' do
context 'user with :update_build persmission' do
it 'cancels running or pending job' do
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(project.builds.first.status).to eq('canceled')
end
end
@@ -441,7 +441,7 @@ describe API::Jobs do
let(:api_user) { reporter }
it 'does not cancel job' do
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
end
@@ -450,7 +450,7 @@ describe API::Jobs do
let(:api_user) { nil }
it 'does not cancel job' do
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
end
@@ -465,7 +465,7 @@ describe API::Jobs do
context 'authorized user' do
context 'user with :update_build permission' do
it 'retries non-running job' do
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(project.builds.first.status).to eq('canceled')
expect(json_response['status']).to eq('pending')
end
@@ -475,7 +475,7 @@ describe API::Jobs do
let(:api_user) { reporter }
it 'does not retry job' do
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
end
@@ -484,7 +484,7 @@ describe API::Jobs do
let(:api_user) { nil }
it 'does not retry job' do
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
end
@@ -498,7 +498,7 @@ describe API::Jobs do
let(:job) { create(:ci_build, :trace, :artifacts, :success, project: project, pipeline: pipeline) }
it 'erases job content' do
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(job).not_to have_trace
expect(job.artifacts_file.exists?).to be_falsy
expect(job.artifacts_metadata.exists?).to be_falsy
@@ -516,7 +516,7 @@ describe API::Jobs do
let(:job) { create(:ci_build, :trace, project: project, pipeline: pipeline) }
it 'responds with forbidden' do
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
end
@@ -533,7 +533,7 @@ describe API::Jobs do
end
it 'keeps artifacts' do
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(job.reload.artifacts_expire_at).to be_nil
end
end
@@ -542,7 +542,7 @@ describe API::Jobs do
let(:job) { create(:ci_build, project: project, pipeline: pipeline) }
it 'responds with not found' do
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -557,7 +557,7 @@ describe API::Jobs do
context 'when user is authorized to trigger a manual action' do
it 'plays the job' do
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['user']['id']).to eq(user.id)
expect(json_response['id']).to eq(job.id)
expect(job.reload).to be_pending
@@ -570,7 +570,7 @@ describe API::Jobs do
it 'does not trigger a manual action' do
expect(job.reload).to be_manual
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -579,7 +579,7 @@ describe API::Jobs do
it 'does not trigger a manual action' do
expect(job.reload).to be_manual
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
end
@@ -587,7 +587,7 @@ describe API::Jobs do
context 'on a non-playable job' do
it 'returns a status code 400, Bad Request' do
- expect(response).to have_http_status 400
+ expect(response).to have_gitlab_http_status 400
expect(response.body).to match("Unplayable Job")
end
end
diff --git a/spec/requests/api/keys_spec.rb b/spec/requests/api/keys_spec.rb
index f534332ca6c..3c4719964b6 100644
--- a/spec/requests/api/keys_spec.rb
+++ b/spec/requests/api/keys_spec.rb
@@ -10,14 +10,14 @@ describe API::Keys do
context 'when unauthenticated' do
it 'returns authentication error' do
get api("/keys/#{key.id}")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
context 'when authenticated' do
it 'returns 404 for non-existing key' do
get api('/keys/999999', admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 Not found')
end
@@ -25,7 +25,7 @@ describe API::Keys do
user.keys << key
user.save
get api("/keys/#{key.id}", admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['title']).to eq(key.title)
expect(json_response['user']['id']).to eq(user.id)
expect(json_response['user']['username']).to eq(user.username)
diff --git a/spec/requests/api/labels_spec.rb b/spec/requests/api/labels_spec.rb
index b231fdea2a3..3498e5bc8d9 100644
--- a/spec/requests/api/labels_spec.rb
+++ b/spec/requests/api/labels_spec.rb
@@ -27,7 +27,7 @@ describe API::Labels do
get api("/projects/#{project.id}/labels", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.size).to eq(3)
@@ -75,7 +75,7 @@ describe API::Labels do
description: 'test',
priority: 2
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['name']).to eq('Foo')
expect(json_response['color']).to eq('#FFAABB')
expect(json_response['description']).to eq('test')
@@ -109,19 +109,19 @@ describe API::Labels do
it 'returns a 400 bad request if name not given' do
post api("/projects/#{project.id}/labels", user), color: '#FFAABB'
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it 'returns a 400 bad request if color not given' do
post api("/projects/#{project.id}/labels", user), name: 'Foobar'
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it 'returns 400 for invalid color' do
post api("/projects/#{project.id}/labels", user),
name: 'Foo',
color: '#FFAA'
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['message']['color']).to eq(['must be a valid color code'])
end
@@ -129,7 +129,7 @@ describe API::Labels do
post api("/projects/#{project.id}/labels", user),
name: 'Foo',
color: '#FFAAFFFF'
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['message']['color']).to eq(['must be a valid color code'])
end
@@ -137,7 +137,7 @@ describe API::Labels do
post api("/projects/#{project.id}/labels", user),
name: ',',
color: '#FFAABB'
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['message']['title']).to eq(['is invalid'])
end
@@ -150,7 +150,7 @@ describe API::Labels do
name: group_label.name,
color: '#FFAABB'
- expect(response).to have_http_status(409)
+ expect(response).to have_gitlab_http_status(409)
expect(json_response['message']).to eq('Label already exists')
end
@@ -160,14 +160,14 @@ describe API::Labels do
color: '#FFAAFFFF',
priority: 'foo'
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it 'returns 409 if label already exists in project' do
post api("/projects/#{project.id}/labels", user),
name: 'label1',
color: '#FFAABB'
- expect(response).to have_http_status(409)
+ expect(response).to have_gitlab_http_status(409)
expect(json_response['message']).to eq('Label already exists')
end
end
@@ -176,18 +176,18 @@ describe API::Labels do
it 'returns 204 for existing label' do
delete api("/projects/#{project.id}/labels", user), name: 'label1'
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
end
it 'returns 404 for non existing label' do
delete api("/projects/#{project.id}/labels", user), name: 'label2'
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 Label Not Found')
end
it 'returns 400 for wrong parameters' do
delete api("/projects/#{project.id}/labels", user)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it_behaves_like '412 response' do
@@ -203,7 +203,7 @@ describe API::Labels do
new_name: 'New Label',
color: '#FFFFFF',
description: 'test'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['name']).to eq('New Label')
expect(json_response['color']).to eq('#FFFFFF')
expect(json_response['description']).to eq('test')
@@ -213,7 +213,7 @@ describe API::Labels do
put api("/projects/#{project.id}/labels", user),
name: 'label1',
new_name: 'New Label'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['name']).to eq('New Label')
expect(json_response['color']).to eq(label1.color)
end
@@ -222,7 +222,7 @@ describe API::Labels do
put api("/projects/#{project.id}/labels", user),
name: 'label1',
color: '#FFFFFF'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['name']).to eq(label1.name)
expect(json_response['color']).to eq('#FFFFFF')
end
@@ -232,7 +232,7 @@ describe API::Labels do
name: 'bug',
description: 'test'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['name']).to eq(priority_label.name)
expect(json_response['description']).to eq('test')
expect(json_response['priority']).to eq(3)
@@ -272,18 +272,18 @@ describe API::Labels do
put api("/projects/#{project.id}/labels", user),
name: 'label2',
new_name: 'label3'
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'returns 400 if no label name given' do
put api("/projects/#{project.id}/labels", user), new_name: 'label2'
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['error']).to eq('name is missing')
end
it 'returns 400 if no new parameters given' do
put api("/projects/#{project.id}/labels", user), name: 'label1'
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['error']).to eq('new_name, color, description, priority are missing, '\
'at least one parameter must be provided')
end
@@ -293,7 +293,7 @@ describe API::Labels do
name: 'label1',
new_name: ',',
color: '#FFFFFF'
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['message']['title']).to eq(['is invalid'])
end
@@ -301,7 +301,7 @@ describe API::Labels do
put api("/projects/#{project.id}/labels", user),
name: 'label1',
color: '#FF'
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['message']['color']).to eq(['must be a valid color code'])
end
@@ -309,7 +309,7 @@ describe API::Labels do
post api("/projects/#{project.id}/labels", user),
name: 'Foo',
color: '#FFAAFFFF'
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['message']['color']).to eq(['must be a valid color code'])
end
@@ -318,7 +318,7 @@ describe API::Labels do
name: 'Foo',
priority: 'foo'
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
end
@@ -327,7 +327,7 @@ describe API::Labels do
it "subscribes to the label" do
post api("/projects/#{project.id}/labels/#{label1.title}/subscribe", user)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response["name"]).to eq(label1.title)
expect(json_response["subscribed"]).to be_truthy
end
@@ -337,7 +337,7 @@ describe API::Labels do
it "subscribes to the label" do
post api("/projects/#{project.id}/labels/#{label1.id}/subscribe", user)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response["name"]).to eq(label1.title)
expect(json_response["subscribed"]).to be_truthy
end
@@ -351,7 +351,7 @@ describe API::Labels do
it "returns 304" do
post api("/projects/#{project.id}/labels/#{label1.id}/subscribe", user)
- expect(response).to have_http_status(304)
+ expect(response).to have_gitlab_http_status(304)
end
end
@@ -359,7 +359,7 @@ describe API::Labels do
it "returns 404 error" do
post api("/projects/#{project.id}/labels/1234/subscribe", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -373,7 +373,7 @@ describe API::Labels do
it "unsubscribes from the label" do
post api("/projects/#{project.id}/labels/#{label1.title}/unsubscribe", user)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response["name"]).to eq(label1.title)
expect(json_response["subscribed"]).to be_falsey
end
@@ -383,7 +383,7 @@ describe API::Labels do
it "unsubscribes from the label" do
post api("/projects/#{project.id}/labels/#{label1.id}/unsubscribe", user)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response["name"]).to eq(label1.title)
expect(json_response["subscribed"]).to be_falsey
end
@@ -397,7 +397,7 @@ describe API::Labels do
it "returns 304" do
post api("/projects/#{project.id}/labels/#{label1.id}/unsubscribe", user)
- expect(response).to have_http_status(304)
+ expect(response).to have_gitlab_http_status(304)
end
end
@@ -405,7 +405,7 @@ describe API::Labels do
it "returns 404 error" do
post api("/projects/#{project.id}/labels/1234/unsubscribe", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
diff --git a/spec/requests/api/lint_spec.rb b/spec/requests/api/lint_spec.rb
index df7c91b5bc1..e3065840e6f 100644
--- a/spec/requests/api/lint_spec.rb
+++ b/spec/requests/api/lint_spec.rb
@@ -10,7 +10,7 @@ describe API::Lint do
it 'passes validation' do
post api('/ci/lint'), { content: yaml_content }
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Hash
expect(json_response['status']).to eq('valid')
expect(json_response['errors']).to eq([])
@@ -21,7 +21,7 @@ describe API::Lint do
it 'responds with errors about invalid syntax' do
post api('/ci/lint'), { content: 'invalid content' }
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['status']).to eq('invalid')
expect(json_response['errors']).to eq(['Invalid configuration format'])
end
@@ -29,7 +29,7 @@ describe API::Lint do
it "responds with errors about invalid configuration" do
post api('/ci/lint'), { content: '{ image: "ruby:2.1", services: ["postgres"] }' }
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['status']).to eq('invalid')
expect(json_response['errors']).to eq(['jobs config should contain at least one visible job'])
end
@@ -39,7 +39,7 @@ describe API::Lint do
it 'responds with validation error about missing content' do
post api('/ci/lint')
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['error']).to eq('content is missing')
end
end
diff --git a/spec/requests/api/members_spec.rb b/spec/requests/api/members_spec.rb
index d3bae8d2888..3349e396ab8 100644
--- a/spec/requests/api/members_spec.rb
+++ b/spec/requests/api/members_spec.rb
@@ -35,7 +35,7 @@ describe API::Members do
get api("/#{source_type.pluralize}/#{source.id}/members", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.size).to eq(2)
@@ -49,7 +49,7 @@ describe API::Members do
get api("/#{source_type.pluralize}/#{source.id}/members", developer)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.size).to eq(2)
@@ -59,7 +59,7 @@ describe API::Members do
it 'finds members with query string' do
get api("/#{source_type.pluralize}/#{source.id}/members", developer), query: master.username
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.count).to eq(1)
@@ -81,7 +81,7 @@ describe API::Members do
user = public_send(type)
get api("/#{source_type.pluralize}/#{source.id}/members/#{developer.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
# User attributes
expect(json_response['id']).to eq(developer.id)
expect(json_response['name']).to eq(developer.name)
@@ -116,7 +116,7 @@ describe API::Members do
post api("/#{source_type.pluralize}/#{source.id}/members", user),
user_id: access_requester.id, access_level: Member::MASTER
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
end
@@ -129,7 +129,7 @@ describe API::Members do
post api("/#{source_type.pluralize}/#{source.id}/members", master),
user_id: access_requester.id, access_level: Member::MASTER
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
end.to change { source.members.count }.by(1)
expect(source.requesters.count).to eq(0)
expect(json_response['id']).to eq(access_requester.id)
@@ -142,7 +142,7 @@ describe API::Members do
post api("/#{source_type.pluralize}/#{source.id}/members", master),
user_id: stranger.id, access_level: Member::DEVELOPER, expires_at: '2016-08-05'
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
end.to change { source.members.count }.by(1)
expect(json_response['id']).to eq(stranger.id)
expect(json_response['access_level']).to eq(Member::DEVELOPER)
@@ -154,28 +154,28 @@ describe API::Members do
post api("/#{source_type.pluralize}/#{source.id}/members", master),
user_id: master.id, access_level: Member::MASTER
- expect(response).to have_http_status(409)
+ expect(response).to have_gitlab_http_status(409)
end
it 'returns 400 when user_id is not given' do
post api("/#{source_type.pluralize}/#{source.id}/members", master),
access_level: Member::MASTER
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it 'returns 400 when access_level is not given' do
post api("/#{source_type.pluralize}/#{source.id}/members", master),
user_id: stranger.id
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it 'returns 400 when access_level is not valid' do
post api("/#{source_type.pluralize}/#{source.id}/members", master),
user_id: stranger.id, access_level: 1234
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
end
end
@@ -197,7 +197,7 @@ describe API::Members do
put api("/#{source_type.pluralize}/#{source.id}/members/#{developer.id}", user),
access_level: Member::MASTER
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
end
@@ -208,7 +208,7 @@ describe API::Members do
put api("/#{source_type.pluralize}/#{source.id}/members/#{developer.id}", master),
access_level: Member::MASTER, expires_at: '2016-08-05'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['id']).to eq(developer.id)
expect(json_response['access_level']).to eq(Member::MASTER)
expect(json_response['expires_at']).to eq('2016-08-05')
@@ -219,20 +219,20 @@ describe API::Members do
put api("/#{source_type.pluralize}/#{source.id}/members/123", master),
access_level: Member::MASTER
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'returns 400 when access_level is not given' do
put api("/#{source_type.pluralize}/#{source.id}/members/#{developer.id}", master)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it 'returns 400 when access level is not valid' do
put api("/#{source_type.pluralize}/#{source.id}/members/#{developer.id}", master),
access_level: 1234
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
end
end
@@ -250,7 +250,7 @@ describe API::Members do
user = public_send(type)
delete api("/#{source_type.pluralize}/#{source.id}/members/#{developer.id}", user)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
end
@@ -261,7 +261,7 @@ describe API::Members do
expect do
delete api("/#{source_type.pluralize}/#{source.id}/members/#{developer.id}", developer)
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
end.to change { source.members.count }.by(-1)
end
end
@@ -272,7 +272,7 @@ describe API::Members do
expect do
delete api("/#{source_type.pluralize}/#{source.id}/members/#{access_requester.id}", master)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end.not_to change { source.requesters.count }
end
end
@@ -281,7 +281,7 @@ describe API::Members do
expect do
delete api("/#{source_type.pluralize}/#{source.id}/members/#{developer.id}", master)
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
end.to change { source.members.count }.by(-1)
end
@@ -293,7 +293,7 @@ describe API::Members do
it 'returns 404 if member does not exist' do
delete api("/#{source_type.pluralize}/#{source.id}/members/123", master)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -344,7 +344,7 @@ describe API::Members do
post api("/projects/#{project.id}/members", master),
user_id: stranger.id, access_level: Member::OWNER
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end.to change { project.members.count }.by(0)
end
end
diff --git a/spec/requests/api/merge_request_diffs_spec.rb b/spec/requests/api/merge_request_diffs_spec.rb
index d9da94d4713..bf4c8443b23 100644
--- a/spec/requests/api/merge_request_diffs_spec.rb
+++ b/spec/requests/api/merge_request_diffs_spec.rb
@@ -26,12 +26,12 @@ describe API::MergeRequestDiffs, 'MergeRequestDiffs' do
it 'returns a 404 when merge_request id is used instead of the iid' do
get api("/projects/#{project.id}/merge_requests/#{merge_request.id}/versions", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'returns a 404 when merge_request_iid not found' do
get api("/projects/#{project.id}/merge_requests/999/versions", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -49,17 +49,17 @@ describe API::MergeRequestDiffs, 'MergeRequestDiffs' do
it 'returns a 404 when merge_request id is used instead of the iid' do
get api("/projects/#{project.id}/merge_requests/#{merge_request.id}/versions/#{merge_request_diff.id}", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'returns a 404 when merge_request version_id is not found' do
get api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/versions/999", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'returns a 404 when merge_request_iid is not found' do
get api("/projects/#{project.id}/merge_requests/12345/versions/#{merge_request_diff.id}", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
diff --git a/spec/requests/api/merge_requests_spec.rb b/spec/requests/api/merge_requests_spec.rb
index 5e66e1607ba..024cfe8b372 100644
--- a/spec/requests/api/merge_requests_spec.rb
+++ b/spec/requests/api/merge_requests_spec.rb
@@ -33,26 +33,26 @@ describe API::MergeRequests do
it 'returns an array of all merge requests' do
get api('/merge_requests', user), scope: 'all'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
end
it "returns authentication error without any scope" do
get api("/merge_requests")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
it "returns authentication error when scope is assigned-to-me" do
get api("/merge_requests"), scope: 'assigned-to-me'
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
it "returns authentication error when scope is created-by-me" do
get api("/merge_requests"), scope: 'created-by-me'
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
@@ -158,7 +158,7 @@ describe API::MergeRequests do
it 'returns merge requests for public projects' do
get api("/projects/#{project.id}/merge_requests")
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
end
@@ -166,7 +166,7 @@ describe API::MergeRequests do
project = create(:project, :private)
get api("/projects/#{project.id}/merge_requests")
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -1061,6 +1061,30 @@ describe API::MergeRequests do
end
end
+ describe 'POST :id/merge_requests/:merge_request_iid/cancel_merge_when_pipeline_succeeds' do
+ before do
+ ::MergeRequests::MergeWhenPipelineSucceedsService.new(merge_request.target_project, user).execute(merge_request)
+ end
+
+ it 'removes the merge_when_pipeline_succeeds status' do
+ post api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/cancel_merge_when_pipeline_succeeds", user)
+
+ expect(response).to have_gitlab_http_status(201)
+ end
+
+ it 'returns 404 if the merge request is not found' do
+ post api("/projects/#{project.id}/merge_requests/123/merge_when_pipeline_succeeds", user)
+
+ expect(response).to have_gitlab_http_status(404)
+ end
+
+ it 'returns 404 if the merge request id is used instead of iid' do
+ post api("/projects/#{project.id}/merge_requests/#{merge_request.id}/merge_when_pipeline_succeeds", user)
+
+ expect(response).to have_gitlab_http_status(404)
+ end
+ end
+
describe 'Time tracking' do
let(:issuable) { merge_request }
diff --git a/spec/requests/api/namespaces_spec.rb b/spec/requests/api/namespaces_spec.rb
index 26cf653ca8e..e60716d46d7 100644
--- a/spec/requests/api/namespaces_spec.rb
+++ b/spec/requests/api/namespaces_spec.rb
@@ -10,7 +10,7 @@ describe API::Namespaces do
context "when unauthenticated" do
it "returns authentication error" do
get api("/namespaces")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
@@ -21,7 +21,7 @@ describe API::Namespaces do
group_kind_json_response = json_response.find { |resource| resource['kind'] == 'group' }
user_kind_json_response = json_response.find { |resource| resource['kind'] == 'user' }
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(group_kind_json_response.keys).to contain_exactly('id', 'kind', 'name', 'path', 'full_path',
'parent_id', 'members_count_with_descendants')
@@ -32,7 +32,7 @@ describe API::Namespaces do
it "admin: returns an array of all namespaces" do
get api("/namespaces", admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(Namespace.count)
@@ -41,7 +41,7 @@ describe API::Namespaces do
it "admin: returns an array of matched namespaces" do
get api("/namespaces?search=#{group2.name}", admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
@@ -75,7 +75,7 @@ describe API::Namespaces do
it "user: returns an array of namespaces" do
get api("/namespaces", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
@@ -84,7 +84,7 @@ describe API::Namespaces do
it "admin: returns an array of matched namespaces" do
get api("/namespaces?search=#{user.username}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
diff --git a/spec/requests/api/notes_spec.rb b/spec/requests/api/notes_spec.rb
index fb440fa551c..784070db173 100644
--- a/spec/requests/api/notes_spec.rb
+++ b/spec/requests/api/notes_spec.rb
@@ -37,7 +37,7 @@ describe API::Notes do
it "returns an array of issue notes" do
get api("/projects/#{project.id}/issues/#{issue.iid}/notes", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.first['body']).to eq(issue_note.note)
@@ -46,14 +46,14 @@ describe API::Notes do
it "returns a 404 error when issue id not found" do
get api("/projects/#{project.id}/issues/12345/notes", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
context "and current user cannot view the notes" do
it "returns an empty array" do
get api("/projects/#{ext_proj.id}/issues/#{ext_issue.iid}/notes", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response).to be_empty
@@ -67,7 +67,7 @@ describe API::Notes do
it "returns 404" do
get api("/projects/#{ext_proj.id}/issues/#{ext_issue.iid}/notes", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -75,7 +75,7 @@ describe API::Notes do
it "returns an empty array" do
get api("/projects/#{ext_proj.id}/issues/#{ext_issue.iid}/notes", private_user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.first['body']).to eq(cross_reference_note.note)
@@ -88,7 +88,7 @@ describe API::Notes do
it "returns an array of snippet notes" do
get api("/projects/#{project.id}/snippets/#{snippet.id}/notes", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.first['body']).to eq(snippet_note.note)
@@ -97,13 +97,13 @@ describe API::Notes do
it "returns a 404 error when snippet id not found" do
get api("/projects/#{project.id}/snippets/42/notes", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it "returns 404 when not authorized" do
get api("/projects/#{project.id}/snippets/#{snippet.id}/notes", private_user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -111,7 +111,7 @@ describe API::Notes do
it "returns an array of merge_requests notes" do
get api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/notes", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.first['body']).to eq(merge_request_note.note)
@@ -120,13 +120,13 @@ describe API::Notes do
it "returns a 404 error if merge request id not found" do
get api("/projects/#{project.id}/merge_requests/4444/notes", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it "returns 404 when not authorized" do
get api("/projects/#{project.id}/merge_requests/4444/notes", private_user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -136,21 +136,21 @@ describe API::Notes do
it "returns an issue note by id" do
get api("/projects/#{project.id}/issues/#{issue.iid}/notes/#{issue_note.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['body']).to eq(issue_note.note)
end
it "returns a 404 error if issue note not found" do
get api("/projects/#{project.id}/issues/#{issue.iid}/notes/12345", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
context "and current user cannot view the note" do
it "returns a 404 error" do
get api("/projects/#{ext_proj.id}/issues/#{ext_issue.iid}/notes/#{cross_reference_note.id}", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
context "when issue is confidential" do
@@ -161,7 +161,7 @@ describe API::Notes do
it "returns 404" do
get api("/projects/#{project.id}/issues/#{issue.iid}/notes/#{issue_note.id}", private_user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -169,7 +169,7 @@ describe API::Notes do
it "returns an issue note by id" do
get api("/projects/#{ext_proj.id}/issues/#{ext_issue.iid}/notes/#{cross_reference_note.id}", private_user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['body']).to eq(cross_reference_note.note)
end
end
@@ -180,14 +180,14 @@ describe API::Notes do
it "returns a snippet note by id" do
get api("/projects/#{project.id}/snippets/#{snippet.id}/notes/#{snippet_note.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['body']).to eq(snippet_note.note)
end
it "returns a 404 error if snippet note not found" do
get api("/projects/#{project.id}/snippets/#{snippet.id}/notes/12345", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -197,7 +197,7 @@ describe API::Notes do
it "creates a new issue note" do
post api("/projects/#{project.id}/issues/#{issue.iid}/notes", user), body: 'hi!'
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['body']).to eq('hi!')
expect(json_response['author']['username']).to eq(user.username)
end
@@ -205,13 +205,13 @@ describe API::Notes do
it "returns a 400 bad request error if body not given" do
post api("/projects/#{project.id}/issues/#{issue.iid}/notes", user)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it "returns a 401 unauthorized error if user not authenticated" do
post api("/projects/#{project.id}/issues/#{issue.iid}/notes"), body: 'hi!'
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
context 'when an admin or owner makes the request' do
@@ -220,7 +220,7 @@ describe API::Notes do
post api("/projects/#{project.id}/issues/#{issue.iid}/notes", user),
body: 'hi!', created_at: creation_time
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['body']).to eq('hi!')
expect(json_response['author']['username']).to eq(user.username)
expect(Time.parse(json_response['created_at'])).to be_like_time(creation_time)
@@ -233,7 +233,7 @@ describe API::Notes do
it 'creates a new issue note' do
post api("/projects/#{project.id}/issues/#{issue2.iid}/notes", user), body: ':+1:'
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['body']).to eq(':+1:')
end
end
@@ -242,7 +242,7 @@ describe API::Notes do
it 'creates a new issue note' do
post api("/projects/#{project.id}/issues/#{issue.iid}/notes", user), body: ':+1:'
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['body']).to eq(':+1:')
end
end
@@ -252,7 +252,7 @@ describe API::Notes do
it "creates a new snippet note" do
post api("/projects/#{project.id}/snippets/#{snippet.id}/notes", user), body: 'hi!'
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['body']).to eq('hi!')
expect(json_response['author']['username']).to eq(user.username)
end
@@ -260,13 +260,13 @@ describe API::Notes do
it "returns a 400 bad request error if body not given" do
post api("/projects/#{project.id}/snippets/#{snippet.id}/notes", user)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it "returns a 401 unauthorized error if user not authenticated" do
post api("/projects/#{project.id}/snippets/#{snippet.id}/notes"), body: 'hi!'
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
@@ -278,7 +278,7 @@ describe API::Notes do
post api("/projects/#{project.id}/issues/#{issue.iid}/notes", user),
body: 'Foo'
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -314,7 +314,7 @@ describe API::Notes do
it 'returns 200 status' do
subject
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
end
it 'creates a new note' do
@@ -328,7 +328,7 @@ describe API::Notes do
it 'returns 403 status' do
subject
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
it 'does not create a new note' do
@@ -352,7 +352,7 @@ describe API::Notes do
put api("/projects/#{project.id}/issues/#{issue.iid}/"\
"notes/#{issue_note.id}", user), body: 'Hello!'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['body']).to eq('Hello!')
end
@@ -360,14 +360,14 @@ describe API::Notes do
put api("/projects/#{project.id}/issues/#{issue.iid}/notes/12345", user),
body: 'Hello!'
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'returns a 400 bad request error if body not given' do
put api("/projects/#{project.id}/issues/#{issue.iid}/"\
"notes/#{issue_note.id}", user)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
end
@@ -376,7 +376,7 @@ describe API::Notes do
put api("/projects/#{project.id}/snippets/#{snippet.id}/"\
"notes/#{snippet_note.id}", user), body: 'Hello!'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['body']).to eq('Hello!')
end
@@ -384,7 +384,7 @@ describe API::Notes do
put api("/projects/#{project.id}/snippets/#{snippet.id}/"\
"notes/12345", user), body: "Hello!"
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -393,7 +393,7 @@ describe API::Notes do
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/"\
"notes/#{merge_request_note.id}", user), body: 'Hello!'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['body']).to eq('Hello!')
end
@@ -401,7 +401,7 @@ describe API::Notes do
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/"\
"notes/12345", user), body: "Hello!"
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -412,17 +412,17 @@ describe API::Notes do
delete api("/projects/#{project.id}/issues/#{issue.iid}/"\
"notes/#{issue_note.id}", user)
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
# Check if note is really deleted
delete api("/projects/#{project.id}/issues/#{issue.iid}/"\
"notes/#{issue_note.id}", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'returns a 404 error when note id not found' do
delete api("/projects/#{project.id}/issues/#{issue.iid}/notes/12345", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it_behaves_like '412 response' do
@@ -435,18 +435,18 @@ describe API::Notes do
delete api("/projects/#{project.id}/snippets/#{snippet.id}/"\
"notes/#{snippet_note.id}", user)
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
# Check if note is really deleted
delete api("/projects/#{project.id}/snippets/#{snippet.id}/"\
"notes/#{snippet_note.id}", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'returns a 404 error when note id not found' do
delete api("/projects/#{project.id}/snippets/#{snippet.id}/"\
"notes/12345", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it_behaves_like '412 response' do
@@ -459,18 +459,18 @@ describe API::Notes do
delete api("/projects/#{project.id}/merge_requests/"\
"#{merge_request.iid}/notes/#{merge_request_note.id}", user)
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
# Check if note is really deleted
delete api("/projects/#{project.id}/merge_requests/"\
"#{merge_request.iid}/notes/#{merge_request_note.id}", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'returns a 404 error when note id not found' do
delete api("/projects/#{project.id}/merge_requests/"\
"#{merge_request.iid}/notes/12345", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it_behaves_like '412 response' do
diff --git a/spec/requests/api/notification_settings_spec.rb b/spec/requests/api/notification_settings_spec.rb
index 7968659a1ec..3273cd26690 100644
--- a/spec/requests/api/notification_settings_spec.rb
+++ b/spec/requests/api/notification_settings_spec.rb
@@ -9,7 +9,7 @@ describe API::NotificationSettings do
it "returns global notification settings for the current user" do
get api("/notification_settings", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_a Hash
expect(json_response['notification_email']).to eq(user.notification_email)
expect(json_response['level']).to eq(user.global_notification_setting.level)
@@ -22,7 +22,7 @@ describe API::NotificationSettings do
it "updates global notification settings for the current user" do
put api("/notification_settings", user), { level: 'watch', notification_email: email.email }
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['notification_email']).to eq(email.email)
expect(user.reload.notification_email).to eq(email.email)
expect(json_response['level']).to eq(user.reload.global_notification_setting.level)
@@ -33,7 +33,7 @@ describe API::NotificationSettings do
it "fails on non-user email address" do
put api("/notification_settings", user), { notification_email: 'invalid@example.com' }
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
end
@@ -41,7 +41,7 @@ describe API::NotificationSettings do
it "returns group level notification settings for the current user" do
get api("/groups/#{group.id}/notification_settings", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_a Hash
expect(json_response['level']).to eq(user.notification_settings_for(group).level)
end
@@ -51,7 +51,7 @@ describe API::NotificationSettings do
it "updates group level notification settings for the current user" do
put api("/groups/#{group.id}/notification_settings", user), { level: 'watch' }
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['level']).to eq(user.reload.notification_settings_for(group).level)
end
end
@@ -60,7 +60,7 @@ describe API::NotificationSettings do
it "returns project level notification settings for the current user" do
get api("/projects/#{project.id}/notification_settings", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_a Hash
expect(json_response['level']).to eq(user.notification_settings_for(project).level)
end
@@ -70,7 +70,7 @@ describe API::NotificationSettings do
it "updates project level notification settings for the current user" do
put api("/projects/#{project.id}/notification_settings", user), { level: 'custom', new_note: true }
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['level']).to eq(user.reload.notification_settings_for(project).level)
expect(json_response['events']['new_note']).to be_truthy
expect(json_response['events']['new_issue']).to be_falsey
@@ -81,7 +81,7 @@ describe API::NotificationSettings do
it "fails on invalid level" do
put api("/projects/#{project.id}/notification_settings", user), { level: 'invalid' }
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
end
end
diff --git a/spec/requests/api/oauth_tokens_spec.rb b/spec/requests/api/oauth_tokens_spec.rb
index 0d56e1f732e..bdda80cc229 100644
--- a/spec/requests/api/oauth_tokens_spec.rb
+++ b/spec/requests/api/oauth_tokens_spec.rb
@@ -12,7 +12,7 @@ describe 'OAuth tokens' do
request_oauth_token(user)
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
expect(json_response['error']).to eq('invalid_grant')
end
end
@@ -23,7 +23,7 @@ describe 'OAuth tokens' do
request_oauth_token(user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['access_token']).not_to be_nil
end
end
@@ -35,7 +35,7 @@ describe 'OAuth tokens' do
request_oauth_token(user)
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
@@ -46,7 +46,7 @@ describe 'OAuth tokens' do
request_oauth_token(user)
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
end
diff --git a/spec/requests/api/pages_domains_spec.rb b/spec/requests/api/pages_domains_spec.rb
new file mode 100644
index 00000000000..d13b3a958c9
--- /dev/null
+++ b/spec/requests/api/pages_domains_spec.rb
@@ -0,0 +1,440 @@
+require 'rails_helper'
+
+describe API::PagesDomains do
+ set(:project) { create(:project) }
+ set(:user) { create(:user) }
+
+ set(:pages_domain) { create(:pages_domain, domain: 'www.domain.test', project: project) }
+ set(:pages_domain_secure) { create(:pages_domain, :with_certificate, :with_key, domain: 'ssl.domain.test', project: project) }
+ set(:pages_domain_expired) { create(:pages_domain, :with_expired_certificate, :with_key, domain: 'expired.domain.test', project: project) }
+
+ let(:pages_domain_params) { build(:pages_domain, domain: 'www.other-domain.test').slice(:domain) }
+ let(:pages_domain_secure_params) { build(:pages_domain, :with_certificate, :with_key, domain: 'ssl.other-domain.test', project: project).slice(:domain, :certificate, :key) }
+ let(:pages_domain_secure_key_missmatch_params) {build(:pages_domain, :with_trusted_chain, :with_key, project: project).slice(:domain, :certificate, :key) }
+ let(:pages_domain_secure_missing_chain_params) {build(:pages_domain, :with_missing_chain, project: project).slice(:certificate) }
+
+ let(:route) { "/projects/#{project.id}/pages/domains" }
+ let(:route_domain) { "/projects/#{project.id}/pages/domains/#{pages_domain.domain}" }
+ let(:route_secure_domain) { "/projects/#{project.id}/pages/domains/#{pages_domain_secure.domain}" }
+ let(:route_expired_domain) { "/projects/#{project.id}/pages/domains/#{pages_domain_expired.domain}" }
+ let(:route_vacant_domain) { "/projects/#{project.id}/pages/domains/www.vacant-domain.test" }
+
+ before do
+ allow(Gitlab.config.pages).to receive(:enabled).and_return(true)
+ end
+
+ describe 'GET /projects/:project_id/pages/domains' do
+ shared_examples_for 'get pages domains' do
+ it 'returns paginated pages domains' do
+ get api(route, user)
+
+ expect(response).to have_gitlab_http_status(200)
+ expect(response).to include_pagination_headers
+ expect(json_response).to be_an Array
+ expect(json_response.size).to eq(3)
+ expect(json_response.map { |pages_domain| pages_domain['domain'] }).to include(pages_domain.domain)
+ expect(json_response.last).to have_key('domain')
+ end
+ end
+
+ context 'when pages is disabled' do
+ before do
+ allow(Gitlab.config.pages).to receive(:enabled).and_return(false)
+ project.add_master(user)
+ end
+
+ it_behaves_like '404 response' do
+ let(:request) { get api(route, user) }
+ end
+ end
+
+ context 'when user is a master' do
+ before do
+ project.add_master(user)
+ end
+
+ it_behaves_like 'get pages domains'
+ end
+
+ context 'when user is a developer' do
+ before do
+ project.add_developer(user)
+ end
+
+ it_behaves_like '403 response' do
+ let(:request) { get api(route, user) }
+ end
+ end
+
+ context 'when user is a reporter' do
+ before do
+ project.add_reporter(user)
+ end
+
+ it_behaves_like '403 response' do
+ let(:request) { get api(route, user) }
+ end
+ end
+
+ context 'when user is a guest' do
+ before do
+ project.add_guest(user)
+ end
+
+ it_behaves_like '403 response' do
+ let(:request) { get api(route, user) }
+ end
+ end
+
+ context 'when user is not a member' do
+ it_behaves_like '404 response' do
+ let(:request) { get api(route, user) }
+ end
+ end
+ end
+
+ describe 'GET /projects/:project_id/pages/domains/:domain' do
+ shared_examples_for 'get pages domain' do
+ it 'returns pages domain' do
+ get api(route_domain, user)
+
+ expect(response).to have_gitlab_http_status(200)
+ expect(json_response['domain']).to eq(pages_domain.domain)
+ expect(json_response['url']).to eq(pages_domain.url)
+ expect(json_response['certificate']).to be_nil
+ end
+
+ it 'returns pages domain with a certificate' do
+ get api(route_secure_domain, user)
+
+ expect(response).to have_gitlab_http_status(200)
+ expect(json_response['domain']).to eq(pages_domain_secure.domain)
+ expect(json_response['url']).to eq(pages_domain_secure.url)
+ expect(json_response['certificate']['subject']).to eq(pages_domain_secure.subject)
+ expect(json_response['certificate']['expired']).to be false
+ end
+
+ it 'returns pages domain with an expired certificate' do
+ get api(route_expired_domain, user)
+
+ expect(response).to have_gitlab_http_status(200)
+ expect(json_response['certificate']['expired']).to be true
+ end
+ end
+
+ context 'when domain is vacant' do
+ before do
+ project.add_master(user)
+ end
+
+ it_behaves_like '404 response' do
+ let(:request) { get api(route_vacant_domain, user) }
+ end
+ end
+
+ context 'when user is a master' do
+ before do
+ project.add_master(user)
+ end
+
+ it_behaves_like 'get pages domain'
+ end
+
+ context 'when user is a developer' do
+ before do
+ project.add_developer(user)
+ end
+
+ it_behaves_like '403 response' do
+ let(:request) { get api(route, user) }
+ end
+ end
+
+ context 'when user is a reporter' do
+ before do
+ project.add_reporter(user)
+ end
+
+ it_behaves_like '403 response' do
+ let(:request) { get api(route, user) }
+ end
+ end
+
+ context 'when user is a guest' do
+ before do
+ project.add_guest(user)
+ end
+
+ it_behaves_like '403 response' do
+ let(:request) { get api(route, user) }
+ end
+ end
+
+ context 'when user is not a member' do
+ it_behaves_like '404 response' do
+ let(:request) { get api(route, user) }
+ end
+ end
+ end
+
+ describe 'POST /projects/:project_id/pages/domains' do
+ let(:params) { pages_domain_params.slice(:domain) }
+ let(:params_secure) { pages_domain_secure_params.slice(:domain, :certificate, :key) }
+
+ shared_examples_for 'post pages domains' do
+ it 'creates a new pages domain' do
+ post api(route, user), params
+ pages_domain = PagesDomain.find_by(domain: json_response['domain'])
+
+ expect(response).to have_gitlab_http_status(201)
+ expect(pages_domain.domain).to eq(params[:domain])
+ expect(pages_domain.certificate).to be_nil
+ expect(pages_domain.key).to be_nil
+ end
+
+ it 'creates a new secure pages domain' do
+ post api(route, user), params_secure
+ pages_domain = PagesDomain.find_by(domain: json_response['domain'])
+
+ expect(response).to have_gitlab_http_status(201)
+ expect(pages_domain.domain).to eq(params_secure[:domain])
+ expect(pages_domain.certificate).to eq(params_secure[:certificate])
+ expect(pages_domain.key).to eq(params_secure[:key])
+ end
+
+ it 'fails to create pages domain without key' do
+ post api(route, user), pages_domain_secure_params.slice(:domain, :certificate)
+
+ expect(response).to have_gitlab_http_status(400)
+ end
+
+ it 'fails to create pages domain with key missmatch' do
+ post api(route, user), pages_domain_secure_key_missmatch_params.slice(:domain, :certificate, :key)
+
+ expect(response).to have_gitlab_http_status(400)
+ end
+ end
+
+ context 'when user is a master' do
+ before do
+ project.add_master(user)
+ end
+
+ it_behaves_like 'post pages domains'
+ end
+
+ context 'when user is a developer' do
+ before do
+ project.add_developer(user)
+ end
+
+ it_behaves_like '403 response' do
+ let(:request) { post api(route, user), params }
+ end
+ end
+
+ context 'when user is a reporter' do
+ before do
+ project.add_reporter(user)
+ end
+
+ it_behaves_like '403 response' do
+ let(:request) { post api(route, user), params }
+ end
+ end
+
+ context 'when user is a guest' do
+ before do
+ project.add_guest(user)
+ end
+
+ it_behaves_like '403 response' do
+ let(:request) { post api(route, user), params }
+ end
+ end
+
+ context 'when user is not a member' do
+ it_behaves_like '404 response' do
+ let(:request) { post api(route, user), params }
+ end
+ end
+ end
+
+ describe 'PUT /projects/:project_id/pages/domains/:domain' do
+ let(:params_secure) { pages_domain_secure_params.slice(:certificate, :key) }
+ let(:params_secure_nokey) { pages_domain_secure_params.slice(:certificate) }
+
+ shared_examples_for 'put pages domain' do
+ it 'updates pages domain removing certificate' do
+ put api(route_secure_domain, user)
+ pages_domain_secure.reload
+
+ expect(response).to have_gitlab_http_status(200)
+ expect(pages_domain_secure.certificate).to be_nil
+ expect(pages_domain_secure.key).to be_nil
+ end
+
+ it 'updates pages domain adding certificate' do
+ put api(route_domain, user), params_secure
+ pages_domain.reload
+
+ expect(response).to have_gitlab_http_status(200)
+ expect(pages_domain.certificate).to eq(params_secure[:certificate])
+ expect(pages_domain.key).to eq(params_secure[:key])
+ end
+
+ it 'updates pages domain with expired certificate' do
+ put api(route_expired_domain, user), params_secure
+ pages_domain_expired.reload
+
+ expect(response).to have_gitlab_http_status(200)
+ expect(pages_domain_expired.certificate).to eq(params_secure[:certificate])
+ expect(pages_domain_expired.key).to eq(params_secure[:key])
+ end
+
+ it 'updates pages domain with expired certificate not updating key' do
+ put api(route_secure_domain, user), params_secure_nokey
+ pages_domain_secure.reload
+
+ expect(response).to have_gitlab_http_status(200)
+ expect(pages_domain_secure.certificate).to eq(params_secure_nokey[:certificate])
+ end
+
+ it 'fails to update pages domain adding certificate without key' do
+ put api(route_domain, user), params_secure_nokey
+
+ expect(response).to have_gitlab_http_status(400)
+ end
+
+ it 'fails to update pages domain adding certificate with missing chain' do
+ put api(route_domain, user), pages_domain_secure_missing_chain_params.slice(:certificate)
+
+ expect(response).to have_gitlab_http_status(400)
+ end
+
+ it 'fails to update pages domain with key missmatch' do
+ put api(route_secure_domain, user), pages_domain_secure_key_missmatch_params.slice(:certificate, :key)
+
+ expect(response).to have_gitlab_http_status(400)
+ end
+ end
+
+ context 'when domain is vacant' do
+ before do
+ project.add_master(user)
+ end
+
+ it_behaves_like '404 response' do
+ let(:request) { put api(route_vacant_domain, user) }
+ end
+ end
+
+ context 'when user is a master' do
+ before do
+ project.add_master(user)
+ end
+
+ it_behaves_like 'put pages domain'
+ end
+
+ context 'when user is a developer' do
+ before do
+ project.add_developer(user)
+ end
+
+ it_behaves_like '403 response' do
+ let(:request) { put api(route_domain, user) }
+ end
+ end
+
+ context 'when user is a reporter' do
+ before do
+ project.add_reporter(user)
+ end
+
+ it_behaves_like '403 response' do
+ let(:request) { put api(route_domain, user) }
+ end
+ end
+
+ context 'when user is a guest' do
+ before do
+ project.add_guest(user)
+ end
+
+ it_behaves_like '403 response' do
+ let(:request) { put api(route_domain, user) }
+ end
+ end
+
+ context 'when user is not a member' do
+ it_behaves_like '404 response' do
+ let(:request) { put api(route_domain, user) }
+ end
+ end
+ end
+
+ describe 'DELETE /projects/:project_id/pages/domains/:domain' do
+ shared_examples_for 'delete pages domain' do
+ it 'deletes a pages domain' do
+ delete api(route_domain, user)
+
+ expect(response).to have_gitlab_http_status(204)
+ end
+ end
+
+ context 'when domain is vacant' do
+ before do
+ project.add_master(user)
+ end
+
+ it_behaves_like '404 response' do
+ let(:request) { delete api(route_vacant_domain, user) }
+ end
+ end
+
+ context 'when user is a master' do
+ before do
+ project.add_master(user)
+ end
+
+ it_behaves_like 'delete pages domain'
+ end
+
+ context 'when user is a developer' do
+ before do
+ project.add_developer(user)
+ end
+
+ it_behaves_like '403 response' do
+ let(:request) { delete api(route_domain, user) }
+ end
+ end
+
+ context 'when user is a reporter' do
+ before do
+ project.add_reporter(user)
+ end
+
+ it_behaves_like '403 response' do
+ let(:request) { delete api(route_domain, user) }
+ end
+ end
+
+ context 'when user is a guest' do
+ before do
+ project.add_guest(user)
+ end
+
+ it_behaves_like '403 response' do
+ let(:request) { delete api(route_domain, user) }
+ end
+ end
+
+ context 'when user is not a member' do
+ it_behaves_like '404 response' do
+ let(:request) { delete api(route_domain, user) }
+ end
+ end
+ end
+end
diff --git a/spec/requests/api/pipeline_schedules_spec.rb b/spec/requests/api/pipeline_schedules_spec.rb
index f650df57383..7ea25059756 100644
--- a/spec/requests/api/pipeline_schedules_spec.rb
+++ b/spec/requests/api/pipeline_schedules_spec.rb
@@ -20,7 +20,7 @@ describe API::PipelineSchedules do
it 'returns list of pipeline_schedules' do
get api("/projects/#{project.id}/pipeline_schedules", developer)
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
expect(response).to include_pagination_headers
expect(response).to match_response_schema('pipeline_schedules')
end
@@ -67,7 +67,7 @@ describe API::PipelineSchedules do
it 'does not return pipeline_schedules list' do
get api("/projects/#{project.id}/pipeline_schedules", user)
- expect(response).to have_http_status(:not_found)
+ expect(response).to have_gitlab_http_status(:not_found)
end
end
@@ -75,7 +75,7 @@ describe API::PipelineSchedules do
it 'does not return pipeline_schedules list' do
get api("/projects/#{project.id}/pipeline_schedules")
- expect(response).to have_http_status(:unauthorized)
+ expect(response).to have_gitlab_http_status(:unauthorized)
end
end
end
@@ -91,14 +91,14 @@ describe API::PipelineSchedules do
it 'returns pipeline_schedule details' do
get api("/projects/#{project.id}/pipeline_schedules/#{pipeline_schedule.id}", developer)
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
expect(response).to match_response_schema('pipeline_schedule')
end
it 'responds with 404 Not Found if requesting non-existing pipeline_schedule' do
get api("/projects/#{project.id}/pipeline_schedules/-5", developer)
- expect(response).to have_http_status(:not_found)
+ expect(response).to have_gitlab_http_status(:not_found)
end
end
@@ -106,7 +106,7 @@ describe API::PipelineSchedules do
it 'does not return pipeline_schedules list' do
get api("/projects/#{project.id}/pipeline_schedules/#{pipeline_schedule.id}", user)
- expect(response).to have_http_status(:not_found)
+ expect(response).to have_gitlab_http_status(:not_found)
end
end
@@ -118,7 +118,7 @@ describe API::PipelineSchedules do
it 'does not return pipeline_schedules list' do
get api("/projects/#{project.id}/pipeline_schedules/#{pipeline_schedule.id}", user)
- expect(response).to have_http_status(:not_found)
+ expect(response).to have_gitlab_http_status(:not_found)
end
end
@@ -126,7 +126,7 @@ describe API::PipelineSchedules do
it 'does not return pipeline_schedules list' do
get api("/projects/#{project.id}/pipeline_schedules/#{pipeline_schedule.id}")
- expect(response).to have_http_status(:unauthorized)
+ expect(response).to have_gitlab_http_status(:unauthorized)
end
end
end
@@ -142,7 +142,7 @@ describe API::PipelineSchedules do
params
end.to change { project.pipeline_schedules.count }.by(1)
- expect(response).to have_http_status(:created)
+ expect(response).to have_gitlab_http_status(:created)
expect(response).to match_response_schema('pipeline_schedule')
expect(json_response['description']).to eq(params[:description])
expect(json_response['ref']).to eq(params[:ref])
@@ -156,7 +156,7 @@ describe API::PipelineSchedules do
it 'does not create pipeline_schedule' do
post api("/projects/#{project.id}/pipeline_schedules", developer)
- expect(response).to have_http_status(:bad_request)
+ expect(response).to have_gitlab_http_status(:bad_request)
end
end
@@ -165,7 +165,7 @@ describe API::PipelineSchedules do
post api("/projects/#{project.id}/pipeline_schedules", developer),
params.merge('cron' => 'invalid-cron')
- expect(response).to have_http_status(:bad_request)
+ expect(response).to have_gitlab_http_status(:bad_request)
expect(json_response['message']).to have_key('cron')
end
end
@@ -175,7 +175,7 @@ describe API::PipelineSchedules do
it 'does not create pipeline_schedule' do
post api("/projects/#{project.id}/pipeline_schedules", user), params
- expect(response).to have_http_status(:not_found)
+ expect(response).to have_gitlab_http_status(:not_found)
end
end
@@ -183,7 +183,7 @@ describe API::PipelineSchedules do
it 'does not create pipeline_schedule' do
post api("/projects/#{project.id}/pipeline_schedules"), params
- expect(response).to have_http_status(:unauthorized)
+ expect(response).to have_gitlab_http_status(:unauthorized)
end
end
end
@@ -198,7 +198,7 @@ describe API::PipelineSchedules do
put api("/projects/#{project.id}/pipeline_schedules/#{pipeline_schedule.id}", developer),
cron: '1 2 3 4 *'
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
expect(response).to match_response_schema('pipeline_schedule')
expect(json_response['cron']).to eq('1 2 3 4 *')
end
@@ -208,7 +208,7 @@ describe API::PipelineSchedules do
put api("/projects/#{project.id}/pipeline_schedules/#{pipeline_schedule.id}", developer),
cron: 'invalid-cron'
- expect(response).to have_http_status(:bad_request)
+ expect(response).to have_gitlab_http_status(:bad_request)
expect(json_response['message']).to have_key('cron')
end
end
@@ -218,7 +218,7 @@ describe API::PipelineSchedules do
it 'does not update pipeline_schedule' do
put api("/projects/#{project.id}/pipeline_schedules/#{pipeline_schedule.id}", user)
- expect(response).to have_http_status(:not_found)
+ expect(response).to have_gitlab_http_status(:not_found)
end
end
@@ -226,7 +226,7 @@ describe API::PipelineSchedules do
it 'does not update pipeline_schedule' do
put api("/projects/#{project.id}/pipeline_schedules/#{pipeline_schedule.id}")
- expect(response).to have_http_status(:unauthorized)
+ expect(response).to have_gitlab_http_status(:unauthorized)
end
end
end
@@ -240,7 +240,7 @@ describe API::PipelineSchedules do
it 'updates owner' do
post api("/projects/#{project.id}/pipeline_schedules/#{pipeline_schedule.id}/take_ownership", developer)
- expect(response).to have_http_status(:created)
+ expect(response).to have_gitlab_http_status(:created)
expect(response).to match_response_schema('pipeline_schedule')
end
end
@@ -249,7 +249,7 @@ describe API::PipelineSchedules do
it 'does not update owner' do
post api("/projects/#{project.id}/pipeline_schedules/#{pipeline_schedule.id}/take_ownership", user)
- expect(response).to have_http_status(:not_found)
+ expect(response).to have_gitlab_http_status(:not_found)
end
end
@@ -257,7 +257,7 @@ describe API::PipelineSchedules do
it 'does not update owner' do
post api("/projects/#{project.id}/pipeline_schedules/#{pipeline_schedule.id}/take_ownership")
- expect(response).to have_http_status(:unauthorized)
+ expect(response).to have_gitlab_http_status(:unauthorized)
end
end
end
@@ -279,13 +279,13 @@ describe API::PipelineSchedules do
delete api("/projects/#{project.id}/pipeline_schedules/#{pipeline_schedule.id}", master)
end.to change { project.pipeline_schedules.count }.by(-1)
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
end
it 'responds with 404 Not Found if requesting non-existing pipeline_schedule' do
delete api("/projects/#{project.id}/pipeline_schedules/-5", master)
- expect(response).to have_http_status(:not_found)
+ expect(response).to have_gitlab_http_status(:not_found)
end
it_behaves_like '412 response' do
@@ -299,7 +299,7 @@ describe API::PipelineSchedules do
it 'does not delete pipeline_schedule' do
delete api("/projects/#{project.id}/pipeline_schedules/#{pipeline_schedule.id}", developer)
- expect(response).to have_http_status(:forbidden)
+ expect(response).to have_gitlab_http_status(:forbidden)
end
end
@@ -307,7 +307,7 @@ describe API::PipelineSchedules do
it 'does not delete pipeline_schedule' do
delete api("/projects/#{project.id}/pipeline_schedules/#{pipeline_schedule.id}")
- expect(response).to have_http_status(:unauthorized)
+ expect(response).to have_gitlab_http_status(:unauthorized)
end
end
end
@@ -327,7 +327,7 @@ describe API::PipelineSchedules do
params
end.to change { pipeline_schedule.variables.count }.by(1)
- expect(response).to have_http_status(:created)
+ expect(response).to have_gitlab_http_status(:created)
expect(response).to match_response_schema('pipeline_schedule_variable')
expect(json_response['key']).to eq(params[:key])
expect(json_response['value']).to eq(params[:value])
@@ -338,7 +338,7 @@ describe API::PipelineSchedules do
it 'does not create pipeline_schedule_variable' do
post api("/projects/#{project.id}/pipeline_schedules/#{pipeline_schedule.id}/variables", developer)
- expect(response).to have_http_status(:bad_request)
+ expect(response).to have_gitlab_http_status(:bad_request)
end
end
@@ -347,7 +347,7 @@ describe API::PipelineSchedules do
post api("/projects/#{project.id}/pipeline_schedules/#{pipeline_schedule.id}/variables", developer),
params.merge('key' => '!?!?')
- expect(response).to have_http_status(:bad_request)
+ expect(response).to have_gitlab_http_status(:bad_request)
expect(json_response['message']).to have_key('key')
end
end
@@ -357,7 +357,7 @@ describe API::PipelineSchedules do
it 'does not create pipeline_schedule_variable' do
post api("/projects/#{project.id}/pipeline_schedules/#{pipeline_schedule.id}/variables", user), params
- expect(response).to have_http_status(:not_found)
+ expect(response).to have_gitlab_http_status(:not_found)
end
end
@@ -365,7 +365,7 @@ describe API::PipelineSchedules do
it 'does not create pipeline_schedule_variable' do
post api("/projects/#{project.id}/pipeline_schedules/#{pipeline_schedule.id}/variables"), params
- expect(response).to have_http_status(:unauthorized)
+ expect(response).to have_gitlab_http_status(:unauthorized)
end
end
end
@@ -384,7 +384,7 @@ describe API::PipelineSchedules do
put api("/projects/#{project.id}/pipeline_schedules/#{pipeline_schedule.id}/variables/#{pipeline_schedule_variable.key}", developer),
value: 'updated_value'
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
expect(response).to match_response_schema('pipeline_schedule_variable')
expect(json_response['value']).to eq('updated_value')
end
@@ -394,7 +394,7 @@ describe API::PipelineSchedules do
it 'does not update pipeline_schedule_variable' do
put api("/projects/#{project.id}/pipeline_schedules/#{pipeline_schedule.id}/variables/#{pipeline_schedule_variable.key}", user)
- expect(response).to have_http_status(:not_found)
+ expect(response).to have_gitlab_http_status(:not_found)
end
end
@@ -402,7 +402,7 @@ describe API::PipelineSchedules do
it 'does not update pipeline_schedule_variable' do
put api("/projects/#{project.id}/pipeline_schedules/#{pipeline_schedule.id}/variables/#{pipeline_schedule_variable.key}")
- expect(response).to have_http_status(:unauthorized)
+ expect(response).to have_gitlab_http_status(:unauthorized)
end
end
end
@@ -428,14 +428,14 @@ describe API::PipelineSchedules do
delete api("/projects/#{project.id}/pipeline_schedules/#{pipeline_schedule.id}/variables/#{pipeline_schedule_variable.key}", master)
end.to change { Ci::PipelineScheduleVariable.count }.by(-1)
- expect(response).to have_http_status(:accepted)
+ expect(response).to have_gitlab_http_status(:accepted)
expect(response).to match_response_schema('pipeline_schedule_variable')
end
it 'responds with 404 Not Found if requesting non-existing pipeline_schedule_variable' do
delete api("/projects/#{project.id}/pipeline_schedules/#{pipeline_schedule.id}/variables/____", master)
- expect(response).to have_http_status(:not_found)
+ expect(response).to have_gitlab_http_status(:not_found)
end
end
@@ -445,7 +445,7 @@ describe API::PipelineSchedules do
it 'does not delete pipeline_schedule_variable' do
delete api("/projects/#{project.id}/pipeline_schedules/#{pipeline_schedule.id}/variables/#{pipeline_schedule_variable.key}", developer)
- expect(response).to have_http_status(:forbidden)
+ expect(response).to have_gitlab_http_status(:forbidden)
end
end
@@ -453,7 +453,7 @@ describe API::PipelineSchedules do
it 'does not delete pipeline_schedule_variable' do
delete api("/projects/#{project.id}/pipeline_schedules/#{pipeline_schedule.id}/variables/#{pipeline_schedule_variable.key}")
- expect(response).to have_http_status(:unauthorized)
+ expect(response).to have_gitlab_http_status(:unauthorized)
end
end
end
diff --git a/spec/requests/api/pipelines_spec.rb b/spec/requests/api/pipelines_spec.rb
index 258085e503f..e4dcc9252fa 100644
--- a/spec/requests/api/pipelines_spec.rb
+++ b/spec/requests/api/pipelines_spec.rb
@@ -19,7 +19,7 @@ describe API::Pipelines do
it 'returns project pipelines' do
get api("/projects/#{project.id}/pipelines", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.first['sha']).to match /\A\h{40}\z/
@@ -37,7 +37,7 @@ describe API::Pipelines do
it 'returns matched pipelines' do
get api("/projects/#{project.id}/pipelines", user), scope: target
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
expect(response).to include_pagination_headers
expect(json_response).not_to be_empty
json_response.each { |r| expect(r['status']).to eq(target) }
@@ -55,7 +55,7 @@ describe API::Pipelines do
it 'returns matched pipelines' do
get api("/projects/#{project.id}/pipelines", user), scope: 'finished'
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
expect(response).to include_pagination_headers
expect(json_response).not_to be_empty
json_response.each { |r| expect(r['status']).to be_in(%w[success failed canceled]) }
@@ -70,7 +70,7 @@ describe API::Pipelines do
it 'returns matched pipelines' do
get api("/projects/#{project.id}/pipelines", user), scope: 'branches'
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
expect(response).to include_pagination_headers
expect(json_response).not_to be_empty
expect(json_response.last['id']).to eq(pipeline_branch.id)
@@ -81,7 +81,7 @@ describe API::Pipelines do
it 'returns matched pipelines' do
get api("/projects/#{project.id}/pipelines", user), scope: 'tags'
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
expect(response).to include_pagination_headers
expect(json_response).not_to be_empty
expect(json_response.last['id']).to eq(pipeline_tag.id)
@@ -93,7 +93,7 @@ describe API::Pipelines do
it 'returns bad_request' do
get api("/projects/#{project.id}/pipelines", user), scope: 'invalid-scope'
- expect(response).to have_http_status(:bad_request)
+ expect(response).to have_gitlab_http_status(:bad_request)
end
end
@@ -108,7 +108,7 @@ describe API::Pipelines do
it 'returns matched pipelines' do
get api("/projects/#{project.id}/pipelines", user), status: target
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
expect(response).to include_pagination_headers
expect(json_response).not_to be_empty
json_response.each { |r| expect(r['status']).to eq(target) }
@@ -120,7 +120,7 @@ describe API::Pipelines do
it 'returns bad_request' do
get api("/projects/#{project.id}/pipelines", user), status: 'invalid-status'
- expect(response).to have_http_status(:bad_request)
+ expect(response).to have_gitlab_http_status(:bad_request)
end
end
@@ -133,7 +133,7 @@ describe API::Pipelines do
it 'returns matched pipelines' do
get api("/projects/#{project.id}/pipelines", user), ref: 'master'
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
expect(response).to include_pagination_headers
expect(json_response).not_to be_empty
json_response.each { |r| expect(r['ref']).to eq('master') }
@@ -144,7 +144,7 @@ describe API::Pipelines do
it 'returns empty' do
get api("/projects/#{project.id}/pipelines", user), ref: 'invalid-ref'
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
expect(response).to include_pagination_headers
expect(json_response).to be_empty
end
@@ -158,7 +158,7 @@ describe API::Pipelines do
it 'returns matched pipelines' do
get api("/projects/#{project.id}/pipelines", user), name: user.name
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
expect(response).to include_pagination_headers
expect(json_response.first['id']).to eq(pipeline.id)
end
@@ -168,7 +168,7 @@ describe API::Pipelines do
it 'returns empty' do
get api("/projects/#{project.id}/pipelines", user), name: 'invalid-name'
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
expect(response).to include_pagination_headers
expect(json_response).to be_empty
end
@@ -182,7 +182,7 @@ describe API::Pipelines do
it 'returns matched pipelines' do
get api("/projects/#{project.id}/pipelines", user), username: user.username
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
expect(response).to include_pagination_headers
expect(json_response.first['id']).to eq(pipeline.id)
end
@@ -192,7 +192,7 @@ describe API::Pipelines do
it 'returns empty' do
get api("/projects/#{project.id}/pipelines", user), username: 'invalid-username'
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
expect(response).to include_pagination_headers
expect(json_response).to be_empty
end
@@ -207,7 +207,7 @@ describe API::Pipelines do
it 'returns matched pipelines' do
get api("/projects/#{project.id}/pipelines", user), yaml_errors: true
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
expect(response).to include_pagination_headers
expect(json_response.first['id']).to eq(pipeline1.id)
end
@@ -217,7 +217,7 @@ describe API::Pipelines do
it 'returns matched pipelines' do
get api("/projects/#{project.id}/pipelines", user), yaml_errors: false
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
expect(response).to include_pagination_headers
expect(json_response.first['id']).to eq(pipeline2.id)
end
@@ -227,7 +227,7 @@ describe API::Pipelines do
it 'returns bad_request' do
get api("/projects/#{project.id}/pipelines", user), yaml_errors: 'invalid-yaml_errors'
- expect(response).to have_http_status(:bad_request)
+ expect(response).to have_gitlab_http_status(:bad_request)
end
end
end
@@ -244,7 +244,7 @@ describe API::Pipelines do
it 'sorts as user_id: :desc' do
get api("/projects/#{project.id}/pipelines", user), order_by: 'user_id', sort: 'desc'
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
expect(response).to include_pagination_headers
expect(json_response).not_to be_empty
@@ -257,7 +257,7 @@ describe API::Pipelines do
it 'returns bad_request' do
get api("/projects/#{project.id}/pipelines", user), order_by: 'user_id', sort: 'invalid_sort'
- expect(response).to have_http_status(:bad_request)
+ expect(response).to have_gitlab_http_status(:bad_request)
end
end
end
@@ -266,7 +266,7 @@ describe API::Pipelines do
it 'returns bad_request' do
get api("/projects/#{project.id}/pipelines", user), order_by: 'lock_version', sort: 'asc'
- expect(response).to have_http_status(:bad_request)
+ expect(response).to have_gitlab_http_status(:bad_request)
end
end
end
@@ -277,7 +277,7 @@ describe API::Pipelines do
it 'does not return project pipelines' do
get api("/projects/#{project.id}/pipelines", non_member)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq '404 Project Not Found'
expect(json_response).not_to be_an Array
end
@@ -296,7 +296,7 @@ describe API::Pipelines do
post api("/projects/#{project.id}/pipeline", user), ref: project.default_branch
end.to change { Ci::Pipeline.count }.by(1)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response).to be_a Hash
expect(json_response['sha']).to eq project.commit.id
end
@@ -304,7 +304,7 @@ describe API::Pipelines do
it 'fails when using an invalid ref' do
post api("/projects/#{project.id}/pipeline", user), ref: 'invalid_ref'
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['message']['base'].first).to eq 'Reference not found'
expect(json_response).not_to be_an Array
end
@@ -314,7 +314,7 @@ describe API::Pipelines do
it 'fails to create pipeline' do
post api("/projects/#{project.id}/pipeline", user), ref: project.default_branch
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['message']['base'].first).to eq 'Missing .gitlab-ci.yml file'
expect(json_response).not_to be_an Array
end
@@ -325,7 +325,7 @@ describe API::Pipelines do
it 'does not create pipeline' do
post api("/projects/#{project.id}/pipeline", non_member), ref: project.default_branch
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq '404 Project Not Found'
expect(json_response).not_to be_an Array
end
@@ -337,14 +337,14 @@ describe API::Pipelines do
it 'returns project pipelines' do
get api("/projects/#{project.id}/pipelines/#{pipeline.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['sha']).to match /\A\h{40}\z/
end
it 'returns 404 when it does not exist' do
get api("/projects/#{project.id}/pipelines/123456", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq '404 Not found'
expect(json_response['id']).to be nil
end
@@ -366,7 +366,7 @@ describe API::Pipelines do
it 'should not return a project pipeline' do
get api("/projects/#{project.id}/pipelines/#{pipeline.id}", non_member)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq '404 Project Not Found'
expect(json_response['id']).to be nil
end
@@ -387,7 +387,7 @@ describe API::Pipelines do
post api("/projects/#{project.id}/pipelines/#{pipeline.id}/retry", user)
end.to change { pipeline.builds.count }.from(1).to(2)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(build.reload.retried?).to be true
end
end
@@ -396,7 +396,7 @@ describe API::Pipelines do
it 'should not return a project pipeline' do
post api("/projects/#{project.id}/pipelines/#{pipeline.id}/retry", non_member)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq '404 Project Not Found'
expect(json_response['id']).to be nil
end
@@ -415,7 +415,7 @@ describe API::Pipelines do
it 'retries failed builds' do
post api("/projects/#{project.id}/pipelines/#{pipeline.id}/cancel", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['status']).to eq('canceled')
end
end
@@ -430,7 +430,7 @@ describe API::Pipelines do
it 'rejects the action' do
post api("/projects/#{project.id}/pipelines/#{pipeline.id}/cancel", reporter)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
expect(pipeline.reload.status).to eq('pending')
end
end
diff --git a/spec/requests/api/project_hooks_spec.rb b/spec/requests/api/project_hooks_spec.rb
index ac3bab09c4c..f31344a6238 100644
--- a/spec/requests/api/project_hooks_spec.rb
+++ b/spec/requests/api/project_hooks_spec.rb
@@ -22,7 +22,7 @@ describe API::ProjectHooks, 'ProjectHooks' do
it "returns project hooks" do
get api("/projects/#{project.id}/hooks", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(response).to include_pagination_headers
expect(json_response.count).to eq(1)
@@ -43,7 +43,7 @@ describe API::ProjectHooks, 'ProjectHooks' do
it "does not access project hooks" do
get api("/projects/#{project.id}/hooks", user3)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
end
@@ -53,7 +53,7 @@ describe API::ProjectHooks, 'ProjectHooks' do
it "returns a project hook" do
get api("/projects/#{project.id}/hooks/#{hook.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['url']).to eq(hook.url)
expect(json_response['issues_events']).to eq(hook.issues_events)
expect(json_response['push_events']).to eq(hook.push_events)
@@ -69,20 +69,20 @@ describe API::ProjectHooks, 'ProjectHooks' do
it "returns a 404 error if hook id is not available" do
get api("/projects/#{project.id}/hooks/1234", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
context "unauthorized user" do
it "does not access an existing hook" do
get api("/projects/#{project.id}/hooks/#{hook.id}", user3)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
it "returns a 404 error if hook id is not available" do
get api("/projects/#{project.id}/hooks/1234", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -94,7 +94,7 @@ describe API::ProjectHooks, 'ProjectHooks' do
job_events: true
end.to change {project.hooks.count}.by(1)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['url']).to eq('http://example.com')
expect(json_response['issues_events']).to eq(true)
expect(json_response['push_events']).to eq(true)
@@ -115,7 +115,7 @@ describe API::ProjectHooks, 'ProjectHooks' do
post api("/projects/#{project.id}/hooks", user), url: "http://example.com", token: token
end.to change {project.hooks.count}.by(1)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response["url"]).to eq("http://example.com")
expect(json_response).not_to include("token")
@@ -127,12 +127,12 @@ describe API::ProjectHooks, 'ProjectHooks' do
it "returns a 400 error if url not given" do
post api("/projects/#{project.id}/hooks", user)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it "returns a 422 error if url not valid" do
post api("/projects/#{project.id}/hooks", user), "url" => "ftp://example.com"
- expect(response).to have_http_status(422)
+ expect(response).to have_gitlab_http_status(422)
end
end
@@ -141,7 +141,7 @@ describe API::ProjectHooks, 'ProjectHooks' do
put api("/projects/#{project.id}/hooks/#{hook.id}", user),
url: 'http://example.org', push_events: false, job_events: true
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['url']).to eq('http://example.org')
expect(json_response['issues_events']).to eq(hook.issues_events)
expect(json_response['push_events']).to eq(false)
@@ -159,7 +159,7 @@ describe API::ProjectHooks, 'ProjectHooks' do
put api("/projects/#{project.id}/hooks/#{hook.id}", user), url: "http://example.org", token: token
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response["url"]).to eq("http://example.org")
expect(json_response).not_to include("token")
@@ -169,17 +169,17 @@ describe API::ProjectHooks, 'ProjectHooks' do
it "returns 404 error if hook id not found" do
put api("/projects/#{project.id}/hooks/1234", user), url: 'http://example.org'
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it "returns 400 error if url is not given" do
put api("/projects/#{project.id}/hooks/#{hook.id}", user)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it "returns a 422 error if url is not valid" do
put api("/projects/#{project.id}/hooks/#{hook.id}", user), url: 'ftp://example.com'
- expect(response).to have_http_status(422)
+ expect(response).to have_gitlab_http_status(422)
end
end
@@ -188,19 +188,19 @@ describe API::ProjectHooks, 'ProjectHooks' do
expect do
delete api("/projects/#{project.id}/hooks/#{hook.id}", user)
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
end.to change {project.hooks.count}.by(-1)
end
it "returns a 404 error when deleting non existent hook" do
delete api("/projects/#{project.id}/hooks/42", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it "returns a 404 error if hook id not given" do
delete api("/projects/#{project.id}/hooks", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it "returns a 404 if a user attempts to delete project hooks he/she does not own" do
@@ -209,7 +209,7 @@ describe API::ProjectHooks, 'ProjectHooks' do
other_project.team << [test_user, :master]
delete api("/projects/#{other_project.id}/hooks/#{hook.id}", test_user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(WebHook.exists?(hook.id)).to be_truthy
end
diff --git a/spec/requests/api/project_snippets_spec.rb b/spec/requests/api/project_snippets_spec.rb
index db34149eb73..e741ac4b7bd 100644
--- a/spec/requests/api/project_snippets_spec.rb
+++ b/spec/requests/api/project_snippets_spec.rb
@@ -12,7 +12,7 @@ describe API::ProjectSnippets do
it 'exposes known attributes' do
get api("/projects/#{project.id}/snippets/#{snippet.id}/user_agent_detail", admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['user_agent']).to eq(user_agent_detail.user_agent)
expect(json_response['ip_address']).to eq(user_agent_detail.ip_address)
expect(json_response['akismet_submitted']).to eq(user_agent_detail.submitted)
@@ -21,7 +21,7 @@ describe API::ProjectSnippets do
it "returns unautorized for non-admin users" do
get api("/projects/#{snippet.project.id}/snippets/#{snippet.id}/user_agent_detail", user)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -36,7 +36,7 @@ describe API::ProjectSnippets do
get api("/projects/#{project.id}/snippets", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.size).to eq(3)
@@ -49,7 +49,7 @@ describe API::ProjectSnippets do
get api("/projects/#{project.id}/snippets/", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.size).to eq(0)
@@ -63,7 +63,7 @@ describe API::ProjectSnippets do
it 'returns snippet json' do
get api("/projects/#{project.id}/snippets/#{snippet.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['title']).to eq(snippet.title)
expect(json_response['description']).to eq(snippet.description)
@@ -73,7 +73,7 @@ describe API::ProjectSnippets do
it 'returns 404 for invalid snippet id' do
get api("/projects/#{project.id}/snippets/1234", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 Not found')
end
end
@@ -92,7 +92,7 @@ describe API::ProjectSnippets do
it 'creates a new snippet' do
post api("/projects/#{project.id}/snippets/", admin), params
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
snippet = ProjectSnippet.find(json_response['id'])
expect(snippet.content).to eq(params[:code])
expect(snippet.description).to eq(params[:description])
@@ -106,7 +106,7 @@ describe API::ProjectSnippets do
post api("/projects/#{project.id}/snippets/", admin), params
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
context 'when the snippet is spam' do
@@ -132,7 +132,7 @@ describe API::ProjectSnippets do
expect { create_snippet(project, visibility: 'public') }
.not_to change { Snippet.count }
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['message']).to eq({ "error" => "Spam detected" })
end
@@ -154,7 +154,7 @@ describe API::ProjectSnippets do
put api("/projects/#{snippet.project.id}/snippets/#{snippet.id}/", admin), code: new_content, description: new_description
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
snippet.reload
expect(snippet.content).to eq(new_content)
expect(snippet.description).to eq(new_description)
@@ -163,14 +163,14 @@ describe API::ProjectSnippets do
it 'returns 404 for invalid snippet id' do
put api("/projects/#{snippet.project.id}/snippets/1234", admin), title: 'foo'
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 Snippet Not Found')
end
it 'returns 400 for missing parameters' do
put api("/projects/#{project.id}/snippets/1234", admin)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
context 'when the snippet is spam' do
@@ -212,7 +212,7 @@ describe API::ProjectSnippets do
expect { update_snippet(title: 'Foo', visibility: 'public') }
.not_to change { snippet.reload.title }
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['message']).to eq({ "error" => "Spam detected" })
end
@@ -230,13 +230,13 @@ describe API::ProjectSnippets do
it 'deletes snippet' do
delete api("/projects/#{snippet.project.id}/snippets/#{snippet.id}/", admin)
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
end
it 'returns 404 for invalid snippet id' do
delete api("/projects/#{snippet.project.id}/snippets/1234", admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 Snippet Not Found')
end
@@ -251,7 +251,7 @@ describe API::ProjectSnippets do
it 'returns raw text' do
get api("/projects/#{snippet.project.id}/snippets/#{snippet.id}/raw", admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response.content_type).to eq 'text/plain'
expect(response.body).to eq(snippet.content)
end
@@ -259,7 +259,7 @@ describe API::ProjectSnippets do
it 'returns 404 for invalid snippet id' do
get api("/projects/#{snippet.project.id}/snippets/1234/raw", admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 Snippet Not Found')
end
end
diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb
index 5964244f8c5..e095ba2af5d 100644
--- a/spec/requests/api/projects_spec.rb
+++ b/spec/requests/api/projects_spec.rb
@@ -45,7 +45,7 @@ describe API::Projects do
it 'returns an array of projects' do
get api('/projects', current_user), filter
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.map { |p| p['id'] }).to contain_exactly(*projects.map(&:id))
@@ -147,7 +147,7 @@ describe API::Projects do
it "does not include statistics by default" do
get api('/projects', user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.first).not_to include('statistics')
@@ -156,7 +156,7 @@ describe API::Projects do
it "includes statistics if requested" do
get api('/projects', user), statistics: true
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.first).to include 'statistics'
@@ -201,7 +201,7 @@ describe API::Projects do
get api('/projects?simple=true', user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.first.keys).to match_array expected_keys
@@ -228,7 +228,7 @@ describe API::Projects do
it 'filters based on private visibility param' do
get api('/projects', user), { visibility: 'private' }
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.map { |p| p['id'] }).to contain_exactly(project.id, project2.id, project3.id)
@@ -239,7 +239,7 @@ describe API::Projects do
get api('/projects', user), { visibility: 'internal' }
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.map { |p| p['id'] }).to contain_exactly(project2.id)
@@ -248,7 +248,7 @@ describe API::Projects do
it 'filters based on public visibility param' do
get api('/projects', user), { visibility: 'public' }
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.map { |p| p['id'] }).to contain_exactly(public_project.id)
@@ -259,7 +259,7 @@ describe API::Projects do
it 'returns the correct order when sorted by id' do
get api('/projects', user), { order_by: 'id', sort: 'desc' }
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.first['id']).to eq(project3.id)
@@ -270,7 +270,7 @@ describe API::Projects do
it 'returns an array of projects the user owns' do
get api('/projects', user4), owned: true
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.first['name']).to eq(project4.name)
@@ -289,7 +289,7 @@ describe API::Projects do
it 'returns the starred projects viewable by the user' do
get api('/projects', user3), starred: true
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.map { |project| project['id'] }).to contain_exactly(project.id, public_project.id)
@@ -311,7 +311,7 @@ describe API::Projects do
it 'returns only projects that satisfy all query parameters' do
get api('/projects', user), { visibility: 'public', owned: true, starred: true, search: 'gitlab' }
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.size).to eq(1)
@@ -330,7 +330,7 @@ describe API::Projects do
it 'returns only projects that satisfy all query parameters' do
get api('/projects', user), { visibility: 'public', membership: true, starred: true, search: 'gitlab' }
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.size).to eq(2)
@@ -363,14 +363,14 @@ describe API::Projects do
allow_any_instance_of(User).to receive(:projects_limit_left).and_return(0)
expect { post api('/projects', user2), name: 'foo' }
.to change {Project.count}.by(0)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
it 'creates new project without path but with name and returns 201' do
expect { post api('/projects', user), name: 'Foo Project' }
.to change { Project.count }.by(1)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
project = Project.first
@@ -381,7 +381,7 @@ describe API::Projects do
it 'creates new project without name but with path and returns 201' do
expect { post api('/projects', user), path: 'foo_project' }
.to change { Project.count }.by(1)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
project = Project.first
@@ -392,7 +392,7 @@ describe API::Projects do
it 'creates new project with name and path and returns 201' do
expect { post api('/projects', user), path: 'path-project-Foo', name: 'Foo Project' }
.to change { Project.count }.by(1)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
project = Project.first
@@ -403,12 +403,12 @@ describe API::Projects do
it 'creates last project before reaching project limit' do
allow_any_instance_of(User).to receive(:projects_limit_left).and_return(1)
post api('/projects', user2), name: 'foo'
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
end
it 'does not create new project without name or path and returns 400' do
expect { post api('/projects', user) }.not_to change { Project.count }
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it "assigns attributes to project" do
@@ -427,7 +427,7 @@ describe API::Projects do
post api('/projects', user), project
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
project.each_pair do |k, v|
next if %i[has_external_issue_tracker issues_enabled merge_requests_enabled wiki_enabled].include?(k)
@@ -543,7 +543,7 @@ describe API::Projects do
post api('/projects', user), project
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
end
context 'when a visibility level is restricted' do
@@ -556,7 +556,7 @@ describe API::Projects do
it 'does not allow a non-admin to use a restricted visibility level' do
post api('/projects', user), project_param
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['message']['visibility_level'].first).to(
match('restricted by your GitLab administrator')
)
@@ -576,14 +576,14 @@ describe API::Projects do
it 'returns error when user not found' do
get api('/users/9999/projects/')
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 User Not Found')
end
it 'returns projects filtered by user' do
get api("/users/#{user4.id}/projects/", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.map { |project| project['id'] }).to contain_exactly(public_project.id)
@@ -597,7 +597,7 @@ describe API::Projects do
it 'creates new project without path but with name and return 201' do
expect { post api("/projects/user/#{user.id}", admin), name: 'Foo Project' }.to change {Project.count}.by(1)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
project = Project.last
@@ -608,7 +608,7 @@ describe API::Projects do
it 'creates new project with name and path and returns 201' do
expect { post api("/projects/user/#{user.id}", admin), path: 'path-project-Foo', name: 'Foo Project' }
.to change { Project.count }.by(1)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
project = Project.last
@@ -620,7 +620,7 @@ describe API::Projects do
expect { post api("/projects/user/#{user.id}", admin) }
.not_to change { Project.count }
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['error']).to eq('name is missing')
end
@@ -634,7 +634,7 @@ describe API::Projects do
post api("/projects/user/#{user.id}", admin), project
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
project.each_pair do |k, v|
next if %i[has_external_issue_tracker path].include?(k)
expect(json_response[k.to_s]).to eq(v)
@@ -646,7 +646,7 @@ describe API::Projects do
post api("/projects/user/#{user.id}", admin), project
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['visibility']).to eq('public')
end
@@ -655,7 +655,7 @@ describe API::Projects do
post api("/projects/user/#{user.id}", admin), project
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['visibility']).to eq('internal')
end
@@ -720,7 +720,7 @@ describe API::Projects do
it "uploads the file and returns its info" do
post api("/projects/#{project.id}/uploads", user), file: fixture_file_upload(Rails.root + "spec/fixtures/dk.png", "image/png")
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['alt']).to eq("dk")
expect(json_response['url']).to start_with("/uploads/")
expect(json_response['url']).to end_with("/dk.png")
@@ -734,7 +734,7 @@ describe API::Projects do
get api("/projects/#{public_project.id}")
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['id']).to eq(public_project.id)
expect(json_response['description']).to eq(public_project.description)
expect(json_response['default_branch']).to eq(public_project.default_branch)
@@ -754,7 +754,7 @@ describe API::Projects do
get api("/projects/#{project.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['id']).to eq(project.id)
expect(json_response['description']).to eq(project.description)
expect(json_response['default_branch']).to eq(project.default_branch)
@@ -798,20 +798,20 @@ describe API::Projects do
it 'returns a project by path name' do
get api("/projects/#{project.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['name']).to eq(project.name)
end
it 'returns a 404 error if not found' do
get api('/projects/42', user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 Project Not Found')
end
it 'returns a 404 error if user is not a member' do
other_user = create(:user)
get api("/projects/#{project.id}", other_user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'handles users with dots' do
@@ -819,14 +819,14 @@ describe API::Projects do
project = create(:project, creator_id: dot_user.id, namespace: dot_user.namespace)
get api("/projects/#{CGI.escape(project.full_path)}", dot_user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['name']).to eq(project.name)
end
it 'exposes namespace fields' do
get api("/projects/#{project.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['namespace']).to eq({
'id' => user.namespace.id,
'name' => user.namespace.name,
@@ -840,28 +840,28 @@ describe API::Projects do
it "does not include statistics by default" do
get api("/projects/#{project.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).not_to include 'statistics'
end
it "includes statistics if requested" do
get api("/projects/#{project.id}", user), statistics: true
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to include 'statistics'
end
it "includes import_error if user can admin project" do
get api("/projects/#{project.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to include("import_error")
end
it "does not include import_error if user cannot admin project" do
get api("/projects/#{project.id}", user3)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).not_to include("import_error")
end
@@ -906,7 +906,7 @@ describe API::Projects do
it 'contains permission information' do
get api("/projects", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response.first['permissions']['project_access']['access_level'])
.to eq(Gitlab::Access::MASTER)
expect(json_response.first['permissions']['group_access']).to be_nil
@@ -918,7 +918,7 @@ describe API::Projects do
project.team << [user, :master]
get api("/projects/#{project.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['permissions']['project_access']['access_level'])
.to eq(Gitlab::Access::MASTER)
expect(json_response['permissions']['group_access']).to be_nil
@@ -935,7 +935,7 @@ describe API::Projects do
it 'sets the owner and return 200' do
get api("/projects/#{project2.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['permissions']['project_access']).to be_nil
expect(json_response['permissions']['group_access']['access_level'])
.to eq(Gitlab::Access::OWNER)
@@ -952,7 +952,7 @@ describe API::Projects do
user = project.namespace.owner
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.size).to eq(1)
@@ -981,7 +981,7 @@ describe API::Projects do
it 'returns a 404 error if not found' do
get api('/projects/42/users', user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 Project Not Found')
end
@@ -990,7 +990,7 @@ describe API::Projects do
get api("/projects/#{project.id}/users", other_user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -1003,7 +1003,7 @@ describe API::Projects do
it 'returns an array of project snippets' do
get api("/projects/#{project.id}/snippets", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.first['title']).to eq(snippet.title)
@@ -1013,13 +1013,13 @@ describe API::Projects do
describe 'GET /projects/:id/snippets/:snippet_id' do
it 'returns a project snippet' do
get api("/projects/#{project.id}/snippets/#{snippet.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['title']).to eq(snippet.title)
end
it 'returns a 404 error if snippet id not found' do
get api("/projects/#{project.id}/snippets/1234", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -1027,7 +1027,7 @@ describe API::Projects do
it 'creates a new project snippet' do
post api("/projects/#{project.id}/snippets", user),
title: 'api test', file_name: 'sample.rb', code: 'test', visibility: 'private'
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['title']).to eq('api test')
end
@@ -1041,7 +1041,7 @@ describe API::Projects do
it 'updates an existing project snippet' do
put api("/projects/#{project.id}/snippets/#{snippet.id}", user),
code: 'updated code'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['title']).to eq('example')
expect(snippet.reload.content).to eq('updated code')
end
@@ -1049,7 +1049,7 @@ describe API::Projects do
it 'updates an existing project snippet with new title' do
put api("/projects/#{project.id}/snippets/#{snippet.id}", user),
title: 'other api test'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['title']).to eq('other api test')
end
end
@@ -1063,13 +1063,13 @@ describe API::Projects do
expect do
delete api("/projects/#{project.id}/snippets/#{snippet.id}", user)
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
end.to change { Snippet.count }.by(-1)
end
it 'returns 404 when deleting unknown snippet id' do
delete api("/projects/#{project.id}/snippets/1234", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it_behaves_like '412 response' do
@@ -1080,12 +1080,12 @@ describe API::Projects do
describe 'GET /projects/:id/snippets/:snippet_id/raw' do
it 'gets a raw project snippet' do
get api("/projects/#{project.id}/snippets/#{snippet.id}/raw", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it 'returns a 404 error if raw project snippet not found' do
get api("/projects/#{project.id}/snippets/5555/raw", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -1098,13 +1098,13 @@ describe API::Projects do
it "is not available for non admin users" do
post api("/projects/#{project_fork_target.id}/fork/#{project_fork_source.id}", user)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
it 'allows project to be forked from an existing project' do
expect(project_fork_target.forked?).not_to be_truthy
post api("/projects/#{project_fork_target.id}/fork/#{project_fork_source.id}", admin)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
project_fork_target.reload
expect(project_fork_target.forked_from_project.id).to eq(project_fork_source.id)
expect(project_fork_target.forked_project_link).not_to be_nil
@@ -1121,7 +1121,7 @@ describe API::Projects do
it 'fails if forked_from project which does not exist' do
post api("/projects/#{project_fork_target.id}/fork/9999", admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'fails with 409 if already forked' do
@@ -1129,7 +1129,7 @@ describe API::Projects do
project_fork_target.reload
expect(project_fork_target.forked_from_project.id).to eq(project_fork_source.id)
post api("/projects/#{project_fork_target.id}/fork/#{new_project_fork_source.id}", admin)
- expect(response).to have_http_status(409)
+ expect(response).to have_gitlab_http_status(409)
project_fork_target.reload
expect(project_fork_target.forked_from_project.id).to eq(project_fork_source.id)
expect(project_fork_target.forked?).to be_truthy
@@ -1139,7 +1139,7 @@ describe API::Projects do
describe 'DELETE /projects/:id/fork' do
it "is not visible to users outside group" do
delete api("/projects/#{project_fork_target.id}/fork", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
context 'when users belong to project group' do
@@ -1161,7 +1161,7 @@ describe API::Projects do
it 'makes forked project unforked' do
delete api("/projects/#{project_fork_target.id}/fork", admin)
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
project_fork_target.reload
expect(project_fork_target.forked_from_project).to be_nil
expect(project_fork_target.forked?).not_to be_truthy
@@ -1174,13 +1174,13 @@ describe API::Projects do
it 'is forbidden to non-owner users' do
delete api("/projects/#{project_fork_target.id}/fork", user2)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
it 'is idempotent if not forked' do
expect(project_fork_target.forked_from_project).to be_nil
delete api("/projects/#{project_fork_target.id}/fork", admin)
- expect(response).to have_http_status(304)
+ expect(response).to have_gitlab_http_status(304)
expect(project_fork_target.reload.forked_from_project).to be_nil
end
end
@@ -1210,7 +1210,7 @@ describe API::Projects do
it 'returns the forks' do
get api("/projects/#{project_fork_source.id}/forks", member)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response.length).to eq(1)
expect(json_response[0]['name']).to eq(private_fork.name)
@@ -1221,7 +1221,7 @@ describe API::Projects do
it 'returns an empty array' do
get api("/projects/#{project_fork_source.id}/forks", non_member)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response.length).to eq(0)
end
@@ -1232,7 +1232,7 @@ describe API::Projects do
it 'returns an empty array' do
get api("/projects/#{project_fork_source.id}/forks")
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response.length).to eq(0)
end
@@ -1250,7 +1250,7 @@ describe API::Projects do
post api("/projects/#{project.id}/share", user), group_id: group.id, group_access: Gitlab::Access::DEVELOPER, expires_at: expires_at
end.to change { ProjectGroupLink.count }.by(1)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['group_id']).to eq(group.id)
expect(json_response['group_access']).to eq(Gitlab::Access::DEVELOPER)
expect(json_response['expires_at']).to eq(expires_at.to_s)
@@ -1258,18 +1258,18 @@ describe API::Projects do
it "returns a 400 error when group id is not given" do
post api("/projects/#{project.id}/share", user), group_access: Gitlab::Access::DEVELOPER
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it "returns a 400 error when access level is not given" do
post api("/projects/#{project.id}/share", user), group_id: group.id
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it "returns a 400 error when sharing is disabled" do
project.namespace.update(share_with_group_lock: true)
post api("/projects/#{project.id}/share", user), group_id: group.id, group_access: Gitlab::Access::DEVELOPER
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it 'returns a 404 error when user cannot read group' do
@@ -1277,19 +1277,19 @@ describe API::Projects do
post api("/projects/#{project.id}/share", user), group_id: private_group.id, group_access: Gitlab::Access::DEVELOPER
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'returns a 404 error when group does not exist' do
post api("/projects/#{project.id}/share", user), group_id: 1234, group_access: Gitlab::Access::DEVELOPER
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it "returns a 400 error when wrong params passed" do
post api("/projects/#{project.id}/share", user), group_id: group.id, group_access: 1234
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['error']).to eq 'group_access does not have a valid value'
end
end
@@ -1305,7 +1305,7 @@ describe API::Projects do
it 'returns 204 when deleting a group share' do
delete api("/projects/#{project.id}/share/#{group.id}", user)
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
expect(project.project_group_links).to be_empty
end
@@ -1317,19 +1317,19 @@ describe API::Projects do
it 'returns a 400 when group id is not an integer' do
delete api("/projects/#{project.id}/share/foo", user)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it 'returns a 404 error when group link does not exist' do
delete api("/projects/#{project.id}/share/1234", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'returns a 404 error when project does not exist' do
delete api("/projects/123/share/1234", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -1350,7 +1350,7 @@ describe API::Projects do
put api("/projects/#{project.id}", user), project_param
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['error']).to match('at least one parameter must be provided')
end
@@ -1360,7 +1360,7 @@ describe API::Projects do
put api("/projects/#{project.id}"), project_param
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
@@ -1370,7 +1370,7 @@ describe API::Projects do
put api("/projects/#{project.id}", user), project_param
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
project_param.each_pair do |k, v|
expect(json_response[k.to_s]).to eq(v)
@@ -1382,7 +1382,7 @@ describe API::Projects do
put api("/projects/#{project3.id}", user), project_param
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
project_param.each_pair do |k, v|
expect(json_response[k.to_s]).to eq(v)
@@ -1395,7 +1395,7 @@ describe API::Projects do
put api("/projects/#{project3.id}", user), project_param
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
project_param.each_pair do |k, v|
expect(json_response[k.to_s]).to eq(v)
@@ -1409,7 +1409,7 @@ describe API::Projects do
put api("/projects/#{project.id}", user), project_param
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['message']['name']).to eq(['has already been taken'])
end
@@ -1418,7 +1418,7 @@ describe API::Projects do
put api("/projects/#{project.id}", user), project_param
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['request_access_enabled']).to eq(false)
end
@@ -1427,7 +1427,7 @@ describe API::Projects do
put api("/projects/#{project3.id}", user), project_param
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
project_param.each_pair do |k, v|
expect(json_response[k.to_s]).to eq(v)
@@ -1439,7 +1439,7 @@ describe API::Projects do
put api("/projects/#{project3.id}", user), project_param
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
project_param.each_pair do |k, v|
expect(json_response[k.to_s]).to eq(v)
@@ -1451,7 +1451,7 @@ describe API::Projects do
it 'updates path' do
project_param = { path: 'bar' }
put api("/projects/#{project3.id}", user4), project_param
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
project_param.each_pair do |k, v|
expect(json_response[k.to_s]).to eq(v)
end
@@ -1465,7 +1465,7 @@ describe API::Projects do
description: 'new description' }
put api("/projects/#{project3.id}", user4), project_param
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
project_param.each_pair do |k, v|
expect(json_response[k.to_s]).to eq(v)
end
@@ -1474,20 +1474,20 @@ describe API::Projects do
it 'does not update path to existing path' do
project_param = { path: project.path }
put api("/projects/#{project3.id}", user4), project_param
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['message']['path']).to eq(['has already been taken'])
end
it 'does not update name' do
project_param = { name: 'bar' }
put api("/projects/#{project3.id}", user4), project_param
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
it 'does not update visibility_level' do
project_param = { visibility: 'public' }
put api("/projects/#{project3.id}", user4), project_param
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -1501,7 +1501,7 @@ describe API::Projects do
description: 'new description',
request_access_enabled: true }
put api("/projects/#{project.id}", user3), project_param
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
end
@@ -1511,7 +1511,7 @@ describe API::Projects do
it 'archives the project' do
post api("/projects/#{project.id}/archive", user)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['archived']).to be_truthy
end
end
@@ -1524,7 +1524,7 @@ describe API::Projects do
it 'remains archived' do
post api("/projects/#{project.id}/archive", user)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['archived']).to be_truthy
end
end
@@ -1537,7 +1537,7 @@ describe API::Projects do
it 'rejects the action' do
post api("/projects/#{project.id}/archive", user3)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
end
@@ -1547,7 +1547,7 @@ describe API::Projects do
it 'remains unarchived' do
post api("/projects/#{project.id}/unarchive", user)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['archived']).to be_falsey
end
end
@@ -1560,7 +1560,7 @@ describe API::Projects do
it 'unarchives the project' do
post api("/projects/#{project.id}/unarchive", user)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['archived']).to be_falsey
end
end
@@ -1573,7 +1573,7 @@ describe API::Projects do
it 'rejects the action' do
post api("/projects/#{project.id}/unarchive", user3)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
end
@@ -1583,7 +1583,7 @@ describe API::Projects do
it 'stars the project' do
expect { post api("/projects/#{project.id}/star", user) }.to change { project.reload.star_count }.by(1)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['star_count']).to eq(1)
end
end
@@ -1597,7 +1597,7 @@ describe API::Projects do
it 'does not modify the star count' do
expect { post api("/projects/#{project.id}/star", user) }.not_to change { project.reload.star_count }
- expect(response).to have_http_status(304)
+ expect(response).to have_gitlab_http_status(304)
end
end
end
@@ -1612,7 +1612,7 @@ describe API::Projects do
it 'unstars the project' do
expect { post api("/projects/#{project.id}/unstar", user) }.to change { project.reload.star_count }.by(-1)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['star_count']).to eq(0)
end
end
@@ -1621,7 +1621,7 @@ describe API::Projects do
it 'does not modify the star count' do
expect { post api("/projects/#{project.id}/unstar", user) }.not_to change { project.reload.star_count }
- expect(response).to have_http_status(304)
+ expect(response).to have_gitlab_http_status(304)
end
end
end
@@ -1631,7 +1631,7 @@ describe API::Projects do
it 'removes project' do
delete api("/projects/#{project.id}", user)
- expect(response).to have_http_status(202)
+ expect(response).to have_gitlab_http_status(202)
expect(json_response['message']).to eql('202 Accepted')
end
@@ -1644,17 +1644,17 @@ describe API::Projects do
user3 = create(:user)
project.team << [user3, :developer]
delete api("/projects/#{project.id}", user3)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
it 'does not remove a non existing project' do
delete api('/projects/1328', user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'does not remove a project not attached to user' do
delete api("/projects/#{project.id}", user2)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -1662,13 +1662,13 @@ describe API::Projects do
it 'removes any existing project' do
delete api("/projects/#{project.id}", admin)
- expect(response).to have_http_status(202)
+ expect(response).to have_gitlab_http_status(202)
expect(json_response['message']).to eql('202 Accepted')
end
it 'does not remove a non existing project' do
delete api('/projects/1328', admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it_behaves_like '412 response' do
@@ -1697,7 +1697,7 @@ describe API::Projects do
it 'forks if user has sufficient access to project' do
post api("/projects/#{project.id}/fork", user2)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['name']).to eq(project.name)
expect(json_response['path']).to eq(project.path)
expect(json_response['owner']['id']).to eq(user2.id)
@@ -1710,7 +1710,7 @@ describe API::Projects do
it 'forks if user is admin' do
post api("/projects/#{project.id}/fork", admin)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['name']).to eq(project.name)
expect(json_response['path']).to eq(project.path)
expect(json_response['owner']['id']).to eq(admin.id)
@@ -1724,14 +1724,14 @@ describe API::Projects do
new_user = create(:user)
post api("/projects/#{project.id}/fork", new_user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 Project Not Found')
end
it 'fails if forked project exists in the user namespace' do
post api("/projects/#{project.id}/fork", user)
- expect(response).to have_http_status(409)
+ expect(response).to have_gitlab_http_status(409)
expect(json_response['message']['name']).to eq(['has already been taken'])
expect(json_response['message']['path']).to eq(['has already been taken'])
end
@@ -1739,61 +1739,61 @@ describe API::Projects do
it 'fails if project to fork from does not exist' do
post api('/projects/424242/fork', user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 Project Not Found')
end
it 'forks with explicit own user namespace id' do
post api("/projects/#{project.id}/fork", user2), namespace: user2.namespace.id
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['owner']['id']).to eq(user2.id)
end
it 'forks with explicit own user name as namespace' do
post api("/projects/#{project.id}/fork", user2), namespace: user2.username
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['owner']['id']).to eq(user2.id)
end
it 'forks to another user when admin' do
post api("/projects/#{project.id}/fork", admin), namespace: user2.username
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['owner']['id']).to eq(user2.id)
end
it 'fails if trying to fork to another user when not admin' do
post api("/projects/#{project.id}/fork", user2), namespace: admin.namespace.id
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'fails if trying to fork to non-existent namespace' do
post api("/projects/#{project.id}/fork", user2), namespace: 42424242
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 Target Namespace Not Found')
end
it 'forks to owned group' do
post api("/projects/#{project.id}/fork", user2), namespace: group2.name
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['namespace']['name']).to eq(group2.name)
end
it 'fails to fork to not owned group' do
post api("/projects/#{project.id}/fork", user2), namespace: group.name
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'forks to not owned group when admin' do
post api("/projects/#{project.id}/fork", admin), namespace: group.name
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['namespace']['name']).to eq(group.name)
end
end
@@ -1802,7 +1802,7 @@ describe API::Projects do
it 'returns authentication error' do
post api("/projects/#{project.id}/fork")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
expect(json_response['message']).to eq('401 Unauthorized')
end
end
@@ -1821,7 +1821,7 @@ describe API::Projects do
post api("/projects/#{project.id}/housekeeping", user)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
end
context 'when housekeeping lease is taken' do
@@ -1830,7 +1830,7 @@ describe API::Projects do
post api("/projects/#{project.id}/housekeeping", user)
- expect(response).to have_http_status(409)
+ expect(response).to have_gitlab_http_status(409)
expect(json_response['message']).to match(/Somebody already triggered housekeeping for this project/)
end
end
@@ -1844,7 +1844,7 @@ describe API::Projects do
it 'returns forbidden error' do
post api("/projects/#{project.id}/housekeeping", user3)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -1852,7 +1852,7 @@ describe API::Projects do
it 'returns authentication error' do
post api("/projects/#{project.id}/housekeeping")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
end
diff --git a/spec/requests/api/repositories_spec.rb b/spec/requests/api/repositories_spec.rb
index 1a0695615e3..9f2ff3b5af6 100644
--- a/spec/requests/api/repositories_spec.rb
+++ b/spec/requests/api/repositories_spec.rb
@@ -17,7 +17,7 @@ describe API::Repositories do
it 'returns the repository tree' do
get api(route, current_user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
@@ -106,7 +106,7 @@ describe API::Repositories do
it 'returns blob attributes as json' do
get api(route, current_user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['size']).to eq(111)
expect(json_response['encoding']).to eq("base64")
expect(Base64.decode64(json_response['content']).lines.first).to eq("class Commit\n")
@@ -165,7 +165,7 @@ describe API::Repositories do
get api(route, current_user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
context 'when sha does not exist' do
@@ -218,7 +218,7 @@ describe API::Repositories do
it 'returns the repository archive' do
get api(route, current_user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
repo_name = project.repository.name.gsub("\.git", "")
type, params = workhorse_send_data
@@ -230,7 +230,7 @@ describe API::Repositories do
it 'returns the repository archive archive.zip' do
get api("/projects/#{project.id}/repository/archive.zip", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
repo_name = project.repository.name.gsub("\.git", "")
type, params = workhorse_send_data
@@ -242,7 +242,7 @@ describe API::Repositories do
it 'returns the repository archive archive.tar.bz2' do
get api("/projects/#{project.id}/repository/archive.tar.bz2", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
repo_name = project.repository.name.gsub("\.git", "")
type, params = workhorse_send_data
@@ -293,7 +293,7 @@ describe API::Repositories do
it "compares branches" do
get api(route, current_user), from: 'master', to: 'feature'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['commits']).to be_present
expect(json_response['diffs']).to be_present
end
@@ -301,7 +301,7 @@ describe API::Repositories do
it "compares tags" do
get api(route, current_user), from: 'v1.0.0', to: 'v1.1.0'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['commits']).to be_present
expect(json_response['diffs']).to be_present
end
@@ -309,7 +309,7 @@ describe API::Repositories do
it "compares commits" do
get api(route, current_user), from: sample_commit.id, to: sample_commit.parent_id
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['commits']).to be_empty
expect(json_response['diffs']).to be_empty
expect(json_response['compare_same_ref']).to be_falsey
@@ -318,7 +318,7 @@ describe API::Repositories do
it "compares commits in reverse order" do
get api(route, current_user), from: sample_commit.parent_id, to: sample_commit.id
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['commits']).to be_present
expect(json_response['diffs']).to be_present
end
@@ -326,7 +326,7 @@ describe API::Repositories do
it "compares same refs" do
get api(route, current_user), from: 'master', to: 'master'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['commits']).to be_empty
expect(json_response['diffs']).to be_empty
expect(json_response['compare_same_ref']).to be_truthy
@@ -367,7 +367,7 @@ describe API::Repositories do
it 'returns valid data' do
get api(route, current_user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
diff --git a/spec/requests/api/runner_spec.rb b/spec/requests/api/runner_spec.rb
index 5068df5b43a..47f4ccd4887 100644
--- a/spec/requests/api/runner_spec.rb
+++ b/spec/requests/api/runner_spec.rb
@@ -16,7 +16,7 @@ describe API::Runner do
it 'returns 400 error' do
post api('/runners')
- expect(response).to have_http_status 400
+ expect(response).to have_gitlab_http_status 400
end
end
@@ -24,7 +24,7 @@ describe API::Runner do
it 'returns 403 error' do
post api('/runners'), token: 'invalid'
- expect(response).to have_http_status 403
+ expect(response).to have_gitlab_http_status 403
end
end
@@ -34,7 +34,7 @@ describe API::Runner do
runner = Ci::Runner.first
- expect(response).to have_http_status 201
+ expect(response).to have_gitlab_http_status 201
expect(json_response['id']).to eq(runner.id)
expect(json_response['token']).to eq(runner.token)
expect(runner.run_untagged).to be true
@@ -47,7 +47,7 @@ describe API::Runner do
it 'creates runner' do
post api('/runners'), token: project.runners_token
- expect(response).to have_http_status 201
+ expect(response).to have_gitlab_http_status 201
expect(project.runners.size).to eq(1)
expect(Ci::Runner.first.token).not_to eq(registration_token)
expect(Ci::Runner.first.token).not_to eq(project.runners_token)
@@ -60,7 +60,7 @@ describe API::Runner do
post api('/runners'), token: registration_token,
description: 'server.hostname'
- expect(response).to have_http_status 201
+ expect(response).to have_gitlab_http_status 201
expect(Ci::Runner.first.description).to eq('server.hostname')
end
end
@@ -70,7 +70,7 @@ describe API::Runner do
post api('/runners'), token: registration_token,
tag_list: 'tag1, tag2'
- expect(response).to have_http_status 201
+ expect(response).to have_gitlab_http_status 201
expect(Ci::Runner.first.tag_list.sort).to eq(%w(tag1 tag2))
end
end
@@ -82,7 +82,7 @@ describe API::Runner do
run_untagged: false,
tag_list: ['tag']
- expect(response).to have_http_status 201
+ expect(response).to have_gitlab_http_status 201
expect(Ci::Runner.first.run_untagged).to be false
expect(Ci::Runner.first.tag_list.sort).to eq(['tag'])
end
@@ -93,7 +93,7 @@ describe API::Runner do
post api('/runners'), token: registration_token,
run_untagged: false
- expect(response).to have_http_status 404
+ expect(response).to have_gitlab_http_status 404
end
end
end
@@ -103,7 +103,7 @@ describe API::Runner do
post api('/runners'), token: registration_token,
locked: true
- expect(response).to have_http_status 201
+ expect(response).to have_gitlab_http_status 201
expect(Ci::Runner.first.locked).to be true
end
end
@@ -116,7 +116,7 @@ describe API::Runner do
post api('/runners'), token: registration_token,
info: { param => value }
- expect(response).to have_http_status 201
+ expect(response).to have_gitlab_http_status 201
expect(Ci::Runner.first.read_attribute(param.to_sym)).to eq(value)
end
end
@@ -128,7 +128,7 @@ describe API::Runner do
it 'returns 400 error' do
delete api('/runners')
- expect(response).to have_http_status 400
+ expect(response).to have_gitlab_http_status 400
end
end
@@ -136,7 +136,7 @@ describe API::Runner do
it 'returns 403 error' do
delete api('/runners'), token: 'invalid'
- expect(response).to have_http_status 403
+ expect(response).to have_gitlab_http_status 403
end
end
@@ -146,7 +146,7 @@ describe API::Runner do
it 'deletes Runner' do
delete api('/runners'), token: runner.token
- expect(response).to have_http_status 204
+ expect(response).to have_gitlab_http_status 204
expect(Ci::Runner.count).to eq(0)
end
@@ -164,7 +164,7 @@ describe API::Runner do
it 'returns 400 error' do
post api('/runners/verify')
- expect(response).to have_http_status :bad_request
+ expect(response).to have_gitlab_http_status :bad_request
end
end
@@ -172,7 +172,7 @@ describe API::Runner do
it 'returns 403 error' do
post api('/runners/verify'), token: 'invalid-token'
- expect(response).to have_http_status 403
+ expect(response).to have_gitlab_http_status 403
end
end
@@ -180,7 +180,7 @@ describe API::Runner do
it 'verifies Runner credentials' do
post api('/runners/verify'), token: runner.token
- expect(response).to have_http_status 200
+ expect(response).to have_gitlab_http_status 200
end
end
end
@@ -216,7 +216,7 @@ describe API::Runner do
context 'when runner sends version in User-Agent' do
context 'for stable version' do
it 'gives 204 and set X-GitLab-Last-Update' do
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
expect(response.header).to have_key('X-GitLab-Last-Update')
end
end
@@ -225,7 +225,7 @@ describe API::Runner do
let(:last_update) { runner.ensure_runner_queue_value }
it 'gives 204 and set the same X-GitLab-Last-Update' do
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
expect(response.header['X-GitLab-Last-Update']).to eq(last_update)
end
end
@@ -235,7 +235,7 @@ describe API::Runner do
let(:new_update) { runner.tick_runner_queue }
it 'gives 204 and set a new X-GitLab-Last-Update' do
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
expect(response.header['X-GitLab-Last-Update']).to eq(new_update)
end
end
@@ -243,19 +243,19 @@ describe API::Runner do
context 'when beta version is sent' do
let(:user_agent) { 'gitlab-runner 9.0.0~beta.167.g2b2bacc (master; go1.7.4; linux/amd64)' }
- it { expect(response).to have_http_status(204) }
+ it { expect(response).to have_gitlab_http_status(204) }
end
context 'when pre-9-0 version is sent' do
let(:user_agent) { 'gitlab-ci-multi-runner 1.6.0 (1-6-stable; go1.6.3; linux/amd64)' }
- it { expect(response).to have_http_status(204) }
+ it { expect(response).to have_gitlab_http_status(204) }
end
context 'when pre-9-0 beta version is sent' do
let(:user_agent) { 'gitlab-ci-multi-runner 1.6.0~beta.167.g2b2bacc (master; go1.6.3; linux/amd64)' }
- it { expect(response).to have_http_status(204) }
+ it { expect(response).to have_gitlab_http_status(204) }
end
end
end
@@ -264,7 +264,7 @@ describe API::Runner do
it 'returns 400 error' do
post api('/jobs/request')
- expect(response).to have_http_status 400
+ expect(response).to have_gitlab_http_status 400
end
end
@@ -272,7 +272,7 @@ describe API::Runner do
it 'returns 403 error' do
post api('/jobs/request'), token: 'invalid'
- expect(response).to have_http_status 403
+ expect(response).to have_gitlab_http_status 403
end
end
@@ -283,7 +283,7 @@ describe API::Runner do
it 'returns 204 error' do
request_job
- expect(response).to have_http_status 204
+ expect(response).to have_gitlab_http_status 204
end
end
@@ -365,7 +365,7 @@ describe API::Runner do
it 'picks a job' do
request_job info: { platform: :darwin }
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(response.headers).not_to have_key('X-GitLab-Last-Update')
expect(runner.reload.platform).to eq('darwin')
expect(json_response['id']).to eq(job.id)
@@ -385,12 +385,12 @@ describe API::Runner do
end
context 'when job is made for tag' do
- let!(:job) { create(:ci_build_tag, pipeline: pipeline, name: 'spinach', stage: 'test', stage_idx: 0) }
+ let!(:job) { create(:ci_build, :tag, pipeline: pipeline, name: 'spinach', stage: 'test', stage_idx: 0) }
it 'sets branch as ref_type' do
request_job
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['git_info']['ref_type']).to eq('tag')
end
end
@@ -399,7 +399,7 @@ describe API::Runner do
it 'sets tag as ref_type' do
request_job
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['git_info']['ref_type']).to eq('branch')
end
end
@@ -415,7 +415,7 @@ describe API::Runner do
it "updates provided Runner's parameter" do
request_job info: { param => value }
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(runner.reload.read_attribute(param.to_sym)).to eq(value)
end
end
@@ -430,14 +430,14 @@ describe API::Runner do
it 'returns a conflict' do
request_job
- expect(response).to have_http_status(409)
+ expect(response).to have_gitlab_http_status(409)
expect(response.headers).not_to have_key('X-GitLab-Last-Update')
end
end
context 'when project and pipeline have multiple jobs' do
- let!(:job) { create(:ci_build_tag, pipeline: pipeline, name: 'spinach', stage: 'test', stage_idx: 0) }
- let!(:job2) { create(:ci_build_tag, pipeline: pipeline, name: 'rubocop', stage: 'test', stage_idx: 0) }
+ let!(:job) { create(:ci_build, :tag, pipeline: pipeline, name: 'spinach', stage: 'test', stage_idx: 0) }
+ let!(:job2) { create(:ci_build, :tag, pipeline: pipeline, name: 'rubocop', stage: 'test', stage_idx: 0) }
let!(:test_job) { create(:ci_build, pipeline: pipeline, name: 'deploy', stage: 'deploy', stage_idx: 1) }
before do
@@ -448,7 +448,7 @@ describe API::Runner do
it 'returns dependent jobs' do
request_job
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['id']).to eq(test_job.id)
expect(json_response['dependencies'].count).to eq(2)
expect(json_response['dependencies']).to include(
@@ -458,7 +458,7 @@ describe API::Runner do
end
context 'when pipeline have jobs with artifacts' do
- let!(:job) { create(:ci_build_tag, :artifacts, pipeline: pipeline, name: 'spinach', stage: 'test', stage_idx: 0) }
+ let!(:job) { create(:ci_build, :tag, :artifacts, pipeline: pipeline, name: 'spinach', stage: 'test', stage_idx: 0) }
let!(:test_job) { create(:ci_build, pipeline: pipeline, name: 'deploy', stage: 'deploy', stage_idx: 1) }
before do
@@ -468,7 +468,7 @@ describe API::Runner do
it 'returns dependent jobs' do
request_job
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['id']).to eq(test_job.id)
expect(json_response['dependencies'].count).to eq(1)
expect(json_response['dependencies']).to include(
@@ -478,8 +478,8 @@ describe API::Runner do
end
context 'when explicit dependencies are defined' do
- let!(:job) { create(:ci_build_tag, pipeline: pipeline, name: 'spinach', stage: 'test', stage_idx: 0) }
- let!(:job2) { create(:ci_build_tag, pipeline: pipeline, name: 'rubocop', stage: 'test', stage_idx: 0) }
+ let!(:job) { create(:ci_build, :tag, pipeline: pipeline, name: 'spinach', stage: 'test', stage_idx: 0) }
+ let!(:job2) { create(:ci_build, :tag, pipeline: pipeline, name: 'rubocop', stage: 'test', stage_idx: 0) }
let!(:test_job) do
create(:ci_build, pipeline: pipeline, token: 'test-job-token', name: 'deploy',
stage: 'deploy', stage_idx: 1,
@@ -494,7 +494,7 @@ describe API::Runner do
it 'returns dependent jobs' do
request_job
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['id']).to eq(test_job.id)
expect(json_response['dependencies'].count).to eq(1)
expect(json_response['dependencies'][0]).to include('id' => job2.id, 'name' => job2.name, 'token' => job2.token)
@@ -502,8 +502,8 @@ describe API::Runner do
end
context 'when dependencies is an empty array' do
- let!(:job) { create(:ci_build_tag, pipeline: pipeline, name: 'spinach', stage: 'test', stage_idx: 0) }
- let!(:job2) { create(:ci_build_tag, pipeline: pipeline, name: 'rubocop', stage: 'test', stage_idx: 0) }
+ let!(:job) { create(:ci_build, :tag, pipeline: pipeline, name: 'spinach', stage: 'test', stage_idx: 0) }
+ let!(:job2) { create(:ci_build, :tag, pipeline: pipeline, name: 'rubocop', stage: 'test', stage_idx: 0) }
let!(:empty_dependencies_job) do
create(:ci_build, pipeline: pipeline, token: 'test-job-token', name: 'empty_dependencies_job',
stage: 'deploy', stage_idx: 1,
@@ -518,7 +518,7 @@ describe API::Runner do
it 'returns an empty array' do
request_job
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['id']).to eq(empty_dependencies_job.id)
expect(json_response['dependencies'].count).to eq(0)
end
@@ -537,7 +537,7 @@ describe API::Runner do
it 'picks job' do
request_job
- expect(response).to have_http_status 201
+ expect(response).to have_gitlab_http_status 201
end
end
@@ -571,7 +571,7 @@ describe API::Runner do
it 'returns variables for triggers' do
request_job
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['variables']).to include(*expected_variables)
end
end
@@ -683,7 +683,7 @@ describe API::Runner do
it 'updates a running build' do
update_job(trace: 'BUILD TRACE UPDATED')
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(job.reload.trace.raw).to eq 'BUILD TRACE UPDATED'
end
end
@@ -702,7 +702,7 @@ describe API::Runner do
it 'responds with forbidden' do
update_job
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -871,7 +871,7 @@ describe API::Runner do
it 'authorizes posting artifacts to running job' do
authorize_artifacts_with_token_in_params
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response.content_type.to_s).to eq(Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE)
expect(json_response['TempPath']).not_to be_nil
end
@@ -881,7 +881,7 @@ describe API::Runner do
authorize_artifacts_with_token_in_params(filesize: 100)
- expect(response).to have_http_status(413)
+ expect(response).to have_gitlab_http_status(413)
end
end
@@ -889,7 +889,7 @@ describe API::Runner do
it 'authorizes posting artifacts to running job' do
authorize_artifacts_with_token_in_headers
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response.content_type.to_s).to eq(Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE)
expect(json_response['TempPath']).not_to be_nil
end
@@ -899,7 +899,7 @@ describe API::Runner do
authorize_artifacts_with_token_in_headers(filesize: 100)
- expect(response).to have_http_status(413)
+ expect(response).to have_gitlab_http_status(413)
end
end
@@ -907,7 +907,7 @@ describe API::Runner do
it 'fails to authorize artifacts posting' do
authorize_artifacts(token: job.project.runners_token)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -916,14 +916,14 @@ describe API::Runner do
authorize_artifacts
- expect(response).to have_http_status(500)
+ expect(response).to have_gitlab_http_status(500)
end
context 'authorization token is invalid' do
it 'responds with forbidden' do
authorize_artifacts(token: 'invalid', filesize: 100 )
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -958,14 +958,14 @@ describe API::Runner do
it 'responds with forbidden' do
upload_artifacts(file_upload, headers_with_token)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
context 'when job is running' do
shared_examples 'successful artifacts upload' do
it 'updates successfully' do
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
end
end
@@ -998,7 +998,7 @@ describe API::Runner do
it 'responds with forbidden' do
upload_artifacts(file_upload, headers.merge(API::Helpers::Runner::JOB_TOKEN_HEADER => job.project.runners_token))
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
end
@@ -1009,7 +1009,7 @@ describe API::Runner do
upload_artifacts(file_upload, headers_with_token)
- expect(response).to have_http_status(413)
+ expect(response).to have_gitlab_http_status(413)
end
end
@@ -1017,7 +1017,7 @@ describe API::Runner do
it 'fails to post artifacts without file' do
post api("/jobs/#{job.id}/artifacts"), {}, headers_with_token
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
end
@@ -1025,7 +1025,7 @@ describe API::Runner do
it 'fails to post artifacts without GitLab-Workhorse' do
post api("/jobs/#{job.id}/artifacts"), { token: job.token }, {}
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -1047,7 +1047,7 @@ describe API::Runner do
let(:expire_in) { '7 days' }
it 'updates when specified' do
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(job.reload.artifacts_expire_at).to be_within(5.minutes).of(7.days.from_now)
end
end
@@ -1056,7 +1056,7 @@ describe API::Runner do
let(:expire_in) { nil }
it 'ignores if not specified' do
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(job.reload.artifacts_expire_at).to be_nil
end
@@ -1065,7 +1065,7 @@ describe API::Runner do
let(:default_artifacts_expire_in) { '5 days' }
it 'sets to application default' do
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(job.reload.artifacts_expire_at).to be_within(5.minutes).of(5.days.from_now)
end
end
@@ -1074,7 +1074,7 @@ describe API::Runner do
let(:default_artifacts_expire_in) { '0' }
it 'does not set expire_in' do
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(job.reload.artifacts_expire_at).to be_nil
end
end
@@ -1103,7 +1103,7 @@ describe API::Runner do
end
it 'stores artifacts and artifacts metadata' do
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(stored_artifacts_file.original_filename).to eq(artifacts.original_filename)
expect(stored_metadata_file.original_filename).to eq(metadata.original_filename)
expect(stored_artifacts_size).to eq(71759)
@@ -1116,7 +1116,7 @@ describe API::Runner do
end
it 'is expected to respond with bad request' do
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it 'does not store metadata' do
@@ -1141,7 +1141,7 @@ describe API::Runner do
it' "fails to post artifacts for outside of tmp path"' do
upload_artifacts(file_upload, headers_with_token)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
end
@@ -1171,7 +1171,7 @@ describe API::Runner do
context 'when using job token' do
it 'download artifacts' do
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response.headers).to include download_headers
end
end
@@ -1180,14 +1180,14 @@ describe API::Runner do
let(:token) { job.project.runners_token }
it 'responds with forbidden' do
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
end
context 'when job does not has artifacts' do
it 'responds with not found' do
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
diff --git a/spec/requests/api/runners_spec.rb b/spec/requests/api/runners_spec.rb
index 67907579225..fe38a7b3251 100644
--- a/spec/requests/api/runners_spec.rb
+++ b/spec/requests/api/runners_spec.rb
@@ -37,7 +37,7 @@ describe API::Runners do
get api('/runners', user)
shared = json_response.any? { |r| r['is_shared'] }
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(shared).to be_falsey
@@ -47,7 +47,7 @@ describe API::Runners do
get api('/runners?scope=active', user)
shared = json_response.any? { |r| r['is_shared'] }
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(shared).to be_falsey
@@ -55,7 +55,7 @@ describe API::Runners do
it 'avoids filtering if scope is invalid' do
get api('/runners?scope=unknown', user)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
end
@@ -63,7 +63,7 @@ describe API::Runners do
it 'does not return runners' do
get api('/runners')
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
end
@@ -75,7 +75,7 @@ describe API::Runners do
get api('/runners/all', admin)
shared = json_response.any? { |r| r['is_shared'] }
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(shared).to be_truthy
@@ -86,7 +86,7 @@ describe API::Runners do
it 'does not return runners list' do
get api('/runners/all', user)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -94,7 +94,7 @@ describe API::Runners do
get api('/runners/all?scope=specific', admin)
shared = json_response.any? { |r| r['is_shared'] }
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(shared).to be_falsey
@@ -102,7 +102,7 @@ describe API::Runners do
it 'avoids filtering if scope is invalid' do
get api('/runners?scope=unknown', admin)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
end
@@ -110,7 +110,7 @@ describe API::Runners do
it 'does not return runners' do
get api('/runners')
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
end
@@ -121,7 +121,7 @@ describe API::Runners do
it "returns runner's details" do
get api("/runners/#{shared_runner.id}", admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['description']).to eq(shared_runner.description)
end
end
@@ -130,7 +130,7 @@ describe API::Runners do
it "returns runner's details" do
get api("/runners/#{specific_runner.id}", admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['description']).to eq(specific_runner.description)
end
end
@@ -138,7 +138,7 @@ describe API::Runners do
it 'returns 404 if runner does not exists' do
get api('/runners/9999', admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -147,7 +147,7 @@ describe API::Runners do
it "returns runner's details" do
get api("/runners/#{specific_runner.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['description']).to eq(specific_runner.description)
end
end
@@ -156,7 +156,7 @@ describe API::Runners do
it "returns runner's details" do
get api("/runners/#{shared_runner.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['description']).to eq(shared_runner.description)
end
end
@@ -166,7 +166,7 @@ describe API::Runners do
it "does not return runner's details" do
get api("/runners/#{specific_runner.id}", user2)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -174,7 +174,7 @@ describe API::Runners do
it "does not return runner's details" do
get api("/runners/#{specific_runner.id}")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
end
@@ -195,7 +195,7 @@ describe API::Runners do
access_level: 'ref_protected')
shared_runner.reload
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(shared_runner.description).to eq("#{description}_updated")
expect(shared_runner.active).to eq(!active)
expect(shared_runner.tag_list).to include('ruby2.1', 'pgsql', 'mysql')
@@ -215,7 +215,7 @@ describe API::Runners do
update_runner(specific_runner.id, admin, description: 'test')
specific_runner.reload
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(specific_runner.description).to eq('test')
expect(specific_runner.description).not_to eq(description)
expect(specific_runner.ensure_runner_queue_value)
@@ -226,7 +226,7 @@ describe API::Runners do
it 'returns 404 if runner does not exists' do
update_runner(9999, admin, description: 'test')
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
def update_runner(id, user, args)
@@ -239,7 +239,7 @@ describe API::Runners do
it 'does not update runner' do
put api("/runners/#{shared_runner.id}", user), description: 'test'
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -247,7 +247,7 @@ describe API::Runners do
it 'does not update runner without access to it' do
put api("/runners/#{specific_runner.id}", user2), description: 'test'
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
it 'updates runner with access to it' do
@@ -255,7 +255,7 @@ describe API::Runners do
put api("/runners/#{specific_runner.id}", admin), description: 'test'
specific_runner.reload
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(specific_runner.description).to eq('test')
expect(specific_runner.description).not_to eq(description)
end
@@ -266,7 +266,7 @@ describe API::Runners do
it 'does not delete runner' do
put api("/runners/#{specific_runner.id}")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
end
@@ -278,7 +278,7 @@ describe API::Runners do
expect do
delete api("/runners/#{shared_runner.id}", admin)
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
end.to change { Ci::Runner.shared.count }.by(-1)
end
@@ -292,7 +292,7 @@ describe API::Runners do
expect do
delete api("/runners/#{unused_specific_runner.id}", admin)
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
end.to change { Ci::Runner.specific.count }.by(-1)
end
@@ -300,7 +300,7 @@ describe API::Runners do
expect do
delete api("/runners/#{specific_runner.id}", admin)
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
end.to change { Ci::Runner.specific.count }.by(-1)
end
end
@@ -308,7 +308,7 @@ describe API::Runners do
it 'returns 404 if runner does not exists' do
delete api('/runners/9999', admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -316,26 +316,26 @@ describe API::Runners do
context 'when runner is shared' do
it 'does not delete runner' do
delete api("/runners/#{shared_runner.id}", user)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
context 'when runner is not shared' do
it 'does not delete runner without access to it' do
delete api("/runners/#{specific_runner.id}", user2)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
it 'does not delete runner with more than one associated project' do
delete api("/runners/#{two_projects_runner.id}", user)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
it 'deletes runner for one owned project' do
expect do
delete api("/runners/#{specific_runner.id}", user)
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
end.to change { Ci::Runner.specific.count }.by(-1)
end
@@ -349,7 +349,7 @@ describe API::Runners do
it 'does not delete runner' do
delete api("/runners/#{specific_runner.id}")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
end
@@ -360,7 +360,7 @@ describe API::Runners do
get api("/projects/#{project.id}/runners", user)
shared = json_response.any? { |r| r['is_shared'] }
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(shared).to be_truthy
@@ -371,7 +371,7 @@ describe API::Runners do
it "does not return project's runners" do
get api("/projects/#{project.id}/runners", user2)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -379,7 +379,7 @@ describe API::Runners do
it "does not return project's runners" do
get api("/projects/#{project.id}/runners")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
end
@@ -396,14 +396,14 @@ describe API::Runners do
expect do
post api("/projects/#{project.id}/runners", user), runner_id: specific_runner2.id
end.to change { project.runners.count }.by(+1)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
end
it 'avoids changes when enabling already enabled runner' do
expect do
post api("/projects/#{project.id}/runners", user), runner_id: specific_runner.id
end.to change { project.runners.count }.by(0)
- expect(response).to have_http_status(409)
+ expect(response).to have_gitlab_http_status(409)
end
it 'does not enable locked runner' do
@@ -413,13 +413,13 @@ describe API::Runners do
post api("/projects/#{project.id}/runners", user), runner_id: specific_runner2.id
end.to change { project.runners.count }.by(0)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
it 'does not enable shared runner' do
post api("/projects/#{project.id}/runners", user), runner_id: shared_runner.id
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
context 'user is admin' do
@@ -427,7 +427,7 @@ describe API::Runners do
expect do
post api("/projects/#{project.id}/runners", admin), runner_id: unused_specific_runner.id
end.to change { project.runners.count }.by(+1)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
end
end
@@ -435,14 +435,14 @@ describe API::Runners do
it 'does not enable runner without access to' do
post api("/projects/#{project.id}/runners", user), runner_id: unused_specific_runner.id
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
it 'raises an error when no runner_id param is provided' do
post api("/projects/#{project.id}/runners", admin)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
end
@@ -450,7 +450,7 @@ describe API::Runners do
it 'does not enable runner' do
post api("/projects/#{project.id}/runners", user2)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -458,7 +458,7 @@ describe API::Runners do
it 'does not enable runner' do
post api("/projects/#{project.id}/runners")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
end
@@ -470,7 +470,7 @@ describe API::Runners do
expect do
delete api("/projects/#{project.id}/runners/#{two_projects_runner.id}", user)
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
end.to change { project.runners.count }.by(-1)
end
@@ -484,14 +484,14 @@ describe API::Runners do
expect do
delete api("/projects/#{project.id}/runners/#{specific_runner.id}", user)
end.to change { project.runners.count }.by(0)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
it 'returns 404 is runner is not found' do
delete api("/projects/#{project.id}/runners/9999", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -499,7 +499,7 @@ describe API::Runners do
it "does not disable project's runner" do
delete api("/projects/#{project.id}/runners/#{specific_runner.id}", user2)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -507,7 +507,7 @@ describe API::Runners do
it "does not disable project's runner" do
delete api("/projects/#{project.id}/runners/#{specific_runner.id}")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
end
diff --git a/spec/requests/api/services_spec.rb b/spec/requests/api/services_spec.rb
index 7e174903918..dfe48e45d49 100644
--- a/spec/requests/api/services_spec.rb
+++ b/spec/requests/api/services_spec.rb
@@ -16,7 +16,7 @@ describe API::Services do
it "updates #{service} settings" do
put api("/projects/#{project.id}/services/#{dashed_service}", user), service_attrs
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
current_service = project.services.first
event = current_service.event_names.empty? ? "foo" : current_service.event_names.first
@@ -24,7 +24,7 @@ describe API::Services do
put api("/projects/#{project.id}/services/#{dashed_service}?#{event}=#{!state}", user), service_attrs
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(project.services.first[event]).not_to eq(state) unless event == "foo"
end
@@ -56,7 +56,7 @@ describe API::Services do
it "deletes #{service}" do
delete api("/projects/#{project.id}/services/#{dashed_service}", user)
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
project.send(service_method).reload
expect(project.send(service_method).activated?).to be_falsey
end
@@ -74,20 +74,20 @@ describe API::Services do
it 'returns authentication error when unauthenticated' do
get api("/projects/#{project.id}/services/#{dashed_service}")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
it "returns all properties of service #{service} when authenticated as admin" do
get api("/projects/#{project.id}/services/#{dashed_service}", admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['properties'].keys.map(&:to_sym)).to match_array(service_attrs_list.map)
end
it "returns properties of service #{service} other than passwords when authenticated as project owner" do
get api("/projects/#{project.id}/services/#{dashed_service}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['properties'].keys.map(&:to_sym)).to match_array(service_attrs_list_without_passwords)
end
@@ -95,7 +95,7 @@ describe API::Services do
project.team << [user2, :developer]
get api("/projects/#{project.id}/services/#{dashed_service}", user2)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
end
@@ -108,7 +108,7 @@ describe API::Services do
it 'returns a not found message' do
post api("/projects/#{project.id}/services/idonotexist/trigger")
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response["error"]).to eq("404 Not Found")
end
end
@@ -127,7 +127,7 @@ describe API::Services do
it 'when the service is inactive' do
post api("/projects/#{project.id}/services/#{service_name}/trigger"), params
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -142,7 +142,7 @@ describe API::Services do
it 'returns status 200' do
post api("/projects/#{project.id}/services/#{service_name}/trigger"), params
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
end
@@ -150,7 +150,7 @@ describe API::Services do
it 'returns a generic 404' do
post api("/projects/404/services/#{service_name}/trigger"), params
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response["message"]).to eq("404 Service Not Found")
end
end
@@ -170,7 +170,7 @@ describe API::Services do
it 'returns status 200' do
post api("/projects/#{project.id}/services/#{service_name}/trigger"), token: 'token', text: 'help'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['response_type']).to eq("ephemeral")
end
end
diff --git a/spec/requests/api/session_spec.rb b/spec/requests/api/session_spec.rb
index 5e77519c867..83d09878813 100644
--- a/spec/requests/api/session_spec.rb
+++ b/spec/requests/api/session_spec.rb
@@ -7,7 +7,7 @@ describe API::Session do
context "when valid password" do
it "returns private token" do
post api("/session"), email: user.email, password: '12345678'
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['email']).to eq(user.email)
expect(json_response['private_token']).to eq(user.private_token)
@@ -22,7 +22,7 @@ describe API::Session do
post api('/session'), email: user.email, password: user.password
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
expect(response.body).to include('You have 2FA enabled.')
end
end
@@ -57,7 +57,7 @@ describe API::Session do
context "when invalid password" do
it "returns authentication error" do
post api("/session"), email: user.email, password: '123'
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
expect(json_response['email']).to be_nil
expect(json_response['private_token']).to be_nil
@@ -68,13 +68,13 @@ describe API::Session do
it "returns authentication error with email" do
post api("/session"), email: user.email
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it "returns authentication error with username" do
post api("/session"), email: user.username
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
end
@@ -82,7 +82,7 @@ describe API::Session do
it "returns authentication error" do
post api("/session"), password: user.password
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
end
@@ -91,7 +91,7 @@ describe API::Session do
user.block
post api("/session"), email: user.username, password: user.password
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
@@ -100,7 +100,7 @@ describe API::Session do
user.ldap_block
post api("/session"), email: user.username, password: user.password
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
end
diff --git a/spec/requests/api/settings_spec.rb b/spec/requests/api/settings_spec.rb
index c24de58ee9d..5d3e78dd7c8 100644
--- a/spec/requests/api/settings_spec.rb
+++ b/spec/requests/api/settings_spec.rb
@@ -7,7 +7,7 @@ describe API::Settings, 'Settings' do
describe "GET /application/settings" do
it "returns application settings" do
get api("/application/settings", admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Hash
expect(json_response['default_projects_limit']).to eq(42)
expect(json_response['password_authentication_enabled']).to be_truthy
@@ -56,7 +56,7 @@ describe API::Settings, 'Settings' do
ed25519_key_restriction: 256,
circuitbreaker_failure_wait_time: 2
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['default_projects_limit']).to eq(3)
expect(json_response['password_authentication_enabled']).to be_falsey
expect(json_response['repository_storages']).to eq(['custom'])
@@ -83,7 +83,7 @@ describe API::Settings, 'Settings' do
it "returns a blank parameter error message" do
put api("/application/settings", admin), koding_enabled: true
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['error']).to eq('koding_url is missing')
end
end
@@ -92,7 +92,7 @@ describe API::Settings, 'Settings' do
it "returns a blank parameter error message" do
put api("/application/settings", admin), plantuml_enabled: true
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['error']).to eq('plantuml_url is missing')
end
end
diff --git a/spec/requests/api/sidekiq_metrics_spec.rb b/spec/requests/api/sidekiq_metrics_spec.rb
index 83042d0cb12..fff9adb7f57 100644
--- a/spec/requests/api/sidekiq_metrics_spec.rb
+++ b/spec/requests/api/sidekiq_metrics_spec.rb
@@ -7,28 +7,28 @@ describe API::SidekiqMetrics do
it 'defines the `queue_metrics` endpoint' do
get api('/sidekiq/queue_metrics', admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_a Hash
end
it 'defines the `process_metrics` endpoint' do
get api('/sidekiq/process_metrics', admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['processes']).to be_an Array
end
it 'defines the `job_stats` endpoint' do
get api('/sidekiq/job_stats', admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_a Hash
end
it 'defines the `compound_metrics` endpoint' do
get api('/sidekiq/compound_metrics', admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_a Hash
expect(json_response['queues']).to be_a Hash
expect(json_response['processes']).to be_an Array
diff --git a/spec/requests/api/snippets_spec.rb b/spec/requests/api/snippets_spec.rb
index d3905f698bd..74198c8eb4f 100644
--- a/spec/requests/api/snippets_spec.rb
+++ b/spec/requests/api/snippets_spec.rb
@@ -11,7 +11,7 @@ describe API::Snippets do
get api("/snippets/", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.map { |snippet| snippet['id']} ).to contain_exactly(
@@ -27,7 +27,7 @@ describe API::Snippets do
get api("/snippets/", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.size).to eq(0)
@@ -46,7 +46,7 @@ describe API::Snippets do
it 'returns all snippets with public visibility from all users' do
get api("/snippets/public", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.map { |snippet| snippet['id']} ).to contain_exactly(
@@ -67,7 +67,7 @@ describe API::Snippets do
it 'returns raw text' do
get api("/snippets/#{snippet.id}/raw", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response.content_type).to eq 'text/plain'
expect(response.body).to eq(snippet.content)
end
@@ -75,7 +75,7 @@ describe API::Snippets do
it 'returns 404 for invalid snippet id' do
get api("/snippets/1234/raw", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 Snippet Not Found')
end
end
@@ -86,7 +86,7 @@ describe API::Snippets do
it 'returns snippet json' do
get api("/snippets/#{snippet.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['title']).to eq(snippet.title)
expect(json_response['description']).to eq(snippet.description)
@@ -96,7 +96,7 @@ describe API::Snippets do
it 'returns 404 for invalid snippet id' do
get api("/snippets/1234", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 Not found')
end
end
@@ -117,7 +117,7 @@ describe API::Snippets do
post api("/snippets/", user), params
end.to change { PersonalSnippet.count }.by(1)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['title']).to eq(params[:title])
expect(json_response['description']).to eq(params[:description])
expect(json_response['file_name']).to eq(params[:file_name])
@@ -128,7 +128,7 @@ describe API::Snippets do
post api("/snippets/", user), params
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
context 'when the snippet is spam' do
@@ -152,7 +152,7 @@ describe API::Snippets do
expect { create_snippet(visibility: 'public') }
.not_to change { Snippet.count }
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['message']).to eq({ "error" => "Spam detected" })
end
@@ -177,7 +177,7 @@ describe API::Snippets do
put api("/snippets/#{snippet.id}", user), content: new_content, description: new_description
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
snippet.reload
expect(snippet.content).to eq(new_content)
expect(snippet.description).to eq(new_description)
@@ -186,21 +186,21 @@ describe API::Snippets do
it 'returns 404 for invalid snippet id' do
put api("/snippets/1234", user), title: 'foo'
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 Snippet Not Found')
end
it "returns 404 for another user's snippet" do
put api("/snippets/#{snippet.id}", other_user), title: 'fubar'
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 Snippet Not Found')
end
it 'returns 400 for missing parameters' do
put api("/snippets/1234", user)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
context 'when the snippet is spam' do
@@ -228,7 +228,7 @@ describe API::Snippets do
expect { update_snippet(title: 'Foo') }
.not_to change { snippet.reload.title }
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['message']).to eq({ "error" => "Spam detected" })
end
@@ -260,14 +260,14 @@ describe API::Snippets do
expect do
delete api("/snippets/#{public_snippet.id}", user)
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
end.to change { PersonalSnippet.count }.by(-1)
end
it 'returns 404 for invalid snippet id' do
delete api("/snippets/1234", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 Snippet Not Found')
end
@@ -284,7 +284,7 @@ describe API::Snippets do
it 'exposes known attributes' do
get api("/snippets/#{snippet.id}/user_agent_detail", admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['user_agent']).to eq(user_agent_detail.user_agent)
expect(json_response['ip_address']).to eq(user_agent_detail.ip_address)
expect(json_response['akismet_submitted']).to eq(user_agent_detail.submitted)
@@ -293,7 +293,7 @@ describe API::Snippets do
it "returns unautorized for non-admin users" do
get api("/snippets/#{snippet.id}/user_agent_detail", user)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
end
diff --git a/spec/requests/api/system_hooks_spec.rb b/spec/requests/api/system_hooks_spec.rb
index 216d278ad21..c7a009e999e 100644
--- a/spec/requests/api/system_hooks_spec.rb
+++ b/spec/requests/api/system_hooks_spec.rb
@@ -14,7 +14,7 @@ describe API::SystemHooks do
it "returns authentication error" do
get api("/hooks")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
@@ -22,7 +22,7 @@ describe API::SystemHooks do
it "returns forbidden error" do
get api("/hooks", user)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -30,7 +30,7 @@ describe API::SystemHooks do
it "returns an array of hooks" do
get api("/hooks", admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.first['url']).to eq(hook.url)
@@ -51,13 +51,13 @@ describe API::SystemHooks do
it "responds with 400 if url not given" do
post api("/hooks", admin)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it "responds with 400 if url is invalid" do
post api("/hooks", admin), url: 'hp://mep.mep'
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it "does not create new hook without url" do
@@ -69,7 +69,7 @@ describe API::SystemHooks do
it 'sets default values for events' do
post api('/hooks', admin), url: 'http://mep.mep', enable_ssl_verification: true
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['enable_ssl_verification']).to be true
expect(json_response['tag_push_events']).to be false
end
@@ -78,13 +78,13 @@ describe API::SystemHooks do
describe "GET /hooks/:id" do
it "returns hook by id" do
get api("/hooks/#{hook.id}", admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['event_name']).to eq('project_create')
end
it "returns 404 on failure" do
get api("/hooks/404", admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -93,14 +93,14 @@ describe API::SystemHooks do
expect do
delete api("/hooks/#{hook.id}", admin)
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
end.to change { SystemHook.count }.by(-1)
end
it 'returns 404 if the system hook does not exist' do
delete api('/hooks/12345', admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it_behaves_like '412 response' do
diff --git a/spec/requests/api/templates_spec.rb b/spec/requests/api/templates_spec.rb
index f8af9295842..de1619f33c1 100644
--- a/spec/requests/api/templates_spec.rb
+++ b/spec/requests/api/templates_spec.rb
@@ -23,7 +23,7 @@ describe API::Templates do
it 'returns a list of available gitignore templates' do
get api('/templates/gitignores')
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.size).to be > 15
@@ -34,7 +34,7 @@ describe API::Templates do
it 'returns a list of available gitlab_ci_ymls' do
get api('/templates/gitlab_ci_ymls')
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.first['name']).not_to be_nil
@@ -45,7 +45,7 @@ describe API::Templates do
it 'adds a disclaimer on the top' do
get api('/templates/gitlab_ci_ymls/Ruby')
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['content']).to start_with("# This file is a template,")
end
end
@@ -74,7 +74,7 @@ describe API::Templates do
it 'returns a list of available license templates' do
get api('/templates/licenses')
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.size).to eq(12)
@@ -86,7 +86,7 @@ describe API::Templates do
it 'returns a list of available popular license templates' do
get api('/templates/licenses?popular=1')
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.size).to eq(3)
@@ -169,7 +169,7 @@ describe API::Templates do
let(:license_type) { 'muth-over9000' }
it 'returns a 404' do
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
diff --git a/spec/requests/api/todos_spec.rb b/spec/requests/api/todos_spec.rb
index 25d7f6dffcf..c6063a2e089 100644
--- a/spec/requests/api/todos_spec.rb
+++ b/spec/requests/api/todos_spec.rb
@@ -110,7 +110,7 @@ describe API::Todos do
it 'returns authentication error' do
post api("/todos/#{pending_1.id}/mark_as_done")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
@@ -118,7 +118,7 @@ describe API::Todos do
it 'marks a todo as done' do
post api("/todos/#{pending_1.id}/mark_as_done", john_doe)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['id']).to eq(pending_1.id)
expect(json_response['state']).to eq('done')
expect(pending_1.reload).to be_done
@@ -137,7 +137,7 @@ describe API::Todos do
it 'returns authentication error' do
post api('/todos/mark_as_done')
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
@@ -145,7 +145,7 @@ describe API::Todos do
it 'marks all todos as done' do
post api('/todos/mark_as_done', john_doe)
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
expect(pending_1.reload).to be_done
expect(pending_2.reload).to be_done
expect(pending_3.reload).to be_done
@@ -196,9 +196,9 @@ describe API::Todos do
post api("/projects/#{project_1.id}/#{issuable_type}/#{issuable.iid}/todo", guest)
if issuable_type == 'merge_requests'
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
else
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
diff --git a/spec/requests/api/triggers_spec.rb b/spec/requests/api/triggers_spec.rb
index 922b99a6cba..b2c56f7af2c 100644
--- a/spec/requests/api/triggers_spec.rb
+++ b/spec/requests/api/triggers_spec.rb
@@ -28,13 +28,13 @@ describe API::Triggers do
it 'returns bad request if token is missing' do
post api("/projects/#{project.id}/trigger/pipeline"), ref: 'master'
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it 'returns not found if project is not found' do
post api('/projects/0/trigger/pipeline'), options.merge(ref: 'master')
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -44,7 +44,7 @@ describe API::Triggers do
it 'creates pipeline' do
post api("/projects/#{project.id}/trigger/pipeline"), options.merge(ref: 'master')
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response).to include('id' => pipeline.id)
pipeline.builds.reload
expect(pipeline.builds.pending.size).to eq(2)
@@ -54,7 +54,7 @@ describe API::Triggers do
it 'returns bad request with no pipeline created if there\'s no commit for that ref' do
post api("/projects/#{project.id}/trigger/pipeline"), options.merge(ref: 'other-branch')
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['message']).to eq('base' => ["Reference not found"])
end
@@ -66,21 +66,21 @@ describe API::Triggers do
it 'validates variables to be a hash' do
post api("/projects/#{project.id}/trigger/pipeline"), options.merge(variables: 'value', ref: 'master')
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['error']).to eq('variables is invalid')
end
it 'validates variables needs to be a map of key-valued strings' do
post api("/projects/#{project.id}/trigger/pipeline"), options.merge(variables: { key: %w(1 2) }, ref: 'master')
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['message']).to eq('variables needs to be a map of key-valued strings')
end
it 'creates trigger request with variables' do
post api("/projects/#{project.id}/trigger/pipeline"), options.merge(variables: variables, ref: 'master')
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(pipeline.variables.map { |v| { v.key => v.value } }.last).to eq(variables)
end
end
@@ -93,7 +93,7 @@ describe API::Triggers do
it 'creates pipeline' do
post api("/projects/#{project.id}/trigger/pipeline"), options.merge(ref: 'master')
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response).to include('id' => pipeline.id)
pipeline.builds.reload
expect(pipeline.builds.pending.size).to eq(2)
@@ -106,7 +106,7 @@ describe API::Triggers do
it 'does not leak the presence of project when token is for different project' do
post api("/projects/#{project2.id}/ref/master/trigger/pipeline?token=#{trigger_token}"), { ref: 'refs/heads/other-branch' }
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'creates builds from the ref given in the URL, not in the body' do
@@ -114,7 +114,7 @@ describe API::Triggers do
post api("/projects/#{project.id}/ref/master/trigger/pipeline?token=#{trigger_token}"), { ref: 'refs/heads/other-branch' }
end.to change(project.builds, :count).by(5)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
end
context 'when ref contains a dot' do
@@ -125,7 +125,7 @@ describe API::Triggers do
post api("/projects/#{project.id}/ref/v.1-branch/trigger/pipeline?token=#{trigger_token}"), { ref: 'refs/heads/other-branch' }
end.to change(project.builds, :count).by(4)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
end
end
end
@@ -136,7 +136,7 @@ describe API::Triggers do
it 'returns list of triggers' do
get api("/projects/#{project.id}/triggers", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_a(Array)
expect(json_response[0]).to have_key('token')
@@ -147,7 +147,7 @@ describe API::Triggers do
it 'does not return triggers list' do
get api("/projects/#{project.id}/triggers", user2)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -155,7 +155,7 @@ describe API::Triggers do
it 'does not return triggers list' do
get api("/projects/#{project.id}/triggers")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
end
@@ -165,14 +165,14 @@ describe API::Triggers do
it 'returns trigger details' do
get api("/projects/#{project.id}/triggers/#{trigger.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_a(Hash)
end
it 'responds with 404 Not Found if requesting non-existing trigger' do
get api("/projects/#{project.id}/triggers/-5", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -180,7 +180,7 @@ describe API::Triggers do
it 'does not return triggers list' do
get api("/projects/#{project.id}/triggers/#{trigger.id}", user2)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -188,7 +188,7 @@ describe API::Triggers do
it 'does not return triggers list' do
get api("/projects/#{project.id}/triggers/#{trigger.id}")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
end
@@ -202,7 +202,7 @@ describe API::Triggers do
description: 'trigger'
end.to change {project.triggers.count}.by(1)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response).to include('description' => 'trigger')
end
end
@@ -211,7 +211,7 @@ describe API::Triggers do
it 'does not create trigger' do
post api("/projects/#{project.id}/triggers", user)
- expect(response).to have_http_status(:bad_request)
+ expect(response).to have_gitlab_http_status(:bad_request)
end
end
end
@@ -221,7 +221,7 @@ describe API::Triggers do
post api("/projects/#{project.id}/triggers", user2),
description: 'trigger'
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -230,7 +230,7 @@ describe API::Triggers do
post api("/projects/#{project.id}/triggers"),
description: 'trigger'
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
end
@@ -243,7 +243,7 @@ describe API::Triggers do
put api("/projects/#{project.id}/triggers/#{trigger.id}", user),
description: new_description
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to include('description' => new_description)
expect(trigger.reload.description).to eq(new_description)
end
@@ -253,7 +253,7 @@ describe API::Triggers do
it 'does not update trigger' do
put api("/projects/#{project.id}/triggers/#{trigger.id}", user2)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -261,7 +261,7 @@ describe API::Triggers do
it 'does not update trigger' do
put api("/projects/#{project.id}/triggers/#{trigger.id}")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
end
@@ -271,7 +271,7 @@ describe API::Triggers do
it 'updates owner' do
post api("/projects/#{project.id}/triggers/#{trigger.id}/take_ownership", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to include('owner')
expect(trigger.reload.owner).to eq(user)
end
@@ -281,7 +281,7 @@ describe API::Triggers do
it 'does not update owner' do
post api("/projects/#{project.id}/triggers/#{trigger.id}/take_ownership", user2)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -289,7 +289,7 @@ describe API::Triggers do
it 'does not update owner' do
post api("/projects/#{project.id}/triggers/#{trigger.id}/take_ownership")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
end
@@ -300,14 +300,14 @@ describe API::Triggers do
expect do
delete api("/projects/#{project.id}/triggers/#{trigger.id}", user)
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
end.to change {project.triggers.count}.by(-1)
end
it 'responds with 404 Not Found if requesting non-existing trigger' do
delete api("/projects/#{project.id}/triggers/-5", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it_behaves_like '412 response' do
@@ -319,7 +319,7 @@ describe API::Triggers do
it 'does not delete trigger' do
delete api("/projects/#{project.id}/triggers/#{trigger.id}", user2)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -327,7 +327,7 @@ describe API::Triggers do
it 'does not delete trigger' do
delete api("/projects/#{project.id}/triggers/#{trigger.id}")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
end
diff --git a/spec/requests/api/users_spec.rb b/spec/requests/api/users_spec.rb
index 69c8aa4482a..4737f034f21 100644
--- a/spec/requests/api/users_spec.rb
+++ b/spec/requests/api/users_spec.rb
@@ -113,7 +113,7 @@ describe API::Users do
it "returns a 403 when non-admin user searches by external UID" do
get api("/users?extern_uid=#{omniauth_user.identities.first.extern_uid}&provider=#{omniauth_user.identities.first.provider}", user)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
it 'does not reveal the `is_admin` flag of the user' do
@@ -130,7 +130,7 @@ describe API::Users do
admin_personal_access_token = create(:personal_access_token, user: admin).token
get api("/users?private_token=#{admin_personal_access_token}&sudo=#{user.id}", admin)
- expect(response).to have_http_status(:success)
+ expect(response).to have_gitlab_http_status(:success)
end
end
@@ -162,13 +162,13 @@ describe API::Users do
it "returns 400 error if provider with no extern_uid" do
get api("/users?extern_uid=#{omniauth_user.identities.first.extern_uid}", admin)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it "returns 400 error if provider with no extern_uid" do
get api("/users?provider=#{omniauth_user.identities.first.provider}", admin)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it "returns a user created before a specific date" do
@@ -240,21 +240,21 @@ describe API::Users do
get api("/users/#{user.id}")
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
it "returns a 404 error if user id not found" do
get api("/users/9999", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 User Not Found')
end
it "returns a 404 for invalid ID" do
get api("/users/1ASDF", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -271,7 +271,7 @@ describe API::Users do
it "creates user with correct attributes" do
post api('/users', admin), attributes_for(:user, admin: true, can_create_group: true)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
user_id = json_response['id']
new_user = User.find(user_id)
expect(new_user).not_to eq(nil)
@@ -285,12 +285,12 @@ describe API::Users do
post api('/users', admin), attributes
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
end
it "creates non-admin user" do
post api('/users', admin), attributes_for(:user, admin: false, can_create_group: false)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
user_id = json_response['id']
new_user = User.find(user_id)
expect(new_user).not_to eq(nil)
@@ -300,7 +300,7 @@ describe API::Users do
it "creates non-admin users by default" do
post api('/users', admin), attributes_for(:user)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
user_id = json_response['id']
new_user = User.find(user_id)
expect(new_user).not_to eq(nil)
@@ -309,12 +309,12 @@ describe API::Users do
it "returns 201 Created on success" do
post api("/users", admin), attributes_for(:user, projects_limit: 3)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
end
it 'creates non-external users by default' do
post api("/users", admin), attributes_for(:user)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
user_id = json_response['id']
new_user = User.find(user_id)
@@ -324,7 +324,7 @@ describe API::Users do
it 'allows an external user to be created' do
post api("/users", admin), attributes_for(:user, external: true)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
user_id = json_response['id']
new_user = User.find(user_id)
@@ -335,7 +335,7 @@ describe API::Users do
it "creates user with reset password" do
post api('/users', admin), attributes_for(:user, reset_password: true).except(:password)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
user_id = json_response['id']
new_user = User.find(user_id)
@@ -349,27 +349,27 @@ describe API::Users do
email: 'invalid email',
password: 'password',
name: 'test'
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it 'returns 400 error if name not given' do
post api('/users', admin), attributes_for(:user).except(:name)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it 'returns 400 error if password not given' do
post api('/users', admin), attributes_for(:user).except(:password)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it 'returns 400 error if email not given' do
post api('/users', admin), attributes_for(:user).except(:email)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it 'returns 400 error if username not given' do
post api('/users', admin), attributes_for(:user).except(:username)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it 'returns 400 error if user does not validate' do
@@ -380,7 +380,7 @@ describe API::Users do
name: 'test',
bio: 'g' * 256,
projects_limit: -1
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['message']['password'])
.to eq(['is too short (minimum is 8 characters)'])
expect(json_response['message']['bio'])
@@ -393,7 +393,7 @@ describe API::Users do
it "is not available for non admin users" do
post api("/users", user), attributes_for(:user)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
context 'with existing user' do
@@ -413,7 +413,7 @@ describe API::Users do
password: 'password',
username: 'foo'
end.to change { User.count }.by(0)
- expect(response).to have_http_status(409)
+ expect(response).to have_gitlab_http_status(409)
expect(json_response['message']).to eq('Email has already been taken')
end
@@ -425,14 +425,14 @@ describe API::Users do
password: 'password',
username: 'test'
end.to change { User.count }.by(0)
- expect(response).to have_http_status(409)
+ expect(response).to have_gitlab_http_status(409)
expect(json_response['message']).to eq('Username has already been taken')
end
it 'creates user with new identity' do
post api("/users", admin), attributes_for(:user, provider: 'github', extern_uid: '67890')
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['identities'].first['extern_uid']).to eq('67890')
expect(json_response['identities'].first['provider']).to eq('github')
end
@@ -450,7 +450,7 @@ describe API::Users do
describe "GET /users/sign_up" do
it "redirects to sign in page" do
get "/users/sign_up"
- expect(response).to have_http_status(302)
+ expect(response).to have_gitlab_http_status(302)
expect(response).to redirect_to(new_user_session_path)
end
end
@@ -465,7 +465,7 @@ describe API::Users do
it "updates user with new bio" do
put api("/users/#{user.id}", admin), { bio: 'new test bio' }
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['bio']).to eq('new test bio')
expect(user.reload.bio).to eq('new test bio')
end
@@ -473,14 +473,14 @@ describe API::Users do
it "updates user with new password and forces reset on next login" do
put api("/users/#{user.id}", admin), password: '12345678'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(user.reload.password_expires_at).to be <= Time.now
end
it "updates user with organization" do
put api("/users/#{user.id}", admin), { organization: 'GitLab' }
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['organization']).to eq('GitLab')
expect(user.reload.organization).to eq('GitLab')
end
@@ -491,14 +491,14 @@ describe API::Users do
user.reload
expect(user.avatar).to be_present
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['avatar_url']).to include(user.avatar_path)
end
it 'updates user with his own email' do
put api("/users/#{user.id}", admin), email: user.email
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['email']).to eq(user.email)
expect(user.reload.email).to eq(user.email)
end
@@ -506,14 +506,14 @@ describe API::Users do
it 'updates user with a new email' do
put api("/users/#{user.id}", admin), email: 'new@email.com'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(user.reload.notification_email).to eq('new@email.com')
end
it 'updates user with his own username' do
put api("/users/#{user.id}", admin), username: user.username
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['username']).to eq(user.username)
expect(user.reload.username).to eq(user.username)
end
@@ -521,14 +521,14 @@ describe API::Users do
it "updates user's existing identity" do
put api("/users/#{omniauth_user.id}", admin), provider: 'ldapmain', extern_uid: '654321'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(omniauth_user.reload.identities.first.extern_uid).to eq('654321')
end
it 'updates user with new identity' do
put api("/users/#{user.id}", admin), provider: 'github', extern_uid: 'john'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(user.reload.identities.first.extern_uid).to eq('john')
expect(user.reload.identities.first.provider).to eq('github')
end
@@ -536,7 +536,7 @@ describe API::Users do
it "updates admin status" do
put api("/users/#{user.id}", admin), { admin: true }
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(user.reload.admin).to eq(true)
end
@@ -551,7 +551,7 @@ describe API::Users do
it "does not update admin status" do
put api("/users/#{admin_user.id}", admin), { can_create_group: false }
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(admin_user.reload.admin).to eq(true)
expect(admin_user.can_create_group).to eq(false)
end
@@ -559,7 +559,7 @@ describe API::Users do
it "does not allow invalid update" do
put api("/users/#{user.id}", admin), { email: 'invalid email' }
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(user.reload.email).not_to eq('invalid email')
end
@@ -569,21 +569,21 @@ describe API::Users do
put api("/users/#{user.id}", user), attributes_for(:user)
end.not_to change { user.reload.attributes }
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
it "returns 404 for non-existing user" do
put api("/users/999999", admin), { bio: 'update should fail' }
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 User Not Found')
end
it "returns a 404 if invalid ID" do
put api("/users/ASDF", admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'returns 400 error if user does not validate' do
@@ -594,7 +594,7 @@ describe API::Users do
name: 'test',
bio: 'g' * 256,
projects_limit: -1
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['message']['password'])
.to eq(['is too short (minimum is 8 characters)'])
expect(json_response['message']['bio'])
@@ -608,13 +608,13 @@ describe API::Users do
it 'returns 400 if provider is missing for identity update' do
put api("/users/#{omniauth_user.id}", admin), extern_uid: '654321'
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it 'returns 400 if external UID is missing for identity update' do
put api("/users/#{omniauth_user.id}", admin), provider: 'ldap'
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
context "with existing user" do
@@ -627,7 +627,7 @@ describe API::Users do
it 'returns 409 conflict error if email address exists' do
put api("/users/#{@user.id}", admin), email: 'test@example.com'
- expect(response).to have_http_status(409)
+ expect(response).to have_gitlab_http_status(409)
expect(@user.reload.email).to eq(@user.email)
end
@@ -635,7 +635,7 @@ describe API::Users do
@user_id = User.all.last.id
put api("/users/#{@user.id}", admin), username: 'test'
- expect(response).to have_http_status(409)
+ expect(response).to have_gitlab_http_status(409)
expect(@user.reload.username).to eq(@user.username)
end
end
@@ -649,14 +649,14 @@ describe API::Users do
it "does not create invalid ssh key" do
post api("/users/#{user.id}/keys", admin), { title: "invalid key" }
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['error']).to eq('key is missing')
end
it 'does not create key without title' do
post api("/users/#{user.id}/keys", admin), key: 'some key'
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['error']).to eq('title is missing')
end
@@ -669,7 +669,7 @@ describe API::Users do
it "returns 400 for invalid ID" do
post api("/users/999999/keys", admin)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
end
@@ -681,14 +681,14 @@ describe API::Users do
context 'when unauthenticated' do
it 'returns authentication error' do
get api("/users/#{user.id}/keys")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
context 'when authenticated' do
it 'returns 404 for non-existing user' do
get api('/users/999999/keys', admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 User Not Found')
end
@@ -698,7 +698,7 @@ describe API::Users do
get api("/users/#{user.id}/keys", admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.first['title']).to eq(key.title)
@@ -714,7 +714,7 @@ describe API::Users do
context 'when unauthenticated' do
it 'returns authentication error' do
delete api("/users/#{user.id}/keys/42")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
@@ -726,7 +726,7 @@ describe API::Users do
expect do
delete api("/users/#{user.id}/keys/#{key.id}", admin)
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
end.to change { user.keys.count }.by(-1)
end
@@ -738,13 +738,13 @@ describe API::Users do
user.keys << key
user.save
delete api("/users/999999/keys/#{key.id}", admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 User Not Found')
end
it 'returns 404 error if key not foud' do
delete api("/users/#{user.id}/keys/42", admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 Key Not Found')
end
end
@@ -758,7 +758,7 @@ describe API::Users do
it 'does not create invalid GPG key' do
post api("/users/#{user.id}/gpg_keys", admin)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['error']).to eq('key is missing')
end
@@ -767,14 +767,14 @@ describe API::Users do
expect do
post api("/users/#{user.id}/gpg_keys", admin), key_attrs
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
end.to change { user.gpg_keys.count }.by(1)
end
it 'returns 400 for invalid ID' do
post api('/users/999999/gpg_keys', admin)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
end
@@ -787,7 +787,7 @@ describe API::Users do
it 'returns authentication error' do
get api("/users/#{user.id}/gpg_keys")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
@@ -795,14 +795,14 @@ describe API::Users do
it 'returns 404 for non-existing user' do
get api('/users/999999/gpg_keys', admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 User Not Found')
end
it 'returns 404 error if key not foud' do
delete api("/users/#{user.id}/gpg_keys/42", admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 GPG Key Not Found')
end
@@ -812,7 +812,7 @@ describe API::Users do
get api("/users/#{user.id}/gpg_keys", admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.first['key']).to eq(gpg_key.key)
@@ -829,7 +829,7 @@ describe API::Users do
it 'returns authentication error' do
delete api("/users/#{user.id}/keys/42")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
@@ -841,7 +841,7 @@ describe API::Users do
expect do
delete api("/users/#{user.id}/gpg_keys/#{gpg_key.id}", admin)
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
end.to change { user.gpg_keys.count }.by(-1)
end
@@ -851,14 +851,14 @@ describe API::Users do
delete api("/users/999999/gpg_keys/#{gpg_key.id}", admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 User Not Found')
end
it 'returns 404 error if key not foud' do
delete api("/users/#{user.id}/gpg_keys/42", admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 GPG Key Not Found')
end
end
@@ -873,7 +873,7 @@ describe API::Users do
it 'returns authentication error' do
post api("/users/#{user.id}/gpg_keys/42/revoke")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
@@ -885,7 +885,7 @@ describe API::Users do
expect do
post api("/users/#{user.id}/gpg_keys/#{gpg_key.id}/revoke", admin)
- expect(response).to have_http_status(:accepted)
+ expect(response).to have_gitlab_http_status(:accepted)
end.to change { user.gpg_keys.count }.by(-1)
end
@@ -895,14 +895,14 @@ describe API::Users do
post api("/users/999999/gpg_keys/#{gpg_key.id}/revoke", admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 User Not Found')
end
it 'returns 404 error if key not foud' do
post api("/users/#{user.id}/gpg_keys/42/revoke", admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 GPG Key Not Found')
end
end
@@ -916,7 +916,7 @@ describe API::Users do
it "does not create invalid email" do
post api("/users/#{user.id}/emails", admin), {}
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['error']).to eq('email is missing')
end
@@ -930,7 +930,7 @@ describe API::Users do
it "returns a 400 for invalid ID" do
post api("/users/999999/emails", admin)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
end
@@ -942,14 +942,14 @@ describe API::Users do
context 'when unauthenticated' do
it 'returns authentication error' do
get api("/users/#{user.id}/emails")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
context 'when authenticated' do
it 'returns 404 for non-existing user' do
get api('/users/999999/emails', admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 User Not Found')
end
@@ -959,7 +959,7 @@ describe API::Users do
get api("/users/#{user.id}/emails", admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.first['email']).to eq(email.email)
@@ -968,7 +968,7 @@ describe API::Users do
it "returns a 404 for invalid ID" do
get api("/users/ASDF/emails", admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -981,7 +981,7 @@ describe API::Users do
context 'when unauthenticated' do
it 'returns authentication error' do
delete api("/users/#{user.id}/emails/42")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
@@ -993,7 +993,7 @@ describe API::Users do
expect do
delete api("/users/#{user.id}/emails/#{email.id}", admin)
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
end.to change { user.emails.count }.by(-1)
end
@@ -1005,20 +1005,20 @@ describe API::Users do
user.emails << email
user.save
delete api("/users/999999/emails/#{email.id}", admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 User Not Found')
end
it 'returns 404 error if email not foud' do
delete api("/users/#{user.id}/emails/42", admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 Email Not Found')
end
it "returns a 404 for invalid ID" do
delete api("/users/ASDF/emails/bar", admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -1034,7 +1034,7 @@ describe API::Users do
it "deletes user" do
Sidekiq::Testing.inline! { delete api("/users/#{user.id}", admin) }
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
expect { User.find(user.id) }.to raise_error ActiveRecord::RecordNotFound
expect { Namespace.find(namespace.id) }.to raise_error ActiveRecord::RecordNotFound
end
@@ -1045,31 +1045,31 @@ describe API::Users do
it "does not delete for unauthenticated user" do
Sidekiq::Testing.inline! { delete api("/users/#{user.id}") }
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
it "is not available for non admin users" do
Sidekiq::Testing.inline! { delete api("/users/#{user.id}", user) }
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
it "returns 404 for non-existing user" do
Sidekiq::Testing.inline! { delete api("/users/999999", admin) }
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 User Not Found')
end
it "returns a 404 for invalid ID" do
Sidekiq::Testing.inline! { delete api("/users/ASDF", admin) }
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
context "hard delete disabled" do
it "moves contributions to the ghost user" do
Sidekiq::Testing.inline! { delete api("/users/#{user.id}", admin) }
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
expect(issue.reload).to be_persisted
expect(issue.author.ghost?).to be_truthy
end
@@ -1079,7 +1079,7 @@ describe API::Users do
it "removes contributions" do
Sidekiq::Testing.inline! { delete api("/users/#{user.id}?hard_delete=true", admin) }
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
expect(Issue.exists?(issue.id)).to be_falsy
end
end
@@ -1093,7 +1093,7 @@ describe API::Users do
it 'returns 403 without private token when sudo is defined' do
get api("/user?private_token=#{personal_access_token}&sudo=123")
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -1101,14 +1101,14 @@ describe API::Users do
it 'returns 403 without private token when sudo defined' do
get api("/user?private_token=#{user.private_token}&sudo=123")
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
it 'returns current user without private token when sudo not defined' do
get api("/user", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to match_response_schema('public_api/v4/user/public')
expect(json_response['id']).to eq(user.id)
end
@@ -1128,13 +1128,13 @@ describe API::Users do
it 'returns 403 without private token when sudo defined' do
get api("/user?private_token=#{admin_personal_access_token}&sudo=#{user.id}")
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
it 'returns initial current user without private token but with is_admin when sudo not defined' do
get api("/user?private_token=#{admin_personal_access_token}")
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to match_response_schema('public_api/v4/user/admin')
expect(json_response['id']).to eq(admin.id)
end
@@ -1144,7 +1144,7 @@ describe API::Users do
it 'returns sudoed user with private token when sudo defined' do
get api("/user?private_token=#{admin.private_token}&sudo=#{user.id}")
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to match_response_schema('public_api/v4/user/login')
expect(json_response['id']).to eq(user.id)
end
@@ -1152,7 +1152,7 @@ describe API::Users do
it 'returns initial current user without private token but with is_admin when sudo not defined' do
get api("/user?private_token=#{admin.private_token}")
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to match_response_schema('public_api/v4/user/admin')
expect(json_response['id']).to eq(admin.id)
end
@@ -1163,7 +1163,7 @@ describe API::Users do
it "returns 401 error if user is unauthenticated" do
get api("/user")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
end
@@ -1172,7 +1172,7 @@ describe API::Users do
context "when unauthenticated" do
it "returns authentication error" do
get api("/user/keys")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
@@ -1183,7 +1183,7 @@ describe API::Users do
get api("/user/keys", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.first["title"]).to eq(key.title)
@@ -1203,14 +1203,14 @@ describe API::Users do
user.keys << key
user.save
get api("/user/keys/#{key.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response["title"]).to eq(key.title)
end
it "returns 404 Not Found within invalid ID" do
get api("/user/keys/42", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 Key Not Found')
end
@@ -1219,14 +1219,14 @@ describe API::Users do
user.save
admin
get api("/user/keys/#{key.id}", admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 Key Not Found')
end
it "returns 404 for invalid ID" do
get api("/users/keys/ASDF", admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
context "scopes" do
@@ -1243,31 +1243,31 @@ describe API::Users do
expect do
post api("/user/keys", user), key_attrs
end.to change { user.keys.count }.by(1)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
end
it "returns a 401 error if unauthorized" do
post api("/user/keys"), title: 'some title', key: 'some key'
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
it "does not create ssh key without key" do
post api("/user/keys", user), title: 'title'
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['error']).to eq('key is missing')
end
it 'does not create ssh key without title' do
post api('/user/keys', user), key: 'some key'
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['error']).to eq('title is missing')
end
it "does not create ssh key without title" do
post api("/user/keys", user), key: "somekey"
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
end
@@ -1279,7 +1279,7 @@ describe API::Users do
expect do
delete api("/user/keys/#{key.id}", user)
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
end.to change { user.keys.count}.by(-1)
end
@@ -1290,7 +1290,7 @@ describe API::Users do
it "returns 404 if key ID not found" do
delete api("/user/keys/42", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 Key Not Found')
end
@@ -1298,13 +1298,13 @@ describe API::Users do
user.keys << key
user.save
delete api("/user/keys/#{key.id}")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
it "returns a 404 for invalid ID" do
delete api("/users/keys/ASDF", admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -1313,7 +1313,7 @@ describe API::Users do
it 'returns authentication error' do
get api('/user/gpg_keys')
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
@@ -1324,7 +1324,7 @@ describe API::Users do
get api('/user/gpg_keys', user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.first['key']).to eq(gpg_key.key)
@@ -1346,14 +1346,14 @@ describe API::Users do
get api("/user/gpg_keys/#{gpg_key.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['key']).to eq(gpg_key.key)
end
it 'returns 404 Not Found within invalid ID' do
get api('/user/gpg_keys/42', user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 GPG Key Not Found')
end
@@ -1363,14 +1363,14 @@ describe API::Users do
get api("/user/gpg_keys/#{gpg_key.id}", admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 GPG Key Not Found')
end
it 'returns 404 for invalid ID' do
get api('/users/gpg_keys/ASDF', admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
context 'scopes' do
@@ -1387,20 +1387,20 @@ describe API::Users do
expect do
post api('/user/gpg_keys', user), key_attrs
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
end.to change { user.gpg_keys.count }.by(1)
end
it 'returns a 401 error if unauthorized' do
post api('/user/gpg_keys'), key: 'some key'
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
it 'does not create GPG key without key' do
post api('/user/gpg_keys', user)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['error']).to eq('key is missing')
end
end
@@ -1413,14 +1413,14 @@ describe API::Users do
expect do
post api("/user/gpg_keys/#{gpg_key.id}/revoke", user)
- expect(response).to have_http_status(:accepted)
+ expect(response).to have_gitlab_http_status(:accepted)
end.to change { user.gpg_keys.count}.by(-1)
end
it 'returns 404 if key ID not found' do
post api('/user/gpg_keys/42/revoke', user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 GPG Key Not Found')
end
@@ -1430,13 +1430,13 @@ describe API::Users do
post api("/user/gpg_keys/#{gpg_key.id}/revoke")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
it 'returns a 404 for invalid ID' do
post api('/users/gpg_keys/ASDF/revoke', admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -1448,14 +1448,14 @@ describe API::Users do
expect do
delete api("/user/gpg_keys/#{gpg_key.id}", user)
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
end.to change { user.gpg_keys.count}.by(-1)
end
it 'returns 404 if key ID not found' do
delete api('/user/gpg_keys/42', user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 GPG Key Not Found')
end
@@ -1465,13 +1465,13 @@ describe API::Users do
delete api("/user/gpg_keys/#{gpg_key.id}")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
it 'returns a 404 for invalid ID' do
delete api('/users/gpg_keys/ASDF', admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -1479,7 +1479,7 @@ describe API::Users do
context "when unauthenticated" do
it "returns authentication error" do
get api("/user/emails")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
@@ -1490,7 +1490,7 @@ describe API::Users do
get api("/user/emails", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.first["email"]).to eq(email.email)
@@ -1510,13 +1510,13 @@ describe API::Users do
user.emails << email
user.save
get api("/user/emails/#{email.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response["email"]).to eq(email.email)
end
it "returns 404 Not Found within invalid ID" do
get api("/user/emails/42", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 Email Not Found')
end
@@ -1525,14 +1525,14 @@ describe API::Users do
user.save
admin
get api("/user/emails/#{email.id}", admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 Email Not Found')
end
it "returns 404 for invalid ID" do
get api("/users/emails/ASDF", admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
context "scopes" do
@@ -1549,18 +1549,18 @@ describe API::Users do
expect do
post api("/user/emails", user), email_attrs
end.to change { user.emails.count }.by(1)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
end
it "returns a 401 error if unauthorized" do
post api("/user/emails"), email: 'some email'
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
it "does not create email with invalid email" do
post api("/user/emails", user), {}
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['error']).to eq('email is missing')
end
end
@@ -1573,7 +1573,7 @@ describe API::Users do
expect do
delete api("/user/emails/#{email.id}", user)
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
end.to change { user.emails.count}.by(-1)
end
@@ -1584,7 +1584,7 @@ describe API::Users do
it "returns 404 if email ID not found" do
delete api("/user/emails/42", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 Email Not Found')
end
@@ -1592,13 +1592,13 @@ describe API::Users do
user.emails << email
user.save
delete api("/user/emails/#{email.id}")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
it "returns 400 for invalid ID" do
delete api("/user/emails/ASDF", admin)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
end
@@ -1609,25 +1609,25 @@ describe API::Users do
it 'blocks existing user' do
post api("/users/#{user.id}/block", admin)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(user.reload.state).to eq('blocked')
end
it 'does not re-block ldap blocked users' do
post api("/users/#{ldap_blocked_user.id}/block", admin)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
expect(ldap_blocked_user.reload.state).to eq('ldap_blocked')
end
it 'does not be available for non admin users' do
post api("/users/#{user.id}/block", user)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
expect(user.reload.state).to eq('active')
end
it 'returns a 404 error if user id not found' do
post api('/users/9999/block', admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 User Not Found')
end
end
@@ -1641,38 +1641,38 @@ describe API::Users do
it 'unblocks existing user' do
post api("/users/#{user.id}/unblock", admin)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(user.reload.state).to eq('active')
end
it 'unblocks a blocked user' do
post api("/users/#{blocked_user.id}/unblock", admin)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(blocked_user.reload.state).to eq('active')
end
it 'does not unblock ldap blocked users' do
post api("/users/#{ldap_blocked_user.id}/unblock", admin)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
expect(ldap_blocked_user.reload.state).to eq('ldap_blocked')
end
it 'does not be available for non admin users' do
post api("/users/#{user.id}/unblock", user)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
expect(user.reload.state).to eq('active')
end
it 'returns a 404 error if user id not found' do
post api('/users/9999/block', admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 User Not Found')
end
it "returns a 404 for invalid ID" do
post api("/users/ASDF/block", admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -1684,7 +1684,7 @@ describe API::Users do
it 'has no permission' do
get api("/user/activities", user)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -1729,21 +1729,21 @@ describe API::Users do
it 'returns a 404 error if user not found' do
get api("/users/#{not_existing_user_id}/impersonation_tokens", admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 User Not Found')
end
it 'returns a 403 error when authenticated as normal user' do
get api("/users/#{not_existing_user_id}/impersonation_tokens", user)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
expect(json_response['message']).to eq('403 Forbidden')
end
it 'returns an array of all impersonated tokens' do
get api("/users/#{user.id}/impersonation_tokens", admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.size).to eq(2)
@@ -1752,7 +1752,7 @@ describe API::Users do
it 'returns an array of active impersonation tokens if state active' do
get api("/users/#{user.id}/impersonation_tokens?state=active", admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.size).to eq(1)
@@ -1762,7 +1762,7 @@ describe API::Users do
it 'returns an array of inactive personal access tokens if active is set to false' do
get api("/users/#{user.id}/impersonation_tokens?state=inactive", admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.size).to eq(1)
expect(json_response).to all(include('active' => false))
@@ -1778,7 +1778,7 @@ describe API::Users do
it 'returns validation error if impersonation token misses some attributes' do
post api("/users/#{user.id}/impersonation_tokens", admin)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['error']).to eq('name is missing')
end
@@ -1787,7 +1787,7 @@ describe API::Users do
name: name,
expires_at: expires_at
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 User Not Found')
end
@@ -1796,7 +1796,7 @@ describe API::Users do
name: name,
expires_at: expires_at
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
expect(json_response['message']).to eq('403 Forbidden')
end
@@ -1807,7 +1807,7 @@ describe API::Users do
scopes: scopes,
impersonation: impersonation
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['name']).to eq(name)
expect(json_response['scopes']).to eq(scopes)
expect(json_response['expires_at']).to eq(expires_at)
@@ -1827,35 +1827,35 @@ describe API::Users do
it 'returns 404 error if user not found' do
get api("/users/#{not_existing_user_id}/impersonation_tokens/1", admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 User Not Found')
end
it 'returns a 404 error if impersonation token not found' do
get api("/users/#{user.id}/impersonation_tokens/#{not_existing_pat_id}", admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 Impersonation Token Not Found')
end
it 'returns a 404 error if token is not impersonation token' do
get api("/users/#{user.id}/impersonation_tokens/#{personal_access_token.id}", admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 Impersonation Token Not Found')
end
it 'returns a 403 error when authenticated as normal user' do
get api("/users/#{user.id}/impersonation_tokens/#{impersonation_token.id}", user)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
expect(json_response['message']).to eq('403 Forbidden')
end
it 'returns a personal access token' do
get api("/users/#{user.id}/impersonation_tokens/#{impersonation_token.id}", admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['token']).to be_present
expect(json_response['impersonation']).to be_truthy
end
@@ -1868,28 +1868,28 @@ describe API::Users do
it 'returns a 404 error if user not found' do
delete api("/users/#{not_existing_user_id}/impersonation_tokens/1", admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 User Not Found')
end
it 'returns a 404 error if impersonation token not found' do
delete api("/users/#{user.id}/impersonation_tokens/#{not_existing_pat_id}", admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 Impersonation Token Not Found')
end
it 'returns a 404 error if token is not impersonation token' do
delete api("/users/#{user.id}/impersonation_tokens/#{personal_access_token.id}", admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 Impersonation Token Not Found')
end
it 'returns a 403 error when authenticated as normal user' do
delete api("/users/#{user.id}/impersonation_tokens/#{impersonation_token.id}", user)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
expect(json_response['message']).to eq('403 Forbidden')
end
@@ -1900,7 +1900,7 @@ describe API::Users do
it 'revokes a impersonation token' do
delete api("/users/#{user.id}/impersonation_tokens/#{impersonation_token.id}", admin)
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
expect(impersonation_token.revoked).to be_falsey
expect(impersonation_token.reload.revoked).to be_truthy
end
diff --git a/spec/requests/api/v3/award_emoji_spec.rb b/spec/requests/api/v3/award_emoji_spec.rb
index 36d793f505d..0cd8b70007f 100644
--- a/spec/requests/api/v3/award_emoji_spec.rb
+++ b/spec/requests/api/v3/award_emoji_spec.rb
@@ -16,7 +16,7 @@ describe API::V3::AwardEmoji do
it "returns an array of award_emoji" do
get v3_api("/projects/#{project.id}/issues/#{issue.id}/award_emoji", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.first['name']).to eq(award_emoji.name)
end
@@ -24,7 +24,7 @@ describe API::V3::AwardEmoji do
it "returns a 404 error when issue id not found" do
get v3_api("/projects/#{project.id}/issues/12345/award_emoji", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -32,7 +32,7 @@ describe API::V3::AwardEmoji do
it "returns an array of award_emoji" do
get v3_api("/projects/#{project.id}/merge_requests/#{merge_request.id}/award_emoji", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.first['name']).to eq(downvote.name)
@@ -46,7 +46,7 @@ describe API::V3::AwardEmoji do
it 'returns the awarded emoji' do
get v3_api("/projects/#{project.id}/snippets/#{snippet.id}/award_emoji", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.first['name']).to eq(award.name)
end
@@ -58,7 +58,7 @@ describe API::V3::AwardEmoji do
get v3_api("/projects/#{project.id}/merge_requests/#{merge_request.id}/award_emoji", user1)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -69,7 +69,7 @@ describe API::V3::AwardEmoji do
it 'returns an array of award emoji' do
get v3_api("/projects/#{project.id}/issues/#{issue.id}/notes/#{note.id}/award_emoji", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.first['name']).to eq(rocket.name)
end
@@ -80,7 +80,7 @@ describe API::V3::AwardEmoji do
it "returns the award emoji" do
get v3_api("/projects/#{project.id}/issues/#{issue.id}/award_emoji/#{award_emoji.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['name']).to eq(award_emoji.name)
expect(json_response['awardable_id']).to eq(issue.id)
expect(json_response['awardable_type']).to eq("Issue")
@@ -89,7 +89,7 @@ describe API::V3::AwardEmoji do
it "returns a 404 error if the award is not found" do
get v3_api("/projects/#{project.id}/issues/#{issue.id}/award_emoji/12345", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -97,7 +97,7 @@ describe API::V3::AwardEmoji do
it 'returns the award emoji' do
get v3_api("/projects/#{project.id}/merge_requests/#{merge_request.id}/award_emoji/#{downvote.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['name']).to eq(downvote.name)
expect(json_response['awardable_id']).to eq(merge_request.id)
expect(json_response['awardable_type']).to eq("MergeRequest")
@@ -111,7 +111,7 @@ describe API::V3::AwardEmoji do
it 'returns the awarded emoji' do
get v3_api("/projects/#{project.id}/snippets/#{snippet.id}/award_emoji/#{award.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['name']).to eq(award.name)
expect(json_response['awardable_id']).to eq(snippet.id)
expect(json_response['awardable_type']).to eq("Snippet")
@@ -124,7 +124,7 @@ describe API::V3::AwardEmoji do
get v3_api("/projects/#{project.id}/merge_requests/#{merge_request.id}/award_emoji/#{downvote.id}", user1)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -135,7 +135,7 @@ describe API::V3::AwardEmoji do
it 'returns an award emoji' do
get v3_api("/projects/#{project.id}/issues/#{issue.id}/notes/#{note.id}/award_emoji/#{rocket.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).not_to be_an Array
expect(json_response['name']).to eq(rocket.name)
end
@@ -148,7 +148,7 @@ describe API::V3::AwardEmoji do
it "creates a new award emoji" do
post v3_api("/projects/#{project.id}/issues/#{issue.id}/award_emoji", user), name: 'blowfish'
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['name']).to eq('blowfish')
expect(json_response['user']['username']).to eq(user.username)
end
@@ -156,19 +156,19 @@ describe API::V3::AwardEmoji do
it "returns a 400 bad request error if the name is not given" do
post v3_api("/projects/#{project.id}/issues/#{issue.id}/award_emoji", user)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it "returns a 401 unauthorized error if the user is not authenticated" do
post v3_api("/projects/#{project.id}/issues/#{issue.id}/award_emoji"), name: 'thumbsup'
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
it "returns a 404 error if the user authored issue" do
post v3_api("/projects/#{project.id}/issues/#{issue2.id}/award_emoji", user), name: 'thumbsup'
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it "normalizes +1 as thumbsup award" do
@@ -182,7 +182,7 @@ describe API::V3::AwardEmoji do
post v3_api("/projects/#{project.id}/issues/#{issue.id}/award_emoji", user), name: 'thumbsup'
post v3_api("/projects/#{project.id}/issues/#{issue.id}/award_emoji", user), name: 'thumbsup'
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response["message"]).to match("has already been taken")
end
end
@@ -194,7 +194,7 @@ describe API::V3::AwardEmoji do
post v3_api("/projects/#{project.id}/snippets/#{snippet.id}/award_emoji", user), name: 'blowfish'
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['name']).to eq('blowfish')
expect(json_response['user']['username']).to eq(user.username)
end
@@ -209,14 +209,14 @@ describe API::V3::AwardEmoji do
post v3_api("/projects/#{project.id}/issues/#{issue.id}/notes/#{note.id}/award_emoji", user), name: 'rocket'
end.to change { note.award_emoji.count }.from(0).to(1)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['user']['username']).to eq(user.username)
end
it "it returns 404 error when user authored note" do
post v3_api("/projects/#{project.id}/issues/#{issue.id}/notes/#{note2.id}/award_emoji", user), name: 'thumbsup'
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it "normalizes +1 as thumbsup award" do
@@ -230,7 +230,7 @@ describe API::V3::AwardEmoji do
post v3_api("/projects/#{project.id}/issues/#{issue.id}/notes/#{note.id}/award_emoji", user), name: 'rocket'
post v3_api("/projects/#{project.id}/issues/#{issue.id}/notes/#{note.id}/award_emoji", user), name: 'rocket'
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response["message"]).to match("has already been taken")
end
end
@@ -242,14 +242,14 @@ describe API::V3::AwardEmoji do
expect do
delete v3_api("/projects/#{project.id}/issues/#{issue.id}/award_emoji/#{award_emoji.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end.to change { issue.award_emoji.count }.from(1).to(0)
end
it 'returns a 404 error when the award emoji can not be found' do
delete v3_api("/projects/#{project.id}/issues/#{issue.id}/award_emoji/12345", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -258,14 +258,14 @@ describe API::V3::AwardEmoji do
expect do
delete v3_api("/projects/#{project.id}/merge_requests/#{merge_request.id}/award_emoji/#{downvote.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end.to change { merge_request.award_emoji.count }.from(1).to(0)
end
it 'returns a 404 error when note id not found' do
delete v3_api("/projects/#{project.id}/merge_requests/#{merge_request.id}/notes/12345", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -277,7 +277,7 @@ describe API::V3::AwardEmoji do
expect do
delete v3_api("/projects/#{project.id}/snippets/#{snippet.id}/award_emoji/#{award.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end.to change { snippet.award_emoji.count }.from(1).to(0)
end
end
@@ -290,7 +290,7 @@ describe API::V3::AwardEmoji do
expect do
delete v3_api("/projects/#{project.id}/issues/#{issue.id}/notes/#{note.id}/award_emoji/#{rocket.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end.to change { note.award_emoji.count }.from(1).to(0)
end
end
diff --git a/spec/requests/api/v3/boards_spec.rb b/spec/requests/api/v3/boards_spec.rb
index ea2627142bf..14409d25544 100644
--- a/spec/requests/api/v3/boards_spec.rb
+++ b/spec/requests/api/v3/boards_spec.rb
@@ -38,7 +38,7 @@ describe API::V3::Boards do
it "returns authentication error" do
get v3_api(base_url)
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
@@ -46,7 +46,7 @@ describe API::V3::Boards do
it "returns the project issue board" do
get v3_api(base_url, user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
expect(json_response.first['id']).to eq(board.id)
@@ -63,7 +63,7 @@ describe API::V3::Boards do
it 'returns issue board lists' do
get v3_api(base_url, user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(2)
expect(json_response.first['label']['name']).to eq(dev_label.title)
@@ -72,7 +72,7 @@ describe API::V3::Boards do
it 'returns 404 if board not found' do
get v3_api("/projects/#{project.id}/boards/22343/lists", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -82,19 +82,19 @@ describe API::V3::Boards do
it "rejects a non member from deleting a list" do
delete v3_api("#{base_url}/#{dev_list.id}", non_member)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
it "rejects a user with guest role from deleting a list" do
delete v3_api("#{base_url}/#{dev_list.id}", guest)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
it "returns 404 error if list id not found" do
delete v3_api("#{base_url}/44444", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
context "when the user is project owner" do
@@ -107,7 +107,7 @@ describe API::V3::Boards do
it "deletes the list if an admin requests it" do
delete v3_api("#{base_url}/#{dev_list.id}", owner)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
end
end
diff --git a/spec/requests/api/v3/branches_spec.rb b/spec/requests/api/v3/branches_spec.rb
index 9cd11a67712..1e038595a1f 100644
--- a/spec/requests/api/v3/branches_spec.rb
+++ b/spec/requests/api/v3/branches_spec.rb
@@ -17,7 +17,7 @@ describe API::V3::Branches do
get v3_api("/projects/#{project.id}/repository/branches", user), per_page: 100
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
branch_names = json_response.map { |x| x['name'] }
expect(branch_names).to match_array(project.repository.branch_names)
@@ -32,20 +32,20 @@ describe API::V3::Branches do
it "removes branch" do
delete v3_api("/projects/#{project.id}/repository/branches/#{branch_name}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['branch_name']).to eq(branch_name)
end
it "removes a branch with dots in the branch name" do
delete v3_api("/projects/#{project.id}/repository/branches/with.1.2.3", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['branch_name']).to eq("with.1.2.3")
end
it 'returns 404 if branch not exists' do
delete v3_api("/projects/#{project.id}/repository/branches/foobar", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -57,13 +57,13 @@ describe API::V3::Branches do
it 'returns 200' do
delete v3_api("/projects/#{project.id}/repository/merged_branches", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it 'returns a 403 error if guest' do
delete v3_api("/projects/#{project.id}/repository/merged_branches", user2)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -73,7 +73,7 @@ describe API::V3::Branches do
branch_name: 'feature1',
ref: branch_sha
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['name']).to eq('feature1')
expect(json_response['commit']['id']).to eq(branch_sha)
@@ -83,14 +83,14 @@ describe API::V3::Branches do
post v3_api("/projects/#{project.id}/repository/branches", user2),
branch_name: branch_name,
ref: branch_sha
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
it 'returns 400 if branch name is invalid' do
post v3_api("/projects/#{project.id}/repository/branches", user),
branch_name: 'new design',
ref: branch_sha
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['message']).to eq('Branch name is invalid')
end
@@ -98,13 +98,13 @@ describe API::V3::Branches do
post v3_api("/projects/#{project.id}/repository/branches", user),
branch_name: 'new_design1',
ref: branch_sha
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
post v3_api("/projects/#{project.id}/repository/branches", user),
branch_name: 'new_design1',
ref: branch_sha
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['message']).to eq('Branch already exists')
end
@@ -113,7 +113,7 @@ describe API::V3::Branches do
branch_name: 'new_design3',
ref: 'foo'
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['message']).to eq('Invalid reference name')
end
end
diff --git a/spec/requests/api/v3/broadcast_messages_spec.rb b/spec/requests/api/v3/broadcast_messages_spec.rb
index d04b1c72004..d9641011491 100644
--- a/spec/requests/api/v3/broadcast_messages_spec.rb
+++ b/spec/requests/api/v3/broadcast_messages_spec.rb
@@ -11,21 +11,21 @@ describe API::V3::BroadcastMessages do
delete v3_api("/broadcast_messages/#{message.id}"),
attributes_for(:broadcast_message)
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
it 'returns a 403 for users' do
delete v3_api("/broadcast_messages/#{message.id}", user),
attributes_for(:broadcast_message)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
it 'deletes the broadcast message for admins' do
expect do
delete v3_api("/broadcast_messages/#{message.id}", admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end.to change { BroadcastMessage.count }.by(-1)
end
end
diff --git a/spec/requests/api/v3/builds_spec.rb b/spec/requests/api/v3/builds_spec.rb
index 0a2ff1058e3..3f58b7ef384 100644
--- a/spec/requests/api/v3/builds_spec.rb
+++ b/spec/requests/api/v3/builds_spec.rb
@@ -21,7 +21,7 @@ describe API::V3::Builds do
context 'authorized user' do
it 'returns project builds' do
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
end
@@ -44,7 +44,7 @@ describe API::V3::Builds do
let(:query) { 'scope=pending' }
it do
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
end
end
@@ -54,7 +54,7 @@ describe API::V3::Builds do
let(:json_build) { json_response.first }
it 'return builds with status skipped' do
- expect(response).to have_http_status 200
+ expect(response).to have_gitlab_http_status 200
expect(json_response).to be_an Array
expect(json_response.length).to eq 1
expect(json_build['status']).to eq 'skipped'
@@ -65,7 +65,7 @@ describe API::V3::Builds do
let(:query) { 'scope[0]=pending&scope[1]=running' }
it do
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
end
end
@@ -73,7 +73,7 @@ describe API::V3::Builds do
context 'respond 400 when scope contains invalid state' do
let(:query) { 'scope[0]=pending&scope[1]=unknown_status' }
- it { expect(response).to have_http_status(400) }
+ it { expect(response).to have_gitlab_http_status(400) }
end
end
@@ -81,7 +81,7 @@ describe API::V3::Builds do
let(:api_user) { nil }
it 'does not return project builds' do
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
end
@@ -93,7 +93,7 @@ describe API::V3::Builds do
end
it 'responds with 404' do
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -109,7 +109,7 @@ describe API::V3::Builds do
end
it 'returns project jobs for specific commit' do
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.size).to eq 2
@@ -132,7 +132,7 @@ describe API::V3::Builds do
end
it 'returns an empty array' do
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response).to be_empty
end
@@ -148,7 +148,7 @@ describe API::V3::Builds do
end
it 'does not return project jobs' do
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
expect(json_response.except('message')).to be_empty
end
end
@@ -162,7 +162,7 @@ describe API::V3::Builds do
context 'authorized user' do
it 'returns specific job data' do
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['name']).to eq('test')
end
@@ -180,7 +180,7 @@ describe API::V3::Builds do
let(:api_user) { nil }
it 'does not return specific job data' do
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
end
@@ -200,7 +200,7 @@ describe API::V3::Builds do
end
it 'returns specific job artifacts' do
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response.headers).to include(download_headers)
expect(response.body).to match_file(build.artifacts_file.file.file)
end
@@ -210,13 +210,13 @@ describe API::V3::Builds do
let(:api_user) { nil }
it 'does not return specific job artifacts' do
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
end
it 'does not return job artifacts if not uploaded' do
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -240,7 +240,7 @@ describe API::V3::Builds do
end
it 'gives 401' do
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
@@ -252,13 +252,13 @@ describe API::V3::Builds do
end
it 'gives 403' do
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
context 'non-existing job' do
shared_examples 'not found' do
- it { expect(response).to have_http_status(:not_found) }
+ it { expect(response).to have_gitlab_http_status(:not_found) }
end
context 'has no such ref' do
@@ -286,7 +286,7 @@ describe API::V3::Builds do
"attachment; filename=#{build.artifacts_file.filename}" }
end
- it { expect(response).to have_http_status(200) }
+ it { expect(response).to have_gitlab_http_status(200) }
it { expect(response.headers).to include(download_headers) }
end
@@ -327,7 +327,7 @@ describe API::V3::Builds do
context 'authorized user' do
it 'returns specific job trace' do
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response.body).to eq(build.trace.raw)
end
end
@@ -336,7 +336,7 @@ describe API::V3::Builds do
let(:api_user) { nil }
it 'does not return specific job trace' do
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
end
@@ -349,7 +349,7 @@ describe API::V3::Builds do
context 'authorized user' do
context 'user with :update_build persmission' do
it 'cancels running or pending job' do
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(project.builds.first.status).to eq('canceled')
end
end
@@ -358,7 +358,7 @@ describe API::V3::Builds do
let(:api_user) { reporter.user }
it 'does not cancel job' do
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
end
@@ -367,7 +367,7 @@ describe API::V3::Builds do
let(:api_user) { nil }
it 'does not cancel job' do
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
end
@@ -382,7 +382,7 @@ describe API::V3::Builds do
context 'authorized user' do
context 'user with :update_build permission' do
it 'retries non-running job' do
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(project.builds.first.status).to eq('canceled')
expect(json_response['status']).to eq('pending')
end
@@ -392,7 +392,7 @@ describe API::V3::Builds do
let(:api_user) { reporter.user }
it 'does not retry job' do
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
end
@@ -401,7 +401,7 @@ describe API::V3::Builds do
let(:api_user) { nil }
it 'does not retry job' do
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
end
@@ -471,7 +471,7 @@ describe API::V3::Builds do
let(:build) { create(:ci_build, :manual, project: project, pipeline: pipeline) }
it 'plays the job' do
- expect(response).to have_http_status 200
+ expect(response).to have_gitlab_http_status 200
expect(json_response['user']['id']).to eq(user.id)
expect(json_response['id']).to eq(build.id)
end
@@ -479,7 +479,7 @@ describe API::V3::Builds do
context 'on a non-playable job' do
it 'returns a status code 400, Bad Request' do
- expect(response).to have_http_status 400
+ expect(response).to have_gitlab_http_status 400
expect(response.body).to match("Unplayable Job")
end
end
diff --git a/spec/requests/api/v3/commits_spec.rb b/spec/requests/api/v3/commits_spec.rb
index 6d0ca33a6fa..d31c94ddd2c 100644
--- a/spec/requests/api/v3/commits_spec.rb
+++ b/spec/requests/api/v3/commits_spec.rb
@@ -19,7 +19,7 @@ describe API::V3::Commits do
commit = project.repository.commit
get v3_api("/projects/#{project.id}/repository/commits", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.first['id']).to eq(commit.id)
expect(json_response.first['committer_name']).to eq(commit.committer_name)
@@ -30,7 +30,7 @@ describe API::V3::Commits do
context "unauthorized user" do
it "does not return project commits" do
get v3_api("/projects/#{project.id}/repository/commits")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
@@ -69,7 +69,7 @@ describe API::V3::Commits do
it "returns an invalid parameter error message" do
get v3_api("/projects/#{project.id}/repository/commits?since=invalid-date", user)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['error']).to eq('since is invalid')
end
end
@@ -92,13 +92,13 @@ describe API::V3::Commits do
it 'returns a 403 unauthorized for user without permissions' do
post v3_api(url, user2)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
it 'returns a 400 bad request if no params are given' do
post v3_api(url, user)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
describe 'create' do
@@ -133,7 +133,7 @@ describe API::V3::Commits do
it 'a new file in project repo' do
post v3_api(url, user), valid_c_params
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['title']).to eq(message)
expect(json_response['committer_name']).to eq(user.name)
expect(json_response['committer_email']).to eq(user.email)
@@ -142,7 +142,7 @@ describe API::V3::Commits do
it 'returns a 400 bad request if file exists' do
post v3_api(url, user), invalid_c_params
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
context 'with project path containing a dot in URL' do
@@ -152,7 +152,7 @@ describe API::V3::Commits do
it 'a new file in project repo' do
post v3_api(url, user), valid_c_params
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
end
end
end
@@ -187,14 +187,14 @@ describe API::V3::Commits do
it 'an existing file in project repo' do
post v3_api(url, user), valid_d_params
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['title']).to eq(message)
end
it 'returns a 400 bad request if file does not exist' do
post v3_api(url, user), invalid_d_params
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
end
@@ -232,14 +232,14 @@ describe API::V3::Commits do
it 'an existing file in project repo' do
post v3_api(url, user), valid_m_params
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['title']).to eq(message)
end
it 'returns a 400 bad request if file does not exist' do
post v3_api(url, user), invalid_m_params
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
end
@@ -275,14 +275,14 @@ describe API::V3::Commits do
it 'an existing file in project repo' do
post v3_api(url, user), valid_u_params
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['title']).to eq(message)
end
it 'returns a 400 bad request if file does not exist' do
post v3_api(url, user), invalid_u_params
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
end
@@ -348,14 +348,14 @@ describe API::V3::Commits do
it 'are commited as one in project repo' do
post v3_api(url, user), valid_mo_params
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['title']).to eq(message)
end
it 'return a 400 bad request if there are any issues' do
post v3_api(url, user), invalid_mo_params
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
end
end
@@ -365,7 +365,7 @@ describe API::V3::Commits do
it "returns a commit by sha" do
get v3_api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['id']).to eq(project.repository.commit.id)
expect(json_response['title']).to eq(project.repository.commit.title)
expect(json_response['stats']['additions']).to eq(project.repository.commit.stats.additions)
@@ -375,13 +375,13 @@ describe API::V3::Commits do
it "returns a 404 error if not found" do
get v3_api("/projects/#{project.id}/repository/commits/invalid_sha", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it "returns nil for commit without CI" do
get v3_api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['status']).to be_nil
end
@@ -391,7 +391,7 @@ describe API::V3::Commits do
get v3_api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['status']).to eq(pipeline.status)
end
@@ -400,7 +400,7 @@ describe API::V3::Commits do
get v3_api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['status']).to eq("created")
end
end
@@ -408,7 +408,7 @@ describe API::V3::Commits do
context "unauthorized user" do
it "does not return the selected commit" do
get v3_api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
end
@@ -419,7 +419,7 @@ describe API::V3::Commits do
it "returns the diff of the selected commit" do
get v3_api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}/diff", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to be >= 1
@@ -428,14 +428,14 @@ describe API::V3::Commits do
it "returns a 404 error if invalid commit" do
get v3_api("/projects/#{project.id}/repository/commits/invalid_sha/diff", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
context "unauthorized user" do
it "does not return the diff of the selected commit" do
get v3_api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}/diff")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
end
@@ -444,7 +444,7 @@ describe API::V3::Commits do
context 'authorized user' do
it 'returns merge_request comments' do
get v3_api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}/comments", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(2)
expect(json_response.first['note']).to eq('a comment on a commit')
@@ -453,14 +453,14 @@ describe API::V3::Commits do
it 'returns a 404 error if merge_request_id not found' do
get v3_api("/projects/#{project.id}/repository/commits/1234ab/comments", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
context 'unauthorized user' do
it 'does not return the diff of the selected commit' do
get v3_api("/projects/#{project.id}/repository/commits/1234ab/comments")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
end
@@ -472,7 +472,7 @@ describe API::V3::Commits do
it 'cherry picks a commit' do
post v3_api("/projects/#{project.id}/repository/commits/#{master_pickable_commit.id}/cherry_pick", user), branch: 'master'
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['title']).to eq(master_pickable_commit.title)
expect(json_response['message']).to eq(master_pickable_commit.cherry_pick_message(user))
expect(json_response['author_name']).to eq(master_pickable_commit.author_name)
@@ -482,7 +482,7 @@ describe API::V3::Commits do
it 'returns 400 if commit is already included in the target branch' do
post v3_api("/projects/#{project.id}/repository/commits/#{master_pickable_commit.id}/cherry_pick", user), branch: 'markdown'
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['message']).to include('Sorry, we cannot cherry-pick this commit automatically.')
end
@@ -492,35 +492,35 @@ describe API::V3::Commits do
post v3_api("/projects/#{project.id}/repository/commits/#{master_pickable_commit.id}/cherry_pick", user2), branch: protected_branch.name
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['message']).to eq('You are not allowed to push into this branch')
end
it 'returns 400 for missing parameters' do
post v3_api("/projects/#{project.id}/repository/commits/#{master_pickable_commit.id}/cherry_pick", user)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['error']).to eq('branch is missing')
end
it 'returns 404 if commit is not found' do
post v3_api("/projects/#{project.id}/repository/commits/abcd0123/cherry_pick", user), branch: 'master'
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 Commit Not Found')
end
it 'returns 404 if branch is not found' do
post v3_api("/projects/#{project.id}/repository/commits/#{master_pickable_commit.id}/cherry_pick", user), branch: 'foo'
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 Branch Not Found')
end
it 'returns 400 for missing parameters' do
post v3_api("/projects/#{project.id}/repository/commits/#{master_pickable_commit.id}/cherry_pick", user)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['error']).to eq('branch is missing')
end
end
@@ -529,7 +529,7 @@ describe API::V3::Commits do
it 'does not cherry pick the commit' do
post v3_api("/projects/#{project.id}/repository/commits/#{master_pickable_commit.id}/cherry_pick"), branch: 'master'
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
end
@@ -538,7 +538,7 @@ describe API::V3::Commits do
context 'authorized user' do
it 'returns comment' do
post v3_api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}/comments", user), note: 'My comment'
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['note']).to eq('My comment')
expect(json_response['path']).to be_nil
expect(json_response['line']).to be_nil
@@ -548,7 +548,7 @@ describe API::V3::Commits do
it 'returns the inline comment' do
post v3_api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}/comments", user), note: 'My comment', path: project.repository.commit.raw_diffs.first.new_path, line: 1, line_type: 'new'
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['note']).to eq('My comment')
expect(json_response['path']).to eq(project.repository.commit.raw_diffs.first.new_path)
expect(json_response['line']).to eq(1)
@@ -557,19 +557,19 @@ describe API::V3::Commits do
it 'returns 400 if note is missing' do
post v3_api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}/comments", user)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it 'returns 404 if note is attached to non existent commit' do
post v3_api("/projects/#{project.id}/repository/commits/1234ab/comments", user), note: 'My comment'
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
context 'unauthorized user' do
it 'does not return the diff of the selected commit' do
post v3_api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}/comments")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
end
diff --git a/spec/requests/api/v3/deploy_keys_spec.rb b/spec/requests/api/v3/deploy_keys_spec.rb
index 2affd0cfa51..785bc1eb4ba 100644
--- a/spec/requests/api/v3/deploy_keys_spec.rb
+++ b/spec/requests/api/v3/deploy_keys_spec.rb
@@ -46,7 +46,7 @@ describe API::V3::DeployKeys do
it 'should return array of ssh keys' do
get v3_api("/projects/#{project.id}/#{path}", admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.first['title']).to eq(deploy_key.title)
end
@@ -56,14 +56,14 @@ describe API::V3::DeployKeys do
it 'should return a single key' do
get v3_api("/projects/#{project.id}/#{path}/#{deploy_key.id}", admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['title']).to eq(deploy_key.title)
end
it 'should return 404 Not Found with invalid ID' do
get v3_api("/projects/#{project.id}/#{path}/404", admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -71,14 +71,14 @@ describe API::V3::DeployKeys do
it 'should not create an invalid ssh key' do
post v3_api("/projects/#{project.id}/#{path}", admin), { title: 'invalid key' }
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['error']).to eq('key is missing')
end
it 'should not create a key without title' do
post v3_api("/projects/#{project.id}/#{path}", admin), key: 'some key'
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['error']).to eq('title is missing')
end
@@ -95,7 +95,7 @@ describe API::V3::DeployKeys do
post v3_api("/projects/#{project.id}/#{path}", admin), { key: deploy_key.key, title: deploy_key.title }
end.not_to change { project.deploy_keys.count }
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
end
it 'joins an existing ssh key to a new project' do
@@ -103,7 +103,7 @@ describe API::V3::DeployKeys do
post v3_api("/projects/#{project2.id}/#{path}", admin), { key: deploy_key.key, title: deploy_key.title }
end.to change { project2.deploy_keys.count }.by(1)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
end
it 'accepts can_push parameter' do
@@ -111,7 +111,7 @@ describe API::V3::DeployKeys do
post v3_api("/projects/#{project.id}/#{path}", admin), key_attrs
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['can_push']).to eq(true)
end
end
@@ -128,7 +128,7 @@ describe API::V3::DeployKeys do
it 'should return 404 Not Found with invalid ID' do
delete v3_api("/projects/#{project.id}/#{path}/404", admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -141,7 +141,7 @@ describe API::V3::DeployKeys do
post v3_api("/projects/#{project2.id}/#{path}/#{deploy_key.id}/enable", admin)
end.to change { project2.deploy_keys.count }.from(0).to(1)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['id']).to eq(deploy_key.id)
end
end
@@ -150,7 +150,7 @@ describe API::V3::DeployKeys do
it 'should return a 404 error' do
post v3_api("/projects/#{project2.id}/#{path}/#{deploy_key.id}/enable", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -162,7 +162,7 @@ describe API::V3::DeployKeys do
delete v3_api("/projects/#{project.id}/#{path}/#{deploy_key.id}/disable", admin)
end.to change { project.deploy_keys.count }.from(1).to(0)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['id']).to eq(deploy_key.id)
end
end
@@ -171,7 +171,7 @@ describe API::V3::DeployKeys do
it 'should return a 404 error' do
delete v3_api("/projects/#{project.id}/#{path}/#{deploy_key.id}/disable", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
diff --git a/spec/requests/api/v3/deployments_spec.rb b/spec/requests/api/v3/deployments_spec.rb
index 0389a264781..90eabda4dac 100644
--- a/spec/requests/api/v3/deployments_spec.rb
+++ b/spec/requests/api/v3/deployments_spec.rb
@@ -30,7 +30,7 @@ describe API::V3::Deployments do
it 'returns projects deployments' do
get v3_api("/projects/#{project.id}/deployments", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.size).to eq(1)
expect(json_response.first['iid']).to eq(deployment.iid)
@@ -42,7 +42,7 @@ describe API::V3::Deployments do
it 'returns a 404 status code' do
get v3_api("/projects/#{project.id}/deployments", non_member)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -52,7 +52,7 @@ describe API::V3::Deployments do
it 'returns the projects deployment' do
get v3_api("/projects/#{project.id}/deployments/#{deployment.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['sha']).to match /\A\h{40}\z/
expect(json_response['id']).to eq(deployment.id)
end
@@ -62,7 +62,7 @@ describe API::V3::Deployments do
it 'returns a 404 status code' do
get v3_api("/projects/#{project.id}/deployments/#{deployment.id}", non_member)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
diff --git a/spec/requests/api/v3/environments_spec.rb b/spec/requests/api/v3/environments_spec.rb
index 39264e819a3..937250b5219 100644
--- a/spec/requests/api/v3/environments_spec.rb
+++ b/spec/requests/api/v3/environments_spec.rb
@@ -36,7 +36,7 @@ describe API::V3::Environments do
it 'returns project environments' do
get v3_api("/projects/#{project.id}/environments", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.size).to eq(1)
expect(json_response.first['name']).to eq(environment.name)
@@ -50,7 +50,7 @@ describe API::V3::Environments do
it 'returns a 404 status code' do
get v3_api("/projects/#{project.id}/environments", non_member)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -60,7 +60,7 @@ describe API::V3::Environments do
it 'creates a environment with valid params' do
post v3_api("/projects/#{project.id}/environments", user), name: "mepmep"
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['name']).to eq('mepmep')
expect(json_response['slug']).to eq('mepmep')
expect(json_response['external']).to be nil
@@ -69,19 +69,19 @@ describe API::V3::Environments do
it 'requires name to be passed' do
post v3_api("/projects/#{project.id}/environments", user), external_url: 'test.gitlab.com'
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it 'returns a 400 if environment already exists' do
post v3_api("/projects/#{project.id}/environments", user), name: environment.name
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it 'returns a 400 if slug is specified' do
post v3_api("/projects/#{project.id}/environments", user), name: "foo", slug: "foo"
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response["error"]).to eq("slug is automatically generated and cannot be changed")
end
end
@@ -90,7 +90,7 @@ describe API::V3::Environments do
it 'rejects the request' do
post v3_api("/projects/#{project.id}/environments", non_member), name: 'gitlab.com'
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'returns a 400 when the required params are missing' do
@@ -105,7 +105,7 @@ describe API::V3::Environments do
put v3_api("/projects/#{project.id}/environments/#{environment.id}", user),
name: 'Mepmep', external_url: url
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['name']).to eq('Mepmep')
expect(json_response['external_url']).to eq(url)
end
@@ -115,7 +115,7 @@ describe API::V3::Environments do
api_url = v3_api("/projects/#{project.id}/environments/#{environment.id}", user)
put api_url, slug: slug + "-foo"
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response["error"]).to eq("slug is automatically generated and cannot be changed")
end
@@ -124,7 +124,7 @@ describe API::V3::Environments do
put v3_api("/projects/#{project.id}/environments/#{environment.id}", user),
name: 'Mepmep'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['name']).to eq('Mepmep')
expect(json_response['external_url']).to eq(url)
end
@@ -132,7 +132,7 @@ describe API::V3::Environments do
it 'returns a 404 if the environment does not exist' do
put v3_api("/projects/#{project.id}/environments/12345", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -141,13 +141,13 @@ describe API::V3::Environments do
it 'returns a 200 for an existing environment' do
delete v3_api("/projects/#{project.id}/environments/#{environment.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it 'returns a 404 for non existing id' do
delete v3_api("/projects/#{project.id}/environments/12345", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 Not found')
end
end
@@ -156,7 +156,7 @@ describe API::V3::Environments do
it 'rejects the request' do
delete v3_api("/projects/#{project.id}/environments/#{environment.id}", non_member)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
diff --git a/spec/requests/api/v3/files_spec.rb b/spec/requests/api/v3/files_spec.rb
index dc7f0eefd16..5500c1cf770 100644
--- a/spec/requests/api/v3/files_spec.rb
+++ b/spec/requests/api/v3/files_spec.rb
@@ -36,7 +36,7 @@ describe API::V3::Files do
it "returns file info" do
get v3_api(route, current_user), params
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['file_path']).to eq(file_path)
expect(json_response['file_name']).to eq('popen.rb')
expect(json_response['last_commit_id']).to eq('570e7b2abdd848b95f2f578043fc23bd6f6fd24d')
@@ -112,7 +112,7 @@ describe API::V3::Files do
it "creates a new file in project repo" do
post v3_api("/projects/#{project.id}/repository/files", user), valid_params
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['file_path']).to eq('newfile.rb')
last_commit = project.repository.commit.raw
expect(last_commit.author_email).to eq(user.email)
@@ -122,7 +122,7 @@ describe API::V3::Files do
it "returns a 400 bad request if no params given" do
post v3_api("/projects/#{project.id}/repository/files", user)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it "returns a 400 if editor fails to create file" do
@@ -131,7 +131,7 @@ describe API::V3::Files do
post v3_api("/projects/#{project.id}/repository/files", user), valid_params
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
context "when specifying an author" do
@@ -140,7 +140,7 @@ describe API::V3::Files do
post v3_api("/projects/#{project.id}/repository/files", user), valid_params
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
last_commit = project.repository.commit.raw
expect(last_commit.author_email).to eq(author_email)
expect(last_commit.author_name).to eq(author_name)
@@ -153,7 +153,7 @@ describe API::V3::Files do
it "creates a new file in project repo" do
post v3_api("/projects/#{project.id}/repository/files", user), valid_params
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['file_path']).to eq('newfile.rb')
last_commit = project.repository.commit.raw
expect(last_commit.author_email).to eq(user.email)
@@ -175,7 +175,7 @@ describe API::V3::Files do
it "updates existing file in project repo" do
put v3_api("/projects/#{project.id}/repository/files", user), valid_params
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['file_path']).to eq(file_path)
last_commit = project.repository.commit.raw
expect(last_commit.author_email).to eq(user.email)
@@ -185,7 +185,7 @@ describe API::V3::Files do
it "returns a 400 bad request if no params given" do
put v3_api("/projects/#{project.id}/repository/files", user)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
context "when specifying an author" do
@@ -194,7 +194,7 @@ describe API::V3::Files do
put v3_api("/projects/#{project.id}/repository/files", user), valid_params
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
last_commit = project.repository.commit.raw
expect(last_commit.author_email).to eq(author_email)
expect(last_commit.author_name).to eq(author_name)
@@ -214,7 +214,7 @@ describe API::V3::Files do
it "deletes existing file in project repo" do
delete v3_api("/projects/#{project.id}/repository/files", user), valid_params
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['file_path']).to eq(file_path)
last_commit = project.repository.commit.raw
expect(last_commit.author_email).to eq(user.email)
@@ -224,7 +224,7 @@ describe API::V3::Files do
it "returns a 400 bad request if no params given" do
delete v3_api("/projects/#{project.id}/repository/files", user)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it "returns a 400 if fails to delete file" do
@@ -232,7 +232,7 @@ describe API::V3::Files do
delete v3_api("/projects/#{project.id}/repository/files", user), valid_params
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
context "when specifying an author" do
@@ -241,7 +241,7 @@ describe API::V3::Files do
delete v3_api("/projects/#{project.id}/repository/files", user), valid_params
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
last_commit = project.repository.commit.raw
expect(last_commit.author_email).to eq(author_email)
expect(last_commit.author_name).to eq(author_name)
@@ -274,7 +274,7 @@ describe API::V3::Files do
it "remains unchanged" do
get v3_api("/projects/#{project.id}/repository/files", user), get_params
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['file_path']).to eq(file_path)
expect(json_response['file_name']).to eq(file_path)
expect(json_response['content']).to eq(put_params[:content])
diff --git a/spec/requests/api/v3/groups_spec.rb b/spec/requests/api/v3/groups_spec.rb
index 778fcc73c30..498cb42fad1 100644
--- a/spec/requests/api/v3/groups_spec.rb
+++ b/spec/requests/api/v3/groups_spec.rb
@@ -23,7 +23,7 @@ describe API::V3::Groups do
it "returns authentication error" do
get v3_api("/groups")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
@@ -31,7 +31,7 @@ describe API::V3::Groups do
it "normal user: returns an array of groups of user1" do
get v3_api("/groups", user1)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
expect(json_response)
@@ -41,7 +41,7 @@ describe API::V3::Groups do
it "does not include statistics" do
get v3_api("/groups", user1), statistics: true
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.first).not_to include 'statistics'
end
@@ -51,7 +51,7 @@ describe API::V3::Groups do
it "admin: returns an array of all groups" do
get v3_api("/groups", admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(2)
end
@@ -59,7 +59,7 @@ describe API::V3::Groups do
it "does not include statistics by default" do
get v3_api("/groups", admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.first).not_to include('statistics')
end
@@ -76,7 +76,7 @@ describe API::V3::Groups do
get v3_api("/groups", admin), statistics: true
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response)
.to satisfy_one { |group| group['statistics'] == attributes }
@@ -87,7 +87,7 @@ describe API::V3::Groups do
it "returns all groups excluding skipped groups" do
get v3_api("/groups", admin), skip_groups: [group2.id]
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
end
@@ -101,7 +101,7 @@ describe API::V3::Groups do
get v3_api("/groups", user1), all_available: true
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(response_groups).to contain_exactly(public_group.name, group1.name)
end
@@ -118,7 +118,7 @@ describe API::V3::Groups do
it "sorts by name ascending by default" do
get v3_api("/groups", user1)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(response_groups).to eq([group3.name, group1.name])
end
@@ -126,7 +126,7 @@ describe API::V3::Groups do
it "sorts in descending order when passed" do
get v3_api("/groups", user1), sort: "desc"
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(response_groups).to eq([group1.name, group3.name])
end
@@ -134,7 +134,7 @@ describe API::V3::Groups do
it "sorts by the order_by param" do
get v3_api("/groups", user1), order_by: "path"
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(response_groups).to eq([group1.name, group3.name])
end
@@ -146,7 +146,7 @@ describe API::V3::Groups do
it 'returns authentication error' do
get v3_api('/groups/owned')
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
@@ -154,7 +154,7 @@ describe API::V3::Groups do
it 'returns an array of groups the user owns' do
get v3_api('/groups/owned', user2)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.first['name']).to eq(group2.name)
@@ -170,7 +170,7 @@ describe API::V3::Groups do
get v3_api("/groups/#{group1.id}", user1)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['id']).to eq(group1.id)
expect(json_response['name']).to eq(group1.name)
expect(json_response['path']).to eq(group1.path)
@@ -192,13 +192,13 @@ describe API::V3::Groups do
it "does not return a non existing group" do
get v3_api("/groups/1328", user1)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it "does not return a group not attached to user1" do
get v3_api("/groups/#{group2.id}", user1)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -206,14 +206,14 @@ describe API::V3::Groups do
it "returns any existing group" do
get v3_api("/groups/#{group2.id}", admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['name']).to eq(group2.name)
end
it "does not return a non existing group" do
get v3_api("/groups/1328", admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -221,20 +221,20 @@ describe API::V3::Groups do
it 'returns any existing group' do
get v3_api("/groups/#{group1.path}", admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['name']).to eq(group1.name)
end
it 'does not return a non existing group' do
get v3_api('/groups/unknown', admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'does not return a group not attached to user1' do
get v3_api("/groups/#{group2.path}", user1)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -246,7 +246,7 @@ describe API::V3::Groups do
it 'updates the group' do
put v3_api("/groups/#{group1.id}", user1), name: new_group_name, request_access_enabled: true
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['name']).to eq(new_group_name)
expect(json_response['request_access_enabled']).to eq(true)
end
@@ -254,7 +254,7 @@ describe API::V3::Groups do
it 'returns 404 for a non existing group' do
put v3_api('/groups/1328', user1), name: new_group_name
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -262,7 +262,7 @@ describe API::V3::Groups do
it 'updates the group' do
put v3_api("/groups/#{group1.id}", admin), name: new_group_name
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['name']).to eq(new_group_name)
end
end
@@ -271,7 +271,7 @@ describe API::V3::Groups do
it 'does not updates the group' do
put v3_api("/groups/#{group1.id}", user2), name: new_group_name
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -279,7 +279,7 @@ describe API::V3::Groups do
it 'returns 404 when trying to update the group' do
put v3_api("/groups/#{group2.id}", user1), name: new_group_name
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -289,7 +289,7 @@ describe API::V3::Groups do
it "returns the group's projects" do
get v3_api("/groups/#{group1.id}/projects", user1)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response.length).to eq(2)
project_names = json_response.map { |proj| proj['name'] }
expect(project_names).to match_array([project1.name, project3.name])
@@ -299,7 +299,7 @@ describe API::V3::Groups do
it "returns the group's projects with simple representation" do
get v3_api("/groups/#{group1.id}/projects", user1), simple: true
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response.length).to eq(2)
project_names = json_response.map { |proj| proj['name'] }
expect(project_names).to match_array([project1.name, project3.name])
@@ -311,7 +311,7 @@ describe API::V3::Groups do
get v3_api("/groups/#{group1.id}/projects", user1), visibility: 'public'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an(Array)
expect(json_response.length).to eq(1)
expect(json_response.first['name']).to eq(public_project.name)
@@ -320,13 +320,13 @@ describe API::V3::Groups do
it "does not return a non existing group" do
get v3_api("/groups/1328/projects", user1)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it "does not return a group not attached to user1" do
get v3_api("/groups/#{group2.id}/projects", user1)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it "only returns projects to which user has access" do
@@ -334,7 +334,7 @@ describe API::V3::Groups do
get v3_api("/groups/#{group1.id}/projects", user3)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response.length).to eq(1)
expect(json_response.first['name']).to eq(project3.name)
end
@@ -344,7 +344,7 @@ describe API::V3::Groups do
get v3_api("/groups/#{project2.group.id}/projects", user3), owned: true
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response.length).to eq(1)
expect(json_response.first['name']).to eq(project2.name)
end
@@ -354,7 +354,7 @@ describe API::V3::Groups do
get v3_api("/groups/#{group1.id}/projects", user1), starred: true
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response.length).to eq(1)
expect(json_response.first['name']).to eq(project1.name)
end
@@ -364,7 +364,7 @@ describe API::V3::Groups do
it "returns any existing group" do
get v3_api("/groups/#{group2.id}/projects", admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response.length).to eq(1)
expect(json_response.first['name']).to eq(project2.name)
end
@@ -372,7 +372,7 @@ describe API::V3::Groups do
it "does not return a non existing group" do
get v3_api("/groups/1328/projects", admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -380,7 +380,7 @@ describe API::V3::Groups do
it 'returns any existing group' do
get v3_api("/groups/#{group1.path}/projects", admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
project_names = json_response.map { |proj| proj['name'] }
expect(project_names).to match_array([project1.name, project3.name])
end
@@ -388,13 +388,13 @@ describe API::V3::Groups do
it 'does not return a non existing group' do
get v3_api('/groups/unknown/projects', admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'does not return a group not attached to user1' do
get v3_api("/groups/#{group2.path}/projects", user1)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -404,7 +404,7 @@ describe API::V3::Groups do
it "does not create group" do
post v3_api("/groups", user1), attributes_for(:group)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -414,7 +414,7 @@ describe API::V3::Groups do
post v3_api("/groups", user3), group
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response["name"]).to eq(group[:name])
expect(json_response["path"]).to eq(group[:path])
@@ -428,7 +428,7 @@ describe API::V3::Groups do
post v3_api("/groups", user3), group
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response["full_path"]).to eq("#{parent.path}/#{group[:path]}")
expect(json_response["parent_id"]).to eq(parent.id)
@@ -437,20 +437,20 @@ describe API::V3::Groups do
it "does not create group, duplicate" do
post v3_api("/groups", user3), { name: 'Duplicate Test', path: group2.path }
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(response.message).to eq("Bad Request")
end
it "returns 400 bad request error if name not given" do
post v3_api("/groups", user3), { path: group2.path }
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it "returns 400 bad request error if path not given" do
post v3_api("/groups", user3), { name: 'test' }
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
end
end
@@ -460,7 +460,7 @@ describe API::V3::Groups do
it "removes group" do
delete v3_api("/groups/#{group1.id}", user1)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it "does not remove a group if not an owner" do
@@ -469,19 +469,19 @@ describe API::V3::Groups do
delete v3_api("/groups/#{group1.id}", user3)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
it "does not remove a non existing group" do
delete v3_api("/groups/1328", user1)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it "does not remove a group not attached to user1" do
delete v3_api("/groups/#{group2.id}", user1)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -489,13 +489,13 @@ describe API::V3::Groups do
it "removes any existing group" do
delete v3_api("/groups/#{group2.id}", admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it "does not remove a non existing group" do
delete v3_api("/groups/1328", admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -513,7 +513,7 @@ describe API::V3::Groups do
it "does not transfer project to group" do
post v3_api("/groups/#{group1.id}/projects/#{project.id}", user2)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -521,7 +521,7 @@ describe API::V3::Groups do
it "transfers project to group" do
post v3_api("/groups/#{group1.id}/projects/#{project.id}", admin)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
end
context 'when using project path in URL' do
@@ -529,7 +529,7 @@ describe API::V3::Groups do
it "transfers project to group" do
post v3_api("/groups/#{group1.id}/projects/#{project_path}", admin)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
end
end
@@ -537,7 +537,7 @@ describe API::V3::Groups do
it "does not transfer project to group" do
post v3_api("/groups/#{group1.id}/projects/nogroup%2Fnoproject", admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -547,7 +547,7 @@ describe API::V3::Groups do
it "transfers project to group" do
post v3_api("/groups/#{group1.path}/projects/#{project_path}", admin)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
end
end
@@ -555,7 +555,7 @@ describe API::V3::Groups do
it "does not transfer project to group" do
post v3_api("/groups/noexist/projects/#{project_path}", admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
diff --git a/spec/requests/api/v3/issues_spec.rb b/spec/requests/api/v3/issues_spec.rb
index 86768d7397a..39a47a62f16 100644
--- a/spec/requests/api/v3/issues_spec.rb
+++ b/spec/requests/api/v3/issues_spec.rb
@@ -59,7 +59,7 @@ describe API::V3::Issues, :mailer do
it "returns authentication error" do
get v3_api("/issues")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
@@ -67,7 +67,7 @@ describe API::V3::Issues, :mailer do
it "returns an array of issues" do
get v3_api("/issues", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.first['title']).to eq(issue.title)
expect(json_response.last).to have_key('web_url')
@@ -76,7 +76,7 @@ describe API::V3::Issues, :mailer do
it 'returns an array of closed issues' do
get v3_api('/issues?state=closed', user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
expect(json_response.first['id']).to eq(closed_issue.id)
@@ -85,7 +85,7 @@ describe API::V3::Issues, :mailer do
it 'returns an array of opened issues' do
get v3_api('/issues?state=opened', user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
expect(json_response.first['id']).to eq(issue.id)
@@ -94,7 +94,7 @@ describe API::V3::Issues, :mailer do
it 'returns an array of all issues' do
get v3_api('/issues?state=all', user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(2)
expect(json_response.first['id']).to eq(issue.id)
@@ -104,7 +104,7 @@ describe API::V3::Issues, :mailer do
it 'returns an array of labeled issues' do
get v3_api("/issues?labels=#{label.title}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
expect(json_response.first['labels']).to eq([label.title])
@@ -113,7 +113,7 @@ describe API::V3::Issues, :mailer do
it 'returns an array of labeled issues when at least one label matches' do
get v3_api("/issues?labels=#{label.title},foo,bar", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
expect(json_response.first['labels']).to eq([label.title])
@@ -122,7 +122,7 @@ describe API::V3::Issues, :mailer do
it 'returns an empty array if no issue matches labels' do
get v3_api('/issues?labels=foo,bar', user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(0)
end
@@ -130,7 +130,7 @@ describe API::V3::Issues, :mailer do
it 'returns an array of labeled issues matching given state' do
get v3_api("/issues?labels=#{label.title}&state=opened", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
expect(json_response.first['labels']).to eq([label.title])
@@ -140,7 +140,7 @@ describe API::V3::Issues, :mailer do
it 'returns an empty array if no issue matches labels and state filters' do
get v3_api("/issues?labels=#{label.title}&state=closed", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(0)
end
@@ -148,7 +148,7 @@ describe API::V3::Issues, :mailer do
it 'returns an empty array if no issue matches milestone' do
get v3_api("/issues?milestone=#{empty_milestone.title}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(0)
end
@@ -156,7 +156,7 @@ describe API::V3::Issues, :mailer do
it 'returns an empty array if milestone does not exist' do
get v3_api("/issues?milestone=foo", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(0)
end
@@ -164,7 +164,7 @@ describe API::V3::Issues, :mailer do
it 'returns an array of issues in given milestone' do
get v3_api("/issues?milestone=#{milestone.title}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(2)
expect(json_response.first['id']).to eq(issue.id)
@@ -175,7 +175,7 @@ describe API::V3::Issues, :mailer do
get v3_api("/issues?milestone=#{milestone.title}", user),
'&state=closed'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
expect(json_response.first['id']).to eq(closed_issue.id)
@@ -184,7 +184,7 @@ describe API::V3::Issues, :mailer do
it 'returns an array of issues with no milestone' do
get v3_api("/issues?milestone=#{no_milestone_title}", author)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
expect(json_response.first['id']).to eq(confidential_issue.id)
@@ -195,7 +195,7 @@ describe API::V3::Issues, :mailer do
response_dates = json_response.map { |issue| issue['created_at'] }
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(response_dates).to eq(response_dates.sort.reverse)
end
@@ -205,7 +205,7 @@ describe API::V3::Issues, :mailer do
response_dates = json_response.map { |issue| issue['created_at'] }
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(response_dates).to eq(response_dates.sort)
end
@@ -215,7 +215,7 @@ describe API::V3::Issues, :mailer do
response_dates = json_response.map { |issue| issue['updated_at'] }
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(response_dates).to eq(response_dates.sort.reverse)
end
@@ -225,7 +225,7 @@ describe API::V3::Issues, :mailer do
response_dates = json_response.map { |issue| issue['updated_at'] }
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(response_dates).to eq(response_dates.sort)
end
@@ -233,7 +233,7 @@ describe API::V3::Issues, :mailer do
it 'matches V3 response schema' do
get v3_api('/issues', user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to match_response_schema('public_api/v3/issues')
end
end
@@ -285,7 +285,7 @@ describe API::V3::Issues, :mailer do
it 'returns all group issues (including opened and closed)' do
get v3_api(base_url, admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(3)
end
@@ -293,7 +293,7 @@ describe API::V3::Issues, :mailer do
it 'returns group issues without confidential issues for non project members' do
get v3_api("#{base_url}?state=opened", non_member)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
expect(json_response.first['title']).to eq(group_issue.title)
@@ -302,7 +302,7 @@ describe API::V3::Issues, :mailer do
it 'returns group confidential issues for author' do
get v3_api("#{base_url}?state=opened", author)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(2)
end
@@ -310,7 +310,7 @@ describe API::V3::Issues, :mailer do
it 'returns group confidential issues for assignee' do
get v3_api("#{base_url}?state=opened", assignee)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(2)
end
@@ -318,7 +318,7 @@ describe API::V3::Issues, :mailer do
it 'returns group issues with confidential issues for project members' do
get v3_api("#{base_url}?state=opened", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(2)
end
@@ -326,7 +326,7 @@ describe API::V3::Issues, :mailer do
it 'returns group confidential issues for admin' do
get v3_api("#{base_url}?state=opened", admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(2)
end
@@ -334,7 +334,7 @@ describe API::V3::Issues, :mailer do
it 'returns an array of labeled group issues' do
get v3_api("#{base_url}?labels=#{group_label.title}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
expect(json_response.first['labels']).to eq([group_label.title])
@@ -343,7 +343,7 @@ describe API::V3::Issues, :mailer do
it 'returns an array of labeled group issues where all labels match' do
get v3_api("#{base_url}?labels=#{group_label.title},foo,bar", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(0)
end
@@ -351,7 +351,7 @@ describe API::V3::Issues, :mailer do
it 'returns an empty array if no group issue matches labels' do
get v3_api("#{base_url}?labels=foo,bar", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(0)
end
@@ -359,7 +359,7 @@ describe API::V3::Issues, :mailer do
it 'returns an empty array if no issue matches milestone' do
get v3_api("#{base_url}?milestone=#{group_empty_milestone.title}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(0)
end
@@ -367,7 +367,7 @@ describe API::V3::Issues, :mailer do
it 'returns an empty array if milestone does not exist' do
get v3_api("#{base_url}?milestone=foo", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(0)
end
@@ -375,7 +375,7 @@ describe API::V3::Issues, :mailer do
it 'returns an array of issues in given milestone' do
get v3_api("#{base_url}?state=opened&milestone=#{group_milestone.title}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
expect(json_response.first['id']).to eq(group_issue.id)
@@ -385,7 +385,7 @@ describe API::V3::Issues, :mailer do
get v3_api("#{base_url}?milestone=#{group_milestone.title}", user),
'&state=closed'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
expect(json_response.first['id']).to eq(group_closed_issue.id)
@@ -394,7 +394,7 @@ describe API::V3::Issues, :mailer do
it 'returns an array of issues with no milestone' do
get v3_api("#{base_url}?milestone=#{no_milestone_title}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
expect(json_response.first['id']).to eq(group_confidential_issue.id)
@@ -405,7 +405,7 @@ describe API::V3::Issues, :mailer do
response_dates = json_response.map { |issue| issue['created_at'] }
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(response_dates).to eq(response_dates.sort.reverse)
end
@@ -415,7 +415,7 @@ describe API::V3::Issues, :mailer do
response_dates = json_response.map { |issue| issue['created_at'] }
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(response_dates).to eq(response_dates.sort)
end
@@ -425,7 +425,7 @@ describe API::V3::Issues, :mailer do
response_dates = json_response.map { |issue| issue['updated_at'] }
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(response_dates).to eq(response_dates.sort.reverse)
end
@@ -435,7 +435,7 @@ describe API::V3::Issues, :mailer do
response_dates = json_response.map { |issue| issue['updated_at'] }
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(response_dates).to eq(response_dates.sort)
end
@@ -447,7 +447,7 @@ describe API::V3::Issues, :mailer do
it 'returns 404 when project does not exist' do
get v3_api('/projects/1000/issues', non_member)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it "returns 404 on private projects for other users" do
@@ -456,7 +456,7 @@ describe API::V3::Issues, :mailer do
get v3_api("/projects/#{private_project.id}/issues", non_member)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'returns no issues when user has access to project but not issues' do
@@ -471,7 +471,7 @@ describe API::V3::Issues, :mailer do
it 'returns project issues without confidential issues for non project members' do
get v3_api("#{base_url}/issues", non_member)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(2)
expect(json_response.first['title']).to eq(issue.title)
@@ -480,7 +480,7 @@ describe API::V3::Issues, :mailer do
it 'returns project issues without confidential issues for project members with guest role' do
get v3_api("#{base_url}/issues", guest)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(2)
expect(json_response.first['title']).to eq(issue.title)
@@ -489,7 +489,7 @@ describe API::V3::Issues, :mailer do
it 'returns project confidential issues for author' do
get v3_api("#{base_url}/issues", author)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(3)
expect(json_response.first['title']).to eq(issue.title)
@@ -498,7 +498,7 @@ describe API::V3::Issues, :mailer do
it 'returns project confidential issues for assignee' do
get v3_api("#{base_url}/issues", assignee)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(3)
expect(json_response.first['title']).to eq(issue.title)
@@ -507,7 +507,7 @@ describe API::V3::Issues, :mailer do
it 'returns project issues with confidential issues for project members' do
get v3_api("#{base_url}/issues", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(3)
expect(json_response.first['title']).to eq(issue.title)
@@ -516,7 +516,7 @@ describe API::V3::Issues, :mailer do
it 'returns project confidential issues for admin' do
get v3_api("#{base_url}/issues", admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(3)
expect(json_response.first['title']).to eq(issue.title)
@@ -525,7 +525,7 @@ describe API::V3::Issues, :mailer do
it 'returns an array of labeled project issues' do
get v3_api("#{base_url}/issues?labels=#{label.title}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
expect(json_response.first['labels']).to eq([label.title])
@@ -534,7 +534,7 @@ describe API::V3::Issues, :mailer do
it 'returns an array of labeled project issues where all labels match' do
get v3_api("#{base_url}/issues?labels=#{label.title},foo,bar", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
expect(json_response.first['labels']).to eq([label.title])
@@ -543,7 +543,7 @@ describe API::V3::Issues, :mailer do
it 'returns an empty array if no project issue matches labels' do
get v3_api("#{base_url}/issues?labels=foo,bar", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(0)
end
@@ -551,7 +551,7 @@ describe API::V3::Issues, :mailer do
it 'returns an empty array if no issue matches milestone' do
get v3_api("#{base_url}/issues?milestone=#{empty_milestone.title}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(0)
end
@@ -559,7 +559,7 @@ describe API::V3::Issues, :mailer do
it 'returns an empty array if milestone does not exist' do
get v3_api("#{base_url}/issues?milestone=foo", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(0)
end
@@ -567,7 +567,7 @@ describe API::V3::Issues, :mailer do
it 'returns an array of issues in given milestone' do
get v3_api("#{base_url}/issues?milestone=#{milestone.title}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(2)
expect(json_response.first['id']).to eq(issue.id)
@@ -578,7 +578,7 @@ describe API::V3::Issues, :mailer do
get v3_api("#{base_url}/issues?milestone=#{milestone.title}", user),
'&state=closed'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
expect(json_response.first['id']).to eq(closed_issue.id)
@@ -587,7 +587,7 @@ describe API::V3::Issues, :mailer do
it 'returns an array of issues with no milestone' do
get v3_api("#{base_url}/issues?milestone=#{no_milestone_title}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
expect(json_response.first['id']).to eq(confidential_issue.id)
@@ -598,7 +598,7 @@ describe API::V3::Issues, :mailer do
response_dates = json_response.map { |issue| issue['created_at'] }
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(response_dates).to eq(response_dates.sort.reverse)
end
@@ -608,7 +608,7 @@ describe API::V3::Issues, :mailer do
response_dates = json_response.map { |issue| issue['created_at'] }
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(response_dates).to eq(response_dates.sort)
end
@@ -618,7 +618,7 @@ describe API::V3::Issues, :mailer do
response_dates = json_response.map { |issue| issue['updated_at'] }
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(response_dates).to eq(response_dates.sort.reverse)
end
@@ -628,7 +628,7 @@ describe API::V3::Issues, :mailer do
response_dates = json_response.map { |issue| issue['updated_at'] }
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(response_dates).to eq(response_dates.sort)
end
@@ -638,7 +638,7 @@ describe API::V3::Issues, :mailer do
it 'exposes known attributes' do
get v3_api("/projects/#{project.id}/issues/#{issue.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['id']).to eq(issue.id)
expect(json_response['iid']).to eq(issue.iid)
expect(json_response['project_id']).to eq(issue.project.id)
@@ -657,7 +657,7 @@ describe API::V3::Issues, :mailer do
it "returns a project issue by id" do
get v3_api("/projects/#{project.id}/issues/#{issue.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['title']).to eq(issue.title)
expect(json_response['iid']).to eq(issue.iid)
end
@@ -682,26 +682,26 @@ describe API::V3::Issues, :mailer do
it "returns 404 if issue id not found" do
get v3_api("/projects/#{project.id}/issues/54321", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
context 'confidential issues' do
it "returns 404 for non project members" do
get v3_api("/projects/#{project.id}/issues/#{confidential_issue.id}", non_member)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it "returns 404 for project members with guest role" do
get v3_api("/projects/#{project.id}/issues/#{confidential_issue.id}", guest)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it "returns confidential issue for project members" do
get v3_api("/projects/#{project.id}/issues/#{confidential_issue.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['title']).to eq(confidential_issue.title)
expect(json_response['iid']).to eq(confidential_issue.iid)
end
@@ -709,7 +709,7 @@ describe API::V3::Issues, :mailer do
it "returns confidential issue for author" do
get v3_api("/projects/#{project.id}/issues/#{confidential_issue.id}", author)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['title']).to eq(confidential_issue.title)
expect(json_response['iid']).to eq(confidential_issue.iid)
end
@@ -717,7 +717,7 @@ describe API::V3::Issues, :mailer do
it "returns confidential issue for assignee" do
get v3_api("/projects/#{project.id}/issues/#{confidential_issue.id}", assignee)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['title']).to eq(confidential_issue.title)
expect(json_response['iid']).to eq(confidential_issue.iid)
end
@@ -725,7 +725,7 @@ describe API::V3::Issues, :mailer do
it "returns confidential issue for admin" do
get v3_api("/projects/#{project.id}/issues/#{confidential_issue.id}", admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['title']).to eq(confidential_issue.title)
expect(json_response['iid']).to eq(confidential_issue.iid)
end
@@ -737,7 +737,7 @@ describe API::V3::Issues, :mailer do
post v3_api("/projects/#{project.id}/issues", user),
title: 'new issue', labels: 'label, label2', assignee_id: assignee.id
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['title']).to eq('new issue')
expect(json_response['description']).to be_nil
expect(json_response['labels']).to eq(%w(label label2))
@@ -749,7 +749,7 @@ describe API::V3::Issues, :mailer do
post v3_api("/projects/#{project.id}/issues", user),
title: 'new issue', confidential: true
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['title']).to eq('new issue')
expect(json_response['confidential']).to be_truthy
end
@@ -758,7 +758,7 @@ describe API::V3::Issues, :mailer do
post v3_api("/projects/#{project.id}/issues", user),
title: 'new issue', confidential: 'y'
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['title']).to eq('new issue')
expect(json_response['confidential']).to be_truthy
end
@@ -767,7 +767,7 @@ describe API::V3::Issues, :mailer do
post v3_api("/projects/#{project.id}/issues", user),
title: 'new issue', confidential: false
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['title']).to eq('new issue')
expect(json_response['confidential']).to be_falsy
end
@@ -776,7 +776,7 @@ describe API::V3::Issues, :mailer do
post v3_api("/projects/#{project.id}/issues", user),
title: 'new issue', confidential: 'foo'
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['error']).to eq('confidential is invalid')
end
@@ -795,7 +795,7 @@ describe API::V3::Issues, :mailer do
it "returns a 400 bad request if title not given" do
post v3_api("/projects/#{project.id}/issues", user), labels: 'label, label2'
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it 'allows special label names' do
@@ -815,7 +815,7 @@ describe API::V3::Issues, :mailer do
post v3_api("/projects/#{project.id}/issues", user),
title: 'g' * 256
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['message']['title']).to eq([
'is too long (maximum is 255 characters)'
])
@@ -834,7 +834,7 @@ describe API::V3::Issues, :mailer do
end
it 'creates a new project issue' do
- expect(response).to have_http_status(:created)
+ expect(response).to have_gitlab_http_status(:created)
end
it 'resolves the discussions in a merge request' do
@@ -855,7 +855,7 @@ describe API::V3::Issues, :mailer do
post v3_api("/projects/#{project.id}/issues", user),
title: 'new issue', due_date: due_date
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['title']).to eq('new issue')
expect(json_response['description']).to be_nil
expect(json_response['due_date']).to eq(due_date)
@@ -868,7 +868,7 @@ describe API::V3::Issues, :mailer do
post v3_api("/projects/#{project.id}/issues", user),
title: 'new issue', labels: 'label, label2', created_at: creation_time
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(Time.parse(json_response['created_at'])).to be_like_time(creation_time)
end
end
@@ -899,7 +899,7 @@ describe API::V3::Issues, :mailer do
it "does not create a new project issue" do
expect { post v3_api("/projects/#{project.id}/issues", user), params }.not_to change(Issue, :count)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['message']).to eq({ "error" => "Spam detected" })
spam_logs = SpamLog.all
@@ -917,7 +917,7 @@ describe API::V3::Issues, :mailer do
put v3_api("/projects/#{project.id}/issues/#{issue.id}", user),
title: 'updated title'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['title']).to eq('updated title')
end
@@ -925,7 +925,7 @@ describe API::V3::Issues, :mailer do
put v3_api("/projects/#{project.id}/issues/44444", user),
title: 'updated title'
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'allows special label names' do
@@ -946,21 +946,21 @@ describe API::V3::Issues, :mailer do
put v3_api("/projects/#{project.id}/issues/#{confidential_issue.id}", non_member),
title: 'updated title'
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
it "returns 403 for project members with guest role" do
put v3_api("/projects/#{project.id}/issues/#{confidential_issue.id}", guest),
title: 'updated title'
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
it "updates a confidential issue for project members" do
put v3_api("/projects/#{project.id}/issues/#{confidential_issue.id}", user),
title: 'updated title'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['title']).to eq('updated title')
end
@@ -968,7 +968,7 @@ describe API::V3::Issues, :mailer do
put v3_api("/projects/#{project.id}/issues/#{confidential_issue.id}", author),
title: 'updated title'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['title']).to eq('updated title')
end
@@ -976,7 +976,7 @@ describe API::V3::Issues, :mailer do
put v3_api("/projects/#{project.id}/issues/#{confidential_issue.id}", admin),
title: 'updated title'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['title']).to eq('updated title')
end
@@ -984,7 +984,7 @@ describe API::V3::Issues, :mailer do
put v3_api("/projects/#{project.id}/issues/#{issue.id}", user),
confidential: true
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['confidential']).to be_truthy
end
@@ -992,7 +992,7 @@ describe API::V3::Issues, :mailer do
put v3_api("/projects/#{project.id}/issues/#{confidential_issue.id}", user),
confidential: false
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['confidential']).to be_falsy
end
@@ -1000,7 +1000,7 @@ describe API::V3::Issues, :mailer do
put v3_api("/projects/#{project.id}/issues/#{confidential_issue.id}", user),
confidential: 'foo'
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['error']).to eq('confidential is invalid')
end
end
@@ -1021,7 +1021,7 @@ describe API::V3::Issues, :mailer do
put v3_api("/projects/#{project.id}/issues/#{issue.id}", user), params
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['message']).to eq({ "error" => "Spam detected" })
spam_logs = SpamLog.all
@@ -1041,7 +1041,7 @@ describe API::V3::Issues, :mailer do
put v3_api("/projects/#{project.id}/issues/#{issue.id}", user),
title: 'updated title'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['labels']).to eq([label.title])
end
@@ -1060,7 +1060,7 @@ describe API::V3::Issues, :mailer do
it 'removes all labels' do
put v3_api("/projects/#{project.id}/issues/#{issue.id}", user), labels: ''
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['labels']).to eq([])
end
@@ -1068,7 +1068,7 @@ describe API::V3::Issues, :mailer do
put v3_api("/projects/#{project.id}/issues/#{issue.id}", user),
labels: 'foo,bar'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['labels']).to include 'foo'
expect(json_response['labels']).to include 'bar'
end
@@ -1092,7 +1092,7 @@ describe API::V3::Issues, :mailer do
put v3_api("/projects/#{project.id}/issues/#{issue.id}", user),
title: 'g' * 256
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['message']['title']).to eq([
'is too long (maximum is 255 characters)'
])
@@ -1104,7 +1104,7 @@ describe API::V3::Issues, :mailer do
put v3_api("/projects/#{project.id}/issues/#{issue.id}", user),
labels: 'label2', state_event: "close"
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['labels']).to include 'label2'
expect(json_response['state']).to eq "closed"
end
@@ -1112,7 +1112,7 @@ describe API::V3::Issues, :mailer do
it 'reopens a project isssue' do
put v3_api("/projects/#{project.id}/issues/#{closed_issue.id}", user), state_event: 'reopen'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['state']).to eq 'opened'
end
@@ -1122,7 +1122,7 @@ describe API::V3::Issues, :mailer do
put v3_api("/projects/#{project.id}/issues/#{issue.id}", user),
labels: 'label3', state_event: 'close', updated_at: update_time
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['labels']).to include 'label3'
expect(Time.parse(json_response['updated_at'])).to be_like_time(update_time)
end
@@ -1135,7 +1135,7 @@ describe API::V3::Issues, :mailer do
put v3_api("/projects/#{project.id}/issues/#{issue.id}", user), due_date: due_date
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['due_date']).to eq(due_date)
end
end
@@ -1144,14 +1144,14 @@ describe API::V3::Issues, :mailer do
it 'updates an issue with no assignee' do
put v3_api("/projects/#{project.id}/issues/#{issue.id}", user), assignee_id: 0
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['assignee']).to eq(nil)
end
it 'updates an issue with assignee' do
put v3_api("/projects/#{project.id}/issues/#{issue.id}", user), assignee_id: user2.id
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['assignee']['name']).to eq(user2.name)
end
end
@@ -1160,13 +1160,13 @@ describe API::V3::Issues, :mailer do
it "rejects a non member from deleting an issue" do
delete v3_api("/projects/#{project.id}/issues/#{issue.id}", non_member)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
it "rejects a developer from deleting an issue" do
delete v3_api("/projects/#{project.id}/issues/#{issue.id}", author)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
context "when the user is project owner" do
@@ -1176,7 +1176,7 @@ describe API::V3::Issues, :mailer do
it "deletes the issue if an admin requests it" do
delete v3_api("/projects/#{project.id}/issues/#{issue.id}", owner)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['state']).to eq 'opened'
end
end
@@ -1185,7 +1185,7 @@ describe API::V3::Issues, :mailer do
it 'returns 404 when trying to move an issue' do
delete v3_api("/projects/#{project.id}/issues/123", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -1198,7 +1198,7 @@ describe API::V3::Issues, :mailer do
post v3_api("/projects/#{project.id}/issues/#{issue.id}/move", user),
to_project_id: target_project.id
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['project_id']).to eq(target_project.id)
end
@@ -1207,7 +1207,7 @@ describe API::V3::Issues, :mailer do
post v3_api("/projects/#{project.id}/issues/#{issue.id}/move", user),
to_project_id: project.id
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['message']).to eq('Cannot move issue to project it originates from!')
end
end
@@ -1217,7 +1217,7 @@ describe API::V3::Issues, :mailer do
post v3_api("/projects/#{project.id}/issues/#{issue.id}/move", user),
to_project_id: target_project2.id
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['message']).to eq('Cannot move issue due to insufficient permissions!')
end
end
@@ -1226,7 +1226,7 @@ describe API::V3::Issues, :mailer do
post v3_api("/projects/#{project.id}/issues/#{issue.id}/move", admin),
to_project_id: target_project2.id
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['project_id']).to eq(target_project2.id)
end
@@ -1235,7 +1235,7 @@ describe API::V3::Issues, :mailer do
post v3_api("/projects/#{project.id}/issues/123/move", user),
to_project_id: target_project.id
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 Issue Not Found')
end
end
@@ -1245,7 +1245,7 @@ describe API::V3::Issues, :mailer do
post v3_api("/projects/123/issues/#{issue.id}/move", user),
to_project_id: target_project.id
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 Project Not Found')
end
end
@@ -1255,7 +1255,7 @@ describe API::V3::Issues, :mailer do
post v3_api("/projects/#{project.id}/issues/#{issue.id}/move", user),
to_project_id: 123
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -1264,26 +1264,26 @@ describe API::V3::Issues, :mailer do
it 'subscribes to an issue' do
post v3_api("/projects/#{project.id}/issues/#{issue.id}/subscription", user2)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['subscribed']).to eq(true)
end
it 'returns 304 if already subscribed' do
post v3_api("/projects/#{project.id}/issues/#{issue.id}/subscription", user)
- expect(response).to have_http_status(304)
+ expect(response).to have_gitlab_http_status(304)
end
it 'returns 404 if the issue is not found' do
post v3_api("/projects/#{project.id}/issues/123/subscription", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'returns 404 if the issue is confidential' do
post v3_api("/projects/#{project.id}/issues/#{confidential_issue.id}/subscription", non_member)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -1291,26 +1291,26 @@ describe API::V3::Issues, :mailer do
it 'unsubscribes from an issue' do
delete v3_api("/projects/#{project.id}/issues/#{issue.id}/subscription", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['subscribed']).to eq(false)
end
it 'returns 304 if not subscribed' do
delete v3_api("/projects/#{project.id}/issues/#{issue.id}/subscription", user2)
- expect(response).to have_http_status(304)
+ expect(response).to have_gitlab_http_status(304)
end
it 'returns 404 if the issue is not found' do
delete v3_api("/projects/#{project.id}/issues/123/subscription", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'returns 404 if the issue is confidential' do
delete v3_api("/projects/#{project.id}/issues/#{confidential_issue.id}/subscription", non_member)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
diff --git a/spec/requests/api/v3/labels_spec.rb b/spec/requests/api/v3/labels_spec.rb
index 32f37a08024..1d31213d5ca 100644
--- a/spec/requests/api/v3/labels_spec.rb
+++ b/spec/requests/api/v3/labels_spec.rb
@@ -27,7 +27,7 @@ describe API::V3::Labels do
get v3_api("/projects/#{project.id}/labels", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.size).to eq(3)
expect(json_response.first.keys).to match_array expected_keys
@@ -71,7 +71,7 @@ describe API::V3::Labels do
it "subscribes to the label" do
post v3_api("/projects/#{project.id}/labels/#{label1.title}/subscription", user)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response["name"]).to eq(label1.title)
expect(json_response["subscribed"]).to be_truthy
end
@@ -81,7 +81,7 @@ describe API::V3::Labels do
it "subscribes to the label" do
post v3_api("/projects/#{project.id}/labels/#{label1.id}/subscription", user)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response["name"]).to eq(label1.title)
expect(json_response["subscribed"]).to be_truthy
end
@@ -93,7 +93,7 @@ describe API::V3::Labels do
it "returns 304" do
post v3_api("/projects/#{project.id}/labels/#{label1.id}/subscription", user)
- expect(response).to have_http_status(304)
+ expect(response).to have_gitlab_http_status(304)
end
end
@@ -101,7 +101,7 @@ describe API::V3::Labels do
it "returns 404 error" do
post v3_api("/projects/#{project.id}/labels/1234/subscription", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -113,7 +113,7 @@ describe API::V3::Labels do
it "unsubscribes from the label" do
delete v3_api("/projects/#{project.id}/labels/#{label1.title}/subscription", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response["name"]).to eq(label1.title)
expect(json_response["subscribed"]).to be_falsey
end
@@ -123,7 +123,7 @@ describe API::V3::Labels do
it "unsubscribes from the label" do
delete v3_api("/projects/#{project.id}/labels/#{label1.id}/subscription", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response["name"]).to eq(label1.title)
expect(json_response["subscribed"]).to be_falsey
end
@@ -135,7 +135,7 @@ describe API::V3::Labels do
it "returns 304" do
delete v3_api("/projects/#{project.id}/labels/#{label1.id}/subscription", user)
- expect(response).to have_http_status(304)
+ expect(response).to have_gitlab_http_status(304)
end
end
@@ -143,7 +143,7 @@ describe API::V3::Labels do
it "returns 404 error" do
delete v3_api("/projects/#{project.id}/labels/1234/subscription", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -152,18 +152,18 @@ describe API::V3::Labels do
it 'returns 200 for existing label' do
delete v3_api("/projects/#{project.id}/labels", user), name: 'label1'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it 'returns 404 for non existing label' do
delete v3_api("/projects/#{project.id}/labels", user), name: 'label2'
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 Label Not Found')
end
it 'returns 400 for wrong parameters' do
delete v3_api("/projects/#{project.id}/labels", user)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
end
end
diff --git a/spec/requests/api/v3/members_spec.rb b/spec/requests/api/v3/members_spec.rb
index bc918a8eb02..68be3d24c26 100644
--- a/spec/requests/api/v3/members_spec.rb
+++ b/spec/requests/api/v3/members_spec.rb
@@ -34,7 +34,7 @@ describe API::V3::Members do
user = public_send(type)
get v3_api("/#{source_type.pluralize}/#{source.id}/members", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response.size).to eq(2)
expect(json_response.map { |u| u['id'] }).to match_array [master.id, developer.id]
end
@@ -46,7 +46,7 @@ describe API::V3::Members do
get v3_api("/#{source_type.pluralize}/#{source.id}/members", developer)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response.size).to eq(2)
expect(json_response.map { |u| u['id'] }).to match_array [master.id, developer.id]
end
@@ -54,7 +54,7 @@ describe API::V3::Members do
it 'finds members with query string' do
get v3_api("/#{source_type.pluralize}/#{source.id}/members", developer), query: master.username
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response.count).to eq(1)
expect(json_response.first['username']).to eq(master.username)
end
@@ -74,7 +74,7 @@ describe API::V3::Members do
user = public_send(type)
get v3_api("/#{source_type.pluralize}/#{source.id}/members/#{developer.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
# User attributes
expect(json_response['id']).to eq(developer.id)
expect(json_response['name']).to eq(developer.name)
@@ -109,7 +109,7 @@ describe API::V3::Members do
post v3_api("/#{source_type.pluralize}/#{source.id}/members", user),
user_id: access_requester.id, access_level: Member::MASTER
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
end
@@ -122,7 +122,7 @@ describe API::V3::Members do
post v3_api("/#{source_type.pluralize}/#{source.id}/members", master),
user_id: access_requester.id, access_level: Member::MASTER
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
end.to change { source.members.count }.by(1)
expect(source.requesters.count).to eq(0)
expect(json_response['id']).to eq(access_requester.id)
@@ -135,7 +135,7 @@ describe API::V3::Members do
post v3_api("/#{source_type.pluralize}/#{source.id}/members", master),
user_id: stranger.id, access_level: Member::DEVELOPER, expires_at: '2016-08-05'
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
end.to change { source.members.count }.by(1)
expect(json_response['id']).to eq(stranger.id)
expect(json_response['access_level']).to eq(Member::DEVELOPER)
@@ -147,28 +147,28 @@ describe API::V3::Members do
post v3_api("/#{source_type.pluralize}/#{source.id}/members", master),
user_id: master.id, access_level: Member::MASTER
- expect(response).to have_http_status(source_type == 'project' ? 201 : 409)
+ expect(response).to have_gitlab_http_status(source_type == 'project' ? 201 : 409)
end
it 'returns 400 when user_id is not given' do
post v3_api("/#{source_type.pluralize}/#{source.id}/members", master),
access_level: Member::MASTER
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it 'returns 400 when access_level is not given' do
post v3_api("/#{source_type.pluralize}/#{source.id}/members", master),
user_id: stranger.id
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it 'returns 422 when access_level is not valid' do
post v3_api("/#{source_type.pluralize}/#{source.id}/members", master),
user_id: stranger.id, access_level: 1234
- expect(response).to have_http_status(422)
+ expect(response).to have_gitlab_http_status(422)
end
end
end
@@ -190,7 +190,7 @@ describe API::V3::Members do
put v3_api("/#{source_type.pluralize}/#{source.id}/members/#{developer.id}", user),
access_level: Member::MASTER
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
end
@@ -201,7 +201,7 @@ describe API::V3::Members do
put v3_api("/#{source_type.pluralize}/#{source.id}/members/#{developer.id}", master),
access_level: Member::MASTER, expires_at: '2016-08-05'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['id']).to eq(developer.id)
expect(json_response['access_level']).to eq(Member::MASTER)
expect(json_response['expires_at']).to eq('2016-08-05')
@@ -212,20 +212,20 @@ describe API::V3::Members do
put v3_api("/#{source_type.pluralize}/#{source.id}/members/123", master),
access_level: Member::MASTER
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'returns 400 when access_level is not given' do
put v3_api("/#{source_type.pluralize}/#{source.id}/members/#{developer.id}", master)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it 'returns 422 when access level is not valid' do
put v3_api("/#{source_type.pluralize}/#{source.id}/members/#{developer.id}", master),
access_level: 1234
- expect(response).to have_http_status(422)
+ expect(response).to have_gitlab_http_status(422)
end
end
end
@@ -243,7 +243,7 @@ describe API::V3::Members do
user = public_send(type)
delete v3_api("/#{source_type.pluralize}/#{source.id}/members/#{developer.id}", user)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
end
@@ -254,7 +254,7 @@ describe API::V3::Members do
expect do
delete v3_api("/#{source_type.pluralize}/#{source.id}/members/#{developer.id}", developer)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end.to change { source.members.count }.by(-1)
end
end
@@ -265,7 +265,7 @@ describe API::V3::Members do
expect do
delete v3_api("/#{source_type.pluralize}/#{source.id}/members/#{access_requester.id}", master)
- expect(response).to have_http_status(source_type == 'project' ? 200 : 404)
+ expect(response).to have_gitlab_http_status(source_type == 'project' ? 200 : 404)
end.not_to change { source.requesters.count }
end
end
@@ -274,7 +274,7 @@ describe API::V3::Members do
expect do
delete v3_api("/#{source_type.pluralize}/#{source.id}/members/#{developer.id}", master)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end.to change { source.members.count }.by(-1)
end
end
@@ -282,7 +282,7 @@ describe API::V3::Members do
it "returns #{source_type == 'project' ? 200 : 404} if member does not exist" do
delete v3_api("/#{source_type.pluralize}/#{source.id}/members/123", master)
- expect(response).to have_http_status(source_type == 'project' ? 200 : 404)
+ expect(response).to have_gitlab_http_status(source_type == 'project' ? 200 : 404)
end
end
end
@@ -333,7 +333,7 @@ describe API::V3::Members do
post v3_api("/projects/#{project.id}/members", master),
user_id: stranger.id, access_level: Member::OWNER
- expect(response).to have_http_status(422)
+ expect(response).to have_gitlab_http_status(422)
end.to change { project.members.count }.by(0)
end
end
diff --git a/spec/requests/api/v3/merge_request_diffs_spec.rb b/spec/requests/api/v3/merge_request_diffs_spec.rb
index 3f21ff40726..e613036a88d 100644
--- a/spec/requests/api/v3/merge_request_diffs_spec.rb
+++ b/spec/requests/api/v3/merge_request_diffs_spec.rb
@@ -24,7 +24,7 @@ describe API::V3::MergeRequestDiffs, 'MergeRequestDiffs' do
it 'returns a 404 when merge_request_id not found' do
get v3_api("/projects/#{project.id}/merge_requests/999/versions", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -42,7 +42,7 @@ describe API::V3::MergeRequestDiffs, 'MergeRequestDiffs' do
it 'returns a 404 when merge_request_id not found' do
get v3_api("/projects/#{project.id}/merge_requests/#{merge_request.id}/versions/999", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
diff --git a/spec/requests/api/v3/merge_requests_spec.rb b/spec/requests/api/v3/merge_requests_spec.rb
index df73c731c96..26251b95680 100644
--- a/spec/requests/api/v3/merge_requests_spec.rb
+++ b/spec/requests/api/v3/merge_requests_spec.rb
@@ -21,14 +21,14 @@ describe API::MergeRequests do
context "when unauthenticated" do
it "returns authentication error" do
get v3_api("/projects/#{project.id}/merge_requests")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
context "when authenticated" do
it "returns an array of all merge_requests" do
get v3_api("/projects/#{project.id}/merge_requests", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(3)
expect(json_response.last['title']).to eq(merge_request.title)
@@ -44,7 +44,7 @@ describe API::MergeRequests do
it "returns an array of all merge_requests" do
get v3_api("/projects/#{project.id}/merge_requests?state", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(3)
expect(json_response.last['title']).to eq(merge_request.title)
@@ -52,7 +52,7 @@ describe API::MergeRequests do
it "returns an array of open merge_requests" do
get v3_api("/projects/#{project.id}/merge_requests?state=opened", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
expect(json_response.last['title']).to eq(merge_request.title)
@@ -60,7 +60,7 @@ describe API::MergeRequests do
it "returns an array of closed merge_requests" do
get v3_api("/projects/#{project.id}/merge_requests?state=closed", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
expect(json_response.first['title']).to eq(merge_request_closed.title)
@@ -68,7 +68,7 @@ describe API::MergeRequests do
it "returns an array of merged merge_requests" do
get v3_api("/projects/#{project.id}/merge_requests?state=merged", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
expect(json_response.first['title']).to eq(merge_request_merged.title)
@@ -77,7 +77,7 @@ describe API::MergeRequests do
it 'matches V3 response schema' do
get v3_api("/projects/#{project.id}/merge_requests", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to match_response_schema('public_api/v3/merge_requests')
end
@@ -89,7 +89,7 @@ describe API::MergeRequests do
it "returns an array of merge_requests in ascending order" do
get v3_api("/projects/#{project.id}/merge_requests?sort=asc", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(3)
response_dates = json_response.map { |merge_request| merge_request['created_at'] }
@@ -98,7 +98,7 @@ describe API::MergeRequests do
it "returns an array of merge_requests in descending order" do
get v3_api("/projects/#{project.id}/merge_requests?sort=desc", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(3)
response_dates = json_response.map { |merge_request| merge_request['created_at'] }
@@ -107,7 +107,7 @@ describe API::MergeRequests do
it "returns an array of merge_requests ordered by updated_at" do
get v3_api("/projects/#{project.id}/merge_requests?order_by=updated_at", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(3)
response_dates = json_response.map { |merge_request| merge_request['updated_at'] }
@@ -116,7 +116,7 @@ describe API::MergeRequests do
it "returns an array of merge_requests ordered by created_at" do
get v3_api("/projects/#{project.id}/merge_requests?order_by=created_at&sort=asc", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(3)
response_dates = json_response.map { |merge_request| merge_request['created_at'] }
@@ -130,7 +130,7 @@ describe API::MergeRequests do
it 'exposes known attributes' do
get v3_api("/projects/#{project.id}/merge_requests/#{merge_request.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['id']).to eq(merge_request.id)
expect(json_response['iid']).to eq(merge_request.iid)
expect(json_response['project_id']).to eq(merge_request.project.id)
@@ -158,7 +158,7 @@ describe API::MergeRequests do
it "returns merge_request" do
get v3_api("/projects/#{project.id}/merge_requests/#{merge_request.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['title']).to eq(merge_request.title)
expect(json_response['iid']).to eq(merge_request.iid)
expect(json_response['work_in_progress']).to eq(false)
@@ -178,7 +178,7 @@ describe API::MergeRequests do
it 'returns merge_request by iid array' do
get v3_api("/projects/#{project.id}/merge_requests", user), iid: [merge_request.iid, merge_request_closed.iid]
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(2)
expect(json_response.first['title']).to eq merge_request_closed.title
@@ -187,7 +187,7 @@ describe API::MergeRequests do
it "returns a 404 error if merge_request_id not found" do
get v3_api("/projects/#{project.id}/merge_requests/999", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
context 'Work in Progress' do
@@ -195,7 +195,7 @@ describe API::MergeRequests do
it "returns merge_request" do
get v3_api("/projects/#{project.id}/merge_requests/#{merge_request_wip.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['work_in_progress']).to eq(true)
end
end
@@ -214,7 +214,7 @@ describe API::MergeRequests do
it 'returns a 404 when merge_request_id not found' do
get v3_api("/projects/#{project.id}/merge_requests/999/commits", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -227,7 +227,7 @@ describe API::MergeRequests do
it 'returns a 404 when merge_request_id not found' do
get v3_api("/projects/#{project.id}/merge_requests/999/changes", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -243,7 +243,7 @@ describe API::MergeRequests do
milestone_id: milestone.id,
remove_source_branch: true
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['title']).to eq('Test merge_request')
expect(json_response['labels']).to eq(%w(label label2))
expect(json_response['milestone']['id']).to eq(milestone.id)
@@ -253,25 +253,25 @@ describe API::MergeRequests do
it "returns 422 when source_branch equals target_branch" do
post v3_api("/projects/#{project.id}/merge_requests", user),
title: "Test merge_request", source_branch: "master", target_branch: "master", author: user
- expect(response).to have_http_status(422)
+ expect(response).to have_gitlab_http_status(422)
end
it "returns 400 when source_branch is missing" do
post v3_api("/projects/#{project.id}/merge_requests", user),
title: "Test merge_request", target_branch: "master", author: user
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it "returns 400 when target_branch is missing" do
post v3_api("/projects/#{project.id}/merge_requests", user),
title: "Test merge_request", source_branch: "markdown", author: user
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it "returns 400 when title is missing" do
post v3_api("/projects/#{project.id}/merge_requests", user),
target_branch: 'master', source_branch: 'markdown'
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it 'allows special label names' do
@@ -307,7 +307,7 @@ describe API::MergeRequests do
target_branch: 'master',
author: user
end.to change { MergeRequest.count }.by(0)
- expect(response).to have_http_status(409)
+ expect(response).to have_gitlab_http_status(409)
end
end
end
@@ -403,7 +403,7 @@ describe API::MergeRequests do
it "denies the deletion of the merge request" do
delete v3_api("/projects/#{project.id}/merge_requests/#{merge_request.id}", developer)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -411,7 +411,7 @@ describe API::MergeRequests do
it "destroys the merge request owners can destroy" do
delete v3_api("/projects/#{project.id}/merge_requests/#{merge_request.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
end
end
@@ -422,7 +422,7 @@ describe API::MergeRequests do
it "returns merge_request in case of success" do
put v3_api("/projects/#{project.id}/merge_requests/#{merge_request.id}/merge", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it "returns 406 if branch can't be merged" do
@@ -431,21 +431,21 @@ describe API::MergeRequests do
put v3_api("/projects/#{project.id}/merge_requests/#{merge_request.id}/merge", user)
- expect(response).to have_http_status(406)
+ expect(response).to have_gitlab_http_status(406)
expect(json_response['message']).to eq('Branch cannot be merged')
end
it "returns 405 if merge_request is not open" do
merge_request.close
put v3_api("/projects/#{project.id}/merge_requests/#{merge_request.id}/merge", user)
- expect(response).to have_http_status(405)
+ expect(response).to have_gitlab_http_status(405)
expect(json_response['message']).to eq('405 Method Not Allowed')
end
it "returns 405 if merge_request is a work in progress" do
merge_request.update_attribute(:title, "WIP: #{merge_request.title}")
put v3_api("/projects/#{project.id}/merge_requests/#{merge_request.id}/merge", user)
- expect(response).to have_http_status(405)
+ expect(response).to have_gitlab_http_status(405)
expect(json_response['message']).to eq('405 Method Not Allowed')
end
@@ -454,7 +454,7 @@ describe API::MergeRequests do
put v3_api("/projects/#{project.id}/merge_requests/#{merge_request.id}/merge", user)
- expect(response).to have_http_status(405)
+ expect(response).to have_gitlab_http_status(405)
expect(json_response['message']).to eq('405 Method Not Allowed')
end
@@ -462,21 +462,21 @@ describe API::MergeRequests do
user2 = create(:user)
project.team << [user2, :reporter]
put v3_api("/projects/#{project.id}/merge_requests/#{merge_request.id}/merge", user2)
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
expect(json_response['message']).to eq('401 Unauthorized')
end
it "returns 409 if the SHA parameter doesn't match" do
put v3_api("/projects/#{project.id}/merge_requests/#{merge_request.id}/merge", user), sha: merge_request.diff_head_sha.reverse
- expect(response).to have_http_status(409)
+ expect(response).to have_gitlab_http_status(409)
expect(json_response['message']).to start_with('SHA does not match HEAD of source branch')
end
it "succeeds if the SHA parameter matches" do
put v3_api("/projects/#{project.id}/merge_requests/#{merge_request.id}/merge", user), sha: merge_request.diff_head_sha
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it "enables merge when pipeline succeeds if the pipeline is active" do
@@ -485,7 +485,7 @@ describe API::MergeRequests do
put v3_api("/projects/#{project.id}/merge_requests/#{merge_request.id}/merge", user), merge_when_build_succeeds: true
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['title']).to eq('Test')
expect(json_response['merge_when_build_succeeds']).to eq(true)
end
@@ -496,39 +496,39 @@ describe API::MergeRequests do
it "returns merge_request" do
put v3_api("/projects/#{project.id}/merge_requests/#{merge_request.id}", user), state_event: "close"
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['state']).to eq('closed')
end
end
it "updates title and returns merge_request" do
put v3_api("/projects/#{project.id}/merge_requests/#{merge_request.id}", user), title: "New title"
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['title']).to eq('New title')
end
it "updates description and returns merge_request" do
put v3_api("/projects/#{project.id}/merge_requests/#{merge_request.id}", user), description: "New description"
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['description']).to eq('New description')
end
it "updates milestone_id and returns merge_request" do
put v3_api("/projects/#{project.id}/merge_requests/#{merge_request.id}", user), milestone_id: milestone.id
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['milestone']['id']).to eq(milestone.id)
end
it "returns merge_request with renamed target_branch" do
put v3_api("/projects/#{project.id}/merge_requests/#{merge_request.id}", user), target_branch: "wiki"
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['target_branch']).to eq('wiki')
end
it "returns merge_request that removes the source branch" do
put v3_api("/projects/#{project.id}/merge_requests/#{merge_request.id}", user), remove_source_branch: true
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['force_remove_source_branch']).to be_truthy
end
@@ -549,7 +549,7 @@ describe API::MergeRequests do
put v3_api("/projects/#{project.id}/merge_requests/#{merge_request.id}", user), state_event: 'close', title: nil
merge_request.reload
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(merge_request.state).to eq('opened')
end
@@ -557,7 +557,7 @@ describe API::MergeRequests do
put v3_api("/projects/#{project.id}/merge_requests/#{merge_request.id}", user), state_event: 'close', target_branch: nil
merge_request.reload
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(merge_request.state).to eq('opened')
end
end
@@ -568,7 +568,7 @@ describe API::MergeRequests do
post v3_api("/projects/#{project.id}/merge_requests/#{merge_request.id}/comments", user), note: "My comment"
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['note']).to eq('My comment')
expect(json_response['author']['name']).to eq(user.name)
expect(json_response['author']['username']).to eq(user.username)
@@ -577,13 +577,13 @@ describe API::MergeRequests do
it "returns 400 if note is missing" do
post v3_api("/projects/#{project.id}/merge_requests/#{merge_request.id}/comments", user)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it "returns 404 if note is attached to non existent merge request" do
post v3_api("/projects/#{project.id}/merge_requests/404/comments", user),
note: 'My comment'
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -593,7 +593,7 @@ describe API::MergeRequests do
it "returns merge_request comments ordered by created_at" do
get v3_api("/projects/#{project.id}/merge_requests/#{merge_request.id}/comments", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(2)
expect(json_response.first['note']).to eq("a comment on a MR")
@@ -603,7 +603,7 @@ describe API::MergeRequests do
it "returns a 404 error if merge_request_id not found" do
get v3_api("/projects/#{project.id}/merge_requests/999/comments", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -615,7 +615,7 @@ describe API::MergeRequests do
end
get v3_api("/projects/#{project.id}/merge_requests/#{mr.id}/closes_issues", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
expect(json_response.first['id']).to eq(issue.id)
@@ -623,7 +623,7 @@ describe API::MergeRequests do
it 'returns an empty array when there are no issues to be closed' do
get v3_api("/projects/#{project.id}/merge_requests/#{merge_request.id}/closes_issues", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(0)
end
@@ -636,7 +636,7 @@ describe API::MergeRequests do
get v3_api("/projects/#{jira_project.id}/merge_requests/#{merge_request.id}/closes_issues", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
expect(json_response.first['title']).to eq(issue.title)
@@ -651,7 +651,7 @@ describe API::MergeRequests do
get v3_api("/projects/#{project.id}/merge_requests/#{merge_request.id}/closes_issues", guest)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -659,20 +659,20 @@ describe API::MergeRequests do
it 'subscribes to a merge request' do
post v3_api("/projects/#{project.id}/merge_requests/#{merge_request.id}/subscription", admin)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['subscribed']).to eq(true)
end
it 'returns 304 if already subscribed' do
post v3_api("/projects/#{project.id}/merge_requests/#{merge_request.id}/subscription", user)
- expect(response).to have_http_status(304)
+ expect(response).to have_gitlab_http_status(304)
end
it 'returns 404 if the merge request is not found' do
post v3_api("/projects/#{project.id}/merge_requests/123/subscription", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'returns 403 if user has no access to read code' do
@@ -681,7 +681,7 @@ describe API::MergeRequests do
post v3_api("/projects/#{project.id}/merge_requests/#{merge_request.id}/subscription", guest)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -689,20 +689,20 @@ describe API::MergeRequests do
it 'unsubscribes from a merge request' do
delete v3_api("/projects/#{project.id}/merge_requests/#{merge_request.id}/subscription", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['subscribed']).to eq(false)
end
it 'returns 304 if not subscribed' do
delete v3_api("/projects/#{project.id}/merge_requests/#{merge_request.id}/subscription", admin)
- expect(response).to have_http_status(304)
+ expect(response).to have_gitlab_http_status(304)
end
it 'returns 404 if the merge request is not found' do
post v3_api("/projects/#{project.id}/merge_requests/123/subscription", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'returns 403 if user has no access to read code' do
@@ -711,7 +711,7 @@ describe API::MergeRequests do
delete v3_api("/projects/#{project.id}/merge_requests/#{merge_request.id}/subscription", guest)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
diff --git a/spec/requests/api/v3/milestones_spec.rb b/spec/requests/api/v3/milestones_spec.rb
index feaa87faec7..e82f35598a6 100644
--- a/spec/requests/api/v3/milestones_spec.rb
+++ b/spec/requests/api/v3/milestones_spec.rb
@@ -12,7 +12,7 @@ describe API::V3::Milestones do
it 'returns project milestones' do
get v3_api("/projects/#{project.id}/milestones", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.first['title']).to eq(milestone.title)
end
@@ -20,13 +20,13 @@ describe API::V3::Milestones do
it 'returns a 401 error if user not authenticated' do
get v3_api("/projects/#{project.id}/milestones")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
it 'returns an array of active milestones' do
get v3_api("/projects/#{project.id}/milestones?state=active", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
expect(json_response.first['id']).to eq(milestone.id)
@@ -35,7 +35,7 @@ describe API::V3::Milestones do
it 'returns an array of closed milestones' do
get v3_api("/projects/#{project.id}/milestones?state=closed", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
expect(json_response.first['id']).to eq(closed_milestone.id)
@@ -46,7 +46,7 @@ describe API::V3::Milestones do
it 'returns a project milestone by id' do
get v3_api("/projects/#{project.id}/milestones/#{milestone.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['title']).to eq(milestone.title)
expect(json_response['iid']).to eq(milestone.iid)
end
@@ -63,7 +63,7 @@ describe API::V3::Milestones do
it 'returns a project milestone by iid array' do
get v3_api("/projects/#{project.id}/milestones", user), iid: [milestone.iid, closed_milestone.iid]
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response.size).to eq(2)
expect(json_response.first['title']).to eq milestone.title
expect(json_response.first['id']).to eq milestone.id
@@ -72,13 +72,13 @@ describe API::V3::Milestones do
it 'returns 401 error if user not authenticated' do
get v3_api("/projects/#{project.id}/milestones/#{milestone.id}")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
it 'returns a 404 error if milestone id not found' do
get v3_api("/projects/#{project.id}/milestones/1234", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -86,7 +86,7 @@ describe API::V3::Milestones do
it 'creates a new project milestone' do
post v3_api("/projects/#{project.id}/milestones", user), title: 'new milestone'
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['title']).to eq('new milestone')
expect(json_response['description']).to be_nil
end
@@ -95,7 +95,7 @@ describe API::V3::Milestones do
post v3_api("/projects/#{project.id}/milestones", user),
title: 'new milestone', description: 'release', due_date: '2013-03-02', start_date: '2013-02-02'
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['description']).to eq('release')
expect(json_response['due_date']).to eq('2013-03-02')
expect(json_response['start_date']).to eq('2013-02-02')
@@ -104,20 +104,20 @@ describe API::V3::Milestones do
it 'returns a 400 error if title is missing' do
post v3_api("/projects/#{project.id}/milestones", user)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it 'returns a 400 error if params are invalid (duplicate title)' do
post v3_api("/projects/#{project.id}/milestones", user),
title: milestone.title, description: 'release', due_date: '2013-03-02'
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it 'creates a new project with reserved html characters' do
post v3_api("/projects/#{project.id}/milestones", user), title: 'foo & bar 1.1 -> 2.2'
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['title']).to eq('foo & bar 1.1 -> 2.2')
expect(json_response['description']).to be_nil
end
@@ -128,7 +128,7 @@ describe API::V3::Milestones do
put v3_api("/projects/#{project.id}/milestones/#{milestone.id}", user),
title: 'updated title'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['title']).to eq('updated title')
end
@@ -137,7 +137,7 @@ describe API::V3::Milestones do
put v3_api("/projects/#{project.id}/milestones/#{milestone.id}", user), due_date: nil
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['due_date']).to be_nil
end
@@ -145,7 +145,7 @@ describe API::V3::Milestones do
put v3_api("/projects/#{project.id}/milestones/1234", user),
title: 'updated title'
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -153,7 +153,7 @@ describe API::V3::Milestones do
it 'updates a project milestone' do
put v3_api("/projects/#{project.id}/milestones/#{milestone.id}", user),
state_event: 'close'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['state']).to eq('closed')
end
@@ -175,7 +175,7 @@ describe API::V3::Milestones do
it 'returns project issues for a particular milestone' do
get v3_api("/projects/#{project.id}/milestones/#{milestone.id}/issues", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.first['milestone']['title']).to eq(milestone.title)
end
@@ -183,14 +183,14 @@ describe API::V3::Milestones do
it 'matches V3 response schema for a list of issues' do
get v3_api("/projects/#{project.id}/milestones/#{milestone.id}/issues", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to match_response_schema('public_api/v3/issues')
end
it 'returns a 401 error if user not authenticated' do
get v3_api("/projects/#{project.id}/milestones/#{milestone.id}/issues")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
describe 'confidential issues' do
@@ -207,7 +207,7 @@ describe API::V3::Milestones do
it 'returns confidential issues to team members' do
get v3_api("/projects/#{public_project.id}/milestones/#{milestone.id}/issues", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.size).to eq(2)
expect(json_response.map { |issue| issue['id'] }).to include(issue.id, confidential_issue.id)
@@ -219,7 +219,7 @@ describe API::V3::Milestones do
get v3_api("/projects/#{public_project.id}/milestones/#{milestone.id}/issues", member)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.size).to eq(1)
expect(json_response.map { |issue| issue['id'] }).to include(issue.id)
@@ -228,7 +228,7 @@ describe API::V3::Milestones do
it 'does not return confidential issues to regular users' do
get v3_api("/projects/#{public_project.id}/milestones/#{milestone.id}/issues", create(:user))
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.size).to eq(1)
expect(json_response.map { |issue| issue['id'] }).to include(issue.id)
diff --git a/spec/requests/api/v3/notes_spec.rb b/spec/requests/api/v3/notes_spec.rb
index 56729692eed..d3455a4bba4 100644
--- a/spec/requests/api/v3/notes_spec.rb
+++ b/spec/requests/api/v3/notes_spec.rb
@@ -35,7 +35,7 @@ describe API::V3::Notes do
it "returns an array of issue notes" do
get v3_api("/projects/#{project.id}/issues/#{issue.id}/notes", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.first['body']).to eq(issue_note.note)
@@ -46,14 +46,14 @@ describe API::V3::Notes do
it "returns a 404 error when issue id not found" do
get v3_api("/projects/#{project.id}/issues/12345/notes", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
context "and current user cannot view the notes" do
it "returns an empty array" do
get v3_api("/projects/#{ext_proj.id}/issues/#{ext_issue.id}/notes", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response).to be_empty
@@ -65,7 +65,7 @@ describe API::V3::Notes do
it "returns 404" do
get v3_api("/projects/#{ext_proj.id}/issues/#{ext_issue.id}/notes", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -73,7 +73,7 @@ describe API::V3::Notes do
it "returns an empty array" do
get v3_api("/projects/#{ext_proj.id}/issues/#{ext_issue.id}/notes", private_user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.first['body']).to eq(cross_reference_note.note)
@@ -86,7 +86,7 @@ describe API::V3::Notes do
it "returns an array of snippet notes" do
get v3_api("/projects/#{project.id}/snippets/#{snippet.id}/notes", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.first['body']).to eq(snippet_note.note)
@@ -95,13 +95,13 @@ describe API::V3::Notes do
it "returns a 404 error when snippet id not found" do
get v3_api("/projects/#{project.id}/snippets/42/notes", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it "returns 404 when not authorized" do
get v3_api("/projects/#{project.id}/snippets/#{snippet.id}/notes", private_user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -109,7 +109,7 @@ describe API::V3::Notes do
it "returns an array of merge_requests notes" do
get v3_api("/projects/#{project.id}/merge_requests/#{merge_request.id}/notes", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.first['body']).to eq(merge_request_note.note)
@@ -118,13 +118,13 @@ describe API::V3::Notes do
it "returns a 404 error if merge request id not found" do
get v3_api("/projects/#{project.id}/merge_requests/4444/notes", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it "returns 404 when not authorized" do
get v3_api("/projects/#{project.id}/merge_requests/4444/notes", private_user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -134,21 +134,21 @@ describe API::V3::Notes do
it "returns an issue note by id" do
get v3_api("/projects/#{project.id}/issues/#{issue.id}/notes/#{issue_note.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['body']).to eq(issue_note.note)
end
it "returns a 404 error if issue note not found" do
get v3_api("/projects/#{project.id}/issues/#{issue.id}/notes/12345", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
context "and current user cannot view the note" do
it "returns a 404 error" do
get v3_api("/projects/#{ext_proj.id}/issues/#{ext_issue.id}/notes/#{cross_reference_note.id}", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
context "when issue is confidential" do
@@ -157,7 +157,7 @@ describe API::V3::Notes do
it "returns 404" do
get v3_api("/projects/#{project.id}/issues/#{issue.id}/notes/#{issue_note.id}", private_user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -165,7 +165,7 @@ describe API::V3::Notes do
it "returns an issue note by id" do
get v3_api("/projects/#{ext_proj.id}/issues/#{ext_issue.id}/notes/#{cross_reference_note.id}", private_user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['body']).to eq(cross_reference_note.note)
end
end
@@ -176,14 +176,14 @@ describe API::V3::Notes do
it "returns a snippet note by id" do
get v3_api("/projects/#{project.id}/snippets/#{snippet.id}/notes/#{snippet_note.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['body']).to eq(snippet_note.note)
end
it "returns a 404 error if snippet note not found" do
get v3_api("/projects/#{project.id}/snippets/#{snippet.id}/notes/12345", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -193,7 +193,7 @@ describe API::V3::Notes do
it "creates a new issue note" do
post v3_api("/projects/#{project.id}/issues/#{issue.id}/notes", user), body: 'hi!'
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['body']).to eq('hi!')
expect(json_response['author']['username']).to eq(user.username)
end
@@ -201,13 +201,13 @@ describe API::V3::Notes do
it "returns a 400 bad request error if body not given" do
post v3_api("/projects/#{project.id}/issues/#{issue.id}/notes", user)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it "returns a 401 unauthorized error if user not authenticated" do
post v3_api("/projects/#{project.id}/issues/#{issue.id}/notes"), body: 'hi!'
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
context 'when an admin or owner makes the request' do
@@ -216,7 +216,7 @@ describe API::V3::Notes do
post v3_api("/projects/#{project.id}/issues/#{issue.id}/notes", user),
body: 'hi!', created_at: creation_time
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['body']).to eq('hi!')
expect(json_response['author']['username']).to eq(user.username)
expect(Time.parse(json_response['created_at'])).to be_like_time(creation_time)
@@ -229,7 +229,7 @@ describe API::V3::Notes do
it 'creates a new issue note' do
post v3_api("/projects/#{project.id}/issues/#{issue2.id}/notes", user), body: ':+1:'
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['body']).to eq(':+1:')
end
end
@@ -238,7 +238,7 @@ describe API::V3::Notes do
it 'creates a new issue note' do
post v3_api("/projects/#{project.id}/issues/#{issue.id}/notes", user), body: ':+1:'
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['body']).to eq(':+1:')
end
end
@@ -248,7 +248,7 @@ describe API::V3::Notes do
it "creates a new snippet note" do
post v3_api("/projects/#{project.id}/snippets/#{snippet.id}/notes", user), body: 'hi!'
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['body']).to eq('hi!')
expect(json_response['author']['username']).to eq(user.username)
end
@@ -256,13 +256,13 @@ describe API::V3::Notes do
it "returns a 400 bad request error if body not given" do
post v3_api("/projects/#{project.id}/snippets/#{snippet.id}/notes", user)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it "returns a 401 unauthorized error if user not authenticated" do
post v3_api("/projects/#{project.id}/snippets/#{snippet.id}/notes"), body: 'hi!'
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
@@ -274,7 +274,7 @@ describe API::V3::Notes do
post v3_api("/projects/#{project.id}/issues/#{issue.id}/notes", user),
body: 'Foo'
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -314,7 +314,7 @@ describe API::V3::Notes do
put v3_api("/projects/#{project.id}/issues/#{issue.id}/"\
"notes/#{issue_note.id}", user), body: 'Hello!'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['body']).to eq('Hello!')
end
@@ -322,14 +322,14 @@ describe API::V3::Notes do
put v3_api("/projects/#{project.id}/issues/#{issue.id}/notes/12345", user),
body: 'Hello!'
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'returns a 400 bad request error if body not given' do
put v3_api("/projects/#{project.id}/issues/#{issue.id}/"\
"notes/#{issue_note.id}", user)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
end
@@ -338,7 +338,7 @@ describe API::V3::Notes do
put v3_api("/projects/#{project.id}/snippets/#{snippet.id}/"\
"notes/#{snippet_note.id}", user), body: 'Hello!'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['body']).to eq('Hello!')
end
@@ -346,7 +346,7 @@ describe API::V3::Notes do
put v3_api("/projects/#{project.id}/snippets/#{snippet.id}/"\
"notes/12345", user), body: "Hello!"
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -355,7 +355,7 @@ describe API::V3::Notes do
put v3_api("/projects/#{project.id}/merge_requests/#{merge_request.id}/"\
"notes/#{merge_request_note.id}", user), body: 'Hello!'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['body']).to eq('Hello!')
end
@@ -363,7 +363,7 @@ describe API::V3::Notes do
put v3_api("/projects/#{project.id}/merge_requests/#{merge_request.id}/"\
"notes/12345", user), body: "Hello!"
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -374,17 +374,17 @@ describe API::V3::Notes do
delete v3_api("/projects/#{project.id}/issues/#{issue.id}/"\
"notes/#{issue_note.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
# Check if note is really deleted
delete v3_api("/projects/#{project.id}/issues/#{issue.id}/"\
"notes/#{issue_note.id}", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'returns a 404 error when note id not found' do
delete v3_api("/projects/#{project.id}/issues/#{issue.id}/notes/12345", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -393,18 +393,18 @@ describe API::V3::Notes do
delete v3_api("/projects/#{project.id}/snippets/#{snippet.id}/"\
"notes/#{snippet_note.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
# Check if note is really deleted
delete v3_api("/projects/#{project.id}/snippets/#{snippet.id}/"\
"notes/#{snippet_note.id}", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'returns a 404 error when note id not found' do
delete v3_api("/projects/#{project.id}/snippets/#{snippet.id}/"\
"notes/12345", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -413,18 +413,18 @@ describe API::V3::Notes do
delete v3_api("/projects/#{project.id}/merge_requests/"\
"#{merge_request.id}/notes/#{merge_request_note.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
# Check if note is really deleted
delete v3_api("/projects/#{project.id}/merge_requests/"\
"#{merge_request.id}/notes/#{merge_request_note.id}", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'returns a 404 error when note id not found' do
delete v3_api("/projects/#{project.id}/merge_requests/"\
"#{merge_request.id}/notes/12345", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
diff --git a/spec/requests/api/v3/pipelines_spec.rb b/spec/requests/api/v3/pipelines_spec.rb
index e1d036ff365..1c7d9fe32bb 100644
--- a/spec/requests/api/v3/pipelines_spec.rb
+++ b/spec/requests/api/v3/pipelines_spec.rb
@@ -32,7 +32,7 @@ describe API::V3::Pipelines do
it 'returns project pipelines' do
get v3_api("/projects/#{project.id}/pipelines", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.first['sha']).to match(/\A\h{40}\z/)
expect(json_response.first['id']).to eq pipeline.id
@@ -44,7 +44,7 @@ describe API::V3::Pipelines do
it 'does not return project pipelines' do
get v3_api("/projects/#{project.id}/pipelines", non_member)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq '404 Project Not Found'
expect(json_response).not_to be_an Array
end
@@ -61,7 +61,7 @@ describe API::V3::Pipelines do
post v3_api("/projects/#{project.id}/pipeline", user), ref: project.default_branch
end.to change { Ci::Pipeline.count }.by(1)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response).to be_a Hash
expect(json_response['sha']).to eq project.commit.id
end
@@ -69,7 +69,7 @@ describe API::V3::Pipelines do
it 'fails when using an invalid ref' do
post v3_api("/projects/#{project.id}/pipeline", user), ref: 'invalid_ref'
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['message']['base'].first).to eq 'Reference not found'
expect(json_response).not_to be_an Array
end
@@ -79,7 +79,7 @@ describe API::V3::Pipelines do
it 'fails to create pipeline' do
post v3_api("/projects/#{project.id}/pipeline", user), ref: project.default_branch
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['message']['base'].first).to eq 'Missing .gitlab-ci.yml file'
expect(json_response).not_to be_an Array
end
@@ -90,7 +90,7 @@ describe API::V3::Pipelines do
it 'does not create pipeline' do
post v3_api("/projects/#{project.id}/pipeline", non_member), ref: project.default_branch
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq '404 Project Not Found'
expect(json_response).not_to be_an Array
end
@@ -102,14 +102,14 @@ describe API::V3::Pipelines do
it 'returns project pipelines' do
get v3_api("/projects/#{project.id}/pipelines/#{pipeline.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['sha']).to match /\A\h{40}\z/
end
it 'returns 404 when it does not exist' do
get v3_api("/projects/#{project.id}/pipelines/123456", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq '404 Not found'
expect(json_response['id']).to be nil
end
@@ -131,7 +131,7 @@ describe API::V3::Pipelines do
it 'should not return a project pipeline' do
get v3_api("/projects/#{project.id}/pipelines/#{pipeline.id}", non_member)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq '404 Project Not Found'
expect(json_response['id']).to be nil
end
@@ -152,7 +152,7 @@ describe API::V3::Pipelines do
post v3_api("/projects/#{project.id}/pipelines/#{pipeline.id}/retry", user)
end.to change { pipeline.builds.count }.from(1).to(2)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(build.reload.retried?).to be true
end
end
@@ -161,7 +161,7 @@ describe API::V3::Pipelines do
it 'should not return a project pipeline' do
post v3_api("/projects/#{project.id}/pipelines/#{pipeline.id}/retry", non_member)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq '404 Project Not Found'
expect(json_response['id']).to be nil
end
@@ -180,7 +180,7 @@ describe API::V3::Pipelines do
it 'retries failed builds' do
post v3_api("/projects/#{project.id}/pipelines/#{pipeline.id}/cancel", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['status']).to eq('canceled')
end
end
@@ -193,7 +193,7 @@ describe API::V3::Pipelines do
it 'rejects the action' do
post v3_api("/projects/#{project.id}/pipelines/#{pipeline.id}/cancel", reporter)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
expect(pipeline.reload.status).to eq('pending')
end
end
diff --git a/spec/requests/api/v3/project_hooks_spec.rb b/spec/requests/api/v3/project_hooks_spec.rb
index b0eddbb5dd2..00f59744a31 100644
--- a/spec/requests/api/v3/project_hooks_spec.rb
+++ b/spec/requests/api/v3/project_hooks_spec.rb
@@ -22,7 +22,7 @@ describe API::ProjectHooks, 'ProjectHooks' do
it "returns project hooks" do
get v3_api("/projects/#{project.id}/hooks", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.count).to eq(1)
expect(json_response.first['url']).to eq("http://example.com")
@@ -42,7 +42,7 @@ describe API::ProjectHooks, 'ProjectHooks' do
it "does not access project hooks" do
get v3_api("/projects/#{project.id}/hooks", user3)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
end
@@ -51,7 +51,7 @@ describe API::ProjectHooks, 'ProjectHooks' do
context "authorized user" do
it "returns a project hook" do
get v3_api("/projects/#{project.id}/hooks/#{hook.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['url']).to eq(hook.url)
expect(json_response['issues_events']).to eq(hook.issues_events)
expect(json_response['push_events']).to eq(hook.push_events)
@@ -66,20 +66,20 @@ describe API::ProjectHooks, 'ProjectHooks' do
it "returns a 404 error if hook id is not available" do
get v3_api("/projects/#{project.id}/hooks/1234", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
context "unauthorized user" do
it "does not access an existing hook" do
get v3_api("/projects/#{project.id}/hooks/#{hook.id}", user3)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
it "returns a 404 error if hook id is not available" do
get v3_api("/projects/#{project.id}/hooks/1234", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -90,7 +90,7 @@ describe API::ProjectHooks, 'ProjectHooks' do
url: "http://example.com", issues_events: true, wiki_page_events: true, build_events: true
end.to change {project.hooks.count}.by(1)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['url']).to eq('http://example.com')
expect(json_response['issues_events']).to eq(true)
expect(json_response['push_events']).to eq(true)
@@ -111,7 +111,7 @@ describe API::ProjectHooks, 'ProjectHooks' do
post v3_api("/projects/#{project.id}/hooks", user), url: "http://example.com", token: token
end.to change {project.hooks.count}.by(1)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response["url"]).to eq("http://example.com")
expect(json_response).not_to include("token")
@@ -123,12 +123,12 @@ describe API::ProjectHooks, 'ProjectHooks' do
it "returns a 400 error if url not given" do
post v3_api("/projects/#{project.id}/hooks", user)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it "returns a 422 error if url not valid" do
post v3_api("/projects/#{project.id}/hooks", user), "url" => "ftp://example.com"
- expect(response).to have_http_status(422)
+ expect(response).to have_gitlab_http_status(422)
end
end
@@ -136,7 +136,7 @@ describe API::ProjectHooks, 'ProjectHooks' do
it "updates an existing project hook" do
put v3_api("/projects/#{project.id}/hooks/#{hook.id}", user),
url: 'http://example.org', push_events: false, build_events: true
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['url']).to eq('http://example.org')
expect(json_response['issues_events']).to eq(hook.issues_events)
expect(json_response['push_events']).to eq(false)
@@ -154,7 +154,7 @@ describe API::ProjectHooks, 'ProjectHooks' do
put v3_api("/projects/#{project.id}/hooks/#{hook.id}", user), url: "http://example.org", token: token
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response["url"]).to eq("http://example.org")
expect(json_response).not_to include("token")
@@ -164,17 +164,17 @@ describe API::ProjectHooks, 'ProjectHooks' do
it "returns 404 error if hook id not found" do
put v3_api("/projects/#{project.id}/hooks/1234", user), url: 'http://example.org'
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it "returns 400 error if url is not given" do
put v3_api("/projects/#{project.id}/hooks/#{hook.id}", user)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it "returns a 422 error if url is not valid" do
put v3_api("/projects/#{project.id}/hooks/#{hook.id}", user), url: 'ftp://example.com'
- expect(response).to have_http_status(422)
+ expect(response).to have_gitlab_http_status(422)
end
end
@@ -183,23 +183,23 @@ describe API::ProjectHooks, 'ProjectHooks' do
expect do
delete v3_api("/projects/#{project.id}/hooks/#{hook.id}", user)
end.to change {project.hooks.count}.by(-1)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it "returns success when deleting hook" do
delete v3_api("/projects/#{project.id}/hooks/#{hook.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it "returns a 404 error when deleting non existent hook" do
delete v3_api("/projects/#{project.id}/hooks/42", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it "returns a 404 error if hook id not given" do
delete v3_api("/projects/#{project.id}/hooks", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it "returns a 404 if a user attempts to delete project hooks he/she does not own" do
@@ -208,7 +208,7 @@ describe API::ProjectHooks, 'ProjectHooks' do
other_project.team << [test_user, :master]
delete v3_api("/projects/#{other_project.id}/hooks/#{hook.id}", test_user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(WebHook.exists?(hook.id)).to be_truthy
end
end
diff --git a/spec/requests/api/v3/project_snippets_spec.rb b/spec/requests/api/v3/project_snippets_spec.rb
index 7e88489082a..2ed31b99516 100644
--- a/spec/requests/api/v3/project_snippets_spec.rb
+++ b/spec/requests/api/v3/project_snippets_spec.rb
@@ -28,7 +28,7 @@ describe API::ProjectSnippets do
get v3_api("/projects/#{project.id}/snippets/", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response.size).to eq(3)
expect(json_response.map { |snippet| snippet['id']} ).to include(public_snippet.id, internal_snippet.id, private_snippet.id)
expect(json_response.last).to have_key('web_url')
@@ -38,7 +38,7 @@ describe API::ProjectSnippets do
create(:project_snippet, :private, project: project)
get v3_api("/projects/#{project.id}/snippets/", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response.size).to eq(0)
end
end
@@ -56,7 +56,7 @@ describe API::ProjectSnippets do
it 'creates a new snippet' do
post v3_api("/projects/#{project.id}/snippets/", admin), params
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
snippet = ProjectSnippet.find(json_response['id'])
expect(snippet.content).to eq(params[:code])
expect(snippet.title).to eq(params[:title])
@@ -69,7 +69,7 @@ describe API::ProjectSnippets do
post v3_api("/projects/#{project.id}/snippets/", admin), params
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
context 'when the snippet is spam' do
@@ -95,7 +95,7 @@ describe API::ProjectSnippets do
expect { create_snippet(project, visibility_level: Snippet::PUBLIC) }
.not_to change { Snippet.count }
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['message']).to eq({ "error" => "Spam detected" })
end
@@ -116,7 +116,7 @@ describe API::ProjectSnippets do
put v3_api("/projects/#{snippet.project.id}/snippets/#{snippet.id}/", admin), code: new_content
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
snippet.reload
expect(snippet.content).to eq(new_content)
end
@@ -124,14 +124,14 @@ describe API::ProjectSnippets do
it 'returns 404 for invalid snippet id' do
put v3_api("/projects/#{snippet.project.id}/snippets/1234", admin), title: 'foo'
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 Snippet Not Found')
end
it 'returns 400 for missing parameters' do
put v3_api("/projects/#{project.id}/snippets/1234", admin)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
context 'when the snippet is spam' do
@@ -173,7 +173,7 @@ describe API::ProjectSnippets do
expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) }
.not_to change { snippet.reload.title }
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['message']).to eq({ "error" => "Spam detected" })
end
@@ -194,13 +194,13 @@ describe API::ProjectSnippets do
delete v3_api("/projects/#{snippet.project.id}/snippets/#{snippet.id}/", admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it 'returns 404 for invalid snippet id' do
delete v3_api("/projects/#{snippet.project.id}/snippets/1234", admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 Snippet Not Found')
end
end
@@ -211,7 +211,7 @@ describe API::ProjectSnippets do
it 'returns raw text' do
get v3_api("/projects/#{snippet.project.id}/snippets/#{snippet.id}/raw", admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response.content_type).to eq 'text/plain'
expect(response.body).to eq(snippet.content)
end
@@ -219,7 +219,7 @@ describe API::ProjectSnippets do
it 'returns 404 for invalid snippet id' do
delete v3_api("/projects/#{snippet.project.id}/snippets/1234", admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 Snippet Not Found')
end
end
diff --git a/spec/requests/api/v3/projects_spec.rb b/spec/requests/api/v3/projects_spec.rb
index e5282c3311f..f62ad747c73 100644
--- a/spec/requests/api/v3/projects_spec.rb
+++ b/spec/requests/api/v3/projects_spec.rb
@@ -44,14 +44,14 @@ describe API::V3::Projects do
context 'when unauthenticated' do
it 'returns authentication error' do
get v3_api('/projects')
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
context 'when authenticated as regular user' do
it 'returns an array of projects' do
get v3_api('/projects', user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.first['name']).to eq(project.name)
expect(json_response.first['owner']['username']).to eq(user.username)
@@ -94,7 +94,7 @@ describe API::V3::Projects do
get v3_api('/projects?simple=true', user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.first.keys).to match_array expected_keys
end
@@ -103,7 +103,7 @@ describe API::V3::Projects do
context 'and using search' do
it 'returns searched project' do
get v3_api('/projects', user), { search: project.name }
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
end
@@ -112,21 +112,21 @@ describe API::V3::Projects do
context 'and using the visibility filter' do
it 'filters based on private visibility param' do
get v3_api('/projects', user), { visibility: 'private' }
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(user.namespace.projects.where(visibility_level: Gitlab::VisibilityLevel::PRIVATE).count)
end
it 'filters based on internal visibility param' do
get v3_api('/projects', user), { visibility: 'internal' }
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(user.namespace.projects.where(visibility_level: Gitlab::VisibilityLevel::INTERNAL).count)
end
it 'filters based on public visibility param' do
get v3_api('/projects', user), { visibility: 'public' }
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(user.namespace.projects.where(visibility_level: Gitlab::VisibilityLevel::PUBLIC).count)
end
@@ -138,7 +138,7 @@ describe API::V3::Projects do
it 'returns archived project' do
get v3_api('/projects?archived=true', user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
expect(json_response.first['id']).to eq(archived_project.id)
@@ -147,7 +147,7 @@ describe API::V3::Projects do
it 'returns non-archived project' do
get v3_api('/projects?archived=false', user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
expect(json_response.first['id']).to eq(project.id)
@@ -156,7 +156,7 @@ describe API::V3::Projects do
it 'returns all project' do
get v3_api('/projects', user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(2)
end
@@ -170,7 +170,7 @@ describe API::V3::Projects do
it 'returns the correct order when sorted by id' do
get v3_api('/projects', user), { order_by: 'id', sort: 'desc' }
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.first['id']).to eq(project3.id)
end
@@ -184,21 +184,21 @@ describe API::V3::Projects do
context 'when unauthenticated' do
it 'returns authentication error' do
get v3_api('/projects/all')
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
context 'when authenticated as regular user' do
it 'returns authentication error' do
get v3_api('/projects/all', user)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
context 'when authenticated as admin' do
it 'returns an array of all projects' do
get v3_api('/projects/all', admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response).to satisfy do |response|
@@ -213,7 +213,7 @@ describe API::V3::Projects do
it "does not include statistics by default" do
get v3_api('/projects/all', admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.first).not_to include('statistics')
end
@@ -221,7 +221,7 @@ describe API::V3::Projects do
it "includes statistics if requested" do
get v3_api('/projects/all', admin), statistics: true
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.first).to include 'statistics'
end
@@ -237,14 +237,14 @@ describe API::V3::Projects do
context 'when unauthenticated' do
it 'returns authentication error' do
get v3_api('/projects/owned')
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
context 'when authenticated as project owner' do
it 'returns an array of projects the user owns' do
get v3_api('/projects/owned', user4)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.first['name']).to eq(project4.name)
expect(json_response.first['owner']['username']).to eq(user4.username)
@@ -253,7 +253,7 @@ describe API::V3::Projects do
it "does not include statistics by default" do
get v3_api('/projects/owned', user4)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.first).not_to include('statistics')
end
@@ -271,7 +271,7 @@ describe API::V3::Projects do
get v3_api('/projects/owned', user4), statistics: true
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.first['statistics']).to eq attributes.stringify_keys
end
@@ -283,7 +283,7 @@ describe API::V3::Projects do
it 'returns the visible projects' do
get v3_api('/projects/visible', current_user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.map { |p| p['id'] }).to contain_exactly(*projects.map(&:id))
end
@@ -329,7 +329,7 @@ describe API::V3::Projects do
it 'returns the starred projects viewable by the user' do
get v3_api('/projects/starred', user3)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.map { |project| project['id'] }).to contain_exactly(project.id, public_project.id)
end
@@ -341,14 +341,14 @@ describe API::V3::Projects do
allow_any_instance_of(User).to receive(:projects_limit_left).and_return(0)
expect { post v3_api('/projects', user2), name: 'foo' }
.to change {Project.count}.by(0)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
it 'creates new project without path but with name and returns 201' do
expect { post v3_api('/projects', user), name: 'Foo Project' }
.to change { Project.count }.by(1)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
project = Project.first
@@ -359,7 +359,7 @@ describe API::V3::Projects do
it 'creates new project without name but with path and returns 201' do
expect { post v3_api('/projects', user), path: 'foo_project' }
.to change { Project.count }.by(1)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
project = Project.first
@@ -370,7 +370,7 @@ describe API::V3::Projects do
it 'creates new project name and path and returns 201' do
expect { post v3_api('/projects', user), path: 'foo-Project', name: 'Foo Project' }
.to change { Project.count }.by(1)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
project = Project.first
@@ -381,12 +381,12 @@ describe API::V3::Projects do
it 'creates last project before reaching project limit' do
allow_any_instance_of(User).to receive(:projects_limit_left).and_return(1)
post v3_api('/projects', user2), name: 'foo'
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
end
it 'does not create new project without name or path and return 400' do
expect { post v3_api('/projects', user) }.not_to change { Project.count }
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it "assigns attributes to project" do
@@ -501,7 +501,7 @@ describe API::V3::Projects do
it 'does not allow a non-admin to use a restricted visibility level' do
post v3_api('/projects', user), @project
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['message']['visibility_level'].first).to(
match('restricted by your GitLab administrator')
)
@@ -523,14 +523,14 @@ describe API::V3::Projects do
it 'should create new project without path and return 201' do
expect { post v3_api("/projects/user/#{user.id}", admin), name: 'foo' }.to change {Project.count}.by(1)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
end
it 'responds with 400 on failure and not project' do
expect { post v3_api("/projects/user/#{user.id}", admin) }
.not_to change { Project.count }
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['error']).to eq('name is missing')
end
@@ -544,7 +544,7 @@ describe API::V3::Projects do
post v3_api("/projects/user/#{user.id}", admin), project
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
project.each_pair do |k, v|
next if %i[has_external_issue_tracker path].include?(k)
expect(json_response[k.to_s]).to eq(v)
@@ -555,7 +555,7 @@ describe API::V3::Projects do
project = attributes_for(:project, :public)
post v3_api("/projects/user/#{user.id}", admin), project
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['public']).to be_truthy
expect(json_response['visibility_level']).to eq(Gitlab::VisibilityLevel::PUBLIC)
end
@@ -564,7 +564,7 @@ describe API::V3::Projects do
project = attributes_for(:project, { public: true })
post v3_api("/projects/user/#{user.id}", admin), project
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['public']).to be_truthy
expect(json_response['visibility_level']).to eq(Gitlab::VisibilityLevel::PUBLIC)
end
@@ -573,7 +573,7 @@ describe API::V3::Projects do
project = attributes_for(:project, :internal)
post v3_api("/projects/user/#{user.id}", admin), project
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['public']).to be_falsey
expect(json_response['visibility_level']).to eq(Gitlab::VisibilityLevel::INTERNAL)
end
@@ -581,7 +581,7 @@ describe API::V3::Projects do
it 'sets a project as internal overriding :public' do
project = attributes_for(:project, :internal, { public: true })
post v3_api("/projects/user/#{user.id}", admin), project
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['public']).to be_falsey
expect(json_response['visibility_level']).to eq(Gitlab::VisibilityLevel::INTERNAL)
end
@@ -635,7 +635,7 @@ describe API::V3::Projects do
it "uploads the file and returns its info" do
post v3_api("/projects/#{project.id}/uploads", user), file: fixture_file_upload(Rails.root + "spec/fixtures/dk.png", "image/png")
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['alt']).to eq("dk")
expect(json_response['url']).to start_with("/uploads/")
expect(json_response['url']).to end_with("/dk.png")
@@ -649,7 +649,7 @@ describe API::V3::Projects do
get v3_api("/projects/#{public_project.id}")
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['id']).to eq(public_project.id)
expect(json_response['description']).to eq(public_project.description)
expect(json_response['default_branch']).to eq(public_project.default_branch)
@@ -668,7 +668,7 @@ describe API::V3::Projects do
get v3_api("/projects/#{project.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['id']).to eq(project.id)
expect(json_response['description']).to eq(project.description)
expect(json_response['default_branch']).to eq(project.default_branch)
@@ -710,20 +710,20 @@ describe API::V3::Projects do
it 'returns a project by path name' do
get v3_api("/projects/#{project.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['name']).to eq(project.name)
end
it 'returns a 404 error if not found' do
get v3_api('/projects/42', user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 Project Not Found')
end
it 'returns a 404 error if user is not a member' do
other_user = create(:user)
get v3_api("/projects/#{project.id}", other_user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'handles users with dots' do
@@ -731,14 +731,14 @@ describe API::V3::Projects do
project = create(:project, creator_id: dot_user.id, namespace: dot_user.namespace)
get v3_api("/projects/#{CGI.escape(project.full_path)}", dot_user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['name']).to eq(project.name)
end
it 'exposes namespace fields' do
get v3_api("/projects/#{project.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['namespace']).to eq({
'id' => user.namespace.id,
'name' => user.namespace.name,
@@ -756,7 +756,7 @@ describe API::V3::Projects do
it 'contains permission information' do
get v3_api("/projects", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response.first['permissions']['project_access']['access_level'])
.to eq(Gitlab::Access::MASTER)
expect(json_response.first['permissions']['group_access']).to be_nil
@@ -768,7 +768,7 @@ describe API::V3::Projects do
project.team << [user, :master]
get v3_api("/projects/#{project.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['permissions']['project_access']['access_level'])
.to eq(Gitlab::Access::MASTER)
expect(json_response['permissions']['group_access']).to be_nil
@@ -783,7 +783,7 @@ describe API::V3::Projects do
it 'sets the owner and return 200' do
get v3_api("/projects/#{project2.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['permissions']['project_access']).to be_nil
expect(json_response['permissions']['group_access']['access_level'])
.to eq(Gitlab::Access::OWNER)
@@ -803,7 +803,7 @@ describe API::V3::Projects do
get v3_api("/projects/#{project.id}/events", current_user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
first_event = json_response.first
@@ -836,7 +836,7 @@ describe API::V3::Projects do
it 'returns a 404 error if not found' do
get v3_api('/projects/42/events', user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 Project Not Found')
end
@@ -845,7 +845,7 @@ describe API::V3::Projects do
get v3_api("/projects/#{project.id}/events", other_user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -857,7 +857,7 @@ describe API::V3::Projects do
get v3_api("/projects/#{project.id}/users", current_user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.size).to eq(1)
@@ -886,7 +886,7 @@ describe API::V3::Projects do
it 'returns a 404 error if not found' do
get v3_api('/projects/42/users', user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 Project Not Found')
end
@@ -895,7 +895,7 @@ describe API::V3::Projects do
get v3_api("/projects/#{project.id}/users", other_user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -905,7 +905,7 @@ describe API::V3::Projects do
it 'returns an array of project snippets' do
get v3_api("/projects/#{project.id}/snippets", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.first['title']).to eq(snippet.title)
end
@@ -914,13 +914,13 @@ describe API::V3::Projects do
describe 'GET /projects/:id/snippets/:snippet_id' do
it 'returns a project snippet' do
get v3_api("/projects/#{project.id}/snippets/#{snippet.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['title']).to eq(snippet.title)
end
it 'returns a 404 error if snippet id not found' do
get v3_api("/projects/#{project.id}/snippets/1234", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -929,7 +929,7 @@ describe API::V3::Projects do
post v3_api("/projects/#{project.id}/snippets", user),
title: 'v3_api test', file_name: 'sample.rb', code: 'test',
visibility_level: '0'
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['title']).to eq('v3_api test')
end
@@ -943,7 +943,7 @@ describe API::V3::Projects do
it 'updates an existing project snippet' do
put v3_api("/projects/#{project.id}/snippets/#{snippet.id}", user),
code: 'updated code'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['title']).to eq('example')
expect(snippet.reload.content).to eq('updated code')
end
@@ -951,7 +951,7 @@ describe API::V3::Projects do
it 'updates an existing project snippet with new title' do
put v3_api("/projects/#{project.id}/snippets/#{snippet.id}", user),
title: 'other v3_api test'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['title']).to eq('other v3_api test')
end
end
@@ -963,24 +963,24 @@ describe API::V3::Projects do
expect do
delete v3_api("/projects/#{project.id}/snippets/#{snippet.id}", user)
end.to change { Snippet.count }.by(-1)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it 'returns 404 when deleting unknown snippet id' do
delete v3_api("/projects/#{project.id}/snippets/1234", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
describe 'GET /projects/:id/snippets/:snippet_id/raw' do
it 'gets a raw project snippet' do
get v3_api("/projects/#{project.id}/snippets/#{snippet.id}/raw", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it 'returns a 404 error if raw project snippet not found' do
get v3_api("/projects/#{project.id}/snippets/5555/raw", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -993,13 +993,13 @@ describe API::V3::Projects do
it "is not available for non admin users" do
post v3_api("/projects/#{project_fork_target.id}/fork/#{project_fork_source.id}", user)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
it 'allows project to be forked from an existing project' do
expect(project_fork_target.forked?).not_to be_truthy
post v3_api("/projects/#{project_fork_target.id}/fork/#{project_fork_source.id}", admin)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
project_fork_target.reload
expect(project_fork_target.forked_from_project.id).to eq(project_fork_source.id)
expect(project_fork_target.forked_project_link).not_to be_nil
@@ -1016,7 +1016,7 @@ describe API::V3::Projects do
it 'fails if forked_from project which does not exist' do
post v3_api("/projects/#{project_fork_target.id}/fork/9999", admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'fails with 409 if already forked' do
@@ -1024,7 +1024,7 @@ describe API::V3::Projects do
project_fork_target.reload
expect(project_fork_target.forked_from_project.id).to eq(project_fork_source.id)
post v3_api("/projects/#{project_fork_target.id}/fork/#{new_project_fork_source.id}", admin)
- expect(response).to have_http_status(409)
+ expect(response).to have_gitlab_http_status(409)
project_fork_target.reload
expect(project_fork_target.forked_from_project.id).to eq(project_fork_source.id)
expect(project_fork_target.forked?).to be_truthy
@@ -1034,7 +1034,7 @@ describe API::V3::Projects do
describe 'DELETE /projects/:id/fork' do
it "is not visible to users outside group" do
delete v3_api("/projects/#{project_fork_target.id}/fork", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
context 'when users belong to project group' do
@@ -1047,7 +1047,7 @@ describe API::V3::Projects do
it 'is forbidden to non-owner users' do
delete v3_api("/projects/#{project_fork_target.id}/fork", user2)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
it 'makes forked project unforked' do
@@ -1056,7 +1056,7 @@ describe API::V3::Projects do
expect(project_fork_target.forked_from_project).not_to be_nil
expect(project_fork_target.forked?).to be_truthy
delete v3_api("/projects/#{project_fork_target.id}/fork", admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
project_fork_target.reload
expect(project_fork_target.forked_from_project).to be_nil
expect(project_fork_target.forked?).not_to be_truthy
@@ -1065,7 +1065,7 @@ describe API::V3::Projects do
it 'is idempotent if not forked' do
expect(project_fork_target.forked_from_project).to be_nil
delete v3_api("/projects/#{project_fork_target.id}/fork", admin)
- expect(response).to have_http_status(304)
+ expect(response).to have_gitlab_http_status(304)
expect(project_fork_target.reload.forked_from_project).to be_nil
end
end
@@ -1082,7 +1082,7 @@ describe API::V3::Projects do
post v3_api("/projects/#{project.id}/share", user), group_id: group.id, group_access: Gitlab::Access::DEVELOPER, expires_at: expires_at
end.to change { ProjectGroupLink.count }.by(1)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['group_id']).to eq(group.id)
expect(json_response['group_access']).to eq(Gitlab::Access::DEVELOPER)
expect(json_response['expires_at']).to eq(expires_at.to_s)
@@ -1090,18 +1090,18 @@ describe API::V3::Projects do
it "returns a 400 error when group id is not given" do
post v3_api("/projects/#{project.id}/share", user), group_access: Gitlab::Access::DEVELOPER
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it "returns a 400 error when access level is not given" do
post v3_api("/projects/#{project.id}/share", user), group_id: group.id
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it "returns a 400 error when sharing is disabled" do
project.namespace.update(share_with_group_lock: true)
post v3_api("/projects/#{project.id}/share", user), group_id: group.id, group_access: Gitlab::Access::DEVELOPER
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it 'returns a 404 error when user cannot read group' do
@@ -1109,19 +1109,19 @@ describe API::V3::Projects do
post v3_api("/projects/#{project.id}/share", user), group_id: private_group.id, group_access: Gitlab::Access::DEVELOPER
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'returns a 404 error when group does not exist' do
post v3_api("/projects/#{project.id}/share", user), group_id: 1234, group_access: Gitlab::Access::DEVELOPER
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it "returns a 400 error when wrong params passed" do
post v3_api("/projects/#{project.id}/share", user), group_id: group.id, group_access: 1234
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['error']).to eq 'group_access does not have a valid value'
end
end
@@ -1133,26 +1133,26 @@ describe API::V3::Projects do
delete v3_api("/projects/#{project.id}/share/#{group.id}", user)
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
expect(project.project_group_links).to be_empty
end
it 'returns a 400 when group id is not an integer' do
delete v3_api("/projects/#{project.id}/share/foo", user)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it 'returns a 404 error when group link does not exist' do
delete v3_api("/projects/#{project.id}/share/1234", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'returns a 404 error when project does not exist' do
delete v3_api("/projects/123/share/1234", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -1173,7 +1173,7 @@ describe API::V3::Projects do
it 'returns project search responses' do
get v3_api("/projects/search/#{args[:query]}", current_user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.size).to eq(args[:results])
json_response.each { |project| expect(project['name']).to match(args[:match_regex] || /.*#{args[:query]}.*/) }
@@ -1216,7 +1216,7 @@ describe API::V3::Projects do
it 'returns authentication error' do
project_param = { name: 'bar' }
put v3_api("/projects/#{project.id}"), project_param
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
@@ -1224,7 +1224,7 @@ describe API::V3::Projects do
it 'updates name' do
project_param = { name: 'bar' }
put v3_api("/projects/#{project.id}", user), project_param
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
project_param.each_pair do |k, v|
expect(json_response[k.to_s]).to eq(v)
end
@@ -1233,7 +1233,7 @@ describe API::V3::Projects do
it 'updates visibility_level' do
project_param = { visibility_level: 20 }
put v3_api("/projects/#{project3.id}", user), project_param
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
project_param.each_pair do |k, v|
expect(json_response[k.to_s]).to eq(v)
end
@@ -1243,7 +1243,7 @@ describe API::V3::Projects do
project3.update_attributes({ visibility_level: Gitlab::VisibilityLevel::PUBLIC })
project_param = { public: false }
put v3_api("/projects/#{project3.id}", user), project_param
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
project_param.each_pair do |k, v|
expect(json_response[k.to_s]).to eq(v)
end
@@ -1253,7 +1253,7 @@ describe API::V3::Projects do
it 'does not update name to existing name' do
project_param = { name: project3.name }
put v3_api("/projects/#{project.id}", user), project_param
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['message']['name']).to eq(['has already been taken'])
end
@@ -1262,14 +1262,14 @@ describe API::V3::Projects do
put v3_api("/projects/#{project.id}", user), project_param
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['request_access_enabled']).to eq(false)
end
it 'updates path & name to existing path & name in different namespace' do
project_param = { path: project4.path, name: project4.name }
put v3_api("/projects/#{project3.id}", user), project_param
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
project_param.each_pair do |k, v|
expect(json_response[k.to_s]).to eq(v)
end
@@ -1280,7 +1280,7 @@ describe API::V3::Projects do
it 'updates path' do
project_param = { path: 'bar' }
put v3_api("/projects/#{project3.id}", user4), project_param
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
project_param.each_pair do |k, v|
expect(json_response[k.to_s]).to eq(v)
end
@@ -1294,7 +1294,7 @@ describe API::V3::Projects do
description: 'new description' }
put v3_api("/projects/#{project3.id}", user4), project_param
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
project_param.each_pair do |k, v|
expect(json_response[k.to_s]).to eq(v)
end
@@ -1303,20 +1303,20 @@ describe API::V3::Projects do
it 'does not update path to existing path' do
project_param = { path: project.path }
put v3_api("/projects/#{project3.id}", user4), project_param
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['message']['path']).to eq(['has already been taken'])
end
it 'does not update name' do
project_param = { name: 'bar' }
put v3_api("/projects/#{project3.id}", user4), project_param
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
it 'does not update visibility_level' do
project_param = { visibility_level: 20 }
put v3_api("/projects/#{project3.id}", user4), project_param
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -1330,7 +1330,7 @@ describe API::V3::Projects do
description: 'new description',
request_access_enabled: true }
put v3_api("/projects/#{project.id}", user3), project_param
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
end
@@ -1340,7 +1340,7 @@ describe API::V3::Projects do
it 'archives the project' do
post v3_api("/projects/#{project.id}/archive", user)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['archived']).to be_truthy
end
end
@@ -1353,7 +1353,7 @@ describe API::V3::Projects do
it 'remains archived' do
post v3_api("/projects/#{project.id}/archive", user)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['archived']).to be_truthy
end
end
@@ -1366,7 +1366,7 @@ describe API::V3::Projects do
it 'rejects the action' do
post v3_api("/projects/#{project.id}/archive", user3)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
end
@@ -1376,7 +1376,7 @@ describe API::V3::Projects do
it 'remains unarchived' do
post v3_api("/projects/#{project.id}/unarchive", user)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['archived']).to be_falsey
end
end
@@ -1389,7 +1389,7 @@ describe API::V3::Projects do
it 'unarchives the project' do
post v3_api("/projects/#{project.id}/unarchive", user)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['archived']).to be_falsey
end
end
@@ -1402,7 +1402,7 @@ describe API::V3::Projects do
it 'rejects the action' do
post v3_api("/projects/#{project.id}/unarchive", user3)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
end
@@ -1412,7 +1412,7 @@ describe API::V3::Projects do
it 'stars the project' do
expect { post v3_api("/projects/#{project.id}/star", user) }.to change { project.reload.star_count }.by(1)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['star_count']).to eq(1)
end
end
@@ -1426,7 +1426,7 @@ describe API::V3::Projects do
it 'does not modify the star count' do
expect { post v3_api("/projects/#{project.id}/star", user) }.not_to change { project.reload.star_count }
- expect(response).to have_http_status(304)
+ expect(response).to have_gitlab_http_status(304)
end
end
end
@@ -1441,7 +1441,7 @@ describe API::V3::Projects do
it 'unstars the project' do
expect { delete v3_api("/projects/#{project.id}/star", user) }.to change { project.reload.star_count }.by(-1)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['star_count']).to eq(0)
end
end
@@ -1450,7 +1450,7 @@ describe API::V3::Projects do
it 'does not modify the star count' do
expect { delete v3_api("/projects/#{project.id}/star", user) }.not_to change { project.reload.star_count }
- expect(response).to have_http_status(304)
+ expect(response).to have_gitlab_http_status(304)
end
end
end
@@ -1459,36 +1459,36 @@ describe API::V3::Projects do
context 'when authenticated as user' do
it 'removes project' do
delete v3_api("/projects/#{project.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it 'does not remove a project if not an owner' do
user3 = create(:user)
project.team << [user3, :developer]
delete v3_api("/projects/#{project.id}", user3)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
it 'does not remove a non existing project' do
delete v3_api('/projects/1328', user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'does not remove a project not attached to user' do
delete v3_api("/projects/#{project.id}", user2)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
context 'when authenticated as admin' do
it 'removes any existing project' do
delete v3_api("/projects/#{project.id}", admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it 'does not remove a non existing project' do
delete v3_api('/projects/1328', admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
diff --git a/spec/requests/api/v3/repositories_spec.rb b/spec/requests/api/v3/repositories_spec.rb
index 67624a0bbea..0167eb2c4f6 100644
--- a/spec/requests/api/v3/repositories_spec.rb
+++ b/spec/requests/api/v3/repositories_spec.rb
@@ -17,7 +17,7 @@ describe API::V3::Repositories do
it 'returns the repository tree' do
get v3_api(route, current_user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
first_commit = json_response.first
@@ -107,7 +107,7 @@ describe API::V3::Repositories do
shared_examples_for 'repository blob' do
it 'returns the repository blob' do
get v3_api(route, current_user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
context 'when sha does not exist' do
it_behaves_like '404 response' do
@@ -162,7 +162,7 @@ describe API::V3::Repositories do
shared_examples_for 'repository raw blob' do
it 'returns the repository raw blob' do
get v3_api(route, current_user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
context 'when sha does not exist' do
it_behaves_like '404 response' do
@@ -205,7 +205,7 @@ describe API::V3::Repositories do
shared_examples_for 'repository archive' do
it 'returns the repository archive' do
get v3_api(route, current_user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
repo_name = project.repository.name.gsub("\.git", "")
type, params = workhorse_send_data
expect(type).to eq('git-archive')
@@ -213,7 +213,7 @@ describe API::V3::Repositories do
end
it 'returns the repository archive archive.zip' do
get v3_api("/projects/#{project.id}/repository/archive.zip", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
repo_name = project.repository.name.gsub("\.git", "")
type, params = workhorse_send_data
expect(type).to eq('git-archive')
@@ -221,7 +221,7 @@ describe API::V3::Repositories do
end
it 'returns the repository archive archive.tar.bz2' do
get v3_api("/projects/#{project.id}/repository/archive.tar.bz2", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
repo_name = project.repository.name.gsub("\.git", "")
type, params = workhorse_send_data
expect(type).to eq('git-archive')
@@ -263,32 +263,32 @@ describe API::V3::Repositories do
shared_examples_for 'repository compare' do
it "compares branches" do
get v3_api(route, current_user), from: 'master', to: 'feature'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['commits']).to be_present
expect(json_response['diffs']).to be_present
end
it "compares tags" do
get v3_api(route, current_user), from: 'v1.0.0', to: 'v1.1.0'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['commits']).to be_present
expect(json_response['diffs']).to be_present
end
it "compares commits" do
get v3_api(route, current_user), from: sample_commit.id, to: sample_commit.parent_id
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['commits']).to be_empty
expect(json_response['diffs']).to be_empty
expect(json_response['compare_same_ref']).to be_falsey
end
it "compares commits in reverse order" do
get v3_api(route, current_user), from: sample_commit.parent_id, to: sample_commit.id
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['commits']).to be_present
expect(json_response['diffs']).to be_present
end
it "compares same refs" do
get v3_api(route, current_user), from: 'master', to: 'master'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['commits']).to be_empty
expect(json_response['diffs']).to be_empty
expect(json_response['compare_same_ref']).to be_truthy
@@ -325,7 +325,7 @@ describe API::V3::Repositories do
it 'returns valid data' do
get v3_api(route, current_user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
first_contributor = json_response.first
diff --git a/spec/requests/api/v3/runners_spec.rb b/spec/requests/api/v3/runners_spec.rb
index a31eb3f1d43..c91b097a3c7 100644
--- a/spec/requests/api/v3/runners_spec.rb
+++ b/spec/requests/api/v3/runners_spec.rb
@@ -37,7 +37,7 @@ describe API::V3::Runners do
expect do
delete v3_api("/runners/#{shared_runner.id}", admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end.to change { Ci::Runner.shared.count }.by(-1)
end
end
@@ -47,7 +47,7 @@ describe API::V3::Runners do
expect do
delete v3_api("/runners/#{unused_specific_runner.id}", admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end.to change { Ci::Runner.specific.count }.by(-1)
end
@@ -55,7 +55,7 @@ describe API::V3::Runners do
expect do
delete v3_api("/runners/#{specific_runner.id}", admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end.to change { Ci::Runner.specific.count }.by(-1)
end
end
@@ -63,7 +63,7 @@ describe API::V3::Runners do
it 'returns 404 if runner does not exists' do
delete v3_api('/runners/9999', admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -71,26 +71,26 @@ describe API::V3::Runners do
context 'when runner is shared' do
it 'does not delete runner' do
delete v3_api("/runners/#{shared_runner.id}", user)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
context 'when runner is not shared' do
it 'does not delete runner without access to it' do
delete v3_api("/runners/#{specific_runner.id}", user2)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
it 'does not delete runner with more than one associated project' do
delete v3_api("/runners/#{two_projects_runner.id}", user)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
it 'deletes runner for one owned project' do
expect do
delete v3_api("/runners/#{specific_runner.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end.to change { Ci::Runner.specific.count }.by(-1)
end
end
@@ -100,7 +100,7 @@ describe API::V3::Runners do
it 'does not delete runner' do
delete v3_api("/runners/#{specific_runner.id}")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
end
@@ -112,7 +112,7 @@ describe API::V3::Runners do
expect do
delete v3_api("/projects/#{project.id}/runners/#{two_projects_runner.id}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end.to change { project.runners.count }.by(-1)
end
end
@@ -122,14 +122,14 @@ describe API::V3::Runners do
expect do
delete v3_api("/projects/#{project.id}/runners/#{specific_runner.id}", user)
end.to change { project.runners.count }.by(0)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
it 'returns 404 is runner is not found' do
delete v3_api("/projects/#{project.id}/runners/9999", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -137,7 +137,7 @@ describe API::V3::Runners do
it "does not disable project's runner" do
delete v3_api("/projects/#{project.id}/runners/#{specific_runner.id}", user2)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -145,7 +145,7 @@ describe API::V3::Runners do
it "does not disable project's runner" do
delete v3_api("/projects/#{project.id}/runners/#{specific_runner.id}")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
end
diff --git a/spec/requests/api/v3/services_spec.rb b/spec/requests/api/v3/services_spec.rb
index f0fa48e22df..8f212ab6be6 100644
--- a/spec/requests/api/v3/services_spec.rb
+++ b/spec/requests/api/v3/services_spec.rb
@@ -13,7 +13,7 @@ describe API::V3::Services do
it "deletes #{service}" do
delete v3_api("/projects/#{project.id}/services/#{dashed_service}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
project.send(service_method).reload
expect(project.send(service_method).activated?).to be_falsey
end
diff --git a/spec/requests/api/v3/settings_spec.rb b/spec/requests/api/v3/settings_spec.rb
index 291f6dcc2aa..25fa0a8aabd 100644
--- a/spec/requests/api/v3/settings_spec.rb
+++ b/spec/requests/api/v3/settings_spec.rb
@@ -7,7 +7,7 @@ describe API::V3::Settings, 'Settings' do
describe "GET /application/settings" do
it "returns application settings" do
get v3_api("/application/settings", admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Hash
expect(json_response['default_projects_limit']).to eq(42)
expect(json_response['password_authentication_enabled']).to be_truthy
@@ -30,7 +30,7 @@ describe API::V3::Settings, 'Settings' do
put v3_api("/application/settings", admin),
default_projects_limit: 3, password_authentication_enabled: false, repository_storage: 'custom', koding_enabled: true, koding_url: 'http://koding.example.com',
plantuml_enabled: true, plantuml_url: 'http://plantuml.example.com'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['default_projects_limit']).to eq(3)
expect(json_response['password_authentication_enabled']).to be_falsey
expect(json_response['repository_storage']).to eq('custom')
@@ -46,7 +46,7 @@ describe API::V3::Settings, 'Settings' do
it "returns a blank parameter error message" do
put v3_api("/application/settings", admin), koding_enabled: true
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['error']).to eq('koding_url is missing')
end
end
@@ -55,7 +55,7 @@ describe API::V3::Settings, 'Settings' do
it "returns a blank parameter error message" do
put v3_api("/application/settings", admin), plantuml_enabled: true
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['error']).to eq('plantuml_url is missing')
end
end
diff --git a/spec/requests/api/v3/snippets_spec.rb b/spec/requests/api/v3/snippets_spec.rb
index 79860725634..e8913039194 100644
--- a/spec/requests/api/v3/snippets_spec.rb
+++ b/spec/requests/api/v3/snippets_spec.rb
@@ -11,7 +11,7 @@ describe API::V3::Snippets do
get v3_api("/snippets/", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response.map { |snippet| snippet['id']} ).to contain_exactly(
public_snippet.id,
internal_snippet.id,
@@ -24,7 +24,7 @@ describe API::V3::Snippets do
create(:personal_snippet, :private)
get v3_api("/snippets/", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response.size).to eq(0)
end
end
@@ -41,7 +41,7 @@ describe API::V3::Snippets do
it 'returns all snippets with public visibility from all users' do
get v3_api("/snippets/public", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response.map { |snippet| snippet['id']} ).to contain_exactly(
public_snippet.id,
public_snippet_other.id)
@@ -60,7 +60,7 @@ describe API::V3::Snippets do
it 'returns raw text' do
get v3_api("/snippets/#{snippet.id}/raw", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response.content_type).to eq 'text/plain'
expect(response.body).to eq(snippet.content)
end
@@ -68,7 +68,7 @@ describe API::V3::Snippets do
it 'returns 404 for invalid snippet id' do
delete v3_api("/snippets/1234", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 Snippet Not Found')
end
end
@@ -88,7 +88,7 @@ describe API::V3::Snippets do
post v3_api("/snippets/", user), params
end.to change { PersonalSnippet.count }.by(1)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['title']).to eq(params[:title])
expect(json_response['file_name']).to eq(params[:file_name])
end
@@ -98,7 +98,7 @@ describe API::V3::Snippets do
post v3_api("/snippets/", user), params
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
context 'when the snippet is spam' do
@@ -121,7 +121,7 @@ describe API::V3::Snippets do
it 'rejects the shippet' do
expect { create_snippet(visibility_level: Snippet::PUBLIC) }
.not_to change { Snippet.count }
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it 'creates a spam log' do
@@ -140,7 +140,7 @@ describe API::V3::Snippets do
put v3_api("/snippets/#{public_snippet.id}", user), content: new_content
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
public_snippet.reload
expect(public_snippet.content).to eq(new_content)
end
@@ -148,21 +148,21 @@ describe API::V3::Snippets do
it 'returns 404 for invalid snippet id' do
put v3_api("/snippets/1234", user), title: 'foo'
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 Snippet Not Found')
end
it "returns 404 for another user's snippet" do
put v3_api("/snippets/#{public_snippet.id}", other_user), title: 'fubar'
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 Snippet Not Found')
end
it 'returns 400 for missing parameters' do
put v3_api("/snippets/1234", user)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
end
@@ -172,14 +172,14 @@ describe API::V3::Snippets do
expect do
delete v3_api("/snippets/#{public_snippet.id}", user)
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
end.to change { PersonalSnippet.count }.by(-1)
end
it 'returns 404 for invalid snippet id' do
delete v3_api("/snippets/1234", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 Snippet Not Found')
end
end
diff --git a/spec/requests/api/v3/system_hooks_spec.rb b/spec/requests/api/v3/system_hooks_spec.rb
index ae427541abb..30711c60faa 100644
--- a/spec/requests/api/v3/system_hooks_spec.rb
+++ b/spec/requests/api/v3/system_hooks_spec.rb
@@ -12,7 +12,7 @@ describe API::V3::SystemHooks do
it "returns authentication error" do
get v3_api("/hooks")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
@@ -20,7 +20,7 @@ describe API::V3::SystemHooks do
it "returns forbidden error" do
get v3_api("/hooks", user)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -28,7 +28,7 @@ describe API::V3::SystemHooks do
it "returns an array of hooks" do
get v3_api("/hooks", admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.first['url']).to eq(hook.url)
expect(json_response.first['push_events']).to be false
@@ -43,14 +43,14 @@ describe API::V3::SystemHooks do
expect do
delete v3_api("/hooks/#{hook.id}", admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end.to change { SystemHook.count }.by(-1)
end
it 'returns 404 if the system hook does not exist' do
delete v3_api('/hooks/12345', admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
diff --git a/spec/requests/api/v3/tags_spec.rb b/spec/requests/api/v3/tags_spec.rb
index 1c4b25c47c3..e6ad005fa87 100644
--- a/spec/requests/api/v3/tags_spec.rb
+++ b/spec/requests/api/v3/tags_spec.rb
@@ -17,7 +17,7 @@ describe API::V3::Tags do
it 'returns the repository tags' do
get v3_api("/projects/#{project.id}/repository/tags", current_user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.first['name']).to eq(tag_name)
end
@@ -40,7 +40,7 @@ describe API::V3::Tags do
it "returns an array of project tags" do
get v3_api("/projects/#{project.id}/repository/tags", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.first['name']).to eq(tag_name)
end
@@ -55,7 +55,7 @@ describe API::V3::Tags do
it "returns an array of project tags with release info" do
get v3_api("/projects/#{project.id}/repository/tags", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.first['name']).to eq(tag_name)
expect(json_response.first['message']).to eq('Version 1.1.0')
@@ -75,13 +75,13 @@ describe API::V3::Tags do
it 'deletes an existing tag' do
delete v3_api("/projects/#{project.id}/repository/tags/#{tag_name}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['tag_name']).to eq(tag_name)
end
it 'raises 404 if the tag does not exist' do
delete v3_api("/projects/#{project.id}/repository/tags/foobar", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
diff --git a/spec/requests/api/v3/templates_spec.rb b/spec/requests/api/v3/templates_spec.rb
index 00446c7f29c..38a8994eb79 100644
--- a/spec/requests/api/v3/templates_spec.rb
+++ b/spec/requests/api/v3/templates_spec.rb
@@ -19,7 +19,7 @@ describe API::V3::Templates do
it 'returns a list of available gitignore templates' do
get v3_api(path)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.size).to be > 15
end
@@ -29,7 +29,7 @@ describe API::V3::Templates do
it 'returns a list of available gitlab_ci_ymls' do
get v3_api(path)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.first['name']).not_to be_nil
end
@@ -39,7 +39,7 @@ describe API::V3::Templates do
it 'adds a disclaimer on the top' do
get v3_api(path)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['content']).to start_with("# This file is a template,")
end
end
@@ -66,7 +66,7 @@ describe API::V3::Templates do
it 'returns a list of available license templates' do
get v3_api(path)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.size).to eq(12)
expect(json_response.map { |l| l['key'] }).to include('agpl-3.0')
@@ -77,7 +77,7 @@ describe API::V3::Templates do
it 'returns a list of available popular license templates' do
get v3_api("#{path}?popular=1")
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.size).to eq(3)
expect(json_response.map { |l| l['key'] }).to include('apache-2.0')
@@ -159,7 +159,7 @@ describe API::V3::Templates do
let(:license_type) { 'muth-over9000' }
it 'returns a 404' do
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
diff --git a/spec/requests/api/v3/triggers_spec.rb b/spec/requests/api/v3/triggers_spec.rb
index 7ccf387f2dc..e8e2f49d7a0 100644
--- a/spec/requests/api/v3/triggers_spec.rb
+++ b/spec/requests/api/v3/triggers_spec.rb
@@ -27,17 +27,17 @@ describe API::V3::Triggers do
context 'Handles errors' do
it 'returns bad request if token is missing' do
post v3_api("/projects/#{project.id}/trigger/builds"), ref: 'master'
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it 'returns not found if project is not found' do
post v3_api('/projects/0/trigger/builds'), options.merge(ref: 'master')
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'returns unauthorized if token is for different project' do
post v3_api("/projects/#{project2.id}/trigger/builds"), options.merge(ref: 'master')
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -46,7 +46,7 @@ describe API::V3::Triggers do
it 'creates builds' do
post v3_api("/projects/#{project.id}/trigger/builds"), options.merge(ref: 'master')
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
pipeline.builds.reload
expect(pipeline.builds.pending.size).to eq(2)
expect(pipeline.builds.size).to eq(5)
@@ -54,7 +54,7 @@ describe API::V3::Triggers do
it 'returns bad request with no builds created if there\'s no commit for that ref' do
post v3_api("/projects/#{project.id}/trigger/builds"), options.merge(ref: 'other-branch')
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['message']['base'])
.to contain_exactly('Reference not found')
end
@@ -66,19 +66,19 @@ describe API::V3::Triggers do
it 'validates variables to be a hash' do
post v3_api("/projects/#{project.id}/trigger/builds"), options.merge(variables: 'value', ref: 'master')
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['error']).to eq('variables is invalid')
end
it 'validates variables needs to be a map of key-valued strings' do
post v3_api("/projects/#{project.id}/trigger/builds"), options.merge(variables: { key: %w(1 2) }, ref: 'master')
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['message']).to eq('variables needs to be a map of key-valued strings')
end
it 'creates trigger request with variables' do
post v3_api("/projects/#{project.id}/trigger/builds"), options.merge(variables: variables, ref: 'master')
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
pipeline.builds.reload
expect(pipeline.variables.map { |v| { v.key => v.value } }.first).to eq(variables)
expect(json_response['variables']).to eq(variables)
@@ -91,7 +91,7 @@ describe API::V3::Triggers do
expect do
post v3_api("/projects/#{project.id}/ref/master/trigger/builds?token=#{trigger_token}"), { ref: 'refs/heads/other-branch' }
end.to change(project.builds, :count).by(5)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
end
context 'when ref contains a dot' do
@@ -102,7 +102,7 @@ describe API::V3::Triggers do
post v3_api("/projects/#{project.id}/ref/v.1-branch/trigger/builds?token=#{trigger_token}"), { ref: 'refs/heads/other-branch' }
end.to change(project.builds, :count).by(4)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
end
end
end
@@ -113,7 +113,7 @@ describe API::V3::Triggers do
it 'returns list of triggers' do
get v3_api("/projects/#{project.id}/triggers", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_a(Array)
expect(json_response[0]).to have_key('token')
@@ -124,7 +124,7 @@ describe API::V3::Triggers do
it 'does not return triggers list' do
get v3_api("/projects/#{project.id}/triggers", user2)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -132,7 +132,7 @@ describe API::V3::Triggers do
it 'does not return triggers list' do
get v3_api("/projects/#{project.id}/triggers")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
end
@@ -142,14 +142,14 @@ describe API::V3::Triggers do
it 'returns trigger details' do
get v3_api("/projects/#{project.id}/triggers/#{trigger.token}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_a(Hash)
end
it 'responds with 404 Not Found if requesting non-existing trigger' do
get v3_api("/projects/#{project.id}/triggers/abcdef012345", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -157,7 +157,7 @@ describe API::V3::Triggers do
it 'does not return triggers list' do
get v3_api("/projects/#{project.id}/triggers/#{trigger.token}", user2)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -165,7 +165,7 @@ describe API::V3::Triggers do
it 'does not return triggers list' do
get v3_api("/projects/#{project.id}/triggers/#{trigger.token}")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
end
@@ -177,7 +177,7 @@ describe API::V3::Triggers do
post v3_api("/projects/#{project.id}/triggers", user)
end.to change {project.triggers.count}.by(1)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response).to be_a(Hash)
end
end
@@ -186,7 +186,7 @@ describe API::V3::Triggers do
it 'does not create trigger' do
post v3_api("/projects/#{project.id}/triggers", user2)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -194,7 +194,7 @@ describe API::V3::Triggers do
it 'does not create trigger' do
post v3_api("/projects/#{project.id}/triggers")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
end
@@ -205,14 +205,14 @@ describe API::V3::Triggers do
expect do
delete v3_api("/projects/#{project.id}/triggers/#{trigger.token}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end.to change {project.triggers.count}.by(-1)
end
it 'responds with 404 Not Found if requesting non-existing trigger' do
delete v3_api("/projects/#{project.id}/triggers/abcdef012345", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -220,7 +220,7 @@ describe API::V3::Triggers do
it 'does not delete trigger' do
delete v3_api("/projects/#{project.id}/triggers/#{trigger.token}", user2)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -228,7 +228,7 @@ describe API::V3::Triggers do
it 'does not delete trigger' do
delete v3_api("/projects/#{project.id}/triggers/#{trigger.token}")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
end
diff --git a/spec/requests/api/v3/users_spec.rb b/spec/requests/api/v3/users_spec.rb
index 227b8d1b0c1..bbd05f240d2 100644
--- a/spec/requests/api/v3/users_spec.rb
+++ b/spec/requests/api/v3/users_spec.rb
@@ -12,7 +12,7 @@ describe API::V3::Users do
it 'returns an array of users' do
get v3_api('/users', user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
username = user.username
@@ -45,14 +45,14 @@ describe API::V3::Users do
context 'when unauthenticated' do
it 'returns authentication error' do
get v3_api("/users/#{user.id}/keys")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
context 'when authenticated' do
it 'returns 404 for non-existing user' do
get v3_api('/users/999999/keys', admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 User Not Found')
end
@@ -62,7 +62,7 @@ describe API::V3::Users do
get v3_api("/users/#{user.id}/keys", admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.first['title']).to eq(key.title)
end
@@ -88,14 +88,14 @@ describe API::V3::Users do
context 'when unauthenticated' do
it 'returns authentication error' do
get v3_api("/users/#{user.id}/emails")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
context 'when authenticated' do
it 'returns 404 for non-existing user' do
get v3_api('/users/999999/emails', admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 User Not Found')
end
@@ -105,7 +105,7 @@ describe API::V3::Users do
get v3_api("/users/#{user.id}/emails", admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.first['email']).to eq(email.email)
end
@@ -113,7 +113,7 @@ describe API::V3::Users do
it "returns a 404 for invalid ID" do
put v3_api("/users/ASDF/emails", admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -122,7 +122,7 @@ describe API::V3::Users do
context "when unauthenticated" do
it "returns authentication error" do
get v3_api("/user/keys")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
@@ -133,7 +133,7 @@ describe API::V3::Users do
get v3_api("/user/keys", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.first["title"]).to eq(key.title)
end
@@ -144,7 +144,7 @@ describe API::V3::Users do
context "when unauthenticated" do
it "returns authentication error" do
get v3_api("/user/emails")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
@@ -155,7 +155,7 @@ describe API::V3::Users do
get v3_api("/user/emails", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.first["email"]).to eq(email.email)
end
@@ -166,25 +166,25 @@ describe API::V3::Users do
before { admin }
it 'blocks existing user' do
put v3_api("/users/#{user.id}/block", admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(user.reload.state).to eq('blocked')
end
it 'does not re-block ldap blocked users' do
put v3_api("/users/#{ldap_blocked_user.id}/block", admin)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
expect(ldap_blocked_user.reload.state).to eq('ldap_blocked')
end
it 'does not be available for non admin users' do
put v3_api("/users/#{user.id}/block", user)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
expect(user.reload.state).to eq('active')
end
it 'returns a 404 error if user id not found' do
put v3_api('/users/9999/block', admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 User Not Found')
end
end
@@ -195,38 +195,38 @@ describe API::V3::Users do
it 'unblocks existing user' do
put v3_api("/users/#{user.id}/unblock", admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(user.reload.state).to eq('active')
end
it 'unblocks a blocked user' do
put v3_api("/users/#{blocked_user.id}/unblock", admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(blocked_user.reload.state).to eq('active')
end
it 'does not unblock ldap blocked users' do
put v3_api("/users/#{ldap_blocked_user.id}/unblock", admin)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
expect(ldap_blocked_user.reload.state).to eq('ldap_blocked')
end
it 'does not be available for non admin users' do
put v3_api("/users/#{user.id}/unblock", user)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
expect(user.reload.state).to eq('active')
end
it 'returns a 404 error if user id not found' do
put v3_api('/users/9999/block', admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 User Not Found')
end
it "returns a 404 for invalid ID" do
put v3_api("/users/ASDF/block", admin)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -246,7 +246,7 @@ describe API::V3::Users do
get api("/users/#{user.id}/events", other_user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_empty
end
end
@@ -262,7 +262,7 @@ describe API::V3::Users do
end
it 'responds with HTTP 200 OK' do
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it 'includes the push payload as a Hash' do
@@ -281,7 +281,7 @@ describe API::V3::Users do
it 'returns the "joined" event' do
get v3_api("/users/#{user.id}/events", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
@@ -327,7 +327,7 @@ describe API::V3::Users do
it 'returns a 404 error if not found' do
get v3_api('/users/420/events', user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq('404 User Not Found')
end
end
diff --git a/spec/requests/api/variables_spec.rb b/spec/requests/api/variables_spec.rb
index 48592e12822..79ee6c126f6 100644
--- a/spec/requests/api/variables_spec.rb
+++ b/spec/requests/api/variables_spec.rb
@@ -13,7 +13,7 @@ describe API::Variables do
it 'returns project variables' do
get api("/projects/#{project.id}/variables", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_a(Array)
end
end
@@ -22,7 +22,7 @@ describe API::Variables do
it 'does not return project variables' do
get api("/projects/#{project.id}/variables", user2)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -30,7 +30,7 @@ describe API::Variables do
it 'does not return project variables' do
get api("/projects/#{project.id}/variables")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
end
@@ -40,7 +40,7 @@ describe API::Variables do
it 'returns project variable details' do
get api("/projects/#{project.id}/variables/#{variable.key}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['value']).to eq(variable.value)
expect(json_response['protected']).to eq(variable.protected?)
end
@@ -48,7 +48,7 @@ describe API::Variables do
it 'responds with 404 Not Found if requesting non-existing variable' do
get api("/projects/#{project.id}/variables/non_existing_variable", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -56,7 +56,7 @@ describe API::Variables do
it 'does not return project variable details' do
get api("/projects/#{project.id}/variables/#{variable.key}", user2)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -64,7 +64,7 @@ describe API::Variables do
it 'does not return project variable details' do
get api("/projects/#{project.id}/variables/#{variable.key}")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
end
@@ -76,7 +76,7 @@ describe API::Variables do
post api("/projects/#{project.id}/variables", user), key: 'TEST_VARIABLE_2', value: 'VALUE_2', protected: true
end.to change {project.variables.count}.by(1)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['key']).to eq('TEST_VARIABLE_2')
expect(json_response['value']).to eq('VALUE_2')
expect(json_response['protected']).to be_truthy
@@ -87,7 +87,7 @@ describe API::Variables do
post api("/projects/#{project.id}/variables", user), key: 'TEST_VARIABLE_2', value: 'VALUE_2'
end.to change {project.variables.count}.by(1)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['key']).to eq('TEST_VARIABLE_2')
expect(json_response['value']).to eq('VALUE_2')
expect(json_response['protected']).to be_falsey
@@ -98,7 +98,7 @@ describe API::Variables do
post api("/projects/#{project.id}/variables", user), key: variable.key, value: 'VALUE_2'
end.to change {project.variables.count}.by(0)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
end
@@ -106,7 +106,7 @@ describe API::Variables do
it 'does not create variable' do
post api("/projects/#{project.id}/variables", user2)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -114,7 +114,7 @@ describe API::Variables do
it 'does not create variable' do
post api("/projects/#{project.id}/variables")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
end
@@ -129,7 +129,7 @@ describe API::Variables do
updated_variable = project.variables.first
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(value_before).to eq(variable.value)
expect(updated_variable.value).to eq('VALUE_1_UP')
expect(updated_variable).to be_protected
@@ -138,7 +138,7 @@ describe API::Variables do
it 'responds with 404 Not Found if requesting non-existing variable' do
put api("/projects/#{project.id}/variables/non_existing_variable", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -146,7 +146,7 @@ describe API::Variables do
it 'does not update variable' do
put api("/projects/#{project.id}/variables/#{variable.key}", user2)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -154,7 +154,7 @@ describe API::Variables do
it 'does not update variable' do
put api("/projects/#{project.id}/variables/#{variable.key}")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
end
@@ -165,14 +165,14 @@ describe API::Variables do
expect do
delete api("/projects/#{project.id}/variables/#{variable.key}", user)
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
end.to change {project.variables.count}.by(-1)
end
it 'responds with 404 Not Found if requesting non-existing variable' do
delete api("/projects/#{project.id}/variables/non_existing_variable", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -180,7 +180,7 @@ describe API::Variables do
it 'does not delete variable' do
delete api("/projects/#{project.id}/variables/#{variable.key}", user2)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -188,7 +188,7 @@ describe API::Variables do
it 'does not delete variable' do
delete api("/projects/#{project.id}/variables/#{variable.key}")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
end
diff --git a/spec/requests/api/wikis_spec.rb b/spec/requests/api/wikis_spec.rb
index 9e889d1eecf..65bd001e491 100644
--- a/spec/requests/api/wikis_spec.rb
+++ b/spec/requests/api/wikis_spec.rb
@@ -26,7 +26,7 @@ describe API::Wikis do
it 'returns the list of wiki pages without content' do
get api(url, user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response.size).to eq(2)
json_response.each_with_index do |page, index|
@@ -39,7 +39,7 @@ describe API::Wikis do
it 'returns the list of wiki pages with content' do
get api(url, user), with_content: 1
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response.size).to eq(2)
json_response.each_with_index do |page, index|
@@ -54,14 +54,14 @@ describe API::Wikis do
it 'return the empty list of wiki pages' do
get api(url, user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response.size).to eq(0)
end
end
shared_examples_for 'returns wiki page' do
it 'returns the wiki page' do
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response.size).to eq(4)
expect(json_response.keys).to match_array(expected_keys_with_content)
expect(json_response['content']).to eq(page.content)
@@ -74,7 +74,7 @@ describe API::Wikis do
it 'creates the wiki page' do
post(api(url, user), payload)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response.size).to eq(4)
expect(json_response.keys).to match_array(expected_keys_with_content)
expect(json_response['content']).to eq(payload[:content])
@@ -89,7 +89,7 @@ describe API::Wikis do
post(api(url, user), payload)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response.size).to eq(1)
expect(json_response['error']).to eq("#{part} is missing")
end
@@ -98,7 +98,7 @@ describe API::Wikis do
shared_examples_for 'updates wiki page' do
it 'updates the wiki page' do
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response.size).to eq(4)
expect(json_response.keys).to match_array(expected_keys_with_content)
expect(json_response['content']).to eq(payload[:content])
@@ -109,7 +109,7 @@ describe API::Wikis do
shared_examples_for '403 Forbidden' do
it 'returns 403 Forbidden' do
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
expect(json_response.size).to eq(1)
expect(json_response['message']).to eq('403 Forbidden')
end
@@ -117,7 +117,7 @@ describe API::Wikis do
shared_examples_for '404 Wiki Page Not Found' do
it 'returns 404 Wiki Page Not Found' do
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response.size).to eq(1)
expect(json_response['message']).to eq('404 Wiki Page Not Found')
end
@@ -125,7 +125,7 @@ describe API::Wikis do
shared_examples_for '404 Project Not Found' do
it 'returns 404 Project Not Found' do
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
expect(json_response.size).to eq(1)
expect(json_response['message']).to eq('404 Project Not Found')
end
@@ -133,7 +133,7 @@ describe API::Wikis do
shared_examples_for '204 No Content' do
it 'returns 204 No Content' do
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
end
end
diff --git a/spec/requests/git_http_spec.rb b/spec/requests/git_http_spec.rb
index ecac40e301b..cd52194033a 100644
--- a/spec/requests/git_http_spec.rb
+++ b/spec/requests/git_http_spec.rb
@@ -9,7 +9,7 @@ describe 'Git HTTP requests' do
context "when no credentials are provided" do
it "responds to downloads with status 401 Unauthorized (no project existence information leak)" do
download(path) do |response|
- expect(response).to have_http_status(:unauthorized)
+ expect(response).to have_gitlab_http_status(:unauthorized)
expect(response.header['WWW-Authenticate']).to start_with('Basic ')
end
end
@@ -18,7 +18,7 @@ describe 'Git HTTP requests' do
context "when only username is provided" do
it "responds to downloads with status 401 Unauthorized" do
download(path, user: user.username) do |response|
- expect(response).to have_http_status(:unauthorized)
+ expect(response).to have_gitlab_http_status(:unauthorized)
expect(response.header['WWW-Authenticate']).to start_with('Basic ')
end
end
@@ -28,7 +28,7 @@ describe 'Git HTTP requests' do
context "when authentication fails" do
it "responds to downloads with status 401 Unauthorized" do
download(path, user: user.username, password: "wrong-password") do |response|
- expect(response).to have_http_status(:unauthorized)
+ expect(response).to have_gitlab_http_status(:unauthorized)
expect(response.header['WWW-Authenticate']).to start_with('Basic ')
end
end
@@ -37,7 +37,7 @@ describe 'Git HTTP requests' do
context "when authentication succeeds" do
it "does not respond to downloads with status 401 Unauthorized" do
download(path, user: user.username, password: user.password) do |response|
- expect(response).not_to have_http_status(:unauthorized)
+ expect(response).not_to have_gitlab_http_status(:unauthorized)
expect(response.header['WWW-Authenticate']).to be_nil
end
end
@@ -49,7 +49,7 @@ describe 'Git HTTP requests' do
context "when no credentials are provided" do
it "responds to uploads with status 401 Unauthorized (no project existence information leak)" do
upload(path) do |response|
- expect(response).to have_http_status(:unauthorized)
+ expect(response).to have_gitlab_http_status(:unauthorized)
expect(response.header['WWW-Authenticate']).to start_with('Basic ')
end
end
@@ -58,7 +58,7 @@ describe 'Git HTTP requests' do
context "when only username is provided" do
it "responds to uploads with status 401 Unauthorized" do
upload(path, user: user.username) do |response|
- expect(response).to have_http_status(:unauthorized)
+ expect(response).to have_gitlab_http_status(:unauthorized)
expect(response.header['WWW-Authenticate']).to start_with('Basic ')
end
end
@@ -68,7 +68,7 @@ describe 'Git HTTP requests' do
context "when authentication fails" do
it "responds to uploads with status 401 Unauthorized" do
upload(path, user: user.username, password: "wrong-password") do |response|
- expect(response).to have_http_status(:unauthorized)
+ expect(response).to have_gitlab_http_status(:unauthorized)
expect(response.header['WWW-Authenticate']).to start_with('Basic ')
end
end
@@ -77,7 +77,7 @@ describe 'Git HTTP requests' do
context "when authentication succeeds" do
it "does not respond to uploads with status 401 Unauthorized" do
upload(path, user: user.username, password: user.password) do |response|
- expect(response).not_to have_http_status(:unauthorized)
+ expect(response).not_to have_gitlab_http_status(:unauthorized)
expect(response.header['WWW-Authenticate']).to be_nil
end
end
@@ -88,7 +88,7 @@ describe 'Git HTTP requests' do
shared_examples_for 'pulls are allowed' do
it do
download(path, env) do |response|
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
expect(response.content_type.to_s).to eq(Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE)
end
end
@@ -97,7 +97,7 @@ describe 'Git HTTP requests' do
shared_examples_for 'pushes are allowed' do
it do
upload(path, env) do |response|
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
expect(response.content_type.to_s).to eq(Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE)
end
end
@@ -115,7 +115,7 @@ describe 'Git HTTP requests' do
context 'when authenticated' do
it 'rejects downloads and uploads with 404 Not Found' do
download_or_upload(path, user: user.username, password: user.password) do |response|
- expect(response).to have_http_status(:not_found)
+ expect(response).to have_gitlab_http_status(:not_found)
end
end
end
@@ -165,7 +165,7 @@ describe 'Git HTTP requests' do
it 'rejects pushes with 403 Forbidden' do
upload(path, env) do |response|
- expect(response).to have_http_status(:forbidden)
+ expect(response).to have_gitlab_http_status(:forbidden)
expect(response.body).to eq(git_access_wiki_error(:write_to_wiki))
end
end
@@ -190,13 +190,13 @@ describe 'Git HTTP requests' do
it 'allows clones' do
download(path, user: user.username, password: user.password) do |response|
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
end
end
it 'pushes are allowed' do
upload(path, user: user.username, password: user.password) do |response|
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
end
end
end
@@ -205,14 +205,14 @@ describe 'Git HTTP requests' do
context 'and not on the team' do
it 'rejects clones with 404 Not Found' do
download(path, user: user.username, password: user.password) do |response|
- expect(response).to have_http_status(:not_found)
+ expect(response).to have_gitlab_http_status(:not_found)
expect(response.body).to eq(git_access_error(:project_not_found))
end
end
it 'rejects pushes with 404 Not Found' do
upload(path, user: user.username, password: user.password) do |response|
- expect(response).to have_http_status(:not_found)
+ expect(response).to have_gitlab_http_status(:not_found)
expect(response.body).to eq(git_access_error(:project_not_found))
end
end
@@ -253,7 +253,7 @@ describe 'Git HTTP requests' do
it 'rejects pushes with 403 Forbidden' do
upload(path, env) do |response|
- expect(response).to have_http_status(:forbidden)
+ expect(response).to have_gitlab_http_status(:forbidden)
expect(response.body).to eq(git_access_error(:receive_pack_disabled_over_http))
end
end
@@ -264,7 +264,7 @@ describe 'Git HTTP requests' do
allow(Gitlab.config.gitlab_shell).to receive(:upload_pack).and_return(false)
download(path, env) do |response|
- expect(response).to have_http_status(:forbidden)
+ expect(response).to have_gitlab_http_status(:forbidden)
expect(response.body).to eq(git_access_error(:upload_pack_disabled_over_http))
end
end
@@ -276,7 +276,7 @@ describe 'Git HTTP requests' do
it 'rejects pushes with 403 Forbidden' do
upload(path, env) do |response|
- expect(response).to have_http_status(:forbidden)
+ expect(response).to have_gitlab_http_status(:forbidden)
expect(response.body).to eq(change_access_error(:push_code))
end
end
@@ -332,7 +332,7 @@ describe 'Git HTTP requests' do
it 'downloads get status 404 with "project was moved" message' do
clone_get(path, {})
- expect(response).to have_http_status(:not_found)
+ expect(response).to have_gitlab_http_status(:not_found)
expect(response.body).to match(project_moved_message)
end
end
@@ -355,7 +355,7 @@ describe 'Git HTTP requests' do
clone_get(path, env)
- expect(response).to have_http_status(:unauthorized)
+ expect(response).to have_gitlab_http_status(:unauthorized)
end
end
end
@@ -374,7 +374,7 @@ describe 'Git HTTP requests' do
project.team << [user, :master]
download(path, env) do |response|
- expect(response).to have_http_status(:unauthorized)
+ expect(response).to have_gitlab_http_status(:unauthorized)
end
end
@@ -382,7 +382,7 @@ describe 'Git HTTP requests' do
user.block
download('doesnt/exist.git', env) do |response|
- expect(response).to have_http_status(:unauthorized)
+ expect(response).to have_gitlab_http_status(:unauthorized)
end
end
end
@@ -392,7 +392,7 @@ describe 'Git HTTP requests' do
expect(Rack::Attack::Allow2Ban).to receive(:reset).twice
download(path, env) do
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
expect(response.content_type.to_s).to eq(Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE)
end
end
@@ -401,7 +401,7 @@ describe 'Git HTTP requests' do
expect(Rack::Attack::Allow2Ban).to receive(:reset).twice
upload(path, env) do
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
expect(response.content_type.to_s).to eq(Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE)
end
end
@@ -440,14 +440,14 @@ describe 'Git HTTP requests' do
context 'when username and password are provided' do
it 'rejects pulls with personal access token error message' do
download(path, user: user.username, password: user.password) do |response|
- expect(response).to have_http_status(:unauthorized)
+ expect(response).to have_gitlab_http_status(:unauthorized)
expect(response.body).to include('You must use a personal access token with \'api\' scope for Git over HTTP')
end
end
it 'rejects the push attempt with personal access token error message' do
upload(path, user: user.username, password: user.password) do |response|
- expect(response).to have_http_status(:unauthorized)
+ expect(response).to have_gitlab_http_status(:unauthorized)
expect(response.body).to include('You must use a personal access token with \'api\' scope for Git over HTTP')
end
end
@@ -468,14 +468,14 @@ describe 'Git HTTP requests' do
it 'rejects pulls with personal access token error message' do
download(path, user: 'foo', password: 'bar') do |response|
- expect(response).to have_http_status(:unauthorized)
+ expect(response).to have_gitlab_http_status(:unauthorized)
expect(response.body).to include('You must use a personal access token with \'api\' scope for Git over HTTP')
end
end
it 'rejects pushes with personal access token error message' do
upload(path, user: 'foo', password: 'bar') do |response|
- expect(response).to have_http_status(:unauthorized)
+ expect(response).to have_gitlab_http_status(:unauthorized)
expect(response.body).to include('You must use a personal access token with \'api\' scope for Git over HTTP')
end
end
@@ -489,7 +489,7 @@ describe 'Git HTTP requests' do
it 'does not display the personal access token error message' do
upload(path, user: 'foo', password: 'bar') do |response|
- expect(response).to have_http_status(:unauthorized)
+ expect(response).to have_gitlab_http_status(:unauthorized)
expect(response.body).not_to include('You must use a personal access token with \'api\' scope for Git over HTTP')
end
end
@@ -541,13 +541,13 @@ describe 'Git HTTP requests' do
it 'downloads get status 404 with "project was moved" message' do
clone_get(path, env)
- expect(response).to have_http_status(:not_found)
+ expect(response).to have_gitlab_http_status(:not_found)
expect(response.body).to match(project_moved_message)
end
it 'uploads get status 404 with "project was moved" message' do
upload(path, env) do |response|
- expect(response).to have_http_status(:not_found)
+ expect(response).to have_gitlab_http_status(:not_found)
expect(response.body).to match(project_moved_message)
end
end
@@ -557,13 +557,13 @@ describe 'Git HTTP requests' do
context "when the user doesn't have access to the project" do
it "pulls get status 404" do
download(path, user: user.username, password: user.password) do |response|
- expect(response).to have_http_status(:not_found)
+ expect(response).to have_gitlab_http_status(:not_found)
end
end
it "uploads get status 404" do
upload(path, user: user.username, password: user.password) do |response|
- expect(response).to have_http_status(:not_found)
+ expect(response).to have_gitlab_http_status(:not_found)
end
end
end
@@ -595,7 +595,7 @@ describe 'Git HTTP requests' do
it "rejects pushes with 403 Forbidden" do
push_get(path, env)
- expect(response).to have_http_status(:forbidden)
+ expect(response).to have_gitlab_http_status(:forbidden)
expect(response.body).to eq(git_access_error(:upload))
end
@@ -604,7 +604,7 @@ describe 'Git HTTP requests' do
it "rejects pulls for other project with 404 Not Found" do
clone_get("#{other_project.full_path}.git", env)
- expect(response).to have_http_status(:not_found)
+ expect(response).to have_gitlab_http_status(:not_found)
expect(response.body).to eq(git_access_error(:project_not_found))
end
end
@@ -627,7 +627,7 @@ describe 'Git HTTP requests' do
it 'rejects pulls with 403 Forbidden' do
clone_get path, env
- expect(response).to have_http_status(:forbidden)
+ expect(response).to have_gitlab_http_status(:forbidden)
expect(response.body).to eq(git_access_error(:no_repo))
end
end
@@ -635,7 +635,7 @@ describe 'Git HTTP requests' do
it 'rejects pushes with 403 Forbidden' do
push_get path, env
- expect(response).to have_http_status(:forbidden)
+ expect(response).to have_gitlab_http_status(:forbidden)
expect(response.body).to eq(git_access_error(:upload))
end
end
@@ -648,7 +648,7 @@ describe 'Git HTTP requests' do
it 'downloads from other project get status 403' do
clone_get "#{other_project.full_path}.git", user: 'gitlab-ci-token', password: build.token
- expect(response).to have_http_status(:forbidden)
+ expect(response).to have_gitlab_http_status(:forbidden)
end
end
@@ -660,7 +660,7 @@ describe 'Git HTTP requests' do
it 'downloads from other project get status 404' do
clone_get "#{other_project.full_path}.git", user: 'gitlab-ci-token', password: build.token
- expect(response).to have_http_status(:not_found)
+ expect(response).to have_gitlab_http_status(:not_found)
end
end
end
@@ -748,7 +748,7 @@ describe 'Git HTTP requests' do
end
it "returns the file" do
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
end
end
@@ -758,7 +758,7 @@ describe 'Git HTTP requests' do
end
it "returns not found" do
- expect(response).to have_http_status(:not_found)
+ expect(response).to have_gitlab_http_status(:not_found)
end
end
end
@@ -783,7 +783,7 @@ describe 'Git HTTP requests' do
context "when the project doesn't exist" do
it "responds with status 404 Not Found" do
download(path, user: user.username, password: user.password) do |response|
- expect(response).to have_http_status(:not_found)
+ expect(response).to have_gitlab_http_status(:not_found)
end
end
end
@@ -800,7 +800,7 @@ describe 'Git HTTP requests' do
it "responds with status 200" do
clone_get(path, env) do |response|
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
end
diff --git a/spec/requests/jwt_controller_spec.rb b/spec/requests/jwt_controller_spec.rb
index 41bf43a9bce..94e04ce5608 100644
--- a/spec/requests/jwt_controller_spec.rb
+++ b/spec/requests/jwt_controller_spec.rb
@@ -13,12 +13,12 @@ describe JwtController do
context 'existing service' do
subject! { get '/jwt/auth', parameters }
- it { expect(response).to have_http_status(200) }
+ it { expect(response).to have_gitlab_http_status(200) }
context 'returning custom http code' do
let(:service) { double(execute: { http_status: 505 }) }
- it { expect(response).to have_http_status(505) }
+ it { expect(response).to have_gitlab_http_status(505) }
end
end
@@ -41,7 +41,7 @@ describe JwtController do
subject! { get '/jwt/auth', parameters, headers }
- it { expect(response).to have_http_status(401) }
+ it { expect(response).to have_gitlab_http_status(401) }
end
context 'using personal access tokens' do
@@ -56,7 +56,7 @@ describe JwtController do
subject! { get '/jwt/auth', parameters, headers }
it 'authenticates correctly' do
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(service_class).to have_received(:new).with(nil, user, parameters)
end
end
@@ -75,7 +75,7 @@ describe JwtController do
context 'without personal token' do
it 'rejects the authorization attempt' do
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
expect(response.body).to include('You must use a personal access token with \'api\' scope for Git over HTTP')
end
end
@@ -85,7 +85,7 @@ describe JwtController do
let(:headers) { { authorization: credentials(user.username, access_token.token) } }
it 'accepts the authorization attempt' do
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
end
end
@@ -98,7 +98,7 @@ describe JwtController do
it 'rejects the authorization attempt' do
get '/jwt/auth', parameters, headers
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
expect(response.body).not_to include('You must use a personal access token with \'api\' scope for Git over HTTP')
end
end
@@ -108,7 +108,7 @@ describe JwtController do
allow_any_instance_of(ApplicationSetting).to receive(:password_authentication_enabled?) { false }
get '/jwt/auth', parameters, headers
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
expect(response.body).to include('You must use a personal access token with \'api\' scope for Git over HTTP')
end
end
@@ -119,7 +119,7 @@ describe JwtController do
it 'accepts the authorization attempt' do
get '/jwt/auth', parameters
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it 'allows read access' do
@@ -132,7 +132,7 @@ describe JwtController do
context 'unknown service' do
subject! { get '/jwt/auth', service: 'unknown' }
- it { expect(response).to have_http_status(404) }
+ it { expect(response).to have_gitlab_http_status(404) }
end
def credentials(login, password)
diff --git a/spec/requests/lfs_http_spec.rb b/spec/requests/lfs_http_spec.rb
index bca5bf81c5c..52e93e157f1 100644
--- a/spec/requests/lfs_http_spec.rb
+++ b/spec/requests/lfs_http_spec.rb
@@ -41,7 +41,7 @@ describe 'Git LFS API and storage' do
end
it 'responds with 501' do
- expect(response).to have_http_status(501)
+ expect(response).to have_gitlab_http_status(501)
expect(json_response).to include('message' => 'Git LFS is not enabled on this GitLab server, contact your admin.')
end
end
@@ -75,13 +75,13 @@ describe 'Git LFS API and storage' do
it 'responds with a 501 message on upload' do
post_lfs_json "#{project.http_url_to_repo}/info/lfs/objects/batch", body, headers
- expect(response).to have_http_status(501)
+ expect(response).to have_gitlab_http_status(501)
end
it 'responds with a 501 message on download' do
get "#{project.http_url_to_repo}/gitlab-lfs/objects/#{sample_oid}", nil, headers
- expect(response).to have_http_status(501)
+ expect(response).to have_gitlab_http_status(501)
end
end
@@ -93,13 +93,13 @@ describe 'Git LFS API and storage' do
it 'responds with a 501 message on upload' do
post_lfs_json "#{project.http_url_to_repo}/info/lfs/objects/batch", body, headers
- expect(response).to have_http_status(501)
+ expect(response).to have_gitlab_http_status(501)
end
it 'responds with a 501 message on download' do
get "#{project.http_url_to_repo}/gitlab-lfs/objects/#{sample_oid}", nil, headers
- expect(response).to have_http_status(501)
+ expect(response).to have_gitlab_http_status(501)
end
end
end
@@ -118,14 +118,14 @@ describe 'Git LFS API and storage' do
it 'responds with a 403 message on upload' do
post_lfs_json "#{project.http_url_to_repo}/info/lfs/objects/batch", body, headers
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
expect(json_response).to include('message' => 'Access forbidden. Check your access level.')
end
it 'responds with a 403 message on download' do
get "#{project.http_url_to_repo}/gitlab-lfs/objects/#{sample_oid}", nil, headers
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
expect(json_response).to include('message' => 'Access forbidden. Check your access level.')
end
end
@@ -138,14 +138,14 @@ describe 'Git LFS API and storage' do
it 'responds with a 200 message on upload' do
post_lfs_json "#{project.http_url_to_repo}/info/lfs/objects/batch", body, headers
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['objects'].first['size']).to eq(1575078)
end
it 'responds with a 200 message on download' do
get "#{project.http_url_to_repo}/gitlab-lfs/objects/#{sample_oid}", nil, headers
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
end
end
@@ -160,7 +160,7 @@ describe 'Git LFS API and storage' do
shared_examples 'a deprecated' do
it 'responds with 501' do
- expect(response).to have_http_status(501)
+ expect(response).to have_gitlab_http_status(501)
end
it 'returns deprecated message' do
@@ -201,7 +201,7 @@ describe 'Git LFS API and storage' do
context 'and request comes from gitlab-workhorse' do
context 'without user being authorized' do
it 'responds with status 401' do
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
@@ -210,7 +210,7 @@ describe 'Git LFS API and storage' do
let(:sendfile) { 'X-Sendfile' }
it 'responds with status 200' do
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it 'responds with the file location' do
@@ -228,7 +228,7 @@ describe 'Git LFS API and storage' do
end
it 'responds with status 404' do
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -272,7 +272,7 @@ describe 'Git LFS API and storage' do
end
it 'responds with status 404' do
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -311,7 +311,7 @@ describe 'Git LFS API and storage' do
end
it 'rejects downloading code' do
- expect(response).to have_http_status(other_project_status)
+ expect(response).to have_gitlab_http_status(other_project_status)
end
end
end
@@ -351,7 +351,7 @@ describe 'Git LFS API and storage' do
let(:authorization) { authorize_user }
it 'responds with status 404' do
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -387,7 +387,7 @@ describe 'Git LFS API and storage' do
end
it 'responds with status 200' do
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it 'with href to download' do
@@ -415,7 +415,7 @@ describe 'Git LFS API and storage' do
end
it 'responds with status 200' do
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it 'with href to download' do
@@ -446,7 +446,7 @@ describe 'Git LFS API and storage' do
end
it 'responds with status 200' do
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it 'with an 404 for specific object' do
@@ -483,7 +483,7 @@ describe 'Git LFS API and storage' do
end
it 'responds with status 200' do
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it 'responds with upload hypermedia link for the new object' do
@@ -528,7 +528,7 @@ describe 'Git LFS API and storage' do
let(:update_user_permissions) { nil }
it 'responds with 404' do
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -536,7 +536,7 @@ describe 'Git LFS API and storage' do
let(:role) { :guest }
it 'responds with 403' do
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
end
@@ -564,7 +564,7 @@ describe 'Git LFS API and storage' do
let(:pipeline) { create(:ci_empty_pipeline, project: other_project) }
it 'rejects downloading code' do
- expect(response).to have_http_status(other_project_status)
+ expect(response).to have_gitlab_http_status(other_project_status)
end
end
end
@@ -608,7 +608,7 @@ describe 'Git LFS API and storage' do
end
it 'responds with status 200 and href to download' do
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it 'responds with status 200 and href to download' do
@@ -636,7 +636,7 @@ describe 'Git LFS API and storage' do
end
it 'responds with authorization required' do
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
end
@@ -669,7 +669,7 @@ describe 'Git LFS API and storage' do
end
it 'responds with status 200' do
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it 'responds with links the object to the project' do
@@ -695,7 +695,7 @@ describe 'Git LFS API and storage' do
end
it 'responds with status 200' do
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it 'responds with upload hypermedia link' do
@@ -725,7 +725,7 @@ describe 'Git LFS API and storage' do
end
it 'responds with status 200' do
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it 'responds with upload hypermedia link for the new object' do
@@ -747,7 +747,7 @@ describe 'Git LFS API and storage' do
let(:authorization) { authorize_user }
it 'responds with 403' do
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -761,7 +761,7 @@ describe 'Git LFS API and storage' do
let(:build) { create(:ci_build, :running, pipeline: pipeline, user: user) }
it 'responds with 403 (not 404 because project is public)' do
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -772,7 +772,7 @@ describe 'Git LFS API and storage' do
# I'm not sure what this tests that is different from the previous test
it 'responds with 403 (not 404 because project is public)' do
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
end
@@ -781,7 +781,7 @@ describe 'Git LFS API and storage' do
let(:build) { create(:ci_build, :running, pipeline: pipeline) }
it 'responds with 403 (not 404 because project is public)' do
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
end
@@ -794,13 +794,13 @@ describe 'Git LFS API and storage' do
end
it 'responds with status 401' do
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
context 'when user does not have push access' do
it 'responds with status 401' do
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
end
@@ -820,7 +820,7 @@ describe 'Git LFS API and storage' do
end
it 'responds with status 404' do
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -865,7 +865,7 @@ describe 'Git LFS API and storage' do
end
it 'responds with status 401' do
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
@@ -875,7 +875,7 @@ describe 'Git LFS API and storage' do
end
it 'responds with status 401' do
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
@@ -885,7 +885,7 @@ describe 'Git LFS API and storage' do
end
it 'does not recognize it as a valid lfs command' do
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
end
@@ -897,7 +897,7 @@ describe 'Git LFS API and storage' do
end
it 'responds with 403' do
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -907,7 +907,7 @@ describe 'Git LFS API and storage' do
end
it 'responds with 403' do
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -917,7 +917,7 @@ describe 'Git LFS API and storage' do
end
it 'does not recognize it as a valid lfs command' do
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
end
@@ -945,7 +945,7 @@ describe 'Git LFS API and storage' do
end
it 'responds with status 200' do
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it 'uses the gitlab-workhorse content type' do
@@ -965,7 +965,7 @@ describe 'Git LFS API and storage' do
end
it 'responds with status 200' do
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it 'lfs object is linked to the project' do
@@ -976,12 +976,12 @@ describe 'Git LFS API and storage' do
context 'invalid tempfiles' do
it 'rejects slashes in the tempfile name (path traversal' do
put_finalize('foo/bar')
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
it 'rejects tempfile names that do not start with the oid' do
put_finalize("foo#{sample_oid}")
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
end
@@ -1010,7 +1010,7 @@ describe 'Git LFS API and storage' do
end
it 'responds with 403 (not 404 because the build user can read the project)' do
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -1024,7 +1024,7 @@ describe 'Git LFS API and storage' do
end
it 'responds with 404 (do not leak non-public project existence)' do
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -1037,7 +1037,7 @@ describe 'Git LFS API and storage' do
end
it 'responds with 404 (do not leak non-public project existence)' do
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -1066,7 +1066,7 @@ describe 'Git LFS API and storage' do
end
it 'responds with status 200' do
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it 'with location of lfs store and object details' do
@@ -1082,7 +1082,7 @@ describe 'Git LFS API and storage' do
end
it 'responds with status 200' do
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it 'lfs object is linked to the source project' do
@@ -1110,7 +1110,7 @@ describe 'Git LFS API and storage' do
let(:build) { create(:ci_build, :running, pipeline: pipeline, user: user) }
it 'responds with 403 (not 404 because project is public)' do
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -1121,7 +1121,7 @@ describe 'Git LFS API and storage' do
# I'm not sure what this tests that is different from the previous test
it 'responds with 403 (not 404 because project is public)' do
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
end
@@ -1130,7 +1130,7 @@ describe 'Git LFS API and storage' do
let(:build) { create(:ci_build, :running, pipeline: pipeline) }
it 'responds with 403 (not 404 because project is public)' do
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
end
@@ -1155,7 +1155,7 @@ describe 'Git LFS API and storage' do
end
it 'responds with status 200' do
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it 'links the lfs object to the project' do
diff --git a/spec/requests/openid_connect_spec.rb b/spec/requests/openid_connect_spec.rb
index a927de952d0..0b1f8ce6f6d 100644
--- a/spec/requests/openid_connect_spec.rb
+++ b/spec/requests/openid_connect_spec.rb
@@ -37,7 +37,7 @@ describe 'OpenID Connect requests' do
it 'userinfo response is unauthorized' do
request_user_info
- expect(response).to have_http_status 403
+ expect(response).to have_gitlab_http_status 403
expect(response.body).to be_blank
end
end
diff --git a/spec/requests/projects/cycle_analytics_events_spec.rb b/spec/requests/projects/cycle_analytics_events_spec.rb
index 6667ce771bd..286d8a884a4 100644
--- a/spec/requests/projects/cycle_analytics_events_spec.rb
+++ b/spec/requests/projects/cycle_analytics_events_spec.rb
@@ -99,19 +99,19 @@ describe 'cycle analytics events' do
it 'does not list the test events' do
get project_cycle_analytics_test_path(project, format: :json)
- expect(response).to have_http_status(:not_found)
+ expect(response).to have_gitlab_http_status(:not_found)
end
it 'does not list the staging events' do
get project_cycle_analytics_staging_path(project, format: :json)
- expect(response).to have_http_status(:not_found)
+ expect(response).to have_gitlab_http_status(:not_found)
end
it 'lists the issue events' do
get project_cycle_analytics_issue_path(project, format: :json)
- expect(response).to have_http_status(:ok)
+ expect(response).to have_gitlab_http_status(:ok)
end
end
end
diff --git a/spec/routing/project_routing_spec.rb b/spec/routing/project_routing_spec.rb
index 39d44245c3f..fb1281a6b42 100644
--- a/spec/routing/project_routing_spec.rb
+++ b/spec/routing/project_routing_spec.rb
@@ -426,18 +426,23 @@ describe 'project routing' do
end
end
- # project_milestones GET /:project_id/milestones(.:format) milestones#index
- # POST /:project_id/milestones(.:format) milestones#create
- # new_project_milestone GET /:project_id/milestones/new(.:format) milestones#new
- # edit_project_milestone GET /:project_id/milestones/:id/edit(.:format) milestones#edit
- # project_milestone GET /:project_id/milestones/:id(.:format) milestones#show
- # PUT /:project_id/milestones/:id(.:format) milestones#update
- # DELETE /:project_id/milestones/:id(.:format) milestones#destroy
+ # project_milestones GET /:project_id/milestones(.:format) milestones#index
+ # POST /:project_id/milestones(.:format) milestones#create
+ # new_project_milestone GET /:project_id/milestones/new(.:format) milestones#new
+ # edit_project_milestone GET /:project_id/milestones/:id/edit(.:format) milestones#edit
+ # project_milestone GET /:project_id/milestones/:id(.:format) milestones#show
+ # PUT /:project_id/milestones/:id(.:format) milestones#update
+ # DELETE /:project_id/milestones/:id(.:format) milestones#destroy
+ # promote_project_milestone POST /:project_id/milestones/:id/promote milestones#promote
describe Projects::MilestonesController, 'routing' do
it_behaves_like 'RESTful project resources' do
let(:controller) { 'milestones' }
let(:actions) { [:index, :create, :new, :edit, :show, :update] }
end
+
+ it 'to #promote' do
+ expect(post('/gitlab/gitlabhq/milestones/1/promote')).to route_to('projects/milestones#promote', namespace_id: 'gitlab', project_id: 'gitlabhq', id: "1")
+ end
end
# project_labels GET /:project_id/labels(.:format) labels#index
diff --git a/spec/routing/routing_spec.rb b/spec/routing/routing_spec.rb
index a45839b16f5..407d19c3b2a 100644
--- a/spec/routing/routing_spec.rb
+++ b/spec/routing/routing_spec.rb
@@ -285,17 +285,15 @@ end
describe "Groups", "routing" do
let(:name) { 'complex.group-namegit' }
-
- before do
- allow_any_instance_of(GroupUrlConstrainer).to receive(:matches?).and_return(true)
- end
+ let!(:group) { create(:group, name: name) }
it "to #show" do
expect(get("/groups/#{name}")).to route_to('groups#show', id: name)
end
it "also supports nested groups" do
- expect(get("/#{name}/#{name}")).to route_to('groups#show', id: "#{name}/#{name}")
+ nested_group = create(:group, parent: group)
+ expect(get("/#{name}/#{nested_group.name}")).to route_to('groups#show', id: "#{name}/#{nested_group.name}")
end
it "also display group#show on the short path" do
@@ -313,10 +311,6 @@ describe "Groups", "routing" do
it "to #members" do
expect(get("/groups/#{name}/group_members")).to route_to('groups/group_members#index', group_id: name)
end
-
- it "also display group#show with slash in the path" do
- expect(get('/group/subgroup')).to route_to('groups#show', id: 'group/subgroup')
- end
end
describe HealthCheckController, 'routing' do
diff --git a/spec/serializers/issue_serializer_spec.rb b/spec/serializers/issue_serializer_spec.rb
new file mode 100644
index 00000000000..75578816e75
--- /dev/null
+++ b/spec/serializers/issue_serializer_spec.rb
@@ -0,0 +1,27 @@
+require 'spec_helper'
+
+describe IssueSerializer do
+ let(:resource) { create(:issue) }
+ let(:user) { create(:user) }
+ let(:json_entity) do
+ described_class.new(current_user: user)
+ .represent(resource, serializer: serializer)
+ .with_indifferent_access
+ end
+
+ context 'non-sidebar issue serialization' do
+ let(:serializer) { nil }
+
+ it 'matches issue json schema' do
+ expect(json_entity).to match_schema('entities/issue')
+ end
+ end
+
+ context 'sidebar issue serialization' do
+ let(:serializer) { 'sidebar' }
+
+ it 'matches sidebar issue json schema' do
+ expect(json_entity).to match_schema('entities/issue_sidebar')
+ end
+ end
+end
diff --git a/spec/serializers/merge_request_basic_serializer_spec.rb b/spec/serializers/merge_request_basic_serializer_spec.rb
index 4daf5a59d0c..1fad8e6bc5d 100644
--- a/spec/serializers/merge_request_basic_serializer_spec.rb
+++ b/spec/serializers/merge_request_basic_serializer_spec.rb
@@ -4,9 +4,13 @@ describe MergeRequestBasicSerializer do
let(:resource) { create(:merge_request) }
let(:user) { create(:user) }
- subject { described_class.new.represent(resource) }
+ let(:json_entity) do
+ described_class.new(current_user: user)
+ .represent(resource, serializer: 'basic')
+ .with_indifferent_access
+ end
- it 'has important MergeRequest attributes' do
- expect(subject).to include(:merge_status)
+ it 'matches basic merge request json' do
+ expect(json_entity).to match_schema('entities/merge_request_basic')
end
end
diff --git a/spec/serializers/merge_request_serializer_spec.rb b/spec/serializers/merge_request_serializer_spec.rb
index 73fbecc153d..e3abefa6d63 100644
--- a/spec/serializers/merge_request_serializer_spec.rb
+++ b/spec/serializers/merge_request_serializer_spec.rb
@@ -9,11 +9,11 @@ describe MergeRequestSerializer do
end
describe '#represent' do
- let(:opts) { { basic: basic } }
- subject { serializer.represent(merge_request, basic: basic) }
+ let(:opts) { { serializer: serializer_entity } }
+ subject { serializer.represent(merge_request, serializer: serializer_entity) }
- context 'when basic param is truthy' do
- let(:basic) { true }
+ context 'when passing basic serializer param' do
+ let(:serializer_entity) { 'basic' }
it 'calls super class #represent with correct params' do
expect_any_instance_of(BaseSerializer).to receive(:represent)
@@ -23,8 +23,8 @@ describe MergeRequestSerializer do
end
end
- context 'when basic param is falsy' do
- let(:basic) { false }
+ context 'when serializer param is falsy' do
+ let(:serializer_entity) { nil }
it 'calls super class #represent with correct params' do
expect_any_instance_of(BaseSerializer).to receive(:represent)
diff --git a/spec/services/merge_requests/merge_service_spec.rb b/spec/services/merge_requests/merge_service_spec.rb
index d1043f99b5a..ac196e92601 100644
--- a/spec/services/merge_requests/merge_service_spec.rb
+++ b/spec/services/merge_requests/merge_service_spec.rb
@@ -12,55 +12,6 @@ describe MergeRequests::MergeService do
end
describe '#execute' do
- context 'MergeRequest#merge_jid' do
- let(:service) do
- described_class.new(project, user, commit_message: 'Awesome message')
- end
-
- before do
- merge_request.update_column(:merge_jid, 'hash-123')
- end
-
- it 'is cleaned when no error is raised' do
- service.execute(merge_request)
-
- expect(merge_request.reload.merge_jid).to be_nil
- end
-
- it 'is cleaned when expected error is raised' do
- allow(service).to receive(:commit).and_raise(described_class::MergeError)
-
- service.execute(merge_request)
-
- expect(merge_request.reload.merge_jid).to be_nil
- end
-
- it 'is cleaned when merge request is not mergeable' do
- allow(merge_request).to receive(:mergeable?).and_return(false)
-
- service.execute(merge_request)
-
- expect(merge_request.reload.merge_jid).to be_nil
- end
-
- it 'is cleaned when no source is found' do
- allow(merge_request).to receive(:diff_head_sha).and_return(nil)
-
- service.execute(merge_request)
-
- expect(merge_request.reload.merge_jid).to be_nil
- end
-
- it 'is not cleaned when unexpected error is raised' do
- service = described_class.new(project, user, commit_message: 'Awesome message')
- allow(service).to receive(:commit).and_raise(StandardError)
-
- expect { service.execute(merge_request) }.to raise_error(StandardError)
-
- expect(merge_request.reload.merge_jid).to be_present
- end
- end
-
context 'valid params' do
let(:service) { described_class.new(project, user, commit_message: 'Awesome message') }
diff --git a/spec/services/milestones/promote_service_spec.rb b/spec/services/milestones/promote_service_spec.rb
new file mode 100644
index 00000000000..9f2df6d6d19
--- /dev/null
+++ b/spec/services/milestones/promote_service_spec.rb
@@ -0,0 +1,77 @@
+require 'spec_helper'
+
+describe Milestones::PromoteService do
+ let(:group) { create(:group) }
+ let(:project) { create(:project, namespace: group) }
+ let(:user) { create(:user) }
+ let(:milestone_title) { 'project milestone' }
+ let(:milestone) { create(:milestone, project: project, title: milestone_title) }
+ let(:service) { described_class.new(project, user) }
+
+ describe '#execute' do
+ before do
+ group.add_master(user)
+ end
+
+ context 'validations' do
+ it 'raises error if milestone does not belong to a project' do
+ allow(milestone).to receive(:project_milestone?).and_return(false)
+
+ expect { service.execute(milestone) }.to raise_error(described_class::PromoteMilestoneError)
+ end
+
+ it 'raises error if project does not belong to a group' do
+ project.update(namespace: user.namespace)
+
+ expect { service.execute(milestone) }.to raise_error(described_class::PromoteMilestoneError)
+ end
+ end
+
+ context 'without duplicated milestone titles across projects' do
+ it 'promotes project milestone to group milestone' do
+ promoted_milestone = service.execute(milestone)
+
+ expect(promoted_milestone).to be_group_milestone
+ end
+
+ it 'sets issuables with new promoted milestone' do
+ issue = create(:issue, milestone: milestone, project: project)
+ merge_request = create(:merge_request, milestone: milestone, source_project: project)
+
+ promoted_milestone = service.execute(milestone)
+
+ expect(promoted_milestone).to be_group_milestone
+ expect(issue.reload.milestone).to eq(promoted_milestone)
+ expect(merge_request.reload.milestone).to eq(promoted_milestone)
+ end
+ end
+
+ context 'with duplicated milestone titles across projects' do
+ let(:project_2) { create(:project, namespace: group) }
+ let!(:milestone_2) { create(:milestone, project: project_2, title: milestone_title) }
+
+ it 'deletes project milestones with the same title' do
+ promoted_milestone = service.execute(milestone)
+
+ expect(promoted_milestone).to be_group_milestone
+ expect(promoted_milestone).to be_valid
+ expect(Milestone.exists?(milestone.id)).to be_falsy
+ expect(Milestone.exists?(milestone_2.id)).to be_falsy
+ end
+
+ it 'sets all issuables with new promoted milestone' do
+ issue = create(:issue, milestone: milestone, project: project)
+ issue_2 = create(:issue, milestone: milestone_2, project: project_2)
+ merge_request = create(:merge_request, milestone: milestone, source_project: project)
+ merge_request_2 = create(:merge_request, milestone: milestone_2, source_project: project_2)
+
+ promoted_milestone = service.execute(milestone)
+
+ expect(issue.reload.milestone).to eq(promoted_milestone)
+ expect(issue_2.reload.milestone).to eq(promoted_milestone)
+ expect(merge_request.reload.milestone).to eq(promoted_milestone)
+ expect(merge_request_2.reload.milestone).to eq(promoted_milestone)
+ end
+ end
+ end
+end
diff --git a/spec/services/projects/hashed_storage_migration_service_spec.rb b/spec/services/projects/hashed_storage_migration_service_spec.rb
index aa1988d29d6..b71b47c59b6 100644
--- a/spec/services/projects/hashed_storage_migration_service_spec.rb
+++ b/spec/services/projects/hashed_storage_migration_service_spec.rb
@@ -23,7 +23,7 @@ describe Projects::HashedStorageMigrationService do
it 'updates project to be hashed and not read-only' do
service.execute
- expect(project.hashed_storage?).to be_truthy
+ expect(project.hashed_storage?(:repository)).to be_truthy
expect(project.repository_read_only).to be_falsey
end
diff --git a/spec/services/system_hooks_service_spec.rb b/spec/services/system_hooks_service_spec.rb
index 8b5d9187785..8f7aea533dc 100644
--- a/spec/services/system_hooks_service_spec.rb
+++ b/spec/services/system_hooks_service_spec.rb
@@ -63,6 +63,12 @@ describe SystemHooksService do
:group_id, :user_id, :user_username, :user_name, :user_email, :group_access
)
end
+
+ it 'includes the correct project visibility level' do
+ data = event_data(project, :create)
+
+ expect(data[:project_visibility]).to eq('private')
+ end
end
context 'event names' do
diff --git a/spec/services/users/last_push_event_service_spec.rb b/spec/services/users/last_push_event_service_spec.rb
index 956358738fe..2b6c0267a0f 100644
--- a/spec/services/users/last_push_event_service_spec.rb
+++ b/spec/services/users/last_push_event_service_spec.rb
@@ -22,7 +22,6 @@ describe Users::LastPushEventService do
it 'caches the event for the origin project when pushing to a fork' do
source = build(:project, id: 5)
- allow(project).to receive(:forked?).and_return(true)
allow(project).to receive(:forked_from_project).and_return(source)
expect(service).to receive(:set_key)
diff --git a/spec/support/api/issues_resolving_discussions_shared_examples.rb b/spec/support/api/issues_resolving_discussions_shared_examples.rb
index d26d279363c..d2d6260dfa8 100644
--- a/spec/support/api/issues_resolving_discussions_shared_examples.rb
+++ b/spec/support/api/issues_resolving_discussions_shared_examples.rb
@@ -1,6 +1,6 @@
shared_examples 'creating an issue resolving discussions through the API' do
it 'creates a new project issue' do
- expect(response).to have_http_status(:created)
+ expect(response).to have_gitlab_http_status(:created)
end
it 'resolves the discussions in a merge request' do
diff --git a/spec/support/api/members_shared_examples.rb b/spec/support/api/members_shared_examples.rb
index dab71a35a55..8d910e52eda 100644
--- a/spec/support/api/members_shared_examples.rb
+++ b/spec/support/api/members_shared_examples.rb
@@ -6,6 +6,6 @@ shared_examples 'a 404 response when source is private' do
it 'returns 404' do
route
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
diff --git a/spec/support/api/milestones_shared_examples.rb b/spec/support/api/milestones_shared_examples.rb
index 4bb5113957e..d9080b02541 100644
--- a/spec/support/api/milestones_shared_examples.rb
+++ b/spec/support/api/milestones_shared_examples.rb
@@ -10,7 +10,7 @@ shared_examples_for 'group and project milestones' do |route_definition|
it 'returns milestones list' do
get api(route, user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.first['title']).to eq(milestone.title)
@@ -19,13 +19,13 @@ shared_examples_for 'group and project milestones' do |route_definition|
it 'returns a 401 error if user not authenticated' do
get api(route)
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
it 'returns an array of active milestones' do
get api("#{route}/?state=active", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
@@ -35,7 +35,7 @@ shared_examples_for 'group and project milestones' do |route_definition|
it 'returns an array of closed milestones' do
get api("#{route}/?state=closed", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
@@ -47,7 +47,7 @@ shared_examples_for 'group and project milestones' do |route_definition|
get api(route, user), iids: [closed_milestone.iid, other_milestone.iid]
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(2)
expect(json_response.map { |m| m['id'] }).to match_array([closed_milestone.id, other_milestone.id])
@@ -56,7 +56,7 @@ shared_examples_for 'group and project milestones' do |route_definition|
it 'does not return any milestone if none found' do
get api(route, user), iids: [Milestone.maximum(:iid).succ]
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(0)
end
@@ -75,7 +75,7 @@ shared_examples_for 'group and project milestones' do |route_definition|
it 'returns a milestone by searching for title' do
get api(route, user), search: 'version2'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response.size).to eq(1)
expect(json_response.first['title']).to eq milestone.title
@@ -85,7 +85,7 @@ shared_examples_for 'group and project milestones' do |route_definition|
it 'returns a milestones by searching for description' do
get api(route, user), search: 'open'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response.size).to eq(1)
expect(json_response.first['title']).to eq milestone.title
@@ -97,7 +97,7 @@ shared_examples_for 'group and project milestones' do |route_definition|
it 'returns a milestone by id' do
get api(resource_route, user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['title']).to eq(milestone.title)
expect(json_response['iid']).to eq(milestone.iid)
end
@@ -105,7 +105,7 @@ shared_examples_for 'group and project milestones' do |route_definition|
it 'returns a milestone by id' do
get api(resource_route, user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['title']).to eq(milestone.title)
expect(json_response['iid']).to eq(milestone.iid)
end
@@ -113,13 +113,13 @@ shared_examples_for 'group and project milestones' do |route_definition|
it 'returns 401 error if user not authenticated' do
get api(resource_route)
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
it 'returns a 404 error if milestone id not found' do
get api("#{route}/1234", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -127,7 +127,7 @@ shared_examples_for 'group and project milestones' do |route_definition|
it 'creates a new milestone' do
post api(route, user), title: 'new milestone'
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['title']).to eq('new milestone')
expect(json_response['description']).to be_nil
end
@@ -136,7 +136,7 @@ shared_examples_for 'group and project milestones' do |route_definition|
post api(route, user),
title: 'new milestone', description: 'release', due_date: '2013-03-02', start_date: '2013-02-02'
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['description']).to eq('release')
expect(json_response['due_date']).to eq('2013-03-02')
expect(json_response['start_date']).to eq('2013-02-02')
@@ -145,20 +145,20 @@ shared_examples_for 'group and project milestones' do |route_definition|
it 'returns a 400 error if title is missing' do
post api(route, user)
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it 'returns a 400 error if params are invalid (duplicate title)' do
post api(route, user),
title: milestone.title, description: 'release', due_date: '2013-03-02'
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it 'creates a new milestone with reserved html characters' do
post api(route, user), title: 'foo & bar 1.1 -> 2.2'
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['title']).to eq('foo & bar 1.1 -> 2.2')
expect(json_response['description']).to be_nil
end
@@ -169,7 +169,7 @@ shared_examples_for 'group and project milestones' do |route_definition|
put api(resource_route, user),
title: 'updated title'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['title']).to eq('updated title')
end
@@ -178,7 +178,7 @@ shared_examples_for 'group and project milestones' do |route_definition|
put api(resource_route, user), due_date: nil
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['due_date']).to be_nil
end
@@ -186,13 +186,13 @@ shared_examples_for 'group and project milestones' do |route_definition|
put api("#{route}/1234", user),
title: 'updated title'
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'closes milestone' do
put api(resource_route, user),
state_event: 'close'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['state']).to eq('closed')
end
@@ -207,7 +207,7 @@ shared_examples_for 'group and project milestones' do |route_definition|
it 'returns issues for a particular milestone' do
get api(issues_route, user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.first['milestone']['title']).to eq(milestone.title)
@@ -228,14 +228,14 @@ shared_examples_for 'group and project milestones' do |route_definition|
it 'matches V4 response schema for a list of issues' do
get api(issues_route, user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to match_response_schema('public_api/v4/issues')
end
it 'returns a 401 error if user not authenticated' do
get api(issues_route)
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
describe 'confidential issues' do
@@ -265,7 +265,7 @@ shared_examples_for 'group and project milestones' do |route_definition|
it 'returns confidential issues to team members' do
get api(issues_route, user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
# 2 for projects, 3 for group(which has another project with an issue)
@@ -279,7 +279,7 @@ shared_examples_for 'group and project milestones' do |route_definition|
get api(issues_route, member)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.size).to eq(1)
@@ -289,7 +289,7 @@ shared_examples_for 'group and project milestones' do |route_definition|
it 'does not return confidential issues to regular users' do
get api(issues_route, create(:user))
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.size).to eq(1)
@@ -302,7 +302,7 @@ shared_examples_for 'group and project milestones' do |route_definition|
get api(issues_route, user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
# 2 for projects, 3 for group(which has another project with an issue)
@@ -325,7 +325,7 @@ shared_examples_for 'group and project milestones' do |route_definition|
another_merge_request
get api(merge_requests_route, user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.size).to eq(1)
expect(json_response.first['title']).to eq(merge_request.title)
@@ -349,20 +349,20 @@ shared_examples_for 'group and project milestones' do |route_definition|
get api(not_found_route, user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'returns a 404 if the user has no access to the milestone' do
new_user = create :user
get api(merge_requests_route, new_user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'returns a 401 error if user not authenticated' do
get api(merge_requests_route)
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
it 'returns merge_requests ordered by position asc' do
@@ -372,7 +372,7 @@ shared_examples_for 'group and project milestones' do |route_definition|
get api(merge_requests_route, user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.size).to eq(2)
diff --git a/spec/support/api/scopes/read_user_shared_examples.rb b/spec/support/api/scopes/read_user_shared_examples.rb
index 111534f2f26..06ae8792c61 100644
--- a/spec/support/api/scopes/read_user_shared_examples.rb
+++ b/spec/support/api/scopes/read_user_shared_examples.rb
@@ -6,7 +6,7 @@ shared_examples_for 'allows the "read_user" scope' do
it 'returns a "200" response' do
get api_call.call(path, user, personal_access_token: token)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
end
@@ -16,7 +16,7 @@ shared_examples_for 'allows the "read_user" scope' do
it 'returns a "200" response' do
get api_call.call(path, user, personal_access_token: token)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
end
@@ -30,7 +30,7 @@ shared_examples_for 'allows the "read_user" scope' do
it 'returns a "403" response' do
get api_call.call(path, user, personal_access_token: token)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
end
@@ -44,7 +44,7 @@ shared_examples_for 'allows the "read_user" scope' do
it 'returns a "200" response' do
get api_call.call(path, user, oauth_access_token: token)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
end
@@ -54,7 +54,7 @@ shared_examples_for 'allows the "read_user" scope' do
it 'returns a "200" response' do
get api_call.call(path, user, oauth_access_token: token)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
end
@@ -64,7 +64,7 @@ shared_examples_for 'allows the "read_user" scope' do
it 'returns a "403" response' do
get api_call.call(path, user, oauth_access_token: token)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
end
@@ -77,7 +77,7 @@ shared_examples_for 'does not allow the "read_user" scope' do
it 'returns a "403" response' do
post api_call.call(path, user, personal_access_token: token), attributes_for(:user, projects_limit: 3)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
end
diff --git a/spec/support/api/time_tracking_shared_examples.rb b/spec/support/api/time_tracking_shared_examples.rb
index 16a3cf06be7..af1083f4bfd 100644
--- a/spec/support/api/time_tracking_shared_examples.rb
+++ b/spec/support/api/time_tracking_shared_examples.rb
@@ -15,7 +15,7 @@ shared_examples 'time tracking endpoints' do |issuable_name|
it "sets the time estimate for #{issuable_name}" do
post api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/time_estimate", user), duration: '1w'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['human_time_estimate']).to eq('1w')
end
@@ -28,7 +28,7 @@ shared_examples 'time tracking endpoints' do |issuable_name|
it 'does not modify the original estimate' do
post api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/time_estimate", user), duration: 'foo'
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(issuable.reload.human_time_estimate).to eq('1w')
end
end
@@ -37,7 +37,7 @@ shared_examples 'time tracking endpoints' do |issuable_name|
it 'updates the estimate' do
post api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/time_estimate", user), duration: '3w1h'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(issuable.reload.human_time_estimate).to eq('3w 1h')
end
end
@@ -54,7 +54,7 @@ shared_examples 'time tracking endpoints' do |issuable_name|
it "resets the time estimate for #{issuable_name}" do
post api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/reset_time_estimate", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['time_estimate']).to eq(0)
end
end
@@ -73,7 +73,7 @@ shared_examples 'time tracking endpoints' do |issuable_name|
post api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/add_spent_time", user),
duration: '2h'
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['human_total_time_spent']).to eq('2h')
end
@@ -84,7 +84,7 @@ shared_examples 'time tracking endpoints' do |issuable_name|
post api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/add_spent_time", user),
duration: '-1h'
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['total_time_spent']).to eq(3600)
end
end
@@ -96,7 +96,7 @@ shared_examples 'time tracking endpoints' do |issuable_name|
post api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/add_spent_time", user),
duration: '-1w'
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['message']['time_spent'].first).to match(/exceeds the total time spent/)
end
end
@@ -112,7 +112,7 @@ shared_examples 'time tracking endpoints' do |issuable_name|
it "resets spent time for #{issuable_name}" do
post api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/reset_spent_time", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['total_time_spent']).to eq(0)
end
end
@@ -124,7 +124,7 @@ shared_examples 'time tracking endpoints' do |issuable_name|
get api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/time_stats", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['total_time_spent']).to eq(1800)
expect(json_response['time_estimate']).to eq(3600)
end
diff --git a/spec/support/api/v3/time_tracking_shared_examples.rb b/spec/support/api/v3/time_tracking_shared_examples.rb
index f982b10d999..afe0f4cecda 100644
--- a/spec/support/api/v3/time_tracking_shared_examples.rb
+++ b/spec/support/api/v3/time_tracking_shared_examples.rb
@@ -11,7 +11,7 @@ shared_examples 'V3 time tracking endpoints' do |issuable_name|
it "sets the time estimate for #{issuable_name}" do
post v3_api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.id}/time_estimate", user), duration: '1w'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['human_time_estimate']).to eq('1w')
end
@@ -24,7 +24,7 @@ shared_examples 'V3 time tracking endpoints' do |issuable_name|
it 'does not modify the original estimate' do
post v3_api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.id}/time_estimate", user), duration: 'foo'
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(issuable.reload.human_time_estimate).to eq('1w')
end
end
@@ -33,7 +33,7 @@ shared_examples 'V3 time tracking endpoints' do |issuable_name|
it 'updates the estimate' do
post v3_api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.id}/time_estimate", user), duration: '3w1h'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(issuable.reload.human_time_estimate).to eq('3w 1h')
end
end
@@ -50,7 +50,7 @@ shared_examples 'V3 time tracking endpoints' do |issuable_name|
it "resets the time estimate for #{issuable_name}" do
post v3_api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.id}/reset_time_estimate", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['time_estimate']).to eq(0)
end
end
@@ -69,7 +69,7 @@ shared_examples 'V3 time tracking endpoints' do |issuable_name|
post v3_api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.id}/add_spent_time", user),
duration: '2h'
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['human_total_time_spent']).to eq('2h')
end
@@ -80,7 +80,7 @@ shared_examples 'V3 time tracking endpoints' do |issuable_name|
post v3_api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.id}/add_spent_time", user),
duration: '-1h'
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['total_time_spent']).to eq(3600)
end
end
@@ -92,7 +92,7 @@ shared_examples 'V3 time tracking endpoints' do |issuable_name|
post v3_api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.id}/add_spent_time", user),
duration: '-1w'
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(json_response['message']['time_spent'].first).to match(/exceeds the total time spent/)
end
end
@@ -108,7 +108,7 @@ shared_examples 'V3 time tracking endpoints' do |issuable_name|
it "resets spent time for #{issuable_name}" do
post v3_api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.id}/reset_spent_time", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['total_time_spent']).to eq(0)
end
end
@@ -120,7 +120,7 @@ shared_examples 'V3 time tracking endpoints' do |issuable_name|
get v3_api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.id}/time_stats", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['total_time_spent']).to eq(1800)
expect(json_response['time_estimate']).to eq(3600)
end
diff --git a/spec/support/jira_service_helper.rb b/spec/support/jira_service_helper.rb
index 0b5f66597fd..88a7aeba461 100644
--- a/spec/support/jira_service_helper.rb
+++ b/spec/support/jira_service_helper.rb
@@ -6,6 +6,8 @@ module JiraServiceHelper
properties = {
title: "JIRA tracker",
url: JIRA_URL,
+ username: 'jira-user',
+ password: 'my-secret-password',
project_key: "JIRA",
jira_issue_transition_id: '1'
}
diff --git a/spec/support/shared_examples/requests/api/custom_attributes_shared_examples.rb b/spec/support/shared_examples/requests/api/custom_attributes_shared_examples.rb
index c9302f7b750..6bc39f2f279 100644
--- a/spec/support/shared_examples/requests/api/custom_attributes_shared_examples.rb
+++ b/spec/support/shared_examples/requests/api/custom_attributes_shared_examples.rb
@@ -9,7 +9,7 @@ shared_examples 'custom attributes endpoints' do |attributable_name|
it 'does not filter by custom attributes' do
get api("/#{attributable_name}", user), custom_attributes: { foo: 'foo', bar: 'bar' }
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response.size).to be 2
end
end
@@ -17,7 +17,7 @@ shared_examples 'custom attributes endpoints' do |attributable_name|
it 'filters by custom attributes' do
get api("/#{attributable_name}", admin), custom_attributes: { foo: 'foo', bar: 'bar' }
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response.size).to be 1
expect(json_response.first['id']).to eq attributable.id
end
@@ -33,7 +33,7 @@ shared_examples 'custom attributes endpoints' do |attributable_name|
it 'returns all custom attributes' do
get api("/#{attributable_name}/#{attributable.id}/custom_attributes", admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to contain_exactly(
{ 'key' => 'foo', 'value' => 'foo' },
{ 'key' => 'bar', 'value' => 'bar' }
@@ -51,7 +51,7 @@ shared_examples 'custom attributes endpoints' do |attributable_name|
it 'returns a single custom attribute' do
get api("/#{attributable_name}/#{attributable.id}/custom_attributes/foo", admin)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to eq({ 'key' => 'foo', 'value' => 'foo' })
end
end
@@ -68,7 +68,7 @@ shared_examples 'custom attributes endpoints' do |attributable_name|
put api("/#{attributable_name}/#{attributable.id}/custom_attributes/new", admin), value: 'new'
end.to change { attributable.custom_attributes.count }.by(1)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to eq({ 'key' => 'new', 'value' => 'new' })
expect(attributable.custom_attributes.find_by(key: 'new').value).to eq 'new'
end
@@ -78,7 +78,7 @@ shared_examples 'custom attributes endpoints' do |attributable_name|
put api("/#{attributable_name}/#{attributable.id}/custom_attributes/foo", admin), value: 'new'
end.not_to change { attributable.custom_attributes.count }
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to eq({ 'key' => 'foo', 'value' => 'new' })
expect(custom_attribute1.reload.value).to eq 'new'
end
@@ -96,7 +96,7 @@ shared_examples 'custom attributes endpoints' do |attributable_name|
delete api("/#{attributable_name}/#{attributable.id}/custom_attributes/foo", admin)
end.to change { attributable.custom_attributes.count }.by(-1)
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
expect(attributable.custom_attributes.find_by(key: 'foo')).to be_nil
end
end
diff --git a/spec/support/unique_ip_check_shared_examples.rb b/spec/support/unique_ip_check_shared_examples.rb
index 2dfa5fbecea..3d9705c9c05 100644
--- a/spec/support/unique_ip_check_shared_examples.rb
+++ b/spec/support/unique_ip_check_shared_examples.rb
@@ -56,13 +56,13 @@ shared_examples 'user login request with unique ip limit' do |success_status = 2
end
it 'allows user authenticating from the same ip' do
- expect(request_from_ip('ip')).to have_http_status(success_status)
- expect(request_from_ip('ip')).to have_http_status(success_status)
+ expect(request_from_ip('ip')).to have_gitlab_http_status(success_status)
+ expect(request_from_ip('ip')).to have_gitlab_http_status(success_status)
end
it 'blocks user authenticating from two distinct ips' do
- expect(request_from_ip('ip')).to have_http_status(success_status)
- expect(request_from_ip('ip2')).to have_http_status(403)
+ expect(request_from_ip('ip')).to have_gitlab_http_status(success_status)
+ expect(request_from_ip('ip2')).to have_gitlab_http_status(403)
end
end
end
diff --git a/spec/support/update_invalid_issuable.rb b/spec/support/update_invalid_issuable.rb
index 50a1d4a56e2..1490287681b 100644
--- a/spec/support/update_invalid_issuable.rb
+++ b/spec/support/update_invalid_issuable.rb
@@ -25,13 +25,11 @@ shared_examples 'update invalid issuable' do |klass|
.and_raise(ActiveRecord::StaleObjectError.new(issuable, :save))
end
- if klass == MergeRequest
- it 'renders edit when format is html' do
- put :update, params
+ it 'renders edit when format is html' do
+ put :update, params
- expect(response).to render_template(:edit)
- expect(assigns[:conflict]).to be_truthy
- end
+ expect(response).to render_template(:edit)
+ expect(assigns[:conflict]).to be_truthy
end
it 'renders json error message when format is json' do
@@ -44,17 +42,16 @@ shared_examples 'update invalid issuable' do |klass|
end
end
- if klass == MergeRequest
- context 'when updating an invalid issuable' do
- before do
- params[:merge_request][:title] = ""
- end
+ context 'when updating an invalid issuable' do
+ before do
+ key = klass == Issue ? :issue : :merge_request
+ params[key][:title] = ""
+ end
- it 'renders edit when merge request is invalid' do
- put :update, params
+ it 'renders edit when merge request is invalid' do
+ put :update, params
- expect(response).to render_template(:edit)
- end
+ expect(response).to render_template(:edit)
end
end
end
diff --git a/spec/uploaders/file_uploader_spec.rb b/spec/uploaders/file_uploader_spec.rb
index 2492d56a5cf..f52b2bab05b 100644
--- a/spec/uploaders/file_uploader_spec.rb
+++ b/spec/uploaders/file_uploader_spec.rb
@@ -3,25 +3,51 @@ require 'spec_helper'
describe FileUploader do
let(:uploader) { described_class.new(build_stubbed(:project)) }
- describe '.absolute_path' do
- it 'returns the correct absolute path by building it dynamically' do
- project = build_stubbed(:project)
- upload = double(model: project, path: 'secret/foo.jpg')
+ context 'legacy storage' do
+ let(:project) { build_stubbed(:project) }
- dynamic_segment = project.path_with_namespace
+ describe '.absolute_path' do
+ it 'returns the correct absolute path by building it dynamically' do
+ upload = double(model: project, path: 'secret/foo.jpg')
- expect(described_class.absolute_path(upload))
- .to end_with("#{dynamic_segment}/secret/foo.jpg")
+ dynamic_segment = project.full_path
+
+ expect(described_class.absolute_path(upload))
+ .to end_with("#{dynamic_segment}/secret/foo.jpg")
+ end
+ end
+
+ describe "#store_dir" do
+ it "stores in the namespace path" do
+ uploader = described_class.new(project)
+
+ expect(uploader.store_dir).to include(project.full_path)
+ expect(uploader.store_dir).not_to include("system")
+ end
end
end
- describe "#store_dir" do
- it "stores in the namespace path" do
- project = build_stubbed(:project)
- uploader = described_class.new(project)
+ context 'hashed storage' do
+ let(:project) { build_stubbed(:project, :hashed) }
+
+ describe '.absolute_path' do
+ it 'returns the correct absolute path by building it dynamically' do
+ upload = double(model: project, path: 'secret/foo.jpg')
+
+ dynamic_segment = project.disk_path
+
+ expect(described_class.absolute_path(upload))
+ .to end_with("#{dynamic_segment}/secret/foo.jpg")
+ end
+ end
+
+ describe "#store_dir" do
+ it "stores in the namespace path" do
+ uploader = described_class.new(project)
- expect(uploader.store_dir).to include(project.path_with_namespace)
- expect(uploader.store_dir).not_to include("system")
+ expect(uploader.store_dir).to include(project.disk_path)
+ expect(uploader.store_dir).not_to include("system")
+ end
end
end
diff --git a/spec/views/help/index.html.haml_spec.rb b/spec/views/help/index.html.haml_spec.rb
index c030129559e..0a78606171d 100644
--- a/spec/views/help/index.html.haml_spec.rb
+++ b/spec/views/help/index.html.haml_spec.rb
@@ -25,6 +25,14 @@ describe 'help/index' do
end
end
+ describe 'instance configuration link' do
+ it 'is visible to guests' do
+ render
+
+ expect(rendered).to have_link(nil, help_instance_configuration_url)
+ end
+ end
+
def stub_user(user = double)
allow(view).to receive(:user_signed_in?).and_return(user)
end
diff --git a/spec/views/help/instance_configuration.html.haml_spec.rb b/spec/views/help/instance_configuration.html.haml_spec.rb
new file mode 100644
index 00000000000..f30b5881fde
--- /dev/null
+++ b/spec/views/help/instance_configuration.html.haml_spec.rb
@@ -0,0 +1,29 @@
+require 'rails_helper'
+
+describe 'help/instance_configuration' do
+ describe 'General Sections:' do
+ let(:instance_configuration) { build(:instance_configuration)}
+ let(:settings) { instance_configuration.settings }
+ let(:ssh_settings) { settings[:ssh_algorithms_hashes] }
+
+ before do
+ assign(:instance_configuration, instance_configuration)
+ end
+
+ it 'has links to several sections' do
+ render
+
+ expect(rendered).to have_link(nil, '#ssh-host-keys-fingerprints') if ssh_settings.any?
+ expect(rendered).to have_link(nil, '#gitlab-pages')
+ expect(rendered).to have_link(nil, '#gitlab-ci')
+ end
+
+ it 'has several sections' do
+ render
+
+ expect(rendered).to have_css('h2#ssh-host-keys-fingerprints') if ssh_settings.any?
+ expect(rendered).to have_css('h2#gitlab-pages')
+ expect(rendered).to have_css('h2#gitlab-ci')
+ end
+ end
+end
diff --git a/spec/views/shared/issuable/_participants.html.haml.rb b/spec/views/shared/issuable/_participants.html.haml.rb
deleted file mode 100644
index 51059d4c0d7..00000000000
--- a/spec/views/shared/issuable/_participants.html.haml.rb
+++ /dev/null
@@ -1,26 +0,0 @@
-require 'spec_helper'
-require 'nokogiri'
-
-describe 'shared/issuable/_participants.html.haml' do
- let(:project) { create(:project) }
- let(:participants) { create_list(:user, 100) }
-
- before do
- allow(view).to receive_messages(project: project,
- participants: participants)
- end
-
- it 'renders lazy loaded avatars' do
- render 'shared/issuable/participants'
-
- html = Nokogiri::HTML(rendered)
-
- avatars = html.css('.participants-author img')
-
- avatars.each do |avatar|
- expect(avatar[:class]).to include('lazy')
- expect(avatar[:src]).to eql(LazyImageTagHelper.placeholder_image)
- expect(avatar[:"data-src"]).to match('http://www.gravatar.com/avatar/')
- end
- end
-end
diff --git a/spec/workers/stuck_merge_jobs_worker_spec.rb b/spec/workers/stuck_merge_jobs_worker_spec.rb
index a5ad78393c9..f8b55e873df 100644
--- a/spec/workers/stuck_merge_jobs_worker_spec.rb
+++ b/spec/workers/stuck_merge_jobs_worker_spec.rb
@@ -12,8 +12,13 @@ describe StuckMergeJobsWorker do
worker.perform
- expect(mr_with_sha.reload).to be_merged
- expect(mr_without_sha.reload).to be_opened
+ mr_with_sha.reload
+ mr_without_sha.reload
+
+ expect(mr_with_sha).to be_merged
+ expect(mr_without_sha).to be_opened
+ expect(mr_with_sha.merge_jid).to be_present
+ expect(mr_without_sha.merge_jid).to be_nil
end
it 'updates merge request to opened when locked but has not been merged' do
diff --git a/vendor/assets/javascripts/autosize.js b/vendor/assets/javascripts/autosize.js
deleted file mode 100644
index cfa49e72c50..00000000000
--- a/vendor/assets/javascripts/autosize.js
+++ /dev/null
@@ -1,243 +0,0 @@
-/*!
- Autosize 3.0.14
- license: MIT
- http://www.jacklmoore.com/autosize
-*/
-(function (global, factory) {
- if (typeof define === 'function' && define.amd) {
- define(['exports', 'module'], factory);
- } else if (typeof exports !== 'undefined' && typeof module !== 'undefined') {
- factory(exports, module);
- } else {
- var mod = {
- exports: {}
- };
- factory(mod.exports, mod);
- global.autosize = mod.exports;
- }
-})(this, function (exports, module) {
- 'use strict';
-
- var set = typeof Set === 'function' ? new Set() : (function () {
- var list = [];
-
- return {
- has: function has(key) {
- return Boolean(list.indexOf(key) > -1);
- },
- add: function add(key) {
- list.push(key);
- },
- 'delete': function _delete(key) {
- list.splice(list.indexOf(key), 1);
- } };
- })();
-
- function assign(ta) {
- var _ref = arguments[1] === undefined ? {} : arguments[1];
-
- var _ref$setOverflowX = _ref.setOverflowX;
- var setOverflowX = _ref$setOverflowX === undefined ? true : _ref$setOverflowX;
- var _ref$setOverflowY = _ref.setOverflowY;
- var setOverflowY = _ref$setOverflowY === undefined ? true : _ref$setOverflowY;
-
- if (!ta || !ta.nodeName || ta.nodeName !== 'TEXTAREA' || set.has(ta)) return;
-
- var heightOffset = null;
- var overflowY = null;
- var clientWidth = ta.clientWidth;
-
- function init() {
- var style = window.getComputedStyle(ta, null);
-
- overflowY = style.overflowY;
-
- if (style.resize === 'vertical') {
- ta.style.resize = 'none';
- } else if (style.resize === 'both') {
- ta.style.resize = 'horizontal';
- }
-
- if (style.boxSizing === 'content-box') {
- heightOffset = -(parseFloat(style.paddingTop) + parseFloat(style.paddingBottom));
- } else {
- heightOffset = parseFloat(style.borderTopWidth) + parseFloat(style.borderBottomWidth);
- }
- // Fix when a textarea is not on document body and heightOffset is Not a Number
- if (isNaN(heightOffset)) {
- heightOffset = 0;
- }
-
- update();
- }
-
- function changeOverflow(value) {
- {
- // Chrome/Safari-specific fix:
- // When the textarea y-overflow is hidden, Chrome/Safari do not reflow the text to account for the space
- // made available by removing the scrollbar. The following forces the necessary text reflow.
- var width = ta.style.width;
- ta.style.width = '0px';
- // Force reflow:
- /* jshint ignore:start */
- ta.offsetWidth;
- /* jshint ignore:end */
- ta.style.width = width;
- }
-
- overflowY = value;
-
- if (setOverflowY) {
- ta.style.overflowY = value;
- }
-
- resize();
- }
-
- function resize() {
- var htmlTop = window.pageYOffset;
- var bodyTop = document.body.scrollTop;
- var originalHeight = ta.style.height;
-
- ta.style.height = 'auto';
-
- var endHeight = ta.scrollHeight + heightOffset;
-
- if (ta.scrollHeight === 0) {
- // If the scrollHeight is 0, then the element probably has display:none or is detached from the DOM.
- ta.style.height = originalHeight;
- return;
- }
-
- ta.style.height = endHeight + 'px';
-
- // used to check if an update is actually necessary on window.resize
- clientWidth = ta.clientWidth;
-
- // prevents scroll-position jumping
- document.documentElement.scrollTop = htmlTop;
- document.body.scrollTop = bodyTop;
- }
-
- function update() {
- var startHeight = ta.style.height;
-
- resize();
-
- var style = window.getComputedStyle(ta, null);
-
- if (style.height !== ta.style.height) {
- if (overflowY !== 'visible') {
- changeOverflow('visible');
- }
- } else {
- if (overflowY !== 'hidden') {
- changeOverflow('hidden');
- }
- }
-
- if (startHeight !== ta.style.height) {
- var evt = document.createEvent('Event');
- evt.initEvent('autosize:resized', true, false);
- ta.dispatchEvent(evt);
- }
- }
-
- var pageResize = function pageResize() {
- if (ta.clientWidth !== clientWidth) {
- update();
- }
- };
-
- var destroy = (function (style) {
- window.removeEventListener('resize', pageResize, false);
- ta.removeEventListener('input', update, false);
- ta.removeEventListener('keyup', update, false);
- ta.removeEventListener('autosize:destroy', destroy, false);
- ta.removeEventListener('autosize:update', update, false);
- set['delete'](ta);
-
- Object.keys(style).forEach(function (key) {
- ta.style[key] = style[key];
- });
- }).bind(ta, {
- height: ta.style.height,
- resize: ta.style.resize,
- overflowY: ta.style.overflowY,
- overflowX: ta.style.overflowX,
- wordWrap: ta.style.wordWrap });
-
- ta.addEventListener('autosize:destroy', destroy, false);
-
- // IE9 does not fire onpropertychange or oninput for deletions,
- // so binding to onkeyup to catch most of those events.
- // There is no way that I know of to detect something like 'cut' in IE9.
- if ('onpropertychange' in ta && 'oninput' in ta) {
- ta.addEventListener('keyup', update, false);
- }
-
- window.addEventListener('resize', pageResize, false);
- ta.addEventListener('input', update, false);
- ta.addEventListener('autosize:update', update, false);
- set.add(ta);
-
- if (setOverflowX) {
- ta.style.overflowX = 'hidden';
- ta.style.wordWrap = 'break-word';
- }
-
- init();
- }
-
- function destroy(ta) {
- if (!(ta && ta.nodeName && ta.nodeName === 'TEXTAREA')) return;
- var evt = document.createEvent('Event');
- evt.initEvent('autosize:destroy', true, false);
- ta.dispatchEvent(evt);
- }
-
- function update(ta) {
- if (!(ta && ta.nodeName && ta.nodeName === 'TEXTAREA')) return;
- var evt = document.createEvent('Event');
- evt.initEvent('autosize:update', true, false);
- ta.dispatchEvent(evt);
- }
-
- var autosize = null;
-
- // Do nothing in Node.js environment and IE8 (or lower)
- if (typeof window === 'undefined' || typeof window.getComputedStyle !== 'function') {
- autosize = function (el) {
- return el;
- };
- autosize.destroy = function (el) {
- return el;
- };
- autosize.update = function (el) {
- return el;
- };
- } else {
- autosize = function (el, options) {
- if (el) {
- Array.prototype.forEach.call(el.length ? el : [el], function (x) {
- return assign(x, options);
- });
- }
- return el;
- };
- autosize.destroy = function (el) {
- if (el) {
- Array.prototype.forEach.call(el.length ? el : [el], destroy);
- }
- return el;
- };
- autosize.update = function (el) {
- if (el) {
- Array.prototype.forEach.call(el.length ? el : [el], update);
- }
- return el;
- };
- }
-
- module.exports = autosize;
-}); \ No newline at end of file
diff --git a/vendor/assets/javascripts/fuzzaldrin-plus.js b/vendor/assets/javascripts/fuzzaldrin-plus.js
deleted file mode 100644
index 1985e3f8f6c..00000000000
--- a/vendor/assets/javascripts/fuzzaldrin-plus.js
+++ /dev/null
@@ -1,1161 +0,0 @@
-/*!
- * fuzzaldrin-plus.js - 0.3.1
- * https://github.com/jeancroy/fuzzaldrin-plus
- *
- * Copyright 2016 - Jean Christophe Roy
- * Released under the MIT license
- * https://github.com/jeancroy/fuzzaldrin-plus/raw/master/LICENSE.md
- */
-(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
-fuzzaldrinPlus = require('fuzzaldrin-plus');
-
-},{"fuzzaldrin-plus":3}],2:[function(require,module,exports){
-(function() {
- var PathSeparator, legacy_scorer, pluckCandidates, scorer, sortCandidates;
-
- scorer = require('./scorer');
-
- legacy_scorer = require('./legacy');
-
- pluckCandidates = function(a) {
- return a.candidate;
- };
-
- sortCandidates = function(a, b) {
- return b.score - a.score;
- };
-
- PathSeparator = require('path').sep;
-
- module.exports = function(candidates, query, _arg) {
- var allowErrors, bAllowErrors, bKey, candidate, coreQuery, key, legacy, maxInners, maxResults, prepQuery, queryHasSlashes, score, scoredCandidates, spotLeft, string, _i, _j, _len, _len1, _ref;
- _ref = _arg != null ? _arg : {}, key = _ref.key, maxResults = _ref.maxResults, maxInners = _ref.maxInners, allowErrors = _ref.allowErrors, legacy = _ref.legacy;
- scoredCandidates = [];
- spotLeft = (maxInners != null) && maxInners > 0 ? maxInners : candidates.length;
- bAllowErrors = !!allowErrors;
- bKey = key != null;
- prepQuery = scorer.prepQuery(query);
- if (!legacy) {
- for (_i = 0, _len = candidates.length; _i < _len; _i++) {
- candidate = candidates[_i];
- string = bKey ? candidate[key] : candidate;
- if (!string) {
- continue;
- }
- score = scorer.score(string, query, prepQuery, bAllowErrors);
- if (score > 0) {
- scoredCandidates.push({
- candidate: candidate,
- score: score
- });
- if (!--spotLeft) {
- break;
- }
- }
- }
- } else {
- queryHasSlashes = prepQuery.depth > 0;
- coreQuery = prepQuery.core;
- for (_j = 0, _len1 = candidates.length; _j < _len1; _j++) {
- candidate = candidates[_j];
- string = key != null ? candidate[key] : candidate;
- if (!string) {
- continue;
- }
- score = legacy_scorer.score(string, coreQuery, queryHasSlashes);
- if (!queryHasSlashes) {
- score = legacy_scorer.basenameScore(string, coreQuery, score);
- }
- if (score > 0) {
- scoredCandidates.push({
- candidate: candidate,
- score: score
- });
- }
- }
- }
- scoredCandidates.sort(sortCandidates);
- candidates = scoredCandidates.map(pluckCandidates);
- if (maxResults != null) {
- candidates = candidates.slice(0, maxResults);
- }
- return candidates;
- };
-
-}).call(this);
-
-},{"./legacy":4,"./scorer":6,"path":7}],3:[function(require,module,exports){
-(function() {
- var PathSeparator, filter, legacy_scorer, matcher, prepQueryCache, scorer;
-
- scorer = require('./scorer');
-
- legacy_scorer = require('./legacy');
-
- filter = require('./filter');
-
- matcher = require('./matcher');
-
- PathSeparator = require('path').sep;
-
- prepQueryCache = null;
-
- module.exports = {
- filter: function(candidates, query, options) {
- if (!((query != null ? query.length : void 0) && (candidates != null ? candidates.length : void 0))) {
- return [];
- }
- return filter(candidates, query, options);
- },
- prepQuery: function(query) {
- return scorer.prepQuery(query);
- },
- score: function(string, query, prepQuery, _arg) {
- var allowErrors, coreQuery, legacy, queryHasSlashes, score, _ref;
- _ref = _arg != null ? _arg : {}, allowErrors = _ref.allowErrors, legacy = _ref.legacy;
- if (!((string != null ? string.length : void 0) && (query != null ? query.length : void 0))) {
- return 0;
- }
- if (prepQuery == null) {
- prepQuery = prepQueryCache && prepQueryCache.query === query ? prepQueryCache : (prepQueryCache = scorer.prepQuery(query));
- }
- if (!legacy) {
- score = scorer.score(string, query, prepQuery, !!allowErrors);
- } else {
- queryHasSlashes = prepQuery.depth > 0;
- coreQuery = prepQuery.core;
- score = legacy_scorer.score(string, coreQuery, queryHasSlashes);
- if (!queryHasSlashes) {
- score = legacy_scorer.basenameScore(string, coreQuery, score);
- }
- }
- return score;
- },
- match: function(string, query, prepQuery, _arg) {
- var allowErrors, baseMatches, matches, query_lw, string_lw, _i, _ref, _results;
- allowErrors = (_arg != null ? _arg : {}).allowErrors;
- if (!string) {
- return [];
- }
- if (!query) {
- return [];
- }
- if (string === query) {
- return (function() {
- _results = [];
- for (var _i = 0, _ref = string.length; 0 <= _ref ? _i < _ref : _i > _ref; 0 <= _ref ? _i++ : _i--){ _results.push(_i); }
- return _results;
- }).apply(this);
- }
- if (prepQuery == null) {
- prepQuery = prepQueryCache && prepQueryCache.query === query ? prepQueryCache : (prepQueryCache = scorer.prepQuery(query));
- }
- if (!(allowErrors || scorer.isMatch(string, prepQuery.core_lw, prepQuery.core_up))) {
- return [];
- }
- string_lw = string.toLowerCase();
- query_lw = prepQuery.query_lw;
- matches = matcher.match(string, string_lw, prepQuery);
- if (matches.length === 0) {
- return matches;
- }
- if (string.indexOf(PathSeparator) > -1) {
- baseMatches = matcher.basenameMatch(string, string_lw, prepQuery);
- matches = matcher.mergeMatches(matches, baseMatches);
- }
- return matches;
- }
- };
-
-}).call(this);
-
-},{"./filter":2,"./legacy":4,"./matcher":5,"./scorer":6,"path":7}],4:[function(require,module,exports){
-(function() {
- var PathSeparator, queryIsLastPathSegment;
-
- PathSeparator = require('path').sep;
-
- exports.basenameScore = function(string, query, score) {
- var base, depth, index, lastCharacter, segmentCount, slashCount;
- index = string.length - 1;
- while (string[index] === PathSeparator) {
- index--;
- }
- slashCount = 0;
- lastCharacter = index;
- base = null;
- while (index >= 0) {
- if (string[index] === PathSeparator) {
- slashCount++;
- if (base == null) {
- base = string.substring(index + 1, lastCharacter + 1);
- }
- } else if (index === 0) {
- if (lastCharacter < string.length - 1) {
- if (base == null) {
- base = string.substring(0, lastCharacter + 1);
- }
- } else {
- if (base == null) {
- base = string;
- }
- }
- }
- index--;
- }
- if (base === string) {
- score *= 2;
- } else if (base) {
- score += exports.score(base, query);
- }
- segmentCount = slashCount + 1;
- depth = Math.max(1, 10 - segmentCount);
- score *= depth * 0.01;
- return score;
- };
-
- exports.score = function(string, query) {
- var character, characterScore, indexInQuery, indexInString, lowerCaseIndex, minIndex, queryLength, queryScore, stringLength, totalCharacterScore, upperCaseIndex, _ref;
- if (string === query) {
- return 1;
- }
- if (queryIsLastPathSegment(string, query)) {
- return 1;
- }
- totalCharacterScore = 0;
- queryLength = query.length;
- stringLength = string.length;
- indexInQuery = 0;
- indexInString = 0;
- while (indexInQuery < queryLength) {
- character = query[indexInQuery++];
- lowerCaseIndex = string.indexOf(character.toLowerCase());
- upperCaseIndex = string.indexOf(character.toUpperCase());
- minIndex = Math.min(lowerCaseIndex, upperCaseIndex);
- if (minIndex === -1) {
- minIndex = Math.max(lowerCaseIndex, upperCaseIndex);
- }
- indexInString = minIndex;
- if (indexInString === -1) {
- return 0;
- }
- characterScore = 0.1;
- if (string[indexInString] === character) {
- characterScore += 0.1;
- }
- if (indexInString === 0 || string[indexInString - 1] === PathSeparator) {
- characterScore += 0.8;
- } else if ((_ref = string[indexInString - 1]) === '-' || _ref === '_' || _ref === ' ') {
- characterScore += 0.7;
- }
- string = string.substring(indexInString + 1, stringLength);
- totalCharacterScore += characterScore;
- }
- queryScore = totalCharacterScore / queryLength;
- return ((queryScore * (queryLength / stringLength)) + queryScore) / 2;
- };
-
- queryIsLastPathSegment = function(string, query) {
- if (string[string.length - query.length - 1] === PathSeparator) {
- return string.lastIndexOf(query) === string.length - query.length;
- }
- };
-
- exports.match = function(string, query, stringOffset) {
- var character, indexInQuery, indexInString, lowerCaseIndex, matches, minIndex, queryLength, stringLength, upperCaseIndex, _i, _ref, _results;
- if (stringOffset == null) {
- stringOffset = 0;
- }
- if (string === query) {
- return (function() {
- _results = [];
- for (var _i = stringOffset, _ref = stringOffset + string.length; stringOffset <= _ref ? _i < _ref : _i > _ref; stringOffset <= _ref ? _i++ : _i--){ _results.push(_i); }
- return _results;
- }).apply(this);
- }
- queryLength = query.length;
- stringLength = string.length;
- indexInQuery = 0;
- indexInString = 0;
- matches = [];
- while (indexInQuery < queryLength) {
- character = query[indexInQuery++];
- lowerCaseIndex = string.indexOf(character.toLowerCase());
- upperCaseIndex = string.indexOf(character.toUpperCase());
- minIndex = Math.min(lowerCaseIndex, upperCaseIndex);
- if (minIndex === -1) {
- minIndex = Math.max(lowerCaseIndex, upperCaseIndex);
- }
- indexInString = minIndex;
- if (indexInString === -1) {
- return [];
- }
- matches.push(stringOffset + indexInString);
- stringOffset += indexInString + 1;
- string = string.substring(indexInString + 1, stringLength);
- }
- return matches;
- };
-
-}).call(this);
-
-},{"path":7}],5:[function(require,module,exports){
-(function() {
- var PathSeparator, scorer;
-
- PathSeparator = require('path').sep;
-
- scorer = require('./scorer');
-
- exports.basenameMatch = function(subject, subject_lw, prepQuery) {
- var basePos, depth, end;
- end = subject.length - 1;
- while (subject[end] === PathSeparator) {
- end--;
- }
- basePos = subject.lastIndexOf(PathSeparator, end);
- if (basePos === -1) {
- return [];
- }
- depth = prepQuery.depth;
- while (depth-- > 0) {
- basePos = subject.lastIndexOf(PathSeparator, basePos - 1);
- if (basePos === -1) {
- return [];
- }
- }
- basePos++;
- end++;
- return exports.match(subject.slice(basePos, end), subject_lw.slice(basePos, end), prepQuery, basePos);
- };
-
- exports.mergeMatches = function(a, b) {
- var ai, bj, i, j, m, n, out;
- m = a.length;
- n = b.length;
- if (n === 0) {
- return a.slice();
- }
- if (m === 0) {
- return b.slice();
- }
- i = -1;
- j = 0;
- bj = b[j];
- out = [];
- while (++i < m) {
- ai = a[i];
- while (bj <= ai && ++j < n) {
- if (bj < ai) {
- out.push(bj);
- }
- bj = b[j];
- }
- out.push(ai);
- }
- while (j < n) {
- out.push(b[j++]);
- }
- return out;
- };
-
- exports.match = function(subject, subject_lw, prepQuery, offset) {
- var DIAGONAL, LEFT, STOP, UP, acro_score, align, backtrack, csc_diag, csc_row, csc_score, i, j, m, matches, move, n, pos, query, query_lw, score, score_diag, score_row, score_up, si_lw, start, trace;
- if (offset == null) {
- offset = 0;
- }
- query = prepQuery.query;
- query_lw = prepQuery.query_lw;
- m = subject.length;
- n = query.length;
- acro_score = scorer.scoreAcronyms(subject, subject_lw, query, query_lw).score;
- score_row = new Array(n);
- csc_row = new Array(n);
- STOP = 0;
- UP = 1;
- LEFT = 2;
- DIAGONAL = 3;
- trace = new Array(m * n);
- pos = -1;
- j = -1;
- while (++j < n) {
- score_row[j] = 0;
- csc_row[j] = 0;
- }
- i = -1;
- while (++i < m) {
- score = 0;
- score_up = 0;
- csc_diag = 0;
- si_lw = subject_lw[i];
- j = -1;
- while (++j < n) {
- csc_score = 0;
- align = 0;
- score_diag = score_up;
- if (query_lw[j] === si_lw) {
- start = scorer.isWordStart(i, subject, subject_lw);
- csc_score = csc_diag > 0 ? csc_diag : scorer.scoreConsecutives(subject, subject_lw, query, query_lw, i, j, start);
- align = score_diag + scorer.scoreCharacter(i, j, start, acro_score, csc_score);
- }
- score_up = score_row[j];
- csc_diag = csc_row[j];
- if (score > score_up) {
- move = LEFT;
- } else {
- score = score_up;
- move = UP;
- }
- if (align > score) {
- score = align;
- move = DIAGONAL;
- } else {
- csc_score = 0;
- }
- score_row[j] = score;
- csc_row[j] = csc_score;
- trace[++pos] = score > 0 ? move : STOP;
- }
- }
- i = m - 1;
- j = n - 1;
- pos = i * n + j;
- backtrack = true;
- matches = [];
- while (backtrack && i >= 0 && j >= 0) {
- switch (trace[pos]) {
- case UP:
- i--;
- pos -= n;
- break;
- case LEFT:
- j--;
- pos--;
- break;
- case DIAGONAL:
- matches.push(i + offset);
- j--;
- i--;
- pos -= n + 1;
- break;
- default:
- backtrack = false;
- }
- }
- matches.reverse();
- return matches;
- };
-
-}).call(this);
-
-},{"./scorer":6,"path":7}],6:[function(require,module,exports){
-(function() {
- var AcronymResult, PathSeparator, Query, basenameScore, coreChars, countDir, doScore, emptyAcronymResult, file_coeff, isMatch, isSeparator, isWordEnd, isWordStart, miss_coeff, opt_char_re, pos_bonus, scoreAcronyms, scoreCharacter, scoreConsecutives, scoreExact, scoreExactMatch, scorePattern, scorePosition, scoreSize, tau_depth, tau_size, truncatedUpperCase, wm;
-
- PathSeparator = require('path').sep;
-
- wm = 150;
-
- pos_bonus = 20;
-
- tau_depth = 13;
-
- tau_size = 85;
-
- file_coeff = 1.2;
-
- miss_coeff = 0.75;
-
- opt_char_re = /[ _\-:\/\\]/g;
-
- exports.coreChars = coreChars = function(query) {
- return query.replace(opt_char_re, '');
- };
-
- exports.score = function(string, query, prepQuery, allowErrors) {
- var score, string_lw;
- if (prepQuery == null) {
- prepQuery = new Query(query);
- }
- if (allowErrors == null) {
- allowErrors = false;
- }
- if (!(allowErrors || isMatch(string, prepQuery.core_lw, prepQuery.core_up))) {
- return 0;
- }
- string_lw = string.toLowerCase();
- score = doScore(string, string_lw, prepQuery);
- return Math.ceil(basenameScore(string, string_lw, prepQuery, score));
- };
-
- Query = (function() {
- function Query(query) {
- if (!(query != null ? query.length : void 0)) {
- return null;
- }
- this.query = query;
- this.query_lw = query.toLowerCase();
- this.core = coreChars(query);
- this.core_lw = this.core.toLowerCase();
- this.core_up = truncatedUpperCase(this.core);
- this.depth = countDir(query, query.length);
- }
-
- return Query;
-
- })();
-
- exports.prepQuery = function(query) {
- return new Query(query);
- };
-
- exports.isMatch = isMatch = function(subject, query_lw, query_up) {
- var i, j, m, n, qj_lw, qj_up, si;
- m = subject.length;
- n = query_lw.length;
- if (!m || n > m) {
- return false;
- }
- i = -1;
- j = -1;
- while (++j < n) {
- qj_lw = query_lw[j];
- qj_up = query_up[j];
- while (++i < m) {
- si = subject[i];
- if (si === qj_lw || si === qj_up) {
- break;
- }
- }
- if (i === m) {
- return false;
- }
- }
- return true;
- };
-
- doScore = function(subject, subject_lw, prepQuery) {
- var acro, acro_score, align, csc_diag, csc_row, csc_score, i, j, m, miss_budget, miss_left, mm, n, pos, query, query_lw, record_miss, score, score_diag, score_row, score_up, si_lw, start, sz;
- query = prepQuery.query;
- query_lw = prepQuery.query_lw;
- m = subject.length;
- n = query.length;
- acro = scoreAcronyms(subject, subject_lw, query, query_lw);
- acro_score = acro.score;
- if (acro.count === n) {
- return scoreExact(n, m, acro_score, acro.pos);
- }
- pos = subject_lw.indexOf(query_lw);
- if (pos > -1) {
- return scoreExactMatch(subject, subject_lw, query, query_lw, pos, n, m);
- }
- score_row = new Array(n);
- csc_row = new Array(n);
- sz = scoreSize(n, m);
- miss_budget = Math.ceil(miss_coeff * n) + 5;
- miss_left = miss_budget;
- j = -1;
- while (++j < n) {
- score_row[j] = 0;
- csc_row[j] = 0;
- }
- i = subject_lw.indexOf(query_lw[0]);
- if (i > -1) {
- i--;
- }
- mm = subject_lw.lastIndexOf(query_lw[n - 1], m);
- if (mm > i) {
- m = mm + 1;
- }
- while (++i < m) {
- score = 0;
- score_diag = 0;
- csc_diag = 0;
- si_lw = subject_lw[i];
- record_miss = true;
- j = -1;
- while (++j < n) {
- score_up = score_row[j];
- if (score_up > score) {
- score = score_up;
- }
- csc_score = 0;
- if (query_lw[j] === si_lw) {
- start = isWordStart(i, subject, subject_lw);
- csc_score = csc_diag > 0 ? csc_diag : scoreConsecutives(subject, subject_lw, query, query_lw, i, j, start);
- align = score_diag + scoreCharacter(i, j, start, acro_score, csc_score);
- if (align > score) {
- score = align;
- miss_left = miss_budget;
- } else {
- if (record_miss && --miss_left <= 0) {
- return score_row[n - 1] * sz;
- }
- record_miss = false;
- }
- }
- score_diag = score_up;
- csc_diag = csc_row[j];
- csc_row[j] = csc_score;
- score_row[j] = score;
- }
- }
- return score * sz;
- };
-
- exports.isWordStart = isWordStart = function(pos, subject, subject_lw) {
- var curr_s, prev_s;
- if (pos === 0) {
- return true;
- }
- curr_s = subject[pos];
- prev_s = subject[pos - 1];
- return isSeparator(curr_s) || isSeparator(prev_s) || (curr_s !== subject_lw[pos] && prev_s === subject_lw[pos - 1]);
- };
-
- exports.isWordEnd = isWordEnd = function(pos, subject, subject_lw, len) {
- var curr_s, next_s;
- if (pos === len - 1) {
- return true;
- }
- curr_s = subject[pos];
- next_s = subject[pos + 1];
- return isSeparator(curr_s) || isSeparator(next_s) || (curr_s === subject_lw[pos] && next_s !== subject_lw[pos + 1]);
- };
-
- isSeparator = function(c) {
- return c === ' ' || c === '.' || c === '-' || c === '_' || c === '/' || c === '\\';
- };
-
- scorePosition = function(pos) {
- var sc;
- if (pos < pos_bonus) {
- sc = pos_bonus - pos;
- return 100 + sc * sc;
- } else {
- return Math.max(100 + pos_bonus - pos, 0);
- }
- };
-
- scoreSize = function(n, m) {
- return tau_size / (tau_size + Math.abs(m - n));
- };
-
- scoreExact = function(n, m, quality, pos) {
- return 2 * n * (wm * quality + scorePosition(pos)) * scoreSize(n, m);
- };
-
- exports.scorePattern = scorePattern = function(count, len, sameCase, start, end) {
- var bonus, sz;
- sz = count;
- bonus = 6;
- if (sameCase === count) {
- bonus += 2;
- }
- if (start) {
- bonus += 3;
- }
- if (end) {
- bonus += 1;
- }
- if (count === len) {
- if (start) {
- if (sameCase === len) {
- sz += 2;
- } else {
- sz += 1;
- }
- }
- if (end) {
- bonus += 1;
- }
- }
- return sameCase + sz * (sz + bonus);
- };
-
- exports.scoreCharacter = scoreCharacter = function(i, j, start, acro_score, csc_score) {
- var posBonus;
- posBonus = scorePosition(i);
- if (start) {
- return posBonus + wm * ((acro_score > csc_score ? acro_score : csc_score) + 10);
- }
- return posBonus + wm * csc_score;
- };
-
- exports.scoreConsecutives = scoreConsecutives = function(subject, subject_lw, query, query_lw, i, j, start) {
- var k, m, mi, n, nj, sameCase, startPos, sz;
- m = subject.length;
- n = query.length;
- mi = m - i;
- nj = n - j;
- k = mi < nj ? mi : nj;
- startPos = i;
- sameCase = 0;
- sz = 0;
- if (query[j] === subject[i]) {
- sameCase++;
- }
- while (++sz < k && query_lw[++j] === subject_lw[++i]) {
- if (query[j] === subject[i]) {
- sameCase++;
- }
- }
- if (sz === 1) {
- return 1 + 2 * sameCase;
- }
- return scorePattern(sz, n, sameCase, start, isWordEnd(i, subject, subject_lw, m));
- };
-
- exports.scoreExactMatch = scoreExactMatch = function(subject, subject_lw, query, query_lw, pos, n, m) {
- var end, i, pos2, sameCase, start;
- start = isWordStart(pos, subject, subject_lw);
- if (!start) {
- pos2 = subject_lw.indexOf(query_lw, pos + 1);
- if (pos2 > -1) {
- start = isWordStart(pos2, subject, subject_lw);
- if (start) {
- pos = pos2;
- }
- }
- }
- i = -1;
- sameCase = 0;
- while (++i < n) {
- if (query[pos + i] === subject[i]) {
- sameCase++;
- }
- }
- end = isWordEnd(pos + n - 1, subject, subject_lw, m);
- return scoreExact(n, m, scorePattern(n, n, sameCase, start, end), pos);
- };
-
- AcronymResult = (function() {
- function AcronymResult(score, pos, count) {
- this.score = score;
- this.pos = pos;
- this.count = count;
- }
-
- return AcronymResult;
-
- })();
-
- emptyAcronymResult = new AcronymResult(0, 0.1, 0);
-
- exports.scoreAcronyms = scoreAcronyms = function(subject, subject_lw, query, query_lw) {
- var count, i, j, m, n, pos, qj_lw, sameCase, score;
- m = subject.length;
- n = query.length;
- if (!(m > 1 && n > 1)) {
- return emptyAcronymResult;
- }
- count = 0;
- pos = 0;
- sameCase = 0;
- i = -1;
- j = -1;
- while (++j < n) {
- qj_lw = query_lw[j];
- while (++i < m) {
- if (qj_lw === subject_lw[i] && isWordStart(i, subject, subject_lw)) {
- if (query[j] === subject[i]) {
- sameCase++;
- }
- pos += i;
- count++;
- break;
- }
- }
- if (i === m) {
- break;
- }
- }
- if (count < 2) {
- return emptyAcronymResult;
- }
- score = scorePattern(count, n, sameCase, true, false);
- return new AcronymResult(score, pos / count, count);
- };
-
- basenameScore = function(subject, subject_lw, prepQuery, fullPathScore) {
- var alpha, basePathScore, basePos, depth, end;
- if (fullPathScore === 0) {
- return 0;
- }
- end = subject.length - 1;
- while (subject[end] === PathSeparator) {
- end--;
- }
- basePos = subject.lastIndexOf(PathSeparator, end);
- if (basePos === -1) {
- return fullPathScore;
- }
- depth = prepQuery.depth;
- while (depth-- > 0) {
- basePos = subject.lastIndexOf(PathSeparator, basePos - 1);
- if (basePos === -1) {
- return fullPathScore;
- }
- }
- basePos++;
- end++;
- basePathScore = doScore(subject.slice(basePos, end), subject_lw.slice(basePos, end), prepQuery);
- alpha = 0.5 * tau_depth / (tau_depth + countDir(subject, end + 1));
- return alpha * basePathScore + (1 - alpha) * fullPathScore * scoreSize(0, file_coeff * (end - basePos));
- };
-
- exports.countDir = countDir = function(path, end) {
- var count, i;
- if (end < 1) {
- return 0;
- }
- count = 0;
- i = -1;
- while (++i < end && path[i] === PathSeparator) {
- continue;
- }
- while (++i < end) {
- if (path[i] === PathSeparator) {
- count++;
- while (++i < end && path[i] === PathSeparator) {
- continue;
- }
- }
- }
- return count;
- };
-
- truncatedUpperCase = function(str) {
- var char, upper, _i, _len;
- upper = "";
- for (_i = 0, _len = str.length; _i < _len; _i++) {
- char = str[_i];
- upper += char.toUpperCase()[0];
- }
- return upper;
- };
-
-}).call(this);
-
-},{"path":7}],7:[function(require,module,exports){
-(function (process){
-// Copyright Joyent, Inc. and other Node contributors.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to permit
-// persons to whom the Software is furnished to do so, subject to the
-// following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
-// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
-// USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-// resolves . and .. elements in a path array with directory names there
-// must be no slashes, empty elements, or device names (c:\) in the array
-// (so also no leading and trailing slashes - it does not distinguish
-// relative and absolute paths)
-function normalizeArray(parts, allowAboveRoot) {
- // if the path tries to go above the root, `up` ends up > 0
- var up = 0;
- for (var i = parts.length - 1; i >= 0; i--) {
- var last = parts[i];
- if (last === '.') {
- parts.splice(i, 1);
- } else if (last === '..') {
- parts.splice(i, 1);
- up++;
- } else if (up) {
- parts.splice(i, 1);
- up--;
- }
- }
-
- // if the path is allowed to go above the root, restore leading ..s
- if (allowAboveRoot) {
- for (; up--; up) {
- parts.unshift('..');
- }
- }
-
- return parts;
-}
-
-// Split a filename into [root, dir, basename, ext], unix version
-// 'root' is just a slash, or nothing.
-var splitPathRe =
- /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
-var splitPath = function(filename) {
- return splitPathRe.exec(filename).slice(1);
-};
-
-// path.resolve([from ...], to)
-// posix version
-exports.resolve = function() {
- var resolvedPath = '',
- resolvedAbsolute = false;
-
- for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
- var path = (i >= 0) ? arguments[i] : process.cwd();
-
- // Skip empty and invalid entries
- if (typeof path !== 'string') {
- throw new TypeError('Arguments to path.resolve must be strings');
- } else if (!path) {
- continue;
- }
-
- resolvedPath = path + '/' + resolvedPath;
- resolvedAbsolute = path.charAt(0) === '/';
- }
-
- // At this point the path should be resolved to a full absolute path, but
- // handle relative paths to be safe (might happen when process.cwd() fails)
-
- // Normalize the path
- resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) {
- return !!p;
- }), !resolvedAbsolute).join('/');
-
- return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
-};
-
-// path.normalize(path)
-// posix version
-exports.normalize = function(path) {
- var isAbsolute = exports.isAbsolute(path),
- trailingSlash = substr(path, -1) === '/';
-
- // Normalize the path
- path = normalizeArray(filter(path.split('/'), function(p) {
- return !!p;
- }), !isAbsolute).join('/');
-
- if (!path && !isAbsolute) {
- path = '.';
- }
- if (path && trailingSlash) {
- path += '/';
- }
-
- return (isAbsolute ? '/' : '') + path;
-};
-
-// posix version
-exports.isAbsolute = function(path) {
- return path.charAt(0) === '/';
-};
-
-// posix version
-exports.join = function() {
- var paths = Array.prototype.slice.call(arguments, 0);
- return exports.normalize(filter(paths, function(p, index) {
- if (typeof p !== 'string') {
- throw new TypeError('Arguments to path.join must be strings');
- }
- return p;
- }).join('/'));
-};
-
-
-// path.relative(from, to)
-// posix version
-exports.relative = function(from, to) {
- from = exports.resolve(from).substr(1);
- to = exports.resolve(to).substr(1);
-
- function trim(arr) {
- var start = 0;
- for (; start < arr.length; start++) {
- if (arr[start] !== '') break;
- }
-
- var end = arr.length - 1;
- for (; end >= 0; end--) {
- if (arr[end] !== '') break;
- }
-
- if (start > end) return [];
- return arr.slice(start, end - start + 1);
- }
-
- var fromParts = trim(from.split('/'));
- var toParts = trim(to.split('/'));
-
- var length = Math.min(fromParts.length, toParts.length);
- var samePartsLength = length;
- for (var i = 0; i < length; i++) {
- if (fromParts[i] !== toParts[i]) {
- samePartsLength = i;
- break;
- }
- }
-
- var outputParts = [];
- for (var i = samePartsLength; i < fromParts.length; i++) {
- outputParts.push('..');
- }
-
- outputParts = outputParts.concat(toParts.slice(samePartsLength));
-
- return outputParts.join('/');
-};
-
-exports.sep = '/';
-exports.delimiter = ':';
-
-exports.dirname = function(path) {
- var result = splitPath(path),
- root = result[0],
- dir = result[1];
-
- if (!root && !dir) {
- // No dirname whatsoever
- return '.';
- }
-
- if (dir) {
- // It has a dirname, strip trailing slash
- dir = dir.substr(0, dir.length - 1);
- }
-
- return root + dir;
-};
-
-
-exports.basename = function(path, ext) {
- var f = splitPath(path)[2];
- // TODO: make this comparison case-insensitive on windows?
- if (ext && f.substr(-1 * ext.length) === ext) {
- f = f.substr(0, f.length - ext.length);
- }
- return f;
-};
-
-
-exports.extname = function(path) {
- return splitPath(path)[3];
-};
-
-function filter (xs, f) {
- if (xs.filter) return xs.filter(f);
- var res = [];
- for (var i = 0; i < xs.length; i++) {
- if (f(xs[i], i, xs)) res.push(xs[i]);
- }
- return res;
-}
-
-// String.prototype.substr - negative index don't work in IE8
-var substr = 'ab'.substr(-1) === 'b'
- ? function (str, start, len) { return str.substr(start, len) }
- : function (str, start, len) {
- if (start < 0) start = str.length + start;
- return str.substr(start, len);
- }
-;
-
-}).call(this,require('_process'))
-},{"_process":8}],8:[function(require,module,exports){
-// shim for using process in browser
-
-var process = module.exports = {};
-var queue = [];
-var draining = false;
-var currentQueue;
-var queueIndex = -1;
-
-function cleanUpNextTick() {
- draining = false;
- if (currentQueue.length) {
- queue = currentQueue.concat(queue);
- } else {
- queueIndex = -1;
- }
- if (queue.length) {
- drainQueue();
- }
-}
-
-function drainQueue() {
- if (draining) {
- return;
- }
- var timeout = setTimeout(cleanUpNextTick);
- draining = true;
-
- var len = queue.length;
- while(len) {
- currentQueue = queue;
- queue = [];
- while (++queueIndex < len) {
- if (currentQueue) {
- currentQueue[queueIndex].run();
- }
- }
- queueIndex = -1;
- len = queue.length;
- }
- currentQueue = null;
- draining = false;
- clearTimeout(timeout);
-}
-
-process.nextTick = function (fun) {
- var args = new Array(arguments.length - 1);
- if (arguments.length > 1) {
- for (var i = 1; i < arguments.length; i++) {
- args[i - 1] = arguments[i];
- }
- }
- queue.push(new Item(fun, args));
- if (queue.length === 1 && !draining) {
- setTimeout(drainQueue, 0);
- }
-};
-
-// v8 likes predictible objects
-function Item(fun, array) {
- this.fun = fun;
- this.array = array;
-}
-Item.prototype.run = function () {
- this.fun.apply(null, this.array);
-};
-process.title = 'browser';
-process.browser = true;
-process.env = {};
-process.argv = [];
-process.version = ''; // empty string to avoid regexp issues
-process.versions = {};
-
-function noop() {}
-
-process.on = noop;
-process.addListener = noop;
-process.once = noop;
-process.off = noop;
-process.removeListener = noop;
-process.removeAllListeners = noop;
-process.emit = noop;
-
-process.binding = function (name) {
- throw new Error('process.binding is not supported');
-};
-
-process.cwd = function () { return '/' };
-process.chdir = function (dir) {
- throw new Error('process.chdir is not supported');
-};
-process.umask = function() { return 0; };
-
-},{}]},{},[1]);
diff --git a/yarn.lock b/yarn.lock
index 91ffbe5d4b0..818878fe36c 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -248,6 +248,10 @@ autoprefixer@^6.3.1:
postcss "^5.2.16"
postcss-value-parser "^3.2.3"
+autosize@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/autosize/-/autosize-4.0.0.tgz#7a0599b1ba84d73bd7589b0d9da3870152c69237"
+
aws-sign2@~0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f"
@@ -2671,6 +2675,10 @@ function-bind@^1.1.1, function-bind@~1.1.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
+fuzzaldrin-plus@^0.5.0:
+ version "0.5.0"
+ resolved "https://registry.yarnpkg.com/fuzzaldrin-plus/-/fuzzaldrin-plus-0.5.0.tgz#ef5f26f0c2fc7e9e9a16ea149a802d6cb4804b1e"
+
gauge@~2.7.3:
version "2.7.4"
resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7"