summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPawel Chojnacki <pawel@chojnacki.ws>2017-06-22 15:05:52 +0200
committerPawel Chojnacki <pawel@chojnacki.ws>2017-06-22 15:05:52 +0200
commit97c42df3b804a37e659c3cda6bd8a52570f31366 (patch)
tree97c38db7f71a93a7b0db5ca2c682d6d17479cbdb
parent3833f1dd84dfec844443a5b1d9ba2bd2b911c0bc (diff)
parent11716f310dcc495600f5a17e08456a1abb296482 (diff)
downloadgitlab-ce-28717-additional-metrics-review-branch.tar.gz
Merge remote-tracking branch 'upstream/master' into 28717-additional-metrics-review-branch28717-additional-metrics-review-branch
-rw-r--r--.gitlab-ci.yml1
-rw-r--r--.gitlab/issue_templates/Bug.md9
-rw-r--r--.gitlab/issue_templates/Feature Proposal.md30
-rw-r--r--.rubocop.yml5
-rw-r--r--.rubocop_todo.yml7
-rw-r--r--CHANGELOG.md4
-rw-r--r--GITALY_SERVER_VERSION2
-rw-r--r--Gemfile9
-rw-r--r--Gemfile.lock25
-rw-r--r--app/assets/javascripts/boards/filtered_search_boards.js1
-rw-r--r--app/assets/javascripts/commit/pipelines/pipelines_bundle.js33
-rw-r--r--app/assets/javascripts/commit/pipelines/pipelines_table.js191
-rw-r--r--app/assets/javascripts/commit/pipelines/pipelines_table.vue90
-rw-r--r--app/assets/javascripts/dispatcher.js29
-rw-r--r--app/assets/javascripts/dropzone_input.js4
-rw-r--r--app/assets/javascripts/environments/components/environment_item.vue15
-rw-r--r--app/assets/javascripts/filtered_search/dropdown_hint.js2
-rw-r--r--app/assets/javascripts/filtered_search/filtered_search_manager.js1
-rw-r--r--app/assets/javascripts/gfm_auto_complete.js6
-rw-r--r--app/assets/javascripts/issuable_bulk_update_sidebar.js2
-rw-r--r--app/assets/javascripts/issue_show/components/app.vue12
-rw-r--r--app/assets/javascripts/issue_show/components/description.vue30
-rw-r--r--app/assets/javascripts/issue_show/components/fields/description.vue2
-rw-r--r--app/assets/javascripts/issue_show/index.js1
-rw-r--r--app/assets/javascripts/issue_show/stores/index.js31
-rw-r--r--app/assets/javascripts/lib/utils/datetime_utility.js2
-rw-r--r--app/assets/javascripts/locale/en/app.js2
-rw-r--r--app/assets/javascripts/locale/es/app.js2
-rw-r--r--app/assets/javascripts/locale/zh_CN/app.js2
-rw-r--r--app/assets/javascripts/merge_request_tabs.js13
-rw-r--r--app/assets/javascripts/milestone.js163
-rw-r--r--app/assets/javascripts/notes.js50
-rw-r--r--app/assets/javascripts/pipeline_schedules/components/interval_pattern_input.js15
-rw-r--r--app/assets/javascripts/pipeline_schedules/components/pipeline_schedules_callout.js14
-rw-r--r--app/assets/javascripts/pipelines/components/async_button.vue41
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines.vue87
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_actions.vue16
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_table.vue (renamed from app/assets/javascripts/vue_shared/components/pipelines_table.vue)5
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_table_row.vue (renamed from app/assets/javascripts/vue_shared/components/pipelines_table_row.vue)23
-rw-r--r--app/assets/javascripts/pipelines/mixins/pipelines.js103
-rw-r--r--app/assets/javascripts/preview_markdown.js2
-rw-r--r--app/assets/javascripts/right_sidebar.js21
-rw-r--r--app/assets/javascripts/settings_panels.js25
-rw-r--r--app/assets/javascripts/sidebar/components/time_tracking/help_state.js4
-rw-r--r--app/assets/javascripts/sidebar/components/time_tracking/sidebar_time_tracking.js8
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/mr_widget_memory_usage.js4
-rw-r--r--app/assets/stylesheets/framework/blocks.scss2
-rw-r--r--app/assets/stylesheets/framework/files.scss1
-rw-r--r--app/assets/stylesheets/framework/filters.scss5
-rw-r--r--app/assets/stylesheets/framework/forms.scss11
-rw-r--r--app/assets/stylesheets/framework/markdown_area.scss11
-rw-r--r--app/assets/stylesheets/framework/nav.scss27
-rw-r--r--app/assets/stylesheets/framework/panels.scss90
-rw-r--r--app/assets/stylesheets/framework/selects.scss29
-rw-r--r--app/assets/stylesheets/framework/sidebar.scss11
-rw-r--r--app/assets/stylesheets/framework/timeline.scss4
-rw-r--r--app/assets/stylesheets/framework/variables.scss2
-rw-r--r--app/assets/stylesheets/pages/cycle_analytics.scss2
-rw-r--r--app/assets/stylesheets/pages/groups.scss2
-rw-r--r--app/assets/stylesheets/pages/issuable.scss32
-rw-r--r--app/assets/stylesheets/pages/milestone.scss6
-rw-r--r--app/assets/stylesheets/pages/note_form.scss52
-rw-r--r--app/assets/stylesheets/pages/notes.scss88
-rw-r--r--app/assets/stylesheets/pages/projects.scss2
-rw-r--r--app/assets/stylesheets/pages/settings.scss4
-rw-r--r--app/assets/stylesheets/pages/tree.scss85
-rw-r--r--app/controllers/concerns/creates_commit.rb4
-rw-r--r--app/controllers/concerns/membership_actions.rb8
-rw-r--r--app/controllers/concerns/milestone_actions.rb2
-rw-r--r--app/controllers/dashboard/projects_controller.rb8
-rw-r--r--app/controllers/explore/projects_controller.rb4
-rw-r--r--app/controllers/jwt_controller.rb4
-rw-r--r--app/controllers/omniauth_callbacks_controller.rb4
-rw-r--r--app/controllers/profiles_controller.rb6
-rw-r--r--app/controllers/projects/application_controller.rb14
-rw-r--r--app/controllers/projects/blob_controller.rb4
-rw-r--r--app/controllers/projects/branches_controller.rb4
-rw-r--r--app/controllers/projects/commits_controller.rb8
-rw-r--r--app/controllers/projects/compare_controller.rb4
-rw-r--r--app/controllers/projects/deploy_keys_controller.rb4
-rw-r--r--app/controllers/projects/discussions_controller.rb6
-rw-r--r--app/controllers/projects/environments_controller.rb2
-rw-r--r--app/controllers/projects/git_http_client_controller.rb46
-rw-r--r--app/controllers/projects/git_http_controller.rb2
-rw-r--r--app/controllers/projects/issues_controller.rb4
-rw-r--r--app/controllers/projects/labels_controller.rb8
-rw-r--r--app/controllers/projects/merge_requests_controller.rb20
-rw-r--r--app/controllers/projects/milestones_controller.rb26
-rw-r--r--app/controllers/projects/settings/ci_cd_controller.rb4
-rw-r--r--app/controllers/projects/snippets_controller.rb6
-rw-r--r--app/controllers/projects/tags_controller.rb4
-rw-r--r--app/controllers/sessions_controller.rb4
-rw-r--r--app/controllers/sherlock/application_controller.rb4
-rw-r--r--app/controllers/users_controller.rb10
-rw-r--r--app/finders/events_finder.rb3
-rw-r--r--app/finders/group_members_finder.rb6
-rw-r--r--app/finders/group_projects_finder.rb74
-rw-r--r--app/finders/groups_finder.rb18
-rw-r--r--app/finders/issuable_finder.rb13
-rw-r--r--app/finders/projects_finder.rb60
-rw-r--r--app/helpers/application_helper.rb8
-rw-r--r--app/helpers/diff_helper.rb4
-rw-r--r--app/helpers/form_helper.rb8
-rw-r--r--app/helpers/issuables_helper.rb7
-rw-r--r--app/helpers/notes_helper.rb4
-rw-r--r--app/helpers/projects_helper.rb29
-rw-r--r--app/helpers/search_helper.rb4
-rw-r--r--app/helpers/wiki_helper.rb6
-rw-r--r--app/models/award_emoji.rb6
-rw-r--r--app/models/ci/build.rb27
-rw-r--r--app/models/ci/pipeline.rb4
-rw-r--r--app/models/ci/runner.rb4
-rw-r--r--app/models/concerns/issuable.rb14
-rw-r--r--app/models/concerns/milestoneish.rb10
-rw-r--r--app/models/concerns/relative_positioning.rb16
-rw-r--r--app/models/concerns/routable.rb16
-rw-r--r--app/models/concerns/sortable.rb12
-rw-r--r--app/models/concerns/subscribable.rb18
-rw-r--r--app/models/deployment.rb22
-rw-r--r--app/models/environment.rb6
-rw-r--r--app/models/event.rb10
-rw-r--r--app/models/group.rb12
-rw-r--r--app/models/issue.rb9
-rw-r--r--app/models/issue_collection.rb6
-rw-r--r--app/models/label.rb12
-rw-r--r--app/models/legacy_diff_note.rb2
-rw-r--r--app/models/member.rb6
-rw-r--r--app/models/merge_request.rb9
-rw-r--r--app/models/merge_request_diff.rb54
-rw-r--r--app/models/merge_request_diff_file.rb11
-rw-r--r--app/models/merge_requests_closing_issues.rb6
-rw-r--r--app/models/milestone.rb42
-rw-r--r--app/models/namespace.rb20
-rw-r--r--app/models/note.rb8
-rw-r--r--app/models/project.rb63
-rw-r--r--app/models/project_authorization.rb6
-rw-r--r--app/models/project_feature.rb7
-rw-r--r--app/models/project_services/chat_message/pipeline_message.rb2
-rw-r--r--app/models/project_services/chat_message/push_message.rb4
-rw-r--r--app/models/project_services/mattermost_slash_commands_service.rb6
-rw-r--r--app/models/project_services/slack_slash_commands_service.rb2
-rw-r--r--app/models/project_services/slash_commands_service.rb (renamed from app/models/project_services/chat_slash_commands_service.rb)6
-rw-r--r--app/models/project_team.rb8
-rw-r--r--app/models/repository.rb8
-rw-r--r--app/models/todo.rb6
-rw-r--r--app/models/user.rb85
-rw-r--r--app/models/wiki_page.rb10
-rw-r--r--app/policies/global_policy.rb2
-rw-r--r--app/serializers/issuable_entity.rb1
-rw-r--r--app/services/ci/create_pipeline_service.rb4
-rw-r--r--app/services/ci/create_trigger_request_service.rb4
-rw-r--r--app/services/ci/register_job_service.rb14
-rw-r--r--app/services/concerns/issues/resolve_discussions.rb6
-rw-r--r--app/services/create_deployment_service.rb16
-rw-r--r--app/services/files/update_service.rb4
-rw-r--r--app/services/git_push_service.rb4
-rw-r--r--app/services/issuable_base_service.rb8
-rw-r--r--app/services/issues/create_service.rb4
-rw-r--r--app/services/labels/promote_service.rb28
-rw-r--r--app/services/labels/transfer_service.rb20
-rw-r--r--app/services/members/authorized_destroy_service.rb30
-rw-r--r--app/services/merge_requests/conflicts/resolve_service.rb8
-rw-r--r--app/services/merge_requests/merge_service.rb4
-rw-r--r--app/services/merge_requests/refresh_service.rb10
-rw-r--r--app/services/merge_requests/update_service.rb6
-rw-r--r--app/services/notes/create_service.rb8
-rw-r--r--app/services/notes/quick_actions_service.rb (renamed from app/services/notes/slash_commands_service.rb)6
-rw-r--r--app/services/preview_markdown_service.rb12
-rw-r--r--app/services/projects/autocomplete_service.rb2
-rw-r--r--app/services/projects/transfer_service.rb114
-rw-r--r--app/services/quick_actions/interpret_service.rb (renamed from app/services/slash_commands/interpret_service.rb)12
-rw-r--r--app/services/tags/create_service.rb4
-rw-r--r--app/services/users/refresh_authorized_projects_service.rb2
-rw-r--r--app/validators/dynamic_path_validator.rb2
-rw-r--r--app/views/admin/application_settings/_form.html.haml4
-rw-r--r--app/views/admin/broadcast_messages/_form.html.haml4
-rw-r--r--app/views/notify/pipeline_failed_email.html.haml6
-rw-r--r--app/views/notify/pipeline_success_email.html.haml6
-rw-r--r--app/views/profiles/show.html.haml15
-rw-r--r--app/views/projects/_find_file_link.html.haml2
-rw-r--r--app/views/projects/_md_preview.html.haml6
-rw-r--r--app/views/projects/_visibility_select.html.haml4
-rw-r--r--app/views/projects/_zen.html.haml9
-rw-r--r--app/views/projects/blob/_breadcrumb.html.haml35
-rw-r--r--app/views/projects/blob/_upload.html.haml8
-rw-r--r--app/views/projects/buttons/_download.html.haml2
-rw-r--r--app/views/projects/buttons/_dropdown.html.haml2
-rw-r--r--app/views/projects/buttons/_fork.html.haml6
-rw-r--r--app/views/projects/commit/_change.html.haml23
-rw-r--r--app/views/projects/commit/_commit_box.html.haml28
-rw-r--r--app/views/projects/commits/_commit.html.haml8
-rw-r--r--app/views/projects/edit.html.haml6
-rw-r--r--app/views/projects/issues/_issue_by_email.html.haml2
-rw-r--r--app/views/projects/issues/show.html.haml8
-rw-r--r--app/views/projects/merge_requests/conflicts/_submit_form.html.haml2
-rw-r--r--app/views/projects/notes/_more_actions_dropdown.html.haml33
-rw-r--r--app/views/projects/pipeline_schedules/_form.html.haml10
-rw-r--r--app/views/projects/pipeline_schedules/_pipeline_schedule.html.haml4
-rw-r--r--app/views/projects/pipeline_schedules/index.html.haml2
-rw-r--r--app/views/projects/project_members/_new_project_member.html.haml4
-rw-r--r--app/views/projects/project_members/_new_shared_group.html.haml2
-rw-r--r--app/views/projects/registry/repositories/_image.html.haml15
-rw-r--r--app/views/projects/tree/_tree_header.html.haml146
-rw-r--r--app/views/shared/_commit_message_container.html.haml2
-rw-r--r--app/views/shared/_new_commit_form.html.haml8
-rw-r--r--app/views/shared/_new_merge_request_checkbox.html.haml8
-rw-r--r--app/views/shared/form_elements/_description.html.haml10
-rw-r--r--app/views/shared/issuable/_bulk_update_sidebar.html.haml2
-rw-r--r--app/views/shared/issuable/_nav.html.haml19
-rw-r--r--app/views/shared/milestones/_issuables.html.haml6
-rw-r--r--app/views/shared/milestones/_tabs.html.haml6
-rw-r--r--app/views/shared/notes/_form.html.haml12
-rw-r--r--app/views/shared/notes/_hints.html.haml6
-rw-r--r--app/views/shared/notes/_notes_with_form.html.haml13
-rw-r--r--app/workers/merge_worker.rb4
-rw-r--r--app/workers/process_commit_worker.rb8
-rw-r--r--app/workers/project_cache_worker.rb6
-rw-r--r--app/workers/propagate_service_template_worker.rb6
-rw-r--r--app/workers/prune_old_events_worker.rb8
-rw-r--r--app/workers/repository_check/batch_worker.rb8
-rw-r--r--app/workers/update_user_activity_worker.rb4
-rw-r--r--changelogs/unreleased/12151-add-since-and-until-params-to-issuables.yml4
-rw-r--r--changelogs/unreleased/25102-files-view-button.yml4
-rw-r--r--changelogs/unreleased/25164-disable-fork-on-project-limit.yml4
-rw-r--r--changelogs/unreleased/26212-upload-user-avatar-trough-api.yml4
-rw-r--r--changelogs/unreleased/27070-rename-slash-commands-to-quick-actions.yml5
-rw-r--r--changelogs/unreleased/27645-html-email-brackets-bug.yml4
-rw-r--r--changelogs/unreleased/27697-make-arrow-icons-consistent-in-dropdown.yml4
-rw-r--r--changelogs/unreleased/28139-use-color-input-broadcast-messages.yml4
-rw-r--r--changelogs/unreleased/30213-project-transfer-move-rollback.yml4
-rw-r--r--changelogs/unreleased/30725-reset-user-limits-when-unchecking-external-user.yml4
-rw-r--r--changelogs/unreleased/32301-filter-archive-project-on-param-present.yml4
-rw-r--r--changelogs/unreleased/33441-supplement_simplified_chinese_translation_of_i18n.yml4
-rw-r--r--changelogs/unreleased/33461-display-user-id.yml4
-rw-r--r--changelogs/unreleased/33837-remove-trash-on-registry-image.yml4
-rw-r--r--changelogs/unreleased/33878_fix_edit_deploy_key.yml4
-rw-r--r--changelogs/unreleased/33917-mr-comment-system-note-highlight-don-t-have-the-same-width.yml4
-rw-r--r--changelogs/unreleased/34008-fix-CI_ENVIRONMENT_URL-2.yml4
-rw-r--r--changelogs/unreleased/disable-environment-list-refresh.yml4
-rw-r--r--changelogs/unreleased/dt-printing-to-api.yml4
-rw-r--r--changelogs/unreleased/fix-33259.yml4
-rw-r--r--changelogs/unreleased/fix-overflow-slash-commands.yml4
-rw-r--r--changelogs/unreleased/fixed-confidential-issue-bar.yml4
-rw-r--r--changelogs/unreleased/issue_20900.yml4
-rw-r--r--changelogs/unreleased/issue_33205.yml4
-rw-r--r--changelogs/unreleased/moved-submodules.yml4
-rw-r--r--changelogs/unreleased/mr-widget-memory-usage-tech-debt-fix.yml4
-rw-r--r--changelogs/unreleased/reduce-sidekiq-wait-timings.yml4
-rw-r--r--changelogs/unreleased/refactor-projects-finder-init-collection.yml5
-rw-r--r--changelogs/unreleased/replase_spinach_spec_create-feature.yml4
-rw-r--r--config/boot.rb4
-rw-r--r--config/gitlab.yml.example6
-rw-r--r--config/initializers/8_metrics.rb4
-rw-r--r--config/karma.config.js10
-rw-r--r--config/locales/en.yml215
-rw-r--r--config/locales/es.yml1
-rw-r--r--config/webpack.config.js23
-rw-r--r--db/fixtures/development/19_environments.rb2
-rw-r--r--db/migrate/20161124141322_migrate_process_commit_worker_jobs.rb6
-rw-r--r--db/migrate/20161207231620_fixup_environment_name_uniqueness.rb32
-rw-r--r--db/migrate/20161207231626_add_environment_slug.rb8
-rw-r--r--db/migrate/20170316163800_rename_system_namespaces.rb10
-rw-r--r--db/migrate/20170503140202_turn_nested_groups_into_regular_groups_for_mysql.rb14
-rw-r--r--db/migrate/20170526185602_add_stage_id_to_ci_builds.rb8
-rw-r--r--db/migrate/20170608171156_create_merge_request_diff_files.rb22
-rw-r--r--db/migrate/20170614115405_merge_request_diff_file_limits_to_mysql.rb1
-rw-r--r--db/migrate/20170619144837_add_index_for_head_pipeline_merge_request.rb15
-rw-r--r--db/migrate/merge_request_diff_file_limits_to_mysql.rb12
-rw-r--r--db/post_migrate/20161109150329_fix_project_records_with_invalid_visibility.rb22
-rw-r--r--db/post_migrate/20161221153951_rename_reserved_project_names.rb12
-rw-r--r--db/post_migrate/20170104150317_requeue_pending_delete_projects.rb12
-rw-r--r--db/post_migrate/20170106142508_fill_authorized_projects.rb4
-rw-r--r--db/post_migrate/20170313133418_rename_more_reserved_project_names.rb12
-rw-r--r--db/post_migrate/20170324160416_migrate_user_activities_to_users_last_activity_on.rb10
-rw-r--r--db/post_migrate/20170502070007_enable_auto_cancel_pending_pipelines_for_all.rb2
-rw-r--r--db/post_migrate/20170502101023_cleanup_namespaceless_pending_delete_projects.rb12
-rw-r--r--db/post_migrate/20170508170547_add_head_pipeline_for_each_merge_request.rb10
-rw-r--r--db/post_migrate/20170526185901_remove_stage_id_index_from_builds.rb18
-rw-r--r--db/post_migrate/20170526185921_migrate_build_stage_reference.rb22
-rw-r--r--db/post_migrate/20170526190000_migrate_build_stage_reference_again.rb27
-rw-r--r--db/post_migrate/20170609183112_remove_position_from_issuables.rb8
-rw-r--r--db/post_migrate/20170621102400_add_stage_id_index_to_builds.rb21
-rw-r--r--db/schema.rb22
-rw-r--r--doc/README.md2
-rw-r--r--doc/administration/high_availability/nfs.md46
-rw-r--r--doc/administration/high_availability/redis_source.md1
-rw-r--r--doc/administration/job_artifacts.md14
-rw-r--r--doc/administration/monitoring/prometheus/gitlab_metrics.md47
-rw-r--r--doc/administration/monitoring/prometheus/gitlab_monitor_exporter.md2
-rw-r--r--doc/administration/monitoring/prometheus/index.md10
-rw-r--r--doc/api/README.md2
-rw-r--r--doc/api/issues.md3
-rw-r--r--doc/api/merge_requests.md2
-rw-r--r--doc/api/projects.md3
-rw-r--r--doc/api/users.md5
-rw-r--r--doc/development/limit_ee_conflicts.md4
-rw-r--r--doc/install/requirements.md91
-rw-r--r--doc/integration/chat_commands.md15
-rw-r--r--doc/integration/slash_commands.md14
-rw-r--r--doc/update/README.md16
-rw-r--r--doc/user/discussions/index.md4
-rw-r--r--doc/user/group/subgroups/index.md6
-rw-r--r--doc/user/permissions.md1
-rw-r--r--doc/user/project/integrations/img/merge_request_performance.pngbin66775 -> 60194 bytes
-rw-r--r--doc/user/project/integrations/prometheus.md8
-rw-r--r--doc/user/project/integrations/slack_slash_commands.md4
-rw-r--r--doc/user/project/issues/confidential_issues.md5
-rwxr-xr-xdoc/user/project/issues/img/confidential_issues_issue_page.pngbin90001 -> 14230 bytes
-rw-r--r--doc/user/project/issues/issues_functionalities.md4
-rw-r--r--doc/user/project/quick_actions.md39
-rw-r--r--doc/user/project/settings/import_export.md17
-rw-r--r--doc/user/project/slash_commands.md40
-rw-r--r--doc/workflow/README.md2
-rw-r--r--doc/workflow/time_tracking.md8
-rw-r--r--features/project/create.feature14
-rw-r--r--lib/api/access_requests.rb4
-rw-r--r--lib/api/branches.rb8
-rw-r--r--lib/api/deploy_keys.rb2
-rw-r--r--lib/api/entities.rb14
-rw-r--r--lib/api/helpers/internal_helpers.rb7
-rw-r--r--lib/api/internal.rb13
-rw-r--r--lib/api/issues.rb2
-rw-r--r--lib/api/merge_requests.rb4
-rw-r--r--lib/api/milestones.rb4
-rw-r--r--lib/api/notes.rb4
-rw-r--r--lib/api/projects.rb2
-rw-r--r--lib/api/services.rb4
-rw-r--r--lib/api/tags.rb16
-rw-r--r--lib/api/users.rb29
-rw-r--r--lib/api/v3/branches.rb8
-rw-r--r--lib/api/v3/entities.rb6
-rw-r--r--lib/api/v3/helpers.rb5
-rw-r--r--lib/api/v3/notes.rb4
-rw-r--r--lib/api/v3/projects.rb2
-rw-r--r--lib/api/v3/services.rb4
-rw-r--r--lib/api/v3/tags.rb4
-rw-r--r--lib/api/v3/users.rb22
-rw-r--r--lib/banzai/reference_extractor.rb4
-rw-r--r--lib/banzai/reference_parser/issue_parser.rb4
-rw-r--r--lib/banzai/reference_parser/user_parser.rb4
-rw-r--r--lib/ci/charts.rb26
-rw-r--r--lib/github/import.rb30
-rw-r--r--lib/github/representation/branch.rb14
-rw-r--r--lib/github/representation/pull_request.rb54
-rw-r--r--lib/gitlab/background_migration.rb4
-rw-r--r--lib/gitlab/cache/ci/project_pipeline_status.rb4
-rw-r--r--lib/gitlab/ci/pipeline_duration.rb4
-rw-r--r--lib/gitlab/conflict/file_collection.rb6
-rw-r--r--lib/gitlab/contributions_calendar.rb46
-rw-r--r--lib/gitlab/current_settings.rb49
-rw-r--r--lib/gitlab/cycle_analytics/base_query.rb18
-rw-r--r--lib/gitlab/database.rb16
-rw-r--r--lib/gitlab/database/median.rb22
-rw-r--r--lib/gitlab/database/migration_helpers.rb36
-rw-r--r--lib/gitlab/database/rename_reserved_paths_migration/v1/rename_base.rb4
-rw-r--r--lib/gitlab/database/rename_reserved_paths_migration/v1/rename_namespaces.rb14
-rw-r--r--lib/gitlab/diff/line.rb20
-rw-r--r--lib/gitlab/diff/parallel_diff.rb20
-rw-r--r--lib/gitlab/downtime_check.rb4
-rw-r--r--lib/gitlab/email/html_parser.rb7
-rw-r--r--lib/gitlab/fake_application_settings.rb27
-rw-r--r--lib/gitlab/git/blob.rb45
-rw-r--r--lib/gitlab/git/commit.rb2
-rw-r--r--lib/gitlab/git/diff.rb17
-rw-r--r--lib/gitlab/git/gitmodules_parser.rb77
-rw-r--r--lib/gitlab/git/repository.rb52
-rw-r--r--lib/gitlab/git_access.rb21
-rw-r--r--lib/gitlab/gitaly_client.rb22
-rw-r--r--lib/gitlab/gitaly_client/commit.rb36
-rw-r--r--lib/gitlab/gitaly_client/notifications.rb12
-rw-r--r--lib/gitlab/gitaly_client/ref.rb21
-rw-r--r--lib/gitlab/group_hierarchy.rb69
-rw-r--r--lib/gitlab/highlight.rb4
-rw-r--r--lib/gitlab/import_export.rb2
-rw-r--r--lib/gitlab/import_export/import_export.yml7
-rw-r--r--lib/gitlab/import_export/json_hash_builder.rb4
-rw-r--r--lib/gitlab/import_export/relation_factory.rb5
-rw-r--r--lib/gitlab/job_waiter.rb2
-rw-r--r--lib/gitlab/ldap/user.rb6
-rw-r--r--lib/gitlab/metrics/influx_db.rb4
-rw-r--r--lib/gitlab/metrics/prometheus.rb16
-rw-r--r--lib/gitlab/metrics/system.rb8
-rw-r--r--lib/gitlab/other_markup.rb4
-rw-r--r--lib/gitlab/performance_bar/peek_query_tracker.rb4
-rw-r--r--lib/gitlab/project_authorizations/with_nested_groups.rb68
-rw-r--r--lib/gitlab/project_authorizations/without_nested_groups.rb6
-rw-r--r--lib/gitlab/quick_actions/command_definition.rb (renamed from lib/gitlab/slash_commands/command_definition.rb)2
-rw-r--r--lib/gitlab/quick_actions/dsl.rb (renamed from lib/gitlab/slash_commands/dsl.rb)6
-rw-r--r--lib/gitlab/quick_actions/extractor.rb (renamed from lib/gitlab/slash_commands/extractor.rb)6
-rw-r--r--lib/gitlab/regex.rb2
-rw-r--r--lib/gitlab/repo_path.rb21
-rw-r--r--lib/gitlab/shell.rb4
-rw-r--r--lib/gitlab/sherlock/line_profiler.rb4
-rw-r--r--lib/gitlab/sherlock/query.rb8
-rw-r--r--lib/gitlab/slash_commands/base_command.rb (renamed from lib/gitlab/chat_commands/base_command.rb)2
-rw-r--r--lib/gitlab/slash_commands/command.rb (renamed from lib/gitlab/chat_commands/command.rb)14
-rw-r--r--lib/gitlab/slash_commands/deploy.rb (renamed from lib/gitlab/chat_commands/deploy.rb)8
-rw-r--r--lib/gitlab/slash_commands/help.rb (renamed from lib/gitlab/chat_commands/help.rb)4
-rw-r--r--lib/gitlab/slash_commands/issue_command.rb (renamed from lib/gitlab/chat_commands/issue_command.rb)2
-rw-r--r--lib/gitlab/slash_commands/issue_new.rb (renamed from lib/gitlab/chat_commands/issue_new.rb)4
-rw-r--r--lib/gitlab/slash_commands/issue_search.rb (renamed from lib/gitlab/chat_commands/issue_search.rb)2
-rw-r--r--lib/gitlab/slash_commands/issue_show.rb (renamed from lib/gitlab/chat_commands/issue_show.rb)6
-rw-r--r--lib/gitlab/slash_commands/presenters/access.rb (renamed from lib/gitlab/chat_commands/presenters/access.rb)2
-rw-r--r--lib/gitlab/slash_commands/presenters/base.rb (renamed from lib/gitlab/chat_commands/presenters/base.rb)2
-rw-r--r--lib/gitlab/slash_commands/presenters/deploy.rb (renamed from lib/gitlab/chat_commands/presenters/deploy.rb)2
-rw-r--r--lib/gitlab/slash_commands/presenters/help.rb (renamed from lib/gitlab/chat_commands/presenters/help.rb)2
-rw-r--r--lib/gitlab/slash_commands/presenters/issue_base.rb (renamed from lib/gitlab/chat_commands/presenters/issue_base.rb)2
-rw-r--r--lib/gitlab/slash_commands/presenters/issue_new.rb (renamed from lib/gitlab/chat_commands/presenters/issue_new.rb)2
-rw-r--r--lib/gitlab/slash_commands/presenters/issue_search.rb (renamed from lib/gitlab/chat_commands/presenters/issue_search.rb)2
-rw-r--r--lib/gitlab/slash_commands/presenters/issue_show.rb (renamed from lib/gitlab/chat_commands/presenters/issue_show.rb)2
-rw-r--r--lib/gitlab/slash_commands/result.rb (renamed from lib/gitlab/chat_commands/result.rb)2
-rw-r--r--lib/gitlab/sql/recursive_cte.rb8
-rw-r--r--lib/gitlab/visibility_level.rb26
-rw-r--r--lib/gitlab/workhorse.rb11
-rw-r--r--lib/tasks/gitlab/gitaly.rake5
-rw-r--r--lib/tasks/migrate/add_limits_mysql.rake2
-rw-r--r--locale/bg/gitlab.po3
-rw-r--r--locale/de/gitlab.po3
-rw-r--r--locale/en/gitlab.po736
-rw-r--r--locale/es/gitlab.po256
-rw-r--r--locale/gitlab.pot746
-rw-r--r--locale/pt_BR/gitlab.po3
-rw-r--r--locale/zh_CN/gitlab.po897
-rw-r--r--locale/zh_HK/gitlab.po3
-rw-r--r--locale/zh_TW/gitlab.po3
-rw-r--r--spec/controllers/admin/users_controller_spec.rb4
-rw-r--r--spec/controllers/groups_controller_spec.rb9
-rw-r--r--spec/controllers/import/bitbucket_controller_spec.rb82
-rw-r--r--spec/controllers/import/github_controller_spec.rb8
-rw-r--r--spec/controllers/import/gitlab_controller_spec.rb82
-rw-r--r--spec/controllers/projects/blob_controller_spec.rb4
-rw-r--r--spec/controllers/projects/branches_controller_spec.rb12
-rw-r--r--spec/controllers/projects/commit_controller_spec.rb4
-rw-r--r--spec/controllers/projects/environments_controller_spec.rb22
-rw-r--r--spec/controllers/projects/issues_controller_spec.rb14
-rw-r--r--spec/controllers/projects/mattermosts_controller_spec.rb4
-rw-r--r--spec/controllers/projects/merge_requests_controller_spec.rb26
-rw-r--r--spec/controllers/projects/raw_controller_spec.rb8
-rw-r--r--spec/controllers/projects/services_controller_spec.rb4
-rw-r--r--spec/controllers/projects/snippets_controller_spec.rb32
-rw-r--r--spec/controllers/projects/tree_controller_spec.rb12
-rw-r--r--spec/controllers/sent_notifications_controller_spec.rb8
-rw-r--r--spec/controllers/sessions_controller_spec.rb16
-rw-r--r--spec/controllers/snippets_controller_spec.rb32
-rw-r--r--spec/factories/application_settings.rb4
-rw-r--r--spec/factories/projects.rb4
-rw-r--r--spec/features/abuse_report_spec.rb2
-rw-r--r--spec/features/admin/admin_abuse_reports_spec.rb2
-rw-r--r--spec/features/admin/admin_active_tab_spec.rb2
-rw-r--r--spec/features/admin/admin_appearance_spec.rb8
-rw-r--r--spec/features/admin/admin_broadcast_messages_spec.rb2
-rw-r--r--spec/features/admin/admin_browse_spam_logs_spec.rb2
-rw-r--r--spec/features/admin/admin_browses_logs_spec.rb2
-rw-r--r--spec/features/admin/admin_builds_spec.rb2
-rw-r--r--spec/features/admin/admin_cohorts_spec.rb2
-rw-r--r--spec/features/admin/admin_conversational_development_index_spec.rb2
-rw-r--r--spec/features/admin/admin_deploy_keys_spec.rb2
-rw-r--r--spec/features/admin/admin_disables_git_access_protocol_spec.rb2
-rw-r--r--spec/features/admin/admin_disables_two_factor_spec.rb4
-rw-r--r--spec/features/admin/admin_groups_spec.rb2
-rw-r--r--spec/features/admin/admin_health_check_spec.rb2
-rw-r--r--spec/features/admin/admin_hook_logs_spec.rb2
-rw-r--r--spec/features/admin/admin_hooks_spec.rb2
-rw-r--r--spec/features/admin/admin_labels_spec.rb2
-rw-r--r--spec/features/admin/admin_manage_applications_spec.rb2
-rw-r--r--spec/features/admin/admin_projects_spec.rb6
-rw-r--r--spec/features/admin/admin_requests_profiles_spec.rb2
-rw-r--r--spec/features/admin/admin_runners_spec.rb2
-rw-r--r--spec/features/admin/admin_settings_spec.rb2
-rw-r--r--spec/features/admin/admin_system_info_spec.rb2
-rw-r--r--spec/features/admin/admin_users_impersonation_tokens_spec.rb2
-rw-r--r--spec/features/admin/admin_users_spec.rb10
-rw-r--r--spec/features/admin/admin_uses_repository_checks_spec.rb2
-rw-r--r--spec/features/atom/dashboard_spec.rb4
-rw-r--r--spec/features/atom/issues_spec.rb14
-rw-r--r--spec/features/atom/users_spec.rb4
-rw-r--r--spec/features/auto_deploy_spec.rb2
-rw-r--r--spec/features/boards/add_issues_modal_spec.rb2
-rw-r--r--spec/features/boards/boards_spec.rb16
-rw-r--r--spec/features/boards/issue_ordering_spec.rb2
-rw-r--r--spec/features/boards/keyboard_shortcut_spec.rb2
-rw-r--r--spec/features/boards/modal_filter_spec.rb2
-rw-r--r--spec/features/boards/new_issue_spec.rb2
-rw-r--r--spec/features/boards/sidebar_spec.rb2
-rw-r--r--spec/features/boards/sub_group_project_spec.rb2
-rw-r--r--spec/features/calendar_spec.rb2
-rw-r--r--spec/features/ci_lint_spec.rb2
-rw-r--r--spec/features/commits_spec.rb12
-rw-r--r--spec/features/container_registry_spec.rb2
-rw-r--r--spec/features/copy_as_gfm_spec.rb2
-rw-r--r--spec/features/cycle_analytics_spec.rb8
-rw-r--r--spec/features/dashboard/active_tab_spec.rb2
-rw-r--r--spec/features/dashboard/activity_spec.rb2
-rw-r--r--spec/features/dashboard/archived_projects_spec.rb2
-rw-r--r--spec/features/dashboard/datetime_on_tooltips_spec.rb6
-rw-r--r--spec/features/dashboard/group_spec.rb2
-rw-r--r--spec/features/dashboard/groups_list_spec.rb8
-rw-r--r--spec/features/dashboard/help_spec.rb2
-rw-r--r--spec/features/dashboard/issuables_counter_spec.rb2
-rw-r--r--spec/features/dashboard/issues_spec.rb7
-rw-r--r--spec/features/dashboard/label_filter_spec.rb2
-rw-r--r--spec/features/dashboard/merge_requests_spec.rb2
-rw-r--r--spec/features/dashboard/milestone_filter_spec.rb2
-rw-r--r--spec/features/dashboard/milestone_tabs_spec.rb4
-rw-r--r--spec/features/dashboard/projects_spec.rb2
-rw-r--r--spec/features/dashboard/shortcuts_spec.rb2
-rw-r--r--spec/features/dashboard/snippets_spec.rb4
-rw-r--r--spec/features/dashboard/user_filters_projects_spec.rb2
-rw-r--r--spec/features/dashboard_issues_spec.rb2
-rw-r--r--spec/features/dashboard_milestones_spec.rb2
-rw-r--r--spec/features/discussion_comments/commit_spec.rb2
-rw-r--r--spec/features/discussion_comments/issue_spec.rb2
-rw-r--r--spec/features/discussion_comments/merge_request_spec.rb2
-rw-r--r--spec/features/discussion_comments/snippets_spec.rb2
-rw-r--r--spec/features/expand_collapse_diffs_spec.rb2
-rw-r--r--spec/features/explore/groups_list_spec.rb2
-rw-r--r--spec/features/explore/new_menu_spec.rb4
-rw-r--r--spec/features/gitlab_flavored_markdown_spec.rb17
-rw-r--r--spec/features/global_search_spec.rb2
-rw-r--r--spec/features/groups/activity_spec.rb2
-rw-r--r--spec/features/groups/empty_states_spec.rb2
-rw-r--r--spec/features/groups/group_name_toggle_spec.rb2
-rw-r--r--spec/features/groups/group_settings_spec.rb2
-rw-r--r--spec/features/groups/labels/edit_spec.rb2
-rw-r--r--spec/features/groups/members/last_owner_cannot_leave_group_spec.rb2
-rw-r--r--spec/features/groups/members/list_spec.rb2
-rw-r--r--spec/features/groups/members/member_cannot_request_access_to_his_project_spec.rb2
-rw-r--r--spec/features/groups/members/member_leaves_group_spec.rb2
-rw-r--r--spec/features/groups/members/owner_manages_access_requests_spec.rb2
-rw-r--r--spec/features/groups/members/sorting_spec.rb2
-rw-r--r--spec/features/groups/members/user_requests_access_spec.rb2
-rw-r--r--spec/features/groups/milestone_spec.rb2
-rw-r--r--spec/features/groups/show_spec.rb2
-rw-r--r--spec/features/groups_spec.rb10
-rw-r--r--spec/features/help_pages_spec.rb4
-rw-r--r--spec/features/issuables/issuable_list_spec.rb2
-rw-r--r--spec/features/issues/award_emoji_spec.rb10
-rw-r--r--spec/features/issues/award_spec.rb2
-rw-r--r--spec/features/issues/bulk_assignment_labels_spec.rb23
-rw-r--r--spec/features/issues/create_branch_merge_request_spec.rb2
-rw-r--r--spec/features/issues/create_issue_for_discussions_in_merge_request_spec.rb4
-rw-r--r--spec/features/issues/create_issue_for_single_discussion_in_merge_request_spec.rb4
-rw-r--r--spec/features/issues/filtered_search/dropdown_assignee_spec.rb2
-rw-r--r--spec/features/issues/filtered_search/dropdown_author_spec.rb2
-rw-r--r--spec/features/issues/filtered_search/dropdown_hint_spec.rb2
-rw-r--r--spec/features/issues/filtered_search/dropdown_label_spec.rb2
-rw-r--r--spec/features/issues/filtered_search/dropdown_milestone_spec.rb2
-rw-r--r--spec/features/issues/filtered_search/search_bar_spec.rb2
-rw-r--r--spec/features/issues/filtered_search/visual_tokens_spec.rb2
-rw-r--r--spec/features/issues/form_spec.rb16
-rw-r--r--spec/features/issues/gfm_autocomplete_spec.rb4
-rw-r--r--spec/features/issues/issue_sidebar_spec.rb2
-rw-r--r--spec/features/issues/markdown_toolbar_spec.rb2
-rw-r--r--spec/features/issues/move_spec.rb2
-rw-r--r--spec/features/issues/note_polling_spec.rb6
-rw-r--r--spec/features/issues/notes_on_issues_spec.rb2
-rw-r--r--spec/features/issues/spam_issues_spec.rb2
-rw-r--r--spec/features/issues/todo_spec.rb2
-rw-r--r--spec/features/issues/update_issues_spec.rb2
-rw-r--r--spec/features/issues/user_uses_slash_commands_spec.rb16
-rw-r--r--spec/features/issues_spec.rb81
-rw-r--r--spec/features/login_spec.rb30
-rw-r--r--spec/features/markdown_spec.rb16
-rw-r--r--spec/features/merge_requests/assign_issues_spec.rb2
-rw-r--r--spec/features/merge_requests/award_spec.rb2
-rw-r--r--spec/features/merge_requests/check_if_mergeable_with_unresolved_discussions_spec.rb2
-rw-r--r--spec/features/merge_requests/cherry_pick_spec.rb2
-rw-r--r--spec/features/merge_requests/closes_issues_spec.rb2
-rw-r--r--spec/features/merge_requests/conflicts_spec.rb4
-rw-r--r--spec/features/merge_requests/create_new_mr_spec.rb2
-rw-r--r--spec/features/merge_requests/created_from_fork_spec.rb2
-rw-r--r--spec/features/merge_requests/deleted_source_branch_spec.rb2
-rw-r--r--spec/features/merge_requests/diff_notes_avatars_spec.rb2
-rw-r--r--spec/features/merge_requests/diff_notes_resolve_spec.rb6
-rw-r--r--spec/features/merge_requests/diffs_spec.rb6
-rw-r--r--spec/features/merge_requests/discussion_spec.rb2
-rw-r--r--spec/features/merge_requests/edit_mr_spec.rb2
-rw-r--r--spec/features/merge_requests/filter_by_labels_spec.rb2
-rw-r--r--spec/features/merge_requests/filter_by_milestone_spec.rb2
-rw-r--r--spec/features/merge_requests/filter_merge_requests_spec.rb2
-rw-r--r--spec/features/merge_requests/form_spec.rb18
-rw-r--r--spec/features/merge_requests/merge_commit_message_toggle_spec.rb2
-rw-r--r--spec/features/merge_requests/merge_immediately_with_pipeline_spec.rb2
-rw-r--r--spec/features/merge_requests/merge_when_pipeline_succeeds_spec.rb4
-rw-r--r--spec/features/merge_requests/mini_pipeline_graph_spec.rb2
-rw-r--r--spec/features/merge_requests/only_allow_merge_if_build_succeeds_spec.rb2
-rw-r--r--spec/features/merge_requests/pipelines_spec.rb2
-rw-r--r--spec/features/merge_requests/target_branch_spec.rb2
-rw-r--r--spec/features/merge_requests/toggle_whitespace_changes_spec.rb2
-rw-r--r--spec/features/merge_requests/toggler_behavior_spec.rb2
-rw-r--r--spec/features/merge_requests/update_merge_requests_spec.rb2
-rw-r--r--spec/features/merge_requests/user_posts_diff_notes_spec.rb2
-rw-r--r--spec/features/merge_requests/user_posts_notes_spec.rb10
-rw-r--r--spec/features/merge_requests/user_sees_system_notes_spec.rb2
-rw-r--r--spec/features/merge_requests/user_uses_slash_commands_spec.rb24
-rw-r--r--spec/features/merge_requests/versions_spec.rb2
-rw-r--r--spec/features/merge_requests/widget_deployments_spec.rb2
-rw-r--r--spec/features/merge_requests/widget_spec.rb6
-rw-r--r--spec/features/merge_requests/wip_message_spec.rb2
-rw-r--r--spec/features/milestone_spec.rb2
-rw-r--r--spec/features/milestones/milestones_spec.rb109
-rw-r--r--spec/features/milestones/show_spec.rb2
-rw-r--r--spec/features/participants_autocomplete_spec.rb2
-rw-r--r--spec/features/profile_spec.rb2
-rw-r--r--spec/features/profiles/account_spec.rb2
-rw-r--r--spec/features/profiles/chat_names_spec.rb2
-rw-r--r--spec/features/profiles/keys_spec.rb2
-rw-r--r--spec/features/profiles/oauth_applications_spec.rb2
-rw-r--r--spec/features/profiles/password_spec.rb2
-rw-r--r--spec/features/profiles/personal_access_tokens_spec.rb2
-rw-r--r--spec/features/profiles/preferences_spec.rb2
-rw-r--r--spec/features/profiles/user_changes_notified_of_own_activity_spec.rb2
-rw-r--r--spec/features/projects/activity/rss_spec.rb2
-rw-r--r--spec/features/projects/badges/coverage_spec.rb4
-rw-r--r--spec/features/projects/badges/list_spec.rb2
-rw-r--r--spec/features/projects/blobs/edit_spec.rb10
-rw-r--r--spec/features/projects/branches/download_buttons_spec.rb2
-rw-r--r--spec/features/projects/branches/new_branch_ref_dropdown_spec.rb2
-rw-r--r--spec/features/projects/branches_spec.rb15
-rw-r--r--spec/features/projects/commit/builds_spec.rb2
-rw-r--r--spec/features/projects/commit/cherry_pick_spec.rb5
-rw-r--r--spec/features/projects/commit/mini_pipeline_graph_spec.rb2
-rw-r--r--spec/features/projects/commit/rss_spec.rb2
-rw-r--r--spec/features/projects/compare_spec.rb2
-rw-r--r--spec/features/projects/deploy_keys_spec.rb2
-rw-r--r--spec/features/projects/developer_views_empty_project_instructions_spec.rb2
-rw-r--r--spec/features/projects/edit_spec.rb2
-rw-r--r--spec/features/projects/environments/environment_metrics_spec.rb2
-rw-r--r--spec/features/projects/environments/environment_spec.rb2
-rw-r--r--spec/features/projects/environments/environments_spec.rb2
-rw-r--r--spec/features/projects/features_visibility_spec.rb10
-rw-r--r--spec/features/projects/files/browse_files_spec.rb2
-rw-r--r--spec/features/projects/files/creating_a_file_spec.rb2
-rw-r--r--spec/features/projects/files/dockerfile_dropdown_spec.rb2
-rw-r--r--spec/features/projects/files/download_buttons_spec.rb2
-rw-r--r--spec/features/projects/files/edit_file_soft_wrap_spec.rb2
-rw-r--r--spec/features/projects/files/editing_a_file_spec.rb2
-rw-r--r--spec/features/projects/files/files_sort_submodules_with_folders_spec.rb2
-rw-r--r--spec/features/projects/files/find_file_keyboard_spec.rb2
-rw-r--r--spec/features/projects/files/find_files_spec.rb2
-rw-r--r--spec/features/projects/files/gitignore_dropdown_spec.rb2
-rw-r--r--spec/features/projects/files/gitlab_ci_yml_dropdown_spec.rb2
-rw-r--r--spec/features/projects/files/project_owner_creates_license_file_spec.rb2
-rw-r--r--spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb2
-rw-r--r--spec/features/projects/files/template_type_dropdown_spec.rb2
-rw-r--r--spec/features/projects/files/undo_template_spec.rb2
-rw-r--r--spec/features/projects/gfm_autocomplete_load_spec.rb2
-rw-r--r--spec/features/projects/group_links_spec.rb2
-rw-r--r--spec/features/projects/guest_navigation_menu_spec.rb2
-rw-r--r--spec/features/projects/import_export/export_file_spec.rb2
-rw-r--r--spec/features/projects/import_export/import_file_spec.rb4
-rw-r--r--spec/features/projects/import_export/namespace_export_file_spec.rb2
-rw-r--r--spec/features/projects/import_export/test_project_export.tar.gzbin681478 -> 681481 bytes
-rw-r--r--spec/features/projects/issuable_templates_spec.rb6
-rw-r--r--spec/features/projects/issues/list_spec.rb2
-rw-r--r--spec/features/projects/issues/rss_spec.rb2
-rw-r--r--spec/features/projects/jobs_spec.rb6
-rw-r--r--spec/features/projects/labels/issues_sorted_by_priority_spec.rb4
-rw-r--r--spec/features/projects/labels/subscription_spec.rb2
-rw-r--r--spec/features/projects/labels/update_prioritization_spec.rb4
-rw-r--r--spec/features/projects/main/download_buttons_spec.rb2
-rw-r--r--spec/features/projects/main/rss_spec.rb2
-rw-r--r--spec/features/projects/members/group_links_spec.rb2
-rw-r--r--spec/features/projects/members/group_member_cannot_leave_group_project_spec.rb2
-rw-r--r--spec/features/projects/members/group_member_cannot_request_access_to_his_group_project_spec.rb2
-rw-r--r--spec/features/projects/members/group_members_spec.rb2
-rw-r--r--spec/features/projects/members/group_requester_cannot_request_access_to_project_spec.rb2
-rw-r--r--spec/features/projects/members/list_spec.rb2
-rw-r--r--spec/features/projects/members/master_adds_member_with_expiration_date_spec.rb2
-rw-r--r--spec/features/projects/members/master_manages_access_requests_spec.rb2
-rw-r--r--spec/features/projects/members/member_cannot_request_access_to_his_project_spec.rb2
-rw-r--r--spec/features/projects/members/member_leaves_project_spec.rb2
-rw-r--r--spec/features/projects/members/owner_cannot_leave_project_spec.rb2
-rw-r--r--spec/features/projects/members/owner_cannot_request_access_to_his_project_spec.rb2
-rw-r--r--spec/features/projects/members/sorting_spec.rb2
-rw-r--r--spec/features/projects/members/user_requests_access_spec.rb2
-rw-r--r--spec/features/projects/merge_request_button_spec.rb4
-rw-r--r--spec/features/projects/merge_requests/list_spec.rb2
-rw-r--r--spec/features/projects/milestones/milestone_spec.rb2
-rw-r--r--spec/features/projects/milestones/milestones_sorting_spec.rb2
-rw-r--r--spec/features/projects/milestones/new_spec.rb18
-rw-r--r--spec/features/projects/new_project_spec.rb2
-rw-r--r--spec/features/projects/pages_spec.rb2
-rw-r--r--spec/features/projects/pipeline_schedules_spec.rb2
-rw-r--r--spec/features/projects/pipelines/pipeline_spec.rb2
-rw-r--r--spec/features/projects/pipelines/pipelines_spec.rb2
-rw-r--r--spec/features/projects/project_settings_spec.rb2
-rw-r--r--spec/features/projects/ref_switcher_spec.rb2
-rw-r--r--spec/features/projects/services/jira_service_spec.rb2
-rw-r--r--spec/features/projects/services/mattermost_slash_command_spec.rb2
-rw-r--r--spec/features/projects/services/slack_service_spec.rb2
-rw-r--r--spec/features/projects/services/slack_slash_command_spec.rb2
-rw-r--r--spec/features/projects/settings/integration_settings_spec.rb2
-rw-r--r--spec/features/projects/settings/merge_requests_settings_spec.rb2
-rw-r--r--spec/features/projects/settings/pipelines_settings_spec.rb2
-rw-r--r--spec/features/projects/settings/repository_settings_spec.rb19
-rw-r--r--spec/features/projects/settings/visibility_settings_spec.rb4
-rw-r--r--spec/features/projects/shortcuts_spec.rb2
-rw-r--r--spec/features/projects/snippets/create_snippet_spec.rb2
-rw-r--r--spec/features/projects/snippets/show_spec.rb2
-rw-r--r--spec/features/projects/snippets_spec.rb16
-rw-r--r--spec/features/projects/sub_group_issuables_spec.rb2
-rw-r--r--spec/features/projects/tags/download_buttons_spec.rb2
-rw-r--r--spec/features/projects/tree/rss_spec.rb2
-rw-r--r--spec/features/projects/user_create_dir_spec.rb2
-rw-r--r--spec/features/projects/user_creates_project_spec.rb27
-rw-r--r--spec/features/projects/view_on_env_spec.rb12
-rw-r--r--spec/features/projects/wiki/markdown_preview_spec.rb2
-rw-r--r--spec/features/projects/wiki/shortcuts_spec.rb2
-rw-r--r--spec/features/projects/wiki/user_creates_wiki_page_spec.rb18
-rw-r--r--spec/features/projects/wiki/user_git_access_wiki_page_spec.rb2
-rw-r--r--spec/features/projects/wiki/user_updates_wiki_page_spec.rb16
-rw-r--r--spec/features/projects/wiki/user_views_project_wiki_page_spec.rb2
-rw-r--r--spec/features/projects/wiki/user_views_wiki_in_project_page_spec.rb2
-rw-r--r--spec/features/projects_spec.rb12
-rw-r--r--spec/features/protected_branches_spec.rb2
-rw-r--r--spec/features/protected_tags_spec.rb2
-rw-r--r--spec/features/reportable_note/commit_spec.rb2
-rw-r--r--spec/features/reportable_note/issue_spec.rb2
-rw-r--r--spec/features/reportable_note/merge_request_spec.rb2
-rw-r--r--spec/features/reportable_note/snippets_spec.rb13
-rw-r--r--spec/features/runners_spec.rb2
-rw-r--r--spec/features/search_spec.rb2
-rw-r--r--spec/features/snippets/create_snippet_spec.rb2
-rw-r--r--spec/features/snippets/edit_snippet_spec.rb2
-rw-r--r--spec/features/snippets/explore_spec.rb4
-rw-r--r--spec/features/snippets/internal_snippet_spec.rb2
-rw-r--r--spec/features/snippets/notes_on_personal_snippets_spec.rb22
-rw-r--r--spec/features/snippets/search_snippets_spec.rb4
-rw-r--r--spec/features/snippets/user_snippets_spec.rb2
-rw-r--r--spec/features/tags/master_creates_tag_spec.rb96
-rw-r--r--spec/features/tags/master_deletes_tag_spec.rb2
-rw-r--r--spec/features/tags/master_updates_tag_spec.rb13
-rw-r--r--spec/features/tags/master_views_tags_spec.rb2
-rw-r--r--spec/features/todos/target_state_spec.rb2
-rw-r--r--spec/features/todos/todos_filtering_spec.rb2
-rw-r--r--spec/features/todos/todos_sorting_spec.rb4
-rw-r--r--spec/features/todos/todos_spec.rb16
-rw-r--r--spec/features/triggers_spec.rb15
-rw-r--r--spec/features/u2f_spec.rb50
-rw-r--r--spec/features/unsubscribe_links_spec.rb2
-rw-r--r--spec/features/uploads/user_uploads_avatar_to_group_spec.rb2
-rw-r--r--spec/features/uploads/user_uploads_avatar_to_profile_spec.rb2
-rw-r--r--spec/features/uploads/user_uploads_file_to_note_spec.rb2
-rw-r--r--spec/features/user_callout_spec.rb2
-rw-r--r--spec/features/user_can_display_performance_bar_spec.rb2
-rw-r--r--spec/features/users/projects_spec.rb2
-rw-r--r--spec/features/users/rss_spec.rb2
-rw-r--r--spec/features/users/snippets_spec.rb2
-rw-r--r--spec/features/users_spec.rb2
-rw-r--r--spec/features/variables_spec.rb2
-rw-r--r--spec/finders/groups_finder_spec.rb65
-rw-r--r--spec/finders/issues_finder_spec.rb22
-rw-r--r--spec/finders/merge_requests_finder_spec.rb42
-rw-r--r--spec/fixtures/emails/html_empty_link.eml26
-rw-r--r--spec/helpers/application_helper_spec.rb115
-rw-r--r--spec/helpers/broadcast_messages_helper_spec.rb4
-rw-r--r--spec/helpers/commits_helper_spec.rb8
-rw-r--r--spec/helpers/diff_helper_spec.rb11
-rw-r--r--spec/helpers/form_helper_spec.rb12
-rw-r--r--spec/helpers/groups_helper_spec.rb4
-rw-r--r--spec/helpers/import_helper_spec.rb20
-rw-r--r--spec/helpers/issuables_helper_spec.rb40
-rw-r--r--spec/helpers/issues_helper_spec.rb4
-rw-r--r--spec/helpers/labels_helper_spec.rb4
-rw-r--r--spec/helpers/markup_helper_spec.rb16
-rw-r--r--spec/helpers/merge_requests_helper_spec.rb4
-rw-r--r--spec/helpers/page_layout_helper_spec.rb4
-rw-r--r--spec/helpers/preferences_helper_spec.rb16
-rw-r--r--spec/javascripts/commit/pipelines/pipelines_spec.js27
-rw-r--r--spec/javascripts/datetime_utility_spec.js4
-rw-r--r--spec/javascripts/deploy_keys/components/key_spec.js1
-rw-r--r--spec/javascripts/deploy_keys/components/keys_panel_spec.js1
-rw-r--r--spec/javascripts/filtered_search/filtered_search_dropdown_manager_spec.js4
-rw-r--r--spec/javascripts/filtered_search/filtered_search_manager_spec.js5
-rw-r--r--spec/javascripts/fixtures/merge_requests.rb13
-rw-r--r--spec/javascripts/fixtures/pipelines_table.html.haml1
-rw-r--r--spec/javascripts/issue_show/components/app_spec.js1
-rw-r--r--spec/javascripts/issue_show/components/description_spec.js28
-rw-r--r--spec/javascripts/merge_request_notes_spec.js96
-rw-r--r--spec/javascripts/notes_spec.js50
-rw-r--r--spec/javascripts/pipelines/async_button_spec.js44
-rw-r--r--spec/javascripts/pipelines/pipelines_actions_spec.js31
-rw-r--r--spec/javascripts/pipelines/pipelines_table_row_spec.js (renamed from spec/javascripts/vue_shared/components/pipelines_table_row_spec.js)2
-rw-r--r--spec/javascripts/pipelines/pipelines_table_spec.js (renamed from spec/javascripts/vue_shared/components/pipelines_table_spec.js)6
-rw-r--r--spec/javascripts/project_title_spec.js76
-rw-r--r--spec/javascripts/test_bundle.js32
-rw-r--r--spec/lib/banzai/cross_project_reference_spec.rb4
-rw-r--r--spec/lib/banzai/filter/abstract_reference_filter_spec.rb28
-rw-r--r--spec/lib/banzai/filter/commit_range_reference_filter_spec.rb36
-rw-r--r--spec/lib/banzai/filter/commit_reference_filter_spec.rb8
-rw-r--r--spec/lib/banzai/filter/external_issue_reference_filter_spec.rb4
-rw-r--r--spec/lib/banzai/filter/issue_reference_filter_spec.rb70
-rw-r--r--spec/lib/banzai/filter/label_reference_filter_spec.rb76
-rw-r--r--spec/lib/banzai/filter/merge_request_reference_filter_spec.rb20
-rw-r--r--spec/lib/banzai/filter/milestone_reference_filter_spec.rb68
-rw-r--r--spec/lib/banzai/filter/redactor_filter_spec.rb6
-rw-r--r--spec/lib/banzai/filter/reference_filter_spec.rb4
-rw-r--r--spec/lib/banzai/filter/relative_link_filter_spec.rb48
-rw-r--r--spec/lib/banzai/filter/sanitization_filter_spec.rb4
-rw-r--r--spec/lib/banzai/filter/snippet_reference_filter_spec.rb20
-rw-r--r--spec/lib/banzai/filter/upload_link_filter_spec.rb24
-rw-r--r--spec/lib/banzai/note_renderer_spec.rb12
-rw-r--r--spec/lib/banzai/redactor_spec.rb22
-rw-r--r--spec/lib/banzai/reference_parser/base_parser_spec.rb140
-rw-r--r--spec/lib/banzai/reference_parser/commit_parser_spec.rb32
-rw-r--r--spec/lib/banzai/reference_parser/commit_range_parser_spec.rb24
-rw-r--r--spec/lib/banzai/reference_parser/issue_parser_spec.rb12
-rw-r--r--spec/lib/banzai/reference_parser/user_parser_spec.rb24
-rw-r--r--spec/lib/container_registry/blob_spec.rb10
-rw-r--r--spec/lib/container_registry/client_spec.rb22
-rw-r--r--spec/lib/container_registry/tag_spec.rb28
-rw-r--r--spec/lib/extracts_path_spec.rb4
-rw-r--r--spec/lib/feature_spec.rb8
-rw-r--r--spec/lib/gitlab/background_migration_spec.rb18
-rw-r--r--spec/lib/gitlab/bitbucket_import/importer_spec.rb8
-rw-r--r--spec/lib/gitlab/cache/ci/project_pipeline_status_spec.rb16
-rw-r--r--spec/lib/gitlab/ci/build/artifacts/metadata_spec.rb12
-rw-r--r--spec/lib/gitlab/closing_issue_extractor_spec.rb32
-rw-r--r--spec/lib/gitlab/conflict/file_spec.rb24
-rw-r--r--spec/lib/gitlab/conflict/parser_spec.rb64
-rw-r--r--spec/lib/gitlab/current_settings_spec.rb31
-rw-r--r--spec/lib/gitlab/data_builder/push_spec.rb4
-rw-r--r--spec/lib/gitlab/database/migration_helpers_spec.rb212
-rw-r--r--spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_namespaces_spec.rb34
-rw-r--r--spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_projects_spec.rb30
-rw-r--r--spec/lib/gitlab/database/rename_reserved_paths_migration/v1_spec.rb26
-rw-r--r--spec/lib/gitlab/database_spec.rb57
-rw-r--r--spec/lib/gitlab/downtime_check_spec.rb32
-rw-r--r--spec/lib/gitlab/email/handler/create_note_handler_spec.rb2
-rw-r--r--spec/lib/gitlab/email/reply_parser_spec.rb40
-rw-r--r--spec/lib/gitlab/etag_caching/middleware_spec.rb4
-rw-r--r--spec/lib/gitlab/fake_application_settings_spec.rb32
-rw-r--r--spec/lib/gitlab/file_detector_spec.rb8
-rw-r--r--spec/lib/gitlab/git/attributes_spec.rb44
-rw-r--r--spec/lib/gitlab/git/blob_spec.rb18
-rw-r--r--spec/lib/gitlab/git/branch_spec.rb4
-rw-r--r--spec/lib/gitlab/git/diff_collection_spec.rb16
-rw-r--r--spec/lib/gitlab/git/diff_spec.rb10
-rw-r--r--spec/lib/gitlab/git/gitmodules_parser_spec.rb28
-rw-r--r--spec/lib/gitlab/git/repository_spec.rb48
-rw-r--r--spec/lib/gitlab/git_access_spec.rb43
-rw-r--r--spec/lib/gitlab/git_access_wiki_spec.rb3
-rw-r--r--spec/lib/gitlab/gitaly_client/commit_spec.rb8
-rw-r--r--spec/lib/gitlab/gitaly_client/notifications_spec.rb4
-rw-r--r--spec/lib/gitlab/gitaly_client/ref_spec.rb40
-rw-r--r--spec/lib/gitlab/gitlab_import/importer_spec.rb4
-rw-r--r--spec/lib/gitlab/group_hierarchy_spec.rb24
-rw-r--r--spec/lib/gitlab/highlight_spec.rb4
-rw-r--r--spec/lib/gitlab/identifier_spec.rb12
-rw-r--r--spec/lib/gitlab/import_export/all_models.yml3
-rw-r--r--spec/lib/gitlab/import_export/project.json38
-rw-r--r--spec/lib/gitlab/import_export/project_tree_restorer_spec.rb7
-rw-r--r--spec/lib/gitlab/import_export/project_tree_saver_spec.rb10
-rw-r--r--spec/lib/gitlab/import_export/safe_model_attributes.yml11
-rw-r--r--spec/lib/gitlab/job_waiter_spec.rb10
-rw-r--r--spec/lib/gitlab/ldap/authentication_spec.rb12
-rw-r--r--spec/lib/gitlab/ldap/user_spec.rb4
-rw-r--r--spec/lib/gitlab/metrics/instrumentation_spec.rb32
-rw-r--r--spec/lib/gitlab/metrics/rack_middleware_spec.rb12
-rw-r--r--spec/lib/gitlab/metrics/sampler_spec.rb54
-rw-r--r--spec/lib/gitlab/metrics/sidekiq_middleware_spec.rb36
-rw-r--r--spec/lib/gitlab/metrics/subscribers/action_view_spec.rb8
-rw-r--r--spec/lib/gitlab/metrics/subscribers/active_record_spec.rb18
-rw-r--r--spec/lib/gitlab/metrics/subscribers/rails_cache_spec.rb80
-rw-r--r--spec/lib/gitlab/metrics/transaction_spec.rb28
-rw-r--r--spec/lib/gitlab/metrics_spec.rb78
-rw-r--r--spec/lib/gitlab/project_authorizations_spec.rb4
-rw-r--r--spec/lib/gitlab/quick_actions/command_definition_spec.rb (renamed from spec/lib/gitlab/slash_commands/command_definition_spec.rb)2
-rw-r--r--spec/lib/gitlab/quick_actions/dsl_spec.rb (renamed from spec/lib/gitlab/slash_commands/dsl_spec.rb)4
-rw-r--r--spec/lib/gitlab/quick_actions/extractor_spec.rb (renamed from spec/lib/gitlab/slash_commands/extractor_spec.rb)4
-rw-r--r--spec/lib/gitlab/regex_spec.rb12
-rw-r--r--spec/lib/gitlab/repo_path_spec.rb75
-rw-r--r--spec/lib/gitlab/route_map_spec.rb24
-rw-r--r--spec/lib/gitlab/sherlock/file_sample_spec.rb4
-rw-r--r--spec/lib/gitlab/sherlock/line_profiler_spec.rb6
-rw-r--r--spec/lib/gitlab/sherlock/middleware_spec.rb4
-rw-r--r--spec/lib/gitlab/sherlock/query_spec.rb4
-rw-r--r--spec/lib/gitlab/sherlock/transaction_spec.rb28
-rw-r--r--spec/lib/gitlab/sidekiq_status/client_middleware_spec.rb4
-rw-r--r--spec/lib/gitlab/sidekiq_status/server_middleware_spec.rb4
-rw-r--r--spec/lib/gitlab/slash_commands/command_spec.rb (renamed from spec/lib/gitlab/chat_commands/command_spec.rb)8
-rw-r--r--spec/lib/gitlab/slash_commands/deploy_spec.rb (renamed from spec/lib/gitlab/chat_commands/deploy_spec.rb)2
-rw-r--r--spec/lib/gitlab/slash_commands/issue_new_spec.rb (renamed from spec/lib/gitlab/chat_commands/issue_new_spec.rb)2
-rw-r--r--spec/lib/gitlab/slash_commands/issue_search_spec.rb (renamed from spec/lib/gitlab/chat_commands/issue_search_spec.rb)2
-rw-r--r--spec/lib/gitlab/slash_commands/issue_show_spec.rb (renamed from spec/lib/gitlab/chat_commands/issue_show_spec.rb)2
-rw-r--r--spec/lib/gitlab/slash_commands/presenters/access_spec.rb (renamed from spec/lib/gitlab/chat_commands/presenters/access_spec.rb)2
-rw-r--r--spec/lib/gitlab/slash_commands/presenters/deploy_spec.rb (renamed from spec/lib/gitlab/chat_commands/presenters/deploy_spec.rb)2
-rw-r--r--spec/lib/gitlab/slash_commands/presenters/issue_new_spec.rb (renamed from spec/lib/gitlab/chat_commands/presenters/issue_new_spec.rb)2
-rw-r--r--spec/lib/gitlab/slash_commands/presenters/issue_search_spec.rb (renamed from spec/lib/gitlab/chat_commands/presenters/issue_search_spec.rb)2
-rw-r--r--spec/lib/gitlab/slash_commands/presenters/issue_show_spec.rb (renamed from spec/lib/gitlab/chat_commands/presenters/issue_show_spec.rb)2
-rw-r--r--spec/lib/gitlab/url_builder_spec.rb4
-rw-r--r--spec/lib/gitlab/view/presenter/delegated_spec.rb4
-rw-r--r--spec/lib/gitlab/visibility_level_spec.rb31
-rw-r--r--spec/lib/gitlab/workhorse_spec.rb7
-rw-r--r--spec/lib/mattermost/command_spec.rb16
-rw-r--r--spec/lib/mattermost/session_spec.rb14
-rw-r--r--spec/lib/mattermost/team_spec.rb12
-rw-r--r--spec/mailers/abuse_report_mailer_spec.rb4
-rw-r--r--spec/migrations/migrate_build_stage_reference_again_spec.rb (renamed from spec/migrations/migrate_build_stage_reference_spec.rb)4
-rw-r--r--spec/migrations/migrate_process_commit_worker_jobs_spec.rb54
-rw-r--r--spec/migrations/turn_nested_groups_into_regular_groups_for_mysql_spec.rb18
-rw-r--r--spec/models/ability_spec.rb56
-rw-r--r--spec/models/abuse_report_spec.rb4
-rw-r--r--spec/models/ci/build_spec.rb52
-rw-r--r--spec/models/ci/pipeline_schedule_spec.rb12
-rw-r--r--spec/models/ci/pipeline_spec.rb16
-rw-r--r--spec/models/ci/variable_spec.rb4
-rw-r--r--spec/models/commit_range_spec.rb6
-rw-r--r--spec/models/concerns/case_sensitivity_spec.rb148
-rw-r--r--spec/models/concerns/has_status_spec.rb4
-rw-r--r--spec/models/concerns/issuable_spec.rb28
-rw-r--r--spec/models/concerns/milestoneish_spec.rb31
-rw-r--r--spec/models/concerns/resolvable_discussion_spec.rb12
-rw-r--r--spec/models/event_spec.rb4
-rw-r--r--spec/models/group_spec.rb4
-rw-r--r--spec/models/issue_collection_spec.rb4
-rw-r--r--spec/models/issue_spec.rb20
-rw-r--r--spec/models/key_spec.rb8
-rw-r--r--spec/models/label_spec.rb4
-rw-r--r--spec/models/member_spec.rb8
-rw-r--r--spec/models/members/group_member_spec.rb8
-rw-r--r--spec/models/merge_request_diff_file_spec.rb11
-rw-r--r--spec/models/merge_request_diff_spec.rb3
-rw-r--r--spec/models/merge_request_spec.rb74
-rw-r--r--spec/models/milestone_spec.rb37
-rw-r--r--spec/models/namespace_spec.rb4
-rw-r--r--spec/models/note_spec.rb16
-rw-r--r--spec/models/project_authorization_spec.rb4
-rw-r--r--spec/models/project_feature_spec.rb12
-rw-r--r--spec/models/project_services/chat_message/pipeline_message_spec.rb10
-rw-r--r--spec/models/project_services/chat_message/push_message_spec.rb16
-rw-r--r--spec/models/project_services/mattermost_slash_commands_service_spec.rb24
-rw-r--r--spec/models/project_spec.rb96
-rw-r--r--spec/models/project_team_spec.rb4
-rw-r--r--spec/models/project_wiki_spec.rb24
-rw-r--r--spec/models/repository_spec.rb166
-rw-r--r--spec/models/upload_spec.rb4
-rw-r--r--spec/models/user_spec.rb42
-rw-r--r--spec/models/wiki_page_spec.rb4
-rw-r--r--spec/policies/project_policy_spec.rb4
-rw-r--r--spec/presenters/ci/build_presenter_spec.rb4
-rw-r--r--spec/requests/api/deploy_keys_spec.rb10
-rw-r--r--spec/requests/api/files_spec.rb4
-rw-r--r--spec/requests/api/groups_spec.rb4
-rw-r--r--spec/requests/api/internal_spec.rb62
-rw-r--r--spec/requests/api/merge_requests_spec.rb30
-rw-r--r--spec/requests/api/milestones_spec.rb42
-rw-r--r--spec/requests/api/notes_spec.rb4
-rw-r--r--spec/requests/api/project_snippets_spec.rb32
-rw-r--r--spec/requests/api/projects_spec.rb36
-rw-r--r--spec/requests/api/runner_spec.rb4
-rw-r--r--spec/requests/api/snippets_spec.rb32
-rw-r--r--spec/requests/api/users_spec.rb51
-rw-r--r--spec/requests/api/v3/files_spec.rb4
-rw-r--r--spec/requests/api/v3/groups_spec.rb4
-rw-r--r--spec/requests/api/v3/merge_requests_spec.rb4
-rw-r--r--spec/requests/api/v3/notes_spec.rb4
-rw-r--r--spec/requests/api/v3/project_snippets_spec.rb32
-rw-r--r--spec/requests/api/v3/projects_spec.rb62
-rw-r--r--spec/requests/api/v3/snippets_spec.rb12
-rw-r--r--spec/requests/api/v3/users_spec.rb32
-rw-r--r--spec/requests/ci/api/builds_spec.rb8
-rw-r--r--spec/requests/git_http_spec.rb53
-rw-r--r--spec/rubocop/cop/migration/update_column_in_batches_spec.rb4
-rw-r--r--spec/services/create_deployment_service_spec.rb55
-rw-r--r--spec/services/files/update_service_spec.rb4
-rw-r--r--spec/services/git_push_service_spec.rb46
-rw-r--r--spec/services/issues/close_service_spec.rb16
-rw-r--r--spec/services/issues/create_service_spec.rb4
-rw-r--r--spec/services/labels/promote_service_spec.rb6
-rw-r--r--spec/services/members/destroy_service_spec.rb4
-rw-r--r--spec/services/merge_requests/close_service_spec.rb4
-rw-r--r--spec/services/merge_requests/conflicts/resolve_service_spec.rb29
-rw-r--r--spec/services/merge_requests/create_service_spec.rb10
-rw-r--r--spec/services/merge_requests/merge_service_spec.rb6
-rw-r--r--spec/services/merge_requests/refresh_service_spec.rb16
-rw-r--r--spec/services/merge_requests/reopen_service_spec.rb4
-rw-r--r--spec/services/merge_requests/update_service_spec.rb8
-rw-r--r--spec/services/notes/quick_actions_service_spec.rb (renamed from spec/services/notes/slash_commands_service_spec.rb)12
-rw-r--r--spec/services/preview_markdown_service_spec.rb18
-rw-r--r--spec/services/projects/housekeeping_service_spec.rb12
-rw-r--r--spec/services/projects/import_service_spec.rb8
-rw-r--r--spec/services/projects/propagate_service_template_spec.rb12
-rw-r--r--spec/services/projects/transfer_service_spec.rb75
-rw-r--r--spec/services/projects/unlink_fork_service_spec.rb6
-rw-r--r--spec/services/quick_actions/interpret_service_spec.rb (renamed from spec/services/slash_commands/interpret_service_spec.rb)2
-rw-r--r--spec/services/submit_usage_ping_service_spec.rb4
-rw-r--r--spec/services/system_note_service_spec.rb52
-rw-r--r--spec/services/tags/create_service_spec.rb12
-rw-r--r--spec/services/user_project_access_changed_service_spec.rb4
-rw-r--r--spec/services/users/activity_service_spec.rb6
-rw-r--r--spec/services/users/refresh_authorized_projects_service_spec.rb24
-rw-r--r--spec/spec_helper.rb1
-rw-r--r--spec/support/capybara.rb10
-rw-r--r--spec/support/chat_slash_commands_shared_examples.rb2
-rw-r--r--spec/support/controllers/githubish_import_controller_shared_examples.rb100
-rw-r--r--spec/support/features/issuable_slash_commands_shared_examples.rb20
-rw-r--r--spec/support/features/reportable_note_shared_examples.rb13
-rw-r--r--spec/support/filtered_search_helpers.rb3
-rw-r--r--spec/support/login_helpers.rb57
-rw-r--r--spec/support/mentionable_shared_examples.rb12
-rw-r--r--spec/support/project_features_apply_to_issuables_shared_examples.rb2
-rw-r--r--spec/support/quick_actions_helpers.rb (renamed from spec/support/slash_commands_helpers.rb)2
-rw-r--r--spec/support/reactive_caching_helpers.rb6
-rw-r--r--spec/support/services/issuable_create_service_slash_commands_shared_examples.rb2
-rw-r--r--spec/support/services_shared_context.rb6
-rw-r--r--spec/support/slack_mattermost_notifications_shared_examples.rb42
-rw-r--r--spec/support/stub_configuration.rb4
-rw-r--r--spec/support/stub_gitlab_calls.rb38
-rw-r--r--spec/support/test_env.rb8
-rw-r--r--spec/support/time_tracking_shared_examples.rb8
-rw-r--r--spec/support/update_invalid_issuable.rb4
-rw-r--r--spec/support/user_activities_helpers.rb4
-rw-r--r--spec/support/wait_for_requests.rb6
-rw-r--r--spec/tasks/gitlab/backup_rake_spec.rb20
-rw-r--r--spec/tasks/gitlab/gitaly_rake_spec.rb13
-rw-r--r--spec/tasks/gitlab/task_helpers_spec.rb16
-rw-r--r--spec/tasks/gitlab/workhorse_rake_spec.rb8
-rw-r--r--spec/validators/dynamic_path_validator_spec.rb9
-rw-r--r--spec/views/devise/shared/_signin_box.html.haml_spec.rb4
-rw-r--r--spec/views/profiles/show.html.haml_spec.rb19
-rw-r--r--spec/views/projects/notes/_more_actions_dropdown.html.haml_spec.rb41
-rw-r--r--spec/views/shared/notes/_form.html.haml_spec.rb6
-rw-r--r--spec/workers/background_migration_worker_spec.rb6
-rw-r--r--spec/workers/delete_user_worker_spec.rb8
-rw-r--r--spec/workers/every_sidekiq_worker_spec.rb10
-rw-r--r--spec/workers/expire_pipeline_cache_worker_spec.rb4
-rw-r--r--spec/workers/git_garbage_collect_worker_spec.rb4
-rw-r--r--spec/workers/new_note_worker_spec.rb4
-rw-r--r--spec/workers/post_receive_spec.rb8
-rw-r--r--spec/workers/process_commit_worker_spec.rb24
-rw-r--r--spec/workers/project_cache_worker_spec.rb28
-rw-r--r--spec/workers/propagate_service_template_worker_spec.rb4
-rw-r--r--spec/workers/repository_fork_worker_spec.rb8
-rw-r--r--spec/workers/repository_import_worker_spec.rb4
1036 files changed, 10545 insertions, 5914 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index f0c266485b6..76a95ad6e0a 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -461,6 +461,7 @@ karma:
- coverage-javascript/
codeclimate:
+ <<: *except-docs
before_script: []
image: docker:latest
stage: test
diff --git a/.gitlab/issue_templates/Bug.md b/.gitlab/issue_templates/Bug.md
index 9d53a48409a..aec734870d6 100644
--- a/.gitlab/issue_templates/Bug.md
+++ b/.gitlab/issue_templates/Bug.md
@@ -1,11 +1,18 @@
Please read this!
Before opening a new issue, make sure to search for keywords in the issues
-filtered by the "regression" or "bug" label:
+filtered by the "regression" or "bug" label.
+
+For the Community Edition issue tracker:
- https://gitlab.com/gitlab-org/gitlab-ce/issues?label_name%5B%5D=regression
- https://gitlab.com/gitlab-org/gitlab-ce/issues?label_name%5B%5D=bug
+For the Enterprise Edition issue tracker:
+
+- https://gitlab.com/gitlab-org/gitlab-ee/issues?label_name%5B%5D=regression
+- https://gitlab.com/gitlab-org/gitlab-ee/issues?label_name%5B%5D=bug
+
and verify the issue you're about to submit isn't a duplicate.
Please remove this notice if you're confident your issue isn't a duplicate.
diff --git a/.gitlab/issue_templates/Feature Proposal.md b/.gitlab/issue_templates/Feature Proposal.md
index d96c9ad59e0..1278061a410 100644
--- a/.gitlab/issue_templates/Feature Proposal.md
+++ b/.gitlab/issue_templates/Feature Proposal.md
@@ -3,8 +3,14 @@ Please read this!
Before opening a new issue, make sure to search for keywords in the issues
filtered by the "feature proposal" label:
+For the Community Edition issue tracker:
+
- https://gitlab.com/gitlab-org/gitlab-ce/issues?label_name%5B%5D=feature+proposal
+For the Enterprise Edition issue tracker:
+
+- https://gitlab.com/gitlab-org/gitlab-ee/issues?label_name%5B%5D=feature+proposal
+
and verify the issue you're about to submit isn't a duplicate.
Please remove this notice if you're confident your issue isn't a duplicate.
@@ -21,12 +27,24 @@ Please remove this notice if you're confident your issue isn't a duplicate.
### Documentation blurb
-(Write the start of the documentation of this feature here, include:
+#### Overview
+
+What is it?
+Why should someone use this feature?
+What is the underlying (business) problem?
+How do you use this feature?
+
+#### Use cases
+
+Who is this for? Provide one or more use cases.
+
+### Feature checklist
-1. Why should someone use it; what's the underlying problem.
-2. What is the solution.
-3. How does someone use this
+Make sure these are completed before closing the issue,
+with a link to the relevant commit.
-During implementation, this can then be copied and used as a starter for the documentation.)
+- [ ] [Feature assurance](https://about.gitlab.com/handbook/product/#feature-assurance)
+- [ ] Documentation
+- [ ] Added to [features.yml](https://gitlab.com/gitlab-com/www-gitlab-com/blob/master/data/features.yml)
-/label ~"feature proposal"
+/label ~"feature proposal" \ No newline at end of file
diff --git a/.rubocop.yml b/.rubocop.yml
index 4537e710dd4..32ec60f540b 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -164,6 +164,11 @@ Style/DefWithParentheses:
Style/Documentation:
Enabled: false
+# Multi-line method chaining should be done with leading dots.
+Style/DotPosition:
+ Enabled: true
+ EnforcedStyle: leading
+
# This cop checks for uses of double negation (!!) to convert something
# to a boolean value. As this is both cryptic and usually redundant, it
# should be avoided.
diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml
index e2d9c37479d..5ab4692dd60 100644
--- a/.rubocop_todo.yml
+++ b/.rubocop_todo.yml
@@ -88,13 +88,6 @@ Security/YAMLLoad:
Style/BarePercentLiterals:
Enabled: false
-# Offense count: 1403
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle, SupportedStyles.
-# SupportedStyles: leading, trailing
-Style/DotPosition:
- Enabled: false
-
# Offense count: 5
# Cop supports --auto-correct.
Style/EachWithObject:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f43858a00a5..af5f5809c41 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,10 @@
documentation](doc/development/changelog.md) for instructions on adding your own
entry.
+## 9.2.7 (2017-06-21)
+
+- Reinstate is_admin flag in users api when authenticated user is an admin. !12211 (rickettm)
+
## 9.2.6 (2017-06-16)
- Fix the last coverage in trace log should be extracted. !11128 (dosuken123)
diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION
index bc859cbd6d9..54d1a4f2a4a 100644
--- a/GITALY_SERVER_VERSION
+++ b/GITALY_SERVER_VERSION
@@ -1 +1 @@
-0.11.2
+0.13.0
diff --git a/Gemfile b/Gemfile
index 2c200f2fa7a..b1790b23dcd 100644
--- a/Gemfile
+++ b/Gemfile
@@ -86,7 +86,7 @@ gem 'kaminari', '~> 0.17.0'
gem 'hamlit', '~> 2.6.1'
# Files attachments
-gem 'carrierwave', '~> 1.0'
+gem 'carrierwave', '~> 1.1'
# Drag and Drop UI
gem 'dropzonejs-rails', '~> 0.7.1'
@@ -158,7 +158,7 @@ gem 'rufus-scheduler', '~> 3.4'
gem 'httparty', '~> 0.13.3'
# Colored output to console
-gem 'rainbow', '~> 2.1.0'
+gem 'rainbow', '~> 2.2'
# GitLab settings
gem 'settingslogic', '~> 2.0.9'
@@ -260,6 +260,7 @@ gem 'premailer-rails', '~> 1.9.0'
# I18n
gem 'ruby_parser', '~> 3.8', require: false
+gem 'rails-i18n', '~> 4.0.9'
gem 'gettext_i18n_rails', '~> 1.8.0'
gem 'gettext_i18n_rails_js', '~> 1.2.0'
gem 'gettext', '~> 3.2.2', require: false, group: :development
@@ -373,7 +374,7 @@ gem 'ruby-prof', '~> 0.16.2'
gem 'oauth2', '~> 1.4'
# Soft deletion
-gem 'paranoia', '~> 2.2'
+gem 'paranoia', '~> 2.3.1'
# Health check
gem 'health_check', '~> 2.6.0'
@@ -383,7 +384,7 @@ gem 'vmstat', '~> 2.3.0'
gem 'sys-filesystem', '~> 1.1.6'
# Gitaly GRPC client
-gem 'gitaly', '~> 0.8.0'
+gem 'gitaly', '~> 0.9.0'
gem 'toml-rb', '~> 0.3.15', require: false
diff --git a/Gemfile.lock b/Gemfile.lock
index 6755c75e331..bfd0498db35 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -108,7 +108,7 @@ GEM
capybara-screenshot (1.0.14)
capybara (>= 1.0, < 3)
launchy
- carrierwave (1.0.0)
+ carrierwave (1.1.0)
activemodel (>= 4.0.0)
activesupport (>= 4.0.0)
mime-types (>= 1.16)
@@ -277,7 +277,7 @@ GEM
po_to_json (>= 1.0.0)
rails (>= 3.2.0)
gherkin-ruby (0.3.2)
- gitaly (0.8.0)
+ gitaly (0.9.0)
google-protobuf (~> 3.1)
grpc (~> 1.0)
github-linguist (4.7.6)
@@ -546,8 +546,8 @@ GEM
rubypants (~> 0.2)
orm_adapter (0.5.0)
os (0.9.6)
- paranoia (2.2.0)
- activerecord (>= 4.0, < 5.1)
+ paranoia (2.3.1)
+ activerecord (>= 4.0, < 5.2)
parser (2.4.0.0)
ast (~> 2.2)
path_expander (1.0.1)
@@ -646,12 +646,16 @@ GEM
rails-deprecated_sanitizer (>= 1.0.1)
rails-html-sanitizer (1.0.3)
loofah (~> 2.0)
+ rails-i18n (4.0.9)
+ i18n (~> 0.7)
+ railties (~> 4.0)
railties (4.2.8)
actionpack (= 4.2.8)
activesupport (= 4.2.8)
rake (>= 0.8.7)
thor (>= 0.18.1, < 2.0)
- rainbow (2.1.0)
+ rainbow (2.2.2)
+ rake
raindrops (0.17.0)
rake (10.5.0)
rblineprof (0.3.6)
@@ -932,7 +936,7 @@ DEPENDENCIES
bundler-audit (~> 0.5.0)
capybara (~> 2.6.2)
capybara-screenshot (~> 1.0.0)
- carrierwave (~> 1.0)
+ carrierwave (~> 1.1)
charlock_holmes (~> 0.7.3)
chronic (~> 0.10.2)
chronic_duration (~> 0.10.6)
@@ -973,7 +977,7 @@ DEPENDENCIES
gettext (~> 3.2.2)
gettext_i18n_rails (~> 1.8.0)
gettext_i18n_rails_js (~> 1.2.0)
- gitaly (~> 0.8.0)
+ gitaly (~> 0.9.0)
github-linguist (~> 4.7.0)
gitlab-flowdock-git-hook (~> 1.0.1)
gitlab-markup (~> 1.5.1)
@@ -1031,7 +1035,7 @@ DEPENDENCIES
omniauth-twitter (~> 1.2.0)
omniauth_crowd (~> 2.2.0)
org-ruby (~> 0.9.12)
- paranoia (~> 2.2)
+ paranoia (~> 2.3.1)
peek (~> 1.0.1)
peek-gc (~> 0.0.2)
peek-host (~> 1.0.0)
@@ -1053,7 +1057,8 @@ DEPENDENCIES
rack-proxy (~> 0.6.0)
rails (= 4.2.8)
rails-deprecated_sanitizer (~> 1.0.3)
- rainbow (~> 2.1.0)
+ rails-i18n (~> 4.0.9)
+ rainbow (~> 2.2)
rblineprof (~> 0.3.6)
rdoc (~> 4.2)
recaptcha (~> 3.0)
@@ -1119,4 +1124,4 @@ DEPENDENCIES
wikicloth (= 0.8.1)
BUNDLED WITH
- 1.15.0
+ 1.15.1
diff --git a/app/assets/javascripts/boards/filtered_search_boards.js b/app/assets/javascripts/boards/filtered_search_boards.js
index b37698fe9ca..3f083655f95 100644
--- a/app/assets/javascripts/boards/filtered_search_boards.js
+++ b/app/assets/javascripts/boards/filtered_search_boards.js
@@ -11,7 +11,6 @@ export default class FilteredSearchBoards extends gl.FilteredSearchManager {
// Issue boards is slightly different, we handle all the requests async
// instead or reloading the page, we just re-fire the list ajax requests
this.isHandledAsync = true;
-
this.cantEdit = cantEdit;
}
diff --git a/app/assets/javascripts/commit/pipelines/pipelines_bundle.js b/app/assets/javascripts/commit/pipelines/pipelines_bundle.js
index 86d99dd87da..2c38440a2af 100644
--- a/app/assets/javascripts/commit/pipelines/pipelines_bundle.js
+++ b/app/assets/javascripts/commit/pipelines/pipelines_bundle.js
@@ -1,29 +1,30 @@
-/* eslint-disable no-param-reassign */
-
import Vue from 'vue';
-import VueResource from 'vue-resource';
-import CommitPipelinesTable from './pipelines_table';
-
-Vue.use(VueResource);
+import commitPipelinesTable from './pipelines_table.vue';
/**
- * Commits View > Pipelines Tab > Pipelines Table.
- *
- * Renders Pipelines table in pipelines tab in the commits show view.
+ * Used in:
+ * - Commit details View > Pipelines Tab > Pipelines Table.
+ * - Merge Request details View > Pipelines Tab > Pipelines Table.
+ * - New Merge Request View > Pipelines Tab > Pipelines Table.
*/
-// export for use in merge_request_tabs.js (TODO: remove this hack)
+const CommitPipelinesTable = Vue.extend(commitPipelinesTable);
+
+// export for use in merge_request_tabs.js (TODO: remove this hack when we understand how to load
+// vue.js in merge_request_tabs.js)
window.gl = window.gl || {};
window.gl.CommitPipelinesTable = CommitPipelinesTable;
-$(() => {
- gl.commits = gl.commits || {};
- gl.commits.pipelines = gl.commits.pipelines || {};
-
+document.addEventListener('DOMContentLoaded', () => {
const pipelineTableViewEl = document.querySelector('#commit-pipeline-table-view');
if (pipelineTableViewEl && pipelineTableViewEl.dataset.disableInitialization === undefined) {
- gl.commits.pipelines.PipelinesTableBundle = new CommitPipelinesTable().$mount();
- pipelineTableViewEl.appendChild(gl.commits.pipelines.PipelinesTableBundle.$el);
+ const table = new CommitPipelinesTable({
+ propsData: {
+ endpoint: pipelineTableViewEl.dataset.endpoint,
+ helpPagePath: pipelineTableViewEl.dataset.helpPagePath,
+ },
+ }).$mount();
+ pipelineTableViewEl.appendChild(table.$el);
}
});
diff --git a/app/assets/javascripts/commit/pipelines/pipelines_table.js b/app/assets/javascripts/commit/pipelines/pipelines_table.js
deleted file mode 100644
index 70ba83ce5b9..00000000000
--- a/app/assets/javascripts/commit/pipelines/pipelines_table.js
+++ /dev/null
@@ -1,191 +0,0 @@
-import Vue from 'vue';
-import Visibility from 'visibilityjs';
-import pipelinesTableComponent from '../../vue_shared/components/pipelines_table.vue';
-import PipelinesService from '../../pipelines/services/pipelines_service';
-import PipelineStore from '../../pipelines/stores/pipelines_store';
-import eventHub from '../../pipelines/event_hub';
-import emptyState from '../../pipelines/components/empty_state.vue';
-import errorState from '../../pipelines/components/error_state.vue';
-import loadingIcon from '../../vue_shared/components/loading_icon.vue';
-import '../../lib/utils/common_utils';
-import '../../vue_shared/vue_resource_interceptor';
-import Poll from '../../lib/utils/poll';
-
-/**
- *
- * Uses `pipelines-table-component` to render Pipelines table with an API call.
- * Endpoint is provided in HTML and passed as `endpoint`.
- * We need a store to store the received environemnts.
- * We need a service to communicate with the server.
- *
- */
-
-export default Vue.component('pipelines-table', {
-
- components: {
- pipelinesTableComponent,
- errorState,
- emptyState,
- loadingIcon,
- },
-
- /**
- * Accesses the DOM to provide the needed data.
- * Returns the necessary props to render `pipelines-table-component` component.
- *
- * @return {Object}
- */
- data() {
- const store = new PipelineStore();
-
- return {
- endpoint: null,
- helpPagePath: null,
- store,
- state: store.state,
- isLoading: false,
- hasError: false,
- isMakingRequest: false,
- updateGraphDropdown: false,
- hasMadeRequest: false,
- };
- },
-
- computed: {
- shouldRenderErrorState() {
- return this.hasError && !this.isLoading;
- },
-
- /**
- * Empty state is only rendered if after the first request we receive no pipelines.
- *
- * @return {Boolean}
- */
- shouldRenderEmptyState() {
- return !this.state.pipelines.length &&
- !this.isLoading &&
- this.hasMadeRequest &&
- !this.hasError;
- },
-
- shouldRenderTable() {
- return !this.isLoading &&
- this.state.pipelines.length > 0 &&
- !this.hasError;
- },
- },
-
- /**
- * When the component is about to be mounted, tell the service to fetch the data
- *
- * A request to fetch the pipelines will be made.
- * In case of a successfull response we will store the data in the provided
- * store, in case of a failed response we need to warn the user.
- *
- */
- beforeMount() {
- const element = document.querySelector('#commit-pipeline-table-view');
-
- this.endpoint = element.dataset.endpoint;
- this.helpPagePath = element.dataset.helpPagePath;
- this.service = new PipelinesService(this.endpoint);
-
- this.poll = new Poll({
- resource: this.service,
- method: 'getPipelines',
- successCallback: this.successCallback,
- errorCallback: this.errorCallback,
- notificationCallback: this.setIsMakingRequest,
- });
-
- if (!Visibility.hidden()) {
- this.isLoading = true;
- this.poll.makeRequest();
- } else {
- // If tab is not visible we need to make the first request so we don't show the empty
- // state without knowing if there are any pipelines
- this.fetchPipelines();
- }
-
- Visibility.change(() => {
- if (!Visibility.hidden()) {
- this.poll.restart();
- } else {
- this.poll.stop();
- }
- });
-
- eventHub.$on('refreshPipelines', this.fetchPipelines);
- },
-
- beforeDestroy() {
- eventHub.$off('refreshPipelines');
- },
-
- destroyed() {
- this.poll.stop();
- },
-
- methods: {
- fetchPipelines() {
- this.isLoading = true;
-
- return this.service.getPipelines()
- .then(response => this.successCallback(response))
- .catch(() => this.errorCallback());
- },
-
- successCallback(resp) {
- const response = resp.json();
-
- this.hasMadeRequest = true;
-
- // depending of the endpoint the response can either bring a `pipelines` key or not.
- const pipelines = response.pipelines || response;
- this.store.storePipelines(pipelines);
- this.isLoading = false;
- this.updateGraphDropdown = true;
- },
-
- errorCallback() {
- this.hasError = true;
- this.isLoading = false;
- this.updateGraphDropdown = false;
- },
-
- setIsMakingRequest(isMakingRequest) {
- this.isMakingRequest = isMakingRequest;
-
- if (isMakingRequest) {
- this.updateGraphDropdown = false;
- }
- },
- },
-
- template: `
- <div class="content-list pipelines">
-
- <loading-icon
- label="Loading pipelines"
- size="3"
- v-if="isLoading"
- />
-
- <empty-state
- v-if="shouldRenderEmptyState"
- :help-page-path="helpPagePath" />
-
- <error-state v-if="shouldRenderErrorState" />
-
- <div
- class="table-holder"
- v-if="shouldRenderTable">
- <pipelines-table-component
- :pipelines="state.pipelines"
- :service="service"
- :update-graph-dropdown="updateGraphDropdown"
- />
- </div>
- </div>
- `,
-});
diff --git a/app/assets/javascripts/commit/pipelines/pipelines_table.vue b/app/assets/javascripts/commit/pipelines/pipelines_table.vue
new file mode 100644
index 00000000000..3c77f14d533
--- /dev/null
+++ b/app/assets/javascripts/commit/pipelines/pipelines_table.vue
@@ -0,0 +1,90 @@
+<script>
+ import PipelinesService from '../../pipelines/services/pipelines_service';
+ import PipelineStore from '../../pipelines/stores/pipelines_store';
+ import pipelinesMixin from '../../pipelines/mixins/pipelines';
+
+ export default {
+ props: {
+ endpoint: {
+ type: String,
+ required: true,
+ },
+ helpPagePath: {
+ type: String,
+ required: true,
+ },
+ },
+ mixins: [
+ pipelinesMixin,
+ ],
+
+ data() {
+ const store = new PipelineStore();
+
+ return {
+ store,
+ state: store.state,
+ };
+ },
+
+ computed: {
+ /**
+ * Empty state is only rendered if after the first request we receive no pipelines.
+ *
+ * @return {Boolean}
+ */
+ shouldRenderEmptyState() {
+ return !this.state.pipelines.length &&
+ !this.isLoading &&
+ this.hasMadeRequest &&
+ !this.hasError;
+ },
+
+ shouldRenderTable() {
+ return !this.isLoading &&
+ this.state.pipelines.length > 0 &&
+ !this.hasError;
+ },
+ },
+ created() {
+ this.service = new PipelinesService(this.endpoint);
+ },
+ methods: {
+ successCallback(resp) {
+ const response = resp.json();
+
+ // depending of the endpoint the response can either bring a `pipelines` key or not.
+ const pipelines = response.pipelines || response;
+ this.setCommonData(pipelines);
+ },
+ },
+ };
+</script>
+<template>
+ <div class="content-list pipelines">
+
+ <loading-icon
+ label="Loading pipelines"
+ size="3"
+ v-if="isLoading"
+ />
+
+ <empty-state
+ v-if="shouldRenderEmptyState"
+ :help-page-path="helpPagePath"
+ />
+
+ <error-state
+ v-if="shouldRenderErrorState"
+ />
+
+ <div
+ class="table-holder"
+ v-if="shouldRenderTable">
+ <pipelines-table-component
+ :pipelines="state.pipelines"
+ :update-graph-dropdown="updateGraphDropdown"
+ />
+ </div>
+ </div>
+</template>
diff --git a/app/assets/javascripts/dispatcher.js b/app/assets/javascripts/dispatcher.js
index 5f87a05067b..88b4b567fa9 100644
--- a/app/assets/javascripts/dispatcher.js
+++ b/app/assets/javascripts/dispatcher.js
@@ -79,7 +79,18 @@ import initSettingsPanels from './settings_panels';
path = page.split(':');
shortcut_handler = null;
- new GfmAutoComplete(gl.GfmAutoComplete && gl.GfmAutoComplete.dataSources).setup();
+ $('.js-gfm-input').each((i, el) => {
+ const gfm = new GfmAutoComplete(gl.GfmAutoComplete && gl.GfmAutoComplete.dataSources);
+ const enableGFM = gl.utils.convertPermissionToBoolean(el.dataset.supportsAutocomplete);
+ gfm.setup($(el), {
+ emojis: true,
+ members: enableGFM,
+ issues: enableGFM,
+ milestones: enableGFM,
+ mergeRequests: enableGFM,
+ labels: enableGFM,
+ });
+ });
function initBlob() {
new LineHighlighter();
@@ -176,7 +187,7 @@ import initSettingsPanels from './settings_panels';
case 'groups:milestones:update':
new ZenMode();
new gl.DueDateSelectors();
- new gl.GLForm($('.milestone-form'));
+ new gl.GLForm($('.milestone-form'), true);
break;
case 'projects:compare:show':
new gl.Diff();
@@ -188,7 +199,7 @@ import initSettingsPanels from './settings_panels';
case 'projects:issues:new':
case 'projects:issues:edit':
shortcut_handler = new ShortcutsNavigation();
- new gl.GLForm($('.issue-form'));
+ new gl.GLForm($('.issue-form'), true);
new IssuableForm($('.issue-form'));
new LabelsSelect();
new MilestoneSelect();
@@ -199,7 +210,7 @@ import initSettingsPanels from './settings_panels';
case 'projects:merge_requests:edit':
new gl.Diff();
shortcut_handler = new ShortcutsNavigation();
- new gl.GLForm($('.merge-request-form'));
+ new gl.GLForm($('.merge-request-form'), true);
new IssuableForm($('.merge-request-form'));
new LabelsSelect();
new MilestoneSelect();
@@ -208,22 +219,24 @@ import initSettingsPanels from './settings_panels';
break;
case 'projects:tags:new':
new ZenMode();
- new gl.GLForm($('.tag-form'));
+ new gl.GLForm($('.tag-form'), true);
new RefSelectDropdown($('.js-branch-select'), window.gl.availableRefs);
break;
case 'projects:snippets:new':
case 'projects:snippets:edit':
case 'projects:snippets:create':
case 'projects:snippets:update':
+ new gl.GLForm($('.snippet-form'), true);
+ break;
case 'snippets:new':
case 'snippets:edit':
case 'snippets:create':
case 'snippets:update':
- new gl.GLForm($('.snippet-form'));
+ new gl.GLForm($('.snippet-form'), false);
break;
case 'projects:releases:edit':
new ZenMode();
- new gl.GLForm($('.release-form'));
+ new gl.GLForm($('.release-form'), true);
break;
case 'projects:merge_requests:show':
new gl.Diff();
@@ -471,7 +484,7 @@ import initSettingsPanels from './settings_panels';
new gl.Wikis();
shortcut_handler = new ShortcutsWiki();
new ZenMode();
- new gl.GLForm($('.wiki-form'));
+ new gl.GLForm($('.wiki-form'), true);
break;
case 'snippets':
shortcut_handler = new ShortcutsNavigation();
diff --git a/app/assets/javascripts/dropzone_input.js b/app/assets/javascripts/dropzone_input.js
index 98ddcc20036..73675d300be 100644
--- a/app/assets/javascripts/dropzone_input.js
+++ b/app/assets/javascripts/dropzone_input.js
@@ -287,6 +287,10 @@ window.DropzoneInput = (function() {
$uploadingErrorMessage.html(message);
};
+ closeAlertMessage = function() {
+ return form.find('.div-dropzone-alert').alert('close');
+ };
+
form.find('.markdown-selector').click(function(e) {
e.preventDefault();
$(this).closest('.gfm-form').find('.div-dropzone').click();
diff --git a/app/assets/javascripts/environments/components/environment_item.vue b/app/assets/javascripts/environments/components/environment_item.vue
index 809c147bf25..b25113e0fc6 100644
--- a/app/assets/javascripts/environments/components/environment_item.vue
+++ b/app/assets/javascripts/environments/components/environment_item.vue
@@ -403,6 +403,14 @@ export default {
return '';
},
+ displayEnvironmentActions() {
+ return this.hasManualActions ||
+ this.externalURL ||
+ this.monitoringUrl ||
+ this.hasStopAction ||
+ this.canRetry;
+ },
+
/**
* Constructs folder URL based on the current location and the folder id.
*
@@ -535,9 +543,12 @@ export default {
</span>
</div>
- <div class="table-section section-30 table-button-footer" role="gridcell">
+ <div
+ v-if="!model.isFolder && displayEnvironmentActions"
+ class="table-section section-30 table-button-footer"
+ role="gridcell">
+
<div
- v-if="!model.isFolder"
class="btn-group table-action-buttons"
role="group">
diff --git a/app/assets/javascripts/filtered_search/dropdown_hint.js b/app/assets/javascripts/filtered_search/dropdown_hint.js
index 2af242a69df..5838b1bdbb7 100644
--- a/app/assets/javascripts/filtered_search/dropdown_hint.js
+++ b/app/assets/javascripts/filtered_search/dropdown_hint.js
@@ -56,7 +56,7 @@ class DropdownHint extends gl.FilteredSearchDropdown {
}
renderContent() {
- const dropdownData = gl.FilteredSearchTokenKeys.get()
+ const dropdownData = this.tokenKeys.get()
.map(tokenKey => ({
icon: `fa-${tokenKey.icon}`,
hint: tokenKey.key,
diff --git a/app/assets/javascripts/filtered_search/filtered_search_manager.js b/app/assets/javascripts/filtered_search/filtered_search_manager.js
index 8f547bd8f1f..c7c8d42e677 100644
--- a/app/assets/javascripts/filtered_search/filtered_search_manager.js
+++ b/app/assets/javascripts/filtered_search/filtered_search_manager.js
@@ -487,6 +487,7 @@ class FilteredSearchManager {
}
searchState(e) {
+ e.preventDefault();
const target = e.currentTarget;
// remove focus outline after click
target.blur();
diff --git a/app/assets/javascripts/gfm_auto_complete.js b/app/assets/javascripts/gfm_auto_complete.js
index 401dec1a370..105762cb1ba 100644
--- a/app/assets/javascripts/gfm_auto_complete.js
+++ b/app/assets/javascripts/gfm_auto_complete.js
@@ -34,7 +34,7 @@ class GfmAutoComplete {
const $input = $(input);
$input.off('focus.setupAtWho').on('focus.setupAtWho', this.setupAtWho.bind(this, $input));
// This triggers at.js again
- // Needed for slash commands with suffixes (ex: /label ~)
+ // Needed for quick actions with suffixes (ex: /label ~)
$input.on('inserted-commands.atwho', $input.trigger.bind($input, 'keyup'));
$input.on('clear-commands-cache.atwho', () => this.clearCache());
});
@@ -48,8 +48,8 @@ class GfmAutoComplete {
if (this.enableMap.mergeRequests) this.setupMergeRequests($input);
if (this.enableMap.labels) this.setupLabels($input);
- // We don't instantiate the slash commands autocomplete for note and issue/MR edit forms
- $input.filter('[data-supports-slash-commands="true"]').atwho({
+ // We don't instantiate the quick actions autocomplete for note and issue/MR edit forms
+ $input.filter('[data-supports-quick-actions="true"]').atwho({
at: '/',
alias: 'commands',
searchKey: 'search',
diff --git a/app/assets/javascripts/issuable_bulk_update_sidebar.js b/app/assets/javascripts/issuable_bulk_update_sidebar.js
index 84bd2e092e6..a8856120c5e 100644
--- a/app/assets/javascripts/issuable_bulk_update_sidebar.js
+++ b/app/assets/javascripts/issuable_bulk_update_sidebar.js
@@ -22,6 +22,7 @@ export default class IssuableBulkUpdateSidebar {
initDomElements() {
this.$page = $('.page-with-sidebar');
this.$sidebar = $('.right-sidebar');
+ this.$sidebarInnerContainer = this.$sidebar.find('.issuable-sidebar');
this.$bulkEditCancelBtn = $('.js-bulk-update-menu-hide');
this.$bulkEditSubmitBtn = $('.update-selected-issues');
this.$bulkUpdateEnableBtn = $('.js-bulk-update-toggle');
@@ -113,6 +114,7 @@ export default class IssuableBulkUpdateSidebar {
toggleSidebarDisplay(show) {
this.$page.toggleClass(SIDEBAR_EXPANDED_CLASS, show);
this.$page.toggleClass(SIDEBAR_COLLAPSED_CLASS, !show);
+ this.$sidebarInnerContainer.toggleClass(HIDDEN_CLASS, !show);
this.$sidebar.toggleClass(SIDEBAR_EXPANDED_CLASS, show);
this.$sidebar.toggleClass(SIDEBAR_COLLAPSED_CLASS, !show);
}
diff --git a/app/assets/javascripts/issue_show/components/app.vue b/app/assets/javascripts/issue_show/components/app.vue
index e14414d3f68..3d5fb7f441c 100644
--- a/app/assets/javascripts/issue_show/components/app.vue
+++ b/app/assets/javascripts/issue_show/components/app.vue
@@ -51,6 +51,11 @@ export default {
required: false,
default: '',
},
+ initialTaskStatus: {
+ type: String,
+ required: false,
+ default: '',
+ },
updatedAt: {
type: String,
required: false,
@@ -105,6 +110,7 @@ export default {
updatedAt: this.updatedAt,
updatedByName: this.updatedByName,
updatedByPath: this.updatedByPath,
+ taskStatus: this.initialTaskStatus,
});
return {
@@ -198,13 +204,7 @@ export default {
method: 'getData',
successCallback: (res) => {
const data = res.json();
- const shouldUpdate = this.store.stateShouldUpdate(data);
-
this.store.updateState(data);
-
- if (this.showForm && (shouldUpdate.title || shouldUpdate.description)) {
- this.store.formState.lockedWarningVisible = true;
- }
},
errorCallback(err) {
throw new Error(err);
diff --git a/app/assets/javascripts/issue_show/components/description.vue b/app/assets/javascripts/issue_show/components/description.vue
index 5ae617356e0..43db66c8e08 100644
--- a/app/assets/javascripts/issue_show/components/description.vue
+++ b/app/assets/javascripts/issue_show/components/description.vue
@@ -37,23 +37,12 @@
});
},
taskStatus() {
- const taskRegexMatches = this.taskStatus.match(/(\d+) of (\d+)/);
- const $issuableHeader = $('.issuable-meta');
- const $tasks = $('#task_status', $issuableHeader);
- const $tasksShort = $('#task_status_short', $issuableHeader);
-
- if (taskRegexMatches) {
- $tasks.text(this.taskStatus);
- $tasksShort.text(`${taskRegexMatches[1]}/${taskRegexMatches[2]} task${taskRegexMatches[2] > 1 ? 's' : ''}`);
- } else {
- $tasks.text('');
- $tasksShort.text('');
- }
+ this.updateTaskStatusText();
},
},
methods: {
renderGFM() {
- $(this.$refs['gfm-entry-content']).renderGFM();
+ $(this.$refs['gfm-content']).renderGFM();
if (this.canUpdate) {
// eslint-disable-next-line no-new
@@ -64,9 +53,24 @@
});
}
},
+ updateTaskStatusText() {
+ const taskRegexMatches = this.taskStatus.match(/(\d+) of ((?!0)\d+)/);
+ const $issuableHeader = $('.issuable-meta');
+ const $tasks = $('#task_status', $issuableHeader);
+ const $tasksShort = $('#task_status_short', $issuableHeader);
+
+ if (taskRegexMatches) {
+ $tasks.text(this.taskStatus);
+ $tasksShort.text(`${taskRegexMatches[1]}/${taskRegexMatches[2]} task${taskRegexMatches[2] > 1 ? 's' : ''}`);
+ } else {
+ $tasks.text('');
+ $tasksShort.text('');
+ }
+ },
},
mounted() {
this.renderGFM();
+ this.updateTaskStatusText();
},
};
</script>
diff --git a/app/assets/javascripts/issue_show/components/fields/description.vue b/app/assets/javascripts/issue_show/components/fields/description.vue
index 30a1be5cb50..54650d2f184 100644
--- a/app/assets/javascripts/issue_show/components/fields/description.vue
+++ b/app/assets/javascripts/issue_show/components/fields/description.vue
@@ -41,7 +41,7 @@
<textarea
id="issue-description"
class="note-textarea js-gfm-input js-autosize markdown-area"
- data-supports-slash-commands="false"
+ data-supports-quick-actionss="false"
aria-label="Description"
v-model="formState.description"
ref="textarea"
diff --git a/app/assets/javascripts/issue_show/index.js b/app/assets/javascripts/issue_show/index.js
index 14b2a1e18e9..ad8cb6465e2 100644
--- a/app/assets/javascripts/issue_show/index.js
+++ b/app/assets/javascripts/issue_show/index.js
@@ -45,6 +45,7 @@ document.addEventListener('DOMContentLoaded', () => {
updatedAt: this.updatedAt,
updatedByName: this.updatedByName,
updatedByPath: this.updatedByPath,
+ initialTaskStatus: this.initialTaskStatus,
},
});
},
diff --git a/app/assets/javascripts/issue_show/stores/index.js b/app/assets/javascripts/issue_show/stores/index.js
index 27c2d349f52..0c8bd6f1cc3 100644
--- a/app/assets/javascripts/issue_show/stores/index.js
+++ b/app/assets/javascripts/issue_show/stores/index.js
@@ -1,23 +1,6 @@
export default class Store {
- constructor({
- titleHtml,
- titleText,
- descriptionHtml,
- descriptionText,
- updatedAt,
- updatedByName,
- updatedByPath,
- }) {
- this.state = {
- titleHtml,
- titleText,
- descriptionHtml,
- descriptionText,
- taskStatus: '',
- updatedAt,
- updatedByName,
- updatedByPath,
- };
+ constructor(initialState) {
+ this.state = initialState;
this.formState = {
title: '',
confidential: false,
@@ -29,6 +12,10 @@ export default class Store {
}
updateState(data) {
+ if (this.stateShouldUpdate(data)) {
+ this.formState.lockedWarningVisible = true;
+ }
+
this.state.titleHtml = data.title;
this.state.titleText = data.title_text;
this.state.descriptionHtml = data.description;
@@ -40,10 +27,8 @@ export default class Store {
}
stateShouldUpdate(data) {
- return {
- title: this.state.titleText !== data.title_text,
- description: this.state.descriptionText !== data.description_text,
- };
+ return this.state.titleText !== data.title_text ||
+ this.state.descriptionText !== data.description_text;
}
setFormState(state) {
diff --git a/app/assets/javascripts/lib/utils/datetime_utility.js b/app/assets/javascripts/lib/utils/datetime_utility.js
index 54c0da3fc9c..bfcc50996cc 100644
--- a/app/assets/javascripts/lib/utils/datetime_utility.js
+++ b/app/assets/javascripts/lib/utils/datetime_utility.js
@@ -34,7 +34,7 @@ window.dateFormat = dateFormat;
w.gl.utils.localTimeAgo = function($timeagoEls, setTimeago = true) {
$timeagoEls.each((i, el) => {
- el.setAttribute('title', gl.utils.formatDate(el.getAttribute('datetime')));
+ el.setAttribute('title', el.getAttribute('title'));
if (setTimeago) {
// Recreate with custom template
diff --git a/app/assets/javascripts/locale/en/app.js b/app/assets/javascripts/locale/en/app.js
index 0bb76c80b7a..d634af959e5 100644
--- a/app/assets/javascripts/locale/en/app.js
+++ b/app/assets/javascripts/locale/en/app.js
@@ -1 +1 @@
-var locales = locales || {}; locales['en'] = {"domain":"app","locale_data":{"app":{"":{"Project-Id-Version":"gitlab 1.0.0","Report-Msgid-Bugs-To":"","PO-Revision-Date":"2017-04-12 22:36-0500","Last-Translator":"FULL NAME <EMAIL@ADDRESS>","Language-Team":"English","Language":"en","MIME-Version":"1.0","Content-Type":"text/plain; charset=UTF-8","Content-Transfer-Encoding":"8bit","Plural-Forms":"nplurals=2; plural=n != 1;","lang":"en","domain":"app","plural_forms":"nplurals=2; plural=n != 1;"},"Are you sure you want to delete this pipeline schedule?":[""],"ByAuthor|by":[""],"Cancel":[""],"Commit":["",""],"Cron Timezone":[""],"Cycle Analytics gives an overview of how much time it takes to go from idea to production in your project.":[""],"CycleAnalyticsStage|Code":[""],"CycleAnalyticsStage|Issue":[""],"CycleAnalyticsStage|Plan":[""],"CycleAnalyticsStage|Production":[""],"CycleAnalyticsStage|Review":[""],"CycleAnalyticsStage|Staging":[""],"CycleAnalyticsStage|Test":[""],"Delete":[""],"Deploy":["",""],"Description":[""],"Edit":[""],"Edit Pipeline Schedule %{id}":[""],"Failed to change the owner":[""],"Failed to remove the pipeline schedule":[""],"Filter":[""],"FirstPushedBy|First":[""],"FirstPushedBy|pushed by":[""],"From issue creation until deploy to production":[""],"From merge request merge until deploy to production":[""],"Interval Pattern":[""],"Introducing Cycle Analytics":[""],"Last %d day":["",""],"Last Pipeline":[""],"Limited to showing %d event at most":["",""],"Median":[""],"New Issue":["",""],"New Pipeline Schedule":[""],"No schedules":[""],"Not available":[""],"Not enough data":[""],"OpenedNDaysAgo|Opened":[""],"Owner":[""],"Pipeline Health":[""],"Pipeline Schedule":[""],"Pipeline Schedules":[""],"PipelineSchedules|Activated":[""],"PipelineSchedules|Active":[""],"PipelineSchedules|All":[""],"PipelineSchedules|Inactive":[""],"PipelineSchedules|Next Run":[""],"PipelineSchedules|None":[""],"PipelineSchedules|Provide a short description for this pipeline":[""],"PipelineSchedules|Take ownership":[""],"PipelineSchedules|Target":[""],"ProjectLifecycle|Stage":[""],"Read more":[""],"Related Commits":[""],"Related Deployed Jobs":[""],"Related Issues":[""],"Related Jobs":[""],"Related Merge Requests":[""],"Related Merged Requests":[""],"Save pipeline schedule":[""],"Schedule a new pipeline":[""],"Select a timezone":[""],"Select target branch":[""],"Showing %d event":["",""],"Target Branch":[""],"The coding stage shows the time from the first commit to creating the merge request. The data will automatically be added here once you create your first merge request.":[""],"The collection of events added to the data gathered for that stage.":[""],"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.":[""],"The phase of the development lifecycle.":[""],"The planning stage shows the time from the previous step to pushing your first commit. This time will be added automatically once you push your first commit.":[""],"The production stage shows the total time it takes between creating an issue and deploying the code to production. The data will be automatically added once you have completed the full idea to production cycle.":[""],"The review stage shows the time from creating the merge request to merging it. The data will automatically be added after you merge your first merge request.":[""],"The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time.":[""],"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.":[""],"The time taken by each data entry gathered by that stage.":[""],"The value lying at the midpoint of a series of observed values. E.g., between 3, 5, 9, the median is 5. Between 3, 5, 7, 8, the median is (5+7)/2 = 6.":[""],"Time before an issue gets scheduled":[""],"Time before an issue starts implementation":[""],"Time between merge request creation and merge/close":[""],"Time until first merge request":[""],"Time|hr":["",""],"Time|min":["",""],"Time|s":[""],"Total Time":[""],"Total test time for all commits/merges":[""],"Want to see the data? Please ask an administrator for access.":[""],"We don't have enough data to show this stage.":[""],"You need permission.":[""],"day":["",""]}}}; \ No newline at end of file
+var locales = locales || {}; locales['en'] = {"domain":"app","locale_data":{"app":{"":{"Project-Id-Version":"gitlab 1.0.0","Report-Msgid-Bugs-To":"","PO-Revision-Date":"2017-04-12 22:36-0500","Last-Translator":"FULL NAME <EMAIL@ADDRESS>","Language-Team":"English","Language":"en","MIME-Version":"1.0","Content-Type":"text/plain; charset=UTF-8","Content-Transfer-Encoding":"8bit","Plural-Forms":"nplurals=2; plural=n != 1;","lang":"en","domain":"app","plural_forms":"nplurals=2; plural=n != 1;"},"%{commit_author_link} committed %{commit_timeago}":[""],"About auto deploy":[""],"Active":[""],"Activity":[""],"Add Changelog":[""],"Add Contribution guide":[""],"Add License":[""],"Add an SSH key to your profile to pull or push via SSH.":[""],"Add new directory":[""],"Archived project! Repository is read-only":[""],"Are you sure you want to delete this pipeline schedule?":[""],"Attach a file by drag &amp; drop or %{upload_link}":[""],"Branch":["",""],"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}":[""],"Branches":[""],"Browse files":[""],"ByAuthor|by":[""],"CI configuration":[""],"Cancel":[""],"ChangeTypeActionLabel|Pick into branch":[""],"ChangeTypeActionLabel|Revert in branch":[""],"ChangeTypeAction|Cherry-pick":[""],"Changelog":[""],"Charts":[""],"Cherry-pick this commit":[""],"Cherry-pick this merge request":[""],"CiStatusLabel|canceled":[""],"CiStatusLabel|created":[""],"CiStatusLabel|failed":[""],"CiStatusLabel|manual action":[""],"CiStatusLabel|passed":[""],"CiStatusLabel|passed with warnings":[""],"CiStatusLabel|pending":[""],"CiStatusLabel|skipped":[""],"CiStatusLabel|waiting for manual action":[""],"CiStatusText|blocked":[""],"CiStatusText|canceled":[""],"CiStatusText|created":[""],"CiStatusText|failed":[""],"CiStatusText|manual":[""],"CiStatusText|passed":[""],"CiStatusText|pending":[""],"CiStatusText|skipped":[""],"CiStatus|running":[""],"Commit":["",""],"Commit message":[""],"CommitBoxTitle|Commit":[""],"CommitMessage|Add %{file_name}":[""],"Commits":[""],"Commits|History":[""],"Committed by":[""],"Compare":[""],"Contribution guide":[""],"Contributors":[""],"Copy URL to clipboard":[""],"Copy commit SHA to clipboard":[""],"Create New Directory":[""],"Create directory":[""],"Create empty bare repository":[""],"Create merge request":[""],"Create new...":[""],"CreateNewFork|Fork":[""],"CreateTag|Tag":[""],"Cron Timezone":[""],"Cron syntax":[""],"Custom notification events":[""],"Custom notification levels are the same as participating levels. With custom notification levels you will also receive notifications for select events. To find out more, check out %{notification_link}.":[""],"Cycle Analytics":[""],"Cycle Analytics gives an overview of how much time it takes to go from idea to production in your project.":[""],"CycleAnalyticsStage|Code":[""],"CycleAnalyticsStage|Issue":[""],"CycleAnalyticsStage|Plan":[""],"CycleAnalyticsStage|Production":[""],"CycleAnalyticsStage|Review":[""],"CycleAnalyticsStage|Staging":[""],"CycleAnalyticsStage|Test":[""],"Define a custom pattern with cron syntax":[""],"Delete":[""],"Deploy":["",""],"Description":[""],"Directory name":[""],"Don't show again":[""],"Download":[""],"Download tar":[""],"Download tar.bz2":[""],"Download tar.gz":[""],"Download zip":[""],"DownloadArtifacts|Download":[""],"DownloadCommit|Email Patches":[""],"DownloadCommit|Plain Diff":[""],"DownloadSource|Download":[""],"Edit":[""],"Edit Pipeline Schedule %{id}":[""],"Every day (at 4:00am)":[""],"Every month (on the 1st at 4:00am)":[""],"Every week (Sundays at 4:00am)":[""],"Failed to change the owner":[""],"Failed to remove the pipeline schedule":[""],"Files":[""],"Find by path":[""],"Find file":[""],"FirstPushedBy|First":[""],"FirstPushedBy|pushed by":[""],"Fork":["",""],"ForkedFromProjectPath|Forked from":[""],"From issue creation until deploy to production":[""],"From merge request merge until deploy to production":[""],"Go to your fork":[""],"GoToYourFork|Fork":[""],"Home":[""],"Housekeeping successfully started":[""],"Import repository":[""],"Interval Pattern":[""],"Introducing Cycle Analytics":[""],"LFSStatus|Disabled":[""],"LFSStatus|Enabled":[""],"Last %d day":["",""],"Last Pipeline":[""],"Last Update":[""],"Last commit":[""],"Learn more in the":[""],"Learn more in the|pipeline schedules documentation":[""],"Leave group":[""],"Leave project":[""],"Limited to showing %d event at most":["",""],"Median":[""],"MissingSSHKeyWarningLink|add an SSH key":[""],"New Issue":["",""],"New Pipeline Schedule":[""],"New branch":[""],"New directory":[""],"New file":[""],"New issue":[""],"New merge request":[""],"New schedule":[""],"New snippet":[""],"New tag":[""],"No repository":[""],"No schedules":[""],"Not available":[""],"Not enough data":[""],"Notification events":[""],"NotificationEvent|Close issue":[""],"NotificationEvent|Close merge request":[""],"NotificationEvent|Failed pipeline":[""],"NotificationEvent|Merge merge request":[""],"NotificationEvent|New issue":[""],"NotificationEvent|New merge request":[""],"NotificationEvent|New note":[""],"NotificationEvent|Reassign issue":[""],"NotificationEvent|Reassign merge request":[""],"NotificationEvent|Reopen issue":[""],"NotificationEvent|Successful pipeline":[""],"NotificationLevel|Custom":[""],"NotificationLevel|Disabled":[""],"NotificationLevel|Global":[""],"NotificationLevel|On mention":[""],"NotificationLevel|Participate":[""],"NotificationLevel|Watch":[""],"OfSearchInADropdown|Filter":[""],"OpenedNDaysAgo|Opened":[""],"Options":[""],"Owner":[""],"Pipeline":[""],"Pipeline Health":[""],"Pipeline Schedule":[""],"Pipeline Schedules":[""],"PipelineSchedules|Activated":[""],"PipelineSchedules|Active":[""],"PipelineSchedules|All":[""],"PipelineSchedules|Inactive":[""],"PipelineSchedules|Next Run":[""],"PipelineSchedules|None":[""],"PipelineSchedules|Provide a short description for this pipeline":[""],"PipelineSchedules|Take ownership":[""],"PipelineSchedules|Target":[""],"PipelineSheduleIntervalPattern|Custom":[""],"Pipeline|with stage":[""],"Pipeline|with stages":[""],"Project '%{project_name}' queued for deletion.":[""],"Project '%{project_name}' was successfully created.":[""],"Project '%{project_name}' was successfully updated.":[""],"Project '%{project_name}' will be deleted.":[""],"Project access must be granted explicitly to each user.":[""],"Project export could not be deleted.":[""],"Project export has been deleted.":[""],"Project export link has expired. Please generate a new export from your project settings.":[""],"Project export started. A download link will be sent by email.":[""],"Project home":[""],"ProjectFeature|Disabled":[""],"ProjectFeature|Everyone with access":[""],"ProjectFeature|Only team members":[""],"ProjectFileTree|Name":[""],"ProjectLastActivity|Never":[""],"ProjectLifecycle|Stage":[""],"ProjectNetworkGraph|Graph":[""],"Read more":[""],"Readme":[""],"RefSwitcher|Branches":[""],"RefSwitcher|Tags":[""],"Related Commits":[""],"Related Deployed Jobs":[""],"Related Issues":[""],"Related Jobs":[""],"Related Merge Requests":[""],"Related Merged Requests":[""],"Remind later":[""],"Remove project":[""],"Request Access":[""],"Revert this commit":[""],"Revert this merge request":[""],"Save pipeline schedule":[""],"Schedule a new pipeline":[""],"Scheduling Pipelines":[""],"Search branches and tags":[""],"Select Archive Format":[""],"Select a timezone":[""],"Select target branch":[""],"Set a password on your account to pull or push via %{protocol}":[""],"Set up CI":[""],"Set up Koding":[""],"Set up auto deploy":[""],"SetPasswordToCloneLink|set a password":[""],"Showing %d event":["",""],"Source code":[""],"StarProject|Star":[""],"Start a %{new_merge_request} with these changes":[""],"Start a <strong>new merge request</strong> with these changes":[""],"Switch branch/tag":[""],"Tag":["",""],"Tags":[""],"Target Branch":[""],"The coding stage shows the time from the first commit to creating the merge request. The data will automatically be added here once you create your first merge request.":[""],"The collection of events added to the data gathered for that stage.":[""],"The fork relationship has been removed.":[""],"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.":[""],"The phase of the development lifecycle.":[""],"The pipelines schedule runs pipelines in the future, repeatedly, for specific branches or tags. Those scheduled pipelines will inherit limited project access based on their associated user.":[""],"The planning stage shows the time from the previous step to pushing your first commit. This time will be added automatically once you push your first commit.":[""],"The production stage shows the total time it takes between creating an issue and deploying the code to production. The data will be automatically added once you have completed the full idea to production cycle.":[""],"The project can be accessed by any logged in user.":[""],"The project can be accessed without any authentication.":[""],"The repository for this project does not exist.":[""],"The review stage shows the time from creating the merge request to merging it. The data will automatically be added after you merge your first merge request.":[""],"The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time.":[""],"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.":[""],"The time taken by each data entry gathered by that stage.":[""],"The value lying at the midpoint of a series of observed values. E.g., between 3, 5, 9, the median is 5. Between 3, 5, 7, 8, the median is (5+7)/2 = 6.":[""],"This means you can not push code until you create an empty repository or import existing one.":[""],"Time before an issue gets scheduled":[""],"Time before an issue starts implementation":[""],"Time between merge request creation and merge/close":[""],"Time until first merge request":[""],"Timeago|%s days ago":[""],"Timeago|%s days remaining":[""],"Timeago|%s hours remaining":[""],"Timeago|%s minutes ago":[""],"Timeago|%s minutes remaining":[""],"Timeago|%s months ago":[""],"Timeago|%s months remaining":[""],"Timeago|%s seconds remaining":[""],"Timeago|%s weeks ago":[""],"Timeago|%s weeks remaining":[""],"Timeago|%s years ago":[""],"Timeago|%s years remaining":[""],"Timeago|1 day remaining":[""],"Timeago|1 hour remaining":[""],"Timeago|1 minute remaining":[""],"Timeago|1 month remaining":[""],"Timeago|1 week remaining":[""],"Timeago|1 year remaining":[""],"Timeago|Past due":[""],"Timeago|a day ago":[""],"Timeago|a month ago":[""],"Timeago|a week ago":[""],"Timeago|a while":[""],"Timeago|a year ago":[""],"Timeago|about %s hours ago":[""],"Timeago|about a minute ago":[""],"Timeago|about an hour ago":[""],"Timeago|in %s days":[""],"Timeago|in %s hours":[""],"Timeago|in %s minutes":[""],"Timeago|in %s months":[""],"Timeago|in %s seconds":[""],"Timeago|in %s weeks":[""],"Timeago|in %s years":[""],"Timeago|in 1 day":[""],"Timeago|in 1 hour":[""],"Timeago|in 1 minute":[""],"Timeago|in 1 month":[""],"Timeago|in 1 week":[""],"Timeago|in 1 year":[""],"Timeago|less than a minute ago":[""],"Time|hr":["",""],"Time|min":["",""],"Time|s":[""],"Total Time":[""],"Total test time for all commits/merges":[""],"Unstar":[""],"Upload New File":[""],"Upload file":[""],"Use your global notification setting":[""],"VisibilityLevel|Internal":[""],"VisibilityLevel|Private":[""],"VisibilityLevel|Public":[""],"Want to see the data? Please ask an administrator for access.":[""],"We don't have enough data to show this stage.":[""],"Withdraw Access Request":[""],"You are going to remove %{project_name_with_namespace}.\\nRemoved project CANNOT be restored!\\nAre you ABSOLUTELY sure?":[""],"You are going to remove the fork relationship to source project %{forked_from_project}. Are you ABSOLUTELY sure?":[""],"You are going to transfer %{project_name_with_namespace} to another owner. Are you ABSOLUTELY sure?":[""],"You can only add files when you are on a branch":[""],"You must sign in to star a project":[""],"You need permission.":[""],"You will not get any notifications via email":[""],"You will only receive notifications for the events you choose":[""],"You will only receive notifications for threads you have participated in":[""],"You will receive notifications for any activity":[""],"You will receive notifications only for comments in which you were @mentioned":[""],"You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account":[""],"You won't be able to pull or push project code via SSH until you %{add_ssh_key_link} to your profile":[""],"Your name":[""],"day":["",""],"new merge request":[""],"notification emails":[""],"parent":["",""]}}}; \ No newline at end of file
diff --git a/app/assets/javascripts/locale/es/app.js b/app/assets/javascripts/locale/es/app.js
index 6977625f4d8..eafcd15acf9 100644
--- a/app/assets/javascripts/locale/es/app.js
+++ b/app/assets/javascripts/locale/es/app.js
@@ -1 +1 @@
-var locales = locales || {}; locales['es'] = {"domain":"app","locale_data":{"app":{"":{"Project-Id-Version":"gitlab 1.0.0","Report-Msgid-Bugs-To":"","PO-Revision-Date":"2017-06-07 12:29-0500","Language-Team":"Spanish","Language":"es","MIME-Version":"1.0","Content-Type":"text/plain; charset=UTF-8","Content-Transfer-Encoding":"8bit","Plural-Forms":"nplurals=2; plural=n != 1;","Last-Translator":"Bob Van Landuyt <bob@gitlab.com>","X-Generator":"Poedit 2.0.2","lang":"es","domain":"app","plural_forms":"nplurals=2; plural=n != 1;"},"About auto deploy":["Acerca del auto despliegue"],"Activity":["Actividad"],"Add Changelog":["Agregar Changelog"],"Add Contribution guide":["Agregar guía de contribución"],"Add License":["Agregar Licencia"],"Add an SSH key to your profile to pull or push via SSH.":["Agregar una clave SSH a tu perfil para actualizar o enviar a través de SSH."],"Add new directory":["Agregar nuevo directorio"],"Archived project! Repository is read-only":["¡Proyecto archivado! El repositorio es de sólo lectura"],"Branch":["Rama","Ramas"],"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}":["La rama <strong>%{branch_name}</strong> fue creada. Para configurar el auto despliegue, escoge una plantilla Yaml para GitLab CI y envía tus cambios. %{link_to_autodeploy_doc}"],"Branches":["Ramas"],"ByAuthor|by":["por"],"CI configuration":["Configuración de CI"],"Changelog":["Changelog"],"Charts":["Gráficos"],"CiStatusLabel|canceled":["cancelado"],"CiStatusLabel|created":["creado"],"CiStatusLabel|failed":["fallado"],"CiStatusLabel|manual action":["acción manual"],"CiStatusLabel|passed":["pasó"],"CiStatusLabel|passed with warnings":["pasó con advertencias"],"CiStatusLabel|pending":["pendiente"],"CiStatusLabel|skipped":["omitido"],"CiStatusLabel|waiting for manual action":["esperando acción manual"],"CiStatusText|blocked":["bloqueado"],"CiStatusText|canceled":["cancelado"],"CiStatusText|created":["creado"],"CiStatusText|failed":["fallado"],"CiStatusText|manual":["manual"],"CiStatusText|passed":["pasó"],"CiStatusText|pending":["pendiente"],"CiStatusText|skipped":["omitido"],"CiStatus|running":["en ejecución"],"Commit":["Cambio","Cambios"],"CommitMessage|Add %{file_name}":["Agregar %{file_name}"],"Commits":["Cambios"],"Commits|History":["Historial"],"Compare":["Comparar"],"Contribution guide":["Guía de contribución"],"Contributors":["Contribuidores"],"Copy URL to clipboard":["Copiar URL al portapapeles"],"Copy commit SHA to clipboard":["Copiar SHA del cambio al portapapeles"],"Create New Directory":["Crear Nuevo Directorio"],"Create directory":["Crear directorio"],"Create empty bare repository":["Crear repositorio vacío"],"Create merge request":["Crear solicitud de fusión"],"CreateNewFork|Fork":["Bifurcar"],"Custom notification events":["Eventos de notificaciones personalizadas"],"Custom notification levels are the same as participating levels. With custom notification levels you will also receive notifications for select events. To find out more, check out %{notification_link}.":["Los niveles de notificación personalizados son los mismos que los niveles participantes. Con los niveles de notificación personalizados, también recibirá notificaciones para eventos seleccionados. Para obtener más información, consulte %{notification_link}."],"Cycle Analytics":["Cycle Analytics"],"Cycle Analytics gives an overview of how much time it takes to go from idea to production in your project.":["Cycle Analytics ofrece una visión general de cuánto tiempo tarda en pasar de idea a producción en su proyecto."],"CycleAnalyticsStage|Code":["Código"],"CycleAnalyticsStage|Issue":["Incidencia"],"CycleAnalyticsStage|Plan":["Planificación"],"CycleAnalyticsStage|Production":["Producción"],"CycleAnalyticsStage|Review":["Revisión"],"CycleAnalyticsStage|Staging":["Puesta en escena"],"CycleAnalyticsStage|Test":["Pruebas"],"Deploy":["Despliegue","Despliegues"],"Directory name":["Nombre del directorio"],"Don't show again":["No mostrar de nuevo"],"Download tar":["Descargar tar"],"Download tar.bz2":["Descargar tar.bz2"],"Download tar.gz":["Descargar tar.gz"],"Download zip":["Descargar zip"],"DownloadArtifacts|Download":["Descargar"],"DownloadSource|Download":["Descargar"],"Files":["Archivos"],"Find by path":["Buscar por ruta"],"Find file":["Buscar archivo"],"FirstPushedBy|First":["Primer"],"FirstPushedBy|pushed by":["enviado por"],"ForkedFromProjectPath|Forked from":["Bifurcado de"],"Forks":["Bifurcaciones"],"From issue creation until deploy to production":["Desde la creación de la incidencia hasta el despliegue a producción"],"From merge request merge until deploy to production":["Desde la integración de la solicitud de fusión hasta el despliegue a producción"],"Go to your fork":["Ir a tu bifurcación"],"GoToYourFork|Fork":["Bifurcación"],"Home":["Inicio"],"Housekeeping successfully started":["Servicio de limpieza iniciado con éxito"],"Import repository":["Importar repositorio"],"Introducing Cycle Analytics":["Introducción a Cycle Analytics"],"LFSStatus|Disabled":["Deshabilitado"],"LFSStatus|Enabled":["Habilitado"],"Last %d day":["Último %d día","Últimos %d días"],"Last Update":["Última actualización"],"Last commit":["Último cambio"],"Leave group":["Abandonar grupo"],"Leave project":["Abandonar proyecto"],"Limited to showing %d event at most":["Limitado a mostrar máximo %d evento","Limitado a mostrar máximo %d eventos"],"Median":["Mediana"],"MissingSSHKeyWarningLink|add an SSH key":["agregar una clave SSH"],"New Issue":["Nueva incidencia","Nuevas incidencias"],"New branch":["Nueva rama"],"New directory":["Nuevo directorio"],"New file":["Nuevo archivo"],"New issue":["Nueva incidencia"],"New merge request":["Nueva solicitud de fusión"],"New snippet":["Nuevo fragmento de código"],"New tag":["Nueva etiqueta"],"No repository":["No hay repositorio"],"Not available":["No disponible"],"Not enough data":["No hay suficientes datos"],"Notification events":["Eventos de notificación"],"NotificationEvent|Close issue":["Cerrar incidencia"],"NotificationEvent|Close merge request":["Cerrar solicitud de fusión"],"NotificationEvent|Failed pipeline":["Pipeline fallido"],"NotificationEvent|Merge merge request":["Integrar solicitud de fusión"],"NotificationEvent|New issue":["Nueva incidencia"],"NotificationEvent|New merge request":["Nueva solicitud de fusión"],"NotificationEvent|New note":["Nueva nota"],"NotificationEvent|Reassign issue":["Reasignar incidencia"],"NotificationEvent|Reassign merge request":["Reasignar solicitud de fusión"],"NotificationEvent|Reopen issue":["Reabrir incidencia"],"NotificationEvent|Successful pipeline":["Pipeline exitoso"],"NotificationLevel|Custom":["Personalizado"],"NotificationLevel|Disabled":["Deshabilitado"],"NotificationLevel|Global":["Global"],"NotificationLevel|On mention":["Cuando me mencionan"],"NotificationLevel|Participate":["Participación"],"NotificationLevel|Watch":["Vigilancia"],"OpenedNDaysAgo|Opened":["Abierto"],"Pipeline Health":["Estado del Pipeline"],"Project '%{project_name}' queued for deletion.":["Proyecto ‘%{project_name}’ en cola para eliminación."],"Project '%{project_name}' was successfully created.":["Proyecto ‘%{project_name}’ fue creado satisfactoriamente."],"Project '%{project_name}' was successfully updated.":["Proyecto ‘%{project_name}’ fue actualizado satisfactoriamente."],"Project '%{project_name}' will be deleted.":["Proyecto ‘%{project_name}’ será eliminado."],"Project access must be granted explicitly to each user.":["El acceso al proyecto debe concederse explícitamente a cada usuario."],"Project export could not be deleted.":["No se pudo eliminar la exportación del proyecto."],"Project export has been deleted.":["La exportación del proyecto ha sido eliminada."],"Project export link has expired. Please generate a new export from your project settings.":["El enlace de exportación del proyecto ha caducado. Por favor, genera una nueva exportación desde la configuración del proyecto."],"Project export started. A download link will be sent by email.":["Se inició la exportación del proyecto. Se enviará un enlace de descarga por correo electrónico."],"Project home":["Inicio del proyecto"],"ProjectFeature|Disabled":["Deshabilitada"],"ProjectFeature|Everyone with access":["Todos con acceso"],"ProjectFeature|Only team members":["Solo miembros del equipo"],"ProjectFileTree|Name":["Nombre"],"ProjectLastActivity|Never":["Nunca"],"ProjectLifecycle|Stage":["Etapa"],"ProjectNetworkGraph|Graph":["Historial gráfico"],"Read more":["Leer más"],"Readme":["Readme"],"RefSwitcher|Branches":["Ramas"],"RefSwitcher|Tags":["Etiquetas"],"Related Commits":["Cambios Relacionados"],"Related Deployed Jobs":["Trabajos Desplegados Relacionados"],"Related Issues":["Incidencias Relacionadas"],"Related Jobs":["Trabajos Relacionados"],"Related Merge Requests":["Solicitudes de fusión Relacionadas"],"Related Merged Requests":["Solicitudes de fusión Relacionadas"],"Remind later":["Recordar después"],"Remove project":["Eliminar proyecto"],"Request Access":["Solicitar acceso"],"Search branches and tags":["Buscar ramas y etiquetas"],"Select Archive Format":["Seleccionar formato de archivo"],"Set a password on your account to pull or push via %{protocol}":["Establezca una contraseña en su cuenta para actualizar o enviar a través de% {protocol}"],"Set up CI":["Configurar CI"],"Set up Koding":["Configurar Koding"],"Set up auto deploy":["Configurar auto despliegue"],"SetPasswordToCloneLink|set a password":["establecer una contraseña"],"Showing %d event":["Mostrando %d evento","Mostrando %d eventos"],"Source code":["Código fuente"],"StarProject|Star":["Destacar"],"Switch branch/tag":["Cambiar rama/etiqueta"],"Tag":["Etiqueta","Etiquetas"],"Tags":["Etiquetas"],"The coding stage shows the time from the first commit to creating the merge request. The data will automatically be added here once you create your first merge request.":["La etapa de desarrollo muestra el tiempo desde el primer cambio hasta la creación de la solicitud de fusión. Los datos serán automáticamente incorporados aquí una vez creada tu primera solicitud de fusión."],"The collection of events added to the data gathered for that stage.":["La colección de eventos agregados a los datos recopilados para esa etapa."],"The fork relationship has been removed.":["La relación con la bifurcación se ha eliminado."],"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.":["La etapa de incidencia muestra el tiempo que toma desde la creación de un tema hasta asignar el tema a un hito, o añadir el tema a una lista en el panel de temas. Empieza a crear temas para ver los datos de esta etapa."],"The phase of the development lifecycle.":["La etapa del ciclo de vida de desarrollo."],"The planning stage shows the time from the previous step to pushing your first commit. This time will be added automatically once you push your first commit.":["La etapa de planificación muestra el tiempo desde el paso anterior hasta el envío de tu primera confirmación. Este tiempo se añadirá automáticamente una vez que usted envíe el primer cambio."],"The production stage shows the total time it takes between creating an issue and deploying the code to production. The data will be automatically added once you have completed the full idea to production cycle.":["La etapa de producción muestra el tiempo total que tarda entre la creación de una incidencia y el despliegue del código a producción. Los datos se añadirán automáticamente una vez haya finalizado por completo el ciclo de idea a producción."],"The project can be accessed by any logged in user.":["El proyecto puede ser accedido por cualquier usuario conectado."],"The project can be accessed without any authentication.":["El proyecto puede accederse sin ninguna autenticación."],"The repository for this project does not exist.":["El repositorio para este proyecto no existe."],"The review stage shows the time from creating the merge request to merging it. The data will automatically be added after you merge your first merge request.":["La etapa de revisión muestra el tiempo desde la creación de la solicitud de fusión hasta que los cambios se fusionaron. Los datos se añadirán automáticamente después de fusionar su primera solicitud de fusión."],"The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time.":["La etapa de puesta en escena muestra el tiempo entre la fusión y el despliegue de código en el entorno de producción. Los datos se añadirán automáticamente una vez que se despliega a producción por primera vez."],"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.":["La etapa de pruebas muestra el tiempo que GitLab CI toma para ejecutar cada pipeline para la solicitud de fusión relacionada. Los datos se añadirán automáticamente luego de que el primer pipeline termine de ejecutarse."],"The time taken by each data entry gathered by that stage.":["El tiempo utilizado por cada entrada de datos obtenido por esa etapa."],"The value lying at the midpoint of a series of observed values. E.g., between 3, 5, 9, the median is 5. Between 3, 5, 7, 8, the median is (5+7)/2 = 6.":["El valor en el punto medio de una serie de valores observados. Por ejemplo, entre 3, 5, 9, la mediana es 5. Entre 3, 5, 7, 8, la mediana es (5 + 7) / 2 = 6."],"This means you can not push code until you create an empty repository or import existing one.":["Esto significa que no puede enviar código hasta que cree un repositorio vacío o importe uno existente."],"Time before an issue gets scheduled":["Tiempo antes de que una incidencia sea programada"],"Time before an issue starts implementation":["Tiempo antes de que empieze la implementación de una incidencia"],"Time between merge request creation and merge/close":["Tiempo entre la creación de la solicitud de fusión y la integración o cierre de ésta"],"Time until first merge request":["Tiempo hasta la primera solicitud de fusión"],"Timeago|%s days ago":["hace %s días"],"Timeago|%s days remaining":["%s días restantes"],"Timeago|%s hours remaining":["%s horas restantes"],"Timeago|%s minutes ago":["hace %s minutos"],"Timeago|%s minutes remaining":["%s minutos restantes"],"Timeago|%s months ago":["hace %s meses"],"Timeago|%s months remaining":["%s meses restantes"],"Timeago|%s seconds remaining":["%s segundos restantes"],"Timeago|%s weeks ago":["hace %s semanas"],"Timeago|%s weeks remaining":["%s semanas restantes"],"Timeago|%s years ago":["hace %s años"],"Timeago|%s years remaining":["%s años restantes"],"Timeago|1 day remaining":["1 día restante"],"Timeago|1 hour remaining":["1 hora restante"],"Timeago|1 minute remaining":["1 minuto restante"],"Timeago|1 month remaining":["1 mes restante"],"Timeago|1 week remaining":["1 semana restante"],"Timeago|1 year remaining":["1 año restante"],"Timeago|Past due":["Atrasado"],"Timeago|a day ago":["hace un día"],"Timeago|a month ago":["hace 1 mes"],"Timeago|a week ago":["hace 1 semana"],"Timeago|a while":["hace un momento"],"Timeago|a year ago":["hace 1 año"],"Timeago|about %s hours ago":["hace alrededor de %s horas"],"Timeago|about a minute ago":["hace alrededor de 1 minuto"],"Timeago|about an hour ago":["hace alrededor de 1 hora"],"Timeago|in %s days":["en %s días"],"Timeago|in %s hours":["en %s horas"],"Timeago|in %s minutes":["en %s minutos"],"Timeago|in %s months":["en %s meses"],"Timeago|in %s seconds":["en %s segundos"],"Timeago|in %s weeks":["en %s semanas"],"Timeago|in %s years":["en %s años"],"Timeago|in 1 day":["en 1 día"],"Timeago|in 1 hour":["en 1 hora"],"Timeago|in 1 minute":["en 1 minuto"],"Timeago|in 1 month":["en 1 mes"],"Timeago|in 1 week":["en 1 semana"],"Timeago|in 1 year":["en 1 año"],"Timeago|less than a minute ago":["hace menos de 1 minuto"],"Time|hr":["hr","hrs"],"Time|min":["min","mins"],"Time|s":["s"],"Total Time":["Tiempo Total"],"Total test time for all commits/merges":["Tiempo total de pruebas para todos los cambios o integraciones"],"Unstar":["No Destacar"],"Upload New File":["Subir nuevo archivo"],"Upload file":["Subir archivo"],"Use your global notification setting":["Utiliza tu configuración de notificación global"],"VisibilityLevel|Internal":["Interno"],"VisibilityLevel|Private":["Privado"],"VisibilityLevel|Public":["Público"],"Want to see the data? Please ask an administrator for access.":["¿Quieres ver los datos? Por favor pide acceso al administrador."],"We don't have enough data to show this stage.":["No hay suficientes datos para mostrar en esta etapa."],"Withdraw Access Request":["Retirar Solicitud de Acceso"],"You are going to remove %{project_name_with_namespace}.\\nRemoved project CANNOT be restored!\\nAre you ABSOLUTELY sure?":["Va a eliminar %{project_name_with_namespace}.\\n¡El proyecto eliminado NO puede ser restaurado!\\n¿Estás TOTALMENTE seguro?"],"You are going to remove the fork relationship to source project %{forked_from_project}. Are you ABSOLUTELY sure?":["Vas a eliminar el enlace de la bifurcación con el proyecto original %{forked_from_project}. ¿Estás TOTALMENTE seguro?"],"You are going to transfer %{project_name_with_namespace} to another owner. Are you ABSOLUTELY sure?":["Vas a transferir %{project_name_with_namespace} a otro propietario. ¿Estás TOTALMENTE seguro?"],"You can only add files when you are on a branch":["Sólo puede agregar archivos cuando estas en una rama"],"You must sign in to star a project":["Debes iniciar sesión para destacar un proyecto"],"You need permission.":["Necesitas permisos."],"You will not get any notifications via email":["No recibirás ninguna notificación por correo electrónico"],"You will only receive notifications for the events you choose":["Solo recibirás notificaciones de los eventos que elijas"],"You will only receive notifications for threads you have participated in":["Solo recibirás notificaciones de los temas en los que has participado"],"You will receive notifications for any activity":["Recibirás notificaciones para cualquier actividad"],"You will receive notifications only for comments in which you were @mentioned":["Recibirás notificaciones sólo para los comentarios en los que se te mencionó"],"You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account":["No podrás actualizar o enviar código al proyecto a través de %{protocol} hasta que %{set_password_link} en tu cuenta"],"You won't be able to pull or push project code via SSH until you %{add_ssh_key_link} to your profile":["No podrás actualizar o enviar código al proyecto a través de SSH hasta que %{add_ssh_key_link} en su perfil"],"Your name":["Tu nombre"],"committed":["cambió"],"day":["día","días"],"notification emails":["correos electrónicos de notificación"]}}}; \ No newline at end of file
+var locales = locales || {}; locales['es'] = {"domain":"app","locale_data":{"app":{"":{"Project-Id-Version":"gitlab 1.0.0","Report-Msgid-Bugs-To":"","PO-Revision-Date":"2017-06-15 21:59-0500","Language-Team":"Spanish","Language":"es","MIME-Version":"1.0","Content-Type":"text/plain; charset=UTF-8","Content-Transfer-Encoding":"8bit","Plural-Forms":"nplurals=2; plural=n != 1;","Last-Translator":"Bob Van Landuyt <bob@gitlab.com>","X-Generator":"Poedit 2.0.2","POT-Creation-Date":"2017-06-15 21:59-0500","lang":"es","domain":"app","plural_forms":"nplurals=2; plural=n != 1;"},"%{commit_author_link} committed %{commit_timeago}":["%{commit_author_link} cambió %{commit_timeago}"],"About auto deploy":["Acerca del auto despliegue"],"Active":["Activo"],"Activity":["Actividad"],"Add Changelog":["Agregar Changelog"],"Add Contribution guide":["Agregar guía de contribución"],"Add License":["Agregar Licencia"],"Add an SSH key to your profile to pull or push via SSH.":["Agregar una clave SSH a tu perfil para actualizar o enviar a través de SSH."],"Add new directory":["Agregar nuevo directorio"],"Archived project! Repository is read-only":["¡Proyecto archivado! El repositorio es de solo lectura"],"Are you sure you want to delete this pipeline schedule?":["¿Estás seguro que deseas eliminar esta programación del pipeline?"],"Attach a file by drag &amp; drop or %{upload_link}":["Adjunte un archivo arrastrando &amp; soltando o %{upload_link}"],"Branch":["Rama","Ramas"],"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}":["La rama <strong>%{branch_name}</strong> fue creada. Para configurar el auto despliegue, escoge una plantilla Yaml para GitLab CI y envía tus cambios. %{link_to_autodeploy_doc}"],"Branches":["Ramas"],"Browse files":["Examinar los archivos"],"ByAuthor|by":["por"],"CI configuration":["Configuración de CI"],"Cancel":["Cancelar"],"ChangeTypeActionLabel|Pick into branch":["Escoger en la rama"],"ChangeTypeActionLabel|Revert in branch":["Revertir en la rama"],"ChangeTypeAction|Cherry-pick":["Cherry-pick"],"ChangeTypeAction|Revert":["Revertir"],"Changelog":["Changelog"],"Charts":["Gráficos"],"Cherry-pick this commit":["Escoger este cambio"],"Cherry-pick this merge request":["Escoger esta solicitud de fusión"],"CiStatusLabel|canceled":["cancelado"],"CiStatusLabel|created":["creado"],"CiStatusLabel|failed":["fallido"],"CiStatusLabel|manual action":["acción manual"],"CiStatusLabel|passed":["pasó"],"CiStatusLabel|passed with warnings":["pasó con advertencias"],"CiStatusLabel|pending":["pendiente"],"CiStatusLabel|skipped":["omitido"],"CiStatusLabel|waiting for manual action":["esperando acción manual"],"CiStatusText|blocked":["bloqueado"],"CiStatusText|canceled":["cancelado"],"CiStatusText|created":["creado"],"CiStatusText|failed":["fallado"],"CiStatusText|manual":["manual"],"CiStatusText|passed":["pasó"],"CiStatusText|pending":["pendiente"],"CiStatusText|skipped":["omitido"],"CiStatus|running":["en ejecución"],"Commit":["Cambio","Cambios"],"Commit message":["Mensaje del cambio"],"CommitBoxTitle|Commit":["Cambio"],"CommitMessage|Add %{file_name}":["Agregar %{file_name}"],"Commits":["Cambios"],"Commits|History":["Historial"],"Committed by":["Enviado por"],"Compare":["Comparar"],"Contribution guide":["Guía de contribución"],"Contributors":["Contribuidores"],"Copy URL to clipboard":["Copiar URL al portapapeles"],"Copy commit SHA to clipboard":["Copiar SHA del cambio al portapapeles"],"Create New Directory":["Crear Nuevo Directorio"],"Create directory":["Crear directorio"],"Create empty bare repository":["Crear repositorio vacío"],"Create merge request":["Crear solicitud de fusión"],"Create new...":["Crear nuevo..."],"CreateNewFork|Fork":["Bifurcar"],"CreateTag|Tag":["Etiqueta"],"Cron Timezone":["Zona horaria del Cron"],"Cron syntax":["Sintaxis de Cron"],"Custom notification events":["Eventos de notificaciones personalizadas"],"Custom notification levels are the same as participating levels. With custom notification levels you will also receive notifications for select events. To find out more, check out %{notification_link}.":["Los niveles de notificación personalizados son los mismos que los niveles participantes. Con los niveles de notificación personalizados, también recibirá notificaciones para eventos seleccionados. Para obtener más información, consulte %{notification_link}."],"Cycle Analytics":["Cycle Analytics"],"Cycle Analytics gives an overview of how much time it takes to go from idea to production in your project.":["Cycle Analytics ofrece una visión general de cuánto tiempo tarda en pasar de idea a producción en su proyecto."],"CycleAnalyticsStage|Code":["Código"],"CycleAnalyticsStage|Issue":["Incidencia"],"CycleAnalyticsStage|Plan":["Planificación"],"CycleAnalyticsStage|Production":["Producción"],"CycleAnalyticsStage|Review":["Revisión"],"CycleAnalyticsStage|Staging":["Puesta en escena"],"CycleAnalyticsStage|Test":["Pruebas"],"Define a custom pattern with cron syntax":["Definir un patrón personalizado con la sintaxis de cron"],"Delete":["Eliminar"],"Deploy":["Despliegue","Despliegues"],"Description":["Descripción"],"Directory name":["Nombre del directorio"],"Don't show again":["No mostrar de nuevo"],"Download":["Descargar"],"Download tar":["Descargar tar"],"Download tar.bz2":["Descargar tar.bz2"],"Download tar.gz":["Descargar tar.gz"],"Download zip":["Descargar zip"],"DownloadArtifacts|Download":["Descargar"],"DownloadCommit|Email Patches":["Parches por correo electrónico"],"DownloadCommit|Plain Diff":["Diferencias en texto plano"],"DownloadSource|Download":["Descargar"],"Edit":["Editar"],"Edit Pipeline Schedule %{id}":["Editar Programación del Pipeline %{id}"],"Every day (at 4:00am)":["Todos los días (a las 4:00 am)"],"Every month (on the 1st at 4:00am)":["Todos los meses (el día 1 a las 4:00 am)"],"Every week (Sundays at 4:00am)":["Todas las semanas (domingos a las 4:00 am)"],"Failed to change the owner":["Error al cambiar el propietario"],"Failed to remove the pipeline schedule":["Error al eliminar la programación del pipeline"],"Files":["Archivos"],"Find by path":["Buscar por ruta"],"Find file":["Buscar archivo"],"FirstPushedBy|First":["Primer"],"FirstPushedBy|pushed by":["enviado por"],"Fork":["Bifurcación","Bifurcaciones"],"ForkedFromProjectPath|Forked from":["Bifurcado de"],"From issue creation until deploy to production":["Desde la creación de la incidencia hasta el despliegue a producción"],"From merge request merge until deploy to production":["Desde la integración de la solicitud de fusión hasta el despliegue a producción"],"Go to your fork":["Ir a tu bifurcación"],"GoToYourFork|Fork":["Bifurcación"],"Home":["Inicio"],"Housekeeping successfully started":["Servicio de limpieza iniciado con éxito"],"Import repository":["Importar repositorio"],"Interval Pattern":["Patrón de intervalo"],"Introducing Cycle Analytics":["Introducción a Cycle Analytics"],"LFSStatus|Disabled":["Deshabilitado"],"LFSStatus|Enabled":["Habilitado"],"Last %d day":["Último %d día","Últimos %d días"],"Last Pipeline":["Último Pipeline"],"Last Update":["Última actualización"],"Last commit":["Último cambio"],"Learn more in the":["Más información en la"],"Learn more in the|pipeline schedules documentation":["documentación sobre la programación de pipelines"],"Leave group":["Abandonar grupo"],"Leave project":["Abandonar proyecto"],"Limited to showing %d event at most":["Limitado a mostrar máximo %d evento","Limitado a mostrar máximo %d eventos"],"Median":["Mediana"],"MissingSSHKeyWarningLink|add an SSH key":["agregar una clave SSH"],"New Issue":["Nueva incidencia","Nuevas incidencias"],"New Pipeline Schedule":["Nueva Programación del Pipeline"],"New branch":["Nueva rama"],"New directory":["Nuevo directorio"],"New file":["Nuevo archivo"],"New issue":["Nueva incidencia"],"New merge request":["Nueva solicitud de fusión"],"New schedule":["Nueva programación"],"New snippet":["Nuevo fragmento de código"],"New tag":["Nueva etiqueta"],"No repository":["No hay repositorio"],"No schedules":["No hay programaciones"],"Not available":["No disponible"],"Not enough data":["No hay suficientes datos"],"Notification events":["Eventos de notificación"],"NotificationEvent|Close issue":["Cerrar incidencia"],"NotificationEvent|Close merge request":["Cerrar solicitud de fusión"],"NotificationEvent|Failed pipeline":["Pipeline fallido"],"NotificationEvent|Merge merge request":["Integrar solicitud de fusión"],"NotificationEvent|New issue":["Nueva incidencia"],"NotificationEvent|New merge request":["Nueva solicitud de fusión"],"NotificationEvent|New note":["Nueva nota"],"NotificationEvent|Reassign issue":["Reasignar incidencia"],"NotificationEvent|Reassign merge request":["Reasignar solicitud de fusión"],"NotificationEvent|Reopen issue":["Reabrir incidencia"],"NotificationEvent|Successful pipeline":["Pipeline exitoso"],"NotificationLevel|Custom":["Personalizado"],"NotificationLevel|Disabled":["Deshabilitado"],"NotificationLevel|Global":["Global"],"NotificationLevel|On mention":["Cuando me mencionan"],"NotificationLevel|Participate":["Participación"],"NotificationLevel|Watch":["Vigilancia"],"OfSearchInADropdown|Filter":["Filtrar"],"OpenedNDaysAgo|Opened":["Abierto"],"Options":["Opciones"],"Owner":["Propietario"],"Pipeline":["Pipeline"],"Pipeline Health":["Estado del Pipeline"],"Pipeline Schedule":["Programación del Pipeline"],"Pipeline Schedules":["Programaciones de los Pipelines"],"PipelineSchedules|Activated":["Activado"],"PipelineSchedules|Active":["Activos"],"PipelineSchedules|All":["Todos"],"PipelineSchedules|Inactive":["Inactivos"],"PipelineSchedules|Next Run":["Próxima Ejecución"],"PipelineSchedules|None":["Ninguno"],"PipelineSchedules|Provide a short description for this pipeline":["Proporcione una breve descripción para este pipeline"],"PipelineSchedules|Take ownership":["Tomar posesión"],"PipelineSchedules|Target":["Destino"],"PipelineSheduleIntervalPattern|Custom":["Personalizado"],"Pipeline|with stage":["con etapa"],"Pipeline|with stages":["con etapas"],"Project '%{project_name}' queued for deletion.":["Proyecto ‘%{project_name}’ en cola para eliminación."],"Project '%{project_name}' was successfully created.":["Proyecto ‘%{project_name}’ fue creado satisfactoriamente."],"Project '%{project_name}' was successfully updated.":["Proyecto ‘%{project_name}’ fue actualizado satisfactoriamente."],"Project '%{project_name}' will be deleted.":["Proyecto ‘%{project_name}’ será eliminado."],"Project access must be granted explicitly to each user.":["El acceso al proyecto debe concederse explícitamente a cada usuario."],"Project export could not be deleted.":["No se pudo eliminar la exportación del proyecto."],"Project export has been deleted.":["La exportación del proyecto ha sido eliminada."],"Project export link has expired. Please generate a new export from your project settings.":["El enlace de exportación del proyecto ha caducado. Por favor, genera una nueva exportación desde la configuración del proyecto."],"Project export started. A download link will be sent by email.":["Se inició la exportación del proyecto. Se enviará un enlace de descarga por correo electrónico."],"Project home":["Inicio del proyecto"],"ProjectFeature|Disabled":["Deshabilitada"],"ProjectFeature|Everyone with access":["Todos con acceso"],"ProjectFeature|Only team members":["Solo miembros del equipo"],"ProjectFileTree|Name":["Nombre"],"ProjectLastActivity|Never":["Nunca"],"ProjectLifecycle|Stage":["Etapa"],"ProjectNetworkGraph|Graph":["Historial gráfico"],"Read more":["Leer más"],"Readme":["Léeme"],"RefSwitcher|Branches":["Ramas"],"RefSwitcher|Tags":["Etiquetas"],"Related Commits":["Cambios Relacionados"],"Related Deployed Jobs":["Trabajos Desplegados Relacionados"],"Related Issues":["Incidencias Relacionadas"],"Related Jobs":["Trabajos Relacionados"],"Related Merge Requests":["Solicitudes de fusión Relacionadas"],"Related Merged Requests":["Solicitudes de fusión Relacionadas"],"Remind later":["Recordar después"],"Remove project":["Eliminar proyecto"],"Request Access":["Solicitar acceso"],"Revert this commit":["Revertir este cambio"],"Revert this merge request":["Revertir esta solicitud de fusión"],"Save pipeline schedule":["Guardar programación del pipeline"],"Schedule a new pipeline":["Programar un nuevo pipeline"],"Scheduling Pipelines":["Programación de Pipelines"],"Search branches and tags":["Buscar ramas y etiquetas"],"Select Archive Format":["Seleccionar formato de archivo"],"Select a timezone":["Selecciona una zona horaria"],"Select target branch":["Selecciona una rama de destino"],"Set a password on your account to pull or push via %{protocol}":["Establezca una contraseña en su cuenta para actualizar o enviar a través de %{protocol}"],"Set up CI":["Configurar CI"],"Set up Koding":["Configurar Koding"],"Set up auto deploy":["Configurar auto despliegue"],"SetPasswordToCloneLink|set a password":["establecer una contraseña"],"Showing %d event":["Mostrando %d evento","Mostrando %d eventos"],"Source code":["Código fuente"],"StarProject|Star":["Destacar"],"Start a %{new_merge_request} with these changes":["Iniciar una %{new_merge_request} con estos cambios"],"Switch branch/tag":["Cambiar rama/etiqueta"],"Tag":["Etiqueta","Etiquetas"],"Tags":["Etiquetas"],"Target Branch":["Rama de destino"],"The coding stage shows the time from the first commit to creating the merge request. The data will automatically be added here once you create your first merge request.":["La etapa de desarrollo muestra el tiempo desde el primer cambio hasta la creación de la solicitud de fusión. Los datos serán automáticamente incorporados aquí una vez creada tu primera solicitud de fusión."],"The collection of events added to the data gathered for that stage.":["La colección de eventos agregados a los datos recopilados para esa etapa."],"The fork relationship has been removed.":["La relación con la bifurcación se ha eliminado."],"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.":["La etapa de incidencia muestra el tiempo que toma desde la creación de un tema hasta asignar el tema a un hito, o añadir el tema a una lista en el panel de temas. Empieza a crear temas para ver los datos de esta etapa."],"The phase of the development lifecycle.":["La etapa del ciclo de vida de desarrollo."],"The pipelines schedule runs pipelines in the future, repeatedly, for specific branches or tags. Those scheduled pipelines will inherit limited project access based on their associated user.":["La programación de pipelines ejecuta pipelines en el futuro, repetidamente, para ramas o etiquetas específicas. Los pipelines programados heredarán acceso limitado al proyecto basado en su usuario asociado."],"The planning stage shows the time from the previous step to pushing your first commit. This time will be added automatically once you push your first commit.":["La etapa de planificación muestra el tiempo desde el paso anterior hasta el envío de tu primera confirmación. Este tiempo se añadirá automáticamente una vez que usted envíe el primer cambio."],"The production stage shows the total time it takes between creating an issue and deploying the code to production. The data will be automatically added once you have completed the full idea to production cycle.":["La etapa de producción muestra el tiempo total que tarda entre la creación de una incidencia y el despliegue del código a producción. Los datos se añadirán automáticamente una vez haya finalizado por completo el ciclo de idea a producción."],"The project can be accessed by any logged in user.":["El proyecto puede ser accedido por cualquier usuario conectado."],"The project can be accessed without any authentication.":["El proyecto puede accederse sin ninguna autenticación."],"The repository for this project does not exist.":["El repositorio para este proyecto no existe."],"The review stage shows the time from creating the merge request to merging it. The data will automatically be added after you merge your first merge request.":["La etapa de revisión muestra el tiempo desde la creación de la solicitud de fusión hasta que los cambios se fusionaron. Los datos se añadirán automáticamente después de fusionar su primera solicitud de fusión."],"The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time.":["La etapa de puesta en escena muestra el tiempo entre la fusión y el despliegue de código en el entorno de producción. Los datos se añadirán automáticamente una vez que se despliega a producción por primera vez."],"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.":["La etapa de pruebas muestra el tiempo que GitLab CI toma para ejecutar cada pipeline para la solicitud de fusión relacionada. Los datos se añadirán automáticamente luego de que el primer pipeline termine de ejecutarse."],"The time taken by each data entry gathered by that stage.":["El tiempo utilizado por cada entrada de datos obtenido por esa etapa."],"The value lying at the midpoint of a series of observed values. E.g., between 3, 5, 9, the median is 5. Between 3, 5, 7, 8, the median is (5+7)/2 = 6.":["El valor en el punto medio de una serie de valores observados. Por ejemplo, entre 3, 5, 9, la mediana es 5. Entre 3, 5, 7, 8, la mediana es (5 + 7) / 2 = 6."],"This means you can not push code until you create an empty repository or import existing one.":["Esto significa que no puede enviar código hasta que cree un repositorio vacío o importe uno existente."],"Time before an issue gets scheduled":["Tiempo antes de que una incidencia sea programada"],"Time before an issue starts implementation":["Tiempo antes de que empieze la implementación de una incidencia"],"Time between merge request creation and merge/close":["Tiempo entre la creación de la solicitud de fusión y la integración o cierre de ésta"],"Time until first merge request":["Tiempo hasta la primera solicitud de fusión"],"Timeago|%s days ago":["hace %s días"],"Timeago|%s days remaining":["%s días restantes"],"Timeago|%s hours remaining":["%s horas restantes"],"Timeago|%s minutes ago":["hace %s minutos"],"Timeago|%s minutes remaining":["%s minutos restantes"],"Timeago|%s months ago":["hace %s meses"],"Timeago|%s months remaining":["%s meses restantes"],"Timeago|%s seconds remaining":["%s segundos restantes"],"Timeago|%s weeks ago":["hace %s semanas"],"Timeago|%s weeks remaining":["%s semanas restantes"],"Timeago|%s years ago":["hace %s años"],"Timeago|%s years remaining":["%s años restantes"],"Timeago|1 day remaining":["1 día restante"],"Timeago|1 hour remaining":["1 hora restante"],"Timeago|1 minute remaining":["1 minuto restante"],"Timeago|1 month remaining":["1 mes restante"],"Timeago|1 week remaining":["1 semana restante"],"Timeago|1 year remaining":["1 año restante"],"Timeago|Past due":["Atrasado"],"Timeago|a day ago":["hace un día"],"Timeago|a month ago":["hace un mes"],"Timeago|a week ago":["hace una semana"],"Timeago|a while":["hace un momento"],"Timeago|a year ago":["hace un año"],"Timeago|about %s hours ago":["hace alrededor de %s horas"],"Timeago|about a minute ago":["hace alrededor de 1 minuto"],"Timeago|about an hour ago":["hace alrededor de 1 hora"],"Timeago|in %s days":["en %s días"],"Timeago|in %s hours":["en %s horas"],"Timeago|in %s minutes":["en %s minutos"],"Timeago|in %s months":["en %s meses"],"Timeago|in %s seconds":["en %s segundos"],"Timeago|in %s weeks":["en %s semanas"],"Timeago|in %s years":["en %s años"],"Timeago|in 1 day":["en 1 día"],"Timeago|in 1 hour":["en 1 hora"],"Timeago|in 1 minute":["en 1 minuto"],"Timeago|in 1 month":["en 1 mes"],"Timeago|in 1 week":["en 1 semana"],"Timeago|in 1 year":["en 1 año"],"Timeago|less than a minute ago":["hace menos de 1 minuto"],"Time|hr":["hr","hrs"],"Time|min":["min","mins"],"Time|s":["s"],"Total Time":["Tiempo Total"],"Total test time for all commits/merges":["Tiempo total de pruebas para todos los cambios o integraciones"],"Unstar":["No Destacar"],"Upload New File":["Subir nuevo archivo"],"Upload file":["Subir archivo"],"Use your global notification setting":["Utiliza tu configuración de notificación global"],"VisibilityLevel|Internal":["Interno"],"VisibilityLevel|Private":["Privado"],"VisibilityLevel|Public":["Público"],"Want to see the data? Please ask an administrator for access.":["¿Quieres ver los datos? Por favor pide acceso al administrador."],"We don't have enough data to show this stage.":["No hay suficientes datos para mostrar en esta etapa."],"Withdraw Access Request":["Retirar Solicitud de Acceso"],"You are going to remove %{project_name_with_namespace}.\\nRemoved project CANNOT be restored!\\nAre you ABSOLUTELY sure?":["Va a eliminar %{project_name_with_namespace}.\\n¡El proyecto eliminado NO puede ser restaurado!\\n¿Estás TOTALMENTE seguro?"],"You are going to remove the fork relationship to source project %{forked_from_project}. Are you ABSOLUTELY sure?":["Vas a eliminar el enlace de la bifurcación con el proyecto original %{forked_from_project}. ¿Estás TOTALMENTE seguro?"],"You are going to transfer %{project_name_with_namespace} to another owner. Are you ABSOLUTELY sure?":["Vas a transferir %{project_name_with_namespace} a otro propietario. ¿Estás TOTALMENTE seguro?"],"You can only add files when you are on a branch":["Solo puedes agregar archivos cuando estás en una rama"],"You must sign in to star a project":["Debes iniciar sesión para destacar un proyecto"],"You need permission.":["Necesitas permisos."],"You will not get any notifications via email":["No recibirás ninguna notificación por correo electrónico"],"You will only receive notifications for the events you choose":["Solo recibirás notificaciones de los eventos que elijas"],"You will only receive notifications for threads you have participated in":["Solo recibirás notificaciones de los temas en los que has participado"],"You will receive notifications for any activity":["Recibirás notificaciones por cualquier actividad"],"You will receive notifications only for comments in which you were @mentioned":["Recibirás notificaciones solo para los comentarios en los que se te mencionó"],"You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account":["No podrás actualizar o enviar código al proyecto a través de %{protocol} hasta que %{set_password_link} en tu cuenta"],"You won't be able to pull or push project code via SSH until you %{add_ssh_key_link} to your profile":["No podrás actualizar o enviar código al proyecto a través de SSH hasta que %{add_ssh_key_link} en su perfil"],"Your name":["Tu nombre"],"day":["día","días"],"new merge request":["nueva solicitud de fusión"],"notification emails":["correos electrónicos de notificación"],"parent":["padre","padres"]}}}; \ No newline at end of file
diff --git a/app/assets/javascripts/locale/zh_CN/app.js b/app/assets/javascripts/locale/zh_CN/app.js
index d1335cfbc0f..9c28e4e4627 100644
--- a/app/assets/javascripts/locale/zh_CN/app.js
+++ b/app/assets/javascripts/locale/zh_CN/app.js
@@ -1 +1 @@
-var locales = locales || {}; locales['zh_CN'] = {"domain":"app","locale_data":{"app":{"":{"Project-Id-Version":"gitlab 1.0.0","Report-Msgid-Bugs-To":"","PO-Revision-Date":"2017-05-04 19:24-0500","Last-Translator":"HuangTao <htve@outlook.com>, 2017","Language-Team":"Chinese (China) (https://www.transifex.com/gitlab-zh/teams/75177/zh_CN/)","MIME-Version":"1.0","Content-Type":"text/plain; charset=UTF-8","Content-Transfer-Encoding":"8bit","Language":"zh_CN","Plural-Forms":"nplurals=1; plural=0;","lang":"zh_CN","domain":"app","plural_forms":"nplurals=1; plural=0;"},"Are you sure you want to delete this pipeline schedule?":[""],"ByAuthor|by":["作者:"],"Cancel":[""],"Commit":["æ交"],"Cron Timezone":[""],"Cycle Analytics gives an overview of how much time it takes to go from idea to production in your project.":["周期分æžæ¦‚述了项目从想法到产å“实现的å„阶段所需的时间。"],"CycleAnalyticsStage|Code":["ç¼–ç "],"CycleAnalyticsStage|Issue":["议题"],"CycleAnalyticsStage|Plan":["计划"],"CycleAnalyticsStage|Production":["生产"],"CycleAnalyticsStage|Review":["评审"],"CycleAnalyticsStage|Staging":["预å‘布"],"CycleAnalyticsStage|Test":["测试"],"Delete":[""],"Deploy":["部署"],"Description":[""],"Edit":[""],"Edit Pipeline Schedule %{id}":[""],"Failed to change the owner":[""],"Failed to remove the pipeline schedule":[""],"Filter":[""],"FirstPushedBy|First":["首次推é€"],"FirstPushedBy|pushed by":["推é€è€…:"],"From issue creation until deploy to production":["从创建议题到部署至生产环境"],"From merge request merge until deploy to production":["从åˆå¹¶è¯·æ±‚被åˆå¹¶åŽåˆ°éƒ¨ç½²è‡³ç”Ÿäº§çŽ¯å¢ƒ"],"Interval Pattern":[""],"Introducing Cycle Analytics":["周期分æžç®€ä»‹"],"Last %d day":["æœ€åŽ %d 天"],"Last Pipeline":[""],"Limited to showing %d event at most":["最多显示 %d 个事件"],"Median":["中ä½æ•°"],"New Issue":["新议题"],"New Pipeline Schedule":[""],"No schedules":[""],"Not available":["æ•°æ®ä¸è¶³"],"Not enough data":["æ•°æ®ä¸è¶³"],"OpenedNDaysAgo|Opened":["开始于"],"Owner":[""],"Pipeline Health":["æµæ°´çº¿å¥åº·æŒ‡æ ‡"],"Pipeline Schedule":[""],"Pipeline Schedules":[""],"PipelineSchedules|Activated":[""],"PipelineSchedules|Active":[""],"PipelineSchedules|All":[""],"PipelineSchedules|Inactive":[""],"PipelineSchedules|Next Run":[""],"PipelineSchedules|None":[""],"PipelineSchedules|Provide a short description for this pipeline":[""],"PipelineSchedules|Take ownership":[""],"PipelineSchedules|Target":[""],"ProjectLifecycle|Stage":["项目生命周期"],"Read more":["了解更多"],"Related Commits":["相关的æ交"],"Related Deployed Jobs":["相关的部署作业"],"Related Issues":["相关的议题"],"Related Jobs":["相关的作业"],"Related Merge Requests":["相关的åˆå¹¶è¯·æ±‚"],"Related Merged Requests":["相关已åˆå¹¶çš„åˆå¹¶è¯·æ±‚"],"Save pipeline schedule":[""],"Schedule a new pipeline":[""],"Select a timezone":[""],"Select target branch":[""],"Showing %d event":["显示 %d 个事件"],"Target Branch":[""],"The coding stage shows the time from the first commit to creating the merge request. The data will automatically be added here once you create your first merge request.":["ç¼–ç é˜¶æ®µæ¦‚述了从第一次æ交到创建åˆå¹¶è¯·æ±‚的时间。创建第一个åˆå¹¶è¯·æ±‚åŽï¼Œæ•°æ®å°†è‡ªåŠ¨æ·»åŠ åˆ°æ­¤å¤„。"],"The collection of events added to the data gathered for that stage.":["与该阶段相关的事件。"],"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.":["议题阶段概述了从创建议题到将议题设置里程碑或将议题添加到议题看æ¿çš„时间。开始创建议题以查看此阶段的数æ®ã€‚"],"The phase of the development lifecycle.":["项目生命周期中的å„个阶段。"],"The planning stage shows the time from the previous step to pushing your first commit. This time will be added automatically once you push your first commit.":["计划阶段概述了从议题添加到日程åŽåˆ°æŽ¨é€é¦–次æ交的时间。当首次推é€æ交åŽï¼Œæ•°æ®å°†è‡ªåŠ¨æ·»åŠ åˆ°æ­¤å¤„。"],"The production stage shows the total time it takes between creating an issue and deploying the code to production. The data will be automatically added once you have completed the full idea to production cycle.":["生产阶段概述了从创建一个议题到将代ç éƒ¨ç½²åˆ°ç”Ÿäº§çŽ¯å¢ƒçš„总时间。当完æˆæƒ³æ³•åˆ°éƒ¨ç½²ç”Ÿäº§çš„循环,数æ®å°†è‡ªåŠ¨æ·»åŠ åˆ°æ­¤å¤„。"],"The review stage shows the time from creating the merge request to merging it. The data will automatically be added after you merge your first merge request.":["评审阶段概述了从创建åˆå¹¶è¯·æ±‚到被åˆå¹¶çš„时间。当创建第一个åˆå¹¶è¯·æ±‚åŽï¼Œæ•°æ®å°†è‡ªåŠ¨æ·»åŠ åˆ°æ­¤å¤„。"],"The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time.":["预å‘布阶段概述了从åˆå¹¶è¯·æ±‚被åˆå¹¶åˆ°éƒ¨ç½²è‡³ç”Ÿäº§çŽ¯å¢ƒçš„总时间。首次部署到生产环境åŽï¼Œæ•°æ®å°†è‡ªåŠ¨æ·»åŠ åˆ°æ­¤å¤„。"],"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.":["测试阶段概述了GitLab CI为相关åˆå¹¶è¯·æ±‚è¿è¡Œæ¯ä¸ªæµæ°´çº¿æ‰€éœ€çš„时间。当第一个æµæ°´çº¿è¿è¡Œå®ŒæˆåŽï¼Œæ•°æ®å°†è‡ªåŠ¨æ·»åŠ åˆ°æ­¤å¤„。"],"The time taken by each data entry gathered by that stage.":["该阶段æ¯æ¡æ•°æ®æ‰€èŠ±çš„时间"],"The value lying at the midpoint of a series of observed values. E.g., between 3, 5, 9, the median is 5. Between 3, 5, 7, 8, the median is (5+7)/2 = 6.":["中ä½æ•°æ˜¯ä¸€ä¸ªæ•°åˆ—中最中间的值。例如在 3ã€5ã€9 之间,中ä½æ•°æ˜¯ 5。在 3ã€5ã€7ã€8 之间,中ä½æ•°æ˜¯ (5 + 7)/ 2 = 6。"],"Time before an issue gets scheduled":["议题被列入日程表的时间"],"Time before an issue starts implementation":["开始进行编ç å‰çš„时间"],"Time between merge request creation and merge/close":["从创建åˆå¹¶è¯·æ±‚到被åˆå¹¶æˆ–关闭的时间"],"Time until first merge request":["创建第一个åˆå¹¶è¯·æ±‚之å‰çš„时间"],"Time|hr":["å°æ—¶"],"Time|min":["分钟"],"Time|s":["秒"],"Total Time":["总时间"],"Total test time for all commits/merges":["所有æ交和åˆå¹¶çš„总测试时间"],"Want to see the data? Please ask an administrator for access.":["æƒé™ä¸è¶³ã€‚如需查看相关数æ®ï¼Œè¯·å‘管ç†å‘˜ç”³è¯·æƒé™ã€‚"],"We don't have enough data to show this stage.":["该阶段的数æ®ä¸è¶³ï¼Œæ— æ³•æ˜¾ç¤ºã€‚"],"You need permission.":["您需è¦ç›¸å…³çš„æƒé™ã€‚"],"day":["天"]}}}; \ No newline at end of file
+var locales = locales || {}; locales['zh_CN'] = {"domain":"app","locale_data":{"app":{"":{"Project-Id-Version":"gitlab 1.0.0","Report-Msgid-Bugs-To":"","POT-Creation-Date":"2017-06-15 21:59-0500","MIME-Version":"1.0","Content-Type":"text/plain; charset=UTF-8","Content-Transfer-Encoding":"8bit","PO-Revision-Date":"2017-06-19 09:57-0400","Last-Translator":"Huang Tao <htve@outlook.com>","Language-Team":"Chinese (China) (https://translate.zanata.org/project/view/GitLab)","Language":"zh-CN","X-Generator":"Zanata 3.9.6","Plural-Forms":"nplurals=1; plural=0","lang":"zh_CN","domain":"app","plural_forms":"nplurals=1; plural=0"},"%{commit_author_link} committed %{commit_timeago}":["ç”± %{commit_author_link} æ交于 %{commit_timeago}"],"About auto deploy":["关于自动部署"],"Active":["å¯ç”¨"],"Activity":["活动"],"Add Changelog":["添加更新日志"],"Add Contribution guide":["添加贡献指å—"],"Add License":["添加许å¯è¯"],"Add an SSH key to your profile to pull or push via SSH.":["新建一个用于推é€æˆ–拉å–çš„ SSH 秘钥到账å·ä¸­ã€‚"],"Add new directory":["添加目录"],"Archived project! Repository is read-only":["项目已归档ï¼å­˜å‚¨åº“为åªè¯»çŠ¶æ€"],"Are you sure you want to delete this pipeline schedule?":["确定è¦åˆ é™¤æ­¤æµæ°´çº¿è®¡åˆ’å—?"],"Attach a file by drag &amp; drop or %{upload_link}":["拖放文件到此处或者 %{upload_link}"],"Branch":["分支"],"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}":["已创建分支 <strong>%{branch_name}</strong> 。如需设置自动部署, 请选择åˆé€‚çš„ GitLab CI Yaml 模æ¿å¹¶æ交更改。%{link_to_autodeploy_doc}"],"Branches":["分支"],"Browse files":["æµè§ˆæ–‡ä»¶"],"ByAuthor|by":["作者:"],"CI configuration":["CI é…ç½®"],"Cancel":["å–消"],"ChangeTypeActionLabel|Pick into branch":["选择分支"],"ChangeTypeActionLabel|Revert in branch":["还原分支"],"ChangeTypeAction|Cherry-pick":["优选"],"ChangeTypeAction|Revert":["还原"],"Changelog":["更新日志"],"Charts":["统计图"],"Cherry-pick this commit":["优选此æ交"],"Cherry-pick this merge request":["优选此åˆå¹¶è¯·æ±‚"],"CiStatusLabel|canceled":["å·²å–消"],"CiStatusLabel|created":["已创建"],"CiStatusLabel|failed":["已失败"],"CiStatusLabel|manual action":["手动æ“作"],"CiStatusLabel|passed":["已通过"],"CiStatusLabel|passed with warnings":["已通过但有警告"],"CiStatusLabel|pending":["等待中"],"CiStatusLabel|skipped":["已跳过"],"CiStatusLabel|waiting for manual action":["等待手动æ“作"],"CiStatusText|blocked":["已阻塞"],"CiStatusText|canceled":["å·²å–消"],"CiStatusText|created":["已创建"],"CiStatusText|failed":["已失败"],"CiStatusText|manual":["手动æ“作"],"CiStatusText|passed":["已通过"],"CiStatusText|pending":["等待中"],"CiStatusText|skipped":["已跳过"],"CiStatus|running":["è¿è¡Œä¸­"],"Commit":["æ交"],"Commit message":["æ交信æ¯"],"CommitBoxTitle|Commit":["æ交"],"CommitMessage|Add %{file_name}":["添加 %{file_name}"],"Commits":["æ交"],"Commits|History":["历å²"],"Committed by":["æ交者:"],"Compare":["比较"],"Contribution guide":["贡献指å—"],"Contributors":["贡献者"],"Copy URL to clipboard":["å¤åˆ¶ URL 到剪贴æ¿"],"Copy commit SHA to clipboard":["å¤åˆ¶æ交 SHA 的值到剪贴æ¿"],"Create New Directory":["创建新目录"],"Create directory":["创建目录"],"Create empty bare repository":["创建空的存储库"],"Create merge request":["创建åˆå¹¶è¯·æ±‚"],"Create new...":["创建..."],"CreateNewFork|Fork":["派生"],"CreateTag|Tag":["标签"],"Cron Timezone":["Cron 时区"],"Cron syntax":["Cron 语法"],"Custom notification events":["自定义通知事件"],"Custom notification levels are the same as participating levels. With custom notification levels you will also receive notifications for select events. To find out more, check out %{notification_link}.":["自定义通知级别继承自å‚与级别。使用自定义通知级别,您会收到å‚与级别åŠé€‰å®šäº‹ä»¶çš„通知。想了解更多信æ¯ï¼Œè¯·æŸ¥çœ‹ %{notification_link}."],"Cycle Analytics":["周期分æž"],"Cycle Analytics gives an overview of how much time it takes to go from idea to production in your project.":["周期分æžæ¦‚述了项目从想法到产å“实现的å„阶段所需的时间。"],"CycleAnalyticsStage|Code":["ç¼–ç "],"CycleAnalyticsStage|Issue":["议题"],"CycleAnalyticsStage|Plan":["计划"],"CycleAnalyticsStage|Production":["生产"],"CycleAnalyticsStage|Review":["评审"],"CycleAnalyticsStage|Staging":["预å‘布"],"CycleAnalyticsStage|Test":["测试"],"Define a custom pattern with cron syntax":["使用 Cron 语法定义自定义模å¼"],"Delete":["删除"],"Deploy":["部署"],"Description":["æè¿°"],"Directory name":["目录å称"],"Don't show again":["ä¸å†æ˜¾ç¤º"],"Download":["下载"],"Download tar":["下载 tar"],"Download tar.bz2":["下载 tar.bz2"],"Download tar.gz":["下载 tar.gz"],"Download zip":["下载 zip"],"DownloadArtifacts|Download":["下载"],"DownloadCommit|Email Patches":["电å­é‚®ä»¶è¡¥ä¸"],"DownloadCommit|Plain Diff":["差异文件"],"DownloadSource|Download":["下载"],"Edit":["编辑"],"Edit Pipeline Schedule %{id}":["编辑 %{id} æµæ°´çº¿è®¡åˆ’"],"Every day (at 4:00am)":["æ¯æ—¥æ‰§è¡Œï¼ˆå‡Œæ™¨ 4 点)"],"Every month (on the 1st at 4:00am)":["æ¯æœˆæ‰§è¡Œï¼ˆæ¯æœˆ 1 日凌晨 4 点)"],"Every week (Sundays at 4:00am)":["æ¯å‘¨æ‰§è¡Œï¼ˆå‘¨æ—¥å‡Œæ™¨ 4 点)"],"Failed to change the owner":["无法å˜æ›´æ‰€æœ‰è€…"],"Failed to remove the pipeline schedule":["无法删除æµæ°´çº¿è®¡åˆ’"],"Files":["文件"],"Find by path":["按路径查找"],"Find file":["查找文件"],"FirstPushedBy|First":["首次推é€"],"FirstPushedBy|pushed by":["推é€è€…:"],"Fork":["派生"],"ForkedFromProjectPath|Forked from":["派生自"],"From issue creation until deploy to production":["从创建议题到部署至生产环境"],"From merge request merge until deploy to production":["从åˆå¹¶è¯·æ±‚被åˆå¹¶åŽåˆ°éƒ¨ç½²è‡³ç”Ÿäº§çŽ¯å¢ƒ"],"Go to your fork":["跳转到派生项目"],"GoToYourFork|Fork":["跳转到派生项目"],"Home":["首页"],"Housekeeping successfully started":["已开始维护"],"Import repository":["导入存储库"],"Interval Pattern":["循环周期"],"Introducing Cycle Analytics":["周期分æžç®€ä»‹"],"LFSStatus|Disabled":["åœç”¨"],"LFSStatus|Enabled":["å¯ç”¨"],"Last %d day":["最近 %d 天"],"Last Pipeline":["最新æµæ°´çº¿"],"Last Update":["最åŽæ›´æ–°"],"Last commit":["最åŽæ交"],"Learn more in the":["了解更多"],"Learn more in the|pipeline schedules documentation":["æµæ°´çº¿è®¡åˆ’文档"],"Leave group":["退出群组"],"Leave project":["退出项目"],"Limited to showing %d event at most":["最多显示 %d 个事件"],"Median":["中ä½æ•°"],"MissingSSHKeyWarningLink|add an SSH key":["新建 SSH 公钥"],"New Issue":["新建议题"],"New Pipeline Schedule":["创建æµæ°´çº¿è®¡åˆ’"],"New branch":["新建分支"],"New directory":["新建目录"],"New file":["新建文件"],"New issue":["新建议题"],"New merge request":["新建åˆå¹¶è¯·æ±‚"],"New schedule":["新建计划"],"New snippet":["新建代ç ç‰‡æ®µ"],"New tag":["新建标签"],"No repository":["没有存储库"],"No schedules":["没有计划"],"Not available":["æ•°æ®ä¸è¶³"],"Not enough data":["æ•°æ®ä¸è¶³"],"Notification events":["通知事件"],"NotificationEvent|Close issue":["关闭议题"],"NotificationEvent|Close merge request":["关闭åˆå¹¶è¯·æ±‚"],"NotificationEvent|Failed pipeline":["æµæ°´çº¿å¤±è´¥"],"NotificationEvent|Merge merge request":["åˆå¹¶è¯·æ±‚被åˆå¹¶"],"NotificationEvent|New issue":["新建议题"],"NotificationEvent|New merge request":["新建åˆå¹¶è¯·æ±‚"],"NotificationEvent|New note":["新建评论"],"NotificationEvent|Reassign issue":["é‡æ–°æŒ‡æ´¾è®®é¢˜"],"NotificationEvent|Reassign merge request":["é‡æ–°æŒ‡æ´¾åˆå¹¶è¯·æ±‚"],"NotificationEvent|Reopen issue":["é‡å¯è®®é¢˜"],"NotificationEvent|Successful pipeline":["æµæ°´çº¿æˆåŠŸå®Œæˆ"],"NotificationLevel|Custom":["自定义"],"NotificationLevel|Disabled":["åœç”¨"],"NotificationLevel|Global":["全局"],"NotificationLevel|On mention":["æåŠ"],"NotificationLevel|Participate":["å‚与"],"NotificationLevel|Watch":["关注"],"OfSearchInADropdown|Filter":["筛选"],"OpenedNDaysAgo|Opened":["开始于"],"Options":["æ“作"],"Owner":["所有者"],"Pipeline":["æµæ°´çº¿"],"Pipeline Health":["æµæ°´çº¿å¥åº·æŒ‡æ ‡"],"Pipeline Schedule":["æµæ°´çº¿è®¡åˆ’"],"Pipeline Schedules":["æµæ°´çº¿è®¡åˆ’"],"PipelineSchedules|Activated":["是å¦å¯ç”¨"],"PipelineSchedules|Active":["å·²å¯ç”¨"],"PipelineSchedules|All":["所有"],"PipelineSchedules|Inactive":["未å¯ç”¨"],"PipelineSchedules|Next Run":["下次è¿è¡Œæ—¶é—´"],"PipelineSchedules|None":["æ— "],"PipelineSchedules|Provide a short description for this pipeline":["为此æµæ°´çº¿æ供简短æè¿°"],"PipelineSchedules|Take ownership":["å–得所有者"],"PipelineSchedules|Target":["目标"],"PipelineSheduleIntervalPattern|Custom":["自定义"],"Pipeline|with stage":["于阶段"],"Pipeline|with stages":["于阶段"],"Project '%{project_name}' queued for deletion.":["项目 '%{project_name}' 已进入删除队列。"],"Project '%{project_name}' was successfully created.":["项目 '%{project_name}' 已创建æˆåŠŸã€‚"],"Project '%{project_name}' was successfully updated.":["项目 '%{project_name}' 已更新完æˆã€‚"],"Project '%{project_name}' will be deleted.":["项目 '%{project_name}' 将被删除。"],"Project access must be granted explicitly to each user.":["项目访问æƒé™å¿…须明确授æƒç»™æ¯ä¸ªç”¨æˆ·ã€‚"],"Project export could not be deleted.":["无法删除项目导出。"],"Project export has been deleted.":["项目导出已被删除。"],"Project export link has expired. Please generate a new export from your project settings.":["项目导出链接已过期。请从项目设置中é‡æ–°ç”Ÿæˆé¡¹ç›®å¯¼å‡ºã€‚"],"Project export started. A download link will be sent by email.":["项目导出已开始。下载链接将通过电å­é‚®ä»¶å‘é€ã€‚"],"Project home":["项目首页"],"ProjectFeature|Disabled":["åœç”¨"],"ProjectFeature|Everyone with access":["任何对项目有访问æƒçš„人"],"ProjectFeature|Only team members":["åªé™å›¢é˜Ÿæˆå‘˜"],"ProjectFileTree|Name":["å称"],"ProjectLastActivity|Never":["从未"],"ProjectLifecycle|Stage":["阶段"],"ProjectNetworkGraph|Graph":["分支图"],"Read more":["了解更多"],"Readme":["自述文件"],"RefSwitcher|Branches":["分支"],"RefSwitcher|Tags":["标签"],"Related Commits":["相关的æ交"],"Related Deployed Jobs":["相关的部署作业"],"Related Issues":["相关的议题"],"Related Jobs":["相关的作业"],"Related Merge Requests":["相关的åˆå¹¶è¯·æ±‚"],"Related Merged Requests":["相关已åˆå¹¶çš„åˆå¹¶è¯·æ±‚"],"Remind later":["ç¨åŽæ醒"],"Remove project":["删除项目"],"Request Access":["申请æƒé™"],"Revert this commit":["还原此æ交"],"Revert this merge request":["还原此åˆå¹¶è¯·æ±‚"],"Save pipeline schedule":["ä¿å­˜æµæ°´çº¿è®¡åˆ’"],"Schedule a new pipeline":["新建æµæ°´çº¿è®¡åˆ’"],"Scheduling Pipelines":["æµæ°´çº¿è®¡åˆ’"],"Search branches and tags":["æœç´¢åˆ†æ”¯å’Œæ ‡ç­¾"],"Select Archive Format":["选择下载格å¼"],"Select a timezone":["选择时区"],"Select target branch":["选择目标分支"],"Set a password on your account to pull or push via %{protocol}":["为账å·åˆ›å»ºä¸€ä¸ªç”¨äºŽæŽ¨é€æˆ–拉å–çš„ %{protocol} 密ç ã€‚"],"Set up CI":["设置 CI"],"Set up Koding":["设置 Koding"],"Set up auto deploy":["设置自动部署"],"SetPasswordToCloneLink|set a password":["设置密ç "],"Showing %d event":["显示 %d 个事件"],"Source code":["æºä»£ç "],"StarProject|Star":["星标"],"Start a %{new_merge_request} with these changes":["由此更改 %{new_merge_request}"],"Switch branch/tag":["切æ¢åˆ†æ”¯/标签"],"Tag":["标签"],"Tags":["标签"],"Target Branch":["目标分支"],"The coding stage shows the time from the first commit to creating the merge request. The data will automatically be added here once you create your first merge request.":["ç¼–ç é˜¶æ®µæ¦‚述了从第一次æ交到创建åˆå¹¶è¯·æ±‚的时间。创建第一个åˆå¹¶è¯·æ±‚åŽï¼Œæ•°æ®å°†è‡ªåŠ¨æ·»åŠ åˆ°æ­¤å¤„。"],"The collection of events added to the data gathered for that stage.":["与该阶段相关的事件集åˆã€‚"],"The fork relationship has been removed.":["派生关系已被删除。"],"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.":["议题阶段概述了从创建议题到将议题添加到里程碑或议题看æ¿æ‰€èŠ±è´¹çš„时间。创建第一个议题åŽï¼Œæ•°æ®å°†è‡ªåŠ¨æ·»åŠ åˆ°æ­¤å¤„.。"],"The phase of the development lifecycle.":["项目生命周期中的å„个阶段。"],"The pipelines schedule runs pipelines in the future, repeatedly, for specific branches or tags. Those scheduled pipelines will inherit limited project access based on their associated user.":["æµæ°´çº¿è®¡åˆ’会周期性é‡å¤è¿è¡ŒæŒ‡å®šåˆ†æ”¯æˆ–标签的æµæ°´çº¿ã€‚这些æµæ°´çº¿å°†æ ¹æ®å…¶å…³è”用户继承有é™çš„项目访问æƒé™ã€‚"],"The planning stage shows the time from the previous step to pushing your first commit. This time will be added automatically once you push your first commit.":["计划阶段概述了从议题添加到日程到推é€é¦–次æ交的时间。当首次推é€æ交åŽï¼Œæ•°æ®å°†è‡ªåŠ¨æ·»åŠ åˆ°æ­¤å¤„。"],"The production stage shows the total time it takes between creating an issue and deploying the code to production. The data will be automatically added once you have completed the full idea to production cycle.":["生产阶段概述了从创建一个议题到将代ç éƒ¨ç½²åˆ°ç”Ÿäº§çŽ¯å¢ƒçš„总时间。当完æˆæƒ³æ³•åˆ°éƒ¨ç½²ç”Ÿäº§çš„循环,数æ®å°†è‡ªåŠ¨æ·»åŠ åˆ°æ­¤å¤„。"],"The project can be accessed by any logged in user.":["该项目å…许已登录的用户访问。"],"The project can be accessed without any authentication.":["该项目å…许任何人访问。"],"The repository for this project does not exist.":["此项目的存储库ä¸å­˜åœ¨ã€‚"],"The review stage shows the time from creating the merge request to merging it. The data will automatically be added after you merge your first merge request.":["评审阶段概述了从创建åˆå¹¶è¯·æ±‚到被åˆå¹¶çš„时间。当创建第一个åˆå¹¶è¯·æ±‚åŽï¼Œæ•°æ®å°†è‡ªåŠ¨æ·»åŠ åˆ°æ­¤å¤„。"],"The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time.":["预å‘布阶段概述了从åˆå¹¶è¯·æ±‚被åˆå¹¶åˆ°éƒ¨ç½²è‡³ç”Ÿäº§çŽ¯å¢ƒçš„总时间。首次部署到生产环境åŽï¼Œæ•°æ®å°†è‡ªåŠ¨æ·»åŠ åˆ°æ­¤å¤„。"],"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.":["测试阶段概述了 GitLab CI 为相关åˆå¹¶è¯·æ±‚è¿è¡Œæ¯ä¸ªæµæ°´çº¿æ‰€éœ€çš„时间。当第一个æµæ°´çº¿è¿è¡Œå®ŒæˆåŽï¼Œæ•°æ®å°†è‡ªåŠ¨æ·»åŠ åˆ°æ­¤å¤„。"],"The time taken by each data entry gathered by that stage.":["该阶段æ¯æ¡æ•°æ®æ‰€èŠ±çš„时间"],"The value lying at the midpoint of a series of observed values. E.g., between 3, 5, 9, the median is 5. Between 3, 5, 7, 8, the median is (5+7)/2 = 6.":["中ä½æ•°æ˜¯ä¸€ä¸ªæ•°åˆ—中最中间的值。例如在 3ã€5ã€9 之间,中ä½æ•°æ˜¯ 5。在 3ã€5ã€7ã€8 之间,中ä½æ•°æ˜¯ (5 + 7)/ 2 = 6。"],"This means you can not push code until you create an empty repository or import existing one.":["在创建一个空的存储库或导入现有存储库之å‰ï¼Œå°†æ— æ³•æŽ¨é€ä»£ç ã€‚"],"Time before an issue gets scheduled":["议题被列入日程表的时间"],"Time before an issue starts implementation":["开始进行编ç å‰çš„时间"],"Time between merge request creation and merge/close":["从创建åˆå¹¶è¯·æ±‚到被åˆå¹¶æˆ–关闭的时间"],"Time until first merge request":["创建第一个åˆå¹¶è¯·æ±‚之å‰çš„时间"],"Timeago|%s days ago":[" %s 天å‰"],"Timeago|%s days remaining":["剩余 %s 天"],"Timeago|%s hours remaining":["剩余 %s å°æ—¶"],"Timeago|%s minutes ago":[" %s 分钟å‰"],"Timeago|%s minutes remaining":["剩余 %s 分钟"],"Timeago|%s months ago":[" %s 个月å‰"],"Timeago|%s months remaining":["剩余 %s 月"],"Timeago|%s seconds remaining":["剩余 %s 秒"],"Timeago|%s weeks ago":[" %s 星期å‰"],"Timeago|%s weeks remaining":["剩余 %s 星期"],"Timeago|%s years ago":[" %s å¹´å‰"],"Timeago|%s years remaining":["剩余 %s å¹´"],"Timeago|1 day remaining":["剩余 1 天"],"Timeago|1 hour remaining":["剩余 1 å°æ—¶"],"Timeago|1 minute remaining":["剩余 1 分钟"],"Timeago|1 month remaining":["剩余 1 个月"],"Timeago|1 week remaining":["剩余 1 星期"],"Timeago|1 year remaining":["剩余 1 å¹´"],"Timeago|Past due":["逾期"],"Timeago|a day ago":[" 1 天å‰"],"Timeago|a month ago":[" 1 个月å‰"],"Timeago|a week ago":[" 1 星期å‰"],"Timeago|a while":["刚刚"],"Timeago|a year ago":[" 1 å¹´å‰"],"Timeago|about %s hours ago":["约 %s å°æ—¶å‰"],"Timeago|about a minute ago":["约 1 分钟å‰"],"Timeago|about an hour ago":["约 1 å°æ—¶å‰"],"Timeago|in %s days":[" %s 天åŽ"],"Timeago|in %s hours":[" %s å°æ—¶åŽ"],"Timeago|in %s minutes":[" %s 分钟åŽ"],"Timeago|in %s months":[" %s 个月åŽ"],"Timeago|in %s seconds":[" %s 秒åŽ"],"Timeago|in %s weeks":[" %s 星期åŽ"],"Timeago|in %s years":[" %s å¹´åŽ"],"Timeago|in 1 day":[" 1 天åŽ"],"Timeago|in 1 hour":[" 1 å°æ—¶åŽ"],"Timeago|in 1 minute":[" 1 分钟åŽ"],"Timeago|in 1 month":[" 1 月åŽ"],"Timeago|in 1 week":[" 1 星期åŽ"],"Timeago|in 1 year":[" 1 å¹´åŽ"],"Timeago|less than a minute ago":["ä¸åˆ° 1 分钟å‰"],"Time|hr":["å°æ—¶"],"Time|min":["分钟"],"Time|s":["秒"],"Total Time":["总时间"],"Total test time for all commits/merges":["所有æ交和åˆå¹¶çš„总测试时间"],"Unstar":["å–消星标"],"Upload New File":["上传新文件"],"Upload file":["上传文件"],"Use your global notification setting":["使用全局通知设置"],"VisibilityLevel|Internal":["内部"],"VisibilityLevel|Private":["ç§æœ‰"],"VisibilityLevel|Public":["公开"],"Want to see the data? Please ask an administrator for access.":["æƒé™ä¸è¶³ã€‚如需查看相关数æ®ï¼Œè¯·å‘管ç†å‘˜ç”³è¯·æƒé™ã€‚"],"We don't have enough data to show this stage.":["该阶段的数æ®ä¸è¶³ï¼Œæ— æ³•æ˜¾ç¤ºã€‚"],"Withdraw Access Request":["å–消æƒé™ç”³è¯·"],"You are going to remove %{project_name_with_namespace}.\\nRemoved project CANNOT be restored!\\nAre you ABSOLUTELY sure?":["å³å°†è¦åˆ é™¤ %{project_name_with_namespace}。\\n已删除的项目无法æ¢å¤ï¼\\n确定继续å—?"],"You are going to remove the fork relationship to source project %{forked_from_project}. Are you ABSOLUTELY sure?":["å³å°†åˆ é™¤ä¸Žæºé¡¹ç›® %{forked_from_project} 的派生关系。确定继续å—?"],"You are going to transfer %{project_name_with_namespace} to another owner. Are you ABSOLUTELY sure?":["å³å°† %{project_name_with_namespace} 转移给å¦ä¸€ä¸ªæ‰€æœ‰è€…。确定继续å—?"],"You can only add files when you are on a branch":["åªèƒ½åœ¨åˆ†æ”¯ä¸Šæ·»åŠ æ–‡ä»¶"],"You have reached your project limit":["您已达到项目数é‡é™åˆ¶"],"You must sign in to star a project":["必须登录æ‰èƒ½å¯¹é¡¹ç›®åŠ æ˜Ÿæ ‡"],"You need permission.":["需è¦ç›¸å…³çš„æƒé™ã€‚"],"You will not get any notifications via email":["ä¸ä¼šæ”¶åˆ°ä»»ä½•é€šçŸ¥é‚®ä»¶"],"You will only receive notifications for the events you choose":["åªæŽ¥æ”¶é€‰æ‹©çš„事件通知"],"You will only receive notifications for threads you have participated in":["åªæŽ¥æ”¶å‚与的主题的通知"],"You will receive notifications for any activity":["接收所有活动的通知"],"You will receive notifications only for comments in which you were @mentioned":["åªæŽ¥æ”¶è¯„论中æåŠ(@)您的通知"],"You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account":["在账å·ä¸­ %{set_password_link} 之å‰å°†æ— æ³•é€šè¿‡ %{protocol} 拉å–或推é€ä»£ç ã€‚"],"You won't be able to pull or push project code via SSH until you %{add_ssh_key_link} to your profile":["在账å·ä¸­ %{add_ssh_key_link} 之å‰å°†æ— æ³•é€šè¿‡ SSH 拉å–或推é€ä»£ç ã€‚"],"Your name":["您的åå­—"],"day":["天"],"new merge request":["新建åˆå¹¶è¯·æ±‚"],"notification emails":["通知邮件"],"parent":["父级"]}}}; \ No newline at end of file
diff --git a/app/assets/javascripts/merge_request_tabs.js b/app/assets/javascripts/merge_request_tabs.js
index 894ed81b044..7bb2236017e 100644
--- a/app/assets/javascripts/merge_request_tabs.js
+++ b/app/assets/javascripts/merge_request_tabs.js
@@ -233,11 +233,18 @@ import BlobForkSuggestion from './blob/blob_fork_suggestion';
}
mountPipelinesView() {
- this.commitPipelinesTable = new gl.CommitPipelinesTable().$mount();
+ const pipelineTableViewEl = document.querySelector('#commit-pipeline-table-view');
+ const CommitPipelinesTable = gl.CommitPipelinesTable;
+ this.commitPipelinesTable = new CommitPipelinesTable({
+ propsData: {
+ endpoint: pipelineTableViewEl.dataset.endpoint,
+ helpPagePath: pipelineTableViewEl.dataset.helpPagePath,
+ },
+ }).$mount();
+
// $mount(el) replaces the el with the new rendered component. We need it in order to mount
// it everytime this tab is clicked - https://vuejs.org/v2/api/#vm-mount
- document.querySelector('#commit-pipeline-table-view')
- .appendChild(this.commitPipelinesTable.$el);
+ pipelineTableViewEl.appendChild(this.commitPipelinesTable.$el);
}
loadDiff(source) {
diff --git a/app/assets/javascripts/milestone.js b/app/assets/javascripts/milestone.js
index 07ede5ee913..3e07ec4d0aa 100644
--- a/app/assets/javascripts/milestone.js
+++ b/app/assets/javascripts/milestone.js
@@ -4,87 +4,7 @@
(function() {
this.Milestone = (function() {
- Milestone.updateIssue = function(li, issue_url, data) {
- return $.ajax({
- type: "PUT",
- url: issue_url,
- data: data,
- success: function(_data) {
- return Milestone.successCallback(_data, li);
- },
- error: function(data) {
- return new Flash("Issue update failed", 'alert');
- },
- dataType: "json"
- });
- };
-
- Milestone.sortIssues = function(url, data) {
- return $.ajax({
- type: "PUT",
- url,
- data: data,
- success: function(_data) {
- return Milestone.successCallback(_data);
- },
- error: function() {
- return new Flash("Issues update failed", 'alert');
- },
- dataType: "json"
- });
- };
-
- Milestone.sortMergeRequests = function(url, data) {
- return $.ajax({
- type: "PUT",
- url,
- data: data,
- success: function(_data) {
- return Milestone.successCallback(_data);
- },
- error: function(data) {
- return new Flash("Issue update failed", 'alert');
- },
- dataType: "json"
- });
- };
-
- Milestone.updateMergeRequest = function(li, merge_request_url, data) {
- return $.ajax({
- type: "PUT",
- url: merge_request_url,
- data: data,
- success: function(_data) {
- return Milestone.successCallback(_data, li);
- },
- error: function(data) {
- return new Flash("Issue update failed", 'alert');
- },
- dataType: "json"
- });
- };
-
- Milestone.successCallback = function(data, element) {
- const $avatarContainer = $(element).find('.assignee-icon');
- $avatarContainer.empty();
-
- if (data.assignees && data.assignees.length > 0) {
- const $avatars = data.assignees.map((assignee) => {
- const img_tag = $('<img/>');
- img_tag.attr('src', assignee.avatar_url);
- img_tag.addClass('avatar s16');
- return img_tag;
- });
-
- $avatarContainer.append($avatars);
- }
- };
-
function Milestone() {
- this.issuesSortEndpoint = $('#tab-issues').data('sort-endpoint');
- this.mergeRequestsSortEndpoint = $('#tab-merge-requests').data('sort-endpoint');
-
- this.bindIssuesSorting();
this.bindTabsSwitching();
// Load merge request tab if it is active
@@ -94,22 +14,6 @@
this.loadInitialTab();
}
- Milestone.prototype.bindIssuesSorting = function() {
- if (!this.issuesSortEndpoint) return;
-
- $('#issues-list-unassigned, #issues-list-ongoing, #issues-list-closed').each(function (i, el) {
- this.createSortable(el, {
- group: 'issue-list',
- listEls: $('.issues-sortable-list'),
- fieldName: 'issue',
- sortCallback: (data) => {
- Milestone.sortIssues(this.issuesSortEndpoint, data);
- },
- updateCallback: Milestone.updateIssue,
- });
- }.bind(this));
- };
-
Milestone.prototype.bindTabsSwitching = function() {
return $('a[data-toggle="tab"]').on('show.bs.tab', (e) => {
const $target = $(e.target);
@@ -119,69 +23,6 @@
});
};
- Milestone.prototype.bindMergeRequestSorting = function() {
- if (!this.mergeRequestsSortEndpoint) return;
-
- $("#merge_requests-list-unassigned, #merge_requests-list-ongoing, #merge_requests-list-closed").each(function (i, el) {
- this.createSortable(el, {
- group: 'merge-request-list',
- listEls: $(".merge_requests-sortable-list:not(#merge_requests-list-merged)"),
- fieldName: 'merge_request',
- sortCallback: (data) => {
- Milestone.sortMergeRequests(this.mergeRequestsSortEndpoint, data);
- },
- updateCallback: Milestone.updateMergeRequest,
- });
- }.bind(this));
- };
-
- Milestone.prototype.createSortable = function(el, opts) {
- return Sortable.create(el, {
- group: opts.group,
- filter: '.is-disabled',
- forceFallback: true,
- onStart: function(e) {
- opts.listEls.css('min-height', e.item.offsetHeight);
- },
- onEnd: function () {
- opts.listEls.css("min-height", "0px");
- },
- onUpdate: function(e) {
- var ids = this.toArray(),
- data;
-
- if (ids.length) {
- data = ids.map(function(id) {
- return 'sortable_' + opts.fieldName + '[]=' + id;
- }).join('&');
-
- opts.sortCallback(data);
- }
- },
- onAdd: function (e) {
- var data, issuableId, issuableUrl, newState;
- newState = e.to.dataset.state;
- issuableUrl = e.item.dataset.url;
- data = (function() {
- switch (newState) {
- case 'ongoing':
- return `${opts.fieldName}[assignee_ids][]=${gon.current_user_id}`;
- case 'unassigned':
- return `${opts.fieldName}[assignee_ids][]=0`;
- case 'closed':
- return opts.fieldName + '[state_event]=close';
- }
- })();
- if (e.from.dataset.state === 'closed') {
- data += '&' + opts.fieldName + '[state_event]=reopen';
- }
-
- opts.updateCallback(e.item, issuableUrl, data);
- this.options.onUpdate.call(this, e);
- }
- });
- };
-
Milestone.prototype.loadInitialTab = function() {
const $target = $(`.js-milestone-tabs a[href="${location.hash}"]`);
@@ -203,10 +44,6 @@
.done((data) => {
$(tabElId).html(data.html);
$target.addClass('is-loaded');
-
- if (tabElId === '#tab-merge-requests') {
- this.bindMergeRequestSorting();
- }
});
}
};
diff --git a/app/assets/javascripts/notes.js b/app/assets/javascripts/notes.js
index d56cf959486..624dd336786 100644
--- a/app/assets/javascripts/notes.js
+++ b/app/assets/javascripts/notes.js
@@ -32,7 +32,7 @@ const normalizeNewlines = function(str) {
(function() {
this.Notes = (function() {
const MAX_VISIBLE_COMMIT_LIST_COUNT = 3;
- const REGEX_SLASH_COMMANDS = /^\/\w+.*$/gm;
+ const REGEX_QUICK_ACTIONS = /^\/\w+.*$/gm;
Notes.interval = null;
@@ -187,7 +187,7 @@ const normalizeNewlines = function(str) {
if ($textarea.val() !== '') {
return;
}
- myLastNote = $(`li.note[data-author-id='${gon.current_user_id}'][data-editable]:last`, $textarea.closest('.note, #notes'));
+ myLastNote = $(`li.note[data-author-id='${gon.current_user_id}'][data-editable]:last`, $textarea.closest('.note, .notes_holder, #notes'));
if (myLastNote.length) {
myLastNoteEditBtn = myLastNote.find('.js-note-edit');
return myLastNoteEditBtn.trigger('click', [true, myLastNote]);
@@ -284,7 +284,7 @@ const normalizeNewlines = function(str) {
return this.initRefresh();
};
- Notes.prototype.handleSlashCommands = function(noteEntity) {
+ Notes.prototype.handleQuickActions = function(noteEntity) {
var votesBlock;
if (noteEntity.commands_changes) {
if ('merge' in noteEntity.commands_changes) {
@@ -322,7 +322,9 @@ const normalizeNewlines = function(str) {
Notes.updateNoteTargetSelector = function($note) {
const hash = gl.utils.getLocationHash();
- $note.toggleClass('target', hash && $note.filter(`#${hash}`).length > 0);
+ // Needs to be an explicit true/false for the jQuery `toggleClass(force)`
+ const addTargetClass = Boolean(hash && $note.filter(`#${hash}`).length > 0);
+ $note.toggleClass('target', addTargetClass);
};
/*
@@ -1220,27 +1222,27 @@ const normalizeNewlines = function(str) {
};
/**
- * Identify if comment has any slash commands
+ * Identify if comment has any quick actions
*/
- Notes.prototype.hasSlashCommands = function(formContent) {
- return REGEX_SLASH_COMMANDS.test(formContent);
+ Notes.prototype.hasQuickActions = function(formContent) {
+ return REGEX_QUICK_ACTIONS.test(formContent);
};
/**
- * Remove slash commands and leave comment with pure message
+ * Remove quick actions and leave comment with pure message
*/
- Notes.prototype.stripSlashCommands = function(formContent) {
- return formContent.replace(REGEX_SLASH_COMMANDS, '').trim();
+ Notes.prototype.stripQuickActions = function(formContent) {
+ return formContent.replace(REGEX_QUICK_ACTIONS, '').trim();
};
/**
- * Gets appropriate description from slash commands found in provided `formContent`
+ * Gets appropriate description from quick actions found in provided `formContent`
*/
- Notes.prototype.getSlashCommandDescription = function (formContent, availableSlashCommands = []) {
+ Notes.prototype.getQuickActionDescription = function (formContent, availableQuickActions = []) {
let tempFormContent;
- // Identify executed slash commands from `formContent`
- const executedCommands = availableSlashCommands.filter((command, index) => {
+ // Identify executed quick actions from `formContent`
+ const executedCommands = availableQuickActions.filter((command, index) => {
const commandRegex = new RegExp(`/${command.name}`);
return commandRegex.test(formContent);
});
@@ -1298,7 +1300,7 @@ const normalizeNewlines = function(str) {
};
/**
- * Create Placeholder System Note DOM element populated with slash command description
+ * Create Placeholder System Note DOM element populated with quick action description
*/
Notes.prototype.createPlaceholderSystemNote = function ({ formContent, uniqueId }) {
const $tempNote = $(
@@ -1347,7 +1349,7 @@ const normalizeNewlines = function(str) {
const { formData, formContent, formAction } = this.getFormData($form);
let noteUniqueId;
let systemNoteUniqueId;
- let hasSlashCommands = false;
+ let hasQuickActions = false;
let $notesContainer;
let tempFormContent;
@@ -1366,9 +1368,9 @@ const normalizeNewlines = function(str) {
}
tempFormContent = formContent;
- if (this.hasSlashCommands(formContent)) {
- tempFormContent = this.stripSlashCommands(formContent);
- hasSlashCommands = true;
+ if (this.hasQuickActions(formContent)) {
+ tempFormContent = this.stripQuickActions(formContent);
+ hasQuickActions = true;
}
// Show placeholder note
@@ -1385,10 +1387,10 @@ const normalizeNewlines = function(str) {
}
// Show placeholder system note
- if (hasSlashCommands) {
+ if (hasQuickActions) {
systemNoteUniqueId = _.uniqueId('tempSystemNote_');
$notesContainer.append(this.createPlaceholderSystemNote({
- formContent: this.getSlashCommandDescription(formContent, AjaxCache.get(gl.GfmAutoComplete.dataSources.commands)),
+ formContent: this.getQuickActionDescription(formContent, AjaxCache.get(gl.GfmAutoComplete.dataSources.commands)),
uniqueId: systemNoteUniqueId,
}));
}
@@ -1410,7 +1412,7 @@ const normalizeNewlines = function(str) {
$notesContainer.find(`#${noteUniqueId}`).remove();
// Reset cached commands list when command is applied
- if (hasSlashCommands) {
+ if (hasQuickActions) {
$form.find('textarea.js-note-text').trigger('clear-commands-cache.atwho');
}
@@ -1444,7 +1446,7 @@ const normalizeNewlines = function(str) {
}
if (note.commands_changes) {
- this.handleSlashCommands(note);
+ this.handleQuickActions(note);
}
$form.trigger('ajax:success', [note]);
@@ -1452,7 +1454,7 @@ const normalizeNewlines = function(str) {
// Submission failed, remove placeholder note and show Flash error message
$notesContainer.find(`#${noteUniqueId}`).remove();
- if (hasSlashCommands) {
+ if (hasQuickActions) {
$notesContainer.find(`#${systemNoteUniqueId}`).remove();
}
diff --git a/app/assets/javascripts/pipeline_schedules/components/interval_pattern_input.js b/app/assets/javascripts/pipeline_schedules/components/interval_pattern_input.js
index 4d623763ca7..901adbe9fce 100644
--- a/app/assets/javascripts/pipeline_schedules/components/interval_pattern_input.js
+++ b/app/assets/javascripts/pipeline_schedules/components/interval_pattern_input.js
@@ -1,4 +1,7 @@
import Vue from 'vue';
+import Translate from '../../vue_shared/translate';
+
+Vue.use(Translate);
const inputNameAttribute = 'schedule[cron]';
@@ -72,11 +75,11 @@ export default {
/>
<label for="custom">
- Custom
+ {{ s__('PipelineSheduleIntervalPattern|Custom') }}
</label>
<span class="cron-syntax-link-wrap">
- (<a :href="cronSyntaxUrl" target="_blank">Cron syntax</a>)
+ (<a :href="cronSyntaxUrl" target="_blank">{{ __('Cron syntax') }}</a>)
</span>
</div>
@@ -92,7 +95,7 @@ export default {
/>
<label class="label-light" for="every-day">
- Every day (at 4:00am)
+ {{ __('Every day (at 4:00am)') }}
</label>
</div>
@@ -108,7 +111,7 @@ export default {
/>
<label class="label-light" for="every-week">
- Every week (Sundays at 4:00am)
+ {{ __('Every week (Sundays at 4:00am)') }}
</label>
</div>
@@ -124,7 +127,7 @@ export default {
/>
<label class="label-light" for="every-month">
- Every month (on the 1st at 4:00am)
+ {{ __('Every month (on the 1st at 4:00am)') }}
</label>
</div>
@@ -133,7 +136,7 @@ export default {
id="schedule_cron"
class="form-control inline cron-interval-input"
type="text"
- placeholder="Define a custom pattern with cron syntax"
+ :placeholder="__('Define a custom pattern with cron syntax')"
required="true"
v-model="cronInterval"
:name="inputNameAttribute"
diff --git a/app/assets/javascripts/pipeline_schedules/components/pipeline_schedules_callout.js b/app/assets/javascripts/pipeline_schedules/components/pipeline_schedules_callout.js
index 5109b110b31..c827b7402dc 100644
--- a/app/assets/javascripts/pipeline_schedules/components/pipeline_schedules_callout.js
+++ b/app/assets/javascripts/pipeline_schedules/components/pipeline_schedules_callout.js
@@ -1,6 +1,10 @@
+import Vue from 'vue';
import Cookies from 'js-cookie';
+import Translate from '../../vue_shared/translate';
import illustrationSvg from '../icons/intro_illustration.svg';
+Vue.use(Translate);
+
const cookieKey = 'pipeline_schedules_callout_dismissed';
export default {
@@ -29,20 +33,18 @@ export default {
</button>
<div class="svg-container" v-html="illustrationSvg"></div>
<div class="user-callout-copy">
- <h4>Scheduling Pipelines</h4>
+ <h4>{{ __('Scheduling Pipelines') }}</h4>
<p>
- The pipelines schedule runs pipelines in the future, repeatedly, for specific branches or tags.
- Those scheduled pipelines will inherit limited project access based on their associated user.
+ {{ __('The pipelines schedule runs pipelines in the future, repeatedly, for specific branches or tags. Those scheduled pipelines will inherit limited project access based on their associated user.') }}
</p>
- <p> Learn more in the
+ <p> {{ __('Learn more in the') }}
<a
:href="docsUrl"
target="_blank"
- rel="nofollow">pipeline schedules documentation</a>. <!-- oneline to prevent extra space before period -->
+ rel="nofollow">{{ s__('Learn more in the|pipeline schedules documentation') }}</a>. <!-- oneline to prevent extra space before period -->
</p>
</div>
</div>
</div>
`,
};
-
diff --git a/app/assets/javascripts/pipelines/components/async_button.vue b/app/assets/javascripts/pipelines/components/async_button.vue
index 37a6f02d8fd..abcd0c4ecea 100644
--- a/app/assets/javascripts/pipelines/components/async_button.vue
+++ b/app/assets/javascripts/pipelines/components/async_button.vue
@@ -1,9 +1,9 @@
<script>
/* eslint-disable no-new, no-alert */
-/* global Flash */
-import '~/flash';
+
import eventHub from '../event_hub';
import loadingIcon from '../../vue_shared/components/loading_icon.vue';
+import tooltipMixin from '../../vue_shared/mixins/tooltip';
export default {
props: {
@@ -11,53 +11,42 @@ export default {
type: String,
required: true,
},
-
- service: {
- type: Object,
- required: true,
- },
-
title: {
type: String,
required: true,
},
-
icon: {
type: String,
required: true,
},
-
cssClass: {
type: String,
required: true,
},
-
confirmActionMessage: {
type: String,
required: false,
},
},
-
components: {
loadingIcon,
},
-
+ mixins: [
+ tooltipMixin,
+ ],
data() {
return {
isLoading: false,
};
},
-
computed: {
iconClass() {
return `fa fa-${this.icon}`;
},
-
buttonClass() {
- return `btn has-tooltip ${this.cssClass}`;
+ return `btn ${this.cssClass}`;
},
},
-
methods: {
onClick() {
if (this.confirmActionMessage && confirm(this.confirmActionMessage)) {
@@ -66,21 +55,11 @@ export default {
this.makeRequest();
}
},
-
makeRequest() {
this.isLoading = true;
- $(this.$el).tooltip('destroy');
-
- this.service.postAction(this.endpoint)
- .then(() => {
- this.isLoading = false;
- eventHub.$emit('refreshPipelines');
- })
- .catch(() => {
- this.isLoading = false;
- new Flash('An error occured while making the request.');
- });
+ $(this.$refs.tooltip).tooltip('destroy');
+ eventHub.$emit('postAction', this.endpoint);
},
},
};
@@ -95,10 +74,12 @@ export default {
:aria-label="title"
data-container="body"
data-placement="top"
+ ref="tooltip"
:disabled="isLoading">
<i
:class="iconClass"
- aria-hidden="true" />
+ aria-hidden="true">
+ </i>
<loading-icon v-if="isLoading" />
</button>
</template>
diff --git a/app/assets/javascripts/pipelines/components/pipelines.vue b/app/assets/javascripts/pipelines/components/pipelines.vue
index fed42d23112..01ae07aad65 100644
--- a/app/assets/javascripts/pipelines/components/pipelines.vue
+++ b/app/assets/javascripts/pipelines/components/pipelines.vue
@@ -1,15 +1,9 @@
<script>
- import Visibility from 'visibilityjs';
import PipelinesService from '../services/pipelines_service';
- import eventHub from '../event_hub';
- import pipelinesTableComponent from '../../vue_shared/components/pipelines_table.vue';
+ import pipelinesMixin from '../mixins/pipelines';
import tablePagination from '../../vue_shared/components/table_pagination.vue';
- import emptyState from './empty_state.vue';
- import errorState from './error_state.vue';
import navigationTabs from './navigation_tabs.vue';
import navigationControls from './nav_controls.vue';
- import loadingIcon from '../../vue_shared/components/loading_icon.vue';
- import Poll from '../../lib/utils/poll';
export default {
props: {
@@ -20,13 +14,12 @@
},
components: {
tablePagination,
- pipelinesTableComponent,
- emptyState,
- errorState,
navigationTabs,
navigationControls,
- loadingIcon,
},
+ mixins: [
+ pipelinesMixin,
+ ],
data() {
const pipelinesData = document.querySelector('#pipelines-list-vue').dataset;
@@ -47,11 +40,6 @@
state: this.store.state,
apiScope: 'all',
pagenum: 1,
- isLoading: false,
- hasError: false,
- isMakingRequest: false,
- updateGraphDropdown: false,
- hasMadeRequest: false,
};
},
computed: {
@@ -62,9 +50,6 @@
const scope = gl.utils.getParameterByName('scope');
return scope === null ? 'all' : scope;
},
- shouldRenderErrorState() {
- return this.hasError && !this.isLoading;
- },
/**
* The empty state should only be rendered when the request is made to fetch all pipelines
@@ -106,7 +91,6 @@
this.state.pipelines.length &&
this.state.pageInfo.total > this.state.pageInfo.perPage;
},
-
hasCiEnabled() {
return this.hasCi !== undefined;
},
@@ -129,37 +113,7 @@
},
created() {
this.service = new PipelinesService(this.endpoint);
-
- const poll = new Poll({
- resource: this.service,
- method: 'getPipelines',
- data: { page: this.pageParameter, scope: this.scopeParameter },
- successCallback: this.successCallback,
- errorCallback: this.errorCallback,
- notificationCallback: this.setIsMakingRequest,
- });
-
- if (!Visibility.hidden()) {
- this.isLoading = true;
- poll.makeRequest();
- } else {
- // If tab is not visible we need to make the first request so we don't show the empty
- // state without knowing if there are any pipelines
- this.fetchPipelines();
- }
-
- Visibility.change(() => {
- if (!Visibility.hidden()) {
- poll.restart();
- } else {
- poll.stop();
- }
- });
-
- eventHub.$on('refreshPipelines', this.fetchPipelines);
- },
- beforeDestroy() {
- eventHub.$off('refreshPipelines');
+ this.requestData = { page: this.pageParameter, scope: this.scopeParameter };
},
methods: {
/**
@@ -174,15 +128,6 @@
return param;
},
- fetchPipelines() {
- if (!this.isMakingRequest) {
- this.isLoading = true;
-
- this.service.getPipelines({ scope: this.scopeParameter, page: this.pageParameter })
- .then(response => this.successCallback(response))
- .catch(() => this.errorCallback());
- }
- },
successCallback(resp) {
const response = {
headers: resp.headers,
@@ -190,33 +135,14 @@
};
this.store.storeCount(response.body.count);
- this.store.storePipelines(response.body.pipelines);
this.store.storePagination(response.headers);
-
- this.isLoading = false;
- this.updateGraphDropdown = true;
- this.hasMadeRequest = true;
- },
-
- errorCallback() {
- this.hasError = true;
- this.isLoading = false;
- this.updateGraphDropdown = false;
- },
-
- setIsMakingRequest(isMakingRequest) {
- this.isMakingRequest = isMakingRequest;
-
- if (isMakingRequest) {
- this.updateGraphDropdown = false;
- }
+ this.setCommonData(response.body.pipelines);
},
},
};
</script>
<template>
<div :class="cssClass">
-
<div
class="top-area scrolling-tabs-container inner-page-scroll-tabs"
v-if="!isLoading && !shouldRenderEmptyState">
@@ -274,7 +200,6 @@
<pipelines-table-component
:pipelines="state.pipelines"
- :service="service"
:update-graph-dropdown="updateGraphDropdown"
/>
</div>
diff --git a/app/assets/javascripts/pipelines/components/pipelines_actions.vue b/app/assets/javascripts/pipelines/components/pipelines_actions.vue
index 97b4de26214..a6fc4f04237 100644
--- a/app/assets/javascripts/pipelines/components/pipelines_actions.vue
+++ b/app/assets/javascripts/pipelines/components/pipelines_actions.vue
@@ -11,10 +11,6 @@
type: Array,
required: true,
},
- service: {
- type: Object,
- required: true,
- },
},
components: {
loadingIcon,
@@ -31,17 +27,9 @@
$(this.$refs.tooltip).tooltip('destroy');
- this.service.postAction(endpoint)
- .then(() => {
- this.isLoading = false;
- eventHub.$emit('refreshPipelines');
- })
- .catch(() => {
- this.isLoading = false;
- // eslint-disable-next-line no-new
- new Flash('An error occured while making the request.');
- });
+ eventHub.$emit('postAction', endpoint);
},
+
isActionDisabled(action) {
if (action.playable === undefined) {
return false;
diff --git a/app/assets/javascripts/vue_shared/components/pipelines_table.vue b/app/assets/javascripts/pipelines/components/pipelines_table.vue
index 884f1ce9689..5088d92209f 100644
--- a/app/assets/javascripts/vue_shared/components/pipelines_table.vue
+++ b/app/assets/javascripts/pipelines/components/pipelines_table.vue
@@ -12,10 +12,6 @@
type: Array,
required: true,
},
- service: {
- type: Object,
- required: true,
- },
updateGraphDropdown: {
type: Boolean,
required: false,
@@ -57,7 +53,6 @@
v-for="model in pipelines"
:key="model.id"
:pipeline="model"
- :service="service"
:update-graph-dropdown="updateGraphDropdown"
/>
</div>
diff --git a/app/assets/javascripts/vue_shared/components/pipelines_table_row.vue b/app/assets/javascripts/pipelines/components/pipelines_table_row.vue
index 4d5ebe2e9ed..c3f1c426d8a 100644
--- a/app/assets/javascripts/vue_shared/components/pipelines_table_row.vue
+++ b/app/assets/javascripts/pipelines/components/pipelines_table_row.vue
@@ -1,13 +1,13 @@
<script>
/* eslint-disable no-param-reassign */
-import asyncButtonComponent from '../../pipelines/components/async_button.vue';
-import pipelinesActionsComponent from '../../pipelines/components/pipelines_actions.vue';
-import pipelinesArtifactsComponent from '../../pipelines/components/pipelines_artifacts.vue';
-import ciBadge from './ci_badge_link.vue';
-import pipelineStage from '../../pipelines/components/stage.vue';
-import pipelineUrl from '../../pipelines/components/pipeline_url.vue';
-import pipelinesTimeago from '../../pipelines/components/time_ago.vue';
-import commitComponent from './commit.vue';
+import asyncButtonComponent from './async_button.vue';
+import pipelinesActionsComponent from './pipelines_actions.vue';
+import pipelinesArtifactsComponent from './pipelines_artifacts.vue';
+import ciBadge from '../../vue_shared/components/ci_badge_link.vue';
+import pipelineStage from './stage.vue';
+import pipelineUrl from './pipeline_url.vue';
+import pipelinesTimeago from './time_ago.vue';
+import commitComponent from '../../vue_shared/components/commit.vue';
/**
* Pipeline table row.
@@ -20,10 +20,6 @@ export default {
type: Object,
required: true,
},
- service: {
- type: Object,
- required: true,
- },
updateGraphDropdown: {
type: Boolean,
required: false,
@@ -271,7 +267,6 @@ export default {
<pipelines-actions-component
v-if="pipeline.details.manual_actions.length"
:actions="pipeline.details.manual_actions"
- :service="service"
/>
<pipelines-artifacts-component
@@ -282,7 +277,6 @@ export default {
<async-button-component
v-if="pipeline.flags.retryable"
- :service="service"
:endpoint="pipeline.retry_path"
css-class="js-pipelines-retry-button btn-default btn-retry"
title="Retry"
@@ -291,7 +285,6 @@ export default {
<async-button-component
v-if="pipeline.flags.cancelable"
- :service="service"
:endpoint="pipeline.cancel_path"
css-class="js-pipelines-cancel-button btn-remove"
title="Cancel"
diff --git a/app/assets/javascripts/pipelines/mixins/pipelines.js b/app/assets/javascripts/pipelines/mixins/pipelines.js
new file mode 100644
index 00000000000..9adc15e6266
--- /dev/null
+++ b/app/assets/javascripts/pipelines/mixins/pipelines.js
@@ -0,0 +1,103 @@
+/* global Flash */
+import '~/flash';
+import Visibility from 'visibilityjs';
+import Poll from '../../lib/utils/poll';
+import emptyState from '../components/empty_state.vue';
+import errorState from '../components/error_state.vue';
+import loadingIcon from '../../vue_shared/components/loading_icon.vue';
+import pipelinesTableComponent from '../components/pipelines_table.vue';
+import eventHub from '../event_hub';
+
+export default {
+ components: {
+ pipelinesTableComponent,
+ errorState,
+ emptyState,
+ loadingIcon,
+ },
+ computed: {
+ shouldRenderErrorState() {
+ return this.hasError && !this.isLoading;
+ },
+ },
+ data() {
+ return {
+ isLoading: false,
+ hasError: false,
+ isMakingRequest: false,
+ updateGraphDropdown: false,
+ hasMadeRequest: false,
+ };
+ },
+ beforeMount() {
+ this.poll = new Poll({
+ resource: this.service,
+ method: 'getPipelines',
+ data: this.requestData ? this.requestData : undefined,
+ successCallback: this.successCallback,
+ errorCallback: this.errorCallback,
+ notificationCallback: this.setIsMakingRequest,
+ });
+
+ if (!Visibility.hidden()) {
+ this.isLoading = true;
+ this.poll.makeRequest();
+ } else {
+ // If tab is not visible we need to make the first request so we don't show the empty
+ // state without knowing if there are any pipelines
+ this.fetchPipelines();
+ }
+
+ Visibility.change(() => {
+ if (!Visibility.hidden()) {
+ this.poll.restart();
+ } else {
+ this.poll.stop();
+ }
+ });
+
+ eventHub.$on('refreshPipelines', this.fetchPipelines);
+ eventHub.$on('postAction', this.postAction);
+ },
+ beforeDestroy() {
+ eventHub.$off('refreshPipelines');
+ eventHub.$on('postAction', this.postAction);
+ },
+ destroyed() {
+ this.poll.stop();
+ },
+ methods: {
+ fetchPipelines() {
+ if (!this.isMakingRequest) {
+ this.isLoading = true;
+
+ this.service.getPipelines(this.requestData)
+ .then(response => this.successCallback(response))
+ .catch(() => this.errorCallback());
+ }
+ },
+ setCommonData(pipelines) {
+ this.store.storePipelines(pipelines);
+ this.isLoading = false;
+ this.updateGraphDropdown = true;
+ this.hasMadeRequest = true;
+ },
+ errorCallback() {
+ this.hasError = true;
+ this.isLoading = false;
+ this.updateGraphDropdown = false;
+ },
+ setIsMakingRequest(isMakingRequest) {
+ this.isMakingRequest = isMakingRequest;
+
+ if (isMakingRequest) {
+ this.updateGraphDropdown = false;
+ }
+ },
+ postAction(endpoint) {
+ this.service.postAction(endpoint)
+ .then(() => eventHub.$emit('refreshPipelines'))
+ .catch(() => new Flash('An error occured while making the request.'));
+ },
+ },
+};
diff --git a/app/assets/javascripts/preview_markdown.js b/app/assets/javascripts/preview_markdown.js
index 4a3df2fd465..141333b2b4d 100644
--- a/app/assets/javascripts/preview_markdown.js
+++ b/app/assets/javascripts/preview_markdown.js
@@ -3,7 +3,7 @@
// MarkdownPreview
//
// Handles toggling the "Write" and "Preview" tab clicks, rendering the preview
-// (including the explanation of slash commands), and showing a warning when
+// (including the explanation of quick actions), and showing a warning when
// more than `x` users are referenced.
//
(function () {
diff --git a/app/assets/javascripts/right_sidebar.js b/app/assets/javascripts/right_sidebar.js
index b71c3097706..da7c0c5a36c 100644
--- a/app/assets/javascripts/right_sidebar.js
+++ b/app/assets/javascripts/right_sidebar.js
@@ -7,6 +7,13 @@ import Cookies from 'js-cookie';
function Sidebar(currentUser) {
this.toggleTodo = this.toggleTodo.bind(this);
this.sidebar = $('aside');
+
+ this.$sidebarInner = this.sidebar.find('.issuable-sidebar');
+ this.$navGitlab = $('.navbar-gitlab');
+ this.$layoutNav = $('.layout-nav');
+ this.$subScroll = $('.sub-nav-scroll');
+ this.$rightSidebar = $('.js-right-sidebar');
+
this.removeListeners();
this.addEventListeners();
}
@@ -21,14 +28,15 @@ import Cookies from 'js-cookie';
Sidebar.prototype.addEventListeners = function() {
const $document = $(document);
- const throttledSetSidebarHeight = _.throttle(this.setSidebarHeight, 10);
+ const throttledSetSidebarHeight = _.throttle(this.setSidebarHeight.bind(this), 20);
+ const debouncedSetSidebarHeight = _.debounce(this.setSidebarHeight.bind(this), 200);
this.sidebar.on('click', '.sidebar-collapsed-icon', this, this.sidebarCollapseClicked);
$('.dropdown').on('hidden.gl.dropdown', this, this.onSidebarDropdownHidden);
$('.dropdown').on('loading.gl.dropdown', this.sidebarDropdownLoading);
$('.dropdown').on('loaded.gl.dropdown', this.sidebarDropdownLoaded);
$(window).on('resize', () => throttledSetSidebarHeight());
- $document.on('scroll', () => throttledSetSidebarHeight());
+ $document.on('scroll', () => debouncedSetSidebarHeight());
$document.on('click', '.js-sidebar-toggle', function(e, triggered) {
var $allGutterToggleIcons, $this, $thisIcon;
e.preventDefault();
@@ -207,13 +215,14 @@ import Cookies from 'js-cookie';
};
Sidebar.prototype.setSidebarHeight = function() {
- const $navHeight = $('.navbar-gitlab').outerHeight() + $('.layout-nav').outerHeight() + $('.sub-nav-scroll').outerHeight();
- const $rightSidebar = $('.js-right-sidebar');
+ const $navHeight = this.$navGitlab.outerHeight() + this.$layoutNav.outerHeight() + (this.$subScroll ? this.$subScroll.outerHeight() : 0);
const diff = $navHeight - $(window).scrollTop();
if (diff > 0) {
- $rightSidebar.outerHeight($(window).height() - diff);
+ this.$rightSidebar.outerHeight($(window).height() - diff);
+ this.$sidebarInner.height('100%');
} else {
- $rightSidebar.outerHeight('100%');
+ this.$rightSidebar.outerHeight('100%');
+ this.$sidebarInner.height('');
}
};
diff --git a/app/assets/javascripts/settings_panels.js b/app/assets/javascripts/settings_panels.js
index e67f449e1a2..59ff2a86293 100644
--- a/app/assets/javascripts/settings_panels.js
+++ b/app/assets/javascripts/settings_panels.js
@@ -1,11 +1,28 @@
+function expandSectionParent($section, $content) {
+ $section.addClass('expanded');
+ $content.off('animationend.expandSectionParent');
+}
+
function expandSection($section) {
$section.find('.js-settings-toggle').text('Close');
- $section.find('.settings-content').addClass('expanded').off('scroll').scrollTop(0);
+
+ const $content = $section.find('.settings-content');
+ $content.addClass('expanded').off('scroll.expandSection').scrollTop(0);
+
+ if ($content.hasClass('no-animate')) {
+ expandSectionParent($section, $content);
+ } else {
+ $content.on('animationend.expandSectionParent', () => expandSectionParent($section, $content));
+ }
}
function closeSection($section) {
$section.find('.js-settings-toggle').text('Expand');
- $section.find('.settings-content').removeClass('expanded').on('scroll', () => expandSection($section));
+
+ const $content = $section.find('.settings-content');
+ $content.removeClass('expanded').on('scroll.expandSection', () => expandSection($section));
+
+ $section.removeClass('expanded');
}
function toggleSection($section) {
@@ -21,7 +38,7 @@ function toggleSection($section) {
export default function initSettingsPanels() {
$('.settings').each((i, elm) => {
const $section = $(elm);
- $section.on('click', '.js-settings-toggle', () => toggleSection($section));
- $section.find('.settings-content:not(.expanded)').on('scroll', () => expandSection($section));
+ $section.on('click.toggleSection', '.js-settings-toggle', () => toggleSection($section));
+ $section.find('.settings-content:not(.expanded)').on('scroll.expandSection', () => expandSection($section));
});
}
diff --git a/app/assets/javascripts/sidebar/components/time_tracking/help_state.js b/app/assets/javascripts/sidebar/components/time_tracking/help_state.js
index b2a77462fe0..142ad437509 100644
--- a/app/assets/javascripts/sidebar/components/time_tracking/help_state.js
+++ b/app/assets/javascripts/sidebar/components/time_tracking/help_state.js
@@ -15,10 +15,10 @@ export default {
<div class="time-tracking-help-state">
<div class="time-tracking-info">
<h4>
- Track time with slash commands
+ Track time with quick actions
</h4>
<p>
- Slash commands can be used in the issues description and comment boxes.
+ Quick actions can be used in the issues description and comment boxes.
</p>
<p>
<code>
diff --git a/app/assets/javascripts/sidebar/components/time_tracking/sidebar_time_tracking.js b/app/assets/javascripts/sidebar/components/time_tracking/sidebar_time_tracking.js
index 244b67b3ad9..650e935b116 100644
--- a/app/assets/javascripts/sidebar/components/time_tracking/sidebar_time_tracking.js
+++ b/app/assets/javascripts/sidebar/components/time_tracking/sidebar_time_tracking.js
@@ -16,10 +16,10 @@ export default {
'issuable-time-tracker': timeTracker,
},
methods: {
- listenForSlashCommands() {
- $(document).on('ajax:success', '.gfm-form', this.slashCommandListened);
+ listenForQuickActions() {
+ $(document).on('ajax:success', '.gfm-form', this.quickActionListened);
},
- slashCommandListened(e, data) {
+ quickActionListened(e, data) {
const subscribedCommands = ['spend_time', 'time_estimate'];
let changedCommands;
if (data !== undefined) {
@@ -35,7 +35,7 @@ export default {
},
},
mounted() {
- this.listenForSlashCommands();
+ this.listenForQuickActions();
},
template: `
<div class="block">
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_memory_usage.js b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_memory_usage.js
index 8155218681c..76cb71b6c12 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_memory_usage.js
+++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_memory_usage.js
@@ -1,5 +1,5 @@
-import statusCodes from '~/lib/utils/http_status';
-import { bytesToMiB } from '~/lib/utils/number_utils';
+import statusCodes from '../../lib/utils/http_status';
+import { bytesToMiB } from '../../lib/utils/number_utils';
import MemoryGraph from '../../vue_shared/components/memory_graph';
import MRWidgetService from '../services/mr_widget_service';
diff --git a/app/assets/stylesheets/framework/blocks.scss b/app/assets/stylesheets/framework/blocks.scss
index fefe5575d9b..95a08c960ea 100644
--- a/app/assets/stylesheets/framework/blocks.scss
+++ b/app/assets/stylesheets/framework/blocks.scss
@@ -254,7 +254,7 @@
}
.landing {
- margin-bottom: $gl-padding;
+ margin: $gl-padding auto;
overflow: hidden;
display: flex;
position: relative;
diff --git a/app/assets/stylesheets/framework/files.scss b/app/assets/stylesheets/framework/files.scss
index b26d8fbd5fe..da03e4f5b5e 100644
--- a/app/assets/stylesheets/framework/files.scss
+++ b/app/assets/stylesheets/framework/files.scss
@@ -63,6 +63,7 @@
background-color: $gray-light;
text-align: right;
padding: 8px $gl-padding;
+ border-bottom: 1px solid $border-color;
@media (max-width: $screen-xs-max) {
text-align: left;
diff --git a/app/assets/stylesheets/framework/filters.scss b/app/assets/stylesheets/framework/filters.scss
index cfbaaaa04c7..767cf5ffea5 100644
--- a/app/assets/stylesheets/framework/filters.scss
+++ b/app/assets/stylesheets/framework/filters.scss
@@ -152,7 +152,7 @@
}
.value-container {
- background-color: $filter-value-selected-color;
+ box-shadow: inset 0 0 0 100px $filtered-search-term-shadow-color;
}
}
@@ -236,9 +236,6 @@
width: 35px;
background-color: $white-light;
border: none;
- position: static;
- right: 0;
- height: 100%;
outline: none;
z-index: 1;
diff --git a/app/assets/stylesheets/framework/forms.scss b/app/assets/stylesheets/framework/forms.scss
index a78179e727f..61e3897f369 100644
--- a/app/assets/stylesheets/framework/forms.scss
+++ b/app/assets/stylesheets/framework/forms.scss
@@ -125,10 +125,11 @@ label {
.select-wrapper {
position: relative;
- .fa-caret-down {
+ .fa-chevron-down {
position: absolute;
+ font-size: 10px;
right: 10px;
- top: 10px;
+ top: 12px;
color: $gray-darkest;
pointer-events: none;
}
@@ -138,6 +139,12 @@ label {
padding-left: 10px;
padding-right: 10px;
-webkit-appearance: none;
+ -moz-appearance: none;
+ appearance: none;
+
+ &::-ms-expand {
+ display: none;
+ }
}
.form-control-inline {
diff --git a/app/assets/stylesheets/framework/markdown_area.scss b/app/assets/stylesheets/framework/markdown_area.scss
index 80691a234f8..b21bcc22a87 100644
--- a/app/assets/stylesheets/framework/markdown_area.scss
+++ b/app/assets/stylesheets/framework/markdown_area.scss
@@ -174,3 +174,14 @@
white-space: nowrap;
}
}
+
+@media(max-width: $screen-xs-max) {
+ .atwho-view-ul {
+ width: 350px;
+ }
+
+ .atwho-view ul li {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ }
+}
diff --git a/app/assets/stylesheets/framework/nav.scss b/app/assets/stylesheets/framework/nav.scss
index 3787ef370b2..28b2a7cfacd 100644
--- a/app/assets/stylesheets/framework/nav.scss
+++ b/app/assets/stylesheets/framework/nav.scss
@@ -45,8 +45,7 @@
li {
display: flex;
- a,
- .btn-link {
+ a {
padding: $gl-btn-padding;
padding-bottom: 11px;
font-size: 14px;
@@ -68,29 +67,7 @@
}
}
- .btn-link {
- padding-top: 16px;
- padding-left: 15px;
- padding-right: 15px;
- border-left: none;
- border-right: none;
- border-top: none;
- border-radius: 0;
-
- &:hover,
- &:active,
- &:focus {
- background-color: transparent;
- }
-
- &:active {
- outline: 0;
- box-shadow: none;
- }
- }
-
- &.active a,
- &.active .btn-link {
+ &.active a {
border-bottom: 2px solid $link-underline-blue;
color: $black;
font-weight: 600;
diff --git a/app/assets/stylesheets/framework/panels.scss b/app/assets/stylesheets/framework/panels.scss
index fa364e68d22..e8d69e62194 100644
--- a/app/assets/stylesheets/framework/panels.scss
+++ b/app/assets/stylesheets/framework/panels.scss
@@ -1,54 +1,60 @@
.panel {
margin-bottom: $gl-padding;
+}
+
+.panel-slim {
+ @extend .panel;
+ margin-bottom: $gl-vert-padding;
+}
+
+
+.panel-heading {
+ padding: $gl-vert-padding $gl-padding;
+ line-height: 36px;
+
+ .controls {
+ margin-top: -2px;
+ float: right;
+ }
+
+ .dropdown-menu-toggle {
+ line-height: 20px;
+ }
- .panel-heading {
- padding: $gl-vert-padding $gl-padding;
- line-height: 36px;
-
- .controls {
- margin-top: -2px;
- float: right;
- }
-
- .dropdown-menu-toggle {
- line-height: 20px;
- }
-
- .badge {
- margin-top: -2px;
- margin-left: 5px;
- }
-
- &.split {
- display: flex;
- align-items: center;
- }
-
- .left {
- flex: 1 1 auto;
- }
-
- .right {
- flex: 0 0 auto;
- text-align: right;
- }
+ .badge {
+ margin-top: -2px;
+ margin-left: 5px;
}
- .panel-empty-heading {
- border-bottom: 0;
+ &.split {
+ display: flex;
+ align-items: center;
}
- .panel-body {
- padding: $gl-padding;
+ .left {
+ flex: 1 1 auto;
+ }
- .form-actions {
- margin: -$gl-padding;
- margin-top: $gl-padding;
- }
+ .right {
+ flex: 0 0 auto;
+ text-align: right;
}
+}
+
+.panel-empty-heading {
+ border-bottom: 0;
+}
+
+.panel-body {
+ padding: $gl-padding;
- .panel-title {
- font-size: inherit;
- line-height: inherit;
+ .form-actions {
+ margin: -$gl-padding;
+ margin-top: $gl-padding;
}
}
+
+.panel-title {
+ font-size: inherit;
+ line-height: inherit;
+}
diff --git a/app/assets/stylesheets/framework/selects.scss b/app/assets/stylesheets/framework/selects.scss
index 1b20c35ad98..40e654f4838 100644
--- a/app/assets/stylesheets/framework/selects.scss
+++ b/app/assets/stylesheets/framework/selects.scss
@@ -18,19 +18,28 @@
background-image: none;
background-color: transparent;
border: none;
- padding-top: 6px;
- padding-right: 10px;
+ padding-top: 12px;
+ padding-right: 20px;
+ font-size: 10px;
b {
- display: inline-block;
- width: 0;
- height: 0;
- margin-left: 2px;
- vertical-align: middle;
- border-top: 5px dashed;
- border-right: 5px solid transparent;
- border-left: 5px solid transparent;
+ display: none;
+ }
+
+ &::after {
+ content: "\f078";
+ position: absolute;
+ z-index: 1;
+ text-align: center;
+ pointer-events: none;
+ box-sizing: border-box;
color: $gray-darkest;
+ display: inline-block;
+ font: normal normal normal 14px/1 FontAwesome;
+ font-size: inherit;
+ text-rendering: auto;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
}
}
diff --git a/app/assets/stylesheets/framework/sidebar.scss b/app/assets/stylesheets/framework/sidebar.scss
index d4421e3af74..5cf9330b8f8 100644
--- a/app/assets/stylesheets/framework/sidebar.scss
+++ b/app/assets/stylesheets/framework/sidebar.scss
@@ -97,17 +97,19 @@
.issues-bulk-update.right-sidebar {
@include maintain-sidebar-dimensions;
- transition: right $sidebar-transition-duration;
- right: -$gutter-width;
+ width: 0;
+ padding: 0;
+ transition: width $sidebar-transition-duration;
&.right-sidebar-expanded {
@include maintain-sidebar-dimensions;
- right: 0;
+ width: $gutter-width;
}
&.right-sidebar-collapsed {
@include maintain-sidebar-dimensions;
- right: -$gutter-width;
+ width: 0;
+ padding: 0;
.block {
padding: 16px 0;
@@ -118,5 +120,6 @@
.issuable-sidebar {
padding: 0 3px;
+ width: calc(100% + 35px);
}
}
diff --git a/app/assets/stylesheets/framework/timeline.scss b/app/assets/stylesheets/framework/timeline.scss
index 10881987038..3d68a50f91f 100644
--- a/app/assets/stylesheets/framework/timeline.scss
+++ b/app/assets/stylesheets/framework/timeline.scss
@@ -44,6 +44,10 @@
&:target,
&.target {
background: $line-target-blue;
+
+ &.system-note .note-body .note-text.system-note-commit-list::after {
+ background: linear-gradient(rgba($line-target-blue, 0.1) -100px, $line-target-blue 100%);
+ }
}
.avatar {
diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss
index 49ba0108228..13c9c6c9fb3 100644
--- a/app/assets/stylesheets/framework/variables.scss
+++ b/app/assets/stylesheets/framework/variables.scss
@@ -282,6 +282,7 @@ $dropdown-toggle-active-border-color: darken($border-color, 14%);
/*
* Filtered Search
*/
+$filtered-search-term-shadow-color: rgba(0, 0, 0, 0.09);
$dropdown-hover-color: $blue-400;
/*
@@ -322,6 +323,7 @@ $note-disabled-comment-color: #b2b2b2;
$note-targe3-outside: #fffff0;
$note-targe3-inside: #ffffd3;
$note-line2-border: #ddd;
+$note-icon-gutter-width: 55px;
/*
diff --git a/app/assets/stylesheets/pages/cycle_analytics.scss b/app/assets/stylesheets/pages/cycle_analytics.scss
index 7bec4bd5f56..3039732ca5b 100644
--- a/app/assets/stylesheets/pages/cycle_analytics.scss
+++ b/app/assets/stylesheets/pages/cycle_analytics.scss
@@ -4,7 +4,7 @@
position: relative;
.landing {
- margin-top: 10px;
+ margin-top: 0;
.inner-content {
white-space: normal;
diff --git a/app/assets/stylesheets/pages/groups.scss b/app/assets/stylesheets/pages/groups.scss
index 72d73b89a2a..6f6c6839975 100644
--- a/app/assets/stylesheets/pages/groups.scss
+++ b/app/assets/stylesheets/pages/groups.scss
@@ -90,8 +90,6 @@
}
.explore-groups.landing {
- margin-top: 10px;
-
.inner-content {
padding: 0;
diff --git a/app/assets/stylesheets/pages/issuable.scss b/app/assets/stylesheets/pages/issuable.scss
index b3f310ff67d..20f2eec9af5 100644
--- a/app/assets/stylesheets/pages/issuable.scss
+++ b/app/assets/stylesheets/pages/issuable.scss
@@ -204,7 +204,7 @@
.issuable-sidebar {
width: calc(100% + 100px);
- height: 100%;
+ height: calc(100% - #{$header-height});
overflow-y: scroll;
overflow-x: hidden;
-webkit-overflow-scrolling: touch;
@@ -729,33 +729,3 @@
}
}
}
-
-.confidential-issue-warning {
- background-color: $gl-gray;
- border-radius: 3px;
- padding: $gl-btn-padding $gl-padding;
- margin-top: $gl-padding-top;
- font-size: 14px;
- color: $white-light;
-
- .fa {
- margin-right: 8px;
- }
-
- a {
- color: $white-light;
- text-decoration: underline;
- }
-
- &.affix {
- position: static;
- width: initial;
-
- @media (min-width: $screen-sm-min) {
- position: sticky;
- position: -webkit-sticky;
- top: 60px;
- z-index: 200;
- }
- }
-}
diff --git a/app/assets/stylesheets/pages/milestone.scss b/app/assets/stylesheets/pages/milestone.scss
index 335e587b8f4..55e0ee1936e 100644
--- a/app/assets/stylesheets/pages/milestone.scss
+++ b/app/assets/stylesheets/pages/milestone.scss
@@ -111,8 +111,8 @@
}
}
-.issues-sortable-list,
-.merge_requests-sortable-list {
+.milestone-issues-list,
+.milestone-merge_requests-list {
.issuable-detail {
display: block;
margin-top: 7px;
@@ -197,6 +197,4 @@
.issuable-row {
background-color: $white-light;
- cursor: -webkit-grab;
- cursor: grab;
}
diff --git a/app/assets/stylesheets/pages/note_form.scss b/app/assets/stylesheets/pages/note_form.scss
index aa307414737..9877ed2cfd6 100644
--- a/app/assets/stylesheets/pages/note_form.scss
+++ b/app/assets/stylesheets/pages/note_form.scss
@@ -103,6 +103,42 @@
}
}
+.confidential-issue-warning {
+ background-color: $gray-normal;
+ border-radius: 3px;
+ padding: 3px 12px;
+ margin: auto;
+ margin-top: 0;
+ text-align: center;
+ font-size: 12px;
+ align-items: center;
+
+ @media (max-width: $screen-md-max) {
+ // On smaller devices the warning becomes the fourth item in the list,
+ // rather than centering, and grows to span the full width of the
+ // comment area.
+ order: 4;
+ margin: 6px auto;
+ width: 100%;
+ }
+
+ .fa {
+ margin-right: 8px;
+ }
+}
+
+.right-sidebar-expanded {
+ .confidential-issue-warning {
+ // When the sidebar is open the warning becomes the fourth item in the list,
+ // rather than centering, and grows to span the full width of the
+ // comment area.
+ order: 4;
+ margin: 6px auto;
+ width: 100%;
+ }
+}
+
+
.discussion-form {
padding: $gl-padding-top $gl-padding $gl-padding;
background-color: $white-light;
@@ -112,8 +148,20 @@
padding: 6px 0;
}
-.notes-form > li {
- border: 0;
+.notes.notes-form > li.timeline-entry {
+ @include notes-media('max', $screen-sm-max) {
+ padding: 0;
+ }
+
+ .timeline-content {
+ @include notes-media('max', $screen-sm-max) {
+ margin: 0;
+ }
+ }
+
+ .timeline-entry-inner {
+ border: 0;
+ }
}
.note-edit-form {
diff --git a/app/assets/stylesheets/pages/notes.scss b/app/assets/stylesheets/pages/notes.scss
index a0442463390..f0dbe4249c5 100644
--- a/app/assets/stylesheets/pages/notes.scss
+++ b/app/assets/stylesheets/pages/notes.scss
@@ -14,16 +14,6 @@ ul.notes {
margin: 0;
padding: 0;
- .timeline-content {
- margin-left: 55px;
-
- &.timeline-content-form {
- @include notes-media('max', $screen-sm-max) {
- margin-left: 0;
- }
- }
- }
-
.note-created-ago,
.note-updated-at {
white-space: nowrap;
@@ -46,15 +36,47 @@ ul.notes {
}
}
- > li {
- padding: $gl-padding $gl-btn-padding;
+ > li { // .timeline-entry
+ padding: 0;
display: block;
position: relative;
- border-bottom: 1px solid $white-normal;
+ border-bottom: 0;
+
+ @include notes-media('min', $screen-sm-min) {
+ padding-left: $note-icon-gutter-width;
+ }
+
+ .timeline-entry-inner {
+ padding: $gl-padding $gl-btn-padding;
+ border-bottom: 1px solid $white-normal;
+ }
- &:last-child {
- // Override `.timeline > li:last-child { border-bottom: none; }`
+ &:target,
+ &.target {
border-bottom: 1px solid $white-normal;
+
+ &:not(:first-child) {
+ border-top: 1px solid $white-normal;
+ margin-top: -1px;
+ }
+
+ .timeline-entry-inner {
+ border-bottom: 0;
+ }
+ }
+
+ .timeline-icon {
+ @include notes-media('min', $screen-sm-min) {
+ margin-left: -$note-icon-gutter-width;
+ }
+ }
+
+ .timeline-content {
+ margin-left: $note-icon-gutter-width;
+
+ @include notes-media('min', $screen-sm-min) {
+ margin-left: 0;
+ }
}
&.being-posted {
@@ -73,7 +95,7 @@ ul.notes {
}
&.note-discussion {
- &.timeline-entry {
+ .timeline-entry-inner {
padding: $gl-padding 10px;
}
}
@@ -152,13 +174,8 @@ ul.notes {
.system-note {
font-size: 14px;
- padding-left: 0;
clear: both;
- @include notes-media('min', $screen-sm-min) {
- margin-left: 65px;
- }
-
.note-header-info {
padding-bottom: 0;
}
@@ -192,13 +209,16 @@ ul.notes {
.timeline-icon {
float: left;
+ @include notes-media('min', $screen-sm-min) {
+ margin-left: 0;
+ width: auto;
+ }
+
svg {
width: 16px;
height: 16px;
fill: $gray-darkest;
- position: absolute;
- left: 0;
- top: 2px;
+ margin-top: 2px;
}
}
@@ -250,7 +270,7 @@ ul.notes {
&::after {
content: '';
width: 100%;
- height: 67px;
+ height: 70px;
position: absolute;
left: 0;
bottom: 0;
@@ -509,11 +529,6 @@ ul.notes {
display: inline;
line-height: 20px;
- @include notes-media('min', $screen-sm-min) {
- margin-left: 10px;
- line-height: 24px;
- }
-
.fa {
color: $gray-darkest;
position: relative;
@@ -644,15 +659,12 @@ ul.notes {
.discussion-body,
.diff-file {
.notes .note {
- padding-left: $gl-padding;
- padding-right: $gl-padding;
-
- &.system-note {
- padding-left: 0;
+ border-bottom: 1px solid $white-normal;
- @media (min-width: $screen-sm-min) {
- margin-left: 70px;
- }
+ .timeline-entry-inner {
+ padding-left: $gl-padding;
+ padding-right: $gl-padding;
+ border-bottom: none;
}
}
}
diff --git a/app/assets/stylesheets/pages/projects.scss b/app/assets/stylesheets/pages/projects.scss
index 062665bc634..562ecbc6986 100644
--- a/app/assets/stylesheets/pages/projects.scss
+++ b/app/assets/stylesheets/pages/projects.scss
@@ -380,7 +380,7 @@ a.deploy-project-label {
padding: 0;
background: transparent;
border: none;
- line-height: 36px;
+ line-height: 34px;
margin: 0;
> li + li::before {
diff --git a/app/assets/stylesheets/pages/settings.scss b/app/assets/stylesheets/pages/settings.scss
index 085706a5001..d69a8e0995c 100644
--- a/app/assets/stylesheets/pages/settings.scss
+++ b/app/assets/stylesheets/pages/settings.scss
@@ -29,6 +29,10 @@
&:first-of-type {
margin-top: 10px;
}
+
+ &.expanded {
+ overflow: visible;
+ }
}
.settings-header {
diff --git a/app/assets/stylesheets/pages/tree.scss b/app/assets/stylesheets/pages/tree.scss
index ab63225147f..ce1a13c6afa 100644
--- a/app/assets/stylesheets/pages/tree.scss
+++ b/app/assets/stylesheets/pages/tree.scss
@@ -1,6 +1,72 @@
.tree-holder {
- > .nav-block {
- margin: 11px 0;
+ .nav-block {
+ margin: 10px 0;
+
+ @media (min-width: $screen-sm-min) {
+ display: flex;
+
+ .tree-ref-container {
+ flex: 1;
+ }
+
+ .tree-controls {
+ text-align: right;
+
+ .btn-group {
+ margin-left: 10px;
+ }
+ }
+
+ .tree-ref-holder {
+ float: left;
+ margin-right: 15px;
+ }
+
+ .repo-breadcrumb {
+ li:last-of-type {
+ position: relative;
+ }
+ }
+
+ .add-to-tree-dropdown {
+ position: absolute;
+ left: 18px;
+ }
+ }
+ }
+
+ @media (max-width: $screen-xs-max) {
+ .repo-breadcrumb {
+ margin-top: 10px;
+ position: relative;
+
+ .dropdown-menu {
+ min-width: 100%;
+ width: 100%;
+ left: inherit;
+ right: 0;
+ }
+ }
+
+ .add-to-tree-dropdown {
+ position: absolute;
+ left: 0;
+ right: 0;
+ }
+
+ .tree-controls {
+ margin-bottom: 10px;
+
+ .btn,
+ .dropdown,
+ .btn-group {
+ width: 100%;
+ }
+
+ .btn {
+ margin: 10px 0 0;
+ }
+ }
}
.file-finder {
@@ -131,11 +197,6 @@
}
}
-.tree-ref-holder {
- float: left;
- margin-right: 15px;
-}
-
.blob-commit-info {
list-style: none;
margin: 0;
@@ -159,16 +220,6 @@
color: $md-link-color;
}
-.tree-controls {
- float: right;
- position: relative;
- z-index: 2;
-
- .project-action-button {
- margin-left: $btn-side-margin;
- }
-}
-
.repo-charts {
.sub-header {
margin: 20px 0;
diff --git a/app/controllers/concerns/creates_commit.rb b/app/controllers/concerns/creates_commit.rb
index 36ad307a93b..1a9904bbe57 100644
--- a/app/controllers/concerns/creates_commit.rb
+++ b/app/controllers/concerns/creates_commit.rb
@@ -97,8 +97,8 @@ module CreatesCommit
def merge_request_exists?
return @merge_request if defined?(@merge_request)
- @merge_request = MergeRequestsFinder.new(current_user, project_id: @project.id).execute.opened.
- find_by(source_project_id: @project_to_commit_into, source_branch: @branch_name, target_branch: @start_branch)
+ @merge_request = MergeRequestsFinder.new(current_user, project_id: @project.id).execute.opened
+ .find_by(source_project_id: @project_to_commit_into, source_branch: @branch_name, target_branch: @start_branch)
end
def different_project?
diff --git a/app/controllers/concerns/membership_actions.rb b/app/controllers/concerns/membership_actions.rb
index 8d07780f6c2..47d9ae350ae 100644
--- a/app/controllers/concerns/membership_actions.rb
+++ b/app/controllers/concerns/membership_actions.rb
@@ -15,8 +15,8 @@ module MembershipActions
end
def destroy
- Members::DestroyService.new(membershipable, current_user, params).
- execute(:all)
+ Members::DestroyService.new(membershipable, current_user, params)
+ .execute(:all)
respond_to do |format|
format.html do
@@ -42,8 +42,8 @@ module MembershipActions
end
def leave
- member = Members::DestroyService.new(membershipable, current_user, user_id: current_user.id).
- execute(:all)
+ member = Members::DestroyService.new(membershipable, current_user, user_id: current_user.id)
+ .execute(:all)
notice =
if member.request?
diff --git a/app/controllers/concerns/milestone_actions.rb b/app/controllers/concerns/milestone_actions.rb
index b2536a1c949..1ff785ac2ca 100644
--- a/app/controllers/concerns/milestone_actions.rb
+++ b/app/controllers/concerns/milestone_actions.rb
@@ -6,7 +6,7 @@ module MilestoneActions
format.html { redirect_to milestone_redirect_path }
format.json do
render json: tabs_json("shared/milestones/_merge_requests_tab", {
- merge_requests: @milestone.merge_requests,
+ merge_requests: @milestone.sorted_merge_requests,
show_project_name: true
})
end
diff --git a/app/controllers/dashboard/projects_controller.rb b/app/controllers/dashboard/projects_controller.rb
index 641c502dbe4..91c1e4dff79 100644
--- a/app/controllers/dashboard/projects_controller.rb
+++ b/app/controllers/dashboard/projects_controller.rb
@@ -22,8 +22,8 @@ class Dashboard::ProjectsController < Dashboard::ApplicationController
end
def starred
- @projects = load_projects(params.merge(starred: true)).
- includes(:forked_from_project, :tags).page(params[:page])
+ @projects = load_projects(params.merge(starred: true))
+ .includes(:forked_from_project, :tags).page(params[:page])
@groups = []
@@ -45,8 +45,8 @@ class Dashboard::ProjectsController < Dashboard::ApplicationController
end
def load_projects(finder_params)
- ProjectsFinder.new(params: finder_params, current_user: current_user).
- execute.includes(:route, namespace: :route)
+ ProjectsFinder.new(params: finder_params, current_user: current_user)
+ .execute.includes(:route, namespace: :route)
end
def load_events
diff --git a/app/controllers/explore/projects_controller.rb b/app/controllers/explore/projects_controller.rb
index 8f1870759e4..741879dee35 100644
--- a/app/controllers/explore/projects_controller.rb
+++ b/app/controllers/explore/projects_controller.rb
@@ -49,7 +49,7 @@ class Explore::ProjectsController < Explore::ApplicationController
private
def load_projects
- ProjectsFinder.new(current_user: current_user, params: params).
- execute.includes(:route, namespace: :route)
+ ProjectsFinder.new(current_user: current_user, params: params)
+ .execute.includes(:route, namespace: :route)
end
end
diff --git a/app/controllers/jwt_controller.rb b/app/controllers/jwt_controller.rb
index 11db164b3fa..4bceb1d67a3 100644
--- a/app/controllers/jwt_controller.rb
+++ b/app/controllers/jwt_controller.rb
@@ -11,8 +11,8 @@ class JwtController < ApplicationController
service = SERVICES[params[:service]]
return head :not_found unless service
- result = service.new(@authentication_result.project, @authentication_result.actor, auth_params).
- execute(authentication_abilities: @authentication_result.authentication_abilities)
+ result = service.new(@authentication_result.project, @authentication_result.actor, auth_params)
+ .execute(authentication_abilities: @authentication_result.authentication_abilities)
render json: result, status: result[:http_status]
end
diff --git a/app/controllers/omniauth_callbacks_controller.rb b/app/controllers/omniauth_callbacks_controller.rb
index 2a8c8ca4bad..b82681b197e 100644
--- a/app/controllers/omniauth_callbacks_controller.rb
+++ b/app/controllers/omniauth_callbacks_controller.rb
@@ -144,7 +144,7 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
end
def log_audit_event(user, options = {})
- AuditEventService.new(user, user, options).
- for_authentication.security_event
+ AuditEventService.new(user, user, options)
+ .for_authentication.security_event
end
end
diff --git a/app/controllers/profiles_controller.rb b/app/controllers/profiles_controller.rb
index 72f34930ca8..f98a9e24de1 100644
--- a/app/controllers/profiles_controller.rb
+++ b/app/controllers/profiles_controller.rb
@@ -49,9 +49,9 @@ class ProfilesController < Profiles::ApplicationController
end
def audit_log
- @events = AuditEvent.where(entity_type: "User", entity_id: current_user.id).
- order("created_at DESC").
- page(params[:page])
+ @events = AuditEvent.where(entity_type: "User", entity_id: current_user.id)
+ .order("created_at DESC")
+ .page(params[:page])
end
def update_username
diff --git a/app/controllers/projects/application_controller.rb b/app/controllers/projects/application_controller.rb
index 603a51266da..3d7ce4f0222 100644
--- a/app/controllers/projects/application_controller.rb
+++ b/app/controllers/projects/application_controller.rb
@@ -53,9 +53,21 @@ class Projects::ApplicationController < ApplicationController
end
end
+ def check_project_feature_available!(feature)
+ render_404 unless project.feature_available?(feature, current_user)
+ end
+
+ def check_issuables_available!
+ render_404 unless project.feature_available?(:issues, current_user) ||
+ project.feature_available?(:merge_requests, current_user)
+ end
+
def method_missing(method_sym, *arguments, &block)
- if method_sym.to_s =~ /\Aauthorize_(.*)!\z/
+ case method_sym.to_s
+ when /\Aauthorize_(.*)!\z/
authorize_action!($1.to_sym)
+ when /\Acheck_(.*)_available!\z/
+ check_project_feature_available!($1.to_sym)
else
super
end
diff --git a/app/controllers/projects/blob_controller.rb b/app/controllers/projects/blob_controller.rb
index 66e6a9a451c..a82d6fd5a4a 100644
--- a/app/controllers/projects/blob_controller.rb
+++ b/app/controllers/projects/blob_controller.rb
@@ -187,7 +187,7 @@ class Projects::BlobController < Projects::ApplicationController
end
def set_last_commit_sha
- @last_commit_sha = Gitlab::Git::Commit.
- last_for_path(@repository, @ref, @path).sha
+ @last_commit_sha = Gitlab::Git::Commit
+ .last_for_path(@repository, @ref, @path).sha
end
end
diff --git a/app/controllers/projects/branches_controller.rb b/app/controllers/projects/branches_controller.rb
index 70b06cfd9b4..94a752c21eb 100644
--- a/app/controllers/projects/branches_controller.rb
+++ b/app/controllers/projects/branches_controller.rb
@@ -37,8 +37,8 @@ class Projects::BranchesController < Projects::ApplicationController
redirect_to_autodeploy = project.empty_repo? && project.deployment_services.present?
- result = CreateBranchService.new(project, current_user).
- execute(branch_name, ref)
+ result = CreateBranchService.new(project, current_user)
+ .execute(branch_name, ref)
if params[:issue_iid]
issue = IssuesFinder.new(current_user, project_id: @project.id).find_by(iid: params[:issue_iid])
diff --git a/app/controllers/projects/commits_controller.rb b/app/controllers/projects/commits_controller.rb
index f33797ca310..37b5a6e9d48 100644
--- a/app/controllers/projects/commits_controller.rb
+++ b/app/controllers/projects/commits_controller.rb
@@ -18,11 +18,11 @@ class Projects::CommitsController < Projects::ApplicationController
@repository.commits(@ref, path: @path, limit: @limit, offset: @offset)
end
- @note_counts = project.notes.where(commit_id: @commits.map(&:id)).
- group(:commit_id).count
+ @note_counts = project.notes.where(commit_id: @commits.map(&:id))
+ .group(:commit_id).count
- @merge_request = MergeRequestsFinder.new(current_user, project_id: @project.id).execute.opened.
- find_by(source_project: @project, source_branch: @ref, target_branch: @repository.root_ref)
+ @merge_request = MergeRequestsFinder.new(current_user, project_id: @project.id).execute.opened
+ .find_by(source_project: @project, source_branch: @ref, target_branch: @repository.root_ref)
respond_to do |format|
format.html
diff --git a/app/controllers/projects/compare_controller.rb b/app/controllers/projects/compare_controller.rb
index 88dd600e5fe..ef400c4d745 100644
--- a/app/controllers/projects/compare_controller.rb
+++ b/app/controllers/projects/compare_controller.rb
@@ -61,7 +61,7 @@ class Projects::CompareController < Projects::ApplicationController
end
def merge_request
- @merge_request ||= MergeRequestsFinder.new(current_user, project_id: @project.id).execute.opened.
- find_by(source_project: @project, source_branch: @head_ref, target_branch: @start_ref)
+ @merge_request ||= MergeRequestsFinder.new(current_user, project_id: @project.id).execute.opened
+ .find_by(source_project: @project, source_branch: @head_ref, target_branch: @start_ref)
end
end
diff --git a/app/controllers/projects/deploy_keys_controller.rb b/app/controllers/projects/deploy_keys_controller.rb
index 7f1469e107d..c2e621fa190 100644
--- a/app/controllers/projects/deploy_keys_controller.rb
+++ b/app/controllers/projects/deploy_keys_controller.rb
@@ -6,7 +6,7 @@ class Projects::DeployKeysController < Projects::ApplicationController
before_action :authorize_admin_project!
before_action :authorize_update_deploy_key!, only: [:edit, :update]
- layout "project_settings"
+ layout 'project_settings'
def index
respond_to do |format|
@@ -66,7 +66,7 @@ class Projects::DeployKeysController < Projects::ApplicationController
protected
def deploy_key
- @deploy_key ||= @project.deploy_keys.find(params[:id])
+ @deploy_key ||= DeployKey.find(params[:id])
end
def create_params
diff --git a/app/controllers/projects/discussions_controller.rb b/app/controllers/projects/discussions_controller.rb
index f4a18a5e8f7..2e6ab7903b8 100644
--- a/app/controllers/projects/discussions_controller.rb
+++ b/app/controllers/projects/discussions_controller.rb
@@ -1,5 +1,5 @@
class Projects::DiscussionsController < Projects::ApplicationController
- before_action :module_enabled
+ before_action :check_merge_requests_available!
before_action :merge_request
before_action :discussion
before_action :authorize_resolve_discussion!
@@ -34,8 +34,4 @@ class Projects::DiscussionsController < Projects::ApplicationController
def authorize_resolve_discussion!
access_denied! unless discussion.can_resolve?(current_user)
end
-
- def module_enabled
- render_404 unless @project.feature_available?(:merge_requests, current_user)
- end
end
diff --git a/app/controllers/projects/environments_controller.rb b/app/controllers/projects/environments_controller.rb
index 3869d4b2d56..f88a1ffd1e9 100644
--- a/app/controllers/projects/environments_controller.rb
+++ b/app/controllers/projects/environments_controller.rb
@@ -15,8 +15,6 @@ class Projects::EnvironmentsController < Projects::ApplicationController
respond_to do |format|
format.html
format.json do
- Gitlab::PollingInterval.set_header(response, interval: 3_000)
-
render json: {
environments: EnvironmentSerializer
.new(project: @project, current_user: @current_user)
diff --git a/app/controllers/projects/git_http_client_controller.rb b/app/controllers/projects/git_http_client_controller.rb
index 928f17e6a8e..7d0e2b3e2ef 100644
--- a/app/controllers/projects/git_http_client_controller.rb
+++ b/app/controllers/projects/git_http_client_controller.rb
@@ -4,7 +4,7 @@ class Projects::GitHttpClientController < Projects::ApplicationController
include ActionController::HttpAuthentication::Basic
include KerberosSpnegoHelper
- attr_reader :authentication_result
+ attr_reader :authentication_result, :redirected_path
delegate :actor, :authentication_abilities, to: :authentication_result, allow_nil: true
@@ -14,7 +14,6 @@ class Projects::GitHttpClientController < Projects::ApplicationController
skip_before_action :verify_authenticity_token
skip_before_action :repository
before_action :authenticate_user
- before_action :ensure_project_found!
private
@@ -68,38 +67,14 @@ class Projects::GitHttpClientController < Projects::ApplicationController
headers['Www-Authenticate'] = challenges.join("\n") if challenges.any?
end
- def ensure_project_found!
- render_not_found if project.blank?
- end
-
def project
- return @project if defined?(@project)
-
- project_id, _ = project_id_with_suffix
- @project =
- if project_id.blank?
- nil
- else
- Project.find_by_full_path("#{params[:namespace_id]}/#{project_id}")
- end
- end
+ parse_repo_path unless defined?(@project)
- # This method returns two values so that we can parse
- # params[:project_id] (untrusted input!) in exactly one place.
- def project_id_with_suffix
- id = params[:project_id] || ''
-
- %w[.wiki.git .git].each do |suffix|
- if id.end_with?(suffix)
- # Be careful to only remove the suffix from the end of 'id'.
- # Accidentally removing it from the middle is how security
- # vulnerabilities happen!
- return [id.slice(0, id.length - suffix.length), suffix]
- end
- end
+ @project
+ end
- # Something is wrong with params[:project_id]; do not pass it on.
- [nil, nil]
+ def parse_repo_path
+ @project, @wiki, @redirected_path = Gitlab::RepoPath.parse("#{params[:namespace_id]}/#{params[:project_id]}")
end
def render_missing_personal_token
@@ -114,14 +89,9 @@ class Projects::GitHttpClientController < Projects::ApplicationController
end
def wiki?
- return @wiki if defined?(@wiki)
-
- _, suffix = project_id_with_suffix
- @wiki = suffix == '.wiki.git'
- end
+ parse_repo_path unless defined?(@wiki)
- def render_not_found
- render plain: 'Not Found', status: :not_found
+ @wiki
end
def handle_basic_authentication(login, password)
diff --git a/app/controllers/projects/git_http_controller.rb b/app/controllers/projects/git_http_controller.rb
index b6b62da7b60..71ae60cb8cd 100644
--- a/app/controllers/projects/git_http_controller.rb
+++ b/app/controllers/projects/git_http_controller.rb
@@ -56,7 +56,7 @@ class Projects::GitHttpController < Projects::GitHttpClientController
end
def access
- @access ||= access_klass.new(access_actor, project, 'http', authentication_abilities: authentication_abilities)
+ @access ||= access_klass.new(access_actor, project, 'http', authentication_abilities: authentication_abilities, redirected_path: redirected_path)
end
def access_actor
diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb
index 56f76e752d0..dfc6baa34a4 100644
--- a/app/controllers/projects/issues_controller.rb
+++ b/app/controllers/projects/issues_controller.rb
@@ -9,7 +9,7 @@ class Projects::IssuesController < Projects::ApplicationController
prepend_before_action :authenticate_user!, only: [:new]
before_action :redirect_to_external_issue_tracker, only: [:index, :new]
- before_action :module_enabled
+ before_action :check_issues_available!
before_action :issue, except: [:index, :new, :create, :bulk_update]
# Allow write(create) issue
@@ -250,7 +250,7 @@ class Projects::IssuesController < Projects::ApplicationController
return render_404 unless can?(current_user, :push_code, @project) && @issue.can_be_worked_on?(current_user)
end
- def module_enabled
+ def check_issues_available!
return render_404 unless @project.feature_available?(:issues, current_user) && @project.default_issues_tracker?
end
diff --git a/app/controllers/projects/labels_controller.rb b/app/controllers/projects/labels_controller.rb
index 1beac202efe..daa973c9281 100644
--- a/app/controllers/projects/labels_controller.rb
+++ b/app/controllers/projects/labels_controller.rb
@@ -1,7 +1,7 @@
class Projects::LabelsController < Projects::ApplicationController
include ToggleSubscriptionAction
- before_action :module_enabled
+ before_action :check_issuables_available!
before_action :label, only: [:edit, :update, :destroy, :promote]
before_action :find_labels, only: [:index, :set_priorities, :remove_priority, :toggle_subscription]
before_action :authorize_read_label!
@@ -135,12 +135,6 @@ class Projects::LabelsController < Projects::ApplicationController
protected
- def module_enabled
- unless @project.feature_available?(:issues, current_user) || @project.feature_available?(:merge_requests, current_user)
- return render_404
- end
- end
-
def label_params
params.require(:label).permit(:title, :description, :color)
end
diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index 314906b5f09..164a8824277 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -7,7 +7,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
include ToggleAwardEmoji
include IssuableCollections
- before_action :module_enabled
+ before_action :check_merge_requests_available!
before_action :merge_request, only: [
:edit, :update, :show, :diffs, :commits, :conflicts, :conflict_for_path, :pipelines, :merge,
:pipeline_status, :ci_environments_status, :toggle_subscription, :cancel_merge_when_pipeline_succeeds, :remove_wip, :resolve_conflicts, :assign_related_issues, :commit_change_content
@@ -143,8 +143,8 @@ class Projects::MergeRequestsController < Projects::ApplicationController
# Get commits from repository
# or from cache if already merged
@commits = @merge_request.commits
- @note_counts = Note.where(commit_id: @commits.map(&:id)).
- group(:commit_id).count
+ @note_counts = Note.where(commit_id: @commits.map(&:id))
+ .group(:commit_id).count
render json: { html: view_to_html_string('projects/merge_requests/show/_commits') }
end
@@ -192,9 +192,9 @@ class Projects::MergeRequestsController < Projects::ApplicationController
end
begin
- MergeRequests::Conflicts::ResolveService.
- new(merge_request).
- execute(current_user, params)
+ MergeRequests::Conflicts::ResolveService
+ .new(merge_request)
+ .execute(current_user, params)
flash[:notice] = 'All merge conflicts were resolved. The merge request can now be merged.'
@@ -461,10 +461,6 @@ class Projects::MergeRequestsController < Projects::ApplicationController
return render_404 unless @conflicts_list.can_be_resolved_by?(current_user)
end
- def module_enabled
- return render_404 unless @project.feature_available?(:merge_requests, current_user)
- end
-
def validates_merge_request
# Show git not found page
# if there is no saved commits between source & target branch
@@ -562,8 +558,8 @@ class Projects::MergeRequestsController < Projects::ApplicationController
@commits = @merge_request.compare_commits.reverse
@commit = @merge_request.diff_head_commit
- @note_counts = Note.where(commit_id: @commits.map(&:id)).
- group(:commit_id).count
+ @note_counts = Note.where(commit_id: @commits.map(&:id))
+ .group(:commit_id).count
@labels = LabelsFinder.new(current_user, project_id: @project.id).execute
diff --git a/app/controllers/projects/milestones_controller.rb b/app/controllers/projects/milestones_controller.rb
index ae16f69955a..953b1e83e49 100644
--- a/app/controllers/projects/milestones_controller.rb
+++ b/app/controllers/projects/milestones_controller.rb
@@ -1,8 +1,8 @@
class Projects::MilestonesController < Projects::ApplicationController
include MilestoneActions
- before_action :module_enabled
- before_action :milestone, only: [:edit, :update, :destroy, :show, :sort_issues, :sort_merge_requests, :merge_requests, :participants, :labels]
+ before_action :check_issuables_available!
+ before_action :milestone, only: [:edit, :update, :destroy, :show, :merge_requests, :participants, :labels]
# Allow read any milestone
before_action :authorize_read_milestone!
@@ -85,22 +85,6 @@ class Projects::MilestonesController < Projects::ApplicationController
end
end
- def sort_issues
- @milestone.sort_issues(params['sortable_issue'].map(&:to_i))
-
- render json: { saved: true }
- end
-
- def sort_merge_requests
- @merge_requests = @milestone.merge_requests.where(id: params['sortable_merge_request'])
- @merge_requests.each do |merge_request|
- merge_request.position = params['sortable_merge_request'].index(merge_request.id.to_s) + 1
- merge_request.save
- end
-
- render json: { saved: true }
- end
-
protected
def milestone
@@ -111,12 +95,6 @@ class Projects::MilestonesController < Projects::ApplicationController
return render_404 unless can?(current_user, :admin_milestone, @project)
end
- def module_enabled
- unless @project.feature_available?(:issues, current_user) || @project.feature_available?(:merge_requests, current_user)
- return render_404
- end
- end
-
def milestone_params
params.require(:milestone).permit(:title, :description, :start_date, :due_date, :state_event)
end
diff --git a/app/controllers/projects/settings/ci_cd_controller.rb b/app/controllers/projects/settings/ci_cd_controller.rb
index 6f009d61950..24fe78bc1bd 100644
--- a/app/controllers/projects/settings/ci_cd_controller.rb
+++ b/app/controllers/projects/settings/ci_cd_controller.rb
@@ -14,8 +14,8 @@ module Projects
def define_runners_variables
@project_runners = @project.runners.ordered
- @assignable_runners = current_user.ci_authorized_runners.
- assignable_for(project).ordered.page(params[:page]).per(20)
+ @assignable_runners = current_user.ci_authorized_runners
+ .assignable_for(project).ordered.page(params[:page]).per(20)
@shared_runners = Ci::Runner.shared.active
@shared_runners_count = @shared_runners.count(:all)
end
diff --git a/app/controllers/projects/snippets_controller.rb b/app/controllers/projects/snippets_controller.rb
index 8a8f8d6a27d..98dd307bd9d 100644
--- a/app/controllers/projects/snippets_controller.rb
+++ b/app/controllers/projects/snippets_controller.rb
@@ -5,7 +5,7 @@ class Projects::SnippetsController < Projects::ApplicationController
include SnippetsActions
include RendersBlob
- before_action :module_enabled
+ before_action :check_snippets_available!
before_action :snippet, only: [:show, :edit, :destroy, :update, :raw, :toggle_award_emoji, :mark_as_spam]
# Allow read any snippet
@@ -102,10 +102,6 @@ class Projects::SnippetsController < Projects::ApplicationController
return render_404 unless can?(current_user, :admin_project_snippet, @snippet)
end
- def module_enabled
- return render_404 unless @project.feature_available?(:snippets, current_user)
- end
-
def snippet_params
params.require(:project_snippet).permit(:title, :content, :file_name, :private, :visibility_level, :description)
end
diff --git a/app/controllers/projects/tags_controller.rb b/app/controllers/projects/tags_controller.rb
index afbea3e2b40..ebc9f4edab4 100644
--- a/app/controllers/projects/tags_controller.rb
+++ b/app/controllers/projects/tags_controller.rb
@@ -29,8 +29,8 @@ class Projects::TagsController < Projects::ApplicationController
end
def create
- result = Tags::CreateService.new(@project, current_user).
- execute(params[:tag_name], params[:ref], params[:message], params[:release_description])
+ result = Tags::CreateService.new(@project, current_user)
+ .execute(params[:tag_name], params[:ref], params[:message], params[:release_description])
if result[:status] == :success
@tag = result[:tag]
diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb
index d7c702b94f8..0d8186dce02 100644
--- a/app/controllers/sessions_controller.rb
+++ b/app/controllers/sessions_controller.rb
@@ -128,8 +128,8 @@ class SessionsController < Devise::SessionsController
end
def log_audit_event(user, options = {})
- AuditEventService.new(user, user, options).
- for_authentication.security_event
+ AuditEventService.new(user, user, options)
+ .for_authentication.security_event
end
def log_user_activity(user)
diff --git a/app/controllers/sherlock/application_controller.rb b/app/controllers/sherlock/application_controller.rb
index 682ca5e3821..6bdd3568a78 100644
--- a/app/controllers/sherlock/application_controller.rb
+++ b/app/controllers/sherlock/application_controller.rb
@@ -4,8 +4,8 @@ module Sherlock
def find_transaction
if params[:transaction_id]
- @transaction = Gitlab::Sherlock.collection.
- find_transaction(params[:transaction_id])
+ @transaction = Gitlab::Sherlock.collection
+ .find_transaction(params[:transaction_id])
end
end
end
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index c211106fbaa..8131eba6a2f 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -106,11 +106,11 @@ class UsersController < ApplicationController
def load_events
# Get user activity feed for projects common for both users
- @events = user.recent_events.
- merge(projects_for_current_user).
- references(:project).
- with_associations.
- limit_recent(20, params[:offset])
+ @events = user.recent_events
+ .merge(projects_for_current_user)
+ .references(:project)
+ .with_associations
+ .limit_recent(20, params[:offset])
end
def load_projects
diff --git a/app/finders/events_finder.rb b/app/finders/events_finder.rb
index b0450ddc1fd..46ecbaba73a 100644
--- a/app/finders/events_finder.rb
+++ b/app/finders/events_finder.rb
@@ -33,7 +33,8 @@ class EventsFinder
private
def by_current_user_access(events)
- events.merge(ProjectsFinder.new(current_user: current_user).execute).references(:project)
+ events.merge(ProjectsFinder.new(current_user: current_user).execute)
+ .joins(:project)
end
def by_action(events)
diff --git a/app/finders/group_members_finder.rb b/app/finders/group_members_finder.rb
index fce3775f40e..067aff408df 100644
--- a/app/finders/group_members_finder.rb
+++ b/app/finders/group_members_finder.rb
@@ -8,9 +8,9 @@ class GroupMembersFinder
return group_members unless @group.parent
- parents_members = GroupMember.non_request.
- where(source_id: @group.ancestors.select(:id)).
- where.not(user_id: @group.users.select(:id))
+ parents_members = GroupMember.non_request
+ .where(source_id: @group.ancestors.select(:id))
+ .where.not(user_id: @group.users.select(:id))
wheres = ["members.id IN (#{group_members.select(:id).to_sql})"]
wheres << "members.id IN (#{parents_members.select(:id).to_sql})"
diff --git a/app/finders/group_projects_finder.rb b/app/finders/group_projects_finder.rb
index f043c38c6f9..f2d3b90b8e2 100644
--- a/app/finders/group_projects_finder.rb
+++ b/app/finders/group_projects_finder.rb
@@ -29,35 +29,69 @@ class GroupProjectsFinder < ProjectsFinder
private
def init_collection
- only_owned = options.fetch(:only_owned, false)
- only_shared = options.fetch(:only_shared, false)
+ projects = if current_user
+ collection_with_user
+ else
+ collection_without_user
+ end
- projects = []
+ union(projects)
+ end
- if current_user
- if group.users.include?(current_user)
- projects << group.projects unless only_shared
- projects << group.shared_projects unless only_owned
+ def collection_with_user
+ if group.users.include?(current_user)
+ if only_shared?
+ [shared_projects]
+ elsif only_owned?
+ [owned_projects]
else
- unless only_shared
- projects << group.projects.visible_to_user(current_user)
- projects << group.projects.public_to_user(current_user)
- end
-
- unless only_owned
- projects << group.shared_projects.visible_to_user(current_user)
- projects << group.shared_projects.public_to_user(current_user)
- end
+ [shared_projects, owned_projects]
end
else
- projects << group.projects.public_only unless only_shared
- projects << group.shared_projects.public_only unless only_owned
+ if only_shared?
+ [shared_projects.public_or_visible_to_user(current_user)]
+ elsif only_owned?
+ [owned_projects.public_or_visible_to_user(current_user)]
+ else
+ [
+ owned_projects.public_or_visible_to_user(current_user),
+ shared_projects.public_or_visible_to_user(current_user)
+ ]
+ end
end
+ end
- projects
+ def collection_without_user
+ if only_shared?
+ [shared_projects.public_only]
+ elsif only_owned?
+ [owned_projects.public_only]
+ else
+ [shared_projects.public_only, owned_projects.public_only]
+ end
end
def union(items)
- find_union(items, Project)
+ if items.one?
+ items.first
+ else
+ find_union(items, Project)
+ end
+ end
+
+ def only_owned?
+ options.fetch(:only_owned, false)
+ end
+
+ def only_shared?
+ options.fetch(:only_shared, false)
+ end
+
+ def owned_projects
+ group.projects
+ end
+
+ def shared_projects
+ group.shared_projects
end
end
diff --git a/app/finders/groups_finder.rb b/app/finders/groups_finder.rb
index f68610e197c..e6fb112e7f2 100644
--- a/app/finders/groups_finder.rb
+++ b/app/finders/groups_finder.rb
@@ -5,8 +5,10 @@ class GroupsFinder < UnionFinder
end
def execute
- groups = find_union(all_groups, Group).with_route.order_id_desc
- by_parent(groups)
+ items = all_groups.map do |item|
+ by_parent(item)
+ end
+ find_union(items, Group).with_route.order_id_desc
end
private
@@ -16,12 +18,22 @@ class GroupsFinder < UnionFinder
def all_groups
groups = []
- groups << current_user.authorized_groups if current_user
+ if current_user
+ groups << Gitlab::GroupHierarchy.new(groups_for_ancestors, groups_for_descendants).all_groups
+ end
groups << Group.unscoped.public_to_user(current_user)
groups
end
+ def groups_for_ancestors
+ current_user.authorized_groups
+ end
+
+ def groups_for_descendants
+ current_user.groups
+ end
+
def by_parent(groups)
return groups unless params[:parent]
diff --git a/app/finders/issuable_finder.rb b/app/finders/issuable_finder.rb
index 957ad875858..558f8b5e2e5 100644
--- a/app/finders/issuable_finder.rb
+++ b/app/finders/issuable_finder.rb
@@ -41,6 +41,7 @@ class IssuableFinder
items = by_iids(items)
items = by_milestone(items)
items = by_label(items)
+ items = by_created_at(items)
# Filtering by project HAS TO be the last because we use the project IDs yielded by the issuable query thus far
items = by_project(items)
@@ -402,6 +403,18 @@ class IssuableFinder
params[:non_archived].present? ? items.non_archived : items
end
+ def by_created_at(items)
+ if params[:created_after].present?
+ items = items.where(items.klass.arel_table[:created_at].gteq(params[:created_after]))
+ end
+
+ if params[:created_before].present?
+ items = items.where(items.klass.arel_table[:created_at].lteq(params[:created_before]))
+ end
+
+ items
+ end
+
def current_user_related?
params[:scope] == 'created-by-me' || params[:scope] == 'authored' || params[:scope] == 'assigned-to-me'
end
diff --git a/app/finders/projects_finder.rb b/app/finders/projects_finder.rb
index 5bf722d1ec6..8bfbe37c543 100644
--- a/app/finders/projects_finder.rb
+++ b/app/finders/projects_finder.rb
@@ -28,34 +28,56 @@ class ProjectsFinder < UnionFinder
end
def execute
- items = init_collection
- items = items.map do |item|
- item = by_ids(item)
- item = by_personal(item)
- item = by_starred(item)
- item = by_trending(item)
- item = by_visibilty_level(item)
- item = by_tags(item)
- item = by_search(item)
- by_archived(item)
- end
- items = union(items)
- sort(items)
+ collection = init_collection
+ collection = by_ids(collection)
+ collection = by_personal(collection)
+ collection = by_starred(collection)
+ collection = by_trending(collection)
+ collection = by_visibilty_level(collection)
+ collection = by_tags(collection)
+ collection = by_search(collection)
+ collection = by_archived(collection)
+
+ sort(collection)
end
private
def init_collection
- projects = []
+ if current_user
+ collection_with_user
+ else
+ collection_without_user
+ end
+ end
- if params[:owned].present?
- projects << current_user.owned_projects if current_user
+ def collection_with_user
+ if owned_projects?
+ current_user.owned_projects
else
- projects << current_user.authorized_projects if current_user
- projects << Project.unscoped.public_to_user(current_user) unless params[:non_public].present?
+ if private_only?
+ current_user.authorized_projects
+ else
+ Project.public_or_visible_to_user(current_user)
+ end
end
+ end
+
+ # Builds a collection for an anonymous user.
+ def collection_without_user
+ if private_only? || owned_projects?
+ Project.none
+ else
+ Project.public_to_user
+ end
+ end
+
+ def owned_projects?
+ params[:owned].present?
+ end
- projects
+ def private_only?
+ params[:non_public].present?
end
def by_ids(items)
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 2bfc7586adc..a3b243fccb7 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -68,7 +68,7 @@ module ApplicationHelper
end
end
- def avatar_icon(user_or_email = nil, size = nil, scale = 2)
+ def avatar_icon(user_or_email = nil, size = nil, scale = 2, only_path: true)
user =
if user_or_email.is_a?(User)
user_or_email
@@ -77,7 +77,7 @@ module ApplicationHelper
end
if user
- user.avatar_url(size: size) || default_avatar
+ user.avatar_url(size: size, only_path: only_path) || default_avatar
else
gravatar_icon(user_or_email, size, scale)
end
@@ -167,9 +167,9 @@ module ApplicationHelper
css_classes = short_format ? 'js-short-timeago' : 'js-timeago'
css_classes << " #{html_class}" unless html_class.blank?
- element = content_tag :time, time.strftime("%b %d, %Y"),
+ element = content_tag :time, l(time, format: "%b %d, %Y"),
class: css_classes,
- title: time.to_time.in_time_zone.to_s(:medium),
+ title: l(time.to_time.in_time_zone, format: :timeago_tooltip),
datetime: time.to_time.getutc.iso8601,
data: {
toggle: 'tooltip',
diff --git a/app/helpers/diff_helper.rb b/app/helpers/diff_helper.rb
index 06822747d11..16a99addd0b 100644
--- a/app/helpers/diff_helper.rb
+++ b/app/helpers/diff_helper.rb
@@ -66,12 +66,12 @@ module DiffHelper
discussions_left = discussions_right = nil
- if left && (left.unchanged? || left.discussable?)
+ if left && left.discussable? && (left.unchanged? || left.removed?)
line_code = diff_file.line_code(left)
discussions_left = @grouped_diff_discussions[line_code]
end
- if right&.discussable?
+ if right && right.discussable? && right.added?
line_code = diff_file.line_code(right)
discussions_right = @grouped_diff_discussions[line_code]
end
diff --git a/app/helpers/form_helper.rb b/app/helpers/form_helper.rb
index 014fc46b130..8ceb5c36bda 100644
--- a/app/helpers/form_helper.rb
+++ b/app/helpers/form_helper.rb
@@ -8,10 +8,10 @@ module FormHelper
content_tag(:div, class: 'alert alert-danger', id: 'error_explanation') do
content_tag(:h4, headline) <<
content_tag(:ul) do
- model.errors.full_messages.
- map { |msg| content_tag(:li, msg) }.
- join.
- html_safe
+ model.errors.full_messages
+ .map { |msg| content_tag(:li, msg) }
+ .join
+ .html_safe
end
end
end
diff --git a/app/helpers/issuables_helper.rb b/app/helpers/issuables_helper.rb
index 5e8f0849969..3259a9c1933 100644
--- a/app/helpers/issuables_helper.rb
+++ b/app/helpers/issuables_helper.rb
@@ -138,8 +138,8 @@ module IssuablesHelper
end
output << "&ensp;".html_safe
- output << content_tag(:span, issuable.task_status, id: "task_status", class: "hidden-xs hidden-sm")
- output << content_tag(:span, issuable.task_status_short, id: "task_status_short", class: "hidden-md hidden-lg")
+ output << content_tag(:span, (issuable.task_status if issuable.tasks?), id: "task_status", class: "hidden-xs hidden-sm")
+ output << content_tag(:span, (issuable.task_status_short if issuable.tasks?), id: "task_status_short", class: "hidden-md hidden-lg")
output
end
@@ -216,7 +216,8 @@ module IssuablesHelper
initialTitleHtml: markdown_field(issuable, :title),
initialTitleText: issuable.title,
initialDescriptionHtml: markdown_field(issuable, :description),
- initialDescriptionText: issuable.description
+ initialDescriptionText: issuable.description,
+ initialTaskStatus: issuable.task_status
}
data.merge!(updated_at_by(issuable))
diff --git a/app/helpers/notes_helper.rb b/app/helpers/notes_helper.rb
index c59d8dafc83..64ad7b280cb 100644
--- a/app/helpers/notes_helper.rb
+++ b/app/helpers/notes_helper.rb
@@ -10,8 +10,8 @@ module NotesHelper
Ability.can_edit_note?(current_user, note)
end
- def note_supports_slash_commands?(note)
- Notes::SlashCommandsService.supported?(note, current_user)
+ def note_supports_quick_actions?(note)
+ Notes::QuickActionsService.supported?(note, current_user)
end
def noteable_json(noteable)
diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb
index c11dd49f4a7..d10e0bd45b0 100644
--- a/app/helpers/projects_helper.rb
+++ b/app/helpers/projects_helper.rb
@@ -80,7 +80,7 @@ module ProjectsHelper
end
def remove_fork_project_message(project)
- _("You are going to remove the fork relationship to source project %{forked_from_project}. Are you ABSOLUTELY sure?") %
+ _("You are going to remove the fork relationship to source project %{forked_from_project}. Are you ABSOLUTELY sure?") %
{ forked_from_project: @project.forked_from_project.name_with_namespace }
end
@@ -151,14 +151,21 @@ module ProjectsHelper
disabled: disabled_option
)
- content_tag(
- :select,
- options,
- name: "project[project_feature_attributes][#{field}]",
- id: "project_project_feature_attributes_#{field}",
- class: "pull-right form-control #{repo_children_classes(field)}",
- data: { field: field }
- ).html_safe
+ content_tag :div, class: "select-wrapper" do
+ concat(
+ content_tag(
+ :select,
+ options,
+ name: "project[project_feature_attributes][#{field}]",
+ id: "project_project_feature_attributes_#{field}",
+ class: "pull-right form-control select-control #{repo_children_classes(field)} ",
+ data: { field: field }
+ )
+ )
+ concat(
+ icon('chevron-down')
+ )
+ end.html_safe
end
def link_to_autodeploy_doc
@@ -187,8 +194,8 @@ module ProjectsHelper
end
def load_pipeline_status(projects)
- Gitlab::Cache::Ci::ProjectPipelineStatus.
- load_in_batch_for_projects(projects)
+ Gitlab::Cache::Ci::ProjectPipelineStatus
+ .load_in_batch_for_projects(projects)
end
private
diff --git a/app/helpers/search_helper.rb b/app/helpers/search_helper.rb
index 9c46035057f..8f15904f068 100644
--- a/app/helpers/search_helper.rb
+++ b/app/helpers/search_helper.rb
@@ -97,8 +97,8 @@ module SearchHelper
# Autocomplete results for the current user's projects
def projects_autocomplete(term, limit = 5)
- current_user.authorized_projects.search_by_title(term).
- sorted_by_stars.non_archived.limit(limit).map do |p|
+ current_user.authorized_projects.search_by_title(term)
+ .sorted_by_stars.non_archived.limit(limit).map do |p|
{
category: "Projects",
id: p.id,
diff --git a/app/helpers/wiki_helper.rb b/app/helpers/wiki_helper.rb
index 3e3f6246fc5..99212a3438f 100644
--- a/app/helpers/wiki_helper.rb
+++ b/app/helpers/wiki_helper.rb
@@ -6,8 +6,8 @@ module WikiHelper
# Returns a String composed of the capitalized name of each directory and the
# capitalized name of the page itself.
def breadcrumb(page_slug)
- page_slug.split('/').
- map { |dir_or_page| WikiPage.unhyphenize(dir_or_page).capitalize }.
- join(' / ')
+ page_slug.split('/')
+ .map { |dir_or_page| WikiPage.unhyphenize(dir_or_page).capitalize }
+ .join(' / ')
end
end
diff --git a/app/models/award_emoji.rb b/app/models/award_emoji.rb
index ebe60441603..91b62dabbcd 100644
--- a/app/models/award_emoji.rb
+++ b/app/models/award_emoji.rb
@@ -19,9 +19,9 @@ class AwardEmoji < ActiveRecord::Base
class << self
def votes_for_collection(ids, type)
- select('name', 'awardable_id', 'COUNT(*) as count').
- where('name IN (?) AND awardable_type = ? AND awardable_id IN (?)', [DOWNVOTE_NAME, UPVOTE_NAME], type, ids).
- group('name', 'awardable_id')
+ select('name', 'awardable_id', 'COUNT(*) as count')
+ .where('name IN (?) AND awardable_type = ? AND awardable_id IN (?)', [DOWNVOTE_NAME, UPVOTE_NAME], type, ids)
+ .group('name', 'awardable_id')
end
end
diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb
index 58758f7ca8a..a300536532b 100644
--- a/app/models/ci/build.rb
+++ b/app/models/ci/build.rb
@@ -138,17 +138,6 @@ module Ci
ExpandVariables.expand(environment, simple_variables) if environment
end
- def environment_url
- return @environment_url if defined?(@environment_url)
-
- @environment_url =
- if unexpanded_url = options&.dig(:environment, :url)
- ExpandVariables.expand(unexpanded_url, simple_variables)
- else
- persisted_environment&.external_url
- end
- end
-
def has_environment?
environment.present?
end
@@ -192,7 +181,7 @@ module Ci
slugified.gsub(/[^a-z0-9]/, '-')[0..62]
end
- # Variables whose value does not depend on other variables
+ # Variables whose value does not depend on environment
def simple_variables
variables = predefined_variables
variables += project.predefined_variables
@@ -207,7 +196,8 @@ module Ci
variables
end
- # All variables, including those dependent on other variables
+ # All variables, including those dependent on environment, which could
+ # contain unexpanded variables.
def variables
simple_variables.concat(persisted_environment_variables)
end
@@ -481,9 +471,10 @@ module Ci
variables = persisted_environment.predefined_variables
- if url = environment_url
- variables << { key: 'CI_ENVIRONMENT_URL', value: url, public: true }
- end
+ # Here we're passing unexpanded environment_url for runner to expand,
+ # and we need to make sure that CI_ENVIRONMENT_NAME and
+ # CI_ENVIRONMENT_SLUG so on are available for the URL be expanded.
+ variables << { key: 'CI_ENVIRONMENT_URL', value: environment_url, public: true } if environment_url
variables
end
@@ -506,6 +497,10 @@ module Ci
variables
end
+ def environment_url
+ options&.dig(:environment, :url) || persisted_environment&.external_url
+ end
+
def build_attributes_from_config
return {} unless pipeline.config_processor
diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb
index 9ddecba5183..1b3e5a25ac2 100644
--- a/app/models/ci/pipeline.rb
+++ b/app/models/ci/pipeline.rb
@@ -168,8 +168,8 @@ module Ci
end
def stages_names
- statuses.order(:stage_idx).distinct.
- pluck(:stage, :stage_idx).map(&:first)
+ statuses.order(:stage_idx).distinct
+ .pluck(:stage, :stage_idx).map(&:first)
end
def legacy_stage(name)
diff --git a/app/models/ci/runner.rb b/app/models/ci/runner.rb
index 487ba61bc9c..d12f96f3d0b 100644
--- a/app/models/ci/runner.rb
+++ b/app/models/ci/runner.rb
@@ -30,8 +30,8 @@ module Ci
scope :assignable_for, ->(project) do
# FIXME: That `to_sql` is needed to workaround a weird Rails bug.
# Without that, placeholders would miss one and couldn't match.
- where(locked: false).
- where.not("id IN (#{project.runners.select(:id).to_sql})").specific
+ where(locked: false)
+ .where.not("id IN (#{project.runners.select(:id).to_sql})").specific
end
validate :tag_constraints
diff --git a/app/models/concerns/issuable.rb b/app/models/concerns/issuable.rb
index ea10d004c9c..d178ee4422b 100644
--- a/app/models/concerns/issuable.rb
+++ b/app/models/concerns/issuable.rb
@@ -67,7 +67,6 @@ module Issuable
scope :authored, ->(user) { where(author_id: user) }
scope :recent, -> { reorder(id: :desc) }
- scope :order_position_asc, -> { reorder(position: :asc) }
scope :of_projects, ->(ids) { where(project_id: ids) }
scope :of_milestones, ->(ids) { where(milestone_id: ids) }
scope :with_milestone, ->(title) { left_joins_milestones.where(milestones: { title: title }) }
@@ -139,7 +138,6 @@ module Issuable
when 'upvotes_desc' then order_upvotes_desc
when 'label_priority' then order_labels_priority(excluded_labels: excluded_labels)
when 'priority' then order_due_date_and_labels_priority(excluded_labels: excluded_labels)
- when 'position_asc' then order_position_asc
else
order_by(method)
end
@@ -163,9 +161,9 @@ module Issuable
#
milestones_due_date = 'MIN(milestones.due_date)'
- order_milestone_due_asc.
- order_labels_priority(excluded_labels: excluded_labels, extra_select_columns: [milestones_due_date]).
- reorder(Gitlab::Database.nulls_last_order(milestones_due_date, 'ASC'),
+ order_milestone_due_asc
+ .order_labels_priority(excluded_labels: excluded_labels, extra_select_columns: [milestones_due_date])
+ .reorder(Gitlab::Database.nulls_last_order(milestones_due_date, 'ASC'),
Gitlab::Database.nulls_last_order('highest_priority', 'ASC'))
end
@@ -184,9 +182,9 @@ module Issuable
"(#{highest_priority}) AS highest_priority"
] + extra_select_columns
- select(select_columns.join(', ')).
- group(arel_table[:id]).
- reorder(Gitlab::Database.nulls_last_order('highest_priority', 'ASC'))
+ select(select_columns.join(', '))
+ .group(arel_table[:id])
+ .reorder(Gitlab::Database.nulls_last_order('highest_priority', 'ASC'))
end
def with_label(title, sort = nil)
diff --git a/app/models/concerns/milestoneish.rb b/app/models/concerns/milestoneish.rb
index a3472af5c55..01599ce49c6 100644
--- a/app/models/concerns/milestoneish.rb
+++ b/app/models/concerns/milestoneish.rb
@@ -40,10 +40,18 @@ module Milestoneish
def issues_visible_to_user(user)
memoize_per_user(user, :issues_visible_to_user) do
IssuesFinder.new(user, issues_finder_params)
- .execute.includes(:assignees).where(milestone_id: milestoneish_ids)
+ .execute.preload(:assignees).where(milestone_id: milestoneish_ids)
end
end
+ def sorted_issues(user)
+ issues_visible_to_user(user).preload_associations.sort('label_priority')
+ end
+
+ def sorted_merge_requests
+ merge_requests.sort('label_priority')
+ end
+
def upcoming?
start_date && start_date.future?
end
diff --git a/app/models/concerns/relative_positioning.rb b/app/models/concerns/relative_positioning.rb
index f1d8532a6d6..7cb9a28a284 100644
--- a/app/models/concerns/relative_positioning.rb
+++ b/app/models/concerns/relative_positioning.rb
@@ -18,10 +18,10 @@ module RelativePositioning
prev_pos = nil
if self.relative_position
- prev_pos = self.class.
- in_projects(project.id).
- where('relative_position < ?', self.relative_position).
- maximum(:relative_position)
+ prev_pos = self.class
+ .in_projects(project.id)
+ .where('relative_position < ?', self.relative_position)
+ .maximum(:relative_position)
end
prev_pos
@@ -31,10 +31,10 @@ module RelativePositioning
next_pos = nil
if self.relative_position
- next_pos = self.class.
- in_projects(project.id).
- where('relative_position > ?', self.relative_position).
- minimum(:relative_position)
+ next_pos = self.class
+ .in_projects(project.id)
+ .where('relative_position > ?', self.relative_position)
+ .minimum(:relative_position)
end
next_pos
diff --git a/app/models/concerns/routable.rb b/app/models/concerns/routable.rb
index 63d02b76f6b..ec7796a9dbb 100644
--- a/app/models/concerns/routable.rb
+++ b/app/models/concerns/routable.rb
@@ -107,6 +107,14 @@ module Routable
RequestStore[key] ||= uncached_full_path
end
+ def build_full_path
+ if parent && path
+ parent.full_path + '/' + path
+ else
+ path
+ end
+ end
+
private
def uncached_full_path
@@ -135,14 +143,6 @@ module Routable
end
end
- def build_full_path
- if parent && path
- parent.full_path + '/' + path
- else
- path
- end
- end
-
def update_route
prepare_route
route.save
diff --git a/app/models/concerns/sortable.rb b/app/models/concerns/sortable.rb
index b9a2d812edd..a155a064032 100644
--- a/app/models/concerns/sortable.rb
+++ b/app/models/concerns/sortable.rb
@@ -39,12 +39,12 @@ module Sortable
private
def highest_label_priority(target_type_column: nil, target_type: nil, target_column:, project_column:, excluded_labels: [])
- query = Label.select(LabelPriority.arel_table[:priority].minimum).
- left_join_priorities.
- joins(:label_links).
- where("label_priorities.project_id = #{project_column}").
- where("label_links.target_id = #{target_column}").
- reorder(nil)
+ query = Label.select(LabelPriority.arel_table[:priority].minimum)
+ .left_join_priorities
+ .joins(:label_links)
+ .where("label_priorities.project_id = #{project_column}")
+ .where("label_links.target_id = #{target_column}")
+ .reorder(nil)
query =
if target_type_column
diff --git a/app/models/concerns/subscribable.rb b/app/models/concerns/subscribable.rb
index 83daa9b1a64..f60a0f8f438 100644
--- a/app/models/concerns/subscribable.rb
+++ b/app/models/concerns/subscribable.rb
@@ -27,16 +27,16 @@ module Subscribable
end
def subscribers(project)
- subscriptions_available(project).
- where(subscribed: true).
- map(&:user)
+ subscriptions_available(project)
+ .where(subscribed: true)
+ .map(&:user)
end
def toggle_subscription(user, project = nil)
unsubscribe_from_other_levels(user, project)
- find_or_initialize_subscription(user, project).
- update(subscribed: !subscribed?(user, project))
+ find_or_initialize_subscription(user, project)
+ .update(subscribed: !subscribed?(user, project))
end
def subscribe(user, project = nil)
@@ -69,14 +69,14 @@ module Subscribable
end
def find_or_initialize_subscription(user, project)
- subscriptions.
- find_or_initialize_by(user_id: user.id, project_id: project.try(:id))
+ subscriptions
+ .find_or_initialize_by(user_id: user.id, project_id: project.try(:id))
end
def subscriptions_available(project)
t = Subscription.arel_table
- subscriptions.
- where(t[:project_id].eq(nil).or(t[:project_id].eq(project.try(:id))))
+ subscriptions
+ .where(t[:project_id].eq(nil).or(t[:project_id].eq(project.try(:id))))
end
end
diff --git a/app/models/deployment.rb b/app/models/deployment.rb
index 00bf0c118ae..056c49e7162 100644
--- a/app/models/deployment.rb
+++ b/app/models/deployment.rb
@@ -58,10 +58,10 @@ class Deployment < ActiveRecord::Base
def update_merge_request_metrics!
return unless environment.update_merge_request_metrics?
- merge_requests = project.merge_requests.
- joins(:metrics).
- where(target_branch: self.ref, merge_request_metrics: { first_deployed_to_production_at: nil }).
- where("merge_request_metrics.merged_at <= ?", self.created_at)
+ merge_requests = project.merge_requests
+ .joins(:metrics)
+ .where(target_branch: self.ref, merge_request_metrics: { first_deployed_to_production_at: nil })
+ .where("merge_request_metrics.merged_at <= ?", self.created_at)
if previous_deployment
merge_requests = merge_requests.where("merge_request_metrics.merged_at >= ?", previous_deployment.created_at)
@@ -76,17 +76,17 @@ class Deployment < ActiveRecord::Base
merge_requests.map(&:id)
end
- MergeRequest::Metrics.
- where(merge_request_id: merge_request_ids, first_deployed_to_production_at: nil).
- update_all(first_deployed_to_production_at: self.created_at)
+ MergeRequest::Metrics
+ .where(merge_request_id: merge_request_ids, first_deployed_to_production_at: nil)
+ .update_all(first_deployed_to_production_at: self.created_at)
end
def previous_deployment
@previous_deployment ||=
- project.deployments.joins(:environment).
- where(environments: { name: self.environment.name }, ref: self.ref).
- where.not(id: self.id).
- take
+ project.deployments.joins(:environment)
+ .where(environments: { name: self.environment.name }, ref: self.ref)
+ .where.not(id: self.id)
+ .take
end
def stop_action
diff --git a/app/models/environment.rb b/app/models/environment.rb
index b391a487b30..7ad36f1d80c 100644
--- a/app/models/environment.rb
+++ b/app/models/environment.rb
@@ -40,9 +40,9 @@ class Environment < ActiveRecord::Base
scope :stopped, -> { with_state(:stopped) }
scope :order_by_last_deployed_at, -> do
max_deployment_id_sql =
- Deployment.select(Deployment.arel_table[:id].maximum).
- where(Deployment.arel_table[:environment_id].eq(arel_table[:id])).
- to_sql
+ Deployment.select(Deployment.arel_table[:id].maximum)
+ .where(Deployment.arel_table[:environment_id].eq(arel_table[:id]))
+ .to_sql
order(Gitlab::Database.nulls_first_order("(#{max_deployment_id_sql})", 'ASC'))
end
diff --git a/app/models/event.rb b/app/models/event.rb
index fad6ff03927..29bc141c5cd 100644
--- a/app/models/event.rb
+++ b/app/models/event.rb
@@ -376,9 +376,9 @@ class Event < ActiveRecord::Base
# At this point it's possible for multiple threads/processes to try to
# update the project. Only one query should actually perform the update,
# hence we add the extra WHERE clause for last_activity_at.
- Project.unscoped.where(id: project_id).
- where('last_activity_at <= ?', RESET_PROJECT_ACTIVITY_INTERVAL.ago).
- update_all(last_activity_at: created_at)
+ Project.unscoped.where(id: project_id)
+ .where('last_activity_at <= ?', RESET_PROJECT_ACTIVITY_INTERVAL.ago)
+ .update_all(last_activity_at: created_at)
end
def authored_by?(user)
@@ -392,7 +392,7 @@ class Event < ActiveRecord::Base
end
def set_last_repository_updated_at
- Project.unscoped.where(id: project_id).
- update_all(last_repository_updated_at: created_at)
+ Project.unscoped.where(id: project_id)
+ .update_all(last_repository_updated_at: created_at)
end
end
diff --git a/app/models/group.rb b/app/models/group.rb
index 5bb2cdc5eff..0b93460d473 100644
--- a/app/models/group.rb
+++ b/app/models/group.rb
@@ -206,8 +206,8 @@ class Group < Namespace
end
def refresh_members_authorized_projects
- UserProjectAccessChangedService.new(user_ids_for_project_authorizations).
- execute
+ UserProjectAccessChangedService.new(user_ids_for_project_authorizations)
+ .execute
end
def user_ids_for_project_authorizations
@@ -225,10 +225,10 @@ class Group < Namespace
def max_member_access_for_user(user)
return GroupMember::OWNER if user.admin?
- members_with_parents.
- where(user_id: user).
- reorder(access_level: :desc).
- first&.
+ members_with_parents
+ .where(user_id: user)
+ .reorder(access_level: :desc)
+ .first&.
access_level || GroupMember::NO_ACCESS
end
diff --git a/app/models/issue.rb b/app/models/issue.rb
index 693cc21bb40..3a9a6dba601 100644
--- a/app/models/issue.rb
+++ b/app/models/issue.rb
@@ -9,6 +9,9 @@ class Issue < ActiveRecord::Base
include Spammable
include FasterCacheKeys
include RelativePositioning
+ include IgnorableColumn
+
+ ignore_column :position
DueDateStruct = Struct.new(:title, :name).freeze
NoDueDate = DueDateStruct.new('No Due Date', '0').freeze
@@ -44,7 +47,7 @@ class Issue < ActiveRecord::Base
scope :created_after, -> (datetime) { where("created_at >= ?", datetime) }
- scope :include_associations, -> { includes(:labels, project: :namespace) }
+ scope :preload_associations, -> { preload(:labels, project: :namespace) }
after_save :expire_etag_cache
@@ -121,8 +124,8 @@ class Issue < ActiveRecord::Base
end
def self.order_by_position_and_priority
- order_labels_priority.
- reorder(Gitlab::Database.nulls_last_order('relative_position', 'ASC'),
+ order_labels_priority
+ .reorder(Gitlab::Database.nulls_last_order('relative_position', 'ASC'),
Gitlab::Database.nulls_last_order('highest_priority', 'ASC'),
"id DESC")
end
diff --git a/app/models/issue_collection.rb b/app/models/issue_collection.rb
index f0b7d9914c8..49f011c113f 100644
--- a/app/models/issue_collection.rb
+++ b/app/models/issue_collection.rb
@@ -17,9 +17,9 @@ class IssueCollection
# Given all the issue projects we get a list of projects that the current
# user has at least reporter access to.
- projects_with_reporter_access = user.
- projects_with_reporter_access_limited_to(project_ids).
- pluck(:id)
+ projects_with_reporter_access = user
+ .projects_with_reporter_access_limited_to(project_ids)
+ .pluck(:id)
collection.select do |issue|
if projects_with_reporter_access.include?(issue.project_id)
diff --git a/app/models/label.rb b/app/models/label.rb
index 955d6b4079b..ed6a8411da9 100644
--- a/app/models/label.rb
+++ b/app/models/label.rb
@@ -46,9 +46,9 @@ class Label < ActiveRecord::Base
labels = Label.arel_table
priorities = LabelPriority.arel_table
- label_priorities = labels.join(priorities, Arel::Nodes::OuterJoin).
- on(labels[:id].eq(priorities[:label_id]).and(priorities[:project_id].eq(project.id))).
- join_sources
+ label_priorities = labels.join(priorities, Arel::Nodes::OuterJoin)
+ .on(labels[:id].eq(priorities[:label_id]).and(priorities[:project_id].eq(project.id)))
+ .join_sources
joins(label_priorities).where(priorities[:priority].eq(nil))
end
@@ -57,9 +57,9 @@ class Label < ActiveRecord::Base
labels = Label.arel_table
priorities = LabelPriority.arel_table
- label_priorities = labels.join(priorities, Arel::Nodes::OuterJoin).
- on(labels[:id].eq(priorities[:label_id])).
- join_sources
+ label_priorities = labels.join(priorities, Arel::Nodes::OuterJoin)
+ .on(labels[:id].eq(priorities[:label_id]))
+ .join_sources
joins(label_priorities)
end
diff --git a/app/models/legacy_diff_note.rb b/app/models/legacy_diff_note.rb
index 7126de2d488..2d5909ab25e 100644
--- a/app/models/legacy_diff_note.rb
+++ b/app/models/legacy_diff_note.rb
@@ -42,7 +42,7 @@ class LegacyDiffNote < Note
end
def for_line?(line)
- !line.meta? && diff_file.line_code(line) == self.line_code
+ line.discussable? && diff_file.line_code(line) == self.line_code
end
def original_line_code
diff --git a/app/models/member.rb b/app/models/member.rb
index 788a32dd8e3..dc9247bc9a0 100644
--- a/app/models/member.rb
+++ b/app/models/member.rb
@@ -99,9 +99,9 @@ class Member < ActiveRecord::Base
users = User.arel_table
members = Member.arel_table
- member_users = members.join(users, Arel::Nodes::OuterJoin).
- on(members[:user_id].eq(users[:id])).
- join_sources
+ member_users = members.join(users, Arel::Nodes::OuterJoin)
+ .on(members[:user_id].eq(users[:id]))
+ .join_sources
joins(member_users)
end
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index dd155252ad5..f581a25f093 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -4,6 +4,9 @@ class MergeRequest < ActiveRecord::Base
include Noteable
include Referable
include Sortable
+ include IgnorableColumn
+
+ ignore_column :position
belongs_to :target_project, class_name: "Project"
belongs_to :source_project, class_name: "Project"
@@ -574,8 +577,8 @@ class MergeRequest < ActiveRecord::Base
messages = [title, description]
messages.concat(commits.map(&:safe_message)) if merge_request_diff
- Gitlab::ClosingIssueExtractor.new(project, current_user).
- closed_by_message(messages.join("\n"))
+ Gitlab::ClosingIssueExtractor.new(project, current_user)
+ .closed_by_message(messages.join("\n"))
else
[]
end
@@ -889,7 +892,7 @@ class MergeRequest < ActiveRecord::Base
!has_commits?
end
- def mergeable_with_slash_command?(current_user, autocomplete_precheck: false, last_diff_sha: nil)
+ def mergeable_with_quick_action?(current_user, autocomplete_precheck: false, last_diff_sha: nil)
return false unless can_be_merged_by?(current_user)
return true if autocomplete_precheck
diff --git a/app/models/merge_request_diff.rb b/app/models/merge_request_diff.rb
index 99dd2130188..f1ee4d3f7a9 100644
--- a/app/models/merge_request_diff.rb
+++ b/app/models/merge_request_diff.rb
@@ -10,6 +10,7 @@ class MergeRequestDiff < ActiveRecord::Base
VALID_CLASSES = [Hash, Rugged::Patch, Rugged::Diff::Delta].freeze
belongs_to :merge_request
+ has_many :merge_request_diff_files, -> { order(:merge_request_diff_id, :relative_order) }
serialize :st_commits # rubocop:disable Cop/ActiverecordSerialize
serialize :st_diffs # rubocop:disable Cop/ActiverecordSerialize
@@ -91,7 +92,7 @@ class MergeRequestDiff < ActiveRecord::Base
head_commit_sha).diffs(options)
else
@raw_diffs ||= {}
- @raw_diffs[options] ||= load_diffs(st_diffs, options)
+ @raw_diffs[options] ||= load_diffs(options)
end
end
@@ -253,24 +254,44 @@ class MergeRequestDiff < ActiveRecord::Base
update_columns_serialized(new_attributes)
end
- def dump_diffs(diffs)
- if diffs.respond_to?(:map)
- diffs.map(&:to_hash)
+ def create_merge_request_diff_files(diffs)
+ rows = diffs.map.with_index do |diff, index|
+ diff.to_hash.merge(
+ merge_request_diff_id: self.id,
+ relative_order: index
+ )
end
+
+ Gitlab::Database.bulk_insert('merge_request_diff_files', rows)
end
- def load_diffs(raw, options)
- if valid_raw_diff?(raw)
- if paths = options[:paths]
- raw = raw.select do |diff|
- paths.include?(diff[:old_path]) || paths.include?(diff[:new_path])
- end
- end
+ def load_diffs(options)
+ return Gitlab::Git::DiffCollection.new([]) unless diffs_from_database
- Gitlab::Git::DiffCollection.new(raw, options)
- else
- Gitlab::Git::DiffCollection.new([])
+ raw = diffs_from_database
+
+ if paths = options[:paths]
+ raw = raw.select do |diff|
+ paths.include?(diff[:old_path]) || paths.include?(diff[:new_path])
+ end
end
+
+ Gitlab::Git::DiffCollection.new(raw, options)
+ end
+
+ def diffs_from_database
+ return @diffs_from_database if defined?(@diffs_from_database)
+
+ @diffs_from_database =
+ if st_diffs.present?
+ if valid_raw_diff?(st_diffs)
+ st_diffs
+ end
+ elsif merge_request_diff_files.present?
+ merge_request_diff_files
+ .as_json(only: Gitlab::Git::Diff::SERIALIZE_KEYS)
+ .map(&:with_indifferent_access)
+ end
end
# Load diffs between branches related to current merge request diff from repo
@@ -285,11 +306,10 @@ class MergeRequestDiff < ActiveRecord::Base
new_attributes[:real_size] = diff_collection.real_size
if diff_collection.any?
- new_diffs = dump_diffs(diff_collection)
new_attributes[:state] = :collected
- end
- new_attributes[:st_diffs] = new_diffs || []
+ create_merge_request_diff_files(diff_collection)
+ end
# Set our state to 'overflow' to make the #empty? and #collected?
# methods (generated by StateMachine) return false.
diff --git a/app/models/merge_request_diff_file.rb b/app/models/merge_request_diff_file.rb
new file mode 100644
index 00000000000..598ebd4d829
--- /dev/null
+++ b/app/models/merge_request_diff_file.rb
@@ -0,0 +1,11 @@
+class MergeRequestDiffFile < ActiveRecord::Base
+ include Gitlab::EncodingHelper
+
+ belongs_to :merge_request_diff
+
+ def utf8_diff
+ return '' if diff.blank?
+
+ encode_utf8(diff) if diff.respond_to?(:encoding)
+ end
+end
diff --git a/app/models/merge_requests_closing_issues.rb b/app/models/merge_requests_closing_issues.rb
index daafb137be4..7f7c114803d 100644
--- a/app/models/merge_requests_closing_issues.rb
+++ b/app/models/merge_requests_closing_issues.rb
@@ -7,9 +7,9 @@ class MergeRequestsClosingIssues < ActiveRecord::Base
class << self
def count_for_collection(ids)
- group(:issue_id).
- where(issue_id: ids).
- pluck('issue_id', 'COUNT(*) as count')
+ group(:issue_id)
+ .where(issue_id: ids)
+ .pluck('issue_id', 'COUNT(*) as count')
end
end
end
diff --git a/app/models/milestone.rb b/app/models/milestone.rb
index b04bed4c014..d2e2749f70d 100644
--- a/app/models/milestone.rb
+++ b/app/models/milestone.rb
@@ -98,11 +98,11 @@ class Milestone < ActiveRecord::Base
if Gitlab::Database.postgresql?
rel.order(:project_id, :due_date).select('DISTINCT ON (project_id) id')
else
- rel.
- group(:project_id).
- having('due_date = MIN(due_date)').
- pluck(:id, :project_id, :due_date).
- map(&:first)
+ rel
+ .group(:project_id)
+ .having('due_date = MIN(due_date)')
+ .pluck(:id, :project_id, :due_date)
+ .map(&:first)
end
end
@@ -164,38 +164,6 @@ class Milestone < ActiveRecord::Base
write_attribute(:title, sanitize_title(value)) if value.present?
end
- # Sorts the issues for the given IDs.
- #
- # This method runs a single SQL query using a CASE statement to update the
- # position of all issues in the current milestone (scoped to the list of IDs).
- #
- # Given the ids [10, 20, 30] this method produces a SQL query something like
- # the following:
- #
- # UPDATE issues
- # SET position = CASE
- # WHEN id = 10 THEN 1
- # WHEN id = 20 THEN 2
- # WHEN id = 30 THEN 3
- # ELSE position
- # END
- # WHERE id IN (10, 20, 30);
- #
- # This method expects that the IDs given in `ids` are already Fixnums.
- def sort_issues(ids)
- pairs = []
-
- ids.each_with_index do |id, index|
- pairs << id
- pairs << index + 1
- end
-
- conditions = 'WHEN id = ? THEN ? ' * ids.length
-
- issues.where(id: ids).
- update_all(["position = CASE #{conditions} ELSE position END", *pairs])
- end
-
private
def milestone_format_reference(format = :iid)
diff --git a/app/models/namespace.rb b/app/models/namespace.rb
index b48d73dcae7..583d4fb5244 100644
--- a/app/models/namespace.rb
+++ b/app/models/namespace.rb
@@ -181,16 +181,16 @@ class Namespace < ActiveRecord::Base
def ancestors
return self.class.none unless parent_id
- Gitlab::GroupHierarchy.
- new(self.class.where(id: parent_id)).
- base_and_ancestors
+ Gitlab::GroupHierarchy
+ .new(self.class.where(id: parent_id))
+ .base_and_ancestors
end
# Returns all the descendants of the current namespace.
def descendants
- Gitlab::GroupHierarchy.
- new(self.class.where(parent_id: id)).
- base_and_descendants
+ Gitlab::GroupHierarchy
+ .new(self.class.where(parent_id: id))
+ .base_and_descendants
end
def user_ids_for_project_authorizations
@@ -253,10 +253,10 @@ class Namespace < ActiveRecord::Base
end
def refresh_access_of_projects_invited_groups
- Group.
- joins(project_group_links: :project).
- where(projects: { namespace_id: id }).
- find_each(&:refresh_members_authorized_projects)
+ Group
+ .joins(project_group_links: :project)
+ .where(projects: { namespace_id: id })
+ .find_each(&:refresh_members_authorized_projects)
end
def remove_exports!
diff --git a/app/models/note.rb b/app/models/note.rb
index 244bf169c29..ca6999427c0 100644
--- a/app/models/note.rb
+++ b/app/models/note.rb
@@ -32,7 +32,7 @@ class Note < ActiveRecord::Base
# Banzai::ObjectRenderer
attr_accessor :user_visible_reference_count
- # Attribute used to store the attributes that have ben changed by slash commands.
+ # Attribute used to store the attributes that have ben changed by quick actions.
attr_accessor :commands_changes
default_value_for :system, false
@@ -137,9 +137,9 @@ class Note < ActiveRecord::Base
end
def count_for_collection(ids, type)
- user.select('noteable_id', 'COUNT(*) as count').
- group(:noteable_id).
- where(noteable_type: type, noteable_id: ids)
+ user.select('noteable_id', 'COUNT(*) as count')
+ .group(:noteable_id)
+ .where(noteable_type: type, noteable_id: ids)
end
end
diff --git a/app/models/project.rb b/app/models/project.rb
index 4c394646787..2c2685875f8 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -244,8 +244,8 @@ class Project < ActiveRecord::Base
scope :inside_path, ->(path) do
# We need routes alias rs for JOIN so it does not conflict with
# includes(:route) which we use in ProjectsFinder.
- joins("INNER JOIN routes rs ON rs.source_id = projects.id AND rs.source_type = 'Project'").
- where('rs.path LIKE ?', "#{sanitize_sql_like(path)}/%")
+ joins("INNER JOIN routes rs ON rs.source_id = projects.id AND rs.source_type = 'Project'")
+ .where('rs.path LIKE ?', "#{sanitize_sql_like(path)}/%")
end
# "enabled" here means "not disabled". It includes private features!
@@ -266,20 +266,49 @@ class Project < ActiveRecord::Base
enum auto_cancel_pending_pipelines: { disabled: 0, enabled: 1 }
+ # Returns a collection of projects that is either public or visible to the
+ # logged in user.
+ def self.public_or_visible_to_user(user = nil)
+ if user
+ authorized = user
+ .project_authorizations
+ .select(1)
+ .where('project_authorizations.project_id = projects.id')
+
+ levels = Gitlab::VisibilityLevel.levels_for_user(user)
+
+ where('EXISTS (?) OR projects.visibility_level IN (?)', authorized, levels)
+ else
+ public_to_user
+ end
+ end
+
# project features may be "disabled", "internal" or "enabled". If "internal",
# they are only available to team members. This scope returns projects where
# the feature is either enabled, or internal with permission for the user.
+ #
+ # This method uses an optimised version of `with_feature_access_level` for
+ # logged in users to more efficiently get private projects with the given
+ # feature.
def self.with_feature_available_for_user(feature, user)
- return with_feature_enabled(feature) if user.try(:admin?)
+ visible = [nil, ProjectFeature::ENABLED]
- unconditional = with_feature_access_level(feature, [nil, ProjectFeature::ENABLED])
- return unconditional if user.nil?
+ if user&.admin?
+ with_feature_enabled(feature)
+ elsif user
+ column = ProjectFeature.quoted_access_level_column(feature)
- conditional = with_feature_access_level(feature, ProjectFeature::PRIVATE)
- authorized = user.authorized_projects.merge(conditional.reorder(nil))
+ authorized = user.project_authorizations.select(1)
+ .where('project_authorizations.project_id = projects.id')
- union = Gitlab::SQL::Union.new([unconditional.select(:id), authorized.select(:id)])
- where(arel_table[:id].in(Arel::Nodes::SqlLiteral.new(union.to_sql)))
+ with_project_feature
+ .where("#{column} IN (?) OR (#{column} = ? AND EXISTS (?))",
+ visible,
+ ProjectFeature::PRIVATE,
+ authorized)
+ else
+ with_feature_access_level(feature, visible)
+ end
end
scope :active, -> { joins(:issues, :notes, :merge_requests).order('issues.created_at, notes.created_at, merge_requests.created_at DESC') }
@@ -340,14 +369,14 @@ class Project < ActiveRecord::Base
# unscoping unnecessary conditions that'll be applied
# when executing `where("projects.id IN (#{union.to_sql})")`
projects = unscoped.select(:id).where(
- ptable[:path].matches(pattern).
- or(ptable[:name].matches(pattern)).
- or(ptable[:description].matches(pattern))
+ ptable[:path].matches(pattern)
+ .or(ptable[:name].matches(pattern))
+ .or(ptable[:description].matches(pattern))
)
- namespaces = unscoped.select(:id).
- joins(:namespace).
- where(ntable[:name].matches(pattern))
+ namespaces = unscoped.select(:id)
+ .joins(:namespace)
+ .where(ntable[:name].matches(pattern))
union = Gitlab::SQL::Union.new([projects, namespaces])
@@ -388,8 +417,8 @@ class Project < ActiveRecord::Base
end
def trending
- joins('INNER JOIN trending_projects ON projects.id = trending_projects.project_id').
- reorder('trending_projects.id ASC')
+ joins('INNER JOIN trending_projects ON projects.id = trending_projects.project_id')
+ .reorder('trending_projects.id ASC')
end
def cached_count
diff --git a/app/models/project_authorization.rb b/app/models/project_authorization.rb
index def09675253..73302207e6b 100644
--- a/app/models/project_authorization.rb
+++ b/app/models/project_authorization.rb
@@ -7,9 +7,9 @@ class ProjectAuthorization < ActiveRecord::Base
validates :user, uniqueness: { scope: [:project, :access_level] }, presence: true
def self.select_from_union(union)
- select(['project_id', 'MAX(access_level) AS access_level']).
- from("(#{union.to_sql}) #{ProjectAuthorization.table_name}").
- group(:project_id)
+ select(['project_id', 'MAX(access_level) AS access_level'])
+ .from("(#{union.to_sql}) #{ProjectAuthorization.table_name}")
+ .group(:project_id)
end
def self.insert_authorizations(rows, per_batch = 1000)
diff --git a/app/models/project_feature.rb b/app/models/project_feature.rb
index e3ef4919b28..dde2a11440d 100644
--- a/app/models/project_feature.rb
+++ b/app/models/project_feature.rb
@@ -27,6 +27,13 @@ class ProjectFeature < ActiveRecord::Base
"#{feature}_access_level".to_sym
end
+
+ def quoted_access_level_column(feature)
+ attribute = connection.quote_column_name(access_level_attribute(feature))
+ table = connection.quote_table_name(table_name)
+
+ "#{table}.#{attribute}"
+ end
end
# Default scopes force us to unscope here since a service may need to check
diff --git a/app/models/project_services/chat_message/pipeline_message.rb b/app/models/project_services/chat_message/pipeline_message.rb
index 3edc395033c..d63d4ec2b12 100644
--- a/app/models/project_services/chat_message/pipeline_message.rb
+++ b/app/models/project_services/chat_message/pipeline_message.rb
@@ -70,7 +70,7 @@ module ChatMessage
end
def branch_link
- "`[#{ref}](#{branch_url})`"
+ "[#{ref}](#{branch_url})"
end
def project_link
diff --git a/app/models/project_services/chat_message/push_message.rb b/app/models/project_services/chat_message/push_message.rb
index 04a59d559ca..c52dd6ef8ef 100644
--- a/app/models/project_services/chat_message/push_message.rb
+++ b/app/models/project_services/chat_message/push_message.rb
@@ -61,7 +61,7 @@ module ChatMessage
end
def removed_branch_message
- "#{user_name} removed #{ref_type} `#{ref}` from #{project_link}"
+ "#{user_name} removed #{ref_type} #{ref} from #{project_link}"
end
def push_message
@@ -102,7 +102,7 @@ module ChatMessage
end
def branch_link
- "`[#{ref}](#{branch_url})`"
+ "[#{ref}](#{branch_url})"
end
def project_link
diff --git a/app/models/project_services/mattermost_slash_commands_service.rb b/app/models/project_services/mattermost_slash_commands_service.rb
index 56f42d63b2d..4d2037286a2 100644
--- a/app/models/project_services/mattermost_slash_commands_service.rb
+++ b/app/models/project_services/mattermost_slash_commands_service.rb
@@ -1,4 +1,4 @@
-class MattermostSlashCommandsService < ChatSlashCommandsService
+class MattermostSlashCommandsService < SlashCommandsService
include TriggersHelper
prop_accessor :token
@@ -20,8 +20,8 @@ class MattermostSlashCommandsService < ChatSlashCommandsService
end
def configure(user, params)
- token = Mattermost::Command.new(user).
- create(command(params))
+ token = Mattermost::Command.new(user)
+ .create(command(params))
update(active: true, token: token) if token
rescue Mattermost::Error => e
diff --git a/app/models/project_services/slack_slash_commands_service.rb b/app/models/project_services/slack_slash_commands_service.rb
index 2182c1c7e4b..1c3892a3f75 100644
--- a/app/models/project_services/slack_slash_commands_service.rb
+++ b/app/models/project_services/slack_slash_commands_service.rb
@@ -1,4 +1,4 @@
-class SlackSlashCommandsService < ChatSlashCommandsService
+class SlackSlashCommandsService < SlashCommandsService
include TriggersHelper
def title
diff --git a/app/models/project_services/chat_slash_commands_service.rb b/app/models/project_services/slash_commands_service.rb
index 8b5bc24fd3c..4592cb747a0 100644
--- a/app/models/project_services/chat_slash_commands_service.rb
+++ b/app/models/project_services/slash_commands_service.rb
@@ -1,6 +1,6 @@
# Base class for Chat services
# This class is not meant to be used directly, but only to inherrit from.
-class ChatSlashCommandsService < Service
+class SlashCommandsService < Service
default_value_for :category, 'chat'
prop_accessor :token
@@ -33,10 +33,10 @@ class ChatSlashCommandsService < Service
user = find_chat_user(params)
if user
- Gitlab::ChatCommands::Command.new(project, user, params).execute
+ Gitlab::SlashCommands::Command.new(project, user, params).execute
else
url = authorize_chat_name_url(params)
- Gitlab::ChatCommands::Presenters::Access.new(url).authorize
+ Gitlab::SlashCommands::Presenters::Access.new(url).authorize
end
end
diff --git a/app/models/project_team.rb b/app/models/project_team.rb
index e1cc56551ba..674eacd28e8 100644
--- a/app/models/project_team.rb
+++ b/app/models/project_team.rb
@@ -172,10 +172,10 @@ class ProjectTeam
return access if user_ids.empty?
- users_access = project.project_authorizations.
- where(user: user_ids).
- group(:user_id).
- maximum(:access_level)
+ users_access = project.project_authorizations
+ .where(user: user_ids)
+ .group(:user_id)
+ .maximum(:access_level)
access.merge!(users_access)
diff --git a/app/models/repository.rb b/app/models/repository.rb
index 7460515fea8..c67475357d9 100644
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -241,11 +241,11 @@ class Repository
cache.fetch(:"diverging_commit_counts_#{branch.name}") do
# Rugged seems to throw a `ReferenceError` when given branch_names rather
# than SHA-1 hashes
- number_commits_behind = raw_repository.
- count_commits_between(branch.dereferenced_target.sha, root_ref_hash)
+ number_commits_behind = raw_repository
+ .count_commits_between(branch.dereferenced_target.sha, root_ref_hash)
- number_commits_ahead = raw_repository.
- count_commits_between(root_ref_hash, branch.dereferenced_target.sha)
+ number_commits_ahead = raw_repository
+ .count_commits_between(root_ref_hash, branch.dereferenced_target.sha)
{ behind: number_commits_behind, ahead: number_commits_ahead }
end
diff --git a/app/models/todo.rb b/app/models/todo.rb
index 696d139af74..7af54b2beb2 100644
--- a/app/models/todo.rb
+++ b/app/models/todo.rb
@@ -70,9 +70,9 @@ class Todo < ActiveRecord::Base
highest_priority = highest_label_priority(params).to_sql
- select("#{table_name}.*, (#{highest_priority}) AS highest_priority").
- order(Gitlab::Database.nulls_last_order('highest_priority', 'ASC')).
- order('todos.created_at')
+ select("#{table_name}.*, (#{highest_priority}) AS highest_priority")
+ .order(Gitlab::Database.nulls_last_order('highest_priority', 'ASC'))
+ .order('todos.created_at')
end
end
diff --git a/app/models/user.rb b/app/models/user.rb
index 5d128e4b390..954a30155f7 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -139,21 +139,21 @@ class User < ActiveRecord::Base
presence: true,
uniqueness: { case_sensitive: false }
- validate :namespace_uniq, if: ->(user) { user.username_changed? }
+ validate :namespace_uniq, if: :username_changed?
validate :avatar_type, if: ->(user) { user.avatar.present? && user.avatar_changed? }
- validate :unique_email, if: ->(user) { user.email_changed? }
- validate :owns_notification_email, if: ->(user) { user.notification_email_changed? }
- validate :owns_public_email, if: ->(user) { user.public_email_changed? }
+ validate :unique_email, if: :email_changed?
+ validate :owns_notification_email, if: :notification_email_changed?
+ validate :owns_public_email, if: :public_email_changed?
validate :signup_domain_valid?, on: :create, if: ->(user) { !user.created_by_id }
validates :avatar, file_size: { maximum: 200.kilobytes.to_i }
before_validation :sanitize_attrs
- before_validation :set_notification_email, if: ->(user) { user.email_changed? }
- before_validation :set_public_email, if: ->(user) { user.public_email_changed? }
+ before_validation :set_notification_email, if: :email_changed?
+ before_validation :set_public_email, if: :public_email_changed?
- after_update :update_emails_with_primary_email, if: ->(user) { user.email_changed? }
+ after_update :update_emails_with_primary_email, if: :email_changed?
before_save :ensure_authentication_token, :ensure_incoming_email_token
- before_save :ensure_external_user_rights
+ before_save :ensure_user_rights_and_limits, if: :external_changed?
after_save :ensure_namespace_correct
after_initialize :set_projects_limit
after_destroy :post_destroy_hook
@@ -223,13 +223,13 @@ class User < ActiveRecord::Base
scope :order_oldest_sign_in, -> { reorder(Gitlab::Database.nulls_last_order('last_sign_in_at', 'ASC')) }
def self.with_two_factor
- joins("LEFT OUTER JOIN u2f_registrations AS u2f ON u2f.user_id = users.id").
- where("u2f.id IS NOT NULL OR otp_required_for_login = ?", true).distinct(arel_table[:id])
+ joins("LEFT OUTER JOIN u2f_registrations AS u2f ON u2f.user_id = users.id")
+ .where("u2f.id IS NOT NULL OR otp_required_for_login = ?", true).distinct(arel_table[:id])
end
def self.without_two_factor
- joins("LEFT OUTER JOIN u2f_registrations AS u2f ON u2f.user_id = users.id").
- where("u2f.id IS NULL AND otp_required_for_login = ?", false)
+ joins("LEFT OUTER JOIN u2f_registrations AS u2f ON u2f.user_id = users.id")
+ .where("u2f.id IS NULL AND otp_required_for_login = ?", false)
end
#
@@ -300,9 +300,9 @@ class User < ActiveRecord::Base
pattern = "%#{query}%"
where(
- table[:name].matches(pattern).
- or(table[:email].matches(pattern)).
- or(table[:username].matches(pattern))
+ table[:name].matches(pattern)
+ .or(table[:email].matches(pattern))
+ .or(table[:username].matches(pattern))
)
end
@@ -317,10 +317,10 @@ class User < ActiveRecord::Base
matched_by_emails_user_ids = email_table.project(email_table[:user_id]).where(email_table[:email].matches(pattern))
where(
- table[:name].matches(pattern).
- or(table[:email].matches(pattern)).
- or(table[:username].matches(pattern)).
- or(table[:id].in(matched_by_emails_user_ids))
+ table[:name].matches(pattern)
+ .or(table[:email].matches(pattern))
+ .or(table[:username].matches(pattern))
+ .or(table[:id].in(matched_by_emails_user_ids))
)
end
@@ -503,8 +503,8 @@ class User < ActiveRecord::Base
# Returns the groups a user has access to
def authorized_groups
- union = Gitlab::SQL::Union.
- new([groups.select(:id), authorized_projects.select(:namespace_id)])
+ union = Gitlab::SQL::Union
+ .new([groups.select(:id), authorized_projects.select(:namespace_id)])
Group.where("namespaces.id IN (#{union.to_sql})")
end
@@ -533,8 +533,8 @@ class User < ActiveRecord::Base
projects = super()
if min_access_level
- projects = projects.
- where('project_authorizations.access_level >= ?', min_access_level)
+ projects = projects
+ .where('project_authorizations.access_level >= ?', min_access_level)
end
projects
@@ -619,9 +619,9 @@ class User < ActiveRecord::Base
next unless project
if project.repository.branch_exists?(event.branch_name)
- merge_requests = MergeRequest.where("created_at >= ?", event.created_at).
- where(source_project_id: project.id,
- source_branch: event.branch_name)
+ merge_requests = MergeRequest.where("created_at >= ?", event.created_at)
+ .where(source_project_id: project.id,
+ source_branch: event.branch_name)
merge_requests.empty?
end
end
@@ -832,8 +832,8 @@ class User < ActiveRecord::Base
def toggle_star(project)
UsersStarProject.transaction do
- user_star_project = users_star_projects.
- where(project: project, user: self).lock(true).first
+ user_star_project = users_star_projects
+ .where(project: project, user: self).lock(true).first
if user_star_project
user_star_project.destroy
@@ -869,11 +869,11 @@ class User < ActiveRecord::Base
# ms on a database with a similar size to GitLab.com's database. On the other
# hand, using a subquery means we can get the exact same data in about 40 ms.
def contributed_projects
- events = Event.select(:project_id).
- contributions.where(author_id: self).
- where("created_at > ?", Time.now - 1.year).
- uniq.
- reorder(nil)
+ events = Event.select(:project_id)
+ .contributions.where(author_id: self)
+ .where("created_at > ?", Time.now - 1.year)
+ .uniq
+ .reorder(nil)
Project.where(id: events)
end
@@ -884,9 +884,9 @@ class User < ActiveRecord::Base
def ci_authorized_runners
@ci_authorized_runners ||= begin
- runner_ids = Ci::RunnerProject.
- where("ci_runner_projects.project_id IN (#{ci_projects_union.to_sql})").
- select(:runner_id)
+ runner_ids = Ci::RunnerProject
+ .where("ci_runner_projects.project_id IN (#{ci_projects_union.to_sql})")
+ .select(:runner_id)
Ci::Runner.specific.where(id: runner_ids)
end
end
@@ -1033,11 +1033,14 @@ class User < ActiveRecord::Base
super
end
- def ensure_external_user_rights
- return unless external?
-
- self.can_create_group = false
- self.projects_limit = 0
+ def ensure_user_rights_and_limits
+ if external?
+ self.can_create_group = false
+ self.projects_limit = 0
+ else
+ self.can_create_group = gitlab_config.default_can_create_group
+ self.projects_limit = current_application_settings.default_projects_limit
+ end
end
def signup_domain_valid?
diff --git a/app/models/wiki_page.rb b/app/models/wiki_page.rb
index c771c22f46a..224eb3cd4d0 100644
--- a/app/models/wiki_page.rb
+++ b/app/models/wiki_page.rb
@@ -22,16 +22,16 @@ class WikiPage
def self.group_by_directory(pages)
return [] if pages.blank?
- pages.sort_by { |page| [page.directory, page.slug] }.
- group_by(&:directory).
- map do |dir, pages|
+ pages.sort_by { |page| [page.directory, page.slug] }
+ .group_by(&:directory)
+ .map do |dir, pages|
if dir.present?
WikiDirectory.new(dir, pages)
else
pages
end
- end.
- flatten
+ end
+ .flatten
end
def self.unhyphenize(name)
diff --git a/app/policies/global_policy.rb b/app/policies/global_policy.rb
index 4757ba71680..2683aaad981 100644
--- a/app/policies/global_policy.rb
+++ b/app/policies/global_policy.rb
@@ -10,7 +10,7 @@ class GlobalPolicy < BasePolicy
can! :access_api
can! :access_git
can! :receive_notifications
- can! :use_slash_commands
+ can! :use_quick_actions
end
end
end
diff --git a/app/serializers/issuable_entity.rb b/app/serializers/issuable_entity.rb
index 65b204d4dd2..bd5211b8e58 100644
--- a/app/serializers/issuable_entity.rb
+++ b/app/serializers/issuable_entity.rb
@@ -5,7 +5,6 @@ class IssuableEntity < Grape::Entity
expose :description
expose :lock_version
expose :milestone_id
- expose :position
expose :state
expose :title
expose :updated_by_id
diff --git a/app/services/ci/create_pipeline_service.rb b/app/services/ci/create_pipeline_service.rb
index 769749c9925..942145c4a8c 100644
--- a/app/services/ci/create_pipeline_service.rb
+++ b/app/services/ci/create_pipeline_service.rb
@@ -67,8 +67,8 @@ module Ci
def update_merge_requests_head_pipeline
return unless pipeline.latest?
- MergeRequest.where(source_project: @pipeline.project, source_branch: @pipeline.ref).
- update_all(head_pipeline_id: @pipeline.id)
+ MergeRequest.where(source_project: @pipeline.project, source_branch: @pipeline.ref)
+ .update_all(head_pipeline_id: @pipeline.id)
end
def skip_ci?
diff --git a/app/services/ci/create_trigger_request_service.rb b/app/services/ci/create_trigger_request_service.rb
index beb27a5a597..cf3d4aee2bc 100644
--- a/app/services/ci/create_trigger_request_service.rb
+++ b/app/services/ci/create_trigger_request_service.rb
@@ -3,8 +3,8 @@ module Ci
def execute(project, trigger, ref, variables = nil)
trigger_request = trigger.trigger_requests.create(variables: variables)
- pipeline = Ci::CreatePipelineService.new(project, trigger.owner, ref: ref).
- execute(:trigger, ignore_skip_ci: true, trigger_request: trigger_request)
+ pipeline = Ci::CreatePipelineService.new(project, trigger.owner, ref: ref)
+ .execute(:trigger, ignore_skip_ci: true, trigger_request: trigger_request)
trigger_request if pipeline.persisted?
end
diff --git a/app/services/ci/register_job_service.rb b/app/services/ci/register_job_service.rb
index d6a4280ce4c..af84d4c7427 100644
--- a/app/services/ci/register_job_service.rb
+++ b/app/services/ci/register_job_service.rb
@@ -54,15 +54,15 @@ module Ci
def builds_for_shared_runner
new_builds.
# don't run projects which have not enabled shared runners and builds
- joins(:project).where(projects: { shared_runners_enabled: true }).
- joins('LEFT JOIN project_features ON ci_builds.project_id = project_features.project_id').
- where('project_features.builds_access_level IS NULL or project_features.builds_access_level > 0').
+ joins(:project).where(projects: { shared_runners_enabled: true })
+ .joins('LEFT JOIN project_features ON ci_builds.project_id = project_features.project_id')
+ .where('project_features.builds_access_level IS NULL or project_features.builds_access_level > 0').
# Implement fair scheduling
# this returns builds that are ordered by number of running builds
# we prefer projects that don't use shared runners at all
- joins("LEFT JOIN (#{running_builds_for_shared_runners.to_sql}) AS project_builds ON ci_builds.project_id=project_builds.project_id").
- order('COALESCE(project_builds.running_builds, 0) ASC', 'ci_builds.id ASC')
+ joins("LEFT JOIN (#{running_builds_for_shared_runners.to_sql}) AS project_builds ON ci_builds.project_id=project_builds.project_id")
+ .order('COALESCE(project_builds.running_builds, 0) ASC', 'ci_builds.id ASC')
end
def builds_for_specific_runner
@@ -70,8 +70,8 @@ module Ci
end
def running_builds_for_shared_runners
- Ci::Build.running.where(runner: Ci::Runner.shared).
- group(:project_id).select(:project_id, 'count(*) AS running_builds')
+ Ci::Build.running.where(runner: Ci::Runner.shared)
+ .group(:project_id).select(:project_id, 'count(*) AS running_builds')
end
def new_builds
diff --git a/app/services/concerns/issues/resolve_discussions.rb b/app/services/concerns/issues/resolve_discussions.rb
index 910a2a15e5d..7d45b4aa26a 100644
--- a/app/services/concerns/issues/resolve_discussions.rb
+++ b/app/services/concerns/issues/resolve_discussions.rb
@@ -10,9 +10,9 @@ module Issues
def merge_request_to_resolve_discussions_of
return @merge_request_to_resolve_discussions_of if defined?(@merge_request_to_resolve_discussions_of)
- @merge_request_to_resolve_discussions_of = MergeRequestsFinder.new(current_user, project_id: project.id).
- execute.
- find_by(iid: merge_request_to_resolve_discussions_of_iid)
+ @merge_request_to_resolve_discussions_of = MergeRequestsFinder.new(current_user, project_id: project.id)
+ .execute
+ .find_by(iid: merge_request_to_resolve_discussions_of_iid)
end
def discussions_to_resolve
diff --git a/app/services/create_deployment_service.rb b/app/services/create_deployment_service.rb
index 46823418bb0..63b85c3de7d 100644
--- a/app/services/create_deployment_service.rb
+++ b/app/services/create_deployment_service.rb
@@ -2,7 +2,7 @@ class CreateDeploymentService
attr_reader :job
delegate :expanded_environment_name,
- :environment_url,
+ :variables,
:project,
to: :job
@@ -14,7 +14,8 @@ class CreateDeploymentService
return unless executable?
ActiveRecord::Base.transaction do
- environment.external_url = environment_url if environment_url
+ environment.external_url = expanded_environment_url if
+ expanded_environment_url
environment.fire_state_event(action)
return unless environment.save
@@ -49,6 +50,17 @@ class CreateDeploymentService
@environment_options ||= job.options&.dig(:environment) || {}
end
+ def expanded_environment_url
+ return @expanded_environment_url if defined?(@expanded_environment_url)
+
+ @expanded_environment_url =
+ ExpandVariables.expand(environment_url, variables) if environment_url
+ end
+
+ def environment_url
+ environment_options[:url]
+ end
+
def on_stop
environment_options[:on_stop]
end
diff --git a/app/services/files/update_service.rb b/app/services/files/update_service.rb
index f23a9f6d57c..bcca1386bed 100644
--- a/app/services/files/update_service.rb
+++ b/app/services/files/update_service.rb
@@ -28,8 +28,8 @@ module Files
end
def last_commit
- @last_commit ||= Gitlab::Git::Commit.
- last_for_path(@start_project.repository, @start_branch, @file_path)
+ @last_commit ||= Gitlab::Git::Commit
+ .last_for_path(@start_project.repository, @start_branch, @file_path)
end
def validate!
diff --git a/app/services/git_push_service.rb b/app/services/git_push_service.rb
index fb1d4aed58b..20d1fb29289 100644
--- a/app/services/git_push_service.rb
+++ b/app/services/git_push_service.rb
@@ -86,8 +86,8 @@ class GitPushService < BaseService
push_commits.last(PROCESS_COMMIT_LIMIT).each do |commit|
if commit.matches_cross_reference_regex?
- ProcessCommitWorker.
- perform_async(project.id, current_user.id, commit.to_hash, default)
+ ProcessCommitWorker
+ .perform_async(project.id, current_user.id, commit.to_hash, default)
end
end
end
diff --git a/app/services/issuable_base_service.rb b/app/services/issuable_base_service.rb
index cd4d180824f..8dd0846f3bc 100644
--- a/app/services/issuable_base_service.rb
+++ b/app/services/issuable_base_service.rb
@@ -142,10 +142,10 @@ class IssuableBaseService < BaseService
LabelsFinder.new(current_user, project_id: @project.id).execute
end
- def merge_slash_commands_into_params!(issuable)
+ def merge_quick_actions_into_params!(issuable)
description, command_params =
- SlashCommands::InterpretService.new(project, current_user).
- execute(params[:description], issuable)
+ QuickActions::InterpretService.new(project, current_user)
+ .execute(params[:description], issuable)
# Avoid a description already set on an issuable to be overwritten by a nil
params[:description] = description if params.key?(:description)
@@ -162,7 +162,7 @@ class IssuableBaseService < BaseService
end
def create(issuable)
- merge_slash_commands_into_params!(issuable)
+ merge_quick_actions_into_params!(issuable)
filter_params(issuable)
params.delete(:state_event)
diff --git a/app/services/issues/create_service.rb b/app/services/issues/create_service.rb
index 3cf4b82b9f2..718a7ac1f22 100644
--- a/app/services/issues/create_service.rb
+++ b/app/services/issues/create_service.rb
@@ -30,8 +30,8 @@ module Issues
Discussions::ResolveService.new(project, current_user,
merge_request: merge_request_to_resolve_discussions_of,
- follow_up_issue: issue).
- execute(discussions_to_resolve)
+ follow_up_issue: issue)
+ .execute(discussions_to_resolve)
end
private
diff --git a/app/services/labels/promote_service.rb b/app/services/labels/promote_service.rb
index 76d0ba67b07..43b539ded53 100644
--- a/app/services/labels/promote_service.rb
+++ b/app/services/labels/promote_service.rb
@@ -26,29 +26,29 @@ module Labels
private
def label_ids_for_merge(new_label)
- LabelsFinder.
- new(current_user, title: new_label.title, group_id: project.group.id).
- execute(skip_authorization: true).
- where.not(id: new_label).
- select(:id) # Can't use pluck() to avoid object-creation because of the batching
+ LabelsFinder
+ .new(current_user, title: new_label.title, group_id: project.group.id)
+ .execute(skip_authorization: true)
+ .where.not(id: new_label)
+ .select(:id) # Can't use pluck() to avoid object-creation because of the batching
end
def update_issuables(new_label, label_ids)
- LabelLink.
- where(label: label_ids).
- update_all(label_id: new_label)
+ LabelLink
+ .where(label: label_ids)
+ .update_all(label_id: new_label)
end
def update_issue_board_lists(new_label, label_ids)
- List.
- where(label: label_ids).
- update_all(label_id: new_label)
+ List
+ .where(label: label_ids)
+ .update_all(label_id: new_label)
end
def update_priorities(new_label, label_ids)
- LabelPriority.
- where(label: label_ids).
- update_all(label_id: new_label)
+ LabelPriority
+ .where(label: label_ids)
+ .update_all(label_id: new_label)
end
def update_project_labels(label_ids)
diff --git a/app/services/labels/transfer_service.rb b/app/services/labels/transfer_service.rb
index 514679ed29d..d2ece354efc 100644
--- a/app/services/labels/transfer_service.rb
+++ b/app/services/labels/transfer_service.rb
@@ -41,16 +41,16 @@ module Labels
end
def group_labels_applied_to_issues
- Label.joins(:issues).
- where(
+ Label.joins(:issues)
+ .where(
issues: { project_id: project.id },
labels: { type: 'GroupLabel', group_id: old_group.id }
)
end
def group_labels_applied_to_merge_requests
- Label.joins(:merge_requests).
- where(
+ Label.joins(:merge_requests)
+ .where(
merge_requests: { target_project_id: project.id },
labels: { type: 'GroupLabel', group_id: old_group.id }
)
@@ -64,15 +64,15 @@ module Labels
end
def update_label_links(labels, old_label_id:, new_label_id:)
- LabelLink.joins(:label).
- merge(labels).
- where(label_id: old_label_id).
- update_all(label_id: new_label_id)
+ LabelLink.joins(:label)
+ .merge(labels)
+ .where(label_id: old_label_id)
+ .update_all(label_id: new_label_id)
end
def update_label_priorities(old_label_id:, new_label_id:)
- LabelPriority.where(project_id: project.id, label_id: old_label_id).
- update_all(label_id: new_label_id)
+ LabelPriority.where(project_id: project.id, label_id: old_label_id)
+ .update_all(label_id: new_label_id)
end
end
end
diff --git a/app/services/members/authorized_destroy_service.rb b/app/services/members/authorized_destroy_service.rb
index f846d72498f..de3a252d6c6 100644
--- a/app/services/members/authorized_destroy_service.rb
+++ b/app/services/members/authorized_destroy_service.rb
@@ -26,30 +26,30 @@ module Members
def unassign_issues_and_merge_requests(member)
if member.is_a?(GroupMember)
- issues = Issue.unscoped.select(1).
- joins(:project).
- where('issues.id = issue_assignees.issue_id AND projects.namespace_id = ?', member.source_id)
+ issues = Issue.unscoped.select(1)
+ .joins(:project)
+ .where('issues.id = issue_assignees.issue_id AND projects.namespace_id = ?', member.source_id)
# DELETE FROM issue_assignees WHERE user_id = X AND EXISTS (...)
- IssueAssignee.unscoped.
- where('user_id = :user_id AND EXISTS (:sub)', user_id: member.user_id, sub: issues).
- delete_all
+ IssueAssignee.unscoped
+ .where('user_id = :user_id AND EXISTS (:sub)', user_id: member.user_id, sub: issues)
+ .delete_all
- MergeRequestsFinder.new(user, group_id: member.source_id, assignee_id: member.user_id).
- execute.
- update_all(assignee_id: nil)
+ MergeRequestsFinder.new(user, group_id: member.source_id, assignee_id: member.user_id)
+ .execute
+ .update_all(assignee_id: nil)
else
project = member.source
# SELECT 1 FROM issues WHERE issues.id = issue_assignees.issue_id AND issues.project_id = X
- issues = Issue.unscoped.select(1).
- where('issues.id = issue_assignees.issue_id').
- where(project_id: project.id)
+ issues = Issue.unscoped.select(1)
+ .where('issues.id = issue_assignees.issue_id')
+ .where(project_id: project.id)
# DELETE FROM issue_assignees WHERE user_id = X AND EXISTS (...)
- IssueAssignee.unscoped.
- where('user_id = :user_id AND EXISTS (:sub)', user_id: member.user_id, sub: issues).
- delete_all
+ IssueAssignee.unscoped
+ .where('user_id = :user_id AND EXISTS (:sub)', user_id: member.user_id, sub: issues)
+ .delete_all
project.merge_requests.opened.assigned_to(member.user).update_all(assignee_id: nil)
end
diff --git a/app/services/merge_requests/conflicts/resolve_service.rb b/app/services/merge_requests/conflicts/resolve_service.rb
index c2c335b8461..6b6e231f4f9 100644
--- a/app/services/merge_requests/conflicts/resolve_service.rb
+++ b/app/services/merge_requests/conflicts/resolve_service.rb
@@ -27,10 +27,10 @@ module MergeRequests
tree: merge_index.write_tree(rugged)
}
- conflicts_for_resolution.
- project.
- repository.
- resolve_conflicts(current_user, merge_request.source_branch, commit_params)
+ conflicts_for_resolution
+ .project
+ .repository
+ .resolve_conflicts(current_user, merge_request.source_branch, commit_params)
end
end
diff --git a/app/services/merge_requests/merge_service.rb b/app/services/merge_requests/merge_service.rb
index fac3ac7a4c7..b247cb89e5e 100644
--- a/app/services/merge_requests/merge_service.rb
+++ b/app/services/merge_requests/merge_service.rb
@@ -61,8 +61,8 @@ module MergeRequests
MergeRequests::PostMergeService.new(project, current_user).execute(merge_request)
if params[:should_remove_source_branch].present? || @merge_request.force_remove_source_branch?
- DeleteBranchService.new(@merge_request.source_project, branch_deletion_user).
- execute(merge_request.source_branch)
+ DeleteBranchService.new(@merge_request.source_project, branch_deletion_user)
+ .execute(merge_request.source_branch)
end
end
diff --git a/app/services/merge_requests/refresh_service.rb b/app/services/merge_requests/refresh_service.rb
index 81d217929d5..e0e7c43f802 100644
--- a/app/services/merge_requests/refresh_service.rb
+++ b/app/services/merge_requests/refresh_service.rb
@@ -43,9 +43,9 @@ module MergeRequests
end
filter_merge_requests(merge_requests).each do |merge_request|
- MergeRequests::PostMergeService.
- new(merge_request.target_project, @current_user).
- execute(merge_request)
+ MergeRequests::PostMergeService
+ .new(merge_request.target_project, @current_user)
+ .execute(merge_request)
end
end
@@ -56,8 +56,8 @@ module MergeRequests
# Refresh merge request diff if we push to source or target branch of merge request
# Note: we should update merge requests from forks too
def reload_merge_requests
- merge_requests = @project.merge_requests.opened.
- by_source_or_target_branch(@branch_name).to_a
+ merge_requests = @project.merge_requests.opened
+ .by_source_or_target_branch(@branch_name).to_a
# Fork merge requests
merge_requests += MergeRequest.opened
diff --git a/app/services/merge_requests/update_service.rb b/app/services/merge_requests/update_service.rb
index 5c843a258fb..75a65aecd1a 100644
--- a/app/services/merge_requests/update_service.rb
+++ b/app/services/merge_requests/update_service.rb
@@ -7,7 +7,7 @@ module MergeRequests
params.except!(:target_project_id)
params.except!(:source_branch)
- merge_from_slash_command(merge_request) if params[:merge]
+ merge_from_quick_action(merge_request) if params[:merge]
if merge_request.closed_without_fork?
params.except!(:target_branch, :force_remove_source_branch)
@@ -74,9 +74,9 @@ module MergeRequests
end
end
- def merge_from_slash_command(merge_request)
+ def merge_from_quick_action(merge_request)
last_diff_sha = params.delete(:merge)
- return unless merge_request.mergeable_with_slash_command?(current_user, last_diff_sha: last_diff_sha)
+ return unless merge_request.mergeable_with_quick_action?(current_user, last_diff_sha: last_diff_sha)
merge_request.update(merge_error: nil)
diff --git a/app/services/notes/create_service.rb b/app/services/notes/create_service.rb
index f3954f6f8c4..06971483992 100644
--- a/app/services/notes/create_service.rb
+++ b/app/services/notes/create_service.rb
@@ -9,11 +9,11 @@ module Notes
# We execute commands (extracted from `params[:note]`) on the noteable
# **before** we save the note because if the note consists of commands
# only, there is no need be create a note!
- slash_commands_service = SlashCommandsService.new(project, current_user)
+ quick_actions_service = QuickActionsService.new(project, current_user)
- if slash_commands_service.supported?(note)
+ if quick_actions_service.supported?(note)
options = { merge_request_diff_head_sha: merge_request_diff_head_sha }
- content, command_params = slash_commands_service.extract_commands(note, options)
+ content, command_params = quick_actions_service.extract_commands(note, options)
only_commands = content.empty?
@@ -30,7 +30,7 @@ module Notes
end
if command_params.present?
- slash_commands_service.execute(command_params, note)
+ quick_actions_service.execute(command_params, note)
# We must add the error after we call #save because errors are reset
# when #save is called
diff --git a/app/services/notes/slash_commands_service.rb b/app/services/notes/quick_actions_service.rb
index ad1e6f6774a..a8d0cc15527 100644
--- a/app/services/notes/slash_commands_service.rb
+++ b/app/services/notes/quick_actions_service.rb
@@ -1,5 +1,5 @@
module Notes
- class SlashCommandsService < BaseService
+ class QuickActionsService < BaseService
UPDATE_SERVICES = {
'Issue' => Issues::UpdateService,
'MergeRequest' => MergeRequests::UpdateService
@@ -22,8 +22,8 @@ module Notes
def extract_commands(note, options = {})
return [note.note, {}] unless supported?(note)
- SlashCommands::InterpretService.new(project, current_user, options).
- execute(note.note, note.noteable)
+ QuickActions::InterpretService.new(project, current_user, options)
+ .execute(note.note, note.noteable)
end
def execute(command_params, note)
diff --git a/app/services/preview_markdown_service.rb b/app/services/preview_markdown_service.rb
index 10d45bbf73c..4ee2c1796bd 100644
--- a/app/services/preview_markdown_service.rb
+++ b/app/services/preview_markdown_service.rb
@@ -1,6 +1,6 @@
class PreviewMarkdownService < BaseService
def execute
- text, commands = explain_slash_commands(params[:text])
+ text, commands = explain_quick_actions(params[:text])
users = find_user_references(text)
success(
@@ -12,11 +12,11 @@ class PreviewMarkdownService < BaseService
private
- def explain_slash_commands(text)
+ def explain_quick_actions(text)
return text, [] unless %w(Issue MergeRequest).include?(commands_target_type)
- slash_commands_service = SlashCommands::InterpretService.new(project, current_user)
- slash_commands_service.explain(text, find_commands_target)
+ quick_actions_service = QuickActions::InterpretService.new(project, current_user)
+ quick_actions_service.explain(text, find_commands_target)
end
def find_user_references(text)
@@ -36,10 +36,10 @@ class PreviewMarkdownService < BaseService
end
def commands_target_type
- params[:slash_commands_target_type]
+ params[:quick_actions_target_type]
end
def commands_target_id
- params[:slash_commands_target_id]
+ params[:quick_actions_target_id]
end
end
diff --git a/app/services/projects/autocomplete_service.rb b/app/services/projects/autocomplete_service.rb
index 015f2828921..fc85f398935 100644
--- a/app/services/projects/autocomplete_service.rb
+++ b/app/services/projects/autocomplete_service.rb
@@ -32,7 +32,7 @@ module Projects
issuable: noteable,
current_user: current_user
}
- SlashCommands::InterpretService.command_definitions.map do |definition|
+ QuickActions::InterpretService.command_definitions.map do |definition|
next unless definition.available?(opts)
definition.to_h(opts)
diff --git a/app/services/projects/transfer_service.rb b/app/services/projects/transfer_service.rb
index 1c24b27a870..fd701e33524 100644
--- a/app/services/projects/transfer_service.rb
+++ b/app/services/projects/transfer_service.rb
@@ -12,87 +12,121 @@ module Projects
TransferError = Class.new(StandardError)
def execute(new_namespace)
- if new_namespace.blank?
+ @new_namespace = new_namespace
+
+ if @new_namespace.blank?
raise TransferError, 'Please select a new namespace for your project.'
end
- unless allowed_transfer?(current_user, project, new_namespace)
+
+ unless allowed_transfer?(current_user, project)
raise TransferError, 'Transfer failed, please contact an admin.'
end
- transfer(project, new_namespace)
+
+ transfer(project)
+
+ true
rescue Projects::TransferService::TransferError => ex
project.reload
project.errors.add(:new_namespace, ex.message)
false
end
- def transfer(project, new_namespace)
- old_namespace = project.namespace
+ private
- Project.transaction do
- old_path = project.path_with_namespace
- old_group = project.group
- new_path = File.join(new_namespace.try(:full_path) || '', project.path)
+ def transfer(project)
+ @old_path = project.path_with_namespace
+ @old_group = project.group
+ @new_path = File.join(@new_namespace.try(:full_path) || '', project.path)
+ @old_namespace = project.namespace
- if Project.where(path: project.path, namespace_id: new_namespace.try(:id)).present?
- raise TransferError.new("Project with same path in target namespace already exists")
- end
+ if Project.where(path: project.path, namespace_id: @new_namespace.try(:id)).exists?
+ raise TransferError.new("Project with same path in target namespace already exists")
+ end
- if project.has_container_registry_tags?
- # we currently doesn't support renaming repository if it contains tags in container registry
- raise TransferError.new('Project cannot be transferred, because tags are present in its container registry')
- end
+ if project.has_container_registry_tags?
+ # We currently don't support renaming repository if it contains tags in container registry
+ raise TransferError.new('Project cannot be transferred, because tags are present in its container registry')
+ end
- project.expire_caches_before_rename(old_path)
+ attempt_transfer_transaction
+ end
+
+ def attempt_transfer_transaction
+ Project.transaction do
+ project.expire_caches_before_rename(@old_path)
- # Apply new namespace id and visibility level
- project.namespace = new_namespace
- project.visibility_level = new_namespace.visibility_level unless project.visibility_level_allowed_by_group?
- project.save!
+ update_namespace_and_visibility(@new_namespace)
# Notifications
- project.send_move_instructions(old_path)
+ project.send_move_instructions(@old_path)
# Move main repository
- unless gitlab_shell.mv_repository(project.repository_storage_path, old_path, new_path)
+ unless move_repo_folder(@old_path, @new_path)
raise TransferError.new('Cannot move project')
end
# Move wiki repo also if present
- gitlab_shell.mv_repository(project.repository_storage_path, "#{old_path}.wiki", "#{new_path}.wiki")
+ move_repo_folder("#{@old_path}.wiki", "#{@new_path}.wiki")
# Move missing group labels to project
- Labels::TransferService.new(current_user, old_group, project).execute
+ Labels::TransferService.new(current_user, @old_group, project).execute
# Move uploads
- Gitlab::UploadsTransfer.new.move_project(project.path, old_namespace.full_path, new_namespace.full_path)
+ Gitlab::UploadsTransfer.new.move_project(project.path, @old_namespace.full_path, @new_namespace.full_path)
# Move pages
- Gitlab::PagesTransfer.new.move_project(project.path, old_namespace.full_path, new_namespace.full_path)
+ Gitlab::PagesTransfer.new.move_project(project.path, @old_namespace.full_path, @new_namespace.full_path)
- project.old_path_with_namespace = old_path
+ project.old_path_with_namespace = @old_path
- SystemHooksService.new.execute_hooks_for(project, :transfer)
+ execute_system_hooks
end
-
- refresh_permissions(old_namespace, new_namespace)
-
- true
+ rescue Exception # rubocop:disable Lint/RescueException
+ rollback_side_effects
+ raise
+ ensure
+ refresh_permissions
end
- def allowed_transfer?(current_user, project, namespace)
- namespace &&
+ def allowed_transfer?(current_user, project)
+ @new_namespace &&
can?(current_user, :change_namespace, project) &&
- namespace.id != project.namespace_id &&
- current_user.can?(:create_projects, namespace)
+ @new_namespace.id != project.namespace_id &&
+ current_user.can?(:create_projects, @new_namespace)
end
- def refresh_permissions(old_namespace, new_namespace)
+ def update_namespace_and_visibility(to_namespace)
+ # Apply new namespace id and visibility level
+ project.namespace = to_namespace
+ project.visibility_level = to_namespace.visibility_level unless project.visibility_level_allowed_by_group?
+ project.save!
+ end
+
+ def refresh_permissions
# This ensures we only schedule 1 job for every user that has access to
# the namespaces.
- user_ids = old_namespace.user_ids_for_project_authorizations |
- new_namespace.user_ids_for_project_authorizations
+ user_ids = @old_namespace.user_ids_for_project_authorizations |
+ @new_namespace.user_ids_for_project_authorizations
UserProjectAccessChangedService.new(user_ids).execute
end
+
+ def rollback_side_effects
+ rollback_folder_move
+ update_namespace_and_visibility(@old_namespace)
+ end
+
+ def rollback_folder_move
+ move_repo_folder(@new_path, @old_path)
+ move_repo_folder("#{@new_path}.wiki", "#{@old_path}.wiki")
+ end
+
+ def move_repo_folder(from_name, to_name)
+ gitlab_shell.mv_repository(project.repository_storage_path, from_name, to_name)
+ end
+
+ def execute_system_hooks
+ SystemHooksService.new.execute_hooks_for(project, :transfer)
+ end
end
end
diff --git a/app/services/slash_commands/interpret_service.rb b/app/services/quick_actions/interpret_service.rb
index 83144b1e011..6816b137361 100644
--- a/app/services/slash_commands/interpret_service.rb
+++ b/app/services/quick_actions/interpret_service.rb
@@ -1,13 +1,13 @@
-module SlashCommands
+module QuickActions
class InterpretService < BaseService
- include Gitlab::SlashCommands::Dsl
+ include Gitlab::QuickActions::Dsl
attr_reader :issuable
# Takes a text and interprets the commands that are extracted from it.
# Returns the content without commands, and hash of changes to be applied to a record.
def execute(content, issuable)
- return [content, {}] unless current_user.can?(:use_slash_commands)
+ return [content, {}] unless current_user.can?(:use_quick_actions)
@issuable = issuable
@updates = {}
@@ -20,7 +20,7 @@ module SlashCommands
# Takes a text and interprets the commands that are extracted from it.
# Returns the content without commands, and array of changes explained.
def explain(content, issuable)
- return [content, []] unless current_user.can?(:use_slash_commands)
+ return [content, []] unless current_user.can?(:use_quick_actions)
@issuable = issuable
@@ -32,7 +32,7 @@ module SlashCommands
private
def extractor
- Gitlab::SlashCommands::Extractor.new(self.class.command_definitions)
+ Gitlab::QuickActions::Extractor.new(self.class.command_definitions)
end
desc do
@@ -71,7 +71,7 @@ module SlashCommands
last_diff_sha = params && params[:merge_request_diff_head_sha]
issuable.is_a?(MergeRequest) &&
issuable.persisted? &&
- issuable.mergeable_with_slash_command?(current_user, autocomplete_precheck: !last_diff_sha, last_diff_sha: last_diff_sha)
+ issuable.mergeable_with_quick_action?(current_user, autocomplete_precheck: !last_diff_sha, last_diff_sha: last_diff_sha)
end
command :merge do
@updates[:merge] = params[:merge_request_diff_head_sha]
diff --git a/app/services/tags/create_service.rb b/app/services/tags/create_service.rb
index 1756da9e519..674792f6138 100644
--- a/app/services/tags/create_service.rb
+++ b/app/services/tags/create_service.rb
@@ -19,8 +19,8 @@ module Tags
if new_tag
if release_description
- CreateReleaseService.new(@project, @current_user).
- execute(tag_name, release_description)
+ CreateReleaseService.new(@project, @current_user)
+ .execute(tag_name, release_description)
end
success.merge(tag: new_tag)
diff --git a/app/services/users/refresh_authorized_projects_service.rb b/app/services/users/refresh_authorized_projects_service.rb
index 3e07b811027..f028f5eb0d4 100644
--- a/app/services/users/refresh_authorized_projects_service.rb
+++ b/app/services/users/refresh_authorized_projects_service.rb
@@ -34,7 +34,7 @@ module Users
# Keep trying until we obtain the lease. If we don't do so we may end up
# not updating the list of authorized projects properly. To prevent
# hammering Redis too much we'll wait for a bit between retries.
- sleep(1)
+ sleep(0.1)
end
begin
diff --git a/app/validators/dynamic_path_validator.rb b/app/validators/dynamic_path_validator.rb
index 27ac60637fd..4688aabc2a8 100644
--- a/app/validators/dynamic_path_validator.rb
+++ b/app/validators/dynamic_path_validator.rb
@@ -26,7 +26,7 @@ class DynamicPathValidator < ActiveModel::EachValidator
end
def path_valid_for_record?(record, value)
- full_path = record.respond_to?(:full_path) ? record.full_path : value
+ full_path = record.respond_to?(:build_full_path) ? record.build_full_path : value
return true unless full_path
diff --git a/app/views/admin/application_settings/_form.html.haml b/app/views/admin/application_settings/_form.html.haml
index 95dffdafabe..b21d5665970 100644
--- a/app/views/admin/application_settings/_form.html.haml
+++ b/app/views/admin/application_settings/_form.html.haml
@@ -325,6 +325,10 @@
= f.label :prometheus_metrics_enabled do
= f.check_box :prometheus_metrics_enabled
Enable Prometheus Metrics
+ - unless Gitlab::Metrics.metrics_folder_present?
+ .help-block
+ %strong.cred WARNING:
+ Environment variable `prometheus_multiproc_dir` does not exist or is not pointing to a valid directory.
%fieldset
%legend Background Jobs
diff --git a/app/views/admin/broadcast_messages/_form.html.haml b/app/views/admin/broadcast_messages/_form.html.haml
index 2269fb1fd8c..5a4ed1c3a2a 100644
--- a/app/views/admin/broadcast_messages/_form.html.haml
+++ b/app/views/admin/broadcast_messages/_form.html.haml
@@ -21,11 +21,11 @@
.form-group.js-toggle-colors-container.hide
= f.label :color, "Background Color", class: 'control-label'
.col-sm-10
- = f.text_field :color, class: "form-control"
+ = f.color_field :color, class: "form-control"
.form-group.js-toggle-colors-container.hide
= f.label :font, "Font Color", class: 'control-label'
.col-sm-10
- = f.text_field :font, class: "form-control"
+ = f.color_field :font, class: "form-control"
.form-group
= f.label :starts_at, class: 'control-label'
.col-sm-10.datetime-controls
diff --git a/app/views/notify/pipeline_failed_email.html.haml b/app/views/notify/pipeline_failed_email.html.haml
index a83faa839df..b7a60938132 100644
--- a/app/views/notify/pipeline_failed_email.html.haml
+++ b/app/views/notify/pipeline_failed_email.html.haml
@@ -60,7 +60,7 @@
%tbody
%tr
%td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;vertical-align:middle;padding-right:5px;" }
- %img.avatar{ height: "24", src: avatar_icon(commit.author || commit.author_email, 24), style: "display:block;border-radius:12px;margin:-2px 0;", width: "24", alt: "Avatar" }/
+ %img.avatar{ height: "24", src: avatar_icon(commit.author || commit.author_email, 24, only_path: false), style: "display:block;border-radius:12px;margin:-2px 0;", width: "24", alt: "Avatar" }/
%td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;vertical-align:middle;" }
- if commit.author
%a.muted{ href: user_url(commit.author), style: "color:#333333;text-decoration:none;" }
@@ -76,7 +76,7 @@
%tbody
%tr
%td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;vertical-align:middle;padding-right:5px;" }
- %img.avatar{ height: "24", src: avatar_icon(commit.committer || commit.committer_email, 24), style: "display:block;border-radius:12px;margin:-2px 0;", width: "24", alt: "Avatar" }/
+ %img.avatar{ height: "24", src: avatar_icon(commit.committer || commit.committer_email, 24, only_path: false), style: "display:block;border-radius:12px;margin:-2px 0;", width: "24", alt: "Avatar" }/
%td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;vertical-align:middle;" }
- if commit.committer
%a.muted{ href: user_url(commit.committer), style: "color:#333333;text-decoration:none;" }
@@ -100,7 +100,7 @@
triggered by
- if @pipeline.user
%td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;vertical-align:middle;padding-right:5px;padding-left:5px", width: "24" }
- %img.avatar{ height: "24", src: avatar_icon(@pipeline.user, 24), style: "display:block;border-radius:12px;margin:-2px 0;", width: "24", alt: "Avatar" }/
+ %img.avatar{ height: "24", src: avatar_icon(@pipeline.user, 24, only_path: false), style: "display:block;border-radius:12px;margin:-2px 0;", width: "24", alt: "Avatar" }/
%td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;font-weight:500;line-height:1.4;vertical-align:baseline;" }
%a.muted{ href: user_url(@pipeline.user), style: "color:#333333;text-decoration:none;" }
= @pipeline.user.name
diff --git a/app/views/notify/pipeline_success_email.html.haml b/app/views/notify/pipeline_success_email.html.haml
index 9c2e2a599b2..3f16885b8e3 100644
--- a/app/views/notify/pipeline_success_email.html.haml
+++ b/app/views/notify/pipeline_success_email.html.haml
@@ -60,7 +60,7 @@
%tbody
%tr
%td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;vertical-align:middle;padding-right:5px;" }
- %img.avatar{ height: "24", src: avatar_icon(commit.author || commit.author_email, 24), style: "display:block;border-radius:12px;margin:-2px 0;", width: "24", alt: "Avatar" }/
+ %img.avatar{ height: "24", src: avatar_icon(commit.author || commit.author_email, 24, only_path: false), style: "display:block;border-radius:12px;margin:-2px 0;", width: "24", alt: "Avatar" }/
%td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;vertical-align:middle;" }
- if commit.author
%a.muted{ href: user_url(commit.author), style: "color:#333333;text-decoration:none;" }
@@ -76,7 +76,7 @@
%tbody
%tr
%td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;vertical-align:middle;padding-right:5px;" }
- %img.avatar{ height: "24", src: avatar_icon(commit.committer || commit.committer_email, 24), style: "display:block;border-radius:12px;margin:-2px 0;", width: "24", alt: "Avatar" }/
+ %img.avatar{ height: "24", src: avatar_icon(commit.committer || commit.committer_email, 24, only_path: false), style: "display:block;border-radius:12px;margin:-2px 0;", width: "24", alt: "Avatar" }/
%td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;vertical-align:middle;" }
- if commit.committer
%a.muted{ href: user_url(commit.committer), style: "color:#333333;text-decoration:none;" }
@@ -100,7 +100,7 @@
triggered by
- if @pipeline.user
%td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;vertical-align:middle;padding-right:5px;padding-left:5px", width: "24" }
- %img.avatar{ height: "24", src: avatar_icon(@pipeline.user, 24), style: "display:block;border-radius:12px;margin:-2px 0;", width: "24", alt: "Avatar" }/
+ %img.avatar{ height: "24", src: avatar_icon(@pipeline.user, 24, only_path: false), style: "display:block;border-radius:12px;margin:-2px 0;", width: "24", alt: "Avatar" }/
%td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;font-size:15px;font-weight:500;line-height:1.4;vertical-align:baseline;" }
%a.muted{ href: user_url(@pipeline.user), style: "color:#333333;text-decoration:none;" }
= @pipeline.user.name
diff --git a/app/views/profiles/show.html.haml b/app/views/profiles/show.html.haml
index fcfd350f0da..15672289c65 100644
--- a/app/views/profiles/show.html.haml
+++ b/app/views/profiles/show.html.haml
@@ -42,10 +42,17 @@
- if current_user.ldap_user?
Some options are unavailable for LDAP accounts
.col-lg-9
- .form-group
- = f.label :name, class: "label-light"
- = f.text_field :name, class: "form-control", required: true
- %span.help-block Enter your name, so people you know can recognize you.
+ .row
+ .form-group.col-md-9
+ = f.label :name, class: "label-light"
+ = f.text_field :name, class: "form-control", required: true
+ %span.help-block Enter your name, so people you know can recognize you.
+
+ .form-group.col-md-3
+ = f.label :id, class: 'label-light' do
+ User ID
+ = f.text_field :id, class: 'form-control', readonly: true
+
.form-group
= f.label :email, class: "label-light"
diff --git a/app/views/projects/_find_file_link.html.haml b/app/views/projects/_find_file_link.html.haml
index c748ccf65e6..cb4d2bbacf5 100644
--- a/app/views/projects/_find_file_link.html.haml
+++ b/app/views/projects/_find_file_link.html.haml
@@ -1,3 +1,3 @@
-= link_to namespace_project_find_file_path(@project.namespace, @project, @ref), class: 'btn btn-grouped shortcuts-find-file', rel: 'nofollow' do
+= link_to namespace_project_find_file_path(@project.namespace, @project, @ref), class: 'btn shortcuts-find-file', rel: 'nofollow' do
= icon('search')
%span= _('Find file')
diff --git a/app/views/projects/_md_preview.html.haml b/app/views/projects/_md_preview.html.haml
index 07445434cf3..d0698285f84 100644
--- a/app/views/projects/_md_preview.html.haml
+++ b/app/views/projects/_md_preview.html.haml
@@ -9,6 +9,12 @@
%li
%a.js-md-preview-button{ href: "#md-preview-holder", tabindex: -1 }
Preview
+
+ - if defined?(@issue) && @issue.confidential?
+ %li.confidential-issue-warning
+ = icon('warning')
+ %span This is a confidential issue. Your comment will not be visible to the public.
+
%li.pull-right
.toolbar-group
= markdown_toolbar_button({ icon: "bold fw", data: { "md-tag" => "**" }, title: "Add bold text" })
diff --git a/app/views/projects/_visibility_select.html.haml b/app/views/projects/_visibility_select.html.haml
index 65fc0a36ca9..4026b9e3c46 100644
--- a/app/views/projects/_visibility_select.html.haml
+++ b/app/views/projects/_visibility_select.html.haml
@@ -1,5 +1,7 @@
- if can_change_visibility_level?(@project, current_user)
- = form.select(model_method, visibility_select_options(@project, selected_level), {}, class: 'form-control visibility-select')
+ .select-wrapper
+ = form.select(model_method, visibility_select_options(@project, selected_level), {}, class: 'form-control visibility-select select-control')
+ = icon('chevron-down')
- else
.info.js-locked{ data: { help_block: visibility_level_description(@project.visibility_level, @project) } }
= visibility_level_icon(@project.visibility_level)
diff --git a/app/views/projects/_zen.html.haml b/app/views/projects/_zen.html.haml
index 3b3d08ddd3c..afc40ca4eab 100644
--- a/app/views/projects/_zen.html.haml
+++ b/app/views/projects/_zen.html.haml
@@ -1,10 +1,15 @@
- @gfm_form = true
- current_text ||= nil
-- supports_slash_commands = local_assigns.fetch(:supports_slash_commands, false)
+- supports_autocomplete = local_assigns.fetch(:supports_autocomplete, true)
+- supports_quick_actions = local_assigns.fetch(:supports_quick_actions, false)
.zen-backdrop
- classes << ' js-gfm-input js-autosize markdown-area'
- if defined?(f) && f
- = f.text_area attr, class: classes, placeholder: placeholder, data: { supports_slash_commands: supports_slash_commands }
+ = f.text_area attr,
+ class: classes,
+ placeholder: placeholder,
+ data: { supports_quick_actions: supports_quick_actions,
+ supports_autocomplete: supports_autocomplete }
- else
= text_area_tag attr, current_text, class: classes, placeholder: placeholder
%a.zen-control.zen-control-leave.js-zen-leave{ href: "#" }
diff --git a/app/views/projects/blob/_breadcrumb.html.haml b/app/views/projects/blob/_breadcrumb.html.haml
index 0ad9f258e48..5840e9863f4 100644
--- a/app/views/projects/blob/_breadcrumb.html.haml
+++ b/app/views/projects/blob/_breadcrumb.html.haml
@@ -1,9 +1,26 @@
- blame = local_assigns.fetch(:blame, false)
.nav-block
+ .tree-ref-container
+ .tree-ref-holder
+ = render 'shared/ref_switcher', destination: 'blob', path: @path
+
+ %ul.breadcrumb.repo-breadcrumb
+ %li
+ = link_to namespace_project_tree_path(@project.namespace, @project, @ref) do
+ = @project.path
+ - path_breadcrumbs do |title, path|
+ - title = truncate(title, length: 40)
+ %li
+ - if path == @path
+ = link_to namespace_project_blob_path(@project.namespace, @project, tree_join(@ref, path)) do
+ %strong= title
+ - else
+ = link_to title, namespace_project_tree_path(@project.namespace, @project, tree_join(@ref, path))
+
.tree-controls
= render 'projects/find_file_link'
- .btn-group.prepend-left-10{ role: "group" }<
+ .btn-group{ role: "group" }<
-# only show normal/blame view links for text files
- if blob.readable_text?
- if blame
@@ -18,19 +35,3 @@
= link_to 'Permalink', namespace_project_blob_path(@project.namespace, @project,
tree_join(@commit.sha, @path)), class: 'btn js-data-file-blob-permalink-url'
-
- .tree-ref-holder
- = render 'shared/ref_switcher', destination: 'blob', path: @path
-
- %ul.breadcrumb.repo-breadcrumb
- %li
- = link_to namespace_project_tree_path(@project.namespace, @project, @ref) do
- = @project.path
- - path_breadcrumbs do |title, path|
- - title = truncate(title, length: 40)
- %li
- - if path == @path
- = link_to namespace_project_blob_path(@project.namespace, @project, tree_join(@ref, path)) do
- %strong= title
- - else
- = link_to title, namespace_project_tree_path(@project.namespace, @project, tree_join(@ref, path))
diff --git a/app/views/projects/blob/_upload.html.haml b/app/views/projects/blob/_upload.html.haml
index e14885f264b..32dbc1b3417 100644
--- a/app/views/projects/blob/_upload.html.haml
+++ b/app/views/projects/blob/_upload.html.haml
@@ -9,8 +9,10 @@
.dropzone
.dropzone-previews.blob-upload-dropzone-previews
%p.dz-message.light
- Attach a file by drag &amp; drop or
- = link_to 'click to upload', '#', class: "markdown-selector"
+ - upload_link = link_to s_('UploadLink|click to upload'), '#', class: "markdown-selector"
+ - dropzone_text = _('Attach a file by drag &amp; drop or %{upload_link}') % { upload_link: upload_link }
+ #{ dropzone_text.html_safe }
+
%br
.dropzone-alerts.alert.alert-danger.data{ style: "display:none" }
@@ -18,7 +20,7 @@
.form-actions
= button_tag button_title, class: 'btn btn-small btn-create btn-upload-file', id: 'submit-all'
- = link_to "Cancel", '#', class: "btn btn-cancel", "data-dismiss" => "modal"
+ = link_to _("Cancel"), '#', class: "btn btn-cancel", "data-dismiss" => "modal"
- unless can?(current_user, :push_code, @project)
.inline.prepend-left-10
diff --git a/app/views/projects/buttons/_download.html.haml b/app/views/projects/buttons/_download.html.haml
index 3cf91bf07f7..a73ddd5eb33 100644
--- a/app/views/projects/buttons/_download.html.haml
+++ b/app/views/projects/buttons/_download.html.haml
@@ -2,7 +2,7 @@
- if !project.empty_repo? && can?(current_user, :download_code, project)
.project-action-button.dropdown.inline>
- %button.btn.has-tooltip{ title: 'Download', 'data-toggle' => 'dropdown', 'aria-label' => s_('DownloadSource|Download') }
+ %button.btn.has-tooltip{ title: s_('DownloadSource|Download'), 'data-toggle' => 'dropdown', 'aria-label' => s_('DownloadSource|Download') }
= icon('download')
= icon("caret-down")
%span.sr-only= _('Select Archive Format')
diff --git a/app/views/projects/buttons/_dropdown.html.haml b/app/views/projects/buttons/_dropdown.html.haml
index 312c349da3a..960b57a8008 100644
--- a/app/views/projects/buttons/_dropdown.html.haml
+++ b/app/views/projects/buttons/_dropdown.html.haml
@@ -1,6 +1,6 @@
- if current_user
.project-action-button.dropdown.inline
- %a.btn.dropdown-toggle.has-tooltip{ href: '#', title: 'Create new...', 'data-toggle' => 'dropdown', 'data-container' => 'body', 'aria-label' => 'Create new...' }
+ %a.btn.dropdown-toggle.has-tooltip{ href: '#', title: _('Create new...'), 'data-toggle' => 'dropdown', 'data-container' => 'body', 'aria-label' => _('Create new...') }
= icon('plus')
= icon("caret-down")
%ul.dropdown-menu.dropdown-menu-align-right.project-home-dropdown
diff --git a/app/views/projects/buttons/_fork.html.haml b/app/views/projects/buttons/_fork.html.haml
index 7a08bb37494..42f8c75f57b 100644
--- a/app/views/projects/buttons/_fork.html.haml
+++ b/app/views/projects/buttons/_fork.html.haml
@@ -4,11 +4,15 @@
= link_to namespace_project_path(current_user, current_user.fork_of(@project)), title: _('Go to your fork'), class: 'btn has-tooltip' do
= custom_icon('icon_fork')
%span= s_('GoToYourFork|Fork')
+ - elsif !current_user.can_create_project?
+ = link_to new_namespace_project_fork_path(@project.namespace, @project), title: _('You have reached your project limit'), class: 'btn has-tooltip disabled' do
+ = custom_icon('icon_fork')
+ %span= s_('CreateNewFork|Fork')
- else
= link_to new_namespace_project_fork_path(@project.namespace, @project), class: 'btn' do
= custom_icon('icon_fork')
%span= s_('CreateNewFork|Fork')
.count-with-arrow
%span.arrow
- = link_to namespace_project_forks_path(@project.namespace, @project), title: n_('Forks', @project.forks_count), class: 'count' do
+ = link_to namespace_project_forks_path(@project.namespace, @project), title: n_('Fork', 'Forks', @project.forks_count), class: 'count' do
= @project.forks_count
diff --git a/app/views/projects/commit/_change.html.haml b/app/views/projects/commit/_change.html.haml
index 281d823da52..2267f123e38 100644
--- a/app/views/projects/commit/_change.html.haml
+++ b/app/views/projects/commit/_change.html.haml
@@ -1,35 +1,36 @@
- case type.to_s
- when 'revert'
- - label = 'Revert'
- - branch_label = 'Revert in branch'
+ - label = s_('ChangeTypeAction|Revert')
+ - branch_label = s_('ChangeTypeActionLabel|Revert in branch')
+ - revert_merge_request = _('Revert this merge request')
+ - revert_commit = _('Revert this commit')
+ - title = commit.merged_merge_request(current_user) ? revert_merge_request : revert_commit
- when 'cherry-pick'
- - label = 'Cherry-pick'
- - branch_label = 'Pick into branch'
+ - label = s_('ChangeTypeAction|Cherry-pick')
+ - branch_label = s_('ChangeTypeActionLabel|Pick into branch')
+ - title = commit.merged_merge_request(current_user) ? _('Cherry-pick this merge request') : _('Cherry-pick this commit')
.modal{ id: "modal-#{type}-commit" }
.modal-dialog
.modal-content
.modal-header
%a.close{ href: "#", "data-dismiss" => "modal" } ×
- %h3.page-title== #{label} this #{commit.change_type_title(current_user)}
+ %h3.page-title= title
.modal-body
= form_tag [type.underscore, @project.namespace.becomes(Namespace), @project, commit], method: :post, remote: false, class: "form-horizontal js-#{type}-form js-requires-input" do
.form-group.branch
= label_tag 'start_branch', branch_label, class: 'control-label'
.col-sm-10
= hidden_field_tag :start_branch, @project.default_branch, id: 'start_branch'
- = dropdown_tag(@project.default_branch, options: { title: "Switch branch", filter: true, placeholder: "Search branches", toggle_class: 'js-project-refs-dropdown dynamic', dropdown_class: 'dropdown-menu-selectable', data: { field_name: "start_branch", selected: @project.default_branch, start_branch: @project.default_branch, refs_url: namespace_project_branches_path(@project.namespace, @project), submit_form_on_click: false } })
+ = dropdown_tag(@project.default_branch, options: { title: s_("BranchSwitcherTitle|Switch branch"), filter: true, placeholder: s_("BranchSwitcherPlaceholder|Search branches"), toggle_class: 'js-project-refs-dropdown dynamic', dropdown_class: 'dropdown-menu-selectable', data: { field_name: "start_branch", selected: @project.default_branch, start_branch: @project.default_branch, refs_url: namespace_project_branches_path(@project.namespace, @project), submit_form_on_click: false } })
- if can?(current_user, :push_code, @project)
- .checkbox
- = label_tag do
- = check_box_tag 'create_merge_request', 1, true, class: 'js-create-merge-request', id: nil
- Start a <strong>new merge request</strong> with these changes
+ = render 'shared/new_merge_request_checkbox'
- else
= hidden_field_tag 'create_merge_request', 1, id: nil
.form-actions
= submit_tag label, class: 'btn btn-create'
- = link_to "Cancel", '#', class: "btn btn-cancel", "data-dismiss" => "modal"
+ = link_to _("Cancel"), '#', class: "btn btn-cancel", "data-dismiss" => "modal"
- unless can?(current_user, :push_code, @project)
.inline.prepend-left-10
diff --git a/app/views/projects/commit/_commit_box.html.haml b/app/views/projects/commit/_commit_box.html.haml
index aab50310234..7fe44816bae 100644
--- a/app/views/projects/commit/_commit_box.html.haml
+++ b/app/views/projects/commit/_commit_box.html.haml
@@ -1,17 +1,17 @@
.page-content-header
.header-main-content
%strong
- Commit
+ #{ s_('CommitBoxTitle|Commit') }
%span.commit-sha= @commit.short_id
- = clipboard_button(text: @commit.id, title: "Copy commit SHA to clipboard")
+ = clipboard_button(text: @commit.id, title: _("Copy commit SHA to clipboard"))
%span.hidden-xs authored
#{time_ago_with_tooltip(@commit.authored_date)}
- %span by
+ %span= s_('ByAuthor|by')
= author_avatar(@commit, size: 24)
%strong
= commit_author_link(@commit, avatar: true, size: 24)
- if @commit.different_committer?
- %span.light Committed by
+ %span.light= _('Committed by')
%strong
= commit_committer_link(@commit, avatar: true, size: 24)
#{time_ago_with_tooltip(@commit.committed_date)}
@@ -22,15 +22,15 @@
= icon('comment')
= @notes_count
= link_to namespace_project_tree_path(@project.namespace, @project, @commit), class: "btn btn-default append-right-10 hidden-xs hidden-sm" do
- Browse files
+ #{ _('Browse files') }
.dropdown.inline
%a.btn.btn-default.dropdown-toggle{ data: { toggle: "dropdown" } }
- %span Options
+ %span= _('Options')
= icon('caret-down')
%ul.dropdown-menu.dropdown-menu-align-right
%li.visible-xs-block.visible-sm-block
= link_to namespace_project_tree_path(@project.namespace, @project, @commit) do
- Browse Files
+ _('Browse Files')
- unless @commit.has_been_reverted?(current_user)
%li.clearfix
= revert_commit_link(@commit, namespace_project_commit_path(@project.namespace, @project, @commit.id), has_tooltip: false)
@@ -38,13 +38,13 @@
= cherry_pick_commit_link(@commit, namespace_project_commit_path(@project.namespace, @project, @commit.id), has_tooltip: false)
- if can_collaborate_with_project?
%li.clearfix
- = link_to "Tag", new_namespace_project_tag_path(@project.namespace, @project, ref: @commit)
+ = link_to s_("CreateTag|Tag"), new_namespace_project_tag_path(@project.namespace, @project, ref: @commit)
%li.divider
%li.dropdown-header
- Download
+ #{ _('Download') }
- unless @commit.parents.length > 1
- %li= link_to "Email Patches", namespace_project_commit_path(@project.namespace, @project, @commit, format: :patch)
- %li= link_to "Plain Diff", namespace_project_commit_path(@project.namespace, @project, @commit, format: :diff)
+ %li= link_to s_("DownloadCommit|Email Patches"), namespace_project_commit_path(@project.namespace, @project, @commit, format: :patch)
+ %li= link_to s_("DownloadCommit|Plain Diff"), namespace_project_commit_path(@project.namespace, @project, @commit, format: :diff)
.commit-box
%h3.commit-title
@@ -57,7 +57,7 @@
.well-segment.branch-info
.icon-container.commit-icon
= custom_icon("icon_commit")
- %span.cgray= pluralize(@commit.parents.count, "parent")
+ %span.cgray= n_('parent', 'parents', @commit.parents.count)
- @commit.parents.each do |parent|
= link_to parent.short_id, namespace_project_commit_path(@project.namespace, @project, parent), class: "commit-sha"
%span.commit-info.branches
@@ -69,11 +69,11 @@
.status-icon-container{ class: "ci-status-icon-#{@commit.status}" }
= link_to namespace_project_pipeline_path(@project.namespace, @project, last_pipeline.id) do
= ci_icon_for_status(last_pipeline.status)
- Pipeline
+ #{ _('Pipeline') }
= link_to "##{last_pipeline.id}", namespace_project_pipeline_path(@project.namespace, @project, last_pipeline.id)
= ci_label_for_status(last_pipeline.status)
- if last_pipeline.stages_count.nonzero?
- with #{"stage".pluralize(last_pipeline.stages_count)}
+ #{ 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
diff --git a/app/views/projects/commits/_commit.html.haml b/app/views/projects/commits/_commit.html.haml
index 7a03c3561af..11de6915961 100644
--- a/app/views/projects/commits/_commit.html.haml
+++ b/app/views/projects/commits/_commit.html.haml
@@ -30,9 +30,11 @@
%pre.commit-row-description.js-toggle-content
= preserve(markdown(commit.description, pipeline: :single_line, author: commit.author))
.commiter
- = commit_author_link(commit, avatar: false, size: 24)
- #{ _('committed') }
- #{time_ago_with_tooltip(commit.committed_date)}
+ - commit_author_link = commit_author_link(commit, avatar: false, size: 24)
+ - commit_timeago = time_ago_with_tooltip(commit.committed_date)
+ - commit_text = _('%{commit_author_link} committed %{commit_timeago}') % { commit_author_link: commit_author_link, commit_timeago: commit_timeago }
+ #{ commit_text.html_safe }
+
.commit-actions.flex-row.hidden-xs
- if commit.status(ref)
diff --git a/app/views/projects/edit.html.haml b/app/views/projects/edit.html.haml
index c3dab68cea5..296e37e20e6 100644
--- a/app/views/projects/edit.html.haml
+++ b/app/views/projects/edit.html.haml
@@ -99,9 +99,9 @@
Git Large File Storage
= link_to icon('question-circle'), help_page_path('workflow/lfs/manage_large_binaries_with_git_lfs')
.col-md-3
- = f.select :lfs_enabled, [%w(Enabled true), %w(Disabled false)], {}, selected: @project.lfs_enabled?, class: 'pull-right form-control project-repo-select', data: { field: 'lfs_enabled' }
-
-
+ .select-wrapper
+ = f.select :lfs_enabled, [%w(Enabled true), %w(Disabled false)], {}, selected: @project.lfs_enabled?, class: 'pull-right form-control project-repo-select select-control', data: { field: 'lfs_enabled' }
+ = icon('chevron-down')
- if Gitlab.config.registry.enabled
.form-group.js-container-registry{ style: ("display: none;" if @project.project_feature.send(:repository_access_level) == 0) }
.checkbox
diff --git a/app/views/projects/issues/_issue_by_email.html.haml b/app/views/projects/issues/_issue_by_email.html.haml
index da65157a10b..35b7d1b920c 100644
--- a/app/views/projects/issues/_issue_by_email.html.haml
+++ b/app/views/projects/issues/_issue_by_email.html.haml
@@ -20,7 +20,7 @@
%p
The subject will be used as the title of the new issue, and the message will be the description.
- = link_to 'Slash commands', help_page_path('user/project/slash_commands'), target: '_blank', tabindex: -1
+ = link_to 'Quick actions', help_page_path('user/project/quick_actions'), target: '_blank', tabindex: -1
and styling with
= link_to 'Markdown', help_page_path('user/markdown'), target: '_blank', tabindex: -1
are supported.
diff --git a/app/views/projects/issues/show.html.haml b/app/views/projects/issues/show.html.haml
index 5f92d020eef..d909b0bfbbd 100644
--- a/app/views/projects/issues/show.html.haml
+++ b/app/views/projects/issues/show.html.haml
@@ -5,13 +5,6 @@
- can_update_issue = can?(current_user, :update_issue, @issue)
- can_report_spam = @issue.submittable_as_spam_by?(current_user)
-- if defined?(@issue) && @issue.confidential?
- .confidential-issue-warning{ data: { spy: 'affix' } }
- %span.confidential-issue-text
- #{confidential_icon(@issue)} This issue is confidential.
- %a{ href: help_page_path('user/project/issues/confidential_issues'), target: '_blank' }
- What are confidential issues?
-
.clearfix.detail-page-header
.issuable-header
.issuable-status-box.status-box.status-box-closed{ class: issue_button_visibility(@issue, false) }
@@ -26,6 +19,7 @@
= icon('angle-double-left')
.issuable-meta
+ = confidential_icon(@issue)
= issuable_meta(@issue, @project, "Issue")
.issuable-actions
diff --git a/app/views/projects/merge_requests/conflicts/_submit_form.html.haml b/app/views/projects/merge_requests/conflicts/_submit_form.html.haml
index 62c9748c510..e675e1830d0 100644
--- a/app/views/projects/merge_requests/conflicts/_submit_form.html.haml
+++ b/app/views/projects/merge_requests/conflicts/_submit_form.html.haml
@@ -1,7 +1,7 @@
.form-horizontal.resolve-conflicts-form
.form-group
%label.col-sm-2.control-label{ "for" => "commit-message" }
- Commit message
+ #{ _('Commit message') }
.col-sm-10
.commit-message-container
.max-width-marker
diff --git a/app/views/projects/notes/_more_actions_dropdown.html.haml b/app/views/projects/notes/_more_actions_dropdown.html.haml
index e0d45054854..75a4687e1e3 100644
--- a/app/views/projects/notes/_more_actions_dropdown.html.haml
+++ b/app/views/projects/notes/_more_actions_dropdown.html.haml
@@ -1,14 +1,19 @@
-.dropdown.more-actions
- = button_tag title: 'More actions', class: 'note-action-button more-actions-toggle has-tooltip btn btn-transparent', data: { toggle: 'dropdown', container: 'body' } do
- = icon('ellipsis-v', class: 'icon')
- %ul.dropdown-menu.more-actions-dropdown.dropdown-open-left
- %li
- = button_tag 'Edit comment', class: 'js-note-edit btn btn-transparent'
- %li.divider
- %li
- = link_to new_abuse_report_path(user_id: note.author.id, ref_url: noteable_note_url(note)) do
- Report as abuse
- - if note_editable
- %li
- = link_to note_url(note), method: :delete, data: { confirm: 'Are you sure you want to delete this comment?' }, remote: true, class: 'js-note-delete' do
- %span.text-danger Delete comment
+- is_current_user = current_user == note.author
+
+- if note_editable || !is_current_user
+ .dropdown.more-actions
+ = button_tag title: 'More actions', class: 'note-action-button more-actions-toggle has-tooltip btn btn-transparent', data: { toggle: 'dropdown', container: 'body' } do
+ = icon('ellipsis-v', class: 'icon')
+ %ul.dropdown-menu.more-actions-dropdown.dropdown-open-left
+ - if note_editable
+ %li
+ = button_tag 'Edit comment', class: 'js-note-edit btn btn-transparent'
+ %li.divider
+ - unless is_current_user
+ %li
+ = link_to new_abuse_report_path(user_id: note.author.id, ref_url: noteable_note_url(note)) do
+ Report as abuse
+ - if note_editable
+ %li
+ = link_to note_url(note), method: :delete, data: { confirm: 'Are you sure you want to delete this comment?' }, remote: true, class: 'js-note-delete' do
+ %span.text-danger Delete comment
diff --git a/app/views/projects/pipeline_schedules/_form.html.haml b/app/views/projects/pipeline_schedules/_form.html.haml
index e8dedf26206..fc7fa5c1876 100644
--- a/app/views/projects/pipeline_schedules/_form.html.haml
+++ b/app/views/projects/pipeline_schedules/_form.html.haml
@@ -7,7 +7,7 @@
.form-group
.col-md-9
= f.label :description, _('Description'), class: 'label-light'
- = f.text_field :description, class: 'form-control', required: true, autofocus: true, placeholder: _('PipelineSchedules|Provide a short description for this pipeline')
+ = f.text_field :description, class: 'form-control', required: true, autofocus: true, placeholder: s_('PipelineSchedules|Provide a short description for this pipeline')
.form-group
.col-md-9
= f.label :cron, _('Interval Pattern'), class: 'label-light'
@@ -15,19 +15,19 @@
.form-group
.col-md-9
= f.label :cron_timezone, _('Cron Timezone'), class: 'label-light'
- = dropdown_tag(_("Select a timezone"), options: { toggle_class: 'btn js-timezone-dropdown', title: _("Select a timezone"), filter: true, placeholder: _("Filter"), data: { data: timezone_data } } )
+ = dropdown_tag(_("Select a timezone"), options: { toggle_class: 'btn js-timezone-dropdown', title: _("Select a timezone"), filter: true, placeholder: s_("OfSearchInADropdown|Filter"), data: { data: timezone_data } } )
= f.text_field :cron_timezone, value: @schedule.cron_timezone, id: 'schedule_cron_timezone', class: 'hidden', name: 'schedule[cron_timezone]', required: true
.form-group
.col-md-9
= f.label :ref, _('Target Branch'), class: 'label-light'
- = dropdown_tag(_("Select target branch"), options: { toggle_class: 'btn js-target-branch-dropdown', dropdown_class: 'git-revision-dropdown', title: _("Select target branch"), filter: true, placeholder: _("Filter"), data: { data: @project.repository.branch_names, default_branch: @project.default_branch } } )
+ = dropdown_tag(_("Select target branch"), options: { toggle_class: 'btn js-target-branch-dropdown', dropdown_class: 'git-revision-dropdown', title: _("Select target branch"), filter: true, placeholder: s_("OfSearchInADropdown|Filter"), data: { data: @project.repository.branch_names, default_branch: @project.default_branch } } )
= f.text_field :ref, value: @schedule.ref, id: 'schedule_ref', class: 'hidden', name: 'schedule[ref]', required: true
.form-group
.col-md-9
- = f.label :active, _('PipelineSchedules|Activated'), class: 'label-light'
+ = f.label :active, s_('PipelineSchedules|Activated'), class: 'label-light'
%div
= f.check_box :active, required: false, value: @schedule.active?
- Active
+ = _('Active')
.footer-block.row-content-block
= f.submit _('Save pipeline schedule'), class: 'btn btn-create', tabindex: 3
= link_to _('Cancel'), pipeline_schedules_path(@project), class: 'btn btn-cancel'
diff --git a/app/views/projects/pipeline_schedules/_pipeline_schedule.html.haml b/app/views/projects/pipeline_schedules/_pipeline_schedule.html.haml
index 2d3344a4aaf..966d6cd8495 100644
--- a/app/views/projects/pipeline_schedules/_pipeline_schedule.html.haml
+++ b/app/views/projects/pipeline_schedules/_pipeline_schedule.html.haml
@@ -13,12 +13,12 @@
= ci_icon_for_status(pipeline_schedule.last_pipeline.status)
%span ##{pipeline_schedule.last_pipeline.id}
- else
- = _("PipelineSchedules|None")
+ = s_("PipelineSchedules|None")
%td.next-run-cell
- if pipeline_schedule.active?
= time_ago_with_tooltip(pipeline_schedule.real_next_run)
- else
- = _("PipelineSchedules|Inactive")
+ = s_("PipelineSchedules|Inactive")
%td
- if pipeline_schedule.owner
= image_tag avatar_icon(pipeline_schedule.owner, 20), class: "avatar s20"
diff --git a/app/views/projects/pipeline_schedules/index.html.haml b/app/views/projects/pipeline_schedules/index.html.haml
index 4a96ee652d2..c296152e54f 100644
--- a/app/views/projects/pipeline_schedules/index.html.haml
+++ b/app/views/projects/pipeline_schedules/index.html.haml
@@ -14,7 +14,7 @@
.nav-controls
= link_to new_namespace_project_pipeline_schedule_path(@project.namespace, @project), class: 'btn btn-create' do
- %span New schedule
+ %span= _('New schedule')
- if @schedules.present?
%ul.content-list
diff --git a/app/views/projects/project_members/_new_project_member.html.haml b/app/views/projects/project_members/_new_project_member.html.haml
index 247c4bdbe2d..8bf2246662a 100644
--- a/app/views/projects/project_members/_new_project_member.html.haml
+++ b/app/views/projects/project_members/_new_project_member.html.haml
@@ -6,7 +6,9 @@
= users_select_tag(:user_ids, multiple: true, class: "input-clamp", scope: :all, email_user: true, placeholder: "Search for members to update or invite")
.form-group
= label_tag :access_level, "Choose a role permission", class: "label-light"
- = select_tag :access_level, options_for_select(ProjectMember.access_level_roles, @project_member.access_level), class: "form-control project-access-select"
+ .select-wrapper
+ = select_tag :access_level, options_for_select(ProjectMember.access_level_roles, @project_member.access_level), class: "form-control project-access-select select-control"
+ = icon('chevron-down')
.help-block.append-bottom-10
= link_to "Read more", help_page_path("user/permissions"), class: "vlink"
about role permissions
diff --git a/app/views/projects/project_members/_new_shared_group.html.haml b/app/views/projects/project_members/_new_shared_group.html.haml
index b7cc8dd7062..643569db646 100644
--- a/app/views/projects/project_members/_new_shared_group.html.haml
+++ b/app/views/projects/project_members/_new_shared_group.html.haml
@@ -8,7 +8,7 @@
= label_tag :link_group_access, "Max access level", class: "label-light"
.select-wrapper
= select_tag :link_group_access, options_for_select(ProjectGroupLink.access_options, ProjectGroupLink.default_access), class: "form-control select-control"
- = icon('caret-down')
+ = icon('chevron-down')
.help-block.append-bottom-10
= link_to "Read more", help_page_path("user/permissions"), class: "vlink"
about role permissions
diff --git a/app/views/projects/registry/repositories/_image.html.haml b/app/views/projects/registry/repositories/_image.html.haml
index 8bc78f8d018..dcdc432b654 100644
--- a/app/views/projects/registry/repositories/_image.html.haml
+++ b/app/views/projects/registry/repositories/_image.html.haml
@@ -6,13 +6,14 @@
= clipboard_button(clipboard_text: "docker pull #{image.location}")
- .controls.hidden-xs.pull-right
- = link_to namespace_project_container_registry_path(@project.namespace, @project, image),
- class: 'btn btn-remove has-tooltip',
- title: 'Remove repository',
- data: { confirm: 'Are you sure?' },
- method: :delete do
- = icon('trash cred', 'aria-hidden': 'true')
+ - if can?(current_user, :update_container_image, @project)
+ .controls.hidden-xs.pull-right
+ = link_to namespace_project_container_registry_path(@project.namespace, @project, image),
+ class: 'btn btn-remove has-tooltip',
+ title: 'Remove repository',
+ data: { confirm: 'Are you sure?' },
+ method: :delete do
+ = icon('trash cred', 'aria-hidden': 'true')
.container-image-tags.js-toggle-content.hide
- if image.has_tags?
diff --git a/app/views/projects/tree/_tree_header.html.haml b/app/views/projects/tree/_tree_header.html.haml
index abde2a48587..00da76349da 100644
--- a/app/views/projects/tree/_tree_header.html.haml
+++ b/app/views/projects/tree/_tree_header.html.haml
@@ -1,79 +1,81 @@
-.tree-controls
- = render 'projects/find_file_link'
-
- = link_to s_('Commits|History'), namespace_project_commits_path(@project.namespace, @project, @id), class: 'btn btn-grouped'
-
- = render 'projects/buttons/download', project: @project, ref: @ref
+.tree-ref-container
+ .tree-ref-holder
+ = render 'shared/ref_switcher', destination: 'tree', path: @path
-.tree-ref-holder
- = render 'shared/ref_switcher', destination: 'tree', path: @path
-
-%ul.breadcrumb.repo-breadcrumb
- %li
- = link_to namespace_project_tree_path(@project.namespace, @project, @ref) do
- = @project.path
- - path_breadcrumbs do |title, path|
+ %ul.breadcrumb.repo-breadcrumb
%li
- = link_to truncate(title, length: 40), namespace_project_tree_path(@project.namespace, @project, tree_join(@ref, path))
+ = link_to namespace_project_tree_path(@project.namespace, @project, @ref) do
+ = @project.path
+ - path_breadcrumbs do |title, path|
+ %li
+ = link_to truncate(title, length: 40), namespace_project_tree_path(@project.namespace, @project, tree_join(@ref, path))
- - if current_user
- %li
- - if !on_top_of_branch?
- %span.btn.add-to-tree.disabled.has-tooltip{ title: _("You can only add files when you are on a branch"), data: { container: 'body' } }
- = icon('plus')
- - else
- %span.dropdown
- %a.dropdown-toggle.btn.add-to-tree{ href: '#', "data-toggle" => "dropdown" }
+ - if current_user
+ %li
+ - if !on_top_of_branch?
+ %span.btn.add-to-tree.disabled.has-tooltip{ title: _("You can only add files when you are on a branch"), data: { container: 'body' } }
= icon('plus')
- %ul.dropdown-menu
- - if can_edit_tree?
- %li
- = link_to namespace_project_new_blob_path(@project.namespace, @project, @id) do
- = icon('pencil fw')
- #{ _('New file') }
- %li
- = link_to '#modal-upload-blob', { 'data-target' => '#modal-upload-blob', 'data-toggle' => 'modal' } do
- = icon('file fw')
- #{ _('Upload file') }
- %li
- = link_to '#modal-create-new-dir', { 'data-target' => '#modal-create-new-dir', 'data-toggle' => 'modal' } do
- = icon('folder fw')
- #{ _('New directory') }
- - elsif can?(current_user, :fork_project, @project)
- %li
- - continue_params = { to: namespace_project_new_blob_path(@project.namespace, @project, @id),
- notice: edit_in_new_fork_notice,
- notice_now: edit_in_new_fork_notice_now }
- - fork_path = namespace_project_forks_path(@project.namespace, @project, namespace_key: current_user.namespace.id,
- continue: continue_params)
- = link_to fork_path, method: :post do
- = icon('pencil fw')
- #{ _('New file') }
+ - else
+ %span.dropdown
+ %a.dropdown-toggle.btn.add-to-tree{ href: '#', "data-toggle" => "dropdown", "data-target" => ".add-to-tree-dropdown" }
+ = icon('plus')
+ .add-to-tree-dropdown
+ %ul.dropdown-menu
+ - if can_edit_tree?
+ %li
+ = link_to namespace_project_new_blob_path(@project.namespace, @project, @id) do
+ = icon('pencil fw')
+ #{ _('New file') }
+ %li
+ = link_to '#modal-upload-blob', { 'data-target' => '#modal-upload-blob', 'data-toggle' => 'modal' } do
+ = icon('file fw')
+ #{ _('Upload file') }
+ %li
+ = link_to '#modal-create-new-dir', { 'data-target' => '#modal-create-new-dir', 'data-toggle' => 'modal' } do
+ = icon('folder fw')
+ #{ _('New directory') }
+ - elsif can?(current_user, :fork_project, @project)
+ %li
+ - continue_params = { to: namespace_project_new_blob_path(@project.namespace, @project, @id),
+ notice: edit_in_new_fork_notice,
+ notice_now: edit_in_new_fork_notice_now }
+ - fork_path = namespace_project_forks_path(@project.namespace, @project, namespace_key: current_user.namespace.id,
+ continue: continue_params)
+ = link_to fork_path, method: :post do
+ = icon('pencil fw')
+ #{ _('New file') }
+ %li
+ - continue_params = { to: request.fullpath,
+ notice: edit_in_new_fork_notice + " Try to upload a file again.",
+ notice_now: edit_in_new_fork_notice_now }
+ - fork_path = namespace_project_forks_path(@project.namespace, @project, namespace_key: current_user.namespace.id,
+ continue: continue_params)
+ = link_to fork_path, method: :post do
+ = icon('file fw')
+ #{ _('Upload file') }
+ %li
+ - continue_params = { to: request.fullpath,
+ notice: edit_in_new_fork_notice + " Try to create a new directory again.",
+ notice_now: edit_in_new_fork_notice_now }
+ - fork_path = namespace_project_forks_path(@project.namespace, @project, namespace_key: current_user.namespace.id,
+ continue: continue_params)
+ = link_to fork_path, method: :post do
+ = icon('folder fw')
+ #{ _('New directory') }
+
+ %li.divider
%li
- - continue_params = { to: request.fullpath,
- notice: edit_in_new_fork_notice + " Try to upload a file again.",
- notice_now: edit_in_new_fork_notice_now }
- - fork_path = namespace_project_forks_path(@project.namespace, @project, namespace_key: current_user.namespace.id,
- continue: continue_params)
- = link_to fork_path, method: :post do
- = icon('file fw')
- #{ _('Upload file') }
+ = link_to new_namespace_project_branch_path(@project.namespace, @project) do
+ = icon('code-fork fw')
+ #{ _('New branch') }
%li
- - continue_params = { to: request.fullpath,
- notice: edit_in_new_fork_notice + " Try to create a new directory again.",
- notice_now: edit_in_new_fork_notice_now }
- - fork_path = namespace_project_forks_path(@project.namespace, @project, namespace_key: current_user.namespace.id,
- continue: continue_params)
- = link_to fork_path, method: :post do
- = icon('folder fw')
- #{ _('New directory') }
+ = link_to new_namespace_project_tag_path(@project.namespace, @project) do
+ = icon('tags fw')
+ #{ _('New tag') }
+
+.tree-controls
+ = render 'projects/find_file_link'
- %li.divider
- %li
- = link_to new_namespace_project_branch_path(@project.namespace, @project) do
- = icon('code-fork fw')
- #{ _('New branch') }
- %li
- = link_to new_namespace_project_tag_path(@project.namespace, @project) do
- = icon('tags fw')
- #{ _('New tag') }
+ = link_to s_('Commits|History'), namespace_project_commits_path(@project.namespace, @project, @id), class: 'btn'
+
+ = render 'projects/buttons/download', project: @project, ref: @ref
diff --git a/app/views/shared/_commit_message_container.html.haml b/app/views/shared/_commit_message_container.html.haml
index 4b98ff88241..2329de9e11f 100644
--- a/app/views/shared/_commit_message_container.html.haml
+++ b/app/views/shared/_commit_message_container.html.haml
@@ -2,7 +2,7 @@
- nonce = SecureRandom.hex
- descriptions = local_assigns.slice(:message_with_description, :message_without_description)
= label_tag "commit_message-#{nonce}", class: 'control-label' do
- Commit message
+ #{ _('Commit message') }
.col-sm-10
.commit-message-container
.max-width-marker
diff --git a/app/views/shared/_new_commit_form.html.haml b/app/views/shared/_new_commit_form.html.haml
index 25a56f84ec5..0a4a24ae807 100644
--- a/app/views/shared/_new_commit_form.html.haml
+++ b/app/views/shared/_new_commit_form.html.haml
@@ -5,16 +5,12 @@
- else
- if can?(current_user, :push_code, @project)
.form-group.branch
- = label_tag 'branch_name', 'Target branch', class: 'control-label'
+ = label_tag 'branch_name', _('Target Branch'), class: 'control-label'
.col-sm-10
= text_field_tag 'branch_name', @branch_name || tree_edit_branch, required: true, class: "form-control js-branch-name ref-name"
.js-create-merge-request-container
- .checkbox
- - nonce = SecureRandom.hex
- = label_tag "create_merge_request-#{nonce}" do
- = check_box_tag 'create_merge_request', 1, true, class: 'js-create-merge-request', id: "create_merge_request-#{nonce}"
- Start a <strong>new merge request</strong> with these changes
+ = render 'shared/new_merge_request_checkbox'
- else
= hidden_field_tag 'branch_name', @branch_name || tree_edit_branch
= hidden_field_tag 'create_merge_request', 1
diff --git a/app/views/shared/_new_merge_request_checkbox.html.haml b/app/views/shared/_new_merge_request_checkbox.html.haml
new file mode 100644
index 00000000000..133c31f09c4
--- /dev/null
+++ b/app/views/shared/_new_merge_request_checkbox.html.haml
@@ -0,0 +1,8 @@
+.checkbox
+ - nonce = SecureRandom.hex
+ = label_tag "create_merge_request-#{nonce}" do
+ = check_box_tag 'create_merge_request', 1, true, class: 'js-create-merge-request', id: "create_merge_request-#{nonce}"
+ - translation_variables = { new_merge_request: "<strong>#{_('new merge request')}</strong>" }
+ - translation = _('Start a %{new_merge_request} with these changes') % translation_variables
+ #{ translation.html_safe }
+
diff --git a/app/views/shared/form_elements/_description.html.haml b/app/views/shared/form_elements/_description.html.haml
index 307d4919224..f65bb6a29e6 100644
--- a/app/views/shared/form_elements/_description.html.haml
+++ b/app/views/shared/form_elements/_description.html.haml
@@ -2,10 +2,10 @@
- model = local_assigns.fetch(:model)
- form = local_assigns.fetch(:form)
-- supports_slash_commands = model.new_record?
+- supports_quick_actions = model.new_record?
-- if supports_slash_commands
- - preview_url = preview_markdown_path(project, slash_commands_target_type: model.class.name)
+- if supports_quick_actions
+ - preview_url = preview_markdown_path(project, quick_actions_target_type: model.class.name)
- else
- preview_url = preview_markdown_path(project)
@@ -17,7 +17,7 @@
= render 'projects/zen', f: form, attr: :description,
classes: 'note-textarea',
placeholder: "Write a comment or drag your files here...",
- supports_slash_commands: supports_slash_commands
- = render 'shared/notes/hints', supports_slash_commands: supports_slash_commands
+ supports_quick_actions: supports_quick_actions
+ = render 'shared/notes/hints', supports_quick_actions: supports_quick_actions
.clearfix
.error-alert
diff --git a/app/views/shared/issuable/_bulk_update_sidebar.html.haml b/app/views/shared/issuable/_bulk_update_sidebar.html.haml
index a8a6d84128d..7cfdfb6e6ee 100644
--- a/app/views/shared/issuable/_bulk_update_sidebar.html.haml
+++ b/app/views/shared/issuable/_bulk_update_sidebar.html.haml
@@ -1,7 +1,7 @@
- type = local_assigns.fetch(:type)
%aside.issues-bulk-update.js-right-sidebar.right-sidebar.affix-top{ data: { "offset-top" => "50", "spy" => "affix" }, "aria-live" => "polite" }
- .issuable-sidebar
+ .issuable-sidebar.hidden
= form_tag [:bulk_update, @project.namespace.becomes(Namespace), @project, type], method: :post, class: "bulk-update" do
.block
.filter-item.inline.update-issues-btn.pull-left
diff --git a/app/views/shared/issuable/_nav.html.haml b/app/views/shared/issuable/_nav.html.haml
index cf7ba52d840..3f03cc7a275 100644
--- a/app/views/shared/issuable/_nav.html.haml
+++ b/app/views/shared/issuable/_nav.html.haml
@@ -1,24 +1,25 @@
- type = local_assigns.fetch(:type, :issues)
- page_context_word = type.to_s.humanize(capitalize: false)
- issuables = @issues || @merge_requests
-- closed_title = 'Filter by issues that are currently closed.'
%ul.nav-links.issues-state-filters
%li{ class: active_when(params[:state] == 'opened') }>
- %button.btn.btn-link{ id: 'state-opened', title: "Filter by #{page_context_word} that are currently opened.", type: 'button', data: { state: 'opened' } }
+ = link_to page_filter_path(state: 'opened', label: true), id: 'state-opened', title: "Filter by #{page_context_word} that are currently opened.", data: { state: 'opened' } do
#{issuables_state_counter_text(type, :opened)}
- if type == :merge_requests
%li{ class: active_when(params[:state] == 'merged') }>
- %button.btn.btn-link{ id: 'state-merged', title: 'Filter by merge requests that are currently merged.', type: 'button', data: { state: 'merged' } }
+ = link_to page_filter_path(state: 'merged', label: true), id: 'state-merged', title: 'Filter by merge requests that are currently merged.', data: { state: 'merged' } do
#{issuables_state_counter_text(type, :merged)}
- - closed_title = 'Filter by merge requests that are currently closed and unmerged.'
-
- %li{ class: active_when(params[:state] == 'closed') }>
- %button.btn.btn-link{ id: 'state-closed', title: closed_title, type: 'button', data: { state: 'closed' } }
- #{issuables_state_counter_text(type, :closed)}
+ %li{ class: active_when(params[:state] == 'closed') }>
+ = link_to page_filter_path(state: 'closed', label: true), id: 'state-closed', title: 'Filter by merge requests that are currently closed and unmerged.', data: { state: 'closed' } do
+ #{issuables_state_counter_text(type, :closed)}
+ - else
+ %li{ class: active_when(params[:state] == 'closed') }>
+ = link_to page_filter_path(state: 'closed', label: true), id: 'state-closed', title: 'Filter by issues that are currently closed.', data: { state: 'closed' } do
+ #{issuables_state_counter_text(type, :closed)}
%li{ class: active_when(params[:state] == 'all') }>
- %button.btn.btn-link{ id: 'state-all', title: "Show all #{page_context_word}.", type: 'button', data: { state: 'all' } }
+ = link_to page_filter_path(state: 'all', label: true), id: 'state-all', title: "Show all #{page_context_word}.", data: { state: 'all' } do
#{issuables_state_counter_text(type, :all)}
diff --git a/app/views/shared/milestones/_issuables.html.haml b/app/views/shared/milestones/_issuables.html.haml
index 8af3bd597c5..7175e275f95 100644
--- a/app/views/shared/milestones/_issuables.html.haml
+++ b/app/views/shared/milestones/_issuables.html.haml
@@ -8,11 +8,11 @@
= title
- if show_counter
.counter
- = number_with_delimiter(issuables.size)
+ = number_with_delimiter(issuables.length)
- class_prefix = dom_class(issuables).pluralize
- %ul{ class: "well-list #{class_prefix}-sortable-list", id: "#{class_prefix}-list-#{id}", "data-state" => id }
+ %ul{ class: "well-list milestone-#{class_prefix}-list", id: "#{class_prefix}-list-#{id}" }
= render partial: 'shared/milestones/issuable',
- collection: issuables.order_position_asc,
+ collection: issuables,
as: :issuable,
locals: { show_project_name: show_project_name, show_full_project_name: show_full_project_name }
diff --git a/app/views/shared/milestones/_tabs.html.haml b/app/views/shared/milestones/_tabs.html.haml
index 6a6d817b344..4de8a6cb15f 100644
--- a/app/views/shared/milestones/_tabs.html.haml
+++ b/app/views/shared/milestones/_tabs.html.haml
@@ -31,12 +31,12 @@
.tab-content.milestone-content
- if milestone.is_a?(GlobalMilestone) || can?(current_user, :read_issue, @project)
.tab-pane.active#tab-issues{ data: { sort_endpoint: (sort_issues_namespace_project_milestone_path(@project.namespace, @project, @milestone) if @project && current_user) } }
- = render 'shared/milestones/issues_tab', issues: milestone.issues_visible_to_user(current_user).include_associations, show_project_name: show_project_name, show_full_project_name: show_full_project_name
- .tab-pane#tab-merge-requests{ data: { sort_endpoint: (sort_merge_requests_namespace_project_milestone_path(@project.namespace, @project, @milestone) if @project && current_user) } }
+ = render 'shared/milestones/issues_tab', issues: milestone.sorted_issues(current_user), show_project_name: show_project_name, show_full_project_name: show_full_project_name
+ .tab-pane#tab-merge-requests
-# loaded async
= render "shared/milestones/tab_loading"
- else
- .tab-pane.active#tab-merge-requests{ data: { sort_endpoint: (sort_merge_requests_namespace_project_milestone_path(@project.namespace, @project, @milestone) if @project && current_user) } }
+ .tab-pane.active#tab-merge-requests
-# loaded async
= render "shared/milestones/tab_loading"
.tab-pane#tab-participants
diff --git a/app/views/shared/notes/_form.html.haml b/app/views/shared/notes/_form.html.haml
index eaf50bc2115..c6b5dcc3647 100644
--- a/app/views/shared/notes/_form.html.haml
+++ b/app/views/shared/notes/_form.html.haml
@@ -1,6 +1,7 @@
-- supports_slash_commands = note_supports_slash_commands?(@note)
-- if supports_slash_commands
- - preview_url = preview_markdown_path(@project, slash_commands_target_type: @note.noteable_type, slash_commands_target_id: @note.noteable_id)
+- supports_autocomplete = local_assigns.fetch(:supports_autocomplete, true)
+- supports_quick_actions = note_supports_quick_actions?(@note)
+- if supports_quick_actions
+ - preview_url = preview_markdown_path(@project, quick_actions_target_type: @note.noteable_type, quick_actions_target_id: @note.noteable_id)
- else
- preview_url = preview_markdown_path(@project)
@@ -27,8 +28,9 @@
attr: :note,
classes: 'note-textarea js-note-text',
placeholder: "Write a comment or drag your files here...",
- supports_slash_commands: supports_slash_commands
- = render 'shared/notes/hints', supports_slash_commands: supports_slash_commands
+ supports_quick_actions: supports_quick_actions,
+ supports_autocomplete: supports_autocomplete
+ = render 'shared/notes/hints', supports_quick_actions: supports_quick_actions
.error-alert
.note-form-actions.clearfix
diff --git a/app/views/shared/notes/_hints.html.haml b/app/views/shared/notes/_hints.html.haml
index 7ce6130de60..bc1ac3d8ac2 100644
--- a/app/views/shared/notes/_hints.html.haml
+++ b/app/views/shared/notes/_hints.html.haml
@@ -1,10 +1,10 @@
-- supports_slash_commands = local_assigns.fetch(:supports_slash_commands, false)
+- supports_quick_actions = local_assigns.fetch(:supports_quick_actions, false)
.comment-toolbar.clearfix
.toolbar-text
= link_to 'Markdown', help_page_path('user/markdown'), target: '_blank', tabindex: -1
- - if supports_slash_commands
+ - if supports_quick_actions
and
- = link_to 'slash commands', help_page_path('user/project/slash_commands'), target: '_blank', tabindex: -1
+ = link_to 'quick actions', help_page_path('user/project/quick_actions'), target: '_blank', tabindex: -1
are
- else
is
diff --git a/app/views/shared/notes/_notes_with_form.html.haml b/app/views/shared/notes/_notes_with_form.html.haml
index 5902798dfd0..f0fcc414756 100644
--- a/app/views/shared/notes/_notes_with_form.html.haml
+++ b/app/views/shared/notes/_notes_with_form.html.haml
@@ -6,13 +6,14 @@
- if can_create_note?
%ul.notes.notes-form.timeline
%li.timeline-entry
- .flash-container.timeline-content
+ .timeline-entry-inner
+ .flash-container.timeline-content
- .timeline-icon.hidden-xs.hidden-sm
- %a.author_link{ href: user_path(current_user) }
- = image_tag avatar_icon(current_user), alt: current_user.to_reference, class: 'avatar s40'
- .timeline-content.timeline-content-form
- = render "shared/notes/form", view: diff_view
+ .timeline-icon.hidden-xs.hidden-sm
+ %a.author_link{ href: user_path(current_user) }
+ = image_tag avatar_icon(current_user), alt: current_user.to_reference, class: 'avatar s40'
+ .timeline-content.timeline-content-form
+ = render "shared/notes/form", view: diff_view, supports_autocomplete: autocomplete
- elsif !current_user
.disabled-comment.text-center.prepend-top-default
Please
diff --git a/app/workers/merge_worker.rb b/app/workers/merge_worker.rb
index 79efca4f2f9..48e2da338f6 100644
--- a/app/workers/merge_worker.rb
+++ b/app/workers/merge_worker.rb
@@ -7,7 +7,7 @@ class MergeWorker
current_user = User.find(current_user_id)
merge_request = MergeRequest.find(merge_request_id)
- MergeRequests::MergeService.new(merge_request.target_project, current_user, params).
- execute(merge_request)
+ MergeRequests::MergeService.new(merge_request.target_project, current_user, params)
+ .execute(merge_request)
end
end
diff --git a/app/workers/process_commit_worker.rb b/app/workers/process_commit_worker.rb
index fe6a49976e0..c0c03848a40 100644
--- a/app/workers/process_commit_worker.rb
+++ b/app/workers/process_commit_worker.rb
@@ -47,8 +47,8 @@ class ProcessCommitWorker
# therefor we use IssueCollection here and skip the authorization check in
# Issues::CloseService#execute.
IssueCollection.new(issues).updatable_by_user(user).each do |issue|
- Issues::CloseService.new(project, author).
- close_issue(issue, commit: commit)
+ Issues::CloseService.new(project, author)
+ .close_issue(issue, commit: commit)
end
end
@@ -57,8 +57,8 @@ class ProcessCommitWorker
return if mentioned_issues.empty?
- Issue::Metrics.where(issue_id: mentioned_issues.map(&:id), first_mentioned_in_commit_at: nil).
- update_all(first_mentioned_in_commit_at: commit.committed_date)
+ Issue::Metrics.where(issue_id: mentioned_issues.map(&:id), first_mentioned_in_commit_at: nil)
+ .update_all(first_mentioned_in_commit_at: commit.committed_date)
end
def build_commit(project, hash)
diff --git a/app/workers/project_cache_worker.rb b/app/workers/project_cache_worker.rb
index 8ff9d07860f..505ff9e086e 100644
--- a/app/workers/project_cache_worker.rb
+++ b/app/workers/project_cache_worker.rb
@@ -32,8 +32,8 @@ class ProjectCacheWorker
private
def try_obtain_lease_for(project_id, section)
- Gitlab::ExclusiveLease.
- new("project_cache_worker:#{project_id}:#{section}", timeout: LEASE_TIMEOUT).
- try_obtain
+ Gitlab::ExclusiveLease
+ .new("project_cache_worker:#{project_id}:#{section}", timeout: LEASE_TIMEOUT)
+ .try_obtain
end
end
diff --git a/app/workers/propagate_service_template_worker.rb b/app/workers/propagate_service_template_worker.rb
index 5ce0e0405d0..6b607451c7a 100644
--- a/app/workers/propagate_service_template_worker.rb
+++ b/app/workers/propagate_service_template_worker.rb
@@ -14,8 +14,8 @@ class PropagateServiceTemplateWorker
private
def try_obtain_lease_for(template_id)
- Gitlab::ExclusiveLease.
- new("propagate_service_template_worker:#{template_id}", timeout: LEASE_TIMEOUT).
- try_obtain
+ Gitlab::ExclusiveLease
+ .new("propagate_service_template_worker:#{template_id}", timeout: LEASE_TIMEOUT)
+ .try_obtain
end
end
diff --git a/app/workers/prune_old_events_worker.rb b/app/workers/prune_old_events_worker.rb
index 392abb9c21b..2b43bb19ad1 100644
--- a/app/workers/prune_old_events_worker.rb
+++ b/app/workers/prune_old_events_worker.rb
@@ -10,9 +10,9 @@ class PruneOldEventsWorker
'(id IN (SELECT id FROM (?) ids_to_remove))',
Event.unscoped.where(
'created_at < ?',
- (12.months + 1.day).ago).
- select(:id).
- limit(10_000)).
- delete_all
+ (12.months + 1.day).ago)
+ .select(:id)
+ .limit(10_000))
+ .delete_all
end
end
diff --git a/app/workers/repository_check/batch_worker.rb b/app/workers/repository_check/batch_worker.rb
index c3e7491ec4e..b94d83bd709 100644
--- a/app/workers/repository_check/batch_worker.rb
+++ b/app/workers/repository_check/batch_worker.rb
@@ -32,10 +32,10 @@ module RepositoryCheck
# has to sit and wait for this query to finish.
def project_ids
limit = 10_000
- never_checked_projects = Project.where('last_repository_check_at IS NULL AND created_at < ?', 24.hours.ago).
- limit(limit).pluck(:id)
- old_check_projects = Project.where('last_repository_check_at < ?', 1.month.ago).
- reorder('last_repository_check_at ASC').limit(limit).pluck(:id)
+ never_checked_projects = Project.where('last_repository_check_at IS NULL AND created_at < ?', 24.hours.ago)
+ .limit(limit).pluck(:id)
+ old_check_projects = Project.where('last_repository_check_at < ?', 1.month.ago)
+ .reorder('last_repository_check_at ASC').limit(limit).pluck(:id)
never_checked_projects + old_check_projects
end
diff --git a/app/workers/update_user_activity_worker.rb b/app/workers/update_user_activity_worker.rb
index b3c2f13aa33..31bbdb69edb 100644
--- a/app/workers/update_user_activity_worker.rb
+++ b/app/workers/update_user_activity_worker.rb
@@ -7,8 +7,8 @@ class UpdateUserActivityWorker
ids = pairs.keys
conditions = 'WHEN id = ? THEN ? ' * ids.length
- User.where(id: ids).
- update_all([
+ User.where(id: ids)
+ .update_all([
"last_activity_on = CASE #{conditions} ELSE last_activity_on END",
*pairs.to_a.flatten
])
diff --git a/changelogs/unreleased/12151-add-since-and-until-params-to-issuables.yml b/changelogs/unreleased/12151-add-since-and-until-params-to-issuables.yml
new file mode 100644
index 00000000000..2c915e62357
--- /dev/null
+++ b/changelogs/unreleased/12151-add-since-and-until-params-to-issuables.yml
@@ -0,0 +1,4 @@
+---
+title: Added "created_after" and "created_before" params to issuables
+merge_request: 12151
+author: Kyle Bishop @kybishop
diff --git a/changelogs/unreleased/25102-files-view-button.yml b/changelogs/unreleased/25102-files-view-button.yml
new file mode 100644
index 00000000000..4ba815d9464
--- /dev/null
+++ b/changelogs/unreleased/25102-files-view-button.yml
@@ -0,0 +1,4 @@
+---
+title: Fix mobile view of files view buttons
+merge_request:
+author:
diff --git a/changelogs/unreleased/25164-disable-fork-on-project-limit.yml b/changelogs/unreleased/25164-disable-fork-on-project-limit.yml
new file mode 100644
index 00000000000..9fa824b161d
--- /dev/null
+++ b/changelogs/unreleased/25164-disable-fork-on-project-limit.yml
@@ -0,0 +1,4 @@
+---
+title: Disable fork button on project limit
+merge_request: 12145
+author: Ivan Chernov
diff --git a/changelogs/unreleased/26212-upload-user-avatar-trough-api.yml b/changelogs/unreleased/26212-upload-user-avatar-trough-api.yml
new file mode 100644
index 00000000000..667454ae95d
--- /dev/null
+++ b/changelogs/unreleased/26212-upload-user-avatar-trough-api.yml
@@ -0,0 +1,4 @@
+---
+title: Accept image for avatar in user API
+merge_request: 12143
+author: Ivan Chernov
diff --git a/changelogs/unreleased/27070-rename-slash-commands-to-quick-actions.yml b/changelogs/unreleased/27070-rename-slash-commands-to-quick-actions.yml
new file mode 100644
index 00000000000..497239db808
--- /dev/null
+++ b/changelogs/unreleased/27070-rename-slash-commands-to-quick-actions.yml
@@ -0,0 +1,5 @@
+---
+title: Rename "Slash commands" to "Quick actions" and deprecate "chat commands" in favor
+ of "slash commands"
+merge_request:
+author:
diff --git a/changelogs/unreleased/27645-html-email-brackets-bug.yml b/changelogs/unreleased/27645-html-email-brackets-bug.yml
new file mode 100644
index 00000000000..e8004d03884
--- /dev/null
+++ b/changelogs/unreleased/27645-html-email-brackets-bug.yml
@@ -0,0 +1,4 @@
+---
+title: Fix an email parsing bug where brackets would be inserted in emails from some Outlook clients
+merge_request: 9045
+author: jneen
diff --git a/changelogs/unreleased/27697-make-arrow-icons-consistent-in-dropdown.yml b/changelogs/unreleased/27697-make-arrow-icons-consistent-in-dropdown.yml
new file mode 100644
index 00000000000..92b5b59f46f
--- /dev/null
+++ b/changelogs/unreleased/27697-make-arrow-icons-consistent-in-dropdown.yml
@@ -0,0 +1,4 @@
+---
+title: Use fa-chevron-down on dropdown arrows for consistency
+merge_request: 9659
+author: TM Lee
diff --git a/changelogs/unreleased/28139-use-color-input-broadcast-messages.yml b/changelogs/unreleased/28139-use-color-input-broadcast-messages.yml
new file mode 100644
index 00000000000..97ebabaff1c
--- /dev/null
+++ b/changelogs/unreleased/28139-use-color-input-broadcast-messages.yml
@@ -0,0 +1,4 @@
+---
+title: Use color inputs for broadcast messages
+merge_request:
+author:
diff --git a/changelogs/unreleased/30213-project-transfer-move-rollback.yml b/changelogs/unreleased/30213-project-transfer-move-rollback.yml
new file mode 100644
index 00000000000..3eb1e399c54
--- /dev/null
+++ b/changelogs/unreleased/30213-project-transfer-move-rollback.yml
@@ -0,0 +1,4 @@
+---
+title: Rollback project repo move if there is an error in Projects::TransferService
+merge_request: 11877
+author:
diff --git a/changelogs/unreleased/30725-reset-user-limits-when-unchecking-external-user.yml b/changelogs/unreleased/30725-reset-user-limits-when-unchecking-external-user.yml
new file mode 100644
index 00000000000..3058404b3f8
--- /dev/null
+++ b/changelogs/unreleased/30725-reset-user-limits-when-unchecking-external-user.yml
@@ -0,0 +1,4 @@
+---
+title: Ensures default user limits when external user is unchecked
+merge_request: 12218
+author:
diff --git a/changelogs/unreleased/32301-filter-archive-project-on-param-present.yml b/changelogs/unreleased/32301-filter-archive-project-on-param-present.yml
new file mode 100644
index 00000000000..d6534ed4e1a
--- /dev/null
+++ b/changelogs/unreleased/32301-filter-archive-project-on-param-present.yml
@@ -0,0 +1,4 @@
+---
+title: Filter archived project in API v3 only if param present
+merge_request: 12245
+author: Ivan Chernov
diff --git a/changelogs/unreleased/33441-supplement_simplified_chinese_translation_of_i18n.yml b/changelogs/unreleased/33441-supplement_simplified_chinese_translation_of_i18n.yml
new file mode 100644
index 00000000000..a7d8ac9054b
--- /dev/null
+++ b/changelogs/unreleased/33441-supplement_simplified_chinese_translation_of_i18n.yml
@@ -0,0 +1,4 @@
+---
+title: Supplement Simplified Chinese translation of Project Page & Repository Page
+merge_request: 11994
+author: Huang Tao
diff --git a/changelogs/unreleased/33461-display-user-id.yml b/changelogs/unreleased/33461-display-user-id.yml
new file mode 100644
index 00000000000..cba94625b07
--- /dev/null
+++ b/changelogs/unreleased/33461-display-user-id.yml
@@ -0,0 +1,4 @@
+---
+title: Display own user id in account settings page
+merge_request: 12141
+author: Riccardo Padovani
diff --git a/changelogs/unreleased/33837-remove-trash-on-registry-image.yml b/changelogs/unreleased/33837-remove-trash-on-registry-image.yml
new file mode 100644
index 00000000000..2d337f5e6e4
--- /dev/null
+++ b/changelogs/unreleased/33837-remove-trash-on-registry-image.yml
@@ -0,0 +1,4 @@
+---
+title: Remove registry image delete button if user cant delete it
+merge_request: 12317
+author: Ivan Chernov
diff --git a/changelogs/unreleased/33878_fix_edit_deploy_key.yml b/changelogs/unreleased/33878_fix_edit_deploy_key.yml
new file mode 100644
index 00000000000..bc47d522240
--- /dev/null
+++ b/changelogs/unreleased/33878_fix_edit_deploy_key.yml
@@ -0,0 +1,4 @@
+---
+title: Fix edit button for deploy keys available from other projects
+merge_request: 12301
+author: Alexander Randa
diff --git a/changelogs/unreleased/33917-mr-comment-system-note-highlight-don-t-have-the-same-width.yml b/changelogs/unreleased/33917-mr-comment-system-note-highlight-don-t-have-the-same-width.yml
new file mode 100644
index 00000000000..f3b92878f6d
--- /dev/null
+++ b/changelogs/unreleased/33917-mr-comment-system-note-highlight-don-t-have-the-same-width.yml
@@ -0,0 +1,4 @@
+---
+title: Standardize timeline note margins across different viewport sizes
+merge_request: 12364
+author:
diff --git a/changelogs/unreleased/34008-fix-CI_ENVIRONMENT_URL-2.yml b/changelogs/unreleased/34008-fix-CI_ENVIRONMENT_URL-2.yml
new file mode 100644
index 00000000000..7f4d6e3bc67
--- /dev/null
+++ b/changelogs/unreleased/34008-fix-CI_ENVIRONMENT_URL-2.yml
@@ -0,0 +1,4 @@
+---
+title: Fix passing CI_ENVIRONMENT_NAME and CI_ENVIRONMENT_SLUG for CI_ENVIRONMENT_URL
+merge_request: 12344
+author:
diff --git a/changelogs/unreleased/disable-environment-list-refresh.yml b/changelogs/unreleased/disable-environment-list-refresh.yml
new file mode 100644
index 00000000000..62fd71496a0
--- /dev/null
+++ b/changelogs/unreleased/disable-environment-list-refresh.yml
@@ -0,0 +1,4 @@
+---
+title: Disable environment list refresh due to bug https://gitlab.com/gitlab-org/gitlab-ee/issues/2677
+merge_request: 12347
+author:
diff --git a/changelogs/unreleased/dt-printing-to-api.yml b/changelogs/unreleased/dt-printing-to-api.yml
new file mode 100644
index 00000000000..5253b57f21a
--- /dev/null
+++ b/changelogs/unreleased/dt-printing-to-api.yml
@@ -0,0 +1,4 @@
+---
+title: Added printing_merge_requst_link_enabled to the API
+merge_request:
+author: David Turner <dturner@twosigma.com>
diff --git a/changelogs/unreleased/fix-33259.yml b/changelogs/unreleased/fix-33259.yml
new file mode 100644
index 00000000000..c68e42c02cf
--- /dev/null
+++ b/changelogs/unreleased/fix-33259.yml
@@ -0,0 +1,4 @@
+---
+title: Fix GitHub importer performance on branch existence check
+merge_request:
+author:
diff --git a/changelogs/unreleased/fix-overflow-slash-commands.yml b/changelogs/unreleased/fix-overflow-slash-commands.yml
new file mode 100644
index 00000000000..98ec399e8cb
--- /dev/null
+++ b/changelogs/unreleased/fix-overflow-slash-commands.yml
@@ -0,0 +1,4 @@
+---
+title: Fixed overflow on mobile screens for the slash commands
+merge_request:
+author:
diff --git a/changelogs/unreleased/fixed-confidential-issue-bar.yml b/changelogs/unreleased/fixed-confidential-issue-bar.yml
deleted file mode 100644
index 6a41590d0af..00000000000
--- a/changelogs/unreleased/fixed-confidential-issue-bar.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Make confidential issues more obviously confidential
-merge_request:
-author:
diff --git a/changelogs/unreleased/issue_20900.yml b/changelogs/unreleased/issue_20900.yml
new file mode 100644
index 00000000000..e8cef6d2bce
--- /dev/null
+++ b/changelogs/unreleased/issue_20900.yml
@@ -0,0 +1,4 @@
+---
+title: Remove issues/merge requests drag n drop and sorting from milestone view
+merge_request:
+author:
diff --git a/changelogs/unreleased/issue_33205.yml b/changelogs/unreleased/issue_33205.yml
new file mode 100644
index 00000000000..54b442048d8
--- /dev/null
+++ b/changelogs/unreleased/issue_33205.yml
@@ -0,0 +1,4 @@
+---
+title: Fix API bug accepting wrong parameter to create merge request
+merge_request:
+author:
diff --git a/changelogs/unreleased/moved-submodules.yml b/changelogs/unreleased/moved-submodules.yml
new file mode 100644
index 00000000000..eee858717ed
--- /dev/null
+++ b/changelogs/unreleased/moved-submodules.yml
@@ -0,0 +1,4 @@
+---
+title: 'Handle renamed submodules in repository browser'
+merge_request: 10798
+author: David Turner
diff --git a/changelogs/unreleased/mr-widget-memory-usage-tech-debt-fix.yml b/changelogs/unreleased/mr-widget-memory-usage-tech-debt-fix.yml
new file mode 100644
index 00000000000..14b5493a246
--- /dev/null
+++ b/changelogs/unreleased/mr-widget-memory-usage-tech-debt-fix.yml
@@ -0,0 +1,4 @@
+---
+title: Changed utilities imports from ~ to relative paths
+merge_request:
+author:
diff --git a/changelogs/unreleased/reduce-sidekiq-wait-timings.yml b/changelogs/unreleased/reduce-sidekiq-wait-timings.yml
new file mode 100644
index 00000000000..4d23accc82e
--- /dev/null
+++ b/changelogs/unreleased/reduce-sidekiq-wait-timings.yml
@@ -0,0 +1,4 @@
+---
+title: Reduce time spent waiting for certain Sidekiq jobs to complete
+merge_request:
+author:
diff --git a/changelogs/unreleased/refactor-projects-finder-init-collection.yml b/changelogs/unreleased/refactor-projects-finder-init-collection.yml
new file mode 100644
index 00000000000..c8113419f21
--- /dev/null
+++ b/changelogs/unreleased/refactor-projects-finder-init-collection.yml
@@ -0,0 +1,5 @@
+---
+title: Refactor ProjectsFinder#init_collection to produce more efficient queries for
+ retrieving projects
+merge_request:
+author:
diff --git a/changelogs/unreleased/replase_spinach_spec_create-feature.yml b/changelogs/unreleased/replase_spinach_spec_create-feature.yml
new file mode 100644
index 00000000000..0613d195d56
--- /dev/null
+++ b/changelogs/unreleased/replase_spinach_spec_create-feature.yml
@@ -0,0 +1,4 @@
+---
+title: Replace 'create.feature' spinach test with an rspec analog
+merge_request: 12343
+author: @blackst0ne
diff --git a/config/boot.rb b/config/boot.rb
index db5ab918021..16de55d7a86 100644
--- a/config/boot.rb
+++ b/config/boot.rb
@@ -6,7 +6,9 @@ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
# set default directory for multiproces metrics gathering
-ENV['prometheus_multiproc_dir'] ||= 'tmp/prometheus_multiproc_dir'
+if ENV['RAILS_ENV'] == 'development' || ENV['RAILS_ENV'] == 'test'
+ ENV['prometheus_multiproc_dir'] ||= 'tmp/prometheus_multiproc_dir'
+end
# Default Bootsnap configuration from https://github.com/Shopify/bootsnap#usage
require 'bootsnap'
diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example
index 0b33783869b..43a8c0078ca 100644
--- a/config/gitlab.yml.example
+++ b/config/gitlab.yml.example
@@ -454,6 +454,10 @@ production: &base
# introduced in 9.0). Eventually Gitaly use will become mandatory and
# this option will disappear.
enabled: true
+ # Default Gitaly authentication token. Can be overriden per storage. Can
+ # be left blank when Gitaly is running locally on a Unix socket, which
+ # is the normal way to deploy Gitaly.
+ token:
#
# 4. Advanced settings
@@ -469,6 +473,7 @@ production: &base
default:
path: /home/git/repositories/
gitaly_address: unix:/home/git/gitlab/tmp/sockets/private/gitaly.socket # TCP connections are supported too (e.g. tcp://host:port)
+ # gitaly_token: 'special token' # Optional: override global gitaly.token for this storage.
## Backup settings
backup:
@@ -594,6 +599,7 @@ test:
gitaly_address: unix:tmp/tests/gitaly/gitaly.socket
gitaly:
enabled: true
+ token: secret
backup:
path: tmp/tests/backups
gitlab_shell:
diff --git a/config/initializers/8_metrics.rb b/config/initializers/8_metrics.rb
index 508b886d6a0..a0a63ddf8f0 100644
--- a/config/initializers/8_metrics.rb
+++ b/config/initializers/8_metrics.rb
@@ -154,8 +154,8 @@ if Gitlab::Metrics.enabled?
ActiveRecord::Querying.public_instance_methods(false).map(&:to_s)
)
- Gitlab::Metrics::Instrumentation.
- instrument_class_hierarchy(ActiveRecord::Base) do |klass, method|
+ Gitlab::Metrics::Instrumentation
+ .instrument_class_hierarchy(ActiveRecord::Base) do |klass, method|
# Instrumenting the ApplicationSetting class can lead to an infinite
# loop. Since the data is cached any way we don't really need to
# instrument it.
diff --git a/config/karma.config.js b/config/karma.config.js
index 978850e5d70..2f571978e08 100644
--- a/config/karma.config.js
+++ b/config/karma.config.js
@@ -54,6 +54,16 @@ module.exports = function(config) {
subdir: '.',
fixWebpackSourcePaths: true
};
+ karmaConfig.browserNoActivityTimeout = 60000; // 60 seconds
+ }
+
+ if (process.env.DEBUG) {
+ karmaConfig.logLevel = config.LOG_DEBUG;
+ process.env.CHROME_LOG_FILE = process.env.CHROME_LOG_FILE || 'chrome_debug.log';
+ }
+
+ if (process.env.CHROME_LOG_FILE) {
+ karmaConfig.customLaunchers.ChromeHeadlessCustom.flags.push('--enable-logging', '--v=1');
}
if (process.env.DEBUG) {
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 9d47425950a..8932db138d9 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -2,17 +2,63 @@
# See https://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points.
en:
- hello: "Hello world"
- errors:
- messages:
- label_already_exists_at_group_level: "already exists at group level for %{group}. Please choose another one."
- wrong_size: "is the wrong size (should be %{file_size})"
- size_too_small: "is too small (should be at least %{file_size})"
- size_too_big: "is too big (should be at most %{file_size})"
views:
pagination:
previous: "Prev"
next: "Next"
+ date:
+ abbr_day_names:
+ - Sun
+ - Mon
+ - Tue
+ - Wed
+ - Thu
+ - Fri
+ - Sat
+ abbr_month_names:
+ -
+ - Jan
+ - Feb
+ - Mar
+ - Apr
+ - May
+ - Jun
+ - Jul
+ - Aug
+ - Sep
+ - Oct
+ - Nov
+ - Dec
+ day_names:
+ - Sunday
+ - Monday
+ - Tuesday
+ - Wednesday
+ - Thursday
+ - Friday
+ - Saturday
+ formats:
+ default: "%Y-%m-%d"
+ long: "%B %d, %Y"
+ short: "%b %d"
+ month_names:
+ -
+ - January
+ - February
+ - March
+ - April
+ - May
+ - June
+ - July
+ - August
+ - September
+ - October
+ - November
+ - December
+ order:
+ - :year
+ - :month
+ - :day
datetime:
time_ago_in_words:
half_a_minute: "half a minute ago"
@@ -49,3 +95,158 @@ en:
almost_x_years:
one: "almost 1 year ago"
other: "almost %{count} years ago"
+ distance_in_words:
+ about_x_hours:
+ one: about 1 hour
+ other: about %{count} hours
+ about_x_months:
+ one: about 1 month
+ other: about %{count} months
+ about_x_years:
+ one: about 1 year
+ other: about %{count} years
+ almost_x_years:
+ one: almost 1 year
+ other: almost %{count} years
+ half_a_minute: half a minute
+ less_than_x_minutes:
+ one: less than a minute
+ other: less than %{count} minutes
+ less_than_x_seconds:
+ one: less than 1 second
+ other: less than %{count} seconds
+ over_x_years:
+ one: over 1 year
+ other: over %{count} years
+ x_days:
+ one: 1 day
+ other: "%{count} days"
+ x_minutes:
+ one: 1 minute
+ other: "%{count} minutes"
+ x_months:
+ one: 1 month
+ other: "%{count} months"
+ x_years:
+ one: 1 year
+ other: "%{count} years"
+ x_seconds:
+ one: 1 second
+ other: "%{count} seconds"
+ prompts:
+ day: Day
+ hour: Hour
+ minute: Minute
+ month: Month
+ second: Seconds
+ year: Year
+ errors:
+ format: "%{attribute} %{message}"
+ messages:
+ label_already_exists_at_group_level: "already exists at group level for %{group}. Please choose another one."
+ wrong_size: "is the wrong size (should be %{file_size})"
+ size_too_small: "is too small (should be at least %{file_size})"
+ size_too_big: "is too big (should be at most %{file_size})"
+ accepted: must be accepted
+ blank: can't be blank
+ present: must be blank
+ confirmation: doesn't match %{attribute}
+ empty: can't be empty
+ equal_to: must be equal to %{count}
+ even: must be even
+ exclusion: is reserved
+ greater_than: must be greater than %{count}
+ greater_than_or_equal_to: must be greater than or equal to %{count}
+ inclusion: is not included in the list
+ invalid: is invalid
+ less_than: must be less than %{count}
+ less_than_or_equal_to: must be less than or equal to %{count}
+ model_invalid: "Validation failed: %{errors}"
+ not_a_number: is not a number
+ not_an_integer: must be an integer
+ odd: must be odd
+ required: must exist
+ taken: has already been taken
+ too_long:
+ one: is too long (maximum is 1 character)
+ other: is too long (maximum is %{count} characters)
+ too_short:
+ one: is too short (minimum is 1 character)
+ other: is too short (minimum is %{count} characters)
+ wrong_length:
+ one: is the wrong length (should be 1 character)
+ other: is the wrong length (should be %{count} characters)
+ other_than: must be other than %{count}
+ template:
+ body: 'There were problems with the following fields:'
+ header:
+ one: 1 error prohibited this %{model} from being saved
+ other: "%{count} errors prohibited this %{model} from being saved"
+ helpers:
+ select:
+ prompt: Please select
+ submit:
+ create: Create %{model}
+ submit: Save %{model}
+ update: Update %{model}
+ number:
+ currency:
+ format:
+ delimiter: ","
+ format: "%u%n"
+ precision: 2
+ separator: "."
+ significant: false
+ strip_insignificant_zeros: false
+ unit: "$"
+ format:
+ delimiter: ","
+ precision: 3
+ separator: "."
+ significant: false
+ strip_insignificant_zeros: false
+ human:
+ decimal_units:
+ format: "%n %u"
+ units:
+ billion: Billion
+ million: Million
+ quadrillion: Quadrillion
+ thousand: Thousand
+ trillion: Trillion
+ unit: ''
+ format:
+ delimiter: ''
+ precision: 3
+ significant: true
+ strip_insignificant_zeros: true
+ storage_units:
+ format: "%n %u"
+ units:
+ byte:
+ one: Byte
+ other: Bytes
+ gb: GB
+ kb: KB
+ mb: MB
+ tb: TB
+ percentage:
+ format:
+ delimiter: ''
+ format: "%n%"
+ precision:
+ format:
+ delimiter: ''
+ support:
+ array:
+ last_word_connector: ", and "
+ two_words_connector: " and "
+ words_connector: ", "
+ time:
+ am: am
+ formats:
+ default: "%a, %d %b %Y %H:%M:%S %z"
+ long: "%B %d, %Y %H:%M"
+ short: "%d %b %H:%M"
+ timeago_tooltip: "%b %-d, %Y %-l:%M%P"
+ pm: pm
diff --git a/config/locales/es.yml b/config/locales/es.yml
index d71c6eb5047..fdc52b4ae11 100644
--- a/config/locales/es.yml
+++ b/config/locales/es.yml
@@ -251,4 +251,5 @@ es:
default: "%A, %d de %B de %Y %H:%M:%S %z"
long: "%d de %B de %Y %H:%M"
short: "%d de %b %H:%M"
+ timeago_tooltip: "%d de %B de %Y %H:%M"
pm: pm
diff --git a/config/webpack.config.js b/config/webpack.config.js
index 04a25edcdb2..f27b7cae310 100644
--- a/config/webpack.config.js
+++ b/config/webpack.config.js
@@ -11,22 +11,13 @@ var WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeMod
var ROOT_PATH = path.resolve(__dirname, '..');
var IS_PRODUCTION = process.env.NODE_ENV === 'production';
-var IS_DEV_SERVER = process.argv[1].indexOf('webpack-dev-server') !== -1;
+var IS_DEV_SERVER = process.argv.join(' ').indexOf('webpack-dev-server') !== -1;
var DEV_SERVER_HOST = process.env.DEV_SERVER_HOST || 'localhost';
var DEV_SERVER_PORT = parseInt(process.env.DEV_SERVER_PORT, 10) || 3808;
var DEV_SERVER_LIVERELOAD = process.env.DEV_SERVER_LIVERELOAD !== 'false';
var WEBPACK_REPORT = process.env.WEBPACK_REPORT;
var NO_COMPRESSION = process.env.NO_COMPRESSION;
-// optional dependency `node-zopfli` is unavailable on CentOS 6
-var ZOPFLI_AVAILABLE;
-try {
- require.resolve('node-zopfli');
- ZOPFLI_AVAILABLE = true;
-} catch(err) {
- ZOPFLI_AVAILABLE = false;
-}
-
var config = {
// because sqljs requires fs.
node: {
@@ -234,12 +225,12 @@ if (IS_PRODUCTION) {
// zopfli requires a lot of compute time and is disabled in CI
if (!NO_COMPRESSION) {
- config.plugins.push(
- new CompressionPlugin({
- asset: '[path].gz[query]',
- algorithm: ZOPFLI_AVAILABLE ? 'zopfli' : 'gzip',
- })
- );
+ // gracefully fall back to gzip if `node-zopfli` is unavailable (e.g. in CentOS 6)
+ try {
+ config.plugins.push(new CompressionPlugin({ algorithm: 'zopfli' }));
+ } catch(err) {
+ config.plugins.push(new CompressionPlugin({ algorithm: 'gzip' }));
+ }
}
}
diff --git a/db/fixtures/development/19_environments.rb b/db/fixtures/development/19_environments.rb
index 93214b9d3e7..c1bbc9af6d6 100644
--- a/db/fixtures/development/19_environments.rb
+++ b/db/fixtures/development/19_environments.rb
@@ -33,7 +33,7 @@ class Gitlab::Seeder::Environments
create_deployment!(
merge_request.source_project,
- "review/#{merge_request.source_branch}",
+ "review/#{merge_request.source_branch.gsub(/[^a-zA-Z0-9]/, '')}",
merge_request.source_branch,
merge_request.diff_head_sha
)
diff --git a/db/migrate/20161124141322_migrate_process_commit_worker_jobs.rb b/db/migrate/20161124141322_migrate_process_commit_worker_jobs.rb
index e5292cfba07..c0cb9d78748 100644
--- a/db/migrate/20161124141322_migrate_process_commit_worker_jobs.rb
+++ b/db/migrate/20161124141322_migrate_process_commit_worker_jobs.rb
@@ -6,9 +6,9 @@ class MigrateProcessCommitWorkerJobs < ActiveRecord::Migration
class Project < ActiveRecord::Base
def self.find_including_path(id)
- select("projects.*, CONCAT(namespaces.path, '/', projects.path) AS path_with_namespace").
- joins('INNER JOIN namespaces ON namespaces.id = projects.namespace_id').
- find_by(id: id)
+ select("projects.*, CONCAT(namespaces.path, '/', projects.path) AS path_with_namespace")
+ .joins('INNER JOIN namespaces ON namespaces.id = projects.namespace_id')
+ .find_by(id: id)
end
def repository_storage_path
diff --git a/db/migrate/20161207231620_fixup_environment_name_uniqueness.rb b/db/migrate/20161207231620_fixup_environment_name_uniqueness.rb
index a20a903a752..f73e4f6c99b 100644
--- a/db/migrate/20161207231620_fixup_environment_name_uniqueness.rb
+++ b/db/migrate/20161207231620_fixup_environment_name_uniqueness.rb
@@ -8,11 +8,11 @@ class FixupEnvironmentNameUniqueness < ActiveRecord::Migration
environments = Arel::Table.new(:environments)
# Get all [project_id, name] pairs that occur more than once
- finder_sql = environments.
- group(environments[:project_id], environments[:name]).
- having(Arel.sql("COUNT(1)").gt(1)).
- project(environments[:project_id], environments[:name]).
- to_sql
+ finder_sql = environments
+ .group(environments[:project_id], environments[:name])
+ .having(Arel.sql("COUNT(1)").gt(1))
+ .project(environments[:project_id], environments[:name])
+ .to_sql
conflicting = connection.exec_query(finder_sql)
@@ -28,12 +28,12 @@ class FixupEnvironmentNameUniqueness < ActiveRecord::Migration
# Rename conflicting environments by appending "-#{id}" to all but the first
def fix_duplicates(project_id, name)
environments = Arel::Table.new(:environments)
- finder_sql = environments.
- where(environments[:project_id].eq(project_id)).
- where(environments[:name].eq(name)).
- order(environments[:id].asc).
- project(environments[:id], environments[:name]).
- to_sql
+ finder_sql = environments
+ .where(environments[:project_id].eq(project_id))
+ .where(environments[:name].eq(name))
+ .order(environments[:id].asc)
+ .project(environments[:id], environments[:name])
+ .to_sql
# Now we have the data for all the conflicting rows
conflicts = connection.exec_query(finder_sql).rows
@@ -41,11 +41,11 @@ class FixupEnvironmentNameUniqueness < ActiveRecord::Migration
conflicts.each do |id, name|
update_sql =
- Arel::UpdateManager.new(ActiveRecord::Base).
- table(environments).
- set(environments[:name] => name + "-" + id.to_s).
- where(environments[:id].eq(id)).
- to_sql
+ Arel::UpdateManager.new(ActiveRecord::Base)
+ .table(environments)
+ .set(environments[:name] => name + "-" + id.to_s)
+ .where(environments[:id].eq(id))
+ .to_sql
connection.exec_update(update_sql, self.class.name, [])
end
diff --git a/db/migrate/20161207231626_add_environment_slug.rb b/db/migrate/20161207231626_add_environment_slug.rb
index 8e98ee5b9ba..83cdd484c4c 100644
--- a/db/migrate/20161207231626_add_environment_slug.rb
+++ b/db/migrate/20161207231626_add_environment_slug.rb
@@ -19,10 +19,10 @@ class AddEnvironmentSlug < ActiveRecord::Migration
finder = environments.project(:id, :name)
connection.exec_query(finder.to_sql).rows.each do |id, name|
- updater = Arel::UpdateManager.new(ActiveRecord::Base).
- table(environments).
- set(environments[:slug] => generate_slug(name)).
- where(environments[:id].eq(id))
+ updater = Arel::UpdateManager.new(ActiveRecord::Base)
+ .table(environments)
+ .set(environments[:slug] => generate_slug(name))
+ .where(environments[:id].eq(id))
connection.exec_update(updater.to_sql, self.class.name, [])
end
diff --git a/db/migrate/20170316163800_rename_system_namespaces.rb b/db/migrate/20170316163800_rename_system_namespaces.rb
index b5408fbf112..9e9fb5ac225 100644
--- a/db/migrate/20170316163800_rename_system_namespaces.rb
+++ b/db/migrate/20170316163800_rename_system_namespaces.rb
@@ -159,9 +159,9 @@ class RenameSystemNamespaces < ActiveRecord::Migration
end
def system_namespace
- @system_namespace ||= Namespace.where(parent_id: nil).
- where(arel_table[:path].matches(system_namespace_path)).
- first
+ @system_namespace ||= Namespace.where(parent_id: nil)
+ .where(arel_table[:path].matches(system_namespace_path))
+ .first
end
def system_namespace_path
@@ -209,8 +209,8 @@ class RenameSystemNamespaces < ActiveRecord::Migration
end
def repo_paths_for_namespace(namespace)
- projects_for_namespace(namespace).distinct.
- select(:repository_storage).map(&:repository_storage_path)
+ projects_for_namespace(namespace).distinct
+ .select(:repository_storage).map(&:repository_storage_path)
end
def uploads_dir
diff --git a/db/migrate/20170503140202_turn_nested_groups_into_regular_groups_for_mysql.rb b/db/migrate/20170503140202_turn_nested_groups_into_regular_groups_for_mysql.rb
index c67690642c9..33908ae1156 100644
--- a/db/migrate/20170503140202_turn_nested_groups_into_regular_groups_for_mysql.rb
+++ b/db/migrate/20170503140202_turn_nested_groups_into_regular_groups_for_mysql.rb
@@ -87,8 +87,8 @@ class TurnNestedGroupsIntoRegularGroupsForMysql < ActiveRecord::Migration
while current&.parent_id
# We're using find_by(id: ...) here to deal with cases where the
# parent_id may point to a missing row.
- current = Namespace.unscoped.select([:id, :parent_id]).
- find_by(id: current.parent_id)
+ current = Namespace.unscoped.select([:id, :parent_id])
+ .find_by(id: current.parent_id)
ancestors << current.id if current
end
@@ -99,11 +99,11 @@ class TurnNestedGroupsIntoRegularGroupsForMysql < ActiveRecord::Migration
# Returns a relation containing all the members that have access to any of
# the current namespace's parent namespaces.
def all_members_for(namespace)
- Member.
- unscoped.
- select(['user_id', 'MAX(access_level) AS access_level']).
- where(source_type: 'Namespace', source_id: ancestors_for(namespace)).
- group(:user_id)
+ Member
+ .unscoped
+ .select(['user_id', 'MAX(access_level) AS access_level'])
+ .where(source_type: 'Namespace', source_id: ancestors_for(namespace))
+ .group(:user_id)
end
def bulk_insert_members(rows)
diff --git a/db/migrate/20170526185602_add_stage_id_to_ci_builds.rb b/db/migrate/20170526185602_add_stage_id_to_ci_builds.rb
index d5675d5828b..d27cba76d81 100644
--- a/db/migrate/20170526185602_add_stage_id_to_ci_builds.rb
+++ b/db/migrate/20170526185602_add_stage_id_to_ci_builds.rb
@@ -3,19 +3,11 @@ class AddStageIdToCiBuilds < ActiveRecord::Migration
DOWNTIME = false
- disable_ddl_transaction!
-
def up
add_column :ci_builds, :stage_id, :integer
-
- add_concurrent_foreign_key :ci_builds, :ci_stages, column: :stage_id, on_delete: :cascade
- add_concurrent_index :ci_builds, :stage_id
end
def down
- remove_foreign_key :ci_builds, column: :stage_id
- remove_concurrent_index :ci_builds, :stage_id
-
remove_column :ci_builds, :stage_id, :integer
end
end
diff --git a/db/migrate/20170608171156_create_merge_request_diff_files.rb b/db/migrate/20170608171156_create_merge_request_diff_files.rb
new file mode 100644
index 00000000000..bf0c0d29adc
--- /dev/null
+++ b/db/migrate/20170608171156_create_merge_request_diff_files.rb
@@ -0,0 +1,22 @@
+class CreateMergeRequestDiffFiles < ActiveRecord::Migration
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ def change
+ create_table :merge_request_diff_files, id: false do |t|
+ t.belongs_to :merge_request_diff, null: false, foreign_key: { on_delete: :cascade }
+ t.integer :relative_order, null: false
+ t.boolean :new_file, null: false
+ t.boolean :renamed_file, null: false
+ t.boolean :deleted_file, null: false
+ t.boolean :too_large, null: false
+ t.string :a_mode, null: false
+ t.string :b_mode, null: false
+ t.text :new_path, null: false
+ t.text :old_path, null: false
+ t.text :diff, null: false
+ t.index [:merge_request_diff_id, :relative_order], name: 'index_merge_request_diff_files_on_mr_diff_id_and_order', unique: true
+ end
+ end
+end
diff --git a/db/migrate/20170614115405_merge_request_diff_file_limits_to_mysql.rb b/db/migrate/20170614115405_merge_request_diff_file_limits_to_mysql.rb
new file mode 100644
index 00000000000..4c1cf08aa06
--- /dev/null
+++ b/db/migrate/20170614115405_merge_request_diff_file_limits_to_mysql.rb
@@ -0,0 +1 @@
+require_relative 'merge_request_diff_file_limits_to_mysql'
diff --git a/db/migrate/20170619144837_add_index_for_head_pipeline_merge_request.rb b/db/migrate/20170619144837_add_index_for_head_pipeline_merge_request.rb
new file mode 100644
index 00000000000..02863bee082
--- /dev/null
+++ b/db/migrate/20170619144837_add_index_for_head_pipeline_merge_request.rb
@@ -0,0 +1,15 @@
+class AddIndexForHeadPipelineMergeRequest < ActiveRecord::Migration
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_index :merge_requests, :head_pipeline_id
+ end
+
+ def down
+ remove_concurrent_index :merge_requests, :head_pipeline_id if index_exists?(:merge_requests, :head_pipeline_id)
+ end
+end
diff --git a/db/migrate/merge_request_diff_file_limits_to_mysql.rb b/db/migrate/merge_request_diff_file_limits_to_mysql.rb
new file mode 100644
index 00000000000..3958380e4b9
--- /dev/null
+++ b/db/migrate/merge_request_diff_file_limits_to_mysql.rb
@@ -0,0 +1,12 @@
+class MergeRequestDiffFileLimitsToMysql < ActiveRecord::Migration
+ DOWNTIME = false
+
+ def up
+ return unless Gitlab::Database.mysql?
+
+ change_column :merge_request_diff_files, :diff, :text, limit: 2147483647
+ end
+
+ def down
+ end
+end
diff --git a/db/post_migrate/20161109150329_fix_project_records_with_invalid_visibility.rb b/db/post_migrate/20161109150329_fix_project_records_with_invalid_visibility.rb
index 14b5ef476f0..69007b8e8ed 100644
--- a/db/post_migrate/20161109150329_fix_project_records_with_invalid_visibility.rb
+++ b/db/post_migrate/20161109150329_fix_project_records_with_invalid_visibility.rb
@@ -13,13 +13,13 @@ class FixProjectRecordsWithInvalidVisibility < ActiveRecord::Migration
namespaces = Arel::Table.new(:namespaces)
finder_sql =
- projects.
- join(namespaces, Arel::Nodes::InnerJoin).
- on(projects[:namespace_id].eq(namespaces[:id])).
- where(projects[:visibility_level].gt(namespaces[:visibility_level])).
- project(projects[:id], namespaces[:visibility_level]).
- take(BATCH_SIZE).
- to_sql
+ projects
+ .join(namespaces, Arel::Nodes::InnerJoin)
+ .on(projects[:namespace_id].eq(namespaces[:id]))
+ .where(projects[:visibility_level].gt(namespaces[:visibility_level]))
+ .project(projects[:id], namespaces[:visibility_level])
+ .take(BATCH_SIZE)
+ .to_sql
# Update matching rows in batches. Each batch can cause up to 3 UPDATE
# statements, in addition to the SELECT: one per visibility_level
@@ -33,10 +33,10 @@ class FixProjectRecordsWithInvalidVisibility < ActiveRecord::Migration
end
updates.each do |visibility_level, project_ids|
- updater = Arel::UpdateManager.new(ActiveRecord::Base).
- table(projects).
- set(projects[:visibility_level] => visibility_level).
- where(projects[:id].in(project_ids))
+ updater = Arel::UpdateManager.new(ActiveRecord::Base)
+ .table(projects)
+ .set(projects[:visibility_level] => visibility_level)
+ .where(projects[:id].in(project_ids))
ActiveRecord::Base.connection.exec_update(updater.to_sql, self.class.name, [])
end
diff --git a/db/post_migrate/20161221153951_rename_reserved_project_names.rb b/db/post_migrate/20161221153951_rename_reserved_project_names.rb
index 49a6bc884a8..d322844e2fd 100644
--- a/db/post_migrate/20161221153951_rename_reserved_project_names.rb
+++ b/db/post_migrate/20161221153951_rename_reserved_project_names.rb
@@ -79,17 +79,17 @@ class RenameReservedProjectNames < ActiveRecord::Migration
private
def reserved_projects
- Project.unscoped.
- includes(:namespace).
- where('EXISTS (SELECT 1 FROM namespaces WHERE projects.namespace_id = namespaces.id)').
- where('projects.path' => KNOWN_PATHS)
+ Project.unscoped
+ .includes(:namespace)
+ .where('EXISTS (SELECT 1 FROM namespaces WHERE projects.namespace_id = namespaces.id)')
+ .where('projects.path' => KNOWN_PATHS)
end
def route_exists?(full_path)
quoted_path = ActiveRecord::Base.connection.quote_string(full_path)
- ActiveRecord::Base.connection.
- select_all("SELECT id, path FROM routes WHERE path = '#{quoted_path}'").present?
+ ActiveRecord::Base.connection
+ .select_all("SELECT id, path FROM routes WHERE path = '#{quoted_path}'").present?
end
# Adds number to the end of the path that is not taken by other route
diff --git a/db/post_migrate/20170104150317_requeue_pending_delete_projects.rb b/db/post_migrate/20170104150317_requeue_pending_delete_projects.rb
index f399950bd5e..d7be004d47f 100644
--- a/db/post_migrate/20170104150317_requeue_pending_delete_projects.rb
+++ b/db/post_migrate/20170104150317_requeue_pending_delete_projects.rb
@@ -39,11 +39,11 @@ class RequeuePendingDeleteProjects < ActiveRecord::Migration
def find_batch
projects = Arel::Table.new(:projects)
- projects.project(projects[:id]).
- where(projects[:pending_delete].eq(true)).
- where(projects[:namespace_id].not_eq(nil)).
- skip(@offset * BATCH_SIZE).
- take(BATCH_SIZE).
- to_sql
+ projects.project(projects[:id])
+ .where(projects[:pending_delete].eq(true))
+ .where(projects[:namespace_id].not_eq(nil))
+ .skip(@offset * BATCH_SIZE)
+ .take(BATCH_SIZE)
+ .to_sql
end
end
diff --git a/db/post_migrate/20170106142508_fill_authorized_projects.rb b/db/post_migrate/20170106142508_fill_authorized_projects.rb
index 314c8440c8b..0ca20587981 100644
--- a/db/post_migrate/20170106142508_fill_authorized_projects.rb
+++ b/db/post_migrate/20170106142508_fill_authorized_projects.rb
@@ -15,8 +15,8 @@ class FillAuthorizedProjects < ActiveRecord::Migration
disable_ddl_transaction!
def up
- relation = User.select(:id).
- where('authorized_projects_populated IS NOT TRUE')
+ relation = User.select(:id)
+ .where('authorized_projects_populated IS NOT TRUE')
relation.find_in_batches(batch_size: 1_000) do |rows|
args = rows.map { |row| [row.id] }
diff --git a/db/post_migrate/20170313133418_rename_more_reserved_project_names.rb b/db/post_migrate/20170313133418_rename_more_reserved_project_names.rb
index 44c688fa134..6a49450cc50 100644
--- a/db/post_migrate/20170313133418_rename_more_reserved_project_names.rb
+++ b/db/post_migrate/20170313133418_rename_more_reserved_project_names.rb
@@ -21,17 +21,17 @@ class RenameMoreReservedProjectNames < ActiveRecord::Migration
private
def reserved_projects
- Project.unscoped.
- includes(:namespace).
- where('EXISTS (SELECT 1 FROM namespaces WHERE projects.namespace_id = namespaces.id)').
- where('projects.path' => KNOWN_PATHS)
+ Project.unscoped
+ .includes(:namespace)
+ .where('EXISTS (SELECT 1 FROM namespaces WHERE projects.namespace_id = namespaces.id)')
+ .where('projects.path' => KNOWN_PATHS)
end
def route_exists?(full_path)
quoted_path = ActiveRecord::Base.connection.quote_string(full_path)
- ActiveRecord::Base.connection.
- select_all("SELECT id, path FROM routes WHERE path = '#{quoted_path}'").present?
+ ActiveRecord::Base.connection
+ .select_all("SELECT id, path FROM routes WHERE path = '#{quoted_path}'").present?
end
# Adds number to the end of the path that is not taken by other route
diff --git a/db/post_migrate/20170324160416_migrate_user_activities_to_users_last_activity_on.rb b/db/post_migrate/20170324160416_migrate_user_activities_to_users_last_activity_on.rb
index 9ad36482c8a..397a9a2d28e 100644
--- a/db/post_migrate/20170324160416_migrate_user_activities_to_users_last_activity_on.rb
+++ b/db/post_migrate/20170324160416_migrate_user_activities_to_users_last_activity_on.rb
@@ -38,11 +38,11 @@ class MigrateUserActivitiesToUsersLastActivityOn < ActiveRecord::Migration
activities = activities(day.at_beginning_of_day, day.at_end_of_day, page: page)
update_sql =
- Arel::UpdateManager.new(ActiveRecord::Base).
- table(users_table).
- set(users_table[:last_activity_on] => day.to_date).
- where(users_table[:username].in(activities.map(&:first))).
- to_sql
+ Arel::UpdateManager.new(ActiveRecord::Base)
+ .table(users_table)
+ .set(users_table[:last_activity_on] => day.to_date)
+ .where(users_table[:username].in(activities.map(&:first)))
+ .to_sql
connection.exec_update(update_sql, self.class.name, [])
diff --git a/db/post_migrate/20170502070007_enable_auto_cancel_pending_pipelines_for_all.rb b/db/post_migrate/20170502070007_enable_auto_cancel_pending_pipelines_for_all.rb
index 3c13a3d2518..765daa0a347 100644
--- a/db/post_migrate/20170502070007_enable_auto_cancel_pending_pipelines_for_all.rb
+++ b/db/post_migrate/20170502070007_enable_auto_cancel_pending_pipelines_for_all.rb
@@ -7,6 +7,8 @@ class EnableAutoCancelPendingPipelinesForAll < ActiveRecord::Migration
DOWNTIME = false
def up
+ disable_statement_timeout
+
update_column_in_batches(:projects, :auto_cancel_pending_pipelines, 1)
end
diff --git a/db/post_migrate/20170502101023_cleanup_namespaceless_pending_delete_projects.rb b/db/post_migrate/20170502101023_cleanup_namespaceless_pending_delete_projects.rb
index ce52de91cdd..c1e64f20109 100644
--- a/db/post_migrate/20170502101023_cleanup_namespaceless_pending_delete_projects.rb
+++ b/db/post_migrate/20170502101023_cleanup_namespaceless_pending_delete_projects.rb
@@ -37,11 +37,11 @@ class CleanupNamespacelessPendingDeleteProjects < ActiveRecord::Migration
def find_batch
projects = Arel::Table.new(:projects)
- projects.project(projects[:id]).
- where(projects[:pending_delete].eq(true)).
- where(projects[:namespace_id].eq(nil)).
- skip(@offset * BATCH_SIZE).
- take(BATCH_SIZE).
- to_sql
+ projects.project(projects[:id])
+ .where(projects[:pending_delete].eq(true))
+ .where(projects[:namespace_id].eq(nil))
+ .skip(@offset * BATCH_SIZE)
+ .take(BATCH_SIZE)
+ .to_sql
end
end
diff --git a/db/post_migrate/20170508170547_add_head_pipeline_for_each_merge_request.rb b/db/post_migrate/20170508170547_add_head_pipeline_for_each_merge_request.rb
index bc3850c0c23..0a4a2d3867a 100644
--- a/db/post_migrate/20170508170547_add_head_pipeline_for_each_merge_request.rb
+++ b/db/post_migrate/20170508170547_add_head_pipeline_for_each_merge_request.rb
@@ -9,11 +9,11 @@ class AddHeadPipelineForEachMergeRequest < ActiveRecord::Migration
pipelines = Arel::Table.new(:ci_pipelines)
merge_requests = Arel::Table.new(:merge_requests)
- head_id = pipelines.
- project(Arel::Nodes::NamedFunction.new('max', [pipelines[:id]])).
- from(pipelines).
- where(pipelines[:ref].eq(merge_requests[:source_branch])).
- where(pipelines[:project_id].eq(merge_requests[:source_project_id]))
+ head_id = pipelines
+ .project(Arel::Nodes::NamedFunction.new('max', [pipelines[:id]]))
+ .from(pipelines)
+ .where(pipelines[:ref].eq(merge_requests[:source_branch]))
+ .where(pipelines[:project_id].eq(merge_requests[:source_project_id]))
sub_query = Arel::Nodes::SqlLiteral.new(Arel::Nodes::Grouping.new(head_id).to_sql)
diff --git a/db/post_migrate/20170526185901_remove_stage_id_index_from_builds.rb b/db/post_migrate/20170526185901_remove_stage_id_index_from_builds.rb
new file mode 100644
index 00000000000..3879cf9133b
--- /dev/null
+++ b/db/post_migrate/20170526185901_remove_stage_id_index_from_builds.rb
@@ -0,0 +1,18 @@
+class RemoveStageIdIndexFromBuilds < ActiveRecord::Migration
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ def up
+ if index_exists?(:ci_builds, :stage_id)
+ remove_foreign_key(:ci_builds, column: :stage_id)
+ remove_concurrent_index(:ci_builds, :stage_id)
+ end
+ end
+
+ def down
+ # noop
+ end
+end
diff --git a/db/post_migrate/20170526185921_migrate_build_stage_reference.rb b/db/post_migrate/20170526185921_migrate_build_stage_reference.rb
index 797e106cae4..98c32d8284c 100644
--- a/db/post_migrate/20170526185921_migrate_build_stage_reference.rb
+++ b/db/post_migrate/20170526185921_migrate_build_stage_reference.rb
@@ -3,23 +3,17 @@ class MigrateBuildStageReference < ActiveRecord::Migration
DOWNTIME = false
- def up
- disable_statement_timeout
-
- stage_id = Arel.sql <<-SQL.strip_heredoc
- (SELECT id FROM ci_stages
- WHERE ci_stages.pipeline_id = ci_builds.commit_id
- AND ci_stages.name = ci_builds.stage)
- SQL
+ ##
+ # This is an empty migration, content has been moved to a new one:
+ # post migrate 20170526190000 MigrateBuildStageReferenceAgain
+ #
+ # See gitlab-org/gitlab-ce!12337 for more details.
- update_column_in_batches(:ci_builds, :stage_id, stage_id) do |table, query|
- query.where(table[:stage_id].eq(nil))
- end
+ def up
+ # noop
end
def down
- disable_statement_timeout
-
- update_column_in_batches(:ci_builds, :stage_id, nil)
+ # noop
end
end
diff --git a/db/post_migrate/20170526190000_migrate_build_stage_reference_again.rb b/db/post_migrate/20170526190000_migrate_build_stage_reference_again.rb
new file mode 100644
index 00000000000..97cb242415d
--- /dev/null
+++ b/db/post_migrate/20170526190000_migrate_build_stage_reference_again.rb
@@ -0,0 +1,27 @@
+class MigrateBuildStageReferenceAgain < ActiveRecord::Migration
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ def up
+ disable_statement_timeout
+
+ stage_id = Arel.sql <<-SQL.strip_heredoc
+ (SELECT id FROM ci_stages
+ WHERE ci_stages.pipeline_id = ci_builds.commit_id
+ AND ci_stages.name = ci_builds.stage)
+ SQL
+
+ update_column_in_batches(:ci_builds, :stage_id, stage_id) do |table, query|
+ query.where(table[:stage_id].eq(nil))
+ end
+ end
+
+ def down
+ disable_statement_timeout
+
+ update_column_in_batches(:ci_builds, :stage_id, nil)
+ end
+end
diff --git a/db/post_migrate/20170609183112_remove_position_from_issuables.rb b/db/post_migrate/20170609183112_remove_position_from_issuables.rb
new file mode 100644
index 00000000000..4caaa2e83e8
--- /dev/null
+++ b/db/post_migrate/20170609183112_remove_position_from_issuables.rb
@@ -0,0 +1,8 @@
+class RemovePositionFromIssuables < ActiveRecord::Migration
+ DOWNTIME = false
+
+ def change
+ remove_column :issues, :position, :integer
+ remove_column :merge_requests, :position, :integer
+ end
+end
diff --git a/db/post_migrate/20170621102400_add_stage_id_index_to_builds.rb b/db/post_migrate/20170621102400_add_stage_id_index_to_builds.rb
new file mode 100644
index 00000000000..7d6609b18bf
--- /dev/null
+++ b/db/post_migrate/20170621102400_add_stage_id_index_to_builds.rb
@@ -0,0 +1,21 @@
+class AddStageIdIndexToBuilds < ActiveRecord::Migration
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ def up
+ unless index_exists?(:ci_builds, :stage_id)
+ add_concurrent_foreign_key(:ci_builds, :ci_stages, column: :stage_id, on_delete: :cascade)
+ add_concurrent_index(:ci_builds, :stage_id)
+ end
+ end
+
+ def down
+ if index_exists?(:ci_builds, :stage_id)
+ remove_foreign_key(:ci_builds, column: :stage_id)
+ remove_concurrent_index(:ci_builds, :stage_id)
+ end
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 956ca2278f4..028556bdccf 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: 20170607121233) do
+ActiveRecord::Schema.define(version: 20170621102400) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -547,7 +547,6 @@ ActiveRecord::Schema.define(version: 20170607121233) do
t.integer "project_id"
t.datetime "created_at"
t.datetime "updated_at"
- t.integer "position", default: 0
t.string "branch_name"
t.text "description"
t.integer "milestone_id"
@@ -693,6 +692,22 @@ ActiveRecord::Schema.define(version: 20170607121233) do
add_index "members", ["source_id", "source_type"], name: "index_members_on_source_id_and_source_type", using: :btree
add_index "members", ["user_id"], name: "index_members_on_user_id", using: :btree
+ create_table "merge_request_diff_files", id: false, force: :cascade do |t|
+ t.integer "merge_request_diff_id", null: false
+ t.integer "relative_order", null: false
+ t.boolean "new_file", null: false
+ t.boolean "renamed_file", null: false
+ t.boolean "deleted_file", null: false
+ t.boolean "too_large", null: false
+ t.string "a_mode", null: false
+ t.string "b_mode", null: false
+ t.text "new_path", null: false
+ t.text "old_path", null: false
+ t.text "diff", null: false
+ end
+
+ add_index "merge_request_diff_files", ["merge_request_diff_id", "relative_order"], name: "index_merge_request_diff_files_on_mr_diff_id_and_order", unique: true, using: :btree
+
create_table "merge_request_diffs", force: :cascade do |t|
t.string "state"
t.text "st_commits"
@@ -738,7 +753,6 @@ ActiveRecord::Schema.define(version: 20170607121233) do
t.integer "target_project_id", null: false
t.integer "iid"
t.text "description"
- t.integer "position", default: 0
t.datetime "locked_at"
t.integer "updated_by_id"
t.text "merge_error"
@@ -763,6 +777,7 @@ ActiveRecord::Schema.define(version: 20170607121233) do
add_index "merge_requests", ["created_at"], name: "index_merge_requests_on_created_at", using: :btree
add_index "merge_requests", ["deleted_at"], name: "index_merge_requests_on_deleted_at", using: :btree
add_index "merge_requests", ["description"], name: "index_merge_requests_on_description_trigram", using: :gin, opclasses: {"description"=>"gin_trgm_ops"}
+ add_index "merge_requests", ["head_pipeline_id"], name: "index_merge_requests_on_head_pipeline_id", using: :btree
add_index "merge_requests", ["milestone_id"], name: "index_merge_requests_on_milestone_id", using: :btree
add_index "merge_requests", ["source_branch"], name: "index_merge_requests_on_source_branch", using: :btree
add_index "merge_requests", ["source_project_id"], name: "index_merge_requests_on_source_project_id", using: :btree
@@ -1532,6 +1547,7 @@ ActiveRecord::Schema.define(version: 20170607121233) do
add_foreign_key "labels", "namespaces", column: "group_id", on_delete: :cascade
add_foreign_key "lists", "boards"
add_foreign_key "lists", "labels"
+ add_foreign_key "merge_request_diff_files", "merge_request_diffs", on_delete: :cascade
add_foreign_key "merge_request_metrics", "ci_pipelines", column: "pipeline_id", on_delete: :cascade
add_foreign_key "merge_request_metrics", "merge_requests", on_delete: :cascade
add_foreign_key "merge_requests_closing_issues", "issues", on_delete: :cascade
diff --git a/doc/README.md b/doc/README.md
index 775fffab2dd..ab8ea192a26 100644
--- a/doc/README.md
+++ b/doc/README.md
@@ -24,7 +24,7 @@ Shortcuts to GitLab's most visited docs:
- [GitLab Workflow](workflow/README.md): Enhance your workflow with the best of GitLab Workflow.
- See also [GitLab Workflow - an overview](https://about.gitlab.com/2016/10/25/gitlab-workflow-an-overview/).
- [GitLab Markdown](user/markdown.md): GitLab's advanced formatting system (GitLab Flavored Markdown).
-- [GitLab Slash Commands](user/project/slash_commands.md): Textual shortcuts for common actions on issues or merge requests that are usually done by clicking buttons or dropdowns in GitLab's UI.
+- [GitLab Quick Actions](user/project/quick_actions.md): Textual shortcuts for common actions on issues or merge requests that are usually done by clicking buttons or dropdowns in GitLab's UI.
### User account
diff --git a/doc/administration/high_availability/nfs.md b/doc/administration/high_availability/nfs.md
index d8e76d6ab94..bd6b7327aed 100644
--- a/doc/administration/high_availability/nfs.md
+++ b/doc/administration/high_availability/nfs.md
@@ -1,12 +1,35 @@
# NFS
-## Required NFS Server features
+You can view information and options set for each of the mounted NFS file
+systems by running `sudo nfsstat -m`.
+
+## NFS Server features
+
+### Required features
**File locking**: GitLab **requires** advisory file locking, which is only
supported natively in NFS version 4. NFSv3 also supports locking as long as
Linux Kernel 2.6.5+ is used. We recommend using version 4 and do not
specifically test NFSv3.
+### Recommended options
+
+When you define your NFS exports, we recommend you also add the following
+options:
+
+- `no_root_squash` - NFS normally changes the `root` user to `nobody`. This is
+ a good security measure when NFS shares will be accessed by many different
+ users. However, in this case only GitLab will use the NFS share so it
+ is safe. GitLab recommends the `no_root_squash` setting because we need to
+ manage file permissions automatically. Without the setting you may receive
+ errors when the Omnibus package tries to alter permissions. Note that GitLab
+ and other bundled components do **not** run as `root` but as non-privileged
+ users. The recommendation for `no_root_squash` is to allow the Omnibus package
+ to set ownership and permissions on files, as needed.
+- `sync` - Force synchronous behavior. Default is asynchronous and under certain
+ circumstances it could lead to data loss if a failure occurs before data has
+ synced.
+
## AWS Elastic File System
GitLab does not recommend using AWS Elastic File System (EFS).
@@ -26,27 +49,10 @@ GitLab does not recommend using EFS with GitLab.
For more details on another person's experience with EFS, see
[Amazon's Elastic File System: Burst Credits](https://www.rawkode.io/2017/04/amazons-elastic-file-system-burst-credits/)
-### Recommended options
-
-When you define your NFS exports, we recommend you also add the following
-options:
-
-- `no_root_squash` - NFS normally changes the `root` user to `nobody`. This is
- a good security measure when NFS shares will be accessed by many different
- users. However, in this case only GitLab will use the NFS share so it
- is safe. GitLab recommends the `no_root_squash` setting because we need to
- manage file permissions automatically. Without the setting you may receive
- errors when the Omnibus package tries to alter permissions. Note that GitLab
- and other bundled components do **not** run as `root` but as non-privileged
- users. The recommendation for `no_root_squash` is to allow the Omnibus package
- to set ownership and permissions on files, as needed.
-- `sync` - Force synchronous behavior. Default is asynchronous and under certain
- circumstances it could lead to data loss if a failure occurs before data has
- synced.
-
## NFS Client mount options
-Below is an example of an NFS mount point we use on GitLab.com:
+Below is an example of an NFS mount point defined in `/etc/fstab` we use on
+GitLab.com:
```
10.1.1.1:/var/opt/gitlab/git-data /var/opt/gitlab/git-data nfs4 defaults,soft,rsize=1048576,wsize=1048576,noatime,nobootwait,lookupcache=positive 0 2
diff --git a/doc/administration/high_availability/redis_source.md b/doc/administration/high_availability/redis_source.md
index 3629772b8af..fe982ea83c2 100644
--- a/doc/administration/high_availability/redis_source.md
+++ b/doc/administration/high_availability/redis_source.md
@@ -364,3 +364,4 @@ When in doubt, please read [Redis Sentinel documentation](http://redis.io/topics
[downloads]: https://about.gitlab.com/downloads
[restart]: ../restart_gitlab.md#installations-from-source
[it]: https://gitlab.com/gitlab-org/gitlab-ce/uploads/c4cc8cd353604bd80315f9384035ff9e/The_Internet_IT_Crowd.png
+[resque]: https://gitlab.com/gitlab-org/gitlab-ce/blob/master/config/resque.yml.example
diff --git a/doc/administration/job_artifacts.md b/doc/administration/job_artifacts.md
index 5599435564e..3587696225c 100644
--- a/doc/administration/job_artifacts.md
+++ b/doc/administration/job_artifacts.md
@@ -46,7 +46,10 @@ To disable artifacts site-wide, follow the steps below.
After a successful job, GitLab Runner uploads an archive containing the job
artifacts to GitLab.
-To change the location where the artifacts are stored, follow the steps below.
+### Using local storage
+
+To change the location where the artifacts are stored locally, follow the steps
+below.
---
@@ -82,6 +85,13 @@ _The artifacts are stored by default in
1. Save the file and [restart GitLab][] for the changes to take effect.
+### Using object storage
+
+In [GitLab Enterprise Edition Premium][eep] you can use an object storage like
+AWS S3 to store the artifacts.
+
+[Learn how to use the object storage option.][ee-os]
+
## Expiring artifacts
If an expiry date is used for the artifacts, they are marked for deletion
@@ -148,3 +158,5 @@ memory and disk I/O.
[reconfigure gitlab]: restart_gitlab.md "How to restart GitLab"
[restart gitlab]: restart_gitlab.md "How to restart GitLab"
[gitlab workhorse]: https://gitlab.com/gitlab-org/gitlab-workhorse "GitLab Workhorse repository"
+[ee-os]: https://docs.gitlab.com/ee/administration/job_artifacts.html#using-object-storage
+[eep]: https://about.gitlab.com/gitlab-ee/ "GitLab Enterprise Edition Premium"
diff --git a/doc/administration/monitoring/prometheus/gitlab_metrics.md b/doc/administration/monitoring/prometheus/gitlab_metrics.md
new file mode 100644
index 00000000000..07c05b5a6fb
--- /dev/null
+++ b/doc/administration/monitoring/prometheus/gitlab_metrics.md
@@ -0,0 +1,47 @@
+# GitLab Prometheus metrics
+
+>**Note:**
+Available since [Omnibus GitLab 9.3][29118]. Currently experimental. For installations from source
+you'll have to configure it yourself.
+
+GitLab monitors its own internal service metrics, and makes them available at the `/-/metrics` endpoint. Unlike other [Prometheus] exporters, this endpoint requires authentication as it is available on the same URL and port as user traffic.
+
+To enable the GitLab Prometheus metrics:
+
+1. Log into GitLab as an administrator, and go to the Admin area.
+1. Click on the gear, then click on Settings.
+1. Find the `Metrics - Prometheus` section, and click `Enable Prometheus Metrics`
+1. [Restart GitLab][restart] for the changes to take effect
+
+## Collecting the metrics
+
+Since the metrics endpoint is available on the same host and port as other traffic, it requires authentication. The token and URL to access is displayed on the [Health Check][health-check] page.
+
+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 one every reconfigure of GitLab. In the future this will not be required.
+
+## Metrics available
+
+In this experimental phase, only a few metrics are available:
+
+| Metric | Type | Description |
+| ------ | ---- | ----------- |
+| db_ping_timeout | Gauge | Whether or not the last database ping timed out |
+| db_ping_success | Gauge | Whether or not the last database ping succeeded |
+| db_ping_latency | Gauge | Round trip time of the database ping |
+| redis_ping_timeout | Gauge | Whether or not the last redis ping timed out |
+| redis_ping_success | Gauge | Whether or not the last redis ping succeeded |
+| redis_ping_latency | Gauge | Round trip time of the redis ping |
+| filesystem_access_latency | gauge | Latency in accessing a specific filesystem |
+| filesystem_accessible | gauge | Whether or not a specific filesystem is accessible |
+| filesystem_write_latency | gauge | Write latency of a specific filesystem |
+| filesystem_writable | gauge | Whether or not the filesystem is writable |
+| filesystem_read_latency | gauge | Read latency of a specific filesystem |
+| filesystem_readable | gauge | Whether or not the filesystem is readable |
+| user_sessions_logins | Counter | Counter of how many users have logged in |
+
+[↠Back to the main Prometheus page](index.md)
+
+[29118]: https://gitlab.com/gitlab-org/gitlab-ce/issues/29118
+[Prometheus]: https://prometheus.io
+[restart]: ../../restart_gitlab.md#omnibus-gitlab-restart
+[health-check]: ../../../user/admin_area/monitoring/health_check.md
diff --git a/doc/administration/monitoring/prometheus/gitlab_monitor_exporter.md b/doc/administration/monitoring/prometheus/gitlab_monitor_exporter.md
index edb9c911aac..f68b03d1ade 100644
--- a/doc/administration/monitoring/prometheus/gitlab_monitor_exporter.md
+++ b/doc/administration/monitoring/prometheus/gitlab_monitor_exporter.md
@@ -4,7 +4,7 @@
Available since [Omnibus GitLab 8.17][1132]. For installations from source
you'll have to install and configure it yourself.
-The [GitLab monitor exporter] allows you to measure various GitLab metrics.
+The [GitLab monitor exporter] allows you to measure various GitLab metrics, pulled from Redis and the database.
To enable the GitLab monitor exporter:
diff --git a/doc/administration/monitoring/prometheus/index.md b/doc/administration/monitoring/prometheus/index.md
index b2445d1c0e5..695fdf09a87 100644
--- a/doc/administration/monitoring/prometheus/index.md
+++ b/doc/administration/monitoring/prometheus/index.md
@@ -110,6 +110,14 @@ To disable the monitoring of Kubernetes:
1. Save the file and [reconfigure GitLab][reconfigure] for the changes to
take effect
+## GitLab Prometheus metrics
+
+> Introduced as an experimental feature in GitLab 9.3.
+
+GitLab monitors its own internal service metrics, and makes them available at the `/-/metrics` endpoint. Unlike other exporters, this endpoint requires authentication as it is available on the same URL and port as user traffic.
+
+[âž” Read more about the GitLab Metrics.](gitlab_metrics.md)
+
## Prometheus exporters
There are a number of libraries and servers which help in exporting existing
@@ -143,7 +151,7 @@ The Postgres exporter allows you to measure various PostgreSQL metrics.
### GitLab monitor exporter
-The GitLab monitor exporter allows you to measure various GitLab metrics.
+The GitLab monitor exporter allows you to measure various GitLab metrics, pulled from Redis and the database.
[âž” Read more about the GitLab monitor exporter.](gitlab_monitor_exporter.md)
diff --git a/doc/api/README.md b/doc/api/README.md
index 4f189c16673..b7f6ee69193 100644
--- a/doc/api/README.md
+++ b/doc/api/README.md
@@ -29,10 +29,10 @@ following locations:
- [Labels](labels.md)
- [Merge Requests](merge_requests.md)
- [Milestones](milestones.md)
-- [Open source license templates](templates/licenses.md)
- [Namespaces](namespaces.md)
- [Notes](notes.md) (comments)
- [Notification settings](notification_settings.md)
+- [Open source license templates](templates/licenses.md)
- [Pipelines](pipelines.md)
- [Pipeline Triggers](pipeline_triggers.md)
- [Pipeline Schedules](pipeline_schedules.md)
diff --git a/doc/api/issues.md b/doc/api/issues.md
index 3f949ca5667..df5666bb7b6 100644
--- a/doc/api/issues.md
+++ b/doc/api/issues.md
@@ -221,7 +221,8 @@ GET /projects/:id/issues?search=issue+title+or+description
| `order_by` | string | no | Return requests ordered by `created_at` or `updated_at` fields. Default is `created_at` |
| `sort` | string | no | Return requests sorted in `asc` or `desc` order. Default is `desc` |
| `search` | string | no | Search project issues against their `title` and `description` |
-
+| `created_after` | datetime | no | Return issues created after the given time (inclusive) |
+| `created_before` | datetime | no | Return issues created before the given time (inclusive) |
```bash
curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/4/issues
diff --git a/doc/api/merge_requests.md b/doc/api/merge_requests.md
index cb22b67f556..3dc808c196d 100644
--- a/doc/api/merge_requests.md
+++ b/doc/api/merge_requests.md
@@ -26,6 +26,8 @@ Parameters:
| `sort` | string | no | Return requests sorted in `asc` or `desc` order. Default is `desc` |
| `milestone` | string | no | Return merge requests for a specific milestone |
| `labels` | string | no | Return merge requests matching a comma separated list of labels |
+| `created_after` | datetime | no | Return merge requests created after the given time (inclusive) |
+| `created_before` | datetime | no | Return merge requests created before the given time (inclusive) |
```json
[
diff --git a/doc/api/projects.md b/doc/api/projects.md
index 58f18105e21..cc1bb3911c8 100644
--- a/doc/api/projects.md
+++ b/doc/api/projects.md
@@ -261,6 +261,7 @@ Parameters:
],
"only_allow_merge_if_pipeline_succeeds": false,
"only_allow_merge_if_all_discussions_are_resolved": false,
+ "printing_merge_requests_link_enabled": true,
"request_access_enabled": false,
"statistics": {
"commit_count": 37,
@@ -344,6 +345,7 @@ Parameters:
| `request_access_enabled` | boolean | no | Allow users to request member access |
| `tag_list` | array | no | The list of tags for a project; put array of tags, that should be finally assigned to a project |
| `avatar` | mixed | no | Image file for avatar of the project |
+| `printing_merge_request_link_enabled` | boolean | no | Show link to create/view merge request when pushing from the command line |
### Create project for user
@@ -379,6 +381,7 @@ Parameters:
| `request_access_enabled` | boolean | no | Allow users to request member access |
| `tag_list` | array | no | The list of tags for a project; put array of tags, that should be finally assigned to a project |
| `avatar` | mixed | no | Image file for avatar of the project |
+| `printing_merge_request_link_enabled` | boolean | no | Show link to create/view merge request when pushing from the command line |
### Edit project
diff --git a/doc/api/users.md b/doc/api/users.md
index 91ce4f6dac3..cf09b8f44aa 100644
--- a/doc/api/users.md
+++ b/doc/api/users.md
@@ -62,6 +62,7 @@ GET /users
"avatar_url": "http://localhost:3000/uploads/user/avatar/1/index.jpg",
"web_url": "http://localhost:3000/john_smith",
"created_at": "2012-05-23T08:00:58Z",
+ "is_admin": false,
"bio": null,
"location": null,
"skype": "",
@@ -94,6 +95,7 @@ GET /users
"avatar_url": "http://localhost:3000/uploads/user/avatar/2/index.jpg",
"web_url": "http://localhost:3000/jack_smith",
"created_at": "2012-05-23T08:01:01Z",
+ "is_admin": false,
"bio": null,
"location": null,
"skype": "",
@@ -197,6 +199,7 @@ Parameters:
"avatar_url": "http://localhost:3000/uploads/user/avatar/1/index.jpg",
"web_url": "http://localhost:3000/john_smith",
"created_at": "2012-05-23T08:00:58Z",
+ "is_admin": false,
"bio": null,
"location": null,
"skype": "",
@@ -251,6 +254,7 @@ Parameters:
- `can_create_group` (optional) - User can create groups - true or false
- `confirm` (optional) - Require confirmation - true (default) or false
- `external` (optional) - Flags the user as external - true or false(default)
+- `avatar` (optional) - Image file for user's avatar
## User modification
@@ -279,6 +283,7 @@ Parameters:
- `admin` (optional) - User is admin - true or false (default)
- `can_create_group` (optional) - User can create groups - true or false
- `external` (optional) - Flags the user as external - true or false(default)
+- `avatar` (optional) - Image file for user's avatar
On password update, user will be forced to change it upon next login.
Note, at the moment this method does only return a `404` error,
diff --git a/doc/development/limit_ee_conflicts.md b/doc/development/limit_ee_conflicts.md
index 51b4b398f2c..899be9eae4b 100644
--- a/doc/development/limit_ee_conflicts.md
+++ b/doc/development/limit_ee_conflicts.md
@@ -166,8 +166,8 @@ For instance this kind of thing:
= render 'projects/zen', f: form, attr: :description,
classes: 'note-textarea',
placeholder: "Write a comment or drag your files here...",
- supports_slash_commands: !issuable.persisted?
- = render 'projects/notes/hints', supports_slash_commands: !issuable.persisted?
+ supports_quick_actions: !issuable.persisted?
+ = render 'projects/notes/hints', supports_quick_actions: !issuable.persisted?
.clearfix
.error-alert
- if issuable.is_a?(Issue)
diff --git a/doc/install/requirements.md b/doc/install/requirements.md
index 197a92905c8..643fe5b686b 100644
--- a/doc/install/requirements.md
+++ b/doc/install/requirements.md
@@ -86,56 +86,31 @@ if your available memory changes.
Notice: The 25 workers of Sidekiq will show up as separate processes in your process overview (such as top or htop) but they share the same RAM allocation since Sidekiq is a multithreaded application. Please see the section below about Unicorn workers for information about many you need of those.
-## GitLab Runner
-
-We strongly advise against installing GitLab Runner on the same machine you plan
-to install GitLab on. Depending on how you decide to configure GitLab Runner and
-what tools you use to exercise your application in the CI environment, GitLab
-Runner can consume significant amount of available memory.
-
-Memory consumption calculations, that are available above, will not be valid if
-you decide to run GitLab Runner and the GitLab Rails application on the same
-machine.
-
-It is also not safe to install everything on a single machine, because of the
-[security reasons] - especially when you plan to use shell executor with GitLab
-Runner.
-
-We recommend using a separate machine for each GitLab Runner, if you plan to
-use the CI features.
-
-[security reasons]: https://gitlab.com/gitlab-org/gitlab-ci-multi-runner/blob/master/docs/security/index.md
-
-## Unicorn Workers
-
-It's possible to increase the amount of unicorn workers and this will usually help to reduce the response time of the applications and increase the ability to handle parallel requests.
-
-For most instances we recommend using: CPU cores + 1 = unicorn workers.
-So for a machine with 2 cores, 3 unicorn workers is ideal.
+## Database
-For all machines that have 2GB and up we recommend a minimum of three unicorn workers.
-If you have a 1GB machine we recommend to configure only two Unicorn workers to prevent excessive swapping.
+The server running the database should have _at least_ 5-10 GB of storage
+available, though the exact requirements depend on the size of the GitLab
+installation (e.g. the number of users, projects, etc).
-To change the Unicorn workers when you have the Omnibus package please see [the Unicorn settings in the Omnibus GitLab documentation](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/doc/settings/unicorn.md#unicorn-settings).
+We currently support the following databases:
-## Database
+- PostgreSQL (highly recommended)
+- MySQL/MariaDB (doesn't support all features)
-We currently support the following databases:
+We **highly recommend** the use of PostgreSQL instead of MySQL/MariaDB as not all
+features of GitLab work with MySQL/MariaDB:
-- PostgreSQL
-- MySQL/MariaDB
+1. MySQL support for subgroups was [dropped with GitLab 9.3][post].
+ See [issue #30472][30472] for more information.
+1. GitLab Geo does [not support MySQL](https://docs.gitlab.com/ee/gitlab-geo/database.html#mysql-replication).
+1. [Zero downtime migrations][zero] do not work with MySQL
-We _highly_ recommend the use of PostgreSQL instead of MySQL/MariaDB as not all
-features of GitLab may work with MySQL/MariaDB. For example, MySQL does not have
-the right features to support nested groups in an efficient manner; see
-<https://gitlab.com/gitlab-org/gitlab-ce/issues/30472> for more information
-about this. GitLab Geo also does [not support MySQL](https://docs.gitlab.com/ee/gitlab-geo/database.html#mysql-replication).
Existing users using GitLab with MySQL/MariaDB are advised to
-migrate to PostgreSQL instead.
+[migrate to PostgreSQL](../update/mysql_to_postgresql.md) instead.
-The server running the database should have _at least_ 5-10 GB of storage
-available, though the exact requirements depend on the size of the GitLab
-installation (e.g. the number of users, projects, etc).
+[30472]: https://gitlab.com/gitlab-org/gitlab-ce/issues/30472
+[zero]: ../update/README.md#upgrading-without-downtime
+[post]: https://about.gitlab.com/2017/06/22/gitlab-9-3-released/#dropping-support-for-subgroups-in-mysql
### PostgreSQL Requirements
@@ -154,6 +129,18 @@ CREATE EXTENSION pg_trgm;
On some systems you may need to install an additional package (e.g.
`postgresql-contrib`) for this extension to become available.
+## Unicorn Workers
+
+It's possible to increase the amount of unicorn workers and this will usually help to reduce the response time of the applications and increase the ability to handle parallel requests.
+
+For most instances we recommend using: CPU cores + 1 = unicorn workers.
+So for a machine with 2 cores, 3 unicorn workers is ideal.
+
+For all machines that have 2GB and up we recommend a minimum of three unicorn workers.
+If you have a 1GB machine we recommend to configure only two Unicorn workers to prevent excessive swapping.
+
+To change the Unicorn workers when you have the Omnibus package please see [the Unicorn settings in the Omnibus GitLab documentation](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/doc/settings/unicorn.md#unicorn-settings).
+
## Redis and Sidekiq
Redis stores all user sessions and the background task queue.
@@ -172,6 +159,26 @@ default settings.
If you would like to disable Prometheus and it's exporters or read more information
about it, check the [Prometheus documentation](../administration/monitoring/prometheus/index.md).
+## GitLab Runner
+
+We strongly advise against installing GitLab Runner on the same machine you plan
+to install GitLab on. Depending on how you decide to configure GitLab Runner and
+what tools you use to exercise your application in the CI environment, GitLab
+Runner can consume significant amount of available memory.
+
+Memory consumption calculations, that are available above, will not be valid if
+you decide to run GitLab Runner and the GitLab Rails application on the same
+machine.
+
+It is also not safe to install everything on a single machine, because of the
+[security reasons] - especially when you plan to use shell executor with GitLab
+Runner.
+
+We recommend using a separate machine for each GitLab Runner, if you plan to
+use the CI features.
+
+[security reasons]: https://gitlab.com/gitlab-org/gitlab-ci-multi-runner/blob/master/docs/security/index.md
+
## Supported web browsers
We support the current and the previous major release of Firefox, Chrome/Chromium, Safari and Microsoft browsers (Microsoft Edge and Internet Explorer 11).
diff --git a/doc/integration/chat_commands.md b/doc/integration/chat_commands.md
index c878dc7e650..2856992ee25 100644
--- a/doc/integration/chat_commands.md
+++ b/doc/integration/chat_commands.md
@@ -1,14 +1 @@
-# Chat Commands
-
-Chat commands in Mattermost and Slack (also called Slack slash commands) allow you to control GitLab and view GitLab content right inside your chat client, without having to leave it. For Slack, this requires a [project service configuration](../user/project/integrations/slack_slash_commands.md). Simply type the command as a message in your chat client to activate it.
-
-Commands are scoped to a project, with a trigger term that is specified during configuration. (We suggest you use the project name as the trigger term for simplicty and clarity.) Taking the trigger term as `project-name`, the commands are:
-
-
-| Command | Effect |
-| ------- | ------ |
-| `/project-name help` | Shows all available chat commands |
-| `/project-name issue new <title> <shift+return> <description>` | Creates a new issue with title `<title>` and description `<description>` |
-| `/project-name issue show <id>` | Shows the issue with id `<id>` |
-| `/project-name issue search <query>` | Shows up to 5 issues matching `<query>` |
-| `/project-name deploy <from> to <to>` | Deploy from the `<from>` environment to the `<to>` environment | \ No newline at end of file
+This document was moved to [integration/slash_commands.md](slash_commands.md).
diff --git a/doc/integration/slash_commands.md b/doc/integration/slash_commands.md
new file mode 100644
index 00000000000..5d880ba785c
--- /dev/null
+++ b/doc/integration/slash_commands.md
@@ -0,0 +1,14 @@
+# Slash Commands
+
+Slash commands in Mattermost and Slack allow you to control GitLab and view GitLab content right inside your chat client, without having to leave it. For Slack, this requires a [project service configuration](../user/project/integrations/slack_slash_commands.md). Simply type the command as a message in your chat client to activate it.
+
+Commands are scoped to a project, with a trigger term that is specified during configuration. (We suggest you use the project name as the trigger term for simplicty and clarity.) Taking the trigger term as `project-name`, the commands are:
+
+
+| Command | Effect |
+| ------- | ------ |
+| `/project-name help` | Shows all available slash commands |
+| `/project-name issue new <title> <shift+return> <description>` | Creates a new issue with title `<title>` and description `<description>` |
+| `/project-name issue show <id>` | Shows the issue with id `<id>` |
+| `/project-name issue search <query>` | Shows up to 5 issues matching `<query>` |
+| `/project-name deploy <from> to <to>` | Deploy from the `<from>` environment to the `<to>` environment |
diff --git a/doc/update/README.md b/doc/update/README.md
index d024a809f24..22dbc7c750f 100644
--- a/doc/update/README.md
+++ b/doc/update/README.md
@@ -11,22 +11,6 @@ There are currently 3 official ways to install GitLab:
Based on your installation, choose a section below that fits your needs.
----
-
-<!-- START doctoc generated TOC please keep comment here to allow auto update -->
-<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
-**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
-
-- [Omnibus Packages](#omnibus-packages)
-- [Installation from source](#installation-from-source)
-- [Installation using Docker](#installation-using-docker)
-- [Upgrading between editions](#upgrading-between-editions)
- - [Community to Enterprise Edition](#community-to-enterprise-edition)
- - [Enterprise to Community Edition](#enterprise-to-community-edition)
-- [Miscellaneous](#miscellaneous)
-
-<!-- END doctoc generated TOC please keep comment here to allow auto update -->
-
## Omnibus Packages
- The [Omnibus update guide](http://docs.gitlab.com/omnibus/update/README.html)
diff --git a/doc/user/discussions/index.md b/doc/user/discussions/index.md
index 59e343ebe51..8b1d299484c 100644
--- a/doc/user/discussions/index.md
+++ b/doc/user/discussions/index.md
@@ -10,7 +10,7 @@ You can leave a comment in the following places:
- commits
- commit diffs
-The comment area supports [Markdown] and [slash commands]. One can edit their
+The comment area supports [Markdown] and [quick actions]. One can edit their
own comment at any time, and anyone with [Master access level][permissions] or
higher can also edit a comment made by someone else.
@@ -146,5 +146,5 @@ comments in greater detail.
[discussion-view]: img/discussion_view.png
[discussions-resolved]: img/discussions_resolved.png
[markdown]: ../markdown.md
-[slash commands]: ../project/slash_commands.md
+[quick actions]: ../project/quick_actions.md
[permissions]: ../permissions.md
diff --git a/doc/user/group/subgroups/index.md b/doc/user/group/subgroups/index.md
index c4921c74a17..5724dcfab48 100644
--- a/doc/user/group/subgroups/index.md
+++ b/doc/user/group/subgroups/index.md
@@ -1,6 +1,9 @@
# Subgroups
-> [Introduced][ce-2772] in GitLab 9.0.
+>**Notes:**
+- [Introduced][ce-2772] in GitLab 9.0.
+- Not available when using MySQL as external database (support removed in
+ GitLab 9.3 [due to performance reasons][issue]).
With subgroups (aka nested groups or hierarchical groups) you can have
up to 20 levels of nested groups, which among other things can help you to:
@@ -173,3 +176,4 @@ Here's a list of what you can't do with subgroups:
[ce-2772]: https://gitlab.com/gitlab-org/gitlab-ce/issues/2772
[permissions]: ../../permissions.md#group
[reserved]: https://gitlab.com/gitlab-org/gitlab-ce/blob/master/lib/gitlab/path_regex.rb
+[issue]: https://gitlab.com/gitlab-org/gitlab-ce/issues/30472#note_27747600
diff --git a/doc/user/permissions.md b/doc/user/permissions.md
index 3fda47b9e34..3d47e644ad2 100644
--- a/doc/user/permissions.md
+++ b/doc/user/permissions.md
@@ -89,6 +89,7 @@ group.
| Create project in group | | | | ✓ | ✓ |
| Manage group members | | | | | ✓ |
| Remove group | | | | | ✓ |
+| Manage group labels | | ✓ | ✓ | ✓ | ✓ |
## External Users
diff --git a/doc/user/project/integrations/img/merge_request_performance.png b/doc/user/project/integrations/img/merge_request_performance.png
index 93b2626fed7..eba6515a6ae 100644
--- a/doc/user/project/integrations/img/merge_request_performance.png
+++ b/doc/user/project/integrations/img/merge_request_performance.png
Binary files differ
diff --git a/doc/user/project/integrations/prometheus.md b/doc/user/project/integrations/prometheus.md
index d3fb5916dc6..86ceb14b965 100644
--- a/doc/user/project/integrations/prometheus.md
+++ b/doc/user/project/integrations/prometheus.md
@@ -167,15 +167,15 @@ environment which has had a successful deployment.
## Determining the performance impact of a merge
> [Introduced][ce-10408] in GitLab 9.2.
+> GitLab 9.3 added the [numeric comparison](https://gitlab.com/gitlab-org/gitlab-ce/issues/27439) of the 30 minute averages.
Developers can view the performance impact of their changes within the merge
-request workflow. When a source branch has been deployed to an environment, a
-sparkline will appear showing the average memory consumption of the app. The dot
+request workflow. When a source branch has been deployed to an environment, a sparkline and numeric comparison of the average memory consumption will appear. On the sparkline, a dot
indicates when the current changes were deployed, with up to 30 minutes of
-performance data displayed before and after. The sparkline will be updated after
+performance data displayed before and after. The comparison shows the difference between the 30 minute average before and after the deployment. This information is updated after
each commit has been deployed.
-Once merged and the target branch has been redeployed, the sparkline will switch
+Once merged and the target branch has been redeployed, the metrics will switch
to show the new environments this revision has been deployed to.
Performance data will be available for the duration it is persisted on the
diff --git a/doc/user/project/integrations/slack_slash_commands.md b/doc/user/project/integrations/slack_slash_commands.md
index 54e0ee611cb..c267da69bb3 100644
--- a/doc/user/project/integrations/slack_slash_commands.md
+++ b/doc/user/project/integrations/slack_slash_commands.md
@@ -2,7 +2,7 @@
> Introduced in GitLab 8.15
-Slack slash commands (also known as chat commmands) allow you to control GitLab and view content right inside Slack, without having to leave it. This requires configurations in both Slack and GitLab.
+Slack slash commands allow you to control GitLab and view content right inside Slack, without having to leave it. This requires configurations in both Slack and GitLab.
> Note: GitLab can also send events (e.g. issue created) to Slack as notifications. This is the separately configured [Slack Notifications Service](slack.md).
@@ -20,4 +20,4 @@ Slack slash commands (also known as chat commmands) allow you to control GitLab
## Usage
-You can now use the [Slack slash commands](../../../integration/chat_commands.md). \ No newline at end of file
+You can now use the [Slack slash commands](../../../integration/slash_commands.md).
diff --git a/doc/user/project/issues/confidential_issues.md b/doc/user/project/issues/confidential_issues.md
index 208be7d0ed5..1760b182114 100644
--- a/doc/user/project/issues/confidential_issues.md
+++ b/doc/user/project/issues/confidential_issues.md
@@ -43,8 +43,9 @@ next to the issues that are marked as confidential.
---
-While inside the issue, you can see a persistent dark banner at the top of the
-screen.
+Likewise, while inside the issue, you can see the eye-slash icon right next to
+the issue number, but there is also an indicator in the comment area that the
+issue you are commenting on is confidential.
![Confidential issue page](img/confidential_issues_issue_page.png)
diff --git a/doc/user/project/issues/img/confidential_issues_issue_page.png b/doc/user/project/issues/img/confidential_issues_issue_page.png
index 91f7cc8d3ca..f04ec8ff32b 100755
--- a/doc/user/project/issues/img/confidential_issues_issue_page.png
+++ b/doc/user/project/issues/img/confidential_issues_issue_page.png
Binary files differ
diff --git a/doc/user/project/issues/issues_functionalities.md b/doc/user/project/issues/issues_functionalities.md
index ba843201e1a..294176e61f9 100644
--- a/doc/user/project/issues/issues_functionalities.md
+++ b/doc/user/project/issues/issues_functionalities.md
@@ -68,7 +68,7 @@ This feature is available only in [GitLab Enterprise Edition](https://about.gitl
- Spend: add the time spent on the implementation of that issue
> **Note:**
-both estimate and spend times are set via [GitLab Slash Commands](../slash_commands.md).
+both estimate and spend times are set via [GitLab Quick Actions](../quick_actions.md).
Learn more on the [Time Tracking documentation](https://docs.gitlab.com/ee/workflow/time_tracking.html).
@@ -147,7 +147,7 @@ or in the issue thread.
#### 15. Award emoji
-- Award an emoji to that issue.
+- Award an emoji to that issue.
> **Tip:**
Posting "+1" as comments in threads spam all
diff --git a/doc/user/project/quick_actions.md b/doc/user/project/quick_actions.md
new file mode 100644
index 00000000000..19b51c83222
--- /dev/null
+++ b/doc/user/project/quick_actions.md
@@ -0,0 +1,39 @@
+# GitLab quick actions
+
+Quick actions are textual shortcuts for common actions on issues or merge
+requests that are usually done by clicking buttons or dropdowns in GitLab's UI.
+You can enter these commands while creating a new issue or merge request, and
+in comments. Each command should be on a separate line in order to be properly
+detected and executed. The commands are removed from the issue, merge request or
+comment body before it is saved and will not be visible to anyone else.
+
+Below is a list of all of the available commands and descriptions about what they
+do.
+
+| Command | Action |
+|:---------------------------|:-------------|
+| `/close` | Close the issue or merge request |
+| `/reopen` | Reopen the issue or merge request |
+| `/merge` | Merge (when pipeline succeeds) |
+| `/title <New title>` | Change title |
+| `/assign @username` | Assign |
+| `/unassign` | Remove assignee |
+| `/milestone %milestone` | Set milestone |
+| `/remove_milestone` | Remove milestone |
+| `/label ~foo ~"bar baz"` | Add label(s) |
+| `/unlabel ~foo ~"bar baz"` | Remove all or specific label(s) |
+| `/relabel ~foo ~"bar baz"` | Replace all label(s) |
+| `/todo` | Add a todo |
+| `/done` | Mark todo as done |
+| `/subscribe` | Subscribe |
+| `/unsubscribe` | Unsubscribe |
+| <code>/due &lt;in 2 days &#124; this Friday &#124; December 31st&gt;</code> | Set due date |
+| `/remove_due_date` | Remove due date |
+| `/wip` | Toggle the Work In Progress status |
+| <code>/estimate &lt;1w 3d 2h 14m&gt;</code> | Set time estimate |
+| `/remove_estimate` | Remove estimated time |
+| <code>/spend &lt;1h 30m &#124; -1h 5m&gt;</code> | Add or subtract spent time |
+| `/remove_time_spent` | Remove time spent |
+| `/target_branch <Branch Name>` | Set target branch for current merge request |
+| `/award :emoji:` | Toggle award for :emoji: |
+| `/board_move ~column` | Move issue to column on the board |
diff --git a/doc/user/project/settings/import_export.md b/doc/user/project/settings/import_export.md
index 58d2fd76c61..35960ade3d4 100644
--- a/doc/user/project/settings/import_export.md
+++ b/doc/user/project/settings/import_export.md
@@ -27,14 +27,15 @@ with all their related data and be moved into a new GitLab instance.
| GitLab version | Import/Export version |
| -------- | -------- |
-| 9.2.0 to current | 0.1.7 |
-| 8.17.0 | 0.1.6 |
-| 8.13.0 | 0.1.5 |
-| 8.12.0 | 0.1.4 |
-| 8.10.3 | 0.1.3 |
-| 8.10.0 | 0.1.2 |
-| 8.9.5 | 0.1.1 |
-| 8.9.0 | 0.1.0 |
+| 9.4.0 to current | 0.1.8 |
+| 9.2.0 | 0.1.7 |
+| 8.17.0 | 0.1.6 |
+| 8.13.0 | 0.1.5 |
+| 8.12.0 | 0.1.4 |
+| 8.10.3 | 0.1.3 |
+| 8.10.0 | 0.1.2 |
+| 8.9.5 | 0.1.1 |
+| 8.9.0 | 0.1.0 |
> The table reflects what GitLab version we updated the Import/Export version at.
> For instance, 8.10.3 and 8.11 will have the same Import/Export version (0.1.3)
diff --git a/doc/user/project/slash_commands.md b/doc/user/project/slash_commands.md
index 08452ca75cd..e9103a3f49c 100644
--- a/doc/user/project/slash_commands.md
+++ b/doc/user/project/slash_commands.md
@@ -1,39 +1 @@
-# GitLab slash commands
-
-Slash commands are textual shortcuts for common actions on issues or merge
-requests that are usually done by clicking buttons or dropdowns in GitLab's UI.
-You can enter these commands while creating a new issue or merge request, and
-in comments. Each command should be on a separate line in order to be properly
-detected and executed. The commands are removed from the issue, merge request or
-comment body before it is saved and will not be visible to anyone else.
-
-Below is a list of all of the available commands and descriptions about what they
-do.
-
-| Command | Action |
-|:---------------------------|:-------------|
-| `/close` | Close the issue or merge request |
-| `/reopen` | Reopen the issue or merge request |
-| `/merge` | Merge (when pipeline succeeds) |
-| `/title <New title>` | Change title |
-| `/assign @username` | Assign |
-| `/unassign` | Remove assignee |
-| `/milestone %milestone` | Set milestone |
-| `/remove_milestone` | Remove milestone |
-| `/label ~foo ~"bar baz"` | Add label(s) |
-| `/unlabel ~foo ~"bar baz"` | Remove all or specific label(s) |
-| `/relabel ~foo ~"bar baz"` | Replace all label(s) |
-| `/todo` | Add a todo |
-| `/done` | Mark todo as done |
-| `/subscribe` | Subscribe |
-| `/unsubscribe` | Unsubscribe |
-| <code>/due &lt;in 2 days &#124; this Friday &#124; December 31st&gt;</code> | Set due date |
-| `/remove_due_date` | Remove due date |
-| `/wip` | Toggle the Work In Progress status |
-| <code>/estimate &lt;1w 3d 2h 14m&gt;</code> | Set time estimate |
-| `/remove_estimate` | Remove estimated time |
-| <code>/spend &lt;1h 30m &#124; -1h 5m&gt;</code> | Add or subtract spent time |
-| `/remove_time_spent` | Remove time spent |
-| `/target_branch <Branch Name>` | Set target branch for current merge request |
-| `/award :emoji:` | Toggle award for :emoji: |
-| `/board_move ~column` | Move issue to column on the board |
+This document was moved to [user/project/quick_actions.md](quick_actions.md).
diff --git a/doc/workflow/README.md b/doc/workflow/README.md
index 604c7d5cefb..54d4028a50a 100644
--- a/doc/workflow/README.md
+++ b/doc/workflow/README.md
@@ -21,7 +21,7 @@
- [Project users](add-user/add-user.md)
- [Protected branches](../user/project/protected_branches.md)
- [Protected tags](../user/project/protected_tags.md)
-- [Slash commands](../user/project/slash_commands.md)
+- [Quick Actions](../user/project/quick_actions.md)
- [Sharing a project with a group](share_with_group.md)
- [Share projects with other groups](share_projects_with_other_groups.md)
- [Time tracking](time_tracking.md)
diff --git a/doc/workflow/time_tracking.md b/doc/workflow/time_tracking.md
index de12994c516..bfe87bb2ceb 100644
--- a/doc/workflow/time_tracking.md
+++ b/doc/workflow/time_tracking.md
@@ -21,13 +21,13 @@ below.
## How to enter data
-Time Tracking uses two [slash commands] that GitLab introduced with this new
+Time Tracking uses two [quick actions] that GitLab introduced with this new
feature: `/spend` and `/estimate`.
-Slash commands can be used in the body of an issue or a merge request, but also
+Quick actions can be used in the body of an issue or a merge request, but also
in a comment in both an issue or a merge request.
-Below is an example of how you can use those new slash commands inside a comment.
+Below is an example of how you can use those new quick actions inside a comment.
![Time tracking example in a comment](time-tracking/time-tracking-example.png)
@@ -70,4 +70,4 @@ The following time units are available:
Default conversion rates are 1w = 5d and 1d = 8h.
[landing]: https://about.gitlab.com/features/time-tracking
-[slash-commands]: ../user/project/slash_commands.md
+[quick actions]: ../user/project/quick_actions.md
diff --git a/features/project/create.feature b/features/project/create.feature
deleted file mode 100644
index 67336d73bf7..00000000000
--- a/features/project/create.feature
+++ /dev/null
@@ -1,14 +0,0 @@
-@project-create
-Feature: Project Create
- In order to get access to project sections
- A user with ability to create a project
- Should be able to create a new one
-
- @javascript
- Scenario: User create a project
- Given I sign in as a user
- And I have an ssh key
- When I visit new project page
- And fill project form with valid data
- Then I should see project page
- And I should see empty project instructions
diff --git a/lib/api/access_requests.rb b/lib/api/access_requests.rb
index a5c9f0b509c..c9b5f58c557 100644
--- a/lib/api/access_requests.rb
+++ b/lib/api/access_requests.rb
@@ -68,8 +68,8 @@ module API
delete ":id/access_requests/:user_id" do
source = find_source(source_type, params[:id])
- ::Members::DestroyService.new(source, current_user, params).
- execute(:requesters)
+ ::Members::DestroyService.new(source, current_user, params)
+ .execute(:requesters)
end
end
end
diff --git a/lib/api/branches.rb b/lib/api/branches.rb
index f35084a582a..3d816f8771d 100644
--- a/lib/api/branches.rb
+++ b/lib/api/branches.rb
@@ -102,8 +102,8 @@ module API
post ":id/repository/branches" do
authorize_push_project
- result = CreateBranchService.new(user_project, current_user).
- execute(params[:branch], params[:ref])
+ result = CreateBranchService.new(user_project, current_user)
+ .execute(params[:branch], params[:ref])
if result[:status] == :success
present result[:branch],
@@ -121,8 +121,8 @@ module API
delete ":id/repository/branches/:branch", requirements: { branch: /.+/ } do
authorize_push_project
- result = DeleteBranchService.new(user_project, current_user).
- execute(params[:branch])
+ result = DeleteBranchService.new(user_project, current_user)
+ .execute(params[:branch])
if result[:status] != :success
render_api_error!(result[:message], result[:return_code])
diff --git a/lib/api/deploy_keys.rb b/lib/api/deploy_keys.rb
index 7cdee8aced7..d5c2f3d5094 100644
--- a/lib/api/deploy_keys.rb
+++ b/lib/api/deploy_keys.rb
@@ -86,7 +86,7 @@ module API
at_least_one_of :title, :can_push
end
put ":id/deploy_keys/:key_id" do
- key = user_project.deploy_keys.find(params.delete(:key_id))
+ key = DeployKey.find(params.delete(:key_id))
authorize!(:update_deploy_key, key)
diff --git a/lib/api/entities.rb b/lib/api/entities.rb
index 412443a2405..aa91451c9f4 100644
--- a/lib/api/entities.rb
+++ b/lib/api/entities.rb
@@ -43,11 +43,14 @@ module API
expose :external
end
- class UserWithPrivateDetails < UserPublic
- expose :private_token
+ class UserWithAdmin < UserPublic
expose :admin?, as: :is_admin
end
+ class UserWithPrivateDetails < UserWithAdmin
+ expose :private_token
+ end
+
class Email < Grape::Entity
expose :id, :email
end
@@ -115,6 +118,7 @@ module API
expose :only_allow_merge_if_pipeline_succeeds
expose :request_access_enabled
expose :only_allow_merge_if_all_discussions_are_resolved
+ expose :printing_merge_request_link_enabled
expose :statistics, using: 'API::Entities::ProjectStatistics', if: :statistics
end
@@ -480,9 +484,9 @@ module API
expose :job_events
# Expose serialized properties
expose :properties do |service, options|
- field_names = service.fields.
- select { |field| options[:include_passwords] || field[:type] != 'password' }.
- map { |field| field[:name] }
+ field_names = service.fields
+ .select { |field| options[:include_passwords] || field[:type] != 'password' }
+ .map { |field| field[:name] }
service.properties.slice(*field_names)
end
end
diff --git a/lib/api/helpers/internal_helpers.rb b/lib/api/helpers/internal_helpers.rb
index d3732d67622..5e9cf5e68b1 100644
--- a/lib/api/helpers/internal_helpers.rb
+++ b/lib/api/helpers/internal_helpers.rb
@@ -10,6 +10,10 @@ module API
set_project unless defined?(@project)
@project
end
+
+ def redirected_path
+ @redirected_path
+ end
def ssh_authentication_abilities
[
@@ -38,8 +42,9 @@ module API
def set_project
if params[:gl_repository]
@project, @wiki = Gitlab::GlRepository.parse(params[:gl_repository])
+ @redirected_path = nil
else
- @project, @wiki = Gitlab::RepoPath.parse(params[:project])
+ @project, @wiki, @redirected_path = Gitlab::RepoPath.parse(params[:project])
end
end
diff --git a/lib/api/internal.rb b/lib/api/internal.rb
index ecd6d672cf7..479ee16a611 100644
--- a/lib/api/internal.rb
+++ b/lib/api/internal.rb
@@ -34,7 +34,7 @@ module API
access_checker_klass = wiki? ? Gitlab::GitAccessWiki : Gitlab::GitAccess
access_checker = access_checker_klass
- .new(actor, project, protocol, authentication_abilities: ssh_authentication_abilities)
+ .new(actor, project, protocol, authentication_abilities: ssh_authentication_abilities, redirected_path: redirected_path)
begin
access_checker.check(params[:action], params[:changes])
@@ -71,11 +71,16 @@ module API
end
#
- # Discover user by ssh key
+ # Discover user by ssh key or user id
#
get "/discover" do
- key = Key.find(params[:key_id])
- present key.user, with: Entities::UserSafe
+ if params[:key_id]
+ key = Key.find(params[:key_id])
+ user = key.user
+ elsif params[:user_id]
+ user = User.find_by(id: params[:user_id])
+ end
+ present user, with: Entities::UserSafe
end
get "/check" do
diff --git a/lib/api/issues.rb b/lib/api/issues.rb
index 78db960ae28..09dca0dff8b 100644
--- a/lib/api/issues.rb
+++ b/lib/api/issues.rb
@@ -27,6 +27,8 @@ module API
optional :milestone, type: String, desc: 'Return issues for a specific milestone'
optional :iids, type: Array[Integer], desc: 'The IID array of issues'
optional :search, type: String, desc: 'Search issues for text present in the title or description'
+ optional :created_after, type: DateTime, desc: 'Return issues created after the specified time'
+ optional :created_before, type: DateTime, desc: 'Return issues created before the specified time'
use :pagination
end
diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb
index 710deba5ae3..1118fc7465b 100644
--- a/lib/api/merge_requests.rb
+++ b/lib/api/merge_requests.rb
@@ -72,6 +72,8 @@ module API
optional :iids, type: Array[Integer], desc: 'The IID array of merge requests'
optional :milestone, type: String, desc: 'Return merge requests for a specific milestone'
optional :labels, type: String, desc: 'Comma-separated list of label names'
+ optional :created_after, type: DateTime, desc: 'Return merge requests created after the specified time'
+ optional :created_before, type: DateTime, desc: 'Return merge requests created before the specified time'
use :pagination
end
get ":id/merge_requests" do
@@ -97,7 +99,7 @@ module API
authorize! :create_merge_request, user_project
mr_params = declared_params(include_missing: false)
- mr_params[:force_remove_source_branch] = mr_params.delete(:remove_source_branch) if mr_params[:remove_source_branch].present?
+ mr_params[:force_remove_source_branch] = mr_params.delete(:remove_source_branch)
merge_request = ::MergeRequests::CreateService.new(user_project, current_user, mr_params).execute
diff --git a/lib/api/milestones.rb b/lib/api/milestones.rb
index a3ea619a2fb..3541d3c95fb 100644
--- a/lib/api/milestones.rb
+++ b/lib/api/milestones.rb
@@ -117,7 +117,7 @@ module API
finder_params = {
project_id: user_project.id,
milestone_title: milestone.title,
- sort: 'position_asc'
+ sort: 'label_priority'
}
issues = IssuesFinder.new(current_user, finder_params).execute
@@ -140,7 +140,7 @@ module API
finder_params = {
project_id: user_project.id,
milestone_title: milestone.title,
- sort: 'position_asc'
+ sort: 'label_priority'
}
merge_requests = MergeRequestsFinder.new(current_user, finder_params).execute
diff --git a/lib/api/notes.rb b/lib/api/notes.rb
index e281e3230fd..01ca62b593f 100644
--- a/lib/api/notes.rb
+++ b/lib/api/notes.rb
@@ -33,8 +33,8 @@ module API
# paginate() only works with a relation. This could lead to a
# mismatch between the pagination headers info and the actual notes
# array returned, but this is really a edge-case.
- paginate(noteable.notes).
- reject { |n| n.cross_reference_not_visible_for?(current_user) }
+ paginate(noteable.notes)
+ .reject { |n| n.cross_reference_not_visible_for?(current_user) }
present notes, with: Entities::Note
else
not_found!("Notes")
diff --git a/lib/api/projects.rb b/lib/api/projects.rb
index 50d34e8a738..c5df45b7902 100644
--- a/lib/api/projects.rb
+++ b/lib/api/projects.rb
@@ -23,6 +23,7 @@ module API
optional :only_allow_merge_if_all_discussions_are_resolved, type: Boolean, desc: 'Only allow to merge if all discussions are resolved'
optional :tag_list, type: Array[String], desc: 'The list of tags for a project'
optional :avatar, type: File, desc: 'Avatar image for project'
+ optional :printing_merge_request_link_enabled, type: Boolean, desc: 'Show link to create/view merge request when pushing from the command line'
end
params :optional_params do
@@ -218,6 +219,7 @@ module API
:only_allow_merge_if_all_discussions_are_resolved,
:only_allow_merge_if_pipeline_succeeds,
:path,
+ :printing_merge_request_link_enabled,
:public_builds,
:request_access_enabled,
:shared_runners_enabled,
diff --git a/lib/api/services.rb b/lib/api/services.rb
index 47bd9940f77..7488f95a9b7 100644
--- a/lib/api/services.rb
+++ b/lib/api/services.rb
@@ -685,7 +685,7 @@ module API
trigger_services.each do |service_slug, settings|
helpers do
- def chat_command_service(project, service_slug, params)
+ def slash_command_service(project, service_slug, params)
project.services.active.where(template: false).find do |service|
service.try(:token) == params[:token] && service.to_param == service_slug.underscore
end
@@ -710,7 +710,7 @@ module API
# This is not accurate, but done to prevent leakage of the project names
not_found!('Service') unless project
- service = chat_command_service(project, service_slug, params)
+ service = slash_command_service(project, service_slug, params)
result = service.try(:trigger, params)
if result
diff --git a/lib/api/tags.rb b/lib/api/tags.rb
index c7b1efe0bfa..633a858f8c7 100644
--- a/lib/api/tags.rb
+++ b/lib/api/tags.rb
@@ -44,8 +44,8 @@ module API
post ':id/repository/tags' do
authorize_push_project
- result = ::Tags::CreateService.new(user_project, current_user).
- execute(params[:tag_name], params[:ref], params[:message], params[:release_description])
+ result = ::Tags::CreateService.new(user_project, current_user)
+ .execute(params[:tag_name], params[:ref], params[:message], params[:release_description])
if result[:status] == :success
present result[:tag],
@@ -63,8 +63,8 @@ module API
delete ":id/repository/tags/:tag_name", requirements: { tag_name: /.+/ } do
authorize_push_project
- result = ::Tags::DestroyService.new(user_project, current_user).
- execute(params[:tag_name])
+ result = ::Tags::DestroyService.new(user_project, current_user)
+ .execute(params[:tag_name])
if result[:status] != :success
render_api_error!(result[:message], result[:return_code])
@@ -81,8 +81,8 @@ module API
post ':id/repository/tags/:tag_name/release', requirements: { tag_name: /.+/ } do
authorize_push_project
- result = CreateReleaseService.new(user_project, current_user).
- execute(params[:tag_name], params[:description])
+ result = CreateReleaseService.new(user_project, current_user)
+ .execute(params[:tag_name], params[:description])
if result[:status] == :success
present result[:release], with: Entities::Release
@@ -101,8 +101,8 @@ module API
put ':id/repository/tags/:tag_name/release', requirements: { tag_name: /.+/ } do
authorize_push_project
- result = UpdateReleaseService.new(user_project, current_user).
- execute(params[:tag_name], params[:description])
+ result = UpdateReleaseService.new(user_project, current_user)
+ .execute(params[:tag_name], params[:description])
if result[:status] == :success
present result[:release], with: Entities::Release
diff --git a/lib/api/users.rb b/lib/api/users.rb
index dda64715ee1..c10e3364382 100644
--- a/lib/api/users.rb
+++ b/lib/api/users.rb
@@ -29,6 +29,7 @@ module API
optional :can_create_group, type: Boolean, desc: 'Flag indicating the user can create groups'
optional :skip_confirmation, type: Boolean, default: false, desc: 'Flag indicating the account is confirmed'
optional :external, type: Boolean, desc: 'Flag indicating the user is an external user'
+ optional :avatar, type: File, desc: 'Avatar image for user'
all_or_none_of :extern_uid, :provider
end
end
@@ -58,7 +59,7 @@ module API
users = UsersFinder.new(current_user, params).execute
- entity = current_user.admin? ? Entities::UserPublic : Entities::UserBasic
+ entity = current_user.admin? ? Entities::UserWithAdmin : Entities::UserBasic
present paginate(users), with: entity
end
@@ -102,13 +103,13 @@ module API
if user.persisted?
present user, with: Entities::UserPublic
else
- conflict!('Email has already been taken') if User.
- where(email: user.email).
- count > 0
+ conflict!('Email has already been taken') if User
+ .where(email: user.email)
+ .count > 0
- conflict!('Username has already been taken') if User.
- where(username: user.username).
- count > 0
+ conflict!('Username has already been taken') if User
+ .where(username: user.username)
+ .count > 0
render_validation_error!(user)
end
@@ -132,12 +133,12 @@ module API
not_found!('User') unless user
conflict!('Email has already been taken') if params[:email] &&
- User.where(email: params[:email]).
- where.not(id: user.id).count > 0
+ User.where(email: params[:email])
+ .where.not(id: user.id).count > 0
conflict!('Username has already been taken') if params[:username] &&
- User.where(username: params[:username]).
- where.not(id: user.id).count > 0
+ User.where(username: params[:username])
+ .where.not(id: user.id).count > 0
user_params = declared_params(include_missing: false)
identity_attrs = user_params.slice(:provider, :extern_uid)
@@ -516,9 +517,9 @@ module API
get "activities" do
authenticated_as_admin!
- activities = User.
- where(User.arel_table[:last_activity_on].gteq(params[:from])).
- reorder(last_activity_on: :asc)
+ activities = User
+ .where(User.arel_table[:last_activity_on].gteq(params[:from]))
+ .reorder(last_activity_on: :asc)
present paginate(activities), with: Entities::UserActivity
end
diff --git a/lib/api/v3/branches.rb b/lib/api/v3/branches.rb
index 0a877b960f6..81b13249892 100644
--- a/lib/api/v3/branches.rb
+++ b/lib/api/v3/branches.rb
@@ -26,8 +26,8 @@ module API
delete ":id/repository/branches/:branch", requirements: { branch: /.+/ } do
authorize_push_project
- result = DeleteBranchService.new(user_project, current_user).
- execute(params[:branch])
+ result = DeleteBranchService.new(user_project, current_user)
+ .execute(params[:branch])
if result[:status] == :success
status(200)
@@ -55,8 +55,8 @@ module API
end
post ":id/repository/branches" do
authorize_push_project
- result = CreateBranchService.new(user_project, current_user).
- execute(params[:branch_name], params[:ref])
+ result = CreateBranchService.new(user_project, current_user)
+ .execute(params[:branch_name], params[:ref])
if result[:status] == :success
present result[:branch],
diff --git a/lib/api/v3/entities.rb b/lib/api/v3/entities.rb
index 7c5065dee90..c848f52723b 100644
--- a/lib/api/v3/entities.rb
+++ b/lib/api/v3/entities.rb
@@ -245,9 +245,9 @@ module API
expose :job_events, as: :build_events
# Expose serialized properties
expose :properties do |service, options|
- field_names = service.fields.
- select { |field| options[:include_passwords] || field[:type] != 'password' }.
- map { |field| field[:name] }
+ field_names = service.fields
+ .select { |field| options[:include_passwords] || field[:type] != 'password' }
+ .map { |field| field[:name] }
service.properties.slice(*field_names)
end
end
diff --git a/lib/api/v3/helpers.rb b/lib/api/v3/helpers.rb
index d9e76560d03..4e63aa01c1a 100644
--- a/lib/api/v3/helpers.rb
+++ b/lib/api/v3/helpers.rb
@@ -38,7 +38,10 @@ module API
projects = projects.where(visibility_level: Gitlab::VisibilityLevel.level_value(params[:visibility]))
end
- projects = projects.where(archived: params[:archived])
+ unless params[:archived].nil?
+ projects = projects.where(archived: to_boolean(params[:archived]))
+ end
+
projects.reorder(params[:order_by] => params[:sort])
end
end
diff --git a/lib/api/v3/notes.rb b/lib/api/v3/notes.rb
index 009ec5c6bbd..23fe95e42e4 100644
--- a/lib/api/v3/notes.rb
+++ b/lib/api/v3/notes.rb
@@ -34,8 +34,8 @@ module API
# paginate() only works with a relation. This could lead to a
# mismatch between the pagination headers info and the actual notes
# array returned, but this is really a edge-case.
- paginate(noteable.notes).
- reject { |n| n.cross_reference_not_visible_for?(current_user) }
+ paginate(noteable.notes)
+ .reject { |n| n.cross_reference_not_visible_for?(current_user) }
present notes, with: ::API::V3::Entities::Note
else
not_found!("Notes")
diff --git a/lib/api/v3/projects.rb b/lib/api/v3/projects.rb
index 20976b9dd08..eb090453b48 100644
--- a/lib/api/v3/projects.rb
+++ b/lib/api/v3/projects.rb
@@ -69,7 +69,7 @@ module API
end
params :filter_params do
- optional :archived, type: Boolean, default: false, desc: 'Limit by archived status'
+ optional :archived, type: Boolean, default: nil, desc: 'Limit by archived status'
optional :visibility, type: String, values: %w[public internal private],
desc: 'Limit by visibility'
optional :search, type: String, desc: 'Return list of authorized projects matching the search criteria'
diff --git a/lib/api/v3/services.rb b/lib/api/v3/services.rb
index 118c6df6549..2d13d6fabfd 100644
--- a/lib/api/v3/services.rb
+++ b/lib/api/v3/services.rb
@@ -608,7 +608,7 @@ module API
trigger_services.each do |service_slug, settings|
helpers do
- def chat_command_service(project, service_slug, params)
+ def slash_command_service(project, service_slug, params)
project.services.active.where(template: false).find do |service|
service.try(:token) == params[:token] && service.to_param == service_slug.underscore
end
@@ -633,7 +633,7 @@ module API
# This is not accurate, but done to prevent leakage of the project names
not_found!('Service') unless project
- service = chat_command_service(project, service_slug, params)
+ service = slash_command_service(project, service_slug, params)
result = service.try(:trigger, params)
if result
diff --git a/lib/api/v3/tags.rb b/lib/api/v3/tags.rb
index c2541de2f50..7e5875cd030 100644
--- a/lib/api/v3/tags.rb
+++ b/lib/api/v3/tags.rb
@@ -22,8 +22,8 @@ module API
delete ":id/repository/tags/:tag_name", requirements: { tag_name: /.+/ } do
authorize_push_project
- result = ::Tags::DestroyService.new(user_project, current_user).
- execute(params[:tag_name])
+ result = ::Tags::DestroyService.new(user_project, current_user)
+ .execute(params[:tag_name])
if result[:status] == :success
status(200)
diff --git a/lib/api/v3/users.rb b/lib/api/v3/users.rb
index f4cda3b2eba..37020019e07 100644
--- a/lib/api/v3/users.rb
+++ b/lib/api/v3/users.rb
@@ -50,13 +50,13 @@ module API
if user.persisted?
present user, with: ::API::Entities::UserPublic
else
- conflict!('Email has already been taken') if User.
- where(email: user.email).
- count > 0
+ conflict!('Email has already been taken') if User
+ .where(email: user.email)
+ .count > 0
- conflict!('Username has already been taken') if User.
- where(username: user.username).
- count > 0
+ conflict!('Username has already been taken') if User
+ .where(username: user.username)
+ .count > 0
render_validation_error!(user)
end
@@ -137,11 +137,11 @@ module API
user = User.find_by(id: params[:id])
not_found!('User') unless user
- events = user.events.
- merge(ProjectsFinder.new(current_user: current_user).execute).
- references(:project).
- with_associations.
- recent
+ events = user.events
+ .merge(ProjectsFinder.new(current_user: current_user).execute)
+ .references(:project)
+ .with_associations
+ .recent
present paginate(events), with: ::API::V3::Entities::Event
end
diff --git a/lib/banzai/reference_extractor.rb b/lib/banzai/reference_extractor.rb
index 8e3b0c4db79..7e6357f8a00 100644
--- a/lib/banzai/reference_extractor.rb
+++ b/lib/banzai/reference_extractor.rb
@@ -10,8 +10,8 @@ module Banzai
end
def references(type, project, current_user = nil)
- processor = Banzai::ReferenceParser[type].
- new(project, current_user)
+ processor = Banzai::ReferenceParser[type]
+ .new(project, current_user)
processor.process(html_documents)
end
diff --git a/lib/banzai/reference_parser/issue_parser.rb b/lib/banzai/reference_parser/issue_parser.rb
index 89ec715ddf6..9fd4bd68d43 100644
--- a/lib/banzai/reference_parser/issue_parser.rb
+++ b/lib/banzai/reference_parser/issue_parser.rb
@@ -9,8 +9,8 @@ module Banzai
issues = issues_for_nodes(nodes)
- readable_issues = Ability.
- issues_readable_by_user(issues.values, user).to_set
+ readable_issues = Ability
+ .issues_readable_by_user(issues.values, user).to_set
nodes.select do |node|
readable_issues.include?(issues[node])
diff --git a/lib/banzai/reference_parser/user_parser.rb b/lib/banzai/reference_parser/user_parser.rb
index 3efbd2fd631..4d336068861 100644
--- a/lib/banzai/reference_parser/user_parser.rb
+++ b/lib/banzai/reference_parser/user_parser.rb
@@ -99,8 +99,8 @@ module Banzai
def find_users_for_projects(ids)
return [] if ids.empty?
- collection_objects_for_ids(Project, ids).
- flat_map { |p| p.team.members.to_a }
+ collection_objects_for_ids(Project, ids)
+ .flat_map { |p| p.team.members.to_a }
end
def can_read_reference?(user, ref_project, node)
diff --git a/lib/ci/charts.rb b/lib/ci/charts.rb
index 3decc3b1a26..6063d6f45e8 100644
--- a/lib/ci/charts.rb
+++ b/lib/ci/charts.rb
@@ -2,10 +2,10 @@ module Ci
module Charts
module DailyInterval
def grouped_count(query)
- query.
- group("DATE(#{Ci::Build.table_name}.created_at)").
- count(:created_at).
- transform_keys { |date| date.strftime(@format) }
+ query
+ .group("DATE(#{Ci::Build.table_name}.created_at)")
+ .count(:created_at)
+ .transform_keys { |date| date.strftime(@format) }
end
def interval_step
@@ -16,14 +16,14 @@ module Ci
module MonthlyInterval
def grouped_count(query)
if Gitlab::Database.postgresql?
- query.
- group("to_char(#{Ci::Build.table_name}.created_at, '01 Month YYYY')").
- count(:created_at).
- transform_keys(&:squish)
+ query
+ .group("to_char(#{Ci::Build.table_name}.created_at, '01 Month YYYY')")
+ .count(:created_at)
+ .transform_keys(&:squish)
else
- query.
- group("DATE_FORMAT(#{Ci::Build.table_name}.created_at, '01 %M %Y')").
- count(:created_at)
+ query
+ .group("DATE_FORMAT(#{Ci::Build.table_name}.created_at, '01 %M %Y')")
+ .count(:created_at)
end
end
@@ -46,8 +46,8 @@ module Ci
end
def collect
- query = project.builds.
- where("? > #{Ci::Build.table_name}.created_at AND #{Ci::Build.table_name}.created_at > ?", @to, @from)
+ query = project.builds
+ .where("? > #{Ci::Build.table_name}.created_at AND #{Ci::Build.table_name}.created_at > ?", @to, @from)
totals_count = grouped_count(query)
success_count = grouped_count(query.success)
diff --git a/lib/github/import.rb b/lib/github/import.rb
index b20614b3060..ff5d7db2705 100644
--- a/lib/github/import.rb
+++ b/lib/github/import.rb
@@ -172,7 +172,7 @@ module Github
next unless merge_request.new_record? && pull_request.valid?
begin
- restore_branches(pull_request)
+ pull_request.restore_branches!
author_id = user_id(pull_request.author, project.creator_id)
description = format_description(pull_request.description, pull_request.author)
@@ -208,7 +208,7 @@ module Github
rescue => e
error(:pull_request, pull_request.url, e.message)
ensure
- clean_up_restored_branches(pull_request)
+ pull_request.remove_restored_branches!
end
end
@@ -325,32 +325,6 @@ module Github
end
end
- def restore_branches(pull_request)
- restore_source_branch(pull_request) unless pull_request.source_branch_exists?
- restore_target_branch(pull_request) unless pull_request.target_branch_exists?
- end
-
- def restore_source_branch(pull_request)
- repository.create_branch(pull_request.source_branch_name, pull_request.source_branch_sha)
- end
-
- def restore_target_branch(pull_request)
- repository.create_branch(pull_request.target_branch_name, pull_request.target_branch_sha)
- end
-
- def remove_branch(name)
- repository.delete_branch(name)
- rescue Rugged::ReferenceError
- errors << { type: :branch, url: nil, error: "Could not clean up restored branch: #{name}" }
- end
-
- def clean_up_restored_branches(pull_request)
- return if pull_request.opened?
-
- remove_branch(pull_request.source_branch_name) unless pull_request.source_branch_exists?
- remove_branch(pull_request.target_branch_name) unless pull_request.target_branch_exists?
- end
-
def label_ids(labels)
labels.map { |attrs| cached[:label_ids][attrs.fetch('name')] }.compact
end
diff --git a/lib/github/representation/branch.rb b/lib/github/representation/branch.rb
index d1dac6944f0..c6fa928d565 100644
--- a/lib/github/representation/branch.rb
+++ b/lib/github/representation/branch.rb
@@ -26,13 +26,25 @@ module Github
end
def exists?
- branch_exists? && commit_exists?
+ @exists ||= branch_exists? && commit_exists?
end
def valid?
sha.present? && ref.present?
end
+ def restore!(name)
+ repository.create_branch(name, sha)
+ rescue Gitlab::Git::Repository::InvalidRef => e
+ Rails.logger.error("#{self.class.name}: Could not restore branch #{name}: #{e}")
+ end
+
+ def remove!(name)
+ repository.delete_branch(name)
+ rescue Rugged::ReferenceError => e
+ Rails.logger.error("#{self.class.name}: Could not remove branch #{name}: #{e}")
+ end
+
private
def branch_exists?
diff --git a/lib/github/representation/pull_request.rb b/lib/github/representation/pull_request.rb
index ac9c8283b4b..55461097e8a 100644
--- a/lib/github/representation/pull_request.rb
+++ b/lib/github/representation/pull_request.rb
@@ -1,8 +1,6 @@
module Github
module Representation
class PullRequest < Representation::Issuable
- attr_reader :project
-
delegate :user, :repo, :ref, :sha, to: :source_branch, prefix: true
delegate :user, :exists?, :repo, :ref, :sha, :short_sha, to: :target_branch, prefix: true
@@ -10,10 +8,6 @@ module Github
project
end
- def source_branch_exists?
- !cross_project? && source_branch.exists?
- end
-
def source_branch_name
@source_branch_name ||=
if cross_project? || !source_branch_exists?
@@ -23,6 +17,12 @@ module Github
end
end
+ def source_branch_exists?
+ return @source_branch_exists if defined?(@source_branch_exists)
+
+ @source_branch_exists = !cross_project? && source_branch.exists?
+ end
+
def target_project
project
end
@@ -31,6 +31,10 @@ module Github
@target_branch_name ||= target_branch_exists? ? target_branch_ref : target_branch_name_prefixed
end
+ def target_branch_exists?
+ @target_branch_exists ||= target_branch.exists?
+ end
+
def state
return 'merged' if raw['state'] == 'closed' && raw['merged_at'].present?
return 'closed' if raw['state'] == 'closed'
@@ -46,6 +50,18 @@ module Github
source_branch.valid? && target_branch.valid?
end
+ def restore_branches!
+ restore_source_branch!
+ restore_target_branch!
+ end
+
+ def remove_restored_branches!
+ return if opened?
+
+ remove_source_branch!
+ remove_target_branch!
+ end
+
private
def project
@@ -73,6 +89,32 @@ module Github
source_branch_repo.id != target_branch_repo.id
end
+
+ def restore_source_branch!
+ return if source_branch_exists?
+
+ source_branch.restore!(source_branch_name)
+ end
+
+ def restore_target_branch!
+ return if target_branch_exists?
+
+ target_branch.restore!(target_branch_name)
+ end
+
+ def remove_source_branch!
+ # We should remove the source/target branches only if they were
+ # restored. Otherwise, we'll remove branches like 'master' that
+ # target_branch_exists? returns true. In other words, we need
+ # to clean up only the restored branches that (source|target)_branch_exists?
+ # returns false for the first time it has been called, because of
+ # this that is important to memoize these values.
+ source_branch.remove!(source_branch_name) unless source_branch_exists?
+ end
+
+ def remove_target_branch!
+ target_branch.remove!(target_branch_name) unless target_branch_exists?
+ end
end
end
end
diff --git a/lib/gitlab/background_migration.rb b/lib/gitlab/background_migration.rb
index 914a3b72abd..d95ecd7b291 100644
--- a/lib/gitlab/background_migration.rb
+++ b/lib/gitlab/background_migration.rb
@@ -5,8 +5,8 @@ module Gitlab
#
# steal_class - The name of the class for which to steal jobs.
def self.steal(steal_class)
- queue = Sidekiq::Queue.
- new(BackgroundMigrationWorker.sidekiq_options['queue'])
+ queue = Sidekiq::Queue
+ .new(BackgroundMigrationWorker.sidekiq_options['queue'])
queue.each do |job|
migration_class, migration_args = job.args
diff --git a/lib/gitlab/cache/ci/project_pipeline_status.rb b/lib/gitlab/cache/ci/project_pipeline_status.rb
index 4fc9a075edc..9c2e09943b0 100644
--- a/lib/gitlab/cache/ci/project_pipeline_status.rb
+++ b/lib/gitlab/cache/ci/project_pipeline_status.rb
@@ -50,8 +50,8 @@ module Gitlab
ref: pipeline.ref
}
- new(pipeline.project, pipeline_info: pipeline_info).
- store_in_cache_if_needed
+ new(pipeline.project, pipeline_info: pipeline_info)
+ .store_in_cache_if_needed
end
def initialize(project, pipeline_info: {}, loaded_from_cache: nil)
diff --git a/lib/gitlab/ci/pipeline_duration.rb b/lib/gitlab/ci/pipeline_duration.rb
index a210e76acaa..3208cc2bef6 100644
--- a/lib/gitlab/ci/pipeline_duration.rb
+++ b/lib/gitlab/ci/pipeline_duration.rb
@@ -87,8 +87,8 @@ module Gitlab
def from_pipeline(pipeline)
status = %w[success failed running canceled]
- builds = pipeline.builds.latest.
- where(status: status).where.not(started_at: nil).order(:started_at)
+ builds = pipeline.builds.latest
+ .where(status: status).where.not(started_at: nil).order(:started_at)
from_builds(builds)
end
diff --git a/lib/gitlab/conflict/file_collection.rb b/lib/gitlab/conflict/file_collection.rb
index 6e73361cad1..1611eba31da 100644
--- a/lib/gitlab/conflict/file_collection.rb
+++ b/lib/gitlab/conflict/file_collection.rb
@@ -16,9 +16,9 @@ module Gitlab
project = merge_request.source_project
new(merge_request, project).tap do |file_collection|
- project.
- repository.
- with_repo_branch_commit(merge_request.target_project.repository, merge_request.target_branch) do
+ project
+ .repository
+ .with_repo_branch_commit(merge_request.target_project.repository, merge_request.target_branch) do
yield file_collection
end
diff --git a/lib/gitlab/contributions_calendar.rb b/lib/gitlab/contributions_calendar.rb
index 060e013183f..bf557103cfd 100644
--- a/lib/gitlab/contributions_calendar.rb
+++ b/lib/gitlab/contributions_calendar.rb
@@ -16,14 +16,14 @@ module Gitlab
# Can't use Event.contributions here because we need to check 3 different
# project_features for the (currently) 3 different contribution types
date_from = 1.year.ago
- repo_events = event_counts(date_from, :repository).
- having(action: Event::PUSHED)
- issue_events = event_counts(date_from, :issues).
- having(action: [Event::CREATED, Event::CLOSED], target_type: "Issue")
- mr_events = event_counts(date_from, :merge_requests).
- having(action: [Event::MERGED, Event::CREATED, Event::CLOSED], target_type: "MergeRequest")
- note_events = event_counts(date_from, :merge_requests).
- having(action: [Event::COMMENTED], target_type: "Note")
+ repo_events = event_counts(date_from, :repository)
+ .having(action: Event::PUSHED)
+ issue_events = event_counts(date_from, :issues)
+ .having(action: [Event::CREATED, Event::CLOSED], target_type: "Issue")
+ mr_events = event_counts(date_from, :merge_requests)
+ .having(action: [Event::MERGED, Event::CREATED, Event::CLOSED], target_type: "MergeRequest")
+ note_events = event_counts(date_from, :merge_requests)
+ .having(action: [Event::COMMENTED], target_type: "Note")
union = Gitlab::SQL::Union.new([repo_events, issue_events, mr_events, note_events])
events = Event.find_by_sql(union.to_sql).map(&:attributes)
@@ -34,9 +34,9 @@ module Gitlab
end
def events_by_date(date)
- events = Event.contributions.where(author_id: contributor.id).
- where(created_at: date.beginning_of_day..date.end_of_day).
- where(project_id: projects)
+ events = Event.contributions.where(author_id: contributor.id)
+ .where(created_at: date.beginning_of_day..date.end_of_day)
+ .where(project_id: projects)
# Use visible_to_user? instead of the complicated logic in activity_dates
# because we're only viewing the events for a single day.
@@ -60,20 +60,20 @@ module Gitlab
# use IN(project_ids...) instead. It's the intersection of two users so
# the list will be (relatively) short
@contributed_project_ids ||= projects.uniq.pluck(:id)
- authed_projects = Project.where(id: @contributed_project_ids).
- with_feature_available_for_user(feature, current_user).
- reorder(nil).
- select(:id)
+ authed_projects = Project.where(id: @contributed_project_ids)
+ .with_feature_available_for_user(feature, current_user)
+ .reorder(nil)
+ .select(:id)
- conditions = t[:created_at].gteq(date_from.beginning_of_day).
- and(t[:created_at].lteq(Date.today.end_of_day)).
- and(t[:author_id].eq(contributor.id))
+ conditions = t[:created_at].gteq(date_from.beginning_of_day)
+ .and(t[:created_at].lteq(Date.today.end_of_day))
+ .and(t[:author_id].eq(contributor.id))
- Event.reorder(nil).
- select(t[:project_id], t[:target_type], t[:action], 'date(created_at) AS date', 'count(id) as total_amount').
- group(t[:project_id], t[:target_type], t[:action], 'date(created_at)').
- where(conditions).
- having(t[:project_id].in(Arel::Nodes::SqlLiteral.new(authed_projects.to_sql)))
+ Event.reorder(nil)
+ .select(t[:project_id], t[:target_type], t[:action], 'date(created_at) AS date', 'count(id) as total_amount')
+ .group(t[:project_id], t[:target_type], t[:action], 'date(created_at)')
+ .where(conditions)
+ .having(t[:project_id].in(Arel::Nodes::SqlLiteral.new(authed_projects.to_sql)))
end
end
end
diff --git a/lib/gitlab/current_settings.rb b/lib/gitlab/current_settings.rb
index 48735fd197d..818b3d9c46b 100644
--- a/lib/gitlab/current_settings.rb
+++ b/lib/gitlab/current_settings.rb
@@ -10,43 +10,49 @@ module Gitlab
delegate :sidekiq_throttling_enabled?, to: :current_application_settings
- def fake_application_settings
- OpenStruct.new(::ApplicationSetting.defaults)
+ def fake_application_settings(defaults = ::ApplicationSetting.defaults)
+ FakeApplicationSettings.new(defaults)
end
private
def ensure_application_settings!
- unless ENV['IN_MEMORY_APPLICATION_SETTINGS'] == 'true'
- settings = retrieve_settings_from_database?
- end
+ return in_memory_application_settings if ENV['IN_MEMORY_APPLICATION_SETTINGS'] == 'true'
- settings || in_memory_application_settings
+ cached_application_settings || uncached_application_settings
end
- def retrieve_settings_from_database?
- settings = retrieve_settings_from_database_cache?
- return settings if settings.present?
-
- return fake_application_settings unless connect_to_db?
-
+ def cached_application_settings
begin
- db_settings = ::ApplicationSetting.current
- # In case Redis isn't running or the Redis UNIX socket file is not available
+ ::ApplicationSetting.cached
rescue ::Redis::BaseError, ::Errno::ENOENT
- db_settings = ::ApplicationSetting.last
+ # In case Redis isn't running or the Redis UNIX socket file is not available
end
- db_settings || ::ApplicationSetting.create_from_defaults
end
- def retrieve_settings_from_database_cache?
+ def uncached_application_settings
+ return fake_application_settings unless connect_to_db?
+
+ # This loads from the database into the cache, so handle Redis errors
begin
- settings = ApplicationSetting.cached
+ db_settings = ::ApplicationSetting.current
rescue ::Redis::BaseError, ::Errno::ENOENT
# In case Redis isn't running or the Redis UNIX socket file is not available
- settings = nil
end
- settings
+
+ # If there are pending migrations, it's possible there are columns that
+ # need to be added to the application settings. To prevent Rake tasks
+ # and other callers from failing, use any loaded settings and return
+ # defaults for missing columns.
+ if ActiveRecord::Migrator.needs_migration?
+ defaults = ::ApplicationSetting.defaults
+ defaults.merge!(db_settings.attributes.symbolize_keys) if db_settings.present?
+ return fake_application_settings(defaults)
+ end
+
+ return db_settings if db_settings.present?
+
+ ::ApplicationSetting.create_from_defaults || in_memory_application_settings
end
def in_memory_application_settings
@@ -62,8 +68,7 @@ module Gitlab
active_db_connection = ActiveRecord::Base.connection.active? rescue false
active_db_connection &&
- ActiveRecord::Base.connection.table_exists?('application_settings') &&
- !ActiveRecord::Migrator.needs_migration?
+ ActiveRecord::Base.connection.table_exists?('application_settings')
rescue ActiveRecord::NoDatabaseError
false
end
diff --git a/lib/gitlab/cycle_analytics/base_query.rb b/lib/gitlab/cycle_analytics/base_query.rb
index d560dca45c8..58729d3ced8 100644
--- a/lib/gitlab/cycle_analytics/base_query.rb
+++ b/lib/gitlab/cycle_analytics/base_query.rb
@@ -12,17 +12,17 @@ module Gitlab
end
def stage_query
- query = mr_closing_issues_table.join(issue_table).on(issue_table[:id].eq(mr_closing_issues_table[:issue_id])).
- join(issue_metrics_table).on(issue_table[:id].eq(issue_metrics_table[:issue_id])).
- where(issue_table[:project_id].eq(@project.id)).
- where(issue_table[:deleted_at].eq(nil)).
- where(issue_table[:created_at].gteq(@options[:from]))
+ query = mr_closing_issues_table.join(issue_table).on(issue_table[:id].eq(mr_closing_issues_table[:issue_id]))
+ .join(issue_metrics_table).on(issue_table[:id].eq(issue_metrics_table[:issue_id]))
+ .where(issue_table[:project_id].eq(@project.id))
+ .where(issue_table[:deleted_at].eq(nil))
+ .where(issue_table[:created_at].gteq(@options[:from]))
# Load merge_requests
- query = query.join(mr_table, Arel::Nodes::OuterJoin).
- on(mr_table[:id].eq(mr_closing_issues_table[:merge_request_id])).
- join(mr_metrics_table).
- on(mr_table[:id].eq(mr_metrics_table[:merge_request_id]))
+ query = query.join(mr_table, Arel::Nodes::OuterJoin)
+ .on(mr_table[:id].eq(mr_closing_issues_table[:merge_request_id]))
+ .join(mr_metrics_table)
+ .on(mr_table[:id].eq(mr_metrics_table[:merge_request_id]))
query
end
diff --git a/lib/gitlab/database.rb b/lib/gitlab/database.rb
index d0bd1299671..0d5a7cf0694 100644
--- a/lib/gitlab/database.rb
+++ b/lib/gitlab/database.rb
@@ -83,6 +83,22 @@ module Gitlab
end
end
+ def self.bulk_insert(table, rows)
+ return if rows.empty?
+
+ keys = rows.first.keys
+ columns = keys.map { |key| connection.quote_column_name(key) }
+
+ tuples = rows.map do |row|
+ row.values_at(*keys).map { |value| connection.quote(value) }
+ end
+
+ connection.execute <<-EOF.strip_heredoc
+ INSERT INTO #{table} (#{columns.join(', ')})
+ VALUES #{tuples.map { |tuple| "(#{tuple.join(', ')})" }.join(', ')}
+ EOF
+ 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/database/median.rb b/lib/gitlab/database/median.rb
index 23890e5f493..059054ac9ff 100644
--- a/lib/gitlab/database/median.rb
+++ b/lib/gitlab/database/median.rb
@@ -29,10 +29,10 @@ module Gitlab
end
def mysql_median_datetime_sql(arel_table, query_so_far, column_sym)
- query = arel_table.
- from(arel_table.project(Arel.sql('*')).order(arel_table[column_sym]).as(arel_table.table_name)).
- project(average([arel_table[column_sym]], 'median')).
- where(
+ query = arel_table
+ .from(arel_table.project(Arel.sql('*')).order(arel_table[column_sym]).as(arel_table.table_name))
+ .project(average([arel_table[column_sym]], 'median'))
+ .where(
Arel::Nodes::Between.new(
Arel.sql("(select @row_id := @row_id + 1)"),
Arel::Nodes::And.new(
@@ -67,8 +67,8 @@ module Gitlab
cte_table = Arel::Table.new("ordered_records")
cte = Arel::Nodes::As.new(
cte_table,
- arel_table.
- project(
+ arel_table
+ .project(
arel_table[column_sym].as(column_sym.to_s),
Arel::Nodes::Over.new(Arel::Nodes::NamedFunction.new("row_number", []),
Arel::Nodes::Window.new.order(arel_table[column_sym])).as('row_id'),
@@ -79,8 +79,8 @@ module Gitlab
# From the CTE, select either the middle row or the middle two rows (this is accomplished
# by 'where cte.row_id between cte.ct / 2.0 AND cte.ct / 2.0 + 1'). Find the average of the
# selected rows, and this is the median value.
- cte_table.project(average([extract_epoch(cte_table[column_sym])], "median")).
- where(
+ cte_table.project(average([extract_epoch(cte_table[column_sym])], "median"))
+ .where(
Arel::Nodes::Between.new(
cte_table[:row_id],
Arel::Nodes::And.new(
@@ -88,9 +88,9 @@ module Gitlab
(cte_table[:ct] / Arel.sql('2.0') + 1)]
)
)
- ).
- with(query_so_far, cte).
- to_sql
+ )
+ .with(query_so_far, cte)
+ .to_sql
end
private
diff --git a/lib/gitlab/database/migration_helpers.rb b/lib/gitlab/database/migration_helpers.rb
index cd85f961242..60cce9c6d9e 100644
--- a/lib/gitlab/database/migration_helpers.rb
+++ b/lib/gitlab/database/migration_helpers.rb
@@ -233,25 +233,31 @@ module Gitlab
# Update in batches of 5% until we run out of any rows to update.
batch_size = ((total / 100.0) * 5.0).ceil
+ max_size = 1000
+
+ # The upper limit is 1000 to ensure we don't lock too many rows. For
+ # example, for "merge_requests" even 1% of the table is around 35 000
+ # rows for GitLab.com.
+ batch_size = max_size if batch_size > max_size
start_arel = table.project(table[:id]).order(table[:id].asc).take(1)
start_arel = yield table, start_arel if block_given?
start_id = exec_query(start_arel.to_sql).to_hash.first['id'].to_i
loop do
- stop_arel = table.project(table[:id]).
- where(table[:id].gteq(start_id)).
- order(table[:id].asc).
- take(1).
- skip(batch_size)
+ stop_arel = table.project(table[:id])
+ .where(table[:id].gteq(start_id))
+ .order(table[:id].asc)
+ .take(1)
+ .skip(batch_size)
stop_arel = yield table, stop_arel if block_given?
stop_row = exec_query(stop_arel.to_sql).to_hash.first
- update_arel = Arel::UpdateManager.new(ActiveRecord::Base).
- table(table).
- set([[table[column], value]]).
- where(table[:id].gteq(start_id))
+ update_arel = Arel::UpdateManager.new(ActiveRecord::Base)
+ .table(table)
+ .set([[table[column], value]])
+ .where(table[:id].gteq(start_id))
if stop_row
stop_id = stop_row['id'].to_i
@@ -580,15 +586,15 @@ module Gitlab
quoted_replacement = Arel::Nodes::Quoted.new(replacement.to_s)
if Database.mysql?
- locate = Arel::Nodes::NamedFunction.
- new('locate', [quoted_pattern, column])
- insert_in_place = Arel::Nodes::NamedFunction.
- new('insert', [column, locate, pattern.size, quoted_replacement])
+ locate = Arel::Nodes::NamedFunction
+ .new('locate', [quoted_pattern, column])
+ insert_in_place = Arel::Nodes::NamedFunction
+ .new('insert', [column, locate, pattern.size, quoted_replacement])
Arel::Nodes::SqlLiteral.new(insert_in_place.to_sql)
else
- replace = Arel::Nodes::NamedFunction.
- new("regexp_replace", [column, quoted_pattern, quoted_replacement])
+ replace = Arel::Nodes::NamedFunction
+ .new("regexp_replace", [column, quoted_pattern, quoted_replacement])
Arel::Nodes::SqlLiteral.new(replace.to_sql)
end
end
diff --git a/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_base.rb b/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_base.rb
index d60fd4bb551..d8163d7da11 100644
--- a/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_base.rb
+++ b/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_base.rb
@@ -27,8 +27,8 @@ module Gitlab
new_full_path = join_routable_path(namespace_path, new_path)
# skips callbacks & validations
- routable.class.where(id: routable).
- update_all(path: new_path)
+ routable.class.where(id: routable)
+ .update_all(path: new_path)
rename_routes(old_full_path, new_full_path)
diff --git a/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_namespaces.rb b/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_namespaces.rb
index 2958ad4b8e5..da7e2cb2e85 100644
--- a/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_namespaces.rb
+++ b/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_namespaces.rb
@@ -18,8 +18,8 @@ module Gitlab
when :top_level
MigrationClasses::Namespace.where(parent_id: nil)
end
- with_paths = MigrationClasses::Route.arel_table[:path].
- matches_any(path_patterns)
+ with_paths = MigrationClasses::Route.arel_table[:path]
+ .matches_any(path_patterns)
namespaces.joins(:route).where(with_paths)
end
@@ -52,15 +52,15 @@ module Gitlab
end
def repo_paths_for_namespace(namespace)
- projects_for_namespace(namespace).distinct.select(:repository_storage).
- map(&:repository_storage_path)
+ projects_for_namespace(namespace).distinct.select(:repository_storage)
+ .map(&:repository_storage_path)
end
def projects_for_namespace(namespace)
namespace_ids = child_ids_for_parent(namespace, ids: [namespace.id])
- namespace_or_children = MigrationClasses::Project.
- arel_table[:namespace_id].
- in(namespace_ids)
+ namespace_or_children = MigrationClasses::Project
+ .arel_table[:namespace_id]
+ .in(namespace_ids)
MigrationClasses::Project.where(namespace_or_children)
end
diff --git a/lib/gitlab/diff/line.rb b/lib/gitlab/diff/line.rb
index bd52ae47e9f..2d89ccfc354 100644
--- a/lib/gitlab/diff/line.rb
+++ b/lib/gitlab/diff/line.rb
@@ -42,25 +42,25 @@ module Gitlab
end
def added?
- type == 'new' || type == 'new-nonewline'
+ %w[new new-nonewline].include?(type)
end
def removed?
- type == 'old' || type == 'old-nonewline'
- end
-
- def rich_text
- @parent_file.highlight_lines! if @parent_file && !@rich_text
-
- @rich_text
+ %w[old old-nonewline].include?(type)
end
def meta?
- type == 'match'
+ %w[match new-nonewline old-nonewline].include?(type)
end
def discussable?
- !['match', 'new-nonewline', 'old-nonewline'].include?(type)
+ !meta?
+ end
+
+ def rich_text
+ @parent_file.highlight_lines! if @parent_file && !@rich_text
+
+ @rich_text
end
def as_json(opts = nil)
diff --git a/lib/gitlab/diff/parallel_diff.rb b/lib/gitlab/diff/parallel_diff.rb
index 481536a380b..0cb26fa45c8 100644
--- a/lib/gitlab/diff/parallel_diff.rb
+++ b/lib/gitlab/diff/parallel_diff.rb
@@ -14,16 +14,7 @@ module Gitlab
lines = []
highlighted_diff_lines = diff_file.highlighted_diff_lines
highlighted_diff_lines.each do |line|
- if line.meta? || line.unchanged?
- # line in the right panel is the same as in the left one
- lines << {
- left: line,
- right: line
- }
-
- free_right_index = nil
- i += 1
- elsif line.removed?
+ if line.removed?
lines << {
left: line,
right: nil
@@ -51,6 +42,15 @@ module Gitlab
free_right_index = nil
i += 1
end
+ elsif line.meta? || line.unchanged?
+ # line in the right panel is the same as in the left one
+ lines << {
+ left: line,
+ right: line
+ }
+
+ free_right_index = nil
+ i += 1
end
end
diff --git a/lib/gitlab/downtime_check.rb b/lib/gitlab/downtime_check.rb
index ab9537ed7d7..941244694e2 100644
--- a/lib/gitlab/downtime_check.rb
+++ b/lib/gitlab/downtime_check.rb
@@ -50,8 +50,8 @@ module Gitlab
# Returns the class for the given migration file path.
def class_for_migration_file(path)
- File.basename(path, File.extname(path)).split('_', 2).last.camelize.
- constantize
+ File.basename(path, File.extname(path)).split('_', 2).last.camelize
+ .constantize
end
# Returns true if the given migration can be performed without downtime.
diff --git a/lib/gitlab/email/html_parser.rb b/lib/gitlab/email/html_parser.rb
index a4ca62bfc41..50559a48973 100644
--- a/lib/gitlab/email/html_parser.rb
+++ b/lib/gitlab/email/html_parser.rb
@@ -17,6 +17,13 @@ module Gitlab
def filter_replies!
document.xpath('//blockquote').each(&:remove)
document.xpath('//table').each(&:remove)
+
+ # bogus links with no href are sometimes added by outlook,
+ # and can result in Html2Text adding extra square brackets
+ # to the text, so we unwrap them here.
+ document.xpath('//a[not(@href)]').each do |link|
+ link.replace(link.children)
+ end
end
def filtered_html
diff --git a/lib/gitlab/fake_application_settings.rb b/lib/gitlab/fake_application_settings.rb
new file mode 100644
index 00000000000..bb14a8cd9e7
--- /dev/null
+++ b/lib/gitlab/fake_application_settings.rb
@@ -0,0 +1,27 @@
+# This class extends an OpenStruct object by adding predicate methods to mimic
+# ActiveRecord access. We rely on the initial values being true or false to
+# determine whether to define a predicate method because for a newly-added
+# column that has not been migrated yet, there is no way to determine the
+# column type without parsing db/schema.rb.
+module Gitlab
+ class FakeApplicationSettings < OpenStruct
+ def initialize(options = {})
+ super
+
+ FakeApplicationSettings.define_predicate_methods(options)
+ end
+
+ # Mimic ActiveRecord predicate methods for boolean values
+ def self.define_predicate_methods(options)
+ options.each do |key, value|
+ next if key.to_s.end_with?('?')
+ next unless [true, false].include?(value)
+
+ define_method "#{key}?" do
+ actual_key = key.to_s.chomp('?')
+ self[actual_key]
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/git/blob.rb b/lib/gitlab/git/blob.rb
index 33a7624e303..a7aceab4c14 100644
--- a/lib/gitlab/git/blob.rb
+++ b/lib/gitlab/git/blob.rb
@@ -14,6 +14,51 @@ module Gitlab
class << self
def find(repository, sha, path)
+ Gitlab::GitalyClient.migrate(:project_raw_show) do |is_enabled|
+ if is_enabled
+ find_by_gitaly(repository, sha, path)
+ else
+ find_by_rugged(repository, sha, path)
+ end
+ end
+ end
+
+ def find_by_gitaly(repository, sha, path)
+ path = path.sub(/\A\/*/, '')
+ path = '/' if path.empty?
+ name = File.basename(path)
+ entry = Gitlab::GitalyClient::Commit.new(repository).tree_entry(sha, path, MAX_DATA_DISPLAY_SIZE)
+ return unless entry
+
+ case entry.type
+ when :COMMIT
+ new(
+ id: entry.oid,
+ name: name,
+ size: 0,
+ data: '',
+ path: path,
+ commit_id: sha
+ )
+ when :BLOB
+ # EncodingDetector checks the first 1024 * 1024 bytes for NUL byte, libgit2 checks
+ # only the first 8000 (https://github.com/libgit2/libgit2/blob/2ed855a9e8f9af211e7274021c2264e600c0f86b/src/filter.h#L15),
+ # which is what we use below to keep a consistent behavior.
+ detect = CharlockHolmes::EncodingDetector.new(8000).detect(entry.data)
+ new(
+ id: entry.oid,
+ name: name,
+ size: entry.size,
+ data: entry.data.dup,
+ mode: entry.mode.to_s(8),
+ path: path,
+ commit_id: sha,
+ binary: detect && detect[:type] == :binary
+ )
+ end
+ end
+
+ def find_by_rugged(repository, sha, path)
commit = repository.lookup(sha)
root_tree = commit.tree
diff --git a/lib/gitlab/git/commit.rb b/lib/gitlab/git/commit.rb
index bb04731f08c..d5d149f1423 100644
--- a/lib/gitlab/git/commit.rb
+++ b/lib/gitlab/git/commit.rb
@@ -4,7 +4,7 @@ module Gitlab
class Commit
include Gitlab::EncodingHelper
- attr_accessor :raw_commit, :head, :refs
+ attr_accessor :raw_commit, :head
SERIALIZE_KEYS = [
:id, :message, :parent_ids,
diff --git a/lib/gitlab/git/diff.rb b/lib/gitlab/git/diff.rb
index 4b689f0e94f..f825568f194 100644
--- a/lib/gitlab/git/diff.rb
+++ b/lib/gitlab/git/diff.rb
@@ -16,11 +16,11 @@ module Gitlab
alias_method :renamed_file?, :renamed_file
attr_accessor :expanded
+ attr_writer :too_large
alias_method :expanded?, :expanded
- # We need this accessor because of `to_hash` and `init_from_hash`
- attr_accessor :too_large
+ SERIALIZE_KEYS = %i(diff new_path old_path a_mode b_mode new_file renamed_file deleted_file too_large).freeze
class << self
# The maximum size of a diff to display.
@@ -231,16 +231,10 @@ module Gitlab
end
end
- def serialize_keys
- @serialize_keys ||= %i(diff new_path old_path a_mode b_mode new_file renamed_file deleted_file too_large)
- end
-
def to_hash
hash = {}
- keys = serialize_keys
-
- keys.each do |key|
+ SERIALIZE_KEYS.each do |key|
hash[key] = send(key)
end
@@ -267,6 +261,9 @@ module Gitlab
end
end
+ # This is used by `to_hash` and `init_from_hash`.
+ alias_method :too_large, :too_large?
+
def too_large!
@diff = ''
@line_count = 0
@@ -315,7 +312,7 @@ module Gitlab
def init_from_hash(hash)
raw_diff = hash.symbolize_keys
- serialize_keys.each do |key|
+ SERIALIZE_KEYS.each do |key|
send(:"#{key}=", raw_diff[key.to_sym])
end
end
diff --git a/lib/gitlab/git/gitmodules_parser.rb b/lib/gitlab/git/gitmodules_parser.rb
new file mode 100644
index 00000000000..f4e3b5e5129
--- /dev/null
+++ b/lib/gitlab/git/gitmodules_parser.rb
@@ -0,0 +1,77 @@
+module Gitlab
+ module Git
+ class GitmodulesParser
+ def initialize(content)
+ @content = content
+ end
+
+ # Parses the contents of a .gitmodules file and returns a hash of
+ # submodule information, indexed by path.
+ def parse
+ reindex_by_path(get_submodules_by_name)
+ end
+
+ private
+
+ class State
+ def initialize
+ @result = {}
+ @current_submodule = nil
+ end
+
+ def start_section(section)
+ # In some .gitmodules files (e.g. nodegit's), a header
+ # with the same name appears multiple times; we want to
+ # accumulate the configs across these
+ @current_submodule = @result[section] || { 'name' => section }
+ @result[section] = @current_submodule
+ end
+
+ def set_attribute(attr, value)
+ @current_submodule[attr] = value
+ end
+
+ def section_started?
+ !@current_submodule.nil?
+ end
+
+ def submodules_by_name
+ @result
+ end
+ end
+
+ def get_submodules_by_name
+ iterator = State.new
+
+ @content.split("\n").each_with_object(iterator) do |text, iterator|
+ next if text =~ /^\s*#/
+
+ if text =~ /\A\[submodule "(?<name>[^"]+)"\]\z/
+ iterator.start_section($~[:name])
+ else
+ next unless iterator.section_started?
+
+ next unless text =~ /\A\s*(?<key>\w+)\s*=\s*(?<value>.*)\z/
+
+ value = $~[:value].chomp
+ iterator.set_attribute($~[:key], value)
+ end
+ end
+
+ iterator.submodules_by_name
+ end
+
+ def reindex_by_path(submodules_by_name)
+ # Convert from an indexed by name to an array indexed by path
+ # If a submodule doesn't have a path, it is considered bogus
+ # and is ignored
+ submodules_by_name.each_with_object({}) do |(name, data), results|
+ path = data.delete 'path'
+ next unless path
+
+ results[path] = data
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/git/repository.rb b/lib/gitlab/git/repository.rb
index 85695d0a4df..c1f942f931a 100644
--- a/lib/gitlab/git/repository.rb
+++ b/lib/gitlab/git/repository.rb
@@ -617,9 +617,9 @@ module Gitlab
#
# Ex.
# {
- # "rack" => {
+ # "current_path/rack" => {
+ # "name" => "original_path/rack",
# "id" => "c67be4624545b4263184c4a0e8f887efd0a66320",
- # "path" => "rack",
# "url" => "git://github.com/chneukirchen/rack.git"
# },
# "encoding" => {
@@ -637,7 +637,8 @@ module Gitlab
return {}
end
- parse_gitmodules(commit, content)
+ parser = GitmodulesParser.new(content)
+ fill_submodule_ids(commit, parser.parse)
end
# Return total commits count accessible from passed ref
@@ -998,42 +999,19 @@ module Gitlab
end
end
- # Parses the contents of a .gitmodules file and returns a hash of
- # submodule information.
- def parse_gitmodules(commit, content)
- modules = {}
-
- name = nil
- content.each_line do |line|
- case line.strip
- when /\A\[submodule "(?<name>[^"]+)"\]\z/ # Submodule header
- name = $~[:name]
- modules[name] = {}
- when /\A(?<key>\w+)\s*=\s*(?<value>.*)\z/ # Key/value pair
- key = $~[:key]
- value = $~[:value].chomp
-
- next unless name && modules[name]
-
- modules[name][key] = value
-
- if key == 'path'
- begin
- modules[name]['id'] = blob_content(commit, value)
- rescue InvalidBlobName
- # The current entry is invalid
- modules.delete(name)
- name = nil
- end
- end
- when /\A#/ # Comment
- next
- else # Invalid line
- name = nil
+ # Fill in the 'id' field of a submodule hash from its values
+ # as-of +commit+. Return a Hash consisting only of entries
+ # from the submodule hash for which the 'id' field is filled.
+ def fill_submodule_ids(commit, submodule_data)
+ submodule_data.each do |path, data|
+ id = begin
+ blob_content(commit, path)
+ rescue InvalidBlobName
+ nil
end
+ data['id'] = id
end
-
- modules
+ submodule_data.select { |path, data| data['id'] }
end
# Returns true if +commit+ introduced changes to +path+, using commit
diff --git a/lib/gitlab/git_access.rb b/lib/gitlab/git_access.rb
index 0a19d24eb20..0b62911958d 100644
--- a/lib/gitlab/git_access.rb
+++ b/lib/gitlab/git_access.rb
@@ -22,12 +22,13 @@ module Gitlab
PUSH_COMMANDS = %w{ git-receive-pack }.freeze
ALL_COMMANDS = DOWNLOAD_COMMANDS + PUSH_COMMANDS
- attr_reader :actor, :project, :protocol, :authentication_abilities
+ attr_reader :actor, :project, :protocol, :authentication_abilities, :redirected_path
- def initialize(actor, project, protocol, authentication_abilities:)
+ def initialize(actor, project, protocol, authentication_abilities:, redirected_path: nil)
@actor = actor
@project = project
@protocol = protocol
+ @redirected_path = redirected_path
@authentication_abilities = authentication_abilities
end
@@ -35,6 +36,7 @@ module Gitlab
check_protocol!
check_active_user!
check_project_accessibility!
+ check_project_moved!
check_command_disabled!(cmd)
check_command_existence!(cmd)
check_repository_existence!
@@ -87,6 +89,21 @@ module Gitlab
end
end
+ def check_project_moved!
+ if redirected_path
+ url = protocol == 'ssh' ? project.ssh_url_to_repo : project.http_url_to_repo
+ message = <<-MESSAGE.strip_heredoc
+ Project '#{redirected_path}' was moved to '#{project.full_path}'.
+
+ Please update your Git remote and try again:
+
+ git remote set-url origin #{url}
+ MESSAGE
+
+ raise NotFoundError, message
+ end
+ end
+
def check_command_disabled!(cmd)
if upload_pack?(cmd)
check_upload_pack_disabled!
diff --git a/lib/gitlab/gitaly_client.rb b/lib/gitlab/gitaly_client.rb
index 2343446bf22..f605c06dfc3 100644
--- a/lib/gitlab/gitaly_client.rb
+++ b/lib/gitlab/gitaly_client.rb
@@ -1,3 +1,5 @@
+require 'base64'
+
require 'gitaly'
module Gitlab
@@ -48,6 +50,26 @@ module Gitlab
address
end
+ # All Gitaly RPC call sites should use GitalyClient.call. This method
+ # makes sure that per-request authentication headers are set.
+ def self.call(storage, service, rpc, request)
+ metadata = request_metadata(storage)
+ metadata = yield(metadata) if block_given?
+ stub(service, storage).send(rpc, request, metadata)
+ end
+
+ def self.request_metadata(storage)
+ encoded_token = Base64.strict_encode64(token(storage).to_s)
+ { metadata: { 'authorization' => "Bearer #{encoded_token}" } }
+ end
+
+ def self.token(storage)
+ params = Gitlab.config.repositories.storages[storage]
+ raise "storage not found: #{storage.inspect}" if params.nil?
+
+ params['gitaly_token'].presence || Gitlab.config.gitaly['token']
+ end
+
def self.enabled?
Gitlab.config.gitaly.enabled
end
diff --git a/lib/gitlab/gitaly_client/commit.rb b/lib/gitlab/gitaly_client/commit.rb
index ba3da781dad..b8877619797 100644
--- a/lib/gitlab/gitaly_client/commit.rb
+++ b/lib/gitlab/gitaly_client/commit.rb
@@ -11,33 +11,51 @@ module Gitlab
end
def is_ancestor(ancestor_id, child_id)
- stub = GitalyClient.stub(:commit, @repository.storage)
request = Gitaly::CommitIsAncestorRequest.new(
repository: @gitaly_repo,
ancestor_id: ancestor_id,
child_id: child_id
)
- stub.commit_is_ancestor(request).value
+ GitalyClient.call(@repository.storage, :commit, :commit_is_ancestor, request).value
end
def diff_from_parent(commit, options = {})
request_params = commit_diff_request_params(commit, options)
request_params[:ignore_whitespace_change] = options.fetch(:ignore_whitespace_change, false)
-
- response = diff_service_stub.commit_diff(Gitaly::CommitDiffRequest.new(request_params))
+ request = Gitaly::CommitDiffRequest.new(request_params)
+ response = GitalyClient.call(@repository.storage, :diff, :commit_diff, request)
Gitlab::Git::DiffCollection.new(GitalyClient::DiffStitcher.new(response), options)
end
def commit_deltas(commit)
- request_params = commit_diff_request_params(commit)
-
- response = diff_service_stub.commit_delta(Gitaly::CommitDeltaRequest.new(request_params))
+ request = Gitaly::CommitDeltaRequest.new(commit_diff_request_params(commit))
+ response = GitalyClient.call(@repository.storage, :diff, :commit_delta, request)
response.flat_map do |msg|
msg.deltas.map { |d| Gitlab::Git::Diff.new(d) }
end
end
+ def tree_entry(ref, path, limit = nil)
+ request = Gitaly::TreeEntryRequest.new(
+ repository: @gitaly_repo,
+ revision: ref,
+ path: path.dup.force_encoding(Encoding::ASCII_8BIT),
+ limit: limit.to_i
+ )
+
+ response = GitalyClient.call(@repository.storage, :commit, :tree_entry, request)
+ entry = response.first
+ return unless entry.oid.present?
+
+ if entry.type == :BLOB
+ rest_of_data = response.reduce("") { |memo, msg| memo << msg.data }
+ entry.data += rest_of_data
+ end
+
+ entry
+ end
+
private
def commit_diff_request_params(commit, options = {})
@@ -50,10 +68,6 @@ module Gitlab
paths: options.fetch(:paths, [])
}
end
-
- def diff_service_stub
- GitalyClient.stub(:diff, @repository.storage)
- end
end
end
end
diff --git a/lib/gitlab/gitaly_client/notifications.rb b/lib/gitlab/gitaly_client/notifications.rb
index 719554eac52..78ed433e6b8 100644
--- a/lib/gitlab/gitaly_client/notifications.rb
+++ b/lib/gitlab/gitaly_client/notifications.rb
@@ -1,17 +1,19 @@
module Gitlab
module GitalyClient
class Notifications
- attr_accessor :stub
-
# 'repository' is a Gitlab::Git::Repository
def initialize(repository)
@gitaly_repo = repository.gitaly_repository
- @stub = GitalyClient.stub(:notifications, repository.storage)
+ @storage = repository.storage
end
def post_receive
- request = Gitaly::PostReceiveRequest.new(repository: @gitaly_repo)
- @stub.post_receive(request)
+ GitalyClient.call(
+ @storage,
+ :notifications,
+ :post_receive,
+ Gitaly::PostReceiveRequest.new(repository: @gitaly_repo)
+ )
end
end
end
diff --git a/lib/gitlab/gitaly_client/ref.rb b/lib/gitlab/gitaly_client/ref.rb
index 227fe45642e..6d5f54dd959 100644
--- a/lib/gitlab/gitaly_client/ref.rb
+++ b/lib/gitlab/gitaly_client/ref.rb
@@ -1,29 +1,28 @@
module Gitlab
module GitalyClient
class Ref
- attr_accessor :stub
-
# 'repository' is a Gitlab::Git::Repository
def initialize(repository)
@gitaly_repo = repository.gitaly_repository
- @stub = GitalyClient.stub(:ref, repository.storage)
+ @storage = repository.storage
end
def default_branch_name
request = Gitaly::FindDefaultBranchNameRequest.new(repository: @gitaly_repo)
- branch_name = stub.find_default_branch_name(request).name
-
- Gitlab::Git.branch_name(branch_name)
+ response = GitalyClient.call(@storage, :ref, :find_default_branch_name, request)
+ Gitlab::Git.branch_name(response.name)
end
def branch_names
request = Gitaly::FindAllBranchNamesRequest.new(repository: @gitaly_repo)
- consume_refs_response(stub.find_all_branch_names(request), prefix: 'refs/heads/')
+ response = GitalyClient.call(@storage, :ref, :find_all_branch_names, request)
+ consume_refs_response(response, prefix: 'refs/heads/')
end
def tag_names
request = Gitaly::FindAllTagNamesRequest.new(repository: @gitaly_repo)
- consume_refs_response(stub.find_all_tag_names(request), prefix: 'refs/tags/')
+ response = GitalyClient.call(@storage, :ref, :find_all_tag_names, request)
+ consume_refs_response(response, prefix: 'refs/tags/')
end
def find_ref_name(commit_id, ref_prefix)
@@ -32,8 +31,7 @@ module Gitlab
commit_id: commit_id,
prefix: ref_prefix
)
-
- stub.find_ref_name(request).name
+ GitalyClient.call(@storage, :ref, :find_ref_name, request).name
end
def count_tag_names
@@ -47,7 +45,8 @@ module Gitlab
def local_branches(sort_by: nil)
request = Gitaly::FindLocalBranchesRequest.new(repository: @gitaly_repo)
request.sort_by = sort_by_param(sort_by) if sort_by
- consume_branches_response(stub.find_local_branches(request))
+ response = GitalyClient.call(@storage, :ref, :find_local_branches, request)
+ consume_branches_response(response)
end
private
diff --git a/lib/gitlab/group_hierarchy.rb b/lib/gitlab/group_hierarchy.rb
index e9d5d52cabb..5a31e56cb30 100644
--- a/lib/gitlab/group_hierarchy.rb
+++ b/lib/gitlab/group_hierarchy.rb
@@ -3,33 +3,38 @@ module Gitlab
#
# This class uses recursive CTEs and as a result will only work on PostgreSQL.
class GroupHierarchy
- attr_reader :base, :model
-
- # base - An instance of ActiveRecord::Relation for which to get parent or
- # child groups.
- def initialize(base)
- @base = base
- @model = base.model
+ attr_reader :ancestors_base, :descendants_base, :model
+
+ # ancestors_base - An instance of ActiveRecord::Relation for which to
+ # get parent groups.
+ # descendants_base - An instance of ActiveRecord::Relation for which to
+ # get child groups. If omitted, ancestors_base is used.
+ def initialize(ancestors_base, descendants_base = ancestors_base)
+ raise ArgumentError.new("Model of ancestors_base does not match model of descendants_base") if ancestors_base.model != descendants_base.model
+
+ @ancestors_base = ancestors_base
+ @descendants_base = descendants_base
+ @model = ancestors_base.model
end
- # Returns a relation that includes the base set of groups and all their
- # ancestors (recursively).
+ # Returns a relation that includes the ancestors_base set of groups
+ # and all their ancestors (recursively).
def base_and_ancestors
- return model.none unless Group.supports_nested_groups?
+ return ancestors_base unless Group.supports_nested_groups?
base_and_ancestors_cte.apply_to(model.all)
end
- # Returns a relation that includes the base set of groups and all their
- # descendants (recursively).
+ # Returns a relation that includes the descendants_base set of groups
+ # and all their descendants (recursively).
def base_and_descendants
- return model.none unless Group.supports_nested_groups?
+ return descendants_base unless Group.supports_nested_groups?
base_and_descendants_cte.apply_to(model.all)
end
- # Returns a relation that includes the base groups, their ancestors, and the
- # descendants of the base groups.
+ # Returns a relation that includes the base groups, their ancestors,
+ # and the descendants of the base groups.
#
# The resulting query will roughly look like the following:
#
@@ -48,8 +53,10 @@ module Gitlab
#
# Using this approach allows us to further add criteria to the relation with
# Rails thinking it's selecting data the usual way.
+ #
+ # If nested groups are not supported, ancestors_base is returned.
def all_groups
- return base unless Group.supports_nested_groups?
+ return ancestors_base unless Group.supports_nested_groups?
ancestors = base_and_ancestors_cte
descendants = base_and_descendants_cte
@@ -60,11 +67,11 @@ module Gitlab
union = SQL::Union.new([model.unscoped.from(ancestors_table),
model.unscoped.from(descendants_table)])
- model.
- unscoped.
- with.
- recursive(ancestors.to_arel, descendants.to_arel).
- from("(#{union.to_sql}) #{model.table_name}")
+ model
+ .unscoped
+ .with
+ .recursive(ancestors.to_arel, descendants.to_arel)
+ .from("(#{union.to_sql}) #{model.table_name}")
end
private
@@ -72,13 +79,13 @@ module Gitlab
def base_and_ancestors_cte
cte = SQL::RecursiveCTE.new(:base_and_ancestors)
- cte << base.except(:order)
+ cte << ancestors_base.except(:order)
# Recursively get all the ancestors of the base set.
- cte << model.
- from([groups_table, cte.table]).
- where(groups_table[:id].eq(cte.table[:parent_id])).
- except(:order)
+ cte << model
+ .from([groups_table, cte.table])
+ .where(groups_table[:id].eq(cte.table[:parent_id]))
+ .except(:order)
cte
end
@@ -86,13 +93,13 @@ module Gitlab
def base_and_descendants_cte
cte = SQL::RecursiveCTE.new(:base_and_descendants)
- cte << base.except(:order)
+ cte << descendants_base.except(:order)
# Recursively get all the descendants of the base set.
- cte << model.
- from([groups_table, cte.table]).
- where(groups_table[:parent_id].eq(cte.table[:id])).
- except(:order)
+ cte << model
+ .from([groups_table, cte.table])
+ .where(groups_table[:parent_id].eq(cte.table[:id]))
+ .except(:order)
cte
end
diff --git a/lib/gitlab/highlight.rb b/lib/gitlab/highlight.rb
index 6b24da030df..5408a1a6838 100644
--- a/lib/gitlab/highlight.rb
+++ b/lib/gitlab/highlight.rb
@@ -1,8 +1,8 @@
module Gitlab
class Highlight
def self.highlight(blob_name, blob_content, repository: nil, plain: false)
- new(blob_name, blob_content, repository: repository).
- highlight(blob_content, continue: false, plain: plain)
+ new(blob_name, blob_content, repository: repository)
+ .highlight(blob_content, continue: false, plain: plain)
end
attr_reader :blob_name
diff --git a/lib/gitlab/import_export.rb b/lib/gitlab/import_export.rb
index 27d5a9198b6..3470a09eaf0 100644
--- a/lib/gitlab/import_export.rb
+++ b/lib/gitlab/import_export.rb
@@ -3,7 +3,7 @@ module Gitlab
extend self
# For every version update, the version history in import_export.md has to be kept up to date.
- VERSION = '0.1.7'.freeze
+ VERSION = '0.1.8'.freeze
FILENAME_LIMIT = 50
def export_path(relative_path:)
diff --git a/lib/gitlab/import_export/import_export.yml b/lib/gitlab/import_export/import_export.yml
index ff2b1d08c3c..72183e8aad4 100644
--- a/lib/gitlab/import_export/import_export.yml
+++ b/lib/gitlab/import_export/import_export.yml
@@ -26,7 +26,8 @@ project_tree:
- notes:
- :author
- :events
- - :merge_request_diff
+ - merge_request_diff:
+ - :merge_request_diff_files
- :events
- :timelogs
- label_links:
@@ -92,6 +93,8 @@ excluded_attributes:
- :expired_at
merge_request_diff:
- :st_diffs
+ merge_request_diff_files:
+ - :diff
issues:
- :milestone_id
merge_requests:
@@ -113,6 +116,8 @@ methods:
- :type
merge_request_diff:
- :utf8_st_diffs
+ merge_request_diff_files:
+ - :utf8_diff
merge_requests:
- :diff_head_sha
project:
diff --git a/lib/gitlab/import_export/json_hash_builder.rb b/lib/gitlab/import_export/json_hash_builder.rb
index 48c09dafcb6..b48f63bcd7e 100644
--- a/lib/gitlab/import_export/json_hash_builder.rb
+++ b/lib/gitlab/import_export/json_hash_builder.rb
@@ -83,7 +83,9 @@ module Gitlab
# +value+ existing model to be included in the hash
# +json_config_hash+ the original hash containing the root model
def add_model_value(current_key, value, json_config_hash)
- @attributes_finder.parse(value) { |hash| value = { value => hash } }
+ @attributes_finder.parse(value) do |hash|
+ value = { value => hash } unless value.is_a?(Hash)
+ end
add_to_array(current_key, json_config_hash, value)
end
diff --git a/lib/gitlab/import_export/relation_factory.rb b/lib/gitlab/import_export/relation_factory.rb
index 695852526cb..20580459046 100644
--- a/lib/gitlab/import_export/relation_factory.rb
+++ b/lib/gitlab/import_export/relation_factory.rb
@@ -71,6 +71,7 @@ module Gitlab
@relation_hash['data'].deep_symbolize_keys! if @relation_name == :events && @relation_hash['data']
set_st_diff_commits if @relation_name == :merge_request_diff
+ set_diff if @relation_name == :merge_request_diff_files
end
def update_user_references
@@ -202,6 +203,10 @@ module Gitlab
HashUtil.deep_symbolize_array_with_date!(@relation_hash['st_commits'])
end
+ def set_diff
+ @relation_hash['diff'] = @relation_hash.delete('utf8_diff')
+ end
+
def existing_or_new_object
# Only find existing records to avoid mapping tables such as milestones
# Otherwise always create the record, skipping the extra SELECT clause.
diff --git a/lib/gitlab/job_waiter.rb b/lib/gitlab/job_waiter.rb
index 8db91d25a4b..208f0e1bbea 100644
--- a/lib/gitlab/job_waiter.rb
+++ b/lib/gitlab/job_waiter.rb
@@ -14,7 +14,7 @@ module Gitlab
# timeout - The maximum amount of seconds to block the caller for. This
# ensures we don't indefinitely block a caller in case a job takes
# long to process, or is never processed.
- def wait(timeout = 60)
+ def wait(timeout = 10)
start = Time.current
while (Time.current - start) <= timeout
diff --git a/lib/gitlab/ldap/user.rb b/lib/gitlab/ldap/user.rb
index 5e299e26c54..39180dc17d9 100644
--- a/lib/gitlab/ldap/user.rb
+++ b/lib/gitlab/ldap/user.rb
@@ -10,9 +10,9 @@ module Gitlab
class << self
def find_by_uid_and_provider(uid, provider)
# LDAP distinguished name is case-insensitive
- identity = ::Identity.
- where(provider: provider).
- iwhere(extern_uid: uid).last
+ identity = ::Identity
+ .where(provider: provider)
+ .iwhere(extern_uid: uid).last
identity && identity.user
end
end
diff --git a/lib/gitlab/metrics/influx_db.rb b/lib/gitlab/metrics/influx_db.rb
index 3a39791edbf..d7c56463aac 100644
--- a/lib/gitlab/metrics/influx_db.rb
+++ b/lib/gitlab/metrics/influx_db.rb
@@ -157,8 +157,8 @@ module Gitlab
host = settings[:host]
port = settings[:port]
- InfluxDB::Client.
- new(udp: { host: host, port: port })
+ InfluxDB::Client
+ .new(udp: { host: host, port: port })
end
end
end
diff --git a/lib/gitlab/metrics/prometheus.rb b/lib/gitlab/metrics/prometheus.rb
index 60686509332..9d314a56e58 100644
--- a/lib/gitlab/metrics/prometheus.rb
+++ b/lib/gitlab/metrics/prometheus.rb
@@ -5,8 +5,16 @@ module Gitlab
module Prometheus
include Gitlab::CurrentSettings
+ def metrics_folder_present?
+ ENV.has_key?('prometheus_multiproc_dir') &&
+ ::Dir.exist?(ENV['prometheus_multiproc_dir']) &&
+ ::File.writable?(ENV['prometheus_multiproc_dir'])
+ end
+
def prometheus_metrics_enabled?
- @prometheus_metrics_enabled ||= current_application_settings[:prometheus_metrics_enabled] || false
+ return @prometheus_metrics_enabled if defined?(@prometheus_metrics_enabled)
+
+ @prometheus_metrics_enabled = prometheus_metrics_enabled_unmemoized
end
def registry
@@ -36,6 +44,12 @@ module Gitlab
NullMetric.new
end
end
+
+ private
+
+ def prometheus_metrics_enabled_unmemoized
+ metrics_folder_present? && current_application_settings[:prometheus_metrics_enabled] || false
+ end
end
end
end
diff --git a/lib/gitlab/metrics/system.rb b/lib/gitlab/metrics/system.rb
index 3aaebb3e9c3..aba3e0df382 100644
--- a/lib/gitlab/metrics/system.rb
+++ b/lib/gitlab/metrics/system.rb
@@ -34,13 +34,13 @@ module Gitlab
# THREAD_CPUTIME is not supported on OS X
if Process.const_defined?(:CLOCK_THREAD_CPUTIME_ID)
def self.cpu_time
- Process.
- clock_gettime(Process::CLOCK_THREAD_CPUTIME_ID, :millisecond)
+ Process
+ .clock_gettime(Process::CLOCK_THREAD_CPUTIME_ID, :millisecond)
end
else
def self.cpu_time
- Process.
- clock_gettime(Process::CLOCK_PROCESS_CPUTIME_ID, :millisecond)
+ Process
+ .clock_gettime(Process::CLOCK_PROCESS_CPUTIME_ID, :millisecond)
end
end
diff --git a/lib/gitlab/other_markup.rb b/lib/gitlab/other_markup.rb
index 31a24460f0f..fc3f21233dd 100644
--- a/lib/gitlab/other_markup.rb
+++ b/lib/gitlab/other_markup.rb
@@ -6,8 +6,8 @@ module Gitlab
# input - the source text in a markup format
#
def self.render(file_name, input, context)
- html = GitHub::Markup.render(file_name, input).
- force_encoding(input.encoding)
+ html = GitHub::Markup.render(file_name, input)
+ .force_encoding(input.encoding)
context[:pipeline] = :markup
html = Banzai.render(html, context)
diff --git a/lib/gitlab/performance_bar/peek_query_tracker.rb b/lib/gitlab/performance_bar/peek_query_tracker.rb
index 7ab80f5ee0f..574ae8731a5 100644
--- a/lib/gitlab/performance_bar/peek_query_tracker.rb
+++ b/lib/gitlab/performance_bar/peek_query_tracker.rb
@@ -3,8 +3,8 @@ module Gitlab
module PerformanceBar
module PeekQueryTracker
def sorted_queries
- PEEK_DB_CLIENT.query_details.
- sort { |a, b| b[:duration] <=> a[:duration] }
+ PEEK_DB_CLIENT.query_details
+ .sort { |a, b| b[:duration] <=> a[:duration] }
end
def results
diff --git a/lib/gitlab/project_authorizations/with_nested_groups.rb b/lib/gitlab/project_authorizations/with_nested_groups.rb
index bb0df1e3dad..15b8beacf60 100644
--- a/lib/gitlab/project_authorizations/with_nested_groups.rb
+++ b/lib/gitlab/project_authorizations/with_nested_groups.rb
@@ -28,34 +28,34 @@ module Gitlab
# Projects that belong directly to any of the groups the user has
# access to.
- Namespace.
- unscoped.
- select([alias_as_column(projects[:id], 'project_id'),
- cte_alias[:access_level]]).
- from(cte_alias).
- joins(:projects),
+ Namespace
+ .unscoped
+ .select([alias_as_column(projects[:id], 'project_id'),
+ cte_alias[:access_level]])
+ .from(cte_alias)
+ .joins(:projects),
# Projects shared with any of the namespaces the user has access to.
- Namespace.
- unscoped.
- select([links[:project_id],
- least(cte_alias[:access_level],
- links[:group_access],
- 'access_level')]).
- from(cte_alias).
- joins('INNER JOIN project_group_links ON project_group_links.group_id = namespaces.id').
- joins('INNER JOIN projects ON projects.id = project_group_links.project_id').
- joins('INNER JOIN namespaces p_ns ON p_ns.id = projects.namespace_id').
- where('p_ns.share_with_group_lock IS FALSE')
+ Namespace
+ .unscoped
+ .select([links[:project_id],
+ least(cte_alias[:access_level],
+ links[:group_access],
+ 'access_level')])
+ .from(cte_alias)
+ .joins('INNER JOIN project_group_links ON project_group_links.group_id = namespaces.id')
+ .joins('INNER JOIN projects ON projects.id = project_group_links.project_id')
+ .joins('INNER JOIN namespaces p_ns ON p_ns.id = projects.namespace_id')
+ .where('p_ns.share_with_group_lock IS FALSE')
]
union = Gitlab::SQL::Union.new(relations)
- ProjectAuthorization.
- unscoped.
- with.
- recursive(cte.to_arel).
- select_from_union(union)
+ ProjectAuthorization
+ .unscoped
+ .with
+ .recursive(cte.to_arel)
+ .select_from_union(union)
end
private
@@ -68,17 +68,17 @@ module Gitlab
namespaces = Namespace.arel_table
# Namespaces the user is a member of.
- cte << user.groups.
- select([namespaces[:id], members[:access_level]]).
- except(:order)
+ cte << user.groups
+ .select([namespaces[:id], members[:access_level]])
+ .except(:order)
# Sub groups of any groups the user is a member of.
cte << Group.select([namespaces[:id],
greatest(members[:access_level],
- cte.table[:access_level], 'access_level')]).
- joins(join_cte(cte)).
- joins(join_members).
- except(:order)
+ cte.table[:access_level], 'access_level')])
+ .joins(join_cte(cte))
+ .joins(join_members)
+ .except(:order)
cte
end
@@ -88,11 +88,11 @@ module Gitlab
members = Member.arel_table
namespaces = Namespace.arel_table
- cond = members[:source_id].
- eq(namespaces[:id]).
- and(members[:source_type].eq('Namespace')).
- and(members[:requested_at].eq(nil)).
- and(members[:user_id].eq(user.id))
+ cond = members[:source_id]
+ .eq(namespaces[:id])
+ .and(members[:source_type].eq('Namespace'))
+ .and(members[:requested_at].eq(nil))
+ .and(members[:user_id].eq(user.id))
Arel::Nodes::OuterJoin.new(members, Arel::Nodes::On.new(cond))
end
diff --git a/lib/gitlab/project_authorizations/without_nested_groups.rb b/lib/gitlab/project_authorizations/without_nested_groups.rb
index 627e8c5fba2..ad87540e6c2 100644
--- a/lib/gitlab/project_authorizations/without_nested_groups.rb
+++ b/lib/gitlab/project_authorizations/without_nested_groups.rb
@@ -26,9 +26,9 @@ module Gitlab
union = Gitlab::SQL::Union.new(relations)
- ProjectAuthorization.
- unscoped.
- select_from_union(union)
+ ProjectAuthorization
+ .unscoped
+ .select_from_union(union)
end
end
end
diff --git a/lib/gitlab/slash_commands/command_definition.rb b/lib/gitlab/quick_actions/command_definition.rb
index caab8856014..3937d9c153a 100644
--- a/lib/gitlab/slash_commands/command_definition.rb
+++ b/lib/gitlab/quick_actions/command_definition.rb
@@ -1,5 +1,5 @@
module Gitlab
- module SlashCommands
+ module QuickActions
class CommandDefinition
attr_accessor :name, :aliases, :description, :explanation, :params,
:condition_block, :parse_params_block, :action_block
diff --git a/lib/gitlab/slash_commands/dsl.rb b/lib/gitlab/quick_actions/dsl.rb
index 1b5b4566d81..a4a97236ffc 100644
--- a/lib/gitlab/slash_commands/dsl.rb
+++ b/lib/gitlab/quick_actions/dsl.rb
@@ -1,5 +1,5 @@
module Gitlab
- module SlashCommands
+ module QuickActions
module Dsl
extend ActiveSupport::Concern
@@ -14,7 +14,7 @@ module Gitlab
end
class_methods do
- # Allows to give a description to the next slash command.
+ # Allows to give a description to the next quick action.
# This description is shown in the autocomplete menu.
# It accepts a block that will be evaluated with the context given to
# `CommandDefintion#to_h`.
@@ -31,7 +31,7 @@ module Gitlab
@description = block_given? ? block : text
end
- # Allows to define params for the next slash command.
+ # Allows to define params for the next quick action.
# These params are shown in the autocomplete menu.
#
# Example:
diff --git a/lib/gitlab/slash_commands/extractor.rb b/lib/gitlab/quick_actions/extractor.rb
index 6dbb467d70d..09576be7156 100644
--- a/lib/gitlab/slash_commands/extractor.rb
+++ b/lib/gitlab/quick_actions/extractor.rb
@@ -1,10 +1,10 @@
module Gitlab
- module SlashCommands
+ module QuickActions
# This class takes an array of commands that should be extracted from a
# given text.
#
# ```
- # extractor = Gitlab::SlashCommands::Extractor.new([:open, :assign, :labels])
+ # extractor = Gitlab::QuickActions::Extractor.new([:open, :assign, :labels])
# ```
class Extractor
attr_reader :command_definitions
@@ -24,7 +24,7 @@ module Gitlab
#
# Usage:
# ```
- # extractor = Gitlab::SlashCommands::Extractor.new([:open, :assign, :labels])
+ # extractor = Gitlab::QuickActions::Extractor.new([:open, :assign, :labels])
# msg = %(hello\n/labels ~foo ~"bar baz"\nworld)
# commands = extractor.extract_commands(msg) #=> [['labels', '~foo ~"bar baz"']]
# msg #=> "hello\nworld"
diff --git a/lib/gitlab/regex.rb b/lib/gitlab/regex.rb
index e4d2a992470..b706434217d 100644
--- a/lib/gitlab/regex.rb
+++ b/lib/gitlab/regex.rb
@@ -43,7 +43,7 @@ module Gitlab
end
def environment_name_regex_message
- "can contain only letters, digits, '-', '_', '/', '$', '{', '}', '.' and spaces"
+ "can contain only letters, digits, '-', '_', '/', '$', '{', '}', '.', and spaces"
end
def kubernetes_namespace_regex
diff --git a/lib/gitlab/repo_path.rb b/lib/gitlab/repo_path.rb
index 878e03f61d7..3591fa9145e 100644
--- a/lib/gitlab/repo_path.rb
+++ b/lib/gitlab/repo_path.rb
@@ -3,16 +3,18 @@ module Gitlab
NotFoundError = Class.new(StandardError)
def self.parse(repo_path)
+ wiki = false
project_path = strip_storage_path(repo_path.sub(/\.git\z/, ''), fail_on_not_found: false)
- project = Project.find_by_full_path(project_path)
- if project_path.end_with?('.wiki') && !project
- project = Project.find_by_full_path(project_path.chomp('.wiki'))
+ project, was_redirected = find_project(project_path)
+
+ if project_path.end_with?('.wiki') && project.nil?
+ project, was_redirected = find_project(project_path.chomp('.wiki'))
wiki = true
- else
- wiki = false
end
- [project, wiki]
+ redirected_path = project_path if was_redirected
+
+ [project, wiki, redirected_path]
end
def self.strip_storage_path(repo_path, fail_on_not_found: true)
@@ -30,5 +32,12 @@ module Gitlab
result.sub(/\A\/*/, '')
end
+
+ def self.find_project(project_path)
+ project = Project.find_by_full_path(project_path, follow_redirects: true)
+ was_redirected = project && project.full_path.casecmp(project_path) != 0
+
+ [project, was_redirected]
+ end
end
end
diff --git a/lib/gitlab/shell.rb b/lib/gitlab/shell.rb
index b1d6ea665b7..22554236c38 100644
--- a/lib/gitlab/shell.rb
+++ b/lib/gitlab/shell.rb
@@ -30,8 +30,8 @@ module Gitlab
end
def version_required
- @version_required ||= File.read(Rails.root.
- join('GITLAB_SHELL_VERSION')).strip
+ @version_required ||= File.read(Rails.root
+ .join('GITLAB_SHELL_VERSION')).strip
end
def strip_key(key)
diff --git a/lib/gitlab/sherlock/line_profiler.rb b/lib/gitlab/sherlock/line_profiler.rb
index aa1468bff6b..b5f9d040047 100644
--- a/lib/gitlab/sherlock/line_profiler.rb
+++ b/lib/gitlab/sherlock/line_profiler.rb
@@ -77,8 +77,8 @@ module Gitlab
line_samples << LineSample.new(duration, events)
end
- samples << FileSample.
- new(file, line_samples, total_duration, total_events)
+ samples << FileSample
+ .new(file, line_samples, total_duration, total_events)
end
samples
diff --git a/lib/gitlab/sherlock/query.rb b/lib/gitlab/sherlock/query.rb
index 99e56e923eb..948bf5e6528 100644
--- a/lib/gitlab/sherlock/query.rb
+++ b/lib/gitlab/sherlock/query.rb
@@ -105,10 +105,10 @@ module Gitlab
end
def format_sql(query)
- query.each_line.
- map { |line| line.strip }.
- join("\n").
- gsub(PREFIX_NEWLINE) { "\n#{$1} " }
+ query.each_line
+ .map { |line| line.strip }
+ .join("\n")
+ .gsub(PREFIX_NEWLINE) { "\n#{$1} " }
end
end
end
diff --git a/lib/gitlab/chat_commands/base_command.rb b/lib/gitlab/slash_commands/base_command.rb
index 25da8474e95..cc3c9a50555 100644
--- a/lib/gitlab/chat_commands/base_command.rb
+++ b/lib/gitlab/slash_commands/base_command.rb
@@ -1,5 +1,5 @@
module Gitlab
- module ChatCommands
+ module SlashCommands
class BaseCommand
QUERY_LIMIT = 5
diff --git a/lib/gitlab/chat_commands/command.rb b/lib/gitlab/slash_commands/command.rb
index 3e0c30c33b7..a78408b0519 100644
--- a/lib/gitlab/chat_commands/command.rb
+++ b/lib/gitlab/slash_commands/command.rb
@@ -1,11 +1,11 @@
module Gitlab
- module ChatCommands
+ module SlashCommands
class Command < BaseCommand
COMMANDS = [
- Gitlab::ChatCommands::IssueShow,
- Gitlab::ChatCommands::IssueNew,
- Gitlab::ChatCommands::IssueSearch,
- Gitlab::ChatCommands::Deploy
+ Gitlab::SlashCommands::IssueShow,
+ Gitlab::SlashCommands::IssueNew,
+ Gitlab::SlashCommands::IssueSearch,
+ Gitlab::SlashCommands::Deploy
].freeze
def execute
@@ -15,10 +15,10 @@ module Gitlab
if command.allowed?(project, current_user)
command.new(project, current_user, params).execute(match)
else
- Gitlab::ChatCommands::Presenters::Access.new.access_denied
+ Gitlab::SlashCommands::Presenters::Access.new.access_denied
end
else
- Gitlab::ChatCommands::Help.new(project, current_user, params).execute(available_commands, params[:text])
+ Gitlab::SlashCommands::Help.new(project, current_user, params).execute(available_commands, params[:text])
end
end
diff --git a/lib/gitlab/chat_commands/deploy.rb b/lib/gitlab/slash_commands/deploy.rb
index 458d90f84e8..e71eb15d604 100644
--- a/lib/gitlab/chat_commands/deploy.rb
+++ b/lib/gitlab/slash_commands/deploy.rb
@@ -1,5 +1,5 @@
module Gitlab
- module ChatCommands
+ module SlashCommands
class Deploy < BaseCommand
def self.match(text)
/\Adeploy\s+(?<from>\S+.*)\s+to+\s+(?<to>\S+.*)\z/.match(text)
@@ -24,12 +24,12 @@ module Gitlab
actions = find_actions(from, to)
if actions.none?
- Gitlab::ChatCommands::Presenters::Deploy.new(nil).no_actions
+ Gitlab::SlashCommands::Presenters::Deploy.new(nil).no_actions
elsif actions.one?
action = play!(from, to, actions.first)
- Gitlab::ChatCommands::Presenters::Deploy.new(action).present(from, to)
+ Gitlab::SlashCommands::Presenters::Deploy.new(action).present(from, to)
else
- Gitlab::ChatCommands::Presenters::Deploy.new(actions).too_many_actions
+ Gitlab::SlashCommands::Presenters::Deploy.new(actions).too_many_actions
end
end
diff --git a/lib/gitlab/chat_commands/help.rb b/lib/gitlab/slash_commands/help.rb
index 6c0e4d304a4..81f3707e03e 100644
--- a/lib/gitlab/chat_commands/help.rb
+++ b/lib/gitlab/slash_commands/help.rb
@@ -1,5 +1,5 @@
module Gitlab
- module ChatCommands
+ module SlashCommands
class Help < BaseCommand
# This class has to be used last, as it always matches. It has to match
# because other commands were not triggered and we want to show the help
@@ -17,7 +17,7 @@ module Gitlab
end
def execute(commands, text)
- Gitlab::ChatCommands::Presenters::Help.new(commands).present(trigger, text)
+ Gitlab::SlashCommands::Presenters::Help.new(commands).present(trigger, text)
end
def trigger
diff --git a/lib/gitlab/chat_commands/issue_command.rb b/lib/gitlab/slash_commands/issue_command.rb
index 84de3e44c70..87ea19b8806 100644
--- a/lib/gitlab/chat_commands/issue_command.rb
+++ b/lib/gitlab/slash_commands/issue_command.rb
@@ -1,5 +1,5 @@
module Gitlab
- module ChatCommands
+ module SlashCommands
class IssueCommand < BaseCommand
def self.available?(project)
project.issues_enabled? && project.default_issues_tracker?
diff --git a/lib/gitlab/chat_commands/issue_new.rb b/lib/gitlab/slash_commands/issue_new.rb
index 016054ecd46..25f965e843d 100644
--- a/lib/gitlab/chat_commands/issue_new.rb
+++ b/lib/gitlab/slash_commands/issue_new.rb
@@ -1,5 +1,5 @@
module Gitlab
- module ChatCommands
+ module SlashCommands
class IssueNew < IssueCommand
def self.match(text)
# we can not match \n with the dot by passing the m modifier as than
@@ -35,7 +35,7 @@ module Gitlab
end
def presenter(issue)
- Gitlab::ChatCommands::Presenters::IssueNew.new(issue)
+ Gitlab::SlashCommands::Presenters::IssueNew.new(issue)
end
end
end
diff --git a/lib/gitlab/chat_commands/issue_search.rb b/lib/gitlab/slash_commands/issue_search.rb
index 3491b53093e..acba84b54b4 100644
--- a/lib/gitlab/chat_commands/issue_search.rb
+++ b/lib/gitlab/slash_commands/issue_search.rb
@@ -1,5 +1,5 @@
module Gitlab
- module ChatCommands
+ module SlashCommands
class IssueSearch < IssueCommand
def self.match(text)
/\Aissue\s+search\s+(?<query>.*)/.match(text)
diff --git a/lib/gitlab/chat_commands/issue_show.rb b/lib/gitlab/slash_commands/issue_show.rb
index d6013f4d10c..ffa5184e5cb 100644
--- a/lib/gitlab/chat_commands/issue_show.rb
+++ b/lib/gitlab/slash_commands/issue_show.rb
@@ -1,5 +1,5 @@
module Gitlab
- module ChatCommands
+ module SlashCommands
class IssueShow < IssueCommand
def self.match(text)
/\Aissue\s+show\s+#{Issue.reference_prefix}?(?<iid>\d+)/.match(text)
@@ -13,9 +13,9 @@ module Gitlab
issue = find_by_iid(match[:iid])
if issue
- Gitlab::ChatCommands::Presenters::IssueShow.new(issue).present
+ Gitlab::SlashCommands::Presenters::IssueShow.new(issue).present
else
- Gitlab::ChatCommands::Presenters::Access.new.not_found
+ Gitlab::SlashCommands::Presenters::Access.new.not_found
end
end
end
diff --git a/lib/gitlab/chat_commands/presenters/access.rb b/lib/gitlab/slash_commands/presenters/access.rb
index 92f4fa17f78..1a817eb735b 100644
--- a/lib/gitlab/chat_commands/presenters/access.rb
+++ b/lib/gitlab/slash_commands/presenters/access.rb
@@ -1,5 +1,5 @@
module Gitlab
- module ChatCommands
+ module SlashCommands
module Presenters
class Access < Presenters::Base
def access_denied
diff --git a/lib/gitlab/chat_commands/presenters/base.rb b/lib/gitlab/slash_commands/presenters/base.rb
index 05994bee79d..27696436574 100644
--- a/lib/gitlab/chat_commands/presenters/base.rb
+++ b/lib/gitlab/slash_commands/presenters/base.rb
@@ -1,5 +1,5 @@
module Gitlab
- module ChatCommands
+ module SlashCommands
module Presenters
class Base
include Gitlab::Routing.url_helpers
diff --git a/lib/gitlab/chat_commands/presenters/deploy.rb b/lib/gitlab/slash_commands/presenters/deploy.rb
index 863d0bf99ca..b8dc77bd37b 100644
--- a/lib/gitlab/chat_commands/presenters/deploy.rb
+++ b/lib/gitlab/slash_commands/presenters/deploy.rb
@@ -1,5 +1,5 @@
module Gitlab
- module ChatCommands
+ module SlashCommands
module Presenters
class Deploy < Presenters::Base
def present(from, to)
diff --git a/lib/gitlab/chat_commands/presenters/help.rb b/lib/gitlab/slash_commands/presenters/help.rb
index cd47b7f4c6a..ea611a4d629 100644
--- a/lib/gitlab/chat_commands/presenters/help.rb
+++ b/lib/gitlab/slash_commands/presenters/help.rb
@@ -1,5 +1,5 @@
module Gitlab
- module ChatCommands
+ module SlashCommands
module Presenters
class Help < Presenters::Base
def present(trigger, text)
diff --git a/lib/gitlab/chat_commands/presenters/issue_base.rb b/lib/gitlab/slash_commands/presenters/issue_base.rb
index 25bc82994ba..341f2aabdd0 100644
--- a/lib/gitlab/chat_commands/presenters/issue_base.rb
+++ b/lib/gitlab/slash_commands/presenters/issue_base.rb
@@ -1,5 +1,5 @@
module Gitlab
- module ChatCommands
+ module SlashCommands
module Presenters
module IssueBase
def color(issuable)
diff --git a/lib/gitlab/chat_commands/presenters/issue_new.rb b/lib/gitlab/slash_commands/presenters/issue_new.rb
index 3674ba25641..86490a39cc1 100644
--- a/lib/gitlab/chat_commands/presenters/issue_new.rb
+++ b/lib/gitlab/slash_commands/presenters/issue_new.rb
@@ -1,5 +1,5 @@
module Gitlab
- module ChatCommands
+ module SlashCommands
module Presenters
class IssueNew < Presenters::Base
include Presenters::IssueBase
diff --git a/lib/gitlab/chat_commands/presenters/issue_search.rb b/lib/gitlab/slash_commands/presenters/issue_search.rb
index 73788cf9662..4e27d668685 100644
--- a/lib/gitlab/chat_commands/presenters/issue_search.rb
+++ b/lib/gitlab/slash_commands/presenters/issue_search.rb
@@ -1,5 +1,5 @@
module Gitlab
- module ChatCommands
+ module SlashCommands
module Presenters
class IssueSearch < Presenters::Base
include Presenters::IssueBase
diff --git a/lib/gitlab/chat_commands/presenters/issue_show.rb b/lib/gitlab/slash_commands/presenters/issue_show.rb
index bd784ad241e..c99316df667 100644
--- a/lib/gitlab/chat_commands/presenters/issue_show.rb
+++ b/lib/gitlab/slash_commands/presenters/issue_show.rb
@@ -1,5 +1,5 @@
module Gitlab
- module ChatCommands
+ module SlashCommands
module Presenters
class IssueShow < Presenters::Base
include Presenters::IssueBase
diff --git a/lib/gitlab/chat_commands/result.rb b/lib/gitlab/slash_commands/result.rb
index 324d7ef43a3..7021b4b01b2 100644
--- a/lib/gitlab/chat_commands/result.rb
+++ b/lib/gitlab/slash_commands/result.rb
@@ -1,5 +1,5 @@
module Gitlab
- module ChatCommands
+ module SlashCommands
Result = Struct.new(:type, :message)
end
end
diff --git a/lib/gitlab/sql/recursive_cte.rb b/lib/gitlab/sql/recursive_cte.rb
index 5b1b03820a3..16ec002f139 100644
--- a/lib/gitlab/sql/recursive_cte.rb
+++ b/lib/gitlab/sql/recursive_cte.rb
@@ -52,10 +52,10 @@ module Gitlab
# Applies the CTE to the given relation, returning a new one that will
# query from it.
def apply_to(relation)
- relation.except(:where).
- with.
- recursive(to_arel).
- from(alias_to(relation.model.arel_table))
+ relation.except(:where)
+ .with
+ .recursive(to_arel)
+ .from(alias_to(relation.model.arel_table))
end
end
end
diff --git a/lib/gitlab/visibility_level.rb b/lib/gitlab/visibility_level.rb
index 2b53798e70f..36e5b5041a6 100644
--- a/lib/gitlab/visibility_level.rb
+++ b/lib/gitlab/visibility_level.rb
@@ -13,18 +13,8 @@ module Gitlab
scope :public_and_internal_only, -> { where(visibility_level: [PUBLIC, INTERNAL] ) }
scope :non_public_only, -> { where.not(visibility_level: PUBLIC) }
- scope :public_to_user, -> (user) do
- if user
- if user.admin?
- all
- elsif !user.external?
- public_and_internal_only
- else
- public_only
- end
- else
- public_only
- end
+ scope :public_to_user, -> (user = nil) do
+ where(visibility_level: VisibilityLevel.levels_for_user(user))
end
end
@@ -35,6 +25,18 @@ module Gitlab
class << self
delegate :values, to: :options
+ def levels_for_user(user = nil)
+ return [PUBLIC] unless user
+
+ if user.admin?
+ [PRIVATE, INTERNAL, PUBLIC]
+ elsif user.external?
+ [PUBLIC]
+ else
+ [INTERNAL, PUBLIC]
+ end
+ end
+
def string_values
string_options.keys
end
diff --git a/lib/gitlab/workhorse.rb b/lib/gitlab/workhorse.rb
index 7f27317775c..f96ee69096d 100644
--- a/lib/gitlab/workhorse.rb
+++ b/lib/gitlab/workhorse.rb
@@ -26,7 +26,10 @@ module Gitlab
}
if Gitlab.config.gitaly.enabled
- address = Gitlab::GitalyClient.address(project.repository_storage)
+ server = {
+ address: Gitlab::GitalyClient.address(project.repository_storage),
+ token: Gitlab::GitalyClient.token(project.repository_storage)
+ }
params[:Repository] = repository.gitaly_repository.to_h
feature_enabled = case action.to_s
@@ -39,8 +42,10 @@ module Gitlab
else
raise "Unsupported action: #{action}"
end
-
- params[:GitalyAddress] = address if feature_enabled
+ if feature_enabled
+ params[:GitalyAddress] = server[:address] # This field will be deprecated
+ params[:GitalyServer] = server
+ end
end
params
diff --git a/lib/tasks/gitlab/gitaly.rake b/lib/tasks/gitlab/gitaly.rake
index e88111c3725..a8db5701d0b 100644
--- a/lib/tasks/gitlab/gitaly.rake
+++ b/lib/tasks/gitlab/gitaly.rake
@@ -58,8 +58,9 @@ namespace :gitlab do
storages << { name: key, path: val['path'] }
end
-
- TOML.dump(socket_path: address.sub(%r{\Aunix:}, ''), storage: storages)
+ config = { socket_path: address.sub(%r{\Aunix:}, ''), storage: storages }
+ config[:auth] = { token: 'secret' } if Rails.env.test?
+ TOML.dump(config)
end
def create_gitaly_configuration
diff --git a/lib/tasks/migrate/add_limits_mysql.rake b/lib/tasks/migrate/add_limits_mysql.rake
index 761f275d42a..151f42a2222 100644
--- a/lib/tasks/migrate/add_limits_mysql.rake
+++ b/lib/tasks/migrate/add_limits_mysql.rake
@@ -1,9 +1,11 @@
require Rails.root.join('db/migrate/limits_to_mysql')
require Rails.root.join('db/migrate/markdown_cache_limits_to_mysql')
+require Rails.root.join('db/migrate/merge_request_diff_file_limits_to_mysql')
desc "GitLab | Add limits to strings in mysql database"
task add_limits_mysql: :environment do
puts "Adding limits to schema.rb for mysql"
LimitsToMysql.new.up
MarkdownCacheLimitsToMysql.new.up
+ MergeRequestDiffFileLimitsToMysql.new.up
end
diff --git a/locale/bg/gitlab.po b/locale/bg/gitlab.po
index e6caf83252d..43a5de65c43 100644
--- a/locale/bg/gitlab.po
+++ b/locale/bg/gitlab.po
@@ -250,6 +250,9 @@ msgstr "ИÑкате ли да видите данните? Помолете аÐ
msgid "We don't have enough data to show this stage."
msgstr "ÐÑма доÑтатъчно данни за този етап."
+msgid "You have reached your project limit"
+msgstr ""
+
msgid "You need permission."
msgstr "Ðуждаете Ñе от разрешение."
diff --git a/locale/de/gitlab.po b/locale/de/gitlab.po
index 9a660571db9..ea864091b10 100644
--- a/locale/de/gitlab.po
+++ b/locale/de/gitlab.po
@@ -291,6 +291,9 @@ msgstr "Um diese Daten einsehen zu können, wenden Sie sich bitte an Ihren Admin
msgid "We don't have enough data to show this stage."
msgstr "Es liegen nicht genügend Daten vor, um diese Phase anzuzeigen."
+msgid "You have reached your project limit"
+msgstr ""
+
msgid "You need permission."
msgstr "Sie benötigen Zugriffsrechte."
diff --git a/locale/en/gitlab.po b/locale/en/gitlab.po
index 4e44731fc5a..afb8fb3176f 100644
--- a/locale/en/gitlab.po
+++ b/locale/en/gitlab.po
@@ -17,23 +17,217 @@ msgstr ""
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"\n"
+msgid "%{commit_author_link} committed %{commit_timeago}"
+msgstr ""
+
+msgid "About auto deploy"
+msgstr ""
+
+msgid "Active"
+msgstr ""
+
+msgid "Activity"
+msgstr ""
+
+msgid "Add Changelog"
+msgstr ""
+
+msgid "Add Contribution guide"
+msgstr ""
+
+msgid "Add License"
+msgstr ""
+
+msgid "Add an SSH key to your profile to pull or push via SSH."
+msgstr ""
+
+msgid "Add new directory"
+msgstr ""
+
+msgid "Archived project! Repository is read-only"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr ""
+msgid "Attach a file by drag &amp; drop or %{upload_link}"
+msgstr ""
+
+msgid "Branch"
+msgid_plural "Branches"
+msgstr[0] ""
+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 "Branches"
+msgstr ""
+
+msgid "Browse files"
+msgstr ""
+
msgid "ByAuthor|by"
msgstr ""
+msgid "CI configuration"
+msgstr ""
+
msgid "Cancel"
msgstr ""
+msgid "ChangeTypeActionLabel|Pick into branch"
+msgstr ""
+
+msgid "ChangeTypeActionLabel|Revert in branch"
+msgstr ""
+
+msgid "ChangeTypeAction|Cherry-pick"
+msgstr ""
+
+msgid "ChangeTypeAction|Revert"
+msgstr ""
+
+msgid "Changelog"
+msgstr ""
+
+msgid "Charts"
+msgstr ""
+
+msgid "Cherry-pick this commit"
+msgstr ""
+
+msgid "Cherry-pick this merge request"
+msgstr ""
+
+msgid "CiStatusLabel|canceled"
+msgstr ""
+
+msgid "CiStatusLabel|created"
+msgstr ""
+
+msgid "CiStatusLabel|failed"
+msgstr ""
+
+msgid "CiStatusLabel|manual action"
+msgstr ""
+
+msgid "CiStatusLabel|passed"
+msgstr ""
+
+msgid "CiStatusLabel|passed with warnings"
+msgstr ""
+
+msgid "CiStatusLabel|pending"
+msgstr ""
+
+msgid "CiStatusLabel|skipped"
+msgstr ""
+
+msgid "CiStatusLabel|waiting for manual action"
+msgstr ""
+
+msgid "CiStatusText|blocked"
+msgstr ""
+
+msgid "CiStatusText|canceled"
+msgstr ""
+
+msgid "CiStatusText|created"
+msgstr ""
+
+msgid "CiStatusText|failed"
+msgstr ""
+
+msgid "CiStatusText|manual"
+msgstr ""
+
+msgid "CiStatusText|passed"
+msgstr ""
+
+msgid "CiStatusText|pending"
+msgstr ""
+
+msgid "CiStatusText|skipped"
+msgstr ""
+
+msgid "CiStatus|running"
+msgstr ""
+
msgid "Commit"
msgid_plural "Commits"
msgstr[0] ""
msgstr[1] ""
+msgid "Commit message"
+msgstr ""
+
+msgid "CommitBoxTitle|Commit"
+msgstr ""
+
+msgid "CommitMessage|Add %{file_name}"
+msgstr ""
+
+msgid "Commits"
+msgstr ""
+
+msgid "Commits|History"
+msgstr ""
+
+msgid "Committed by"
+msgstr ""
+
+msgid "Compare"
+msgstr ""
+
+msgid "Contribution guide"
+msgstr ""
+
+msgid "Contributors"
+msgstr ""
+
+msgid "Copy URL to clipboard"
+msgstr ""
+
+msgid "Copy commit SHA to clipboard"
+msgstr ""
+
+msgid "Create New Directory"
+msgstr ""
+
+msgid "Create directory"
+msgstr ""
+
+msgid "Create empty bare repository"
+msgstr ""
+
+msgid "Create merge request"
+msgstr ""
+
+msgid "Create new..."
+msgstr ""
+
+msgid "CreateNewFork|Fork"
+msgstr ""
+
+msgid "CreateTag|Tag"
+msgstr ""
+
msgid "Cron Timezone"
msgstr ""
+msgid "Cron syntax"
+msgstr ""
+
+msgid "Custom notification events"
+msgstr ""
+
+msgid "Custom notification levels are the same as participating levels. With custom notification levels you will also receive notifications for select events. To find out more, check out %{notification_link}."
+msgstr ""
+
+msgid "Cycle Analytics"
+msgstr ""
+
msgid "Cycle Analytics gives an overview of how much time it takes to go from idea to production in your project."
msgstr ""
@@ -58,6 +252,9 @@ msgstr ""
msgid "CycleAnalyticsStage|Test"
msgstr ""
+msgid "Define a custom pattern with cron syntax"
+msgstr ""
+
msgid "Delete"
msgstr ""
@@ -69,19 +266,67 @@ msgstr[1] ""
msgid "Description"
msgstr ""
+msgid "Directory name"
+msgstr ""
+
+msgid "Don't show again"
+msgstr ""
+
+msgid "Download"
+msgstr ""
+
+msgid "Download tar"
+msgstr ""
+
+msgid "Download tar.bz2"
+msgstr ""
+
+msgid "Download tar.gz"
+msgstr ""
+
+msgid "Download zip"
+msgstr ""
+
+msgid "DownloadArtifacts|Download"
+msgstr ""
+
+msgid "DownloadCommit|Email Patches"
+msgstr ""
+
+msgid "DownloadCommit|Plain Diff"
+msgstr ""
+
+msgid "DownloadSource|Download"
+msgstr ""
+
msgid "Edit"
msgstr ""
msgid "Edit Pipeline Schedule %{id}"
msgstr ""
+msgid "Every day (at 4:00am)"
+msgstr ""
+
+msgid "Every month (on the 1st at 4:00am)"
+msgstr ""
+
+msgid "Every week (Sundays at 4:00am)"
+msgstr ""
+
msgid "Failed to change the owner"
msgstr ""
msgid "Failed to remove the pipeline schedule"
msgstr ""
-msgid "Filter"
+msgid "Files"
+msgstr ""
+
+msgid "Find by path"
+msgstr ""
+
+msgid "Find file"
msgstr ""
msgid "FirstPushedBy|First"
@@ -90,18 +335,47 @@ msgstr ""
msgid "FirstPushedBy|pushed by"
msgstr ""
+msgid "Fork"
+msgid_plural "Forks"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ForkedFromProjectPath|Forked from"
+msgstr ""
+
msgid "From issue creation until deploy to production"
msgstr ""
msgid "From merge request merge until deploy to production"
msgstr ""
+msgid "Go to your fork"
+msgstr ""
+
+msgid "GoToYourFork|Fork"
+msgstr ""
+
+msgid "Home"
+msgstr ""
+
+msgid "Housekeeping successfully started"
+msgstr ""
+
+msgid "Import repository"
+msgstr ""
+
msgid "Interval Pattern"
msgstr ""
msgid "Introducing Cycle Analytics"
msgstr ""
+msgid "LFSStatus|Disabled"
+msgstr ""
+
+msgid "LFSStatus|Enabled"
+msgstr ""
+
msgid "Last %d day"
msgid_plural "Last %d days"
msgstr[0] ""
@@ -110,6 +384,24 @@ msgstr[1] ""
msgid "Last Pipeline"
msgstr ""
+msgid "Last Update"
+msgstr ""
+
+msgid "Last commit"
+msgstr ""
+
+msgid "Learn more in the"
+msgstr ""
+
+msgid "Learn more in the|pipeline schedules documentation"
+msgstr ""
+
+msgid "Leave group"
+msgstr ""
+
+msgid "Leave project"
+msgstr ""
+
msgid "Limited to showing %d event at most"
msgid_plural "Limited to showing %d events at most"
msgstr[0] ""
@@ -118,6 +410,9 @@ msgstr[1] ""
msgid "Median"
msgstr ""
+msgid "MissingSSHKeyWarningLink|add an SSH key"
+msgstr ""
+
msgid "New Issue"
msgid_plural "New Issues"
msgstr[0] ""
@@ -126,6 +421,33 @@ msgstr[1] ""
msgid "New Pipeline Schedule"
msgstr ""
+msgid "New branch"
+msgstr ""
+
+msgid "New directory"
+msgstr ""
+
+msgid "New file"
+msgstr ""
+
+msgid "New issue"
+msgstr ""
+
+msgid "New merge request"
+msgstr ""
+
+msgid "New schedule"
+msgstr ""
+
+msgid "New snippet"
+msgstr ""
+
+msgid "New tag"
+msgstr ""
+
+msgid "No repository"
+msgstr ""
+
msgid "No schedules"
msgstr ""
@@ -135,12 +457,75 @@ msgstr ""
msgid "Not enough data"
msgstr ""
+msgid "Notification events"
+msgstr ""
+
+msgid "NotificationEvent|Close issue"
+msgstr ""
+
+msgid "NotificationEvent|Close merge request"
+msgstr ""
+
+msgid "NotificationEvent|Failed pipeline"
+msgstr ""
+
+msgid "NotificationEvent|Merge merge request"
+msgstr ""
+
+msgid "NotificationEvent|New issue"
+msgstr ""
+
+msgid "NotificationEvent|New merge request"
+msgstr ""
+
+msgid "NotificationEvent|New note"
+msgstr ""
+
+msgid "NotificationEvent|Reassign issue"
+msgstr ""
+
+msgid "NotificationEvent|Reassign merge request"
+msgstr ""
+
+msgid "NotificationEvent|Reopen issue"
+msgstr ""
+
+msgid "NotificationEvent|Successful pipeline"
+msgstr ""
+
+msgid "NotificationLevel|Custom"
+msgstr ""
+
+msgid "NotificationLevel|Disabled"
+msgstr ""
+
+msgid "NotificationLevel|Global"
+msgstr ""
+
+msgid "NotificationLevel|On mention"
+msgstr ""
+
+msgid "NotificationLevel|Participate"
+msgstr ""
+
+msgid "NotificationLevel|Watch"
+msgstr ""
+
+msgid "OfSearchInADropdown|Filter"
+msgstr ""
+
msgid "OpenedNDaysAgo|Opened"
msgstr ""
+msgid "Options"
+msgstr ""
+
msgid "Owner"
msgstr ""
+msgid "Pipeline"
+msgstr ""
+
msgid "Pipeline Health"
msgstr ""
@@ -177,12 +562,78 @@ msgstr ""
msgid "PipelineSchedules|Target"
msgstr ""
+msgid "PipelineSheduleIntervalPattern|Custom"
+msgstr ""
+
+msgid "Pipeline|with stage"
+msgstr ""
+
+msgid "Pipeline|with stages"
+msgstr ""
+
+msgid "Project '%{project_name}' queued for deletion."
+msgstr ""
+
+msgid "Project '%{project_name}' was successfully created."
+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 ""
+
+msgid "Project export could not be deleted."
+msgstr ""
+
+msgid "Project export has been deleted."
+msgstr ""
+
+msgid "Project export link has expired. Please generate a new export from your project settings."
+msgstr ""
+
+msgid "Project export started. A download link will be sent by email."
+msgstr ""
+
+msgid "Project home"
+msgstr ""
+
+msgid "ProjectFeature|Disabled"
+msgstr ""
+
+msgid "ProjectFeature|Everyone with access"
+msgstr ""
+
+msgid "ProjectFeature|Only team members"
+msgstr ""
+
+msgid "ProjectFileTree|Name"
+msgstr ""
+
+msgid "ProjectLastActivity|Never"
+msgstr ""
+
msgid "ProjectLifecycle|Stage"
msgstr ""
+msgid "ProjectNetworkGraph|Graph"
+msgstr ""
+
msgid "Read more"
msgstr ""
+msgid "Readme"
+msgstr ""
+
+msgid "RefSwitcher|Branches"
+msgstr ""
+
+msgid "RefSwitcher|Tags"
+msgstr ""
+
msgid "Related Commits"
msgstr ""
@@ -201,23 +652,85 @@ msgstr ""
msgid "Related Merged Requests"
msgstr ""
+msgid "Remind later"
+msgstr ""
+
+msgid "Remove project"
+msgstr ""
+
+msgid "Request Access"
+msgstr ""
+
+msgid "Revert this commit"
+msgstr ""
+
+msgid "Revert this merge request"
+msgstr ""
+
msgid "Save pipeline schedule"
msgstr ""
msgid "Schedule a new pipeline"
msgstr ""
+msgid "Scheduling Pipelines"
+msgstr ""
+
+msgid "Search branches and tags"
+msgstr ""
+
+msgid "Select Archive Format"
+msgstr ""
+
msgid "Select a timezone"
msgstr ""
msgid "Select target branch"
msgstr ""
+msgid "Set a password on your account to pull or push via %{protocol}"
+msgstr ""
+
+msgid "Set up CI"
+msgstr ""
+
+msgid "Set up Koding"
+msgstr ""
+
+msgid "Set up auto deploy"
+msgstr ""
+
+msgid "SetPasswordToCloneLink|set a password"
+msgstr ""
+
msgid "Showing %d event"
msgid_plural "Showing %d events"
msgstr[0] ""
msgstr[1] ""
+msgid "Source code"
+msgstr ""
+
+msgid "StarProject|Star"
+msgstr ""
+
+msgid "Start a %{new_merge_request} with these changes"
+msgstr ""
+
+msgid "Start a <strong>new merge request</strong> with these changes"
+msgstr ""
+
+msgid "Switch branch/tag"
+msgstr ""
+
+msgid "Tag"
+msgid_plural "Tags"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Tags"
+msgstr ""
+
msgid "Target Branch"
msgstr ""
@@ -227,18 +740,33 @@ msgstr ""
msgid "The collection of events added to the data gathered for that stage."
msgstr ""
+msgid "The fork relationship has been removed."
+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 phase of the development lifecycle."
msgstr ""
+msgid "The pipelines schedule runs pipelines in the future, repeatedly, for specific branches or tags. Those scheduled pipelines will inherit limited project access based on their associated user."
+msgstr ""
+
msgid "The planning stage shows the time from the previous step to pushing your first commit. This time will be added automatically once you push your first commit."
msgstr ""
msgid "The production stage shows the total time it takes between creating an issue and deploying the code to production. The data will be automatically added once you have completed the full idea to production cycle."
msgstr ""
+msgid "The project can be accessed by any logged in user."
+msgstr ""
+
+msgid "The project can be accessed without any authentication."
+msgstr ""
+
+msgid "The repository for this project does not exist."
+msgstr ""
+
msgid "The review stage shows the time from creating the merge request to merging it. The data will automatically be added after you merge your first merge request."
msgstr ""
@@ -254,6 +782,9 @@ msgstr ""
msgid "The value lying at the midpoint of a series of observed values. E.g., between 3, 5, 9, the median is 5. Between 3, 5, 7, 8, the median is (5+7)/2 = 6."
msgstr ""
+msgid "This means you can not push code until you create an empty repository or import existing one."
+msgstr ""
+
msgid "Time before an issue gets scheduled"
msgstr ""
@@ -266,6 +797,129 @@ msgstr ""
msgid "Time until first merge request"
msgstr ""
+msgid "Timeago|%s days ago"
+msgstr ""
+
+msgid "Timeago|%s days remaining"
+msgstr ""
+
+msgid "Timeago|%s hours remaining"
+msgstr ""
+
+msgid "Timeago|%s minutes ago"
+msgstr ""
+
+msgid "Timeago|%s minutes remaining"
+msgstr ""
+
+msgid "Timeago|%s months ago"
+msgstr ""
+
+msgid "Timeago|%s months remaining"
+msgstr ""
+
+msgid "Timeago|%s seconds remaining"
+msgstr ""
+
+msgid "Timeago|%s weeks ago"
+msgstr ""
+
+msgid "Timeago|%s weeks remaining"
+msgstr ""
+
+msgid "Timeago|%s years ago"
+msgstr ""
+
+msgid "Timeago|%s years remaining"
+msgstr ""
+
+msgid "Timeago|1 day remaining"
+msgstr ""
+
+msgid "Timeago|1 hour remaining"
+msgstr ""
+
+msgid "Timeago|1 minute remaining"
+msgstr ""
+
+msgid "Timeago|1 month remaining"
+msgstr ""
+
+msgid "Timeago|1 week remaining"
+msgstr ""
+
+msgid "Timeago|1 year remaining"
+msgstr ""
+
+msgid "Timeago|Past due"
+msgstr ""
+
+msgid "Timeago|a day ago"
+msgstr ""
+
+msgid "Timeago|a month ago"
+msgstr ""
+
+msgid "Timeago|a week ago"
+msgstr ""
+
+msgid "Timeago|a while"
+msgstr ""
+
+msgid "Timeago|a year ago"
+msgstr ""
+
+msgid "Timeago|about %s hours ago"
+msgstr ""
+
+msgid "Timeago|about a minute ago"
+msgstr ""
+
+msgid "Timeago|about an hour ago"
+msgstr ""
+
+msgid "Timeago|in %s days"
+msgstr ""
+
+msgid "Timeago|in %s hours"
+msgstr ""
+
+msgid "Timeago|in %s minutes"
+msgstr ""
+
+msgid "Timeago|in %s months"
+msgstr ""
+
+msgid "Timeago|in %s seconds"
+msgstr ""
+
+msgid "Timeago|in %s weeks"
+msgstr ""
+
+msgid "Timeago|in %s years"
+msgstr ""
+
+msgid "Timeago|in 1 day"
+msgstr ""
+
+msgid "Timeago|in 1 hour"
+msgstr ""
+
+msgid "Timeago|in 1 minute"
+msgstr ""
+
+msgid "Timeago|in 1 month"
+msgstr ""
+
+msgid "Timeago|in 1 week"
+msgstr ""
+
+msgid "Timeago|in 1 year"
+msgstr ""
+
+msgid "Timeago|less than a minute ago"
+msgstr ""
+
msgid "Time|hr"
msgid_plural "Time|hrs"
msgstr[0] ""
@@ -285,16 +939,96 @@ msgstr ""
msgid "Total test time for all commits/merges"
msgstr ""
+msgid "Unstar"
+msgstr ""
+
+msgid "Upload New File"
+msgstr ""
+
+msgid "Upload file"
+msgstr ""
+
+msgid "Use your global notification setting"
+msgstr ""
+
+msgid "VisibilityLevel|Internal"
+msgstr ""
+
+msgid "VisibilityLevel|Private"
+msgstr ""
+
+msgid "VisibilityLevel|Public"
+msgstr ""
+
msgid "Want to see the data? Please ask an administrator for access."
msgstr ""
msgid "We don't have enough data to show this stage."
msgstr ""
+msgid "Withdraw Access Request"
+msgstr ""
+
+msgid ""
+"You are going to remove %{project_name_with_namespace}.\n"
+"Removed project CANNOT be restored!\n"
+"Are you ABSOLUTELY sure?"
+msgstr ""
+
+msgid "You are going to remove the fork relationship to source project %{forked_from_project}. Are you ABSOLUTELY sure?"
+msgstr ""
+
+msgid "You are going to transfer %{project_name_with_namespace} to another owner. Are you ABSOLUTELY sure?"
+msgstr ""
+
+msgid "You can only add files when you are on a branch"
+msgstr ""
+
+msgid "You have reached your project limit"
+msgstr ""
+
+msgid "You must sign in to star a project"
+msgstr ""
+
msgid "You need permission."
msgstr ""
+msgid "You will not get any notifications via email"
+msgstr ""
+
+msgid "You will only receive notifications for the events you choose"
+msgstr ""
+
+msgid "You will only receive notifications for threads you have participated in"
+msgstr ""
+
+msgid "You will receive notifications for any activity"
+msgstr ""
+
+msgid "You will receive notifications only for comments in which you were @mentioned"
+msgstr ""
+
+msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
+msgstr ""
+
+msgid "You won't be able to pull or push project code via SSH until you %{add_ssh_key_link} to your profile"
+msgstr ""
+
+msgid "Your name"
+msgstr ""
+
msgid "day"
msgid_plural "days"
msgstr[0] ""
msgstr[1] ""
+
+msgid "new merge request"
+msgstr ""
+
+msgid "notification emails"
+msgstr ""
+
+msgid "parent"
+msgid_plural "parents"
+msgstr[0] ""
+msgstr[1] ""
diff --git a/locale/es/gitlab.po b/locale/es/gitlab.po
index 78d28d69885..f661cbddf5f 100644
--- a/locale/es/gitlab.po
+++ b/locale/es/gitlab.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: gitlab 1.0.0\n"
"Report-Msgid-Bugs-To: \n"
-"PO-Revision-Date: 2017-06-07 12:29-0500\n"
+"PO-Revision-Date: 2017-06-19 15:22-0500\n"
"Language-Team: Spanish\n"
"Language: es\n"
"MIME-Version: 1.0\n"
@@ -17,9 +17,15 @@ msgstr ""
"Last-Translator: Bob Van Landuyt <bob@gitlab.com>\n"
"X-Generator: Poedit 2.0.2\n"
+msgid "%{commit_author_link} committed %{commit_timeago}"
+msgstr "%{commit_author_link} cambió %{commit_timeago}"
+
msgid "About auto deploy"
msgstr "Acerca del auto despliegue"
+msgid "Active"
+msgstr "Activo"
+
msgid "Activity"
msgstr "Actividad"
@@ -39,7 +45,13 @@ msgid "Add new directory"
msgstr "Agregar nuevo directorio"
msgid "Archived project! Repository is read-only"
-msgstr "¡Proyecto archivado! El repositorio es de sólo lectura"
+msgstr "¡Proyecto archivado! El repositorio es de solo lectura"
+
+msgid "Are you sure you want to delete this pipeline schedule?"
+msgstr "¿Estás seguro que deseas eliminar esta programación del pipeline?"
+
+msgid "Attach a file by drag &amp; drop or %{upload_link}"
+msgstr "Adjunte un archivo arrastrando &amp; soltando o %{upload_link}"
msgid "Branch"
msgid_plural "Branches"
@@ -49,21 +61,51 @@ msgstr[1] "Ramas"
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 "La rama <strong>%{branch_name}</strong> fue creada. Para configurar el auto despliegue, escoge una plantilla Yaml para GitLab CI y envía tus cambios. %{link_to_autodeploy_doc}"
+msgid "BranchSwitcherPlaceholder|Search branches"
+msgstr "Buscar ramas"
+
+msgid "BranchSwitcherTitle|Switch branch"
+msgstr "Cambiar rama"
+
msgid "Branches"
msgstr "Ramas"
+msgid "Browse files"
+msgstr "Examinar los archivos"
+
msgid "ByAuthor|by"
msgstr "por"
msgid "CI configuration"
msgstr "Configuración de CI"
+msgid "Cancel"
+msgstr "Cancelar"
+
+msgid "ChangeTypeActionLabel|Pick into branch"
+msgstr "Escoger en la rama"
+
+msgid "ChangeTypeActionLabel|Revert in branch"
+msgstr "Revertir en la rama"
+
+msgid "ChangeTypeAction|Cherry-pick"
+msgstr "Cherry-pick"
+
+msgid "ChangeTypeAction|Revert"
+msgstr "Revertir"
+
msgid "Changelog"
msgstr "Changelog"
msgid "Charts"
msgstr "Gráficos"
+msgid "Cherry-pick this commit"
+msgstr "Escoger este cambio"
+
+msgid "Cherry-pick this merge request"
+msgstr "Escoger esta solicitud de fusión"
+
msgid "CiStatusLabel|canceled"
msgstr "cancelado"
@@ -71,7 +113,7 @@ msgid "CiStatusLabel|created"
msgstr "creado"
msgid "CiStatusLabel|failed"
-msgstr "fallado"
+msgstr "fallido"
msgid "CiStatusLabel|manual action"
msgstr "acción manual"
@@ -123,6 +165,12 @@ msgid_plural "Commits"
msgstr[0] "Cambio"
msgstr[1] "Cambios"
+msgid "Commit message"
+msgstr "Mensaje del cambio"
+
+msgid "CommitBoxTitle|Commit"
+msgstr "Cambio"
+
msgid "CommitMessage|Add %{file_name}"
msgstr "Agregar %{file_name}"
@@ -132,6 +180,9 @@ msgstr "Cambios"
msgid "Commits|History"
msgstr "Historial"
+msgid "Committed by"
+msgstr "Enviado por"
+
msgid "Compare"
msgstr "Comparar"
@@ -159,9 +210,21 @@ msgstr "Crear repositorio vacío"
msgid "Create merge request"
msgstr "Crear solicitud de fusión"
+msgid "Create new..."
+msgstr "Crear nuevo..."
+
msgid "CreateNewFork|Fork"
msgstr "Bifurcar"
+msgid "CreateTag|Tag"
+msgstr "Etiqueta"
+
+msgid "Cron Timezone"
+msgstr "Zona horaria del Cron"
+
+msgid "Cron syntax"
+msgstr "Sintaxis de Cron"
+
msgid "Custom notification events"
msgstr "Eventos de notificaciones personalizadas"
@@ -195,17 +258,29 @@ msgstr "Puesta en escena"
msgid "CycleAnalyticsStage|Test"
msgstr "Pruebas"
+msgid "Define a custom pattern with cron syntax"
+msgstr "Definir un patrón personalizado con la sintaxis de cron"
+
+msgid "Delete"
+msgstr "Eliminar"
+
msgid "Deploy"
msgid_plural "Deploys"
msgstr[0] "Despliegue"
msgstr[1] "Despliegues"
+msgid "Description"
+msgstr "Descripción"
+
msgid "Directory name"
msgstr "Nombre del directorio"
msgid "Don't show again"
msgstr "No mostrar de nuevo"
+msgid "Download"
+msgstr "Descargar"
+
msgid "Download tar"
msgstr "Descargar tar"
@@ -221,9 +296,36 @@ msgstr "Descargar zip"
msgid "DownloadArtifacts|Download"
msgstr "Descargar"
+msgid "DownloadCommit|Email Patches"
+msgstr "Parches por correo electrónico"
+
+msgid "DownloadCommit|Plain Diff"
+msgstr "Diferencias en texto plano"
+
msgid "DownloadSource|Download"
msgstr "Descargar"
+msgid "Edit"
+msgstr "Editar"
+
+msgid "Edit Pipeline Schedule %{id}"
+msgstr "Editar Programación del Pipeline %{id}"
+
+msgid "Every day (at 4:00am)"
+msgstr "Todos los días (a las 4:00 am)"
+
+msgid "Every month (on the 1st at 4:00am)"
+msgstr "Todos los meses (el día 1 a las 4:00 am)"
+
+msgid "Every week (Sundays at 4:00am)"
+msgstr "Todas las semanas (domingos a las 4:00 am)"
+
+msgid "Failed to change the owner"
+msgstr "Error al cambiar el propietario"
+
+msgid "Failed to remove the pipeline schedule"
+msgstr "Error al eliminar la programación del pipeline"
+
msgid "Files"
msgstr "Archivos"
@@ -239,12 +341,14 @@ msgstr "Primer"
msgid "FirstPushedBy|pushed by"
msgstr "enviado por"
+msgid "Fork"
+msgid_plural "Forks"
+msgstr[0] "Bifurcación"
+msgstr[1] "Bifurcaciones"
+
msgid "ForkedFromProjectPath|Forked from"
msgstr "Bifurcado de"
-msgid "Forks"
-msgstr "Bifurcaciones"
-
msgid "From issue creation until deploy to production"
msgstr "Desde la creación de la incidencia hasta el despliegue a producción"
@@ -266,6 +370,9 @@ msgstr "Servicio de limpieza iniciado con éxito"
msgid "Import repository"
msgstr "Importar repositorio"
+msgid "Interval Pattern"
+msgstr "Patrón de intervalo"
+
msgid "Introducing Cycle Analytics"
msgstr "Introducción a Cycle Analytics"
@@ -280,12 +387,21 @@ msgid_plural "Last %d days"
msgstr[0] "Último %d día"
msgstr[1] "Últimos %d días"
+msgid "Last Pipeline"
+msgstr "Último Pipeline"
+
msgid "Last Update"
msgstr "Última actualización"
msgid "Last commit"
msgstr "Último cambio"
+msgid "Learn more in the"
+msgstr "Más información en la"
+
+msgid "Learn more in the|pipeline schedules documentation"
+msgstr "documentación sobre la programación de pipelines"
+
msgid "Leave group"
msgstr "Abandonar grupo"
@@ -308,6 +424,9 @@ msgid_plural "New Issues"
msgstr[0] "Nueva incidencia"
msgstr[1] "Nuevas incidencias"
+msgid "New Pipeline Schedule"
+msgstr "Nueva Programación del Pipeline"
+
msgid "New branch"
msgstr "Nueva rama"
@@ -323,6 +442,9 @@ msgstr "Nueva incidencia"
msgid "New merge request"
msgstr "Nueva solicitud de fusión"
+msgid "New schedule"
+msgstr "Nueva programación"
+
msgid "New snippet"
msgstr "Nuevo fragmento de código"
@@ -332,6 +454,9 @@ msgstr "Nueva etiqueta"
msgid "No repository"
msgstr "No hay repositorio"
+msgid "No schedules"
+msgstr "No hay programaciones"
+
msgid "Not available"
msgstr "No disponible"
@@ -392,12 +517,66 @@ msgstr "Participación"
msgid "NotificationLevel|Watch"
msgstr "Vigilancia"
+msgid "OfSearchInADropdown|Filter"
+msgstr "Filtrar"
+
msgid "OpenedNDaysAgo|Opened"
msgstr "Abierto"
+msgid "Options"
+msgstr "Opciones"
+
+msgid "Owner"
+msgstr "Propietario"
+
+msgid "Pipeline"
+msgstr "Pipeline"
+
msgid "Pipeline Health"
msgstr "Estado del Pipeline"
+msgid "Pipeline Schedule"
+msgstr "Programación del Pipeline"
+
+msgid "Pipeline Schedules"
+msgstr "Programaciones de los Pipelines"
+
+msgid "PipelineSchedules|Activated"
+msgstr "Activado"
+
+msgid "PipelineSchedules|Active"
+msgstr "Activos"
+
+msgid "PipelineSchedules|All"
+msgstr "Todos"
+
+msgid "PipelineSchedules|Inactive"
+msgstr "Inactivos"
+
+msgid "PipelineSchedules|Next Run"
+msgstr "Próxima Ejecución"
+
+msgid "PipelineSchedules|None"
+msgstr "Ninguno"
+
+msgid "PipelineSchedules|Provide a short description for this pipeline"
+msgstr "Proporcione una breve descripción para este pipeline"
+
+msgid "PipelineSchedules|Take ownership"
+msgstr "Tomar posesión"
+
+msgid "PipelineSchedules|Target"
+msgstr "Destino"
+
+msgid "PipelineSheduleIntervalPattern|Custom"
+msgstr "Personalizado"
+
+msgid "Pipeline|with stage"
+msgstr "con etapa"
+
+msgid "Pipeline|with stages"
+msgstr "con etapas"
+
msgid "Project '%{project_name}' queued for deletion."
msgstr "Proyecto ‘%{project_name}’ en cola para eliminación."
@@ -453,7 +632,7 @@ msgid "Read more"
msgstr "Leer más"
msgid "Readme"
-msgstr "Readme"
+msgstr "Léeme"
msgid "RefSwitcher|Branches"
msgstr "Ramas"
@@ -488,14 +667,35 @@ msgstr "Eliminar proyecto"
msgid "Request Access"
msgstr "Solicitar acceso"
+msgid "Revert this commit"
+msgstr "Revertir este cambio"
+
+msgid "Revert this merge request"
+msgstr "Revertir esta solicitud de fusión"
+
+msgid "Save pipeline schedule"
+msgstr "Guardar programación del pipeline"
+
+msgid "Schedule a new pipeline"
+msgstr "Programar un nuevo pipeline"
+
+msgid "Scheduling Pipelines"
+msgstr "Programación de Pipelines"
+
msgid "Search branches and tags"
msgstr "Buscar ramas y etiquetas"
msgid "Select Archive Format"
msgstr "Seleccionar formato de archivo"
+msgid "Select a timezone"
+msgstr "Selecciona una zona horaria"
+
+msgid "Select target branch"
+msgstr "Selecciona una rama de destino"
+
msgid "Set a password on your account to pull or push via %{protocol}"
-msgstr "Establezca una contraseña en su cuenta para actualizar o enviar a través de% {protocol}"
+msgstr "Establezca una contraseña en su cuenta para actualizar o enviar a través de %{protocol}"
msgid "Set up CI"
msgstr "Configurar CI"
@@ -520,6 +720,9 @@ msgstr "Código fuente"
msgid "StarProject|Star"
msgstr "Destacar"
+msgid "Start a %{new_merge_request} with these changes"
+msgstr "Iniciar una %{new_merge_request} con estos cambios"
+
msgid "Switch branch/tag"
msgstr "Cambiar rama/etiqueta"
@@ -531,6 +734,9 @@ msgstr[1] "Etiquetas"
msgid "Tags"
msgstr "Etiquetas"
+msgid "Target Branch"
+msgstr "Rama de destino"
+
msgid "The coding stage shows the time from the first commit to creating the merge request. The data will automatically be added here once you create your first merge request."
msgstr "La etapa de desarrollo muestra el tiempo desde el primer cambio hasta la creación de la solicitud de fusión. Los datos serán automáticamente incorporados aquí una vez creada tu primera solicitud de fusión."
@@ -546,6 +752,9 @@ msgstr "La etapa de incidencia muestra el tiempo que toma desde la creación de
msgid "The phase of the development lifecycle."
msgstr "La etapa del ciclo de vida de desarrollo."
+msgid "The pipelines schedule runs pipelines in the future, repeatedly, for specific branches or tags. Those scheduled pipelines will inherit limited project access based on their associated user."
+msgstr "La programación de pipelines ejecuta pipelines en el futuro, repetidamente, para ramas o etiquetas específicas. Los pipelines programados heredarán acceso limitado al proyecto basado en su usuario asociado."
+
msgid "The planning stage shows the time from the previous step to pushing your first commit. This time will be added automatically once you push your first commit."
msgstr "La etapa de planificación muestra el tiempo desde el paso anterior hasta el envío de tu primera confirmación. Este tiempo se añadirá automáticamente una vez que usted envíe el primer cambio."
@@ -652,16 +861,16 @@ msgid "Timeago|a day ago"
msgstr "hace un día"
msgid "Timeago|a month ago"
-msgstr "hace 1 mes"
+msgstr "hace un mes"
msgid "Timeago|a week ago"
-msgstr "hace 1 semana"
+msgstr "hace una semana"
msgid "Timeago|a while"
msgstr "hace un momento"
msgid "Timeago|a year ago"
-msgstr "hace 1 año"
+msgstr "hace un año"
msgid "Timeago|about %s hours ago"
msgstr "hace alrededor de %s horas"
@@ -742,6 +951,9 @@ msgstr "Subir nuevo archivo"
msgid "Upload file"
msgstr "Subir archivo"
+msgid "UploadLink|click to upload"
+msgstr "Hacer clic para subir"
+
msgid "Use your global notification setting"
msgstr "Utiliza tu configuración de notificación global"
@@ -772,18 +984,21 @@ msgstr ""
"¡El proyecto eliminado NO puede ser restaurado!\n"
"¿Estás TOTALMENTE seguro?"
-msgid "You are going to remove the fork relationship to source project %{forked_from_project}. Are you ABSOLUTELY sure?"
+msgid "You are going to remove the fork relationship to source project %{forked_from_project}. Are you ABSOLUTELY sure?"
msgstr "Vas a eliminar el enlace de la bifurcación con el proyecto original %{forked_from_project}. ¿Estás TOTALMENTE seguro?"
msgid "You are going to transfer %{project_name_with_namespace} to another owner. Are you ABSOLUTELY sure?"
msgstr "Vas a transferir %{project_name_with_namespace} a otro propietario. ¿Estás TOTALMENTE seguro?"
msgid "You can only add files when you are on a branch"
-msgstr "Sólo puede agregar archivos cuando estas en una rama"
+msgstr "Solo puedes agregar archivos cuando estás en una rama"
msgid "You must sign in to star a project"
msgstr "Debes iniciar sesión para destacar un proyecto"
+msgid "You have reached your project limit"
+msgstr ""
+
msgid "You need permission."
msgstr "Necesitas permisos."
@@ -797,10 +1012,10 @@ msgid "You will only receive notifications for threads you have participated in"
msgstr "Solo recibirás notificaciones de los temas en los que has participado"
msgid "You will receive notifications for any activity"
-msgstr "Recibirás notificaciones para cualquier actividad"
+msgstr "Recibirás notificaciones por cualquier actividad"
msgid "You will receive notifications only for comments in which you were @mentioned"
-msgstr "Recibirás notificaciones sólo para los comentarios en los que se te mencionó"
+msgstr "Recibirás notificaciones solo para los comentarios en los que se te mencionó"
msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
msgstr "No podrás actualizar o enviar código al proyecto a través de %{protocol} hasta que %{set_password_link} en tu cuenta"
@@ -811,13 +1026,18 @@ msgstr "No podrás actualizar o enviar código al proyecto a través de SSH hast
msgid "Your name"
msgstr "Tu nombre"
-msgid "committed"
-msgstr "cambió"
-
msgid "day"
msgid_plural "days"
msgstr[0] "día"
msgstr[1] "días"
+msgid "new merge request"
+msgstr "nueva solicitud de fusión"
+
msgid "notification emails"
msgstr "correos electrónicos de notificación"
+
+msgid "parent"
+msgid_plural "parents"
+msgstr[0] "padre"
+msgstr[1] "padres"
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 050f6c446c1..a2e32b478d3 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-06-07 21:22+0200\n"
-"PO-Revision-Date: 2017-06-07 21:22+0200\n"
+"POT-Creation-Date: 2017-06-19 15:13-0500\n"
+"PO-Revision-Date: 2017-06-19 15:13-0500\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
@@ -18,23 +18,223 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
+msgid "%{commit_author_link} committed %{commit_timeago}"
+msgstr ""
+
+msgid "About auto deploy"
+msgstr ""
+
+msgid "Active"
+msgstr ""
+
+msgid "Activity"
+msgstr ""
+
+msgid "Add Changelog"
+msgstr ""
+
+msgid "Add Contribution guide"
+msgstr ""
+
+msgid "Add License"
+msgstr ""
+
+msgid "Add an SSH key to your profile to pull or push via SSH."
+msgstr ""
+
+msgid "Add new directory"
+msgstr ""
+
+msgid "Archived project! Repository is read-only"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr ""
+msgid "Attach a file by drag &amp; drop or %{upload_link}"
+msgstr ""
+
+msgid "Branch"
+msgid_plural "Branches"
+msgstr[0] ""
+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 "BranchSwitcherPlaceholder|Search branches"
+msgstr ""
+
+msgid "BranchSwitcherTitle|Switch branch"
+msgstr ""
+
+msgid "Branches"
+msgstr ""
+
+msgid "Browse files"
+msgstr ""
+
msgid "ByAuthor|by"
msgstr ""
+msgid "CI configuration"
+msgstr ""
+
msgid "Cancel"
msgstr ""
+msgid "ChangeTypeActionLabel|Pick into branch"
+msgstr ""
+
+msgid "ChangeTypeActionLabel|Revert in branch"
+msgstr ""
+
+msgid "ChangeTypeAction|Cherry-pick"
+msgstr ""
+
+msgid "ChangeTypeAction|Revert"
+msgstr ""
+
+msgid "Changelog"
+msgstr ""
+
+msgid "Charts"
+msgstr ""
+
+msgid "Cherry-pick this commit"
+msgstr ""
+
+msgid "Cherry-pick this merge request"
+msgstr ""
+
+msgid "CiStatusLabel|canceled"
+msgstr ""
+
+msgid "CiStatusLabel|created"
+msgstr ""
+
+msgid "CiStatusLabel|failed"
+msgstr ""
+
+msgid "CiStatusLabel|manual action"
+msgstr ""
+
+msgid "CiStatusLabel|passed"
+msgstr ""
+
+msgid "CiStatusLabel|passed with warnings"
+msgstr ""
+
+msgid "CiStatusLabel|pending"
+msgstr ""
+
+msgid "CiStatusLabel|skipped"
+msgstr ""
+
+msgid "CiStatusLabel|waiting for manual action"
+msgstr ""
+
+msgid "CiStatusText|blocked"
+msgstr ""
+
+msgid "CiStatusText|canceled"
+msgstr ""
+
+msgid "CiStatusText|created"
+msgstr ""
+
+msgid "CiStatusText|failed"
+msgstr ""
+
+msgid "CiStatusText|manual"
+msgstr ""
+
+msgid "CiStatusText|passed"
+msgstr ""
+
+msgid "CiStatusText|pending"
+msgstr ""
+
+msgid "CiStatusText|skipped"
+msgstr ""
+
+msgid "CiStatus|running"
+msgstr ""
+
msgid "Commit"
msgid_plural "Commits"
msgstr[0] ""
msgstr[1] ""
+msgid "Commit message"
+msgstr ""
+
+msgid "CommitBoxTitle|Commit"
+msgstr ""
+
+msgid "CommitMessage|Add %{file_name}"
+msgstr ""
+
+msgid "Commits"
+msgstr ""
+
+msgid "Commits|History"
+msgstr ""
+
+msgid "Committed by"
+msgstr ""
+
+msgid "Compare"
+msgstr ""
+
+msgid "Contribution guide"
+msgstr ""
+
+msgid "Contributors"
+msgstr ""
+
+msgid "Copy URL to clipboard"
+msgstr ""
+
+msgid "Copy commit SHA to clipboard"
+msgstr ""
+
+msgid "Create New Directory"
+msgstr ""
+
+msgid "Create directory"
+msgstr ""
+
+msgid "Create empty bare repository"
+msgstr ""
+
+msgid "Create merge request"
+msgstr ""
+
+msgid "Create new..."
+msgstr ""
+
+msgid "CreateNewFork|Fork"
+msgstr ""
+
+msgid "CreateTag|Tag"
+msgstr ""
+
msgid "Cron Timezone"
msgstr ""
+msgid "Cron syntax"
+msgstr ""
+
+msgid "Custom notification events"
+msgstr ""
+
+msgid "Custom notification levels are the same as participating levels. With custom notification levels you will also receive notifications for select events. To find out more, check out %{notification_link}."
+msgstr ""
+
+msgid "Cycle Analytics"
+msgstr ""
+
msgid "Cycle Analytics gives an overview of how much time it takes to go from idea to production in your project."
msgstr ""
@@ -59,6 +259,9 @@ msgstr ""
msgid "CycleAnalyticsStage|Test"
msgstr ""
+msgid "Define a custom pattern with cron syntax"
+msgstr ""
+
msgid "Delete"
msgstr ""
@@ -70,19 +273,67 @@ msgstr[1] ""
msgid "Description"
msgstr ""
+msgid "Directory name"
+msgstr ""
+
+msgid "Don't show again"
+msgstr ""
+
+msgid "Download"
+msgstr ""
+
+msgid "Download tar"
+msgstr ""
+
+msgid "Download tar.bz2"
+msgstr ""
+
+msgid "Download tar.gz"
+msgstr ""
+
+msgid "Download zip"
+msgstr ""
+
+msgid "DownloadArtifacts|Download"
+msgstr ""
+
+msgid "DownloadCommit|Email Patches"
+msgstr ""
+
+msgid "DownloadCommit|Plain Diff"
+msgstr ""
+
+msgid "DownloadSource|Download"
+msgstr ""
+
msgid "Edit"
msgstr ""
msgid "Edit Pipeline Schedule %{id}"
msgstr ""
+msgid "Every day (at 4:00am)"
+msgstr ""
+
+msgid "Every month (on the 1st at 4:00am)"
+msgstr ""
+
+msgid "Every week (Sundays at 4:00am)"
+msgstr ""
+
msgid "Failed to change the owner"
msgstr ""
msgid "Failed to remove the pipeline schedule"
msgstr ""
-msgid "Filter"
+msgid "Files"
+msgstr ""
+
+msgid "Find by path"
+msgstr ""
+
+msgid "Find file"
msgstr ""
msgid "FirstPushedBy|First"
@@ -91,18 +342,47 @@ msgstr ""
msgid "FirstPushedBy|pushed by"
msgstr ""
+msgid "Fork"
+msgid_plural "Forks"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ForkedFromProjectPath|Forked from"
+msgstr ""
+
msgid "From issue creation until deploy to production"
msgstr ""
msgid "From merge request merge until deploy to production"
msgstr ""
+msgid "Go to your fork"
+msgstr ""
+
+msgid "GoToYourFork|Fork"
+msgstr ""
+
+msgid "Home"
+msgstr ""
+
+msgid "Housekeeping successfully started"
+msgstr ""
+
+msgid "Import repository"
+msgstr ""
+
msgid "Interval Pattern"
msgstr ""
msgid "Introducing Cycle Analytics"
msgstr ""
+msgid "LFSStatus|Disabled"
+msgstr ""
+
+msgid "LFSStatus|Enabled"
+msgstr ""
+
msgid "Last %d day"
msgid_plural "Last %d days"
msgstr[0] ""
@@ -111,6 +391,24 @@ msgstr[1] ""
msgid "Last Pipeline"
msgstr ""
+msgid "Last Update"
+msgstr ""
+
+msgid "Last commit"
+msgstr ""
+
+msgid "Learn more in the"
+msgstr ""
+
+msgid "Learn more in the|pipeline schedules documentation"
+msgstr ""
+
+msgid "Leave group"
+msgstr ""
+
+msgid "Leave project"
+msgstr ""
+
msgid "Limited to showing %d event at most"
msgid_plural "Limited to showing %d events at most"
msgstr[0] ""
@@ -119,6 +417,9 @@ msgstr[1] ""
msgid "Median"
msgstr ""
+msgid "MissingSSHKeyWarningLink|add an SSH key"
+msgstr ""
+
msgid "New Issue"
msgid_plural "New Issues"
msgstr[0] ""
@@ -127,6 +428,33 @@ msgstr[1] ""
msgid "New Pipeline Schedule"
msgstr ""
+msgid "New branch"
+msgstr ""
+
+msgid "New directory"
+msgstr ""
+
+msgid "New file"
+msgstr ""
+
+msgid "New issue"
+msgstr ""
+
+msgid "New merge request"
+msgstr ""
+
+msgid "New schedule"
+msgstr ""
+
+msgid "New snippet"
+msgstr ""
+
+msgid "New tag"
+msgstr ""
+
+msgid "No repository"
+msgstr ""
+
msgid "No schedules"
msgstr ""
@@ -136,12 +464,75 @@ msgstr ""
msgid "Not enough data"
msgstr ""
+msgid "Notification events"
+msgstr ""
+
+msgid "NotificationEvent|Close issue"
+msgstr ""
+
+msgid "NotificationEvent|Close merge request"
+msgstr ""
+
+msgid "NotificationEvent|Failed pipeline"
+msgstr ""
+
+msgid "NotificationEvent|Merge merge request"
+msgstr ""
+
+msgid "NotificationEvent|New issue"
+msgstr ""
+
+msgid "NotificationEvent|New merge request"
+msgstr ""
+
+msgid "NotificationEvent|New note"
+msgstr ""
+
+msgid "NotificationEvent|Reassign issue"
+msgstr ""
+
+msgid "NotificationEvent|Reassign merge request"
+msgstr ""
+
+msgid "NotificationEvent|Reopen issue"
+msgstr ""
+
+msgid "NotificationEvent|Successful pipeline"
+msgstr ""
+
+msgid "NotificationLevel|Custom"
+msgstr ""
+
+msgid "NotificationLevel|Disabled"
+msgstr ""
+
+msgid "NotificationLevel|Global"
+msgstr ""
+
+msgid "NotificationLevel|On mention"
+msgstr ""
+
+msgid "NotificationLevel|Participate"
+msgstr ""
+
+msgid "NotificationLevel|Watch"
+msgstr ""
+
+msgid "OfSearchInADropdown|Filter"
+msgstr ""
+
msgid "OpenedNDaysAgo|Opened"
msgstr ""
+msgid "Options"
+msgstr ""
+
msgid "Owner"
msgstr ""
+msgid "Pipeline"
+msgstr ""
+
msgid "Pipeline Health"
msgstr ""
@@ -178,12 +569,78 @@ msgstr ""
msgid "PipelineSchedules|Target"
msgstr ""
+msgid "PipelineSheduleIntervalPattern|Custom"
+msgstr ""
+
+msgid "Pipeline|with stage"
+msgstr ""
+
+msgid "Pipeline|with stages"
+msgstr ""
+
+msgid "Project '%{project_name}' queued for deletion."
+msgstr ""
+
+msgid "Project '%{project_name}' was successfully created."
+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 ""
+
+msgid "Project export could not be deleted."
+msgstr ""
+
+msgid "Project export has been deleted."
+msgstr ""
+
+msgid "Project export link has expired. Please generate a new export from your project settings."
+msgstr ""
+
+msgid "Project export started. A download link will be sent by email."
+msgstr ""
+
+msgid "Project home"
+msgstr ""
+
+msgid "ProjectFeature|Disabled"
+msgstr ""
+
+msgid "ProjectFeature|Everyone with access"
+msgstr ""
+
+msgid "ProjectFeature|Only team members"
+msgstr ""
+
+msgid "ProjectFileTree|Name"
+msgstr ""
+
+msgid "ProjectLastActivity|Never"
+msgstr ""
+
msgid "ProjectLifecycle|Stage"
msgstr ""
+msgid "ProjectNetworkGraph|Graph"
+msgstr ""
+
msgid "Read more"
msgstr ""
+msgid "Readme"
+msgstr ""
+
+msgid "RefSwitcher|Branches"
+msgstr ""
+
+msgid "RefSwitcher|Tags"
+msgstr ""
+
msgid "Related Commits"
msgstr ""
@@ -202,23 +659,82 @@ msgstr ""
msgid "Related Merged Requests"
msgstr ""
+msgid "Remind later"
+msgstr ""
+
+msgid "Remove project"
+msgstr ""
+
+msgid "Request Access"
+msgstr ""
+
+msgid "Revert this commit"
+msgstr ""
+
+msgid "Revert this merge request"
+msgstr ""
+
msgid "Save pipeline schedule"
msgstr ""
msgid "Schedule a new pipeline"
msgstr ""
+msgid "Scheduling Pipelines"
+msgstr ""
+
+msgid "Search branches and tags"
+msgstr ""
+
+msgid "Select Archive Format"
+msgstr ""
+
msgid "Select a timezone"
msgstr ""
msgid "Select target branch"
msgstr ""
+msgid "Set a password on your account to pull or push via %{protocol}"
+msgstr ""
+
+msgid "Set up CI"
+msgstr ""
+
+msgid "Set up Koding"
+msgstr ""
+
+msgid "Set up auto deploy"
+msgstr ""
+
+msgid "SetPasswordToCloneLink|set a password"
+msgstr ""
+
msgid "Showing %d event"
msgid_plural "Showing %d events"
msgstr[0] ""
msgstr[1] ""
+msgid "Source code"
+msgstr ""
+
+msgid "StarProject|Star"
+msgstr ""
+
+msgid "Start a %{new_merge_request} with these changes"
+msgstr ""
+
+msgid "Switch branch/tag"
+msgstr ""
+
+msgid "Tag"
+msgid_plural "Tags"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "Tags"
+msgstr ""
+
msgid "Target Branch"
msgstr ""
@@ -228,18 +744,33 @@ msgstr ""
msgid "The collection of events added to the data gathered for that stage."
msgstr ""
+msgid "The fork relationship has been removed."
+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 phase of the development lifecycle."
msgstr ""
+msgid "The pipelines schedule runs pipelines in the future, repeatedly, for specific branches or tags. Those scheduled pipelines will inherit limited project access based on their associated user."
+msgstr ""
+
msgid "The planning stage shows the time from the previous step to pushing your first commit. This time will be added automatically once you push your first commit."
msgstr ""
msgid "The production stage shows the total time it takes between creating an issue and deploying the code to production. The data will be automatically added once you have completed the full idea to production cycle."
msgstr ""
+msgid "The project can be accessed by any logged in user."
+msgstr ""
+
+msgid "The project can be accessed without any authentication."
+msgstr ""
+
+msgid "The repository for this project does not exist."
+msgstr ""
+
msgid "The review stage shows the time from creating the merge request to merging it. The data will automatically be added after you merge your first merge request."
msgstr ""
@@ -255,6 +786,9 @@ msgstr ""
msgid "The value lying at the midpoint of a series of observed values. E.g., between 3, 5, 9, the median is 5. Between 3, 5, 7, 8, the median is (5+7)/2 = 6."
msgstr ""
+msgid "This means you can not push code until you create an empty repository or import existing one."
+msgstr ""
+
msgid "Time before an issue gets scheduled"
msgstr ""
@@ -267,6 +801,129 @@ msgstr ""
msgid "Time until first merge request"
msgstr ""
+msgid "Timeago|%s days ago"
+msgstr ""
+
+msgid "Timeago|%s days remaining"
+msgstr ""
+
+msgid "Timeago|%s hours remaining"
+msgstr ""
+
+msgid "Timeago|%s minutes ago"
+msgstr ""
+
+msgid "Timeago|%s minutes remaining"
+msgstr ""
+
+msgid "Timeago|%s months ago"
+msgstr ""
+
+msgid "Timeago|%s months remaining"
+msgstr ""
+
+msgid "Timeago|%s seconds remaining"
+msgstr ""
+
+msgid "Timeago|%s weeks ago"
+msgstr ""
+
+msgid "Timeago|%s weeks remaining"
+msgstr ""
+
+msgid "Timeago|%s years ago"
+msgstr ""
+
+msgid "Timeago|%s years remaining"
+msgstr ""
+
+msgid "Timeago|1 day remaining"
+msgstr ""
+
+msgid "Timeago|1 hour remaining"
+msgstr ""
+
+msgid "Timeago|1 minute remaining"
+msgstr ""
+
+msgid "Timeago|1 month remaining"
+msgstr ""
+
+msgid "Timeago|1 week remaining"
+msgstr ""
+
+msgid "Timeago|1 year remaining"
+msgstr ""
+
+msgid "Timeago|Past due"
+msgstr ""
+
+msgid "Timeago|a day ago"
+msgstr ""
+
+msgid "Timeago|a month ago"
+msgstr ""
+
+msgid "Timeago|a week ago"
+msgstr ""
+
+msgid "Timeago|a while"
+msgstr ""
+
+msgid "Timeago|a year ago"
+msgstr ""
+
+msgid "Timeago|about %s hours ago"
+msgstr ""
+
+msgid "Timeago|about a minute ago"
+msgstr ""
+
+msgid "Timeago|about an hour ago"
+msgstr ""
+
+msgid "Timeago|in %s days"
+msgstr ""
+
+msgid "Timeago|in %s hours"
+msgstr ""
+
+msgid "Timeago|in %s minutes"
+msgstr ""
+
+msgid "Timeago|in %s months"
+msgstr ""
+
+msgid "Timeago|in %s seconds"
+msgstr ""
+
+msgid "Timeago|in %s weeks"
+msgstr ""
+
+msgid "Timeago|in %s years"
+msgstr ""
+
+msgid "Timeago|in 1 day"
+msgstr ""
+
+msgid "Timeago|in 1 hour"
+msgstr ""
+
+msgid "Timeago|in 1 minute"
+msgstr ""
+
+msgid "Timeago|in 1 month"
+msgstr ""
+
+msgid "Timeago|in 1 week"
+msgstr ""
+
+msgid "Timeago|in 1 year"
+msgstr ""
+
+msgid "Timeago|less than a minute ago"
+msgstr ""
+
msgid "Time|hr"
msgid_plural "Time|hrs"
msgstr[0] ""
@@ -286,16 +943,99 @@ msgstr ""
msgid "Total test time for all commits/merges"
msgstr ""
+msgid "Unstar"
+msgstr ""
+
+msgid "Upload New File"
+msgstr ""
+
+msgid "Upload file"
+msgstr ""
+
+msgid "UploadLink|click to upload"
+msgstr ""
+
+msgid "Use your global notification setting"
+msgstr ""
+
+msgid "VisibilityLevel|Internal"
+msgstr ""
+
+msgid "VisibilityLevel|Private"
+msgstr ""
+
+msgid "VisibilityLevel|Public"
+msgstr ""
+
msgid "Want to see the data? Please ask an administrator for access."
msgstr ""
msgid "We don't have enough data to show this stage."
msgstr ""
+msgid "Withdraw Access Request"
+msgstr ""
+
+msgid ""
+"You are going to remove %{project_name_with_namespace}.\n"
+"Removed project CANNOT be restored!\n"
+"Are you ABSOLUTELY sure?"
+msgstr ""
+
+msgid "You are going to remove the fork relationship to source project %{forked_from_project}. Are you ABSOLUTELY sure?"
+msgstr ""
+
+msgid "You are going to transfer %{project_name_with_namespace} to another owner. Are you ABSOLUTELY sure?"
+msgstr ""
+
+msgid "You can only add files when you are on a branch"
+msgstr ""
+
+msgid "You have reached your project limit"
+msgstr ""
+
+msgid "You must sign in to star a project"
+msgstr ""
+
msgid "You need permission."
msgstr ""
+msgid "You will not get any notifications via email"
+msgstr ""
+
+msgid "You will only receive notifications for the events you choose"
+msgstr ""
+
+msgid "You will only receive notifications for threads you have participated in"
+msgstr ""
+
+msgid "You will receive notifications for any activity"
+msgstr ""
+
+msgid "You will receive notifications only for comments in which you were @mentioned"
+msgstr ""
+
+msgid "You won't be able to pull or push project code via %{protocol} until you %{set_password_link} on your account"
+msgstr ""
+
+msgid "You won't be able to pull or push project code via SSH until you %{add_ssh_key_link} to your profile"
+msgstr ""
+
+msgid "Your name"
+msgstr ""
+
msgid "day"
msgid_plural "days"
msgstr[0] ""
msgstr[1] ""
+
+msgid "new merge request"
+msgstr ""
+
+msgid "notification emails"
+msgstr ""
+
+msgid "parent"
+msgid_plural "parents"
+msgstr[0] ""
+msgstr[1] ""
diff --git a/locale/pt_BR/gitlab.po b/locale/pt_BR/gitlab.po
index 5ad41f92b64..fe6d51c36ac 100644
--- a/locale/pt_BR/gitlab.po
+++ b/locale/pt_BR/gitlab.po
@@ -250,6 +250,9 @@ msgstr "Precisa visualizar os dados? Solicite acesso ao administrador."
msgid "We don't have enough data to show this stage."
msgstr "Não temos dados suficientes para mostrar esta fase."
+msgid "You have reached your project limit"
+msgstr ""
+
msgid "You need permission."
msgstr "Você precisa de permissão."
diff --git a/locale/zh_CN/gitlab.po b/locale/zh_CN/gitlab.po
index 11434460207..8ba95093b82 100644
--- a/locale/zh_CN/gitlab.po
+++ b/locale/zh_CN/gitlab.po
@@ -1,39 +1,241 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the gitlab package.
-# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
-#
+# Huang Tao <htve@outlook.com>, 2017. #zanata
+# Xiaogang Wen <xiaogang@gitlab.com>, 2017.
msgid ""
msgstr ""
"Project-Id-Version: gitlab 1.0.0\n"
"Report-Msgid-Bugs-To: \n"
-"PO-Revision-Date: 2017-05-04 19:24-0500\n"
-"Last-Translator: HuangTao <htve@outlook.com>, 2017\n"
-"Language-Team: Chinese (China) (https://www.transifex.com/gitlab-zh/teams/7517"
-"7/zh_CN/)\n"
+"POT-Creation-Date: 2017-06-15 21:59-0500\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"Language: zh_CN\n"
-"Plural-Forms: nplurals=1; plural=0;\n"
+"PO-Revision-Date: 2017-06-19 09:57-0400\n"
+"Last-Translator: Huang Tao <htve@outlook.com>\n"
+"Language-Team: Chinese (China) (https://translate.zanata.org/project/view/GitLab)\n"
+"Language: zh-CN\n"
+"X-Generator: Zanata 3.9.6\n"
+"Plural-Forms: nplurals=1; plural=0\n"
+
+msgid "%{commit_author_link} committed %{commit_timeago}"
+msgstr "ç”± %{commit_author_link} æ交于 %{commit_timeago}"
+
+msgid "About auto deploy"
+msgstr "关于自动部署"
+
+msgid "Active"
+msgstr "å¯ç”¨"
+
+msgid "Activity"
+msgstr "活动"
+
+msgid "Add Changelog"
+msgstr "添加更新日志"
+
+msgid "Add Contribution guide"
+msgstr "添加贡献指å—"
+
+msgid "Add License"
+msgstr "添加许å¯è¯"
+
+msgid "Add an SSH key to your profile to pull or push via SSH."
+msgstr "新建一个用于推é€æˆ–拉å–çš„ SSH 秘钥到账å·ä¸­ã€‚"
+
+msgid "Add new directory"
+msgstr "添加目录"
+
+msgid "Archived project! Repository is read-only"
+msgstr "项目已归档ï¼å­˜å‚¨åº“为åªè¯»çŠ¶æ€"
msgid "Are you sure you want to delete this pipeline schedule?"
+msgstr "确定è¦åˆ é™¤æ­¤æµæ°´çº¿è®¡åˆ’å—?"
+
+msgid "Attach a file by drag &amp; drop or %{upload_link}"
+msgstr "拖放文件到此处或者 %{upload_link}"
+
+msgid "Branch"
+msgid_plural "Branches"
+msgstr[0] "分支"
+
+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 ""
+"已创建分支 <strong>%{branch_name}</strong> 。如需设置自动部署, 请选择åˆé€‚çš„ GitLab CI Yaml "
+"模æ¿å¹¶æ交更改。%{link_to_autodeploy_doc}"
+
+msgid "Branches"
+msgstr "分支"
+
+msgid "Browse files"
+msgstr "æµè§ˆæ–‡ä»¶"
msgid "ByAuthor|by"
msgstr "作者:"
+msgid "CI configuration"
+msgstr "CI é…ç½®"
+
msgid "Cancel"
-msgstr ""
+msgstr "å–消"
+
+msgid "ChangeTypeActionLabel|Pick into branch"
+msgstr "选择分支"
+
+msgid "ChangeTypeActionLabel|Revert in branch"
+msgstr "还原分支"
+
+msgid "ChangeTypeAction|Cherry-pick"
+msgstr "优选"
+
+msgid "ChangeTypeAction|Revert"
+msgstr "还原"
+
+msgid "Changelog"
+msgstr "更新日志"
+
+msgid "Charts"
+msgstr "统计图"
+
+msgid "Cherry-pick this commit"
+msgstr "优选此æ交"
+
+msgid "Cherry-pick this merge request"
+msgstr "优选此åˆå¹¶è¯·æ±‚"
+
+msgid "CiStatusLabel|canceled"
+msgstr "å·²å–消"
+
+msgid "CiStatusLabel|created"
+msgstr "已创建"
+
+msgid "CiStatusLabel|failed"
+msgstr "已失败"
+
+msgid "CiStatusLabel|manual action"
+msgstr "手动æ“作"
+
+msgid "CiStatusLabel|passed"
+msgstr "已通过"
+
+msgid "CiStatusLabel|passed with warnings"
+msgstr "已通过但有警告"
+
+msgid "CiStatusLabel|pending"
+msgstr "等待中"
+
+msgid "CiStatusLabel|skipped"
+msgstr "已跳过"
+
+msgid "CiStatusLabel|waiting for manual action"
+msgstr "等待手动æ“作"
+
+msgid "CiStatusText|blocked"
+msgstr "已阻塞"
+
+msgid "CiStatusText|canceled"
+msgstr "å·²å–消"
+
+msgid "CiStatusText|created"
+msgstr "已创建"
+
+msgid "CiStatusText|failed"
+msgstr "已失败"
+
+msgid "CiStatusText|manual"
+msgstr "手动æ“作"
+
+msgid "CiStatusText|passed"
+msgstr "已通过"
+
+msgid "CiStatusText|pending"
+msgstr "等待中"
+
+msgid "CiStatusText|skipped"
+msgstr "已跳过"
+
+msgid "CiStatus|running"
+msgstr "è¿è¡Œä¸­"
msgid "Commit"
msgid_plural "Commits"
msgstr[0] "æ交"
+msgid "Commit message"
+msgstr "æ交信æ¯"
+
+msgid "CommitBoxTitle|Commit"
+msgstr "æ交"
+
+msgid "CommitMessage|Add %{file_name}"
+msgstr "添加 %{file_name}"
+
+msgid "Commits"
+msgstr "æ交"
+
+msgid "Commits|History"
+msgstr "历å²"
+
+msgid "Committed by"
+msgstr "æ交者:"
+
+msgid "Compare"
+msgstr "比较"
+
+msgid "Contribution guide"
+msgstr "贡献指å—"
+
+msgid "Contributors"
+msgstr "贡献者"
+
+msgid "Copy URL to clipboard"
+msgstr "å¤åˆ¶ URL 到剪贴æ¿"
+
+msgid "Copy commit SHA to clipboard"
+msgstr "å¤åˆ¶æ交 SHA 的值到剪贴æ¿"
+
+msgid "Create New Directory"
+msgstr "创建新目录"
+
+msgid "Create directory"
+msgstr "创建目录"
+
+msgid "Create empty bare repository"
+msgstr "创建空的存储库"
+
+msgid "Create merge request"
+msgstr "创建åˆå¹¶è¯·æ±‚"
+
+msgid "Create new..."
+msgstr "创建..."
+
+msgid "CreateNewFork|Fork"
+msgstr "派生"
+
+msgid "CreateTag|Tag"
+msgstr "标签"
+
msgid "Cron Timezone"
+msgstr "Cron 时区"
+
+msgid "Cron syntax"
+msgstr "Cron 语法"
+
+msgid "Custom notification events"
+msgstr "自定义通知事件"
+
+msgid ""
+"Custom notification levels are the same as participating levels. With custom "
+"notification levels you will also receive notifications for select events. "
+"To find out more, check out %{notification_link}."
msgstr ""
+"自定义通知级别继承自å‚与级别。使用自定义通知级别,您会收到å‚与级别åŠé€‰å®šäº‹ä»¶çš„通知。想了解更多信æ¯ï¼Œè¯·æŸ¥çœ‹ %{notification_link}."
+
+msgid "Cycle Analytics"
+msgstr "周期分æž"
-msgid "Cycle Analytics gives an overview of how much time it takes to go from idea to production in your project."
+msgid ""
+"Cycle Analytics gives an overview of how much time it takes to go from idea "
+"to production in your project."
msgstr "周期分æžæ¦‚述了项目从想法到产å“实现的å„阶段所需的时间。"
msgid "CycleAnalyticsStage|Code"
@@ -57,30 +259,81 @@ msgstr "预å‘布"
msgid "CycleAnalyticsStage|Test"
msgstr "测试"
+msgid "Define a custom pattern with cron syntax"
+msgstr "使用 Cron 语法定义自定义模å¼"
+
msgid "Delete"
-msgstr ""
+msgstr "删除"
msgid "Deploy"
msgid_plural "Deploys"
msgstr[0] "部署"
msgid "Description"
-msgstr ""
+msgstr "æè¿°"
+
+msgid "Directory name"
+msgstr "目录å称"
+
+msgid "Don't show again"
+msgstr "ä¸å†æ˜¾ç¤º"
+
+msgid "Download"
+msgstr "下载"
+
+msgid "Download tar"
+msgstr "下载 tar"
+
+msgid "Download tar.bz2"
+msgstr "下载 tar.bz2"
+
+msgid "Download tar.gz"
+msgstr "下载 tar.gz"
+
+msgid "Download zip"
+msgstr "下载 zip"
+
+msgid "DownloadArtifacts|Download"
+msgstr "下载"
+
+msgid "DownloadCommit|Email Patches"
+msgstr "电å­é‚®ä»¶è¡¥ä¸"
+
+msgid "DownloadCommit|Plain Diff"
+msgstr "差异文件"
+
+msgid "DownloadSource|Download"
+msgstr "下载"
msgid "Edit"
-msgstr ""
+msgstr "编辑"
msgid "Edit Pipeline Schedule %{id}"
-msgstr ""
+msgstr "编辑 %{id} æµæ°´çº¿è®¡åˆ’"
+
+msgid "Every day (at 4:00am)"
+msgstr "æ¯æ—¥æ‰§è¡Œï¼ˆå‡Œæ™¨ 4 点)"
+
+msgid "Every month (on the 1st at 4:00am)"
+msgstr "æ¯æœˆæ‰§è¡Œï¼ˆæ¯æœˆ 1 日凌晨 4 点)"
+
+msgid "Every week (Sundays at 4:00am)"
+msgstr "æ¯å‘¨æ‰§è¡Œï¼ˆå‘¨æ—¥å‡Œæ™¨ 4 点)"
msgid "Failed to change the owner"
-msgstr ""
+msgstr "无法å˜æ›´æ‰€æœ‰è€…"
msgid "Failed to remove the pipeline schedule"
-msgstr ""
+msgstr "无法删除æµæ°´çº¿è®¡åˆ’"
-msgid "Filter"
-msgstr ""
+msgid "Files"
+msgstr "文件"
+
+msgid "Find by path"
+msgstr "按路径查找"
+
+msgid "Find file"
+msgstr "查找文件"
msgid "FirstPushedBy|First"
msgstr "首次推é€"
@@ -88,24 +341,70 @@ msgstr "首次推é€"
msgid "FirstPushedBy|pushed by"
msgstr "推é€è€…:"
+msgid "Fork"
+msgid_plural "Forks"
+msgstr[0] "派生"
+
+msgid "ForkedFromProjectPath|Forked from"
+msgstr "派生自"
+
msgid "From issue creation until deploy to production"
msgstr "从创建议题到部署至生产环境"
msgid "From merge request merge until deploy to production"
msgstr "从åˆå¹¶è¯·æ±‚被åˆå¹¶åŽåˆ°éƒ¨ç½²è‡³ç”Ÿäº§çŽ¯å¢ƒ"
+msgid "Go to your fork"
+msgstr "跳转到派生项目"
+
+msgid "GoToYourFork|Fork"
+msgstr "跳转到派生项目"
+
+msgid "Home"
+msgstr "首页"
+
+msgid "Housekeeping successfully started"
+msgstr "已开始维护"
+
+msgid "Import repository"
+msgstr "导入存储库"
+
msgid "Interval Pattern"
-msgstr ""
+msgstr "循环周期"
msgid "Introducing Cycle Analytics"
msgstr "周期分æžç®€ä»‹"
+msgid "LFSStatus|Disabled"
+msgstr "åœç”¨"
+
+msgid "LFSStatus|Enabled"
+msgstr "å¯ç”¨"
+
msgid "Last %d day"
msgid_plural "Last %d days"
-msgstr[0] "æœ€åŽ %d 天"
+msgstr[0] "最近 %d 天"
msgid "Last Pipeline"
-msgstr ""
+msgstr "最新æµæ°´çº¿"
+
+msgid "Last Update"
+msgstr "最åŽæ›´æ–°"
+
+msgid "Last commit"
+msgstr "最åŽæ交"
+
+msgid "Learn more in the"
+msgstr "了解更多"
+
+msgid "Learn more in the|pipeline schedules documentation"
+msgstr "æµæ°´çº¿è®¡åˆ’文档"
+
+msgid "Leave group"
+msgstr "退出群组"
+
+msgid "Leave project"
+msgstr "退出项目"
msgid "Limited to showing %d event at most"
msgid_plural "Limited to showing %d events at most"
@@ -114,15 +413,45 @@ msgstr[0] "最多显示 %d 个事件"
msgid "Median"
msgstr "中ä½æ•°"
+msgid "MissingSSHKeyWarningLink|add an SSH key"
+msgstr "新建 SSH 公钥"
+
msgid "New Issue"
msgid_plural "New Issues"
-msgstr[0] "新议题"
+msgstr[0] "新建议题"
msgid "New Pipeline Schedule"
-msgstr ""
+msgstr "创建æµæ°´çº¿è®¡åˆ’"
+
+msgid "New branch"
+msgstr "新建分支"
+
+msgid "New directory"
+msgstr "新建目录"
+
+msgid "New file"
+msgstr "新建文件"
+
+msgid "New issue"
+msgstr "新建议题"
+
+msgid "New merge request"
+msgstr "新建åˆå¹¶è¯·æ±‚"
+
+msgid "New schedule"
+msgstr "新建计划"
+
+msgid "New snippet"
+msgstr "新建代ç ç‰‡æ®µ"
+
+msgid "New tag"
+msgstr "新建标签"
+
+msgid "No repository"
+msgstr "没有存储库"
msgid "No schedules"
-msgstr ""
+msgstr "没有计划"
msgid "Not available"
msgstr "æ•°æ®ä¸è¶³"
@@ -130,54 +459,185 @@ msgstr "æ•°æ®ä¸è¶³"
msgid "Not enough data"
msgstr "æ•°æ®ä¸è¶³"
+msgid "Notification events"
+msgstr "通知事件"
+
+msgid "NotificationEvent|Close issue"
+msgstr "关闭议题"
+
+msgid "NotificationEvent|Close merge request"
+msgstr "关闭åˆå¹¶è¯·æ±‚"
+
+msgid "NotificationEvent|Failed pipeline"
+msgstr "æµæ°´çº¿å¤±è´¥"
+
+msgid "NotificationEvent|Merge merge request"
+msgstr "åˆå¹¶è¯·æ±‚被åˆå¹¶"
+
+msgid "NotificationEvent|New issue"
+msgstr "新建议题"
+
+msgid "NotificationEvent|New merge request"
+msgstr "新建åˆå¹¶è¯·æ±‚"
+
+msgid "NotificationEvent|New note"
+msgstr "新建评论"
+
+msgid "NotificationEvent|Reassign issue"
+msgstr "é‡æ–°æŒ‡æ´¾è®®é¢˜"
+
+msgid "NotificationEvent|Reassign merge request"
+msgstr "é‡æ–°æŒ‡æ´¾åˆå¹¶è¯·æ±‚"
+
+msgid "NotificationEvent|Reopen issue"
+msgstr "é‡å¯è®®é¢˜"
+
+msgid "NotificationEvent|Successful pipeline"
+msgstr "æµæ°´çº¿æˆåŠŸå®Œæˆ"
+
+msgid "NotificationLevel|Custom"
+msgstr "自定义"
+
+msgid "NotificationLevel|Disabled"
+msgstr "åœç”¨"
+
+msgid "NotificationLevel|Global"
+msgstr "全局"
+
+msgid "NotificationLevel|On mention"
+msgstr "æåŠ"
+
+msgid "NotificationLevel|Participate"
+msgstr "å‚与"
+
+msgid "NotificationLevel|Watch"
+msgstr "关注"
+
+msgid "OfSearchInADropdown|Filter"
+msgstr "筛选"
+
msgid "OpenedNDaysAgo|Opened"
msgstr "开始于"
+msgid "Options"
+msgstr "æ“作"
+
msgid "Owner"
-msgstr ""
+msgstr "所有者"
+
+msgid "Pipeline"
+msgstr "æµæ°´çº¿"
msgid "Pipeline Health"
msgstr "æµæ°´çº¿å¥åº·æŒ‡æ ‡"
msgid "Pipeline Schedule"
-msgstr ""
+msgstr "æµæ°´çº¿è®¡åˆ’"
msgid "Pipeline Schedules"
-msgstr ""
+msgstr "æµæ°´çº¿è®¡åˆ’"
msgid "PipelineSchedules|Activated"
-msgstr ""
+msgstr "是å¦å¯ç”¨"
msgid "PipelineSchedules|Active"
-msgstr ""
+msgstr "å·²å¯ç”¨"
msgid "PipelineSchedules|All"
-msgstr ""
+msgstr "所有"
msgid "PipelineSchedules|Inactive"
-msgstr ""
+msgstr "未å¯ç”¨"
msgid "PipelineSchedules|Next Run"
-msgstr ""
+msgstr "下次è¿è¡Œæ—¶é—´"
msgid "PipelineSchedules|None"
-msgstr ""
+msgstr "æ— "
msgid "PipelineSchedules|Provide a short description for this pipeline"
-msgstr ""
+msgstr "为此æµæ°´çº¿æ供简短æè¿°"
msgid "PipelineSchedules|Take ownership"
-msgstr ""
+msgstr "å–得所有者"
msgid "PipelineSchedules|Target"
-msgstr ""
+msgstr "目标"
+
+msgid "PipelineSheduleIntervalPattern|Custom"
+msgstr "自定义"
+
+msgid "Pipeline|with stage"
+msgstr "于阶段"
+
+msgid "Pipeline|with stages"
+msgstr "于阶段"
+
+msgid "Project '%{project_name}' queued for deletion."
+msgstr "项目 '%{project_name}' 已进入删除队列。"
+
+msgid "Project '%{project_name}' was successfully created."
+msgstr "项目 '%{project_name}' 已创建æˆåŠŸã€‚"
+
+msgid "Project '%{project_name}' was successfully updated."
+msgstr "项目 '%{project_name}' 已更新完æˆã€‚"
+
+msgid "Project '%{project_name}' will be deleted."
+msgstr "项目 '%{project_name}' 将被删除。"
+
+msgid "Project access must be granted explicitly to each user."
+msgstr "项目访问æƒé™å¿…须明确授æƒç»™æ¯ä¸ªç”¨æˆ·ã€‚"
+
+msgid "Project export could not be deleted."
+msgstr "无法删除项目导出。"
+
+msgid "Project export has been deleted."
+msgstr "项目导出已被删除。"
+
+msgid ""
+"Project export link has expired. Please generate a new export from your "
+"project settings."
+msgstr "项目导出链接已过期。请从项目设置中é‡æ–°ç”Ÿæˆé¡¹ç›®å¯¼å‡ºã€‚"
+
+msgid "Project export started. A download link will be sent by email."
+msgstr "项目导出已开始。下载链接将通过电å­é‚®ä»¶å‘é€ã€‚"
+
+msgid "Project home"
+msgstr "项目首页"
+
+msgid "ProjectFeature|Disabled"
+msgstr "åœç”¨"
+
+msgid "ProjectFeature|Everyone with access"
+msgstr "任何对项目有访问æƒçš„人"
+
+msgid "ProjectFeature|Only team members"
+msgstr "åªé™å›¢é˜Ÿæˆå‘˜"
+
+msgid "ProjectFileTree|Name"
+msgstr "å称"
+
+msgid "ProjectLastActivity|Never"
+msgstr "从未"
msgid "ProjectLifecycle|Stage"
-msgstr "项目生命周期"
+msgstr "阶段"
+
+msgid "ProjectNetworkGraph|Graph"
+msgstr "分支图"
msgid "Read more"
msgstr "了解更多"
+msgid "Readme"
+msgstr "自述文件"
+
+msgid "RefSwitcher|Branches"
+msgstr "分支"
+
+msgid "RefSwitcher|Tags"
+msgstr "标签"
+
msgid "Related Commits"
msgstr "相关的æ交"
@@ -196,58 +656,163 @@ msgstr "相关的åˆå¹¶è¯·æ±‚"
msgid "Related Merged Requests"
msgstr "相关已åˆå¹¶çš„åˆå¹¶è¯·æ±‚"
+msgid "Remind later"
+msgstr "ç¨åŽæ醒"
+
+msgid "Remove project"
+msgstr "删除项目"
+
+msgid "Request Access"
+msgstr "申请æƒé™"
+
+msgid "Revert this commit"
+msgstr "还原此æ交"
+
+msgid "Revert this merge request"
+msgstr "还原此åˆå¹¶è¯·æ±‚"
+
msgid "Save pipeline schedule"
-msgstr ""
+msgstr "ä¿å­˜æµæ°´çº¿è®¡åˆ’"
msgid "Schedule a new pipeline"
-msgstr ""
+msgstr "新建æµæ°´çº¿è®¡åˆ’"
+
+msgid "Scheduling Pipelines"
+msgstr "æµæ°´çº¿è®¡åˆ’"
+
+msgid "Search branches and tags"
+msgstr "æœç´¢åˆ†æ”¯å’Œæ ‡ç­¾"
+
+msgid "Select Archive Format"
+msgstr "选择下载格å¼"
msgid "Select a timezone"
-msgstr ""
+msgstr "选择时区"
msgid "Select target branch"
-msgstr ""
+msgstr "选择目标分支"
+
+msgid "Set a password on your account to pull or push via %{protocol}"
+msgstr "为账å·åˆ›å»ºä¸€ä¸ªç”¨äºŽæŽ¨é€æˆ–拉å–çš„ %{protocol} 密ç ã€‚"
+
+msgid "Set up CI"
+msgstr "设置 CI"
+
+msgid "Set up Koding"
+msgstr "设置 Koding"
+
+msgid "Set up auto deploy"
+msgstr "设置自动部署"
+
+msgid "SetPasswordToCloneLink|set a password"
+msgstr "设置密ç "
msgid "Showing %d event"
msgid_plural "Showing %d events"
msgstr[0] "显示 %d 个事件"
+msgid "Source code"
+msgstr "æºä»£ç "
+
+msgid "StarProject|Star"
+msgstr "星标"
+
+msgid "Start a %{new_merge_request} with these changes"
+msgstr "由此更改 %{new_merge_request}"
+
+msgid "Switch branch/tag"
+msgstr "切æ¢åˆ†æ”¯/标签"
+
+msgid "Tag"
+msgid_plural "Tags"
+msgstr[0] "标签"
+
+msgid "Tags"
+msgstr "标签"
+
msgid "Target Branch"
-msgstr ""
+msgstr "目标分支"
-msgid "The coding stage shows the time from the first commit to creating the merge request. The data will automatically be added here once you create your first merge request."
+msgid ""
+"The coding stage shows the time from the first commit to creating the merge "
+"request. The data will automatically be added here once you create your "
+"first merge request."
msgstr "ç¼–ç é˜¶æ®µæ¦‚述了从第一次æ交到创建åˆå¹¶è¯·æ±‚的时间。创建第一个åˆå¹¶è¯·æ±‚åŽï¼Œæ•°æ®å°†è‡ªåŠ¨æ·»åŠ åˆ°æ­¤å¤„。"
msgid "The collection of events added to the data gathered for that stage."
-msgstr "与该阶段相关的事件。"
+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 fork relationship has been removed."
+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 phase of the development lifecycle."
msgstr "项目生命周期中的å„个阶段。"
-msgid "The planning stage shows the time from the previous step to pushing your first commit. This time will be added automatically once you push your first commit."
-msgstr "计划阶段概述了从议题添加到日程åŽåˆ°æŽ¨é€é¦–次æ交的时间。当首次推é€æ交åŽï¼Œæ•°æ®å°†è‡ªåŠ¨æ·»åŠ åˆ°æ­¤å¤„。"
+msgid ""
+"The pipelines schedule runs pipelines in the future, repeatedly, for "
+"specific branches or tags. Those scheduled pipelines will inherit limited "
+"project access based on their associated user."
+msgstr "æµæ°´çº¿è®¡åˆ’会周期性é‡å¤è¿è¡ŒæŒ‡å®šåˆ†æ”¯æˆ–标签的æµæ°´çº¿ã€‚这些æµæ°´çº¿å°†æ ¹æ®å…¶å…³è”用户继承有é™çš„项目访问æƒé™ã€‚"
-msgid "The production stage shows the total time it takes between creating an issue and deploying the code to production. The data will be automatically added once you have completed the full idea to production cycle."
+msgid ""
+"The planning stage shows the time from the previous step to pushing your "
+"first commit. This time will be added automatically once you push your first "
+"commit."
+msgstr "计划阶段概述了从议题添加到日程到推é€é¦–次æ交的时间。当首次推é€æ交åŽï¼Œæ•°æ®å°†è‡ªåŠ¨æ·»åŠ åˆ°æ­¤å¤„。"
+
+msgid ""
+"The production stage shows the total time it takes between creating an issue "
+"and deploying the code to production. The data will be automatically added "
+"once you have completed the full idea to production cycle."
msgstr "生产阶段概述了从创建一个议题到将代ç éƒ¨ç½²åˆ°ç”Ÿäº§çŽ¯å¢ƒçš„总时间。当完æˆæƒ³æ³•åˆ°éƒ¨ç½²ç”Ÿäº§çš„循环,数æ®å°†è‡ªåŠ¨æ·»åŠ åˆ°æ­¤å¤„。"
-msgid "The review stage shows the time from creating the merge request to merging it. The data will automatically be added after you merge your first merge request."
+msgid "The project can be accessed by any logged in user."
+msgstr "该项目å…许已登录的用户访问。"
+
+msgid "The project can be accessed without any authentication."
+msgstr "该项目å…许任何人访问。"
+
+msgid "The repository for this project does not exist."
+msgstr "此项目的存储库ä¸å­˜åœ¨ã€‚"
+
+msgid ""
+"The review stage shows the time from creating the merge request to merging "
+"it. The data will automatically be added after you merge your first merge "
+"request."
msgstr "评审阶段概述了从创建åˆå¹¶è¯·æ±‚到被åˆå¹¶çš„时间。当创建第一个åˆå¹¶è¯·æ±‚åŽï¼Œæ•°æ®å°†è‡ªåŠ¨æ·»åŠ åˆ°æ­¤å¤„。"
-msgid "The staging stage shows the time between merging the MR and deploying code to the production environment. The data will be automatically added once you deploy to production for the first time."
+msgid ""
+"The staging stage shows the time between merging the MR and deploying code "
+"to the production environment. The data will be automatically added once you "
+"deploy to production for the first time."
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 "测试阶段概述了GitLab CI为相关åˆå¹¶è¯·æ±‚è¿è¡Œæ¯ä¸ªæµæ°´çº¿æ‰€éœ€çš„时间。当第一个æµæ°´çº¿è¿è¡Œå®ŒæˆåŽï¼Œæ•°æ®å°†è‡ªåŠ¨æ·»åŠ åˆ°æ­¤å¤„。"
+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 "测试阶段概述了 GitLab CI 为相关åˆå¹¶è¯·æ±‚è¿è¡Œæ¯ä¸ªæµæ°´çº¿æ‰€éœ€çš„时间。当第一个æµæ°´çº¿è¿è¡Œå®ŒæˆåŽï¼Œæ•°æ®å°†è‡ªåŠ¨æ·»åŠ åˆ°æ­¤å¤„。"
msgid "The time taken by each data entry gathered by that stage."
msgstr "该阶段æ¯æ¡æ•°æ®æ‰€èŠ±çš„时间"
-msgid "The value lying at the midpoint of a series of observed values. E.g., between 3, 5, 9, the median is 5. Between 3, 5, 7, 8, the median is (5+7)/2 = 6."
+msgid ""
+"The value lying at the midpoint of a series of observed values. E.g., "
+"between 3, 5, 9, the median is 5. Between 3, 5, 7, 8, the median is (5+7)/2 ="
+" 6."
msgstr "中ä½æ•°æ˜¯ä¸€ä¸ªæ•°åˆ—中最中间的值。例如在 3ã€5ã€9 之间,中ä½æ•°æ˜¯ 5。在 3ã€5ã€7ã€8 之间,中ä½æ•°æ˜¯ (5 + 7)/ 2 = 6。"
+msgid ""
+"This means you can not push code until you create an empty repository or "
+"import existing one."
+msgstr "在创建一个空的存储库或导入现有存储库之å‰ï¼Œå°†æ— æ³•æŽ¨é€ä»£ç ã€‚"
+
msgid "Time before an issue gets scheduled"
msgstr "议题被列入日程表的时间"
@@ -260,6 +825,129 @@ msgstr "从创建åˆå¹¶è¯·æ±‚到被åˆå¹¶æˆ–关闭的时间"
msgid "Time until first merge request"
msgstr "创建第一个åˆå¹¶è¯·æ±‚之å‰çš„时间"
+msgid "Timeago|%s days ago"
+msgstr " %s 天å‰"
+
+msgid "Timeago|%s days remaining"
+msgstr "剩余 %s 天"
+
+msgid "Timeago|%s hours remaining"
+msgstr "剩余 %s å°æ—¶"
+
+msgid "Timeago|%s minutes ago"
+msgstr " %s 分钟å‰"
+
+msgid "Timeago|%s minutes remaining"
+msgstr "剩余 %s 分钟"
+
+msgid "Timeago|%s months ago"
+msgstr " %s 个月å‰"
+
+msgid "Timeago|%s months remaining"
+msgstr "剩余 %s 月"
+
+msgid "Timeago|%s seconds remaining"
+msgstr "剩余 %s 秒"
+
+msgid "Timeago|%s weeks ago"
+msgstr " %s 星期å‰"
+
+msgid "Timeago|%s weeks remaining"
+msgstr "剩余 %s 星期"
+
+msgid "Timeago|%s years ago"
+msgstr " %s å¹´å‰"
+
+msgid "Timeago|%s years remaining"
+msgstr "剩余 %s 年"
+
+msgid "Timeago|1 day remaining"
+msgstr "剩余 1 天"
+
+msgid "Timeago|1 hour remaining"
+msgstr "剩余 1 å°æ—¶"
+
+msgid "Timeago|1 minute remaining"
+msgstr "剩余 1 分钟"
+
+msgid "Timeago|1 month remaining"
+msgstr "剩余 1 个月"
+
+msgid "Timeago|1 week remaining"
+msgstr "剩余 1 星期"
+
+msgid "Timeago|1 year remaining"
+msgstr "剩余 1 年"
+
+msgid "Timeago|Past due"
+msgstr "逾期"
+
+msgid "Timeago|a day ago"
+msgstr " 1 天å‰"
+
+msgid "Timeago|a month ago"
+msgstr " 1 个月å‰"
+
+msgid "Timeago|a week ago"
+msgstr " 1 星期å‰"
+
+msgid "Timeago|a while"
+msgstr "刚刚"
+
+msgid "Timeago|a year ago"
+msgstr " 1 å¹´å‰"
+
+msgid "Timeago|about %s hours ago"
+msgstr "约 %s å°æ—¶å‰"
+
+msgid "Timeago|about a minute ago"
+msgstr "约 1 分钟å‰"
+
+msgid "Timeago|about an hour ago"
+msgstr "约 1 å°æ—¶å‰"
+
+msgid "Timeago|in %s days"
+msgstr " %s 天åŽ"
+
+msgid "Timeago|in %s hours"
+msgstr " %s å°æ—¶åŽ"
+
+msgid "Timeago|in %s minutes"
+msgstr " %s 分钟åŽ"
+
+msgid "Timeago|in %s months"
+msgstr " %s 个月åŽ"
+
+msgid "Timeago|in %s seconds"
+msgstr " %s 秒åŽ"
+
+msgid "Timeago|in %s weeks"
+msgstr " %s 星期åŽ"
+
+msgid "Timeago|in %s years"
+msgstr " %s å¹´åŽ"
+
+msgid "Timeago|in 1 day"
+msgstr " 1 天åŽ"
+
+msgid "Timeago|in 1 hour"
+msgstr " 1 å°æ—¶åŽ"
+
+msgid "Timeago|in 1 minute"
+msgstr " 1 分钟åŽ"
+
+msgid "Timeago|in 1 month"
+msgstr " 1 月åŽ"
+
+msgid "Timeago|in 1 week"
+msgstr " 1 星期åŽ"
+
+msgid "Timeago|in 1 year"
+msgstr " 1 å¹´åŽ"
+
+msgid "Timeago|less than a minute ago"
+msgstr "ä¸åˆ° 1 分钟å‰"
+
msgid "Time|hr"
msgid_plural "Time|hrs"
msgstr[0] "å°æ—¶"
@@ -277,15 +965,108 @@ msgstr "总时间"
msgid "Total test time for all commits/merges"
msgstr "所有æ交和åˆå¹¶çš„总测试时间"
+msgid "Unstar"
+msgstr "å–消星标"
+
+msgid "Upload New File"
+msgstr "上传新文件"
+
+msgid "Upload file"
+msgstr "上传文件"
+
+msgid "Use your global notification setting"
+msgstr "使用全局通知设置"
+
+msgid "VisibilityLevel|Internal"
+msgstr "内部"
+
+msgid "VisibilityLevel|Private"
+msgstr "ç§æœ‰"
+
+msgid "VisibilityLevel|Public"
+msgstr "公开"
+
msgid "Want to see the data? Please ask an administrator for access."
msgstr "æƒé™ä¸è¶³ã€‚如需查看相关数æ®ï¼Œè¯·å‘管ç†å‘˜ç”³è¯·æƒé™ã€‚"
msgid "We don't have enough data to show this stage."
msgstr "该阶段的数æ®ä¸è¶³ï¼Œæ— æ³•æ˜¾ç¤ºã€‚"
+msgid "Withdraw Access Request"
+msgstr "å–消æƒé™ç”³è¯·"
+
+msgid ""
+"You are going to remove %{project_name_with_namespace}.\n"
+"Removed project CANNOT be restored!\n"
+"Are you ABSOLUTELY sure?"
+msgstr "å³å°†è¦åˆ é™¤ %{project_name_with_namespace}。\n"
+"已删除的项目无法æ¢å¤ï¼\n"
+"确定继续å—?"
+
+msgid ""
+"You are going to remove the fork relationship to source project "
+"%{forked_from_project}. Are you ABSOLUTELY sure?"
+msgstr "å³å°†åˆ é™¤ä¸Žæºé¡¹ç›® %{forked_from_project} 的派生关系。确定继续å—?"
+
+msgid ""
+"You are going to transfer %{project_name_with_namespace} to another owner. "
+"Are you ABSOLUTELY sure?"
+msgstr "å³å°† %{project_name_with_namespace} 转移给å¦ä¸€ä¸ªæ‰€æœ‰è€…。确定继续å—?"
+
+msgid "You can only add files when you are on a branch"
+msgstr "åªèƒ½åœ¨åˆ†æ”¯ä¸Šæ·»åŠ æ–‡ä»¶"
+
+msgid "You have reached your project limit"
+msgstr "您已达到项目数é‡é™åˆ¶"
+
+msgid "You must sign in to star a project"
+msgstr "必须登录æ‰èƒ½å¯¹é¡¹ç›®åŠ æ˜Ÿæ ‡"
+
msgid "You need permission."
-msgstr "您需è¦ç›¸å…³çš„æƒé™ã€‚"
+msgstr "需è¦ç›¸å…³çš„æƒé™ã€‚"
+
+msgid "You will not get any notifications via email"
+msgstr "ä¸ä¼šæ”¶åˆ°ä»»ä½•é€šçŸ¥é‚®ä»¶"
+
+msgid "You will only receive notifications for the events you choose"
+msgstr "åªæŽ¥æ”¶é€‰æ‹©çš„事件通知"
+
+msgid ""
+"You will only receive notifications for threads you have participated in"
+msgstr "åªæŽ¥æ”¶å‚与的主题的通知"
+
+msgid "You will receive notifications for any activity"
+msgstr "接收所有活动的通知"
+
+msgid ""
+"You will receive notifications only for comments in which you were "
+"@mentioned"
+msgstr "åªæŽ¥æ”¶è¯„论中æåŠ(@)您的通知"
+
+msgid ""
+"You won't be able to pull or push project code via %{protocol} until you "
+"%{set_password_link} on your account"
+msgstr "在账å·ä¸­ %{set_password_link} 之å‰å°†æ— æ³•é€šè¿‡ %{protocol} 拉å–或推é€ä»£ç ã€‚"
+
+msgid ""
+"You won't be able to pull or push project code via SSH until you "
+"%{add_ssh_key_link} to your profile"
+msgstr "在账å·ä¸­ %{add_ssh_key_link} 之å‰å°†æ— æ³•é€šè¿‡ SSH 拉å–或推é€ä»£ç ã€‚"
+
+msgid "Your name"
+msgstr "您的åå­—"
msgid "day"
msgid_plural "days"
msgstr[0] "天"
+
+msgid "new merge request"
+msgstr "新建åˆå¹¶è¯·æ±‚"
+
+msgid "notification emails"
+msgstr "通知邮件"
+
+msgid "parent"
+msgid_plural "parents"
+msgstr[0] "父级"
+
diff --git a/locale/zh_HK/gitlab.po b/locale/zh_HK/gitlab.po
index 81b2ff863ea..f0a9e44daf3 100644
--- a/locale/zh_HK/gitlab.po
+++ b/locale/zh_HK/gitlab.po
@@ -283,6 +283,9 @@ msgstr "權é™ä¸è¶³ã€‚如需查看相關數據,請å‘管ç†å“¡ç”³è«‹æ¬Šé™ã€‚
msgid "We don't have enough data to show this stage."
msgstr "該階段的數據ä¸è¶³ï¼Œç„¡æ³•é¡¯ç¤ºã€‚"
+msgid "You have reached your project limit"
+msgstr ""
+
msgid "You need permission."
msgstr "您需è¦ç›¸é—œçš„權é™ã€‚"
diff --git a/locale/zh_TW/gitlab.po b/locale/zh_TW/gitlab.po
index e40723a9d8d..5130572d7ed 100644
--- a/locale/zh_TW/gitlab.po
+++ b/locale/zh_TW/gitlab.po
@@ -283,6 +283,9 @@ msgstr "權é™ä¸è¶³ã€‚如需查看相關資料,請å‘管ç†å“¡ç”³è«‹æ¬Šé™ã€‚
msgid "We don't have enough data to show this stage."
msgstr "因該階段的資料ä¸è¶³è€Œç„¡æ³•é¡¯ç¤ºç›¸é—œè³‡è¨Š"
+msgid "You have reached your project limit"
+msgstr ""
+
msgid "You need permission."
msgstr "您需è¦ç›¸é—œçš„權é™ã€‚"
diff --git a/spec/controllers/admin/users_controller_spec.rb b/spec/controllers/admin/users_controller_spec.rb
index 7d6c317482f..69928a906c6 100644
--- a/spec/controllers/admin/users_controller_spec.rb
+++ b/spec/controllers/admin/users_controller_spec.rb
@@ -116,8 +116,8 @@ describe Admin::UsersController do
it 'displays an alert' do
go
- expect(flash[:notice]).
- to eq 'Two-factor Authentication has been disabled for this user'
+ expect(flash[:notice])
+ .to eq 'Two-factor Authentication has been disabled for this user'
end
def go
diff --git a/spec/controllers/groups_controller_spec.rb b/spec/controllers/groups_controller_spec.rb
index b0b24b1de1b..c4092303a67 100644
--- a/spec/controllers/groups_controller_spec.rb
+++ b/spec/controllers/groups_controller_spec.rb
@@ -2,7 +2,7 @@ require 'rails_helper'
describe GroupsController do
let(:user) { create(:user) }
- let(:group) { create(:group) }
+ let(:group) { create(:group, :public) }
let(:project) { create(:empty_project, namespace: group) }
let!(:group_member) { create(:group_member, group: group, user: user) }
@@ -35,14 +35,15 @@ describe GroupsController do
sign_in(user)
end
- it 'shows the public subgroups' do
+ it 'shows all subgroups' do
get :subgroups, id: group.to_param
- expect(assigns(:nested_groups)).to contain_exactly(public_subgroup)
+ expect(assigns(:nested_groups)).to contain_exactly(public_subgroup, private_subgroup)
end
- context 'being member' do
+ context 'being member of private subgroup' do
it 'shows public and private subgroups the user is member of' do
+ group_member.destroy!
private_subgroup.add_guest(user)
get :subgroups, id: group.to_param
diff --git a/spec/controllers/import/bitbucket_controller_spec.rb b/spec/controllers/import/bitbucket_controller_spec.rb
index 0be7bc6a045..8ef10dabd4c 100644
--- a/spec/controllers/import/bitbucket_controller_spec.rb
+++ b/spec/controllers/import/bitbucket_controller_spec.rb
@@ -31,8 +31,8 @@ describe Import::BitbucketController do
expires_at: expires_at,
expires_in: expires_in,
refresh_token: refresh_token)
- allow_any_instance_of(OAuth2::Client).
- to receive(:get_token).and_return(access_token)
+ allow_any_instance_of(OAuth2::Client)
+ .to receive(:get_token).and_return(access_token)
stub_omniauth_provider('bitbucket')
get :callback
@@ -93,9 +93,9 @@ describe Import::BitbucketController do
context "when the repository owner is the Bitbucket user" do
context "when the Bitbucket user and GitLab user's usernames match" do
it "takes the current user's namespace" do
- expect(Gitlab::BitbucketImport::ProjectCreator).
- to receive(:new).with(bitbucket_repo, bitbucket_repo.name, user.namespace, user, access_params).
- and_return(double(execute: true))
+ expect(Gitlab::BitbucketImport::ProjectCreator)
+ .to receive(:new).with(bitbucket_repo, bitbucket_repo.name, user.namespace, user, access_params)
+ .and_return(double(execute: true))
post :create, format: :js
end
@@ -105,9 +105,9 @@ describe Import::BitbucketController do
let(:bitbucket_username) { "someone_else" }
it "takes the current user's namespace" do
- expect(Gitlab::BitbucketImport::ProjectCreator).
- to receive(:new).with(bitbucket_repo, bitbucket_repo.name, user.namespace, user, access_params).
- and_return(double(execute: true))
+ expect(Gitlab::BitbucketImport::ProjectCreator)
+ .to receive(:new).with(bitbucket_repo, bitbucket_repo.name, user.namespace, user, access_params)
+ .and_return(double(execute: true))
post :create, format: :js
end
@@ -141,9 +141,9 @@ describe Import::BitbucketController do
end
it "takes the existing namespace" do
- expect(Gitlab::BitbucketImport::ProjectCreator).
- to receive(:new).with(bitbucket_repo, bitbucket_repo.name, existing_namespace, user, access_params).
- and_return(double(execute: true))
+ expect(Gitlab::BitbucketImport::ProjectCreator)
+ .to receive(:new).with(bitbucket_repo, bitbucket_repo.name, existing_namespace, user, access_params)
+ .and_return(double(execute: true))
post :create, format: :js
end
@@ -151,8 +151,8 @@ describe Import::BitbucketController do
context "when the namespace is not owned by the GitLab user" do
it "doesn't create a project" do
- expect(Gitlab::BitbucketImport::ProjectCreator).
- not_to receive(:new)
+ expect(Gitlab::BitbucketImport::ProjectCreator)
+ .not_to receive(:new)
post :create, format: :js
end
@@ -162,16 +162,16 @@ describe Import::BitbucketController do
context "when a namespace with the Bitbucket user's username doesn't exist" do
context "when current user can create namespaces" do
it "creates the namespace" do
- expect(Gitlab::BitbucketImport::ProjectCreator).
- to receive(:new).and_return(double(execute: true))
+ expect(Gitlab::BitbucketImport::ProjectCreator)
+ .to receive(:new).and_return(double(execute: true))
expect { post :create, format: :js }.to change(Namespace, :count).by(1)
end
it "takes the new namespace" do
- expect(Gitlab::BitbucketImport::ProjectCreator).
- to receive(:new).with(bitbucket_repo, bitbucket_repo.name, an_instance_of(Group), user, access_params).
- and_return(double(execute: true))
+ expect(Gitlab::BitbucketImport::ProjectCreator)
+ .to receive(:new).with(bitbucket_repo, bitbucket_repo.name, an_instance_of(Group), user, access_params)
+ .and_return(double(execute: true))
post :create, format: :js
end
@@ -183,16 +183,16 @@ describe Import::BitbucketController do
end
it "doesn't create the namespace" do
- expect(Gitlab::BitbucketImport::ProjectCreator).
- to receive(:new).and_return(double(execute: true))
+ expect(Gitlab::BitbucketImport::ProjectCreator)
+ .to receive(:new).and_return(double(execute: true))
expect { post :create, format: :js }.not_to change(Namespace, :count)
end
it "takes the current user's namespace" do
- expect(Gitlab::BitbucketImport::ProjectCreator).
- to receive(:new).with(bitbucket_repo, bitbucket_repo.name, user.namespace, user, access_params).
- and_return(double(execute: true))
+ expect(Gitlab::BitbucketImport::ProjectCreator)
+ .to receive(:new).with(bitbucket_repo, bitbucket_repo.name, user.namespace, user, access_params)
+ .and_return(double(execute: true))
post :create, format: :js
end
@@ -210,9 +210,9 @@ describe Import::BitbucketController do
end
it 'takes the selected namespace and name' do
- expect(Gitlab::BitbucketImport::ProjectCreator).
- to receive(:new).with(bitbucket_repo, test_name, nested_namespace, user, access_params).
- and_return(double(execute: true))
+ expect(Gitlab::BitbucketImport::ProjectCreator)
+ .to receive(:new).with(bitbucket_repo, test_name, nested_namespace, user, access_params)
+ .and_return(double(execute: true))
post :create, { target_namespace: nested_namespace.full_path, new_name: test_name, format: :js }
end
@@ -222,26 +222,26 @@ describe Import::BitbucketController do
let(:test_name) { 'test_name' }
it 'takes the selected namespace and name' do
- expect(Gitlab::BitbucketImport::ProjectCreator).
- to receive(:new).with(bitbucket_repo, test_name, kind_of(Namespace), user, access_params).
- and_return(double(execute: true))
+ expect(Gitlab::BitbucketImport::ProjectCreator)
+ .to receive(:new).with(bitbucket_repo, test_name, kind_of(Namespace), user, access_params)
+ .and_return(double(execute: true))
post :create, { target_namespace: 'foo/bar', new_name: test_name, format: :js }
end
it 'creates the namespaces' do
- allow(Gitlab::BitbucketImport::ProjectCreator).
- to receive(:new).with(bitbucket_repo, test_name, kind_of(Namespace), user, access_params).
- and_return(double(execute: true))
+ allow(Gitlab::BitbucketImport::ProjectCreator)
+ .to receive(:new).with(bitbucket_repo, test_name, kind_of(Namespace), user, access_params)
+ .and_return(double(execute: true))
expect { post :create, { target_namespace: 'foo/bar', new_name: test_name, format: :js } }
.to change { Namespace.count }.by(2)
end
it 'new namespace has the right parent' do
- allow(Gitlab::BitbucketImport::ProjectCreator).
- to receive(:new).with(bitbucket_repo, test_name, kind_of(Namespace), user, access_params).
- and_return(double(execute: true))
+ allow(Gitlab::BitbucketImport::ProjectCreator)
+ .to receive(:new).with(bitbucket_repo, test_name, kind_of(Namespace), user, access_params)
+ .and_return(double(execute: true))
post :create, { target_namespace: 'foo/bar', new_name: test_name, format: :js }
@@ -254,17 +254,17 @@ describe Import::BitbucketController do
let!(:parent_namespace) { create(:group, name: 'foo', owner: user) }
it 'takes the selected namespace and name' do
- expect(Gitlab::BitbucketImport::ProjectCreator).
- to receive(:new).with(bitbucket_repo, test_name, kind_of(Namespace), user, access_params).
- and_return(double(execute: true))
+ expect(Gitlab::BitbucketImport::ProjectCreator)
+ .to receive(:new).with(bitbucket_repo, test_name, kind_of(Namespace), user, access_params)
+ .and_return(double(execute: true))
post :create, { target_namespace: 'foo/foobar/bar', new_name: test_name, format: :js }
end
it 'creates the namespaces' do
- allow(Gitlab::BitbucketImport::ProjectCreator).
- to receive(:new).with(bitbucket_repo, test_name, kind_of(Namespace), user, access_params).
- and_return(double(execute: true))
+ allow(Gitlab::BitbucketImport::ProjectCreator)
+ .to receive(:new).with(bitbucket_repo, test_name, kind_of(Namespace), user, access_params)
+ .and_return(double(execute: true))
expect { post :create, { target_namespace: 'foo/foobar/bar', new_name: test_name, format: :js } }
.to change { Namespace.count }.by(2)
diff --git a/spec/controllers/import/github_controller_spec.rb b/spec/controllers/import/github_controller_spec.rb
index 95696e14b6c..45c3fa075ef 100644
--- a/spec/controllers/import/github_controller_spec.rb
+++ b/spec/controllers/import/github_controller_spec.rb
@@ -21,10 +21,10 @@ describe Import::GithubController do
describe "GET callback" do
it "updates access token" do
token = "asdasd12345"
- allow_any_instance_of(Gitlab::GithubImport::Client).
- to receive(:get_token).and_return(token)
- allow_any_instance_of(Gitlab::GithubImport::Client).
- to receive(:github_options).and_return({})
+ allow_any_instance_of(Gitlab::GithubImport::Client)
+ .to receive(:get_token).and_return(token)
+ allow_any_instance_of(Gitlab::GithubImport::Client)
+ .to receive(:github_options).and_return({})
stub_omniauth_provider('github')
get :callback
diff --git a/spec/controllers/import/gitlab_controller_spec.rb b/spec/controllers/import/gitlab_controller_spec.rb
index 3afd09063d7..997107dadea 100644
--- a/spec/controllers/import/gitlab_controller_spec.rb
+++ b/spec/controllers/import/gitlab_controller_spec.rb
@@ -18,8 +18,8 @@ describe Import::GitlabController do
describe "GET callback" do
it "updates access token" do
- allow_any_instance_of(Gitlab::GitlabImport::Client).
- to receive(:get_token).and_return(token)
+ allow_any_instance_of(Gitlab::GitlabImport::Client)
+ .to receive(:get_token).and_return(token)
stub_omniauth_provider('gitlab')
get :callback
@@ -78,9 +78,9 @@ describe Import::GitlabController do
context "when the repository owner is the GitLab.com user" do
context "when the GitLab.com user and GitLab server user's usernames match" do
it "takes the current user's namespace" do
- expect(Gitlab::GitlabImport::ProjectCreator).
- to receive(:new).with(gitlab_repo, user.namespace, user, access_params).
- and_return(double(execute: true))
+ expect(Gitlab::GitlabImport::ProjectCreator)
+ .to receive(:new).with(gitlab_repo, user.namespace, user, access_params)
+ .and_return(double(execute: true))
post :create, format: :js
end
@@ -90,9 +90,9 @@ describe Import::GitlabController do
let(:gitlab_username) { "someone_else" }
it "takes the current user's namespace" do
- expect(Gitlab::GitlabImport::ProjectCreator).
- to receive(:new).with(gitlab_repo, user.namespace, user, access_params).
- and_return(double(execute: true))
+ expect(Gitlab::GitlabImport::ProjectCreator)
+ .to receive(:new).with(gitlab_repo, user.namespace, user, access_params)
+ .and_return(double(execute: true))
post :create, format: :js
end
@@ -116,9 +116,9 @@ describe Import::GitlabController do
end
it "takes the existing namespace" do
- expect(Gitlab::GitlabImport::ProjectCreator).
- to receive(:new).with(gitlab_repo, existing_namespace, user, access_params).
- and_return(double(execute: true))
+ expect(Gitlab::GitlabImport::ProjectCreator)
+ .to receive(:new).with(gitlab_repo, existing_namespace, user, access_params)
+ .and_return(double(execute: true))
post :create, format: :js
end
@@ -126,8 +126,8 @@ describe Import::GitlabController do
context "when the namespace is not owned by the GitLab server user" do
it "doesn't create a project" do
- expect(Gitlab::GitlabImport::ProjectCreator).
- not_to receive(:new)
+ expect(Gitlab::GitlabImport::ProjectCreator)
+ .not_to receive(:new)
post :create, format: :js
end
@@ -137,16 +137,16 @@ describe Import::GitlabController do
context "when a namespace with the GitLab.com user's username doesn't exist" do
context "when current user can create namespaces" do
it "creates the namespace" do
- expect(Gitlab::GitlabImport::ProjectCreator).
- to receive(:new).and_return(double(execute: true))
+ expect(Gitlab::GitlabImport::ProjectCreator)
+ .to receive(:new).and_return(double(execute: true))
expect { post :create, format: :js }.to change(Namespace, :count).by(1)
end
it "takes the new namespace" do
- expect(Gitlab::GitlabImport::ProjectCreator).
- to receive(:new).with(gitlab_repo, an_instance_of(Group), user, access_params).
- and_return(double(execute: true))
+ expect(Gitlab::GitlabImport::ProjectCreator)
+ .to receive(:new).with(gitlab_repo, an_instance_of(Group), user, access_params)
+ .and_return(double(execute: true))
post :create, format: :js
end
@@ -158,16 +158,16 @@ describe Import::GitlabController do
end
it "doesn't create the namespace" do
- expect(Gitlab::GitlabImport::ProjectCreator).
- to receive(:new).and_return(double(execute: true))
+ expect(Gitlab::GitlabImport::ProjectCreator)
+ .to receive(:new).and_return(double(execute: true))
expect { post :create, format: :js }.not_to change(Namespace, :count)
end
it "takes the current user's namespace" do
- expect(Gitlab::GitlabImport::ProjectCreator).
- to receive(:new).with(gitlab_repo, user.namespace, user, access_params).
- and_return(double(execute: true))
+ expect(Gitlab::GitlabImport::ProjectCreator)
+ .to receive(:new).with(gitlab_repo, user.namespace, user, access_params)
+ .and_return(double(execute: true))
post :create, format: :js
end
@@ -183,9 +183,9 @@ describe Import::GitlabController do
end
it 'takes the selected namespace and name' do
- expect(Gitlab::GitlabImport::ProjectCreator).
- to receive(:new).with(gitlab_repo, nested_namespace, user, access_params).
- and_return(double(execute: true))
+ expect(Gitlab::GitlabImport::ProjectCreator)
+ .to receive(:new).with(gitlab_repo, nested_namespace, user, access_params)
+ .and_return(double(execute: true))
post :create, { target_namespace: nested_namespace.full_path, format: :js }
end
@@ -195,26 +195,26 @@ describe Import::GitlabController do
let(:test_name) { 'test_name' }
it 'takes the selected namespace and name' do
- expect(Gitlab::GitlabImport::ProjectCreator).
- to receive(:new).with(gitlab_repo, kind_of(Namespace), user, access_params).
- and_return(double(execute: true))
+ expect(Gitlab::GitlabImport::ProjectCreator)
+ .to receive(:new).with(gitlab_repo, kind_of(Namespace), user, access_params)
+ .and_return(double(execute: true))
post :create, { target_namespace: 'foo/bar', format: :js }
end
it 'creates the namespaces' do
- allow(Gitlab::GitlabImport::ProjectCreator).
- to receive(:new).with(gitlab_repo, kind_of(Namespace), user, access_params).
- and_return(double(execute: true))
+ allow(Gitlab::GitlabImport::ProjectCreator)
+ .to receive(:new).with(gitlab_repo, kind_of(Namespace), user, access_params)
+ .and_return(double(execute: true))
expect { post :create, { target_namespace: 'foo/bar', format: :js } }
.to change { Namespace.count }.by(2)
end
it 'new namespace has the right parent' do
- allow(Gitlab::GitlabImport::ProjectCreator).
- to receive(:new).with(gitlab_repo, kind_of(Namespace), user, access_params).
- and_return(double(execute: true))
+ allow(Gitlab::GitlabImport::ProjectCreator)
+ .to receive(:new).with(gitlab_repo, kind_of(Namespace), user, access_params)
+ .and_return(double(execute: true))
post :create, { target_namespace: 'foo/bar', format: :js }
@@ -227,17 +227,17 @@ describe Import::GitlabController do
let!(:parent_namespace) { create(:group, name: 'foo', owner: user) }
it 'takes the selected namespace and name' do
- expect(Gitlab::GitlabImport::ProjectCreator).
- to receive(:new).with(gitlab_repo, kind_of(Namespace), user, access_params).
- and_return(double(execute: true))
+ expect(Gitlab::GitlabImport::ProjectCreator)
+ .to receive(:new).with(gitlab_repo, kind_of(Namespace), user, access_params)
+ .and_return(double(execute: true))
post :create, { target_namespace: 'foo/foobar/bar', format: :js }
end
it 'creates the namespaces' do
- allow(Gitlab::GitlabImport::ProjectCreator).
- to receive(:new).with(gitlab_repo, kind_of(Namespace), user, access_params).
- and_return(double(execute: true))
+ allow(Gitlab::GitlabImport::ProjectCreator)
+ .to receive(:new).with(gitlab_repo, kind_of(Namespace), user, access_params)
+ .and_return(double(execute: true))
expect { post :create, { target_namespace: 'foo/foobar/bar', format: :js } }
.to change { Namespace.count }.by(2)
diff --git a/spec/controllers/projects/blob_controller_spec.rb b/spec/controllers/projects/blob_controller_spec.rb
index 3b3caa9d3e6..c20cf6a4291 100644
--- a/spec/controllers/projects/blob_controller_spec.rb
+++ b/spec/controllers/projects/blob_controller_spec.rb
@@ -47,8 +47,8 @@ describe Projects::BlobController do
context 'redirect to tree' do
let(:id) { 'markdown/doc' }
it 'redirects' do
- expect(subject).
- to redirect_to("/#{project.path_with_namespace}/tree/markdown/doc")
+ expect(subject)
+ .to redirect_to("/#{project.path_with_namespace}/tree/markdown/doc")
end
end
end
diff --git a/spec/controllers/projects/branches_controller_spec.rb b/spec/controllers/projects/branches_controller_spec.rb
index f9e21f9d8f6..14426b09c73 100644
--- a/spec/controllers/projects/branches_controller_spec.rb
+++ b/spec/controllers/projects/branches_controller_spec.rb
@@ -32,8 +32,8 @@ describe Projects::BranchesController do
let(:branch) { "merge_branch" }
let(:ref) { "master" }
it 'redirects' do
- expect(subject).
- to redirect_to("/#{project.path_with_namespace}/tree/merge_branch")
+ expect(subject)
+ .to redirect_to("/#{project.path_with_namespace}/tree/merge_branch")
end
end
@@ -41,8 +41,8 @@ describe Projects::BranchesController do
let(:branch) { "<script>alert('merge');</script>" }
let(:ref) { "master" }
it 'redirects' do
- expect(subject).
- to redirect_to("/#{project.path_with_namespace}/tree/alert('merge');")
+ expect(subject)
+ .to redirect_to("/#{project.path_with_namespace}/tree/alert('merge');")
end
end
@@ -81,8 +81,8 @@ describe Projects::BranchesController do
branch_name: branch,
issue_iid: issue.iid
- expect(subject).
- to redirect_to("/#{project.path_with_namespace}/tree/1-feature-branch")
+ expect(subject)
+ .to redirect_to("/#{project.path_with_namespace}/tree/1-feature-branch")
end
it 'posts a system note' do
diff --git a/spec/controllers/projects/commit_controller_spec.rb b/spec/controllers/projects/commit_controller_spec.rb
index 7fb08df1950..e10da40eaab 100644
--- a/spec/controllers/projects/commit_controller_spec.rb
+++ b/spec/controllers/projects/commit_controller_spec.rb
@@ -66,8 +66,8 @@ describe Projects::CommitController do
end
it "does not escape Html" do
- allow_any_instance_of(Commit).to receive(:"to_#{format}").
- and_return('HTML entities &<>" ')
+ allow_any_instance_of(Commit).to receive(:"to_#{format}")
+ .and_return('HTML entities &<>" ')
go(id: commit.id, format: format)
diff --git a/spec/controllers/projects/environments_controller_spec.rb b/spec/controllers/projects/environments_controller_spec.rb
index 749b090d6e0..ad0b046742d 100644
--- a/spec/controllers/projects/environments_controller_spec.rb
+++ b/spec/controllers/projects/environments_controller_spec.rb
@@ -58,9 +58,11 @@ describe Projects::EnvironmentsController do
expect(json_response['stopped_count']).to eq 1
end
- it 'sets the polling interval header' do
+ it 'does not set the polling interval header' do
+ # TODO, this is a temporary fix, see follow up issue:
+ # https://gitlab.com/gitlab-org/gitlab-ee/issues/2677
expect(response).to have_http_status(:ok)
- expect(response.headers['Poll-Interval']).to eq("3000")
+ expect(response.headers['Poll-Interval']).to be_nil
end
end
@@ -233,14 +235,14 @@ describe Projects::EnvironmentsController do
context 'and valid id' do
it 'returns the first terminal for the environment' do
- expect_any_instance_of(Environment).
- to receive(:terminals).
- and_return([:fake_terminal])
-
- expect(Gitlab::Workhorse).
- to receive(:terminal_websocket).
- with(:fake_terminal).
- and_return(workhorse: :response)
+ expect_any_instance_of(Environment)
+ .to receive(:terminals)
+ .and_return([:fake_terminal])
+
+ expect(Gitlab::Workhorse)
+ .to receive(:terminal_websocket)
+ .with(:fake_terminal)
+ .and_return(workhorse: :response)
get :terminal_websocket_authorize, environment_params
diff --git a/spec/controllers/projects/issues_controller_spec.rb b/spec/controllers/projects/issues_controller_spec.rb
index f853bfe370c..9f98427a86b 100644
--- a/spec/controllers/projects/issues_controller_spec.rb
+++ b/spec/controllers/projects/issues_controller_spec.rb
@@ -328,8 +328,8 @@ describe Projects::IssuesController do
it 'redirect to issue page' do
update_verified_issue
- expect(response).
- to redirect_to(namespace_project_issue_path(project.namespace, project, issue))
+ expect(response)
+ .to redirect_to(namespace_project_issue_path(project.namespace, project, issue))
end
it 'accepts an issue after recaptcha is verified' do
@@ -343,8 +343,8 @@ describe Projects::IssuesController do
it 'does not mark spam log as recaptcha_verified when it does not belong to current_user' do
spam_log = create(:spam_log)
- expect { update_issue(spam_log_id: spam_log.id, recaptcha_verification: true) }.
- not_to change { SpamLog.last.recaptcha_verified }
+ expect { update_issue(spam_log_id: spam_log.id, recaptcha_verification: true) }
+ .not_to change { SpamLog.last.recaptcha_verified }
end
end
end
@@ -685,8 +685,8 @@ describe Projects::IssuesController do
it 'does not mark spam log as recaptcha_verified when it does not belong to current_user' do
spam_log = create(:spam_log)
- expect { post_new_issue({}, { spam_log_id: spam_log.id, recaptcha_verification: true } ) }.
- not_to change { SpamLog.last.recaptcha_verified }
+ expect { post_new_issue({}, { spam_log_id: spam_log.id, recaptcha_verification: true } ) }
+ .not_to change { SpamLog.last.recaptcha_verified }
end
end
end
@@ -702,7 +702,7 @@ describe Projects::IssuesController do
end
end
- context 'when description has slash commands' do
+ context 'when description has quick actions' do
before do
sign_in(user)
end
diff --git a/spec/controllers/projects/mattermosts_controller_spec.rb b/spec/controllers/projects/mattermosts_controller_spec.rb
index c5abf11cfa5..422a8b6fac0 100644
--- a/spec/controllers/projects/mattermosts_controller_spec.rb
+++ b/spec/controllers/projects/mattermosts_controller_spec.rb
@@ -11,8 +11,8 @@ describe Projects::MattermostsController do
describe 'GET #new' do
before do
- allow_any_instance_of(MattermostSlashCommandsService).
- to receive(:list_teams).and_return([])
+ allow_any_instance_of(MattermostSlashCommandsService)
+ .to receive(:list_teams).and_return([])
end
it 'accepts the request' do
diff --git a/spec/controllers/projects/merge_requests_controller_spec.rb b/spec/controllers/projects/merge_requests_controller_spec.rb
index d8a3a510f97..6817c2652fd 100644
--- a/spec/controllers/projects/merge_requests_controller_spec.rb
+++ b/spec/controllers/projects/merge_requests_controller_spec.rb
@@ -783,8 +783,8 @@ describe Projects::MergeRequestsController do
describe 'GET conflicts' do
context 'when the conflicts cannot be resolved in the UI' do
before do
- allow_any_instance_of(Gitlab::Conflict::Parser).
- to receive(:parse).and_raise(Gitlab::Conflict::Parser::UnmergeableFile)
+ allow_any_instance_of(Gitlab::Conflict::Parser)
+ .to receive(:parse).and_raise(Gitlab::Conflict::Parser::UnmergeableFile)
get :conflicts,
namespace_id: merge_request_with_conflicts.project.namespace.to_param,
@@ -926,8 +926,8 @@ describe Projects::MergeRequestsController do
context 'when the conflicts cannot be resolved in the UI' do
before do
- allow_any_instance_of(Gitlab::Conflict::Parser).
- to receive(:parse).and_raise(Gitlab::Conflict::Parser::UnmergeableFile)
+ allow_any_instance_of(Gitlab::Conflict::Parser)
+ .to receive(:parse).and_raise(Gitlab::Conflict::Parser::UnmergeableFile)
conflict_for_path('files/ruby/regex.rb')
end
@@ -959,9 +959,9 @@ describe Projects::MergeRequestsController do
end
it 'returns the file in JSON format' do
- content = MergeRequests::Conflicts::ListService.new(merge_request_with_conflicts).
- file_for_path(path, path).
- content
+ content = MergeRequests::Conflicts::ListService.new(merge_request_with_conflicts)
+ .file_for_path(path, path)
+ .content
expect(json_response).to include('old_path' => path,
'new_path' => path,
@@ -1085,9 +1085,9 @@ describe Projects::MergeRequestsController do
context 'when a file has identical content to the conflict' do
before do
- content = MergeRequests::Conflicts::ListService.new(merge_request_with_conflicts).
- file_for_path('files/ruby/popen.rb', 'files/ruby/popen.rb').
- content
+ content = MergeRequests::Conflicts::ListService.new(merge_request_with_conflicts)
+ .file_for_path('files/ruby/popen.rb', 'files/ruby/popen.rb')
+ .content
resolved_files = [
{
@@ -1153,9 +1153,9 @@ describe Projects::MergeRequestsController do
end
it 'calls MergeRequests::AssignIssuesService' do
- expect(MergeRequests::AssignIssuesService).to receive(:new).
- with(project, user, merge_request: merge_request).
- and_return(double(execute: { count: 1 }))
+ expect(MergeRequests::AssignIssuesService).to receive(:new)
+ .with(project, user, merge_request: merge_request)
+ .and_return(double(execute: { count: 1 }))
post_assign_issues
end
diff --git a/spec/controllers/projects/raw_controller_spec.rb b/spec/controllers/projects/raw_controller_spec.rb
index 952071af57f..b4eaab29fed 100644
--- a/spec/controllers/projects/raw_controller_spec.rb
+++ b/spec/controllers/projects/raw_controller_spec.rb
@@ -15,8 +15,8 @@ describe Projects::RawController do
expect(response).to have_http_status(200)
expect(response.header['Content-Type']).to eq('text/plain; charset=utf-8')
- expect(response.header['Content-Disposition']).
- to eq('inline')
+ expect(response.header['Content-Disposition'])
+ .to eq('inline')
expect(response.header[Gitlab::Workhorse::SEND_DATA_HEADER]).to start_with('git-blob:')
end
end
@@ -88,8 +88,8 @@ describe Projects::RawController do
expect(response).to have_http_status(200)
expect(response.header['Content-Type']).to eq('text/plain; charset=utf-8')
- expect(response.header['Content-Disposition']).
- to eq('inline')
+ expect(response.header['Content-Disposition'])
+ .to eq('inline')
expect(response.header[Gitlab::Workhorse::SEND_DATA_HEADER]).to start_with('git-blob:')
end
end
diff --git a/spec/controllers/projects/services_controller_spec.rb b/spec/controllers/projects/services_controller_spec.rb
index 23b463c0082..4dc227a36d4 100644
--- a/spec/controllers/projects/services_controller_spec.rb
+++ b/spec/controllers/projects/services_controller_spec.rb
@@ -67,8 +67,8 @@ describe Projects::ServicesController do
put :test, namespace_id: project.namespace.id, project_id: project.id, id: service.id, service: service_params
expect(response.status).to eq(200)
- expect(JSON.parse(response.body)).
- to eq('error' => true, 'message' => 'Test failed.', 'service_response' => 'Bad test')
+ expect(JSON.parse(response.body))
+ .to eq('error' => true, 'message' => 'Test failed.', 'service_response' => 'Bad test')
end
end
end
diff --git a/spec/controllers/projects/snippets_controller_spec.rb b/spec/controllers/projects/snippets_controller_spec.rb
index 2434f822c6f..ec0b7f8c967 100644
--- a/spec/controllers/projects/snippets_controller_spec.rb
+++ b/spec/controllers/projects/snippets_controller_spec.rb
@@ -103,21 +103,21 @@ describe Projects::SnippetsController do
context 'when the snippet is private' do
it 'creates the snippet' do
- expect { create_snippet(project, visibility_level: Snippet::PRIVATE) }.
- to change { Snippet.count }.by(1)
+ expect { create_snippet(project, visibility_level: Snippet::PRIVATE) }
+ .to change { Snippet.count }.by(1)
end
end
context 'when the snippet is public' do
it 'rejects the shippet' do
- expect { create_snippet(project, visibility_level: Snippet::PUBLIC) }.
- not_to change { Snippet.count }
+ expect { create_snippet(project, visibility_level: Snippet::PUBLIC) }
+ .not_to change { Snippet.count }
expect(response).to render_template(:new)
end
it 'creates a spam log' do
- expect { create_snippet(project, visibility_level: Snippet::PUBLIC) }.
- to change { SpamLog.count }.by(1)
+ expect { create_snippet(project, visibility_level: Snippet::PUBLIC) }
+ .to change { SpamLog.count }.by(1)
end
it 'renders :new with recaptcha disabled' do
@@ -183,8 +183,8 @@ describe Projects::SnippetsController do
let(:visibility_level) { Snippet::PRIVATE }
it 'updates the snippet' do
- expect { update_snippet(title: 'Foo') }.
- to change { snippet.reload.title }.to('Foo')
+ expect { update_snippet(title: 'Foo') }
+ .to change { snippet.reload.title }.to('Foo')
end
end
@@ -192,13 +192,13 @@ describe Projects::SnippetsController do
let(:visibility_level) { Snippet::PUBLIC }
it 'rejects the shippet' do
- expect { update_snippet(title: 'Foo') }.
- not_to change { snippet.reload.title }
+ expect { update_snippet(title: 'Foo') }
+ .not_to change { snippet.reload.title }
end
it 'creates a spam log' do
- expect { update_snippet(title: 'Foo') }.
- to change { SpamLog.count }.by(1)
+ expect { update_snippet(title: 'Foo') }
+ .to change { SpamLog.count }.by(1)
end
it 'renders :edit with recaptcha disabled' do
@@ -237,13 +237,13 @@ describe Projects::SnippetsController do
let(:visibility_level) { Snippet::PRIVATE }
it 'rejects the shippet' do
- expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) }.
- not_to change { snippet.reload.title }
+ expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) }
+ .not_to change { snippet.reload.title }
end
it 'creates a spam log' do
- expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) }.
- to change { SpamLog.count }.by(1)
+ expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) }
+ .to change { SpamLog.count }.by(1)
end
it 'renders :edit with recaptcha disabled' do
diff --git a/spec/controllers/projects/tree_controller_spec.rb b/spec/controllers/projects/tree_controller_spec.rb
index a43dad5756d..16cd2e076e5 100644
--- a/spec/controllers/projects/tree_controller_spec.rb
+++ b/spec/controllers/projects/tree_controller_spec.rb
@@ -82,8 +82,8 @@ describe Projects::TreeController do
let(:id) { 'master/README.md' }
it 'redirects' do
redirect_url = "/#{project.path_with_namespace}/blob/master/README.md"
- expect(subject).
- to redirect_to(redirect_url)
+ expect(subject)
+ .to redirect_to(redirect_url)
end
end
end
@@ -106,8 +106,8 @@ describe Projects::TreeController do
let(:branch_name) { 'master-test'}
it 'redirects to the new directory' do
- expect(subject).
- to redirect_to("/#{project.path_with_namespace}/tree/#{branch_name}/#{path}")
+ expect(subject)
+ .to redirect_to("/#{project.path_with_namespace}/tree/#{branch_name}/#{path}")
expect(flash[:notice]).to eq('The directory has been successfully created.')
end
end
@@ -117,8 +117,8 @@ describe Projects::TreeController do
let(:branch_name) { 'master'}
it 'does not allow overwriting of existing files' do
- expect(subject).
- to redirect_to("/#{project.path_with_namespace}/tree/master")
+ expect(subject)
+ .to redirect_to("/#{project.path_with_namespace}/tree/master")
expect(flash[:alert]).to eq('A file with this name already exists')
end
end
diff --git a/spec/controllers/sent_notifications_controller_spec.rb b/spec/controllers/sent_notifications_controller_spec.rb
index 0cc8a3b68eb..917bd44c91b 100644
--- a/spec/controllers/sent_notifications_controller_spec.rb
+++ b/spec/controllers/sent_notifications_controller_spec.rb
@@ -87,8 +87,8 @@ describe SentNotificationsController, type: :controller do
end
it 'redirects to the issue page' do
- expect(response).
- to redirect_to(namespace_project_issue_path(project.namespace, project, issue))
+ expect(response)
+ .to redirect_to(namespace_project_issue_path(project.namespace, project, issue))
end
end
@@ -113,8 +113,8 @@ describe SentNotificationsController, type: :controller do
end
it 'redirects to the merge request page' do
- expect(response).
- to redirect_to(namespace_project_merge_request_path(project.namespace, project, merge_request))
+ expect(response)
+ .to redirect_to(namespace_project_merge_request_path(project.namespace, project, merge_request))
end
end
end
diff --git a/spec/controllers/sessions_controller_spec.rb b/spec/controllers/sessions_controller_spec.rb
index 03f4b0ba343..bf922260b2f 100644
--- a/spec/controllers/sessions_controller_spec.rb
+++ b/spec/controllers/sessions_controller_spec.rb
@@ -9,8 +9,8 @@ describe SessionsController do
context 'when auto sign-in is enabled' do
before do
stub_omniauth_setting(auto_sign_in_with_provider: :saml)
- allow(controller).to receive(:omniauth_authorize_path).with(:user, :saml).
- and_return('/saml')
+ allow(controller).to receive(:omniauth_authorize_path).with(:user, :saml)
+ .and_return('/saml')
end
context 'and no auto_sign_in param is passed' do
@@ -89,8 +89,8 @@ describe SessionsController do
context 'remember_me field' do
it 'sets a remember_user_token cookie when enabled' do
allow(controller).to receive(:find_user).and_return(user)
- expect(controller).
- to receive(:remember_me).with(user).and_call_original
+ expect(controller)
+ .to receive(:remember_me).with(user).and_call_original
authenticate_2fa(remember_me: '1', otp_attempt: user.current_otp)
@@ -228,8 +228,8 @@ describe SessionsController do
it 'sets a remember_user_token cookie when enabled' do
allow(U2fRegistration).to receive(:authenticate).and_return(true)
allow(controller).to receive(:find_user).and_return(user)
- expect(controller).
- to receive(:remember_me).with(user).and_call_original
+ expect(controller)
+ .to receive(:remember_me).with(user).and_call_original
authenticate_2fa_u2f(remember_me: '1', login: user.username, device_response: "{}")
@@ -262,8 +262,8 @@ describe SessionsController do
it 'redirects correctly for referer on same host with params' do
search_path = '/search?search=seed_project'
- allow(controller.request).to receive(:referer).
- and_return('http://%{host}%{path}' % { host: Gitlab.config.gitlab.host, path: search_path })
+ allow(controller.request).to receive(:referer)
+ .and_return('http://%{host}%{path}' % { host: Gitlab.config.gitlab.host, path: search_path })
get(:new, redirect_to_referer: :yes)
diff --git a/spec/controllers/snippets_controller_spec.rb b/spec/controllers/snippets_controller_spec.rb
index b1339b2a185..430d1208cd1 100644
--- a/spec/controllers/snippets_controller_spec.rb
+++ b/spec/controllers/snippets_controller_spec.rb
@@ -222,20 +222,20 @@ describe SnippetsController do
context 'when the snippet is private' do
it 'creates the snippet' do
- expect { create_snippet(visibility_level: Snippet::PRIVATE) }.
- to change { Snippet.count }.by(1)
+ expect { create_snippet(visibility_level: Snippet::PRIVATE) }
+ .to change { Snippet.count }.by(1)
end
end
context 'when the snippet is public' do
it 'rejects the shippet' do
- expect { create_snippet(visibility_level: Snippet::PUBLIC) }.
- not_to change { Snippet.count }
+ expect { create_snippet(visibility_level: Snippet::PUBLIC) }
+ .not_to change { Snippet.count }
end
it 'creates a spam log' do
- expect { create_snippet(visibility_level: Snippet::PUBLIC) }.
- to change { SpamLog.count }.by(1)
+ expect { create_snippet(visibility_level: Snippet::PUBLIC) }
+ .to change { SpamLog.count }.by(1)
end
it 'renders :new with recaptcha disabled' do
@@ -296,8 +296,8 @@ describe SnippetsController do
let(:visibility_level) { Snippet::PRIVATE }
it 'updates the snippet' do
- expect { update_snippet(title: 'Foo') }.
- to change { snippet.reload.title }.to('Foo')
+ expect { update_snippet(title: 'Foo') }
+ .to change { snippet.reload.title }.to('Foo')
end
end
@@ -305,13 +305,13 @@ describe SnippetsController do
let(:visibility_level) { Snippet::PRIVATE }
it 'rejects the snippet' do
- expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) }.
- not_to change { snippet.reload.title }
+ expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) }
+ .not_to change { snippet.reload.title }
end
it 'creates a spam log' do
- expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) }.
- to change { SpamLog.count }.by(1)
+ expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) }
+ .to change { SpamLog.count }.by(1)
end
it 'renders :edit with recaptcha disabled' do
@@ -350,13 +350,13 @@ describe SnippetsController do
let(:visibility_level) { Snippet::PUBLIC }
it 'rejects the shippet' do
- expect { update_snippet(title: 'Foo') }.
- not_to change { snippet.reload.title }
+ expect { update_snippet(title: 'Foo') }
+ .not_to change { snippet.reload.title }
end
it 'creates a spam log' do
- expect { update_snippet(title: 'Foo') }.
- to change { SpamLog.count }.by(1)
+ expect { update_snippet(title: 'Foo') }
+ .to change { SpamLog.count }.by(1)
end
it 'renders :edit with recaptcha disabled' do
diff --git a/spec/factories/application_settings.rb b/spec/factories/application_settings.rb
new file mode 100644
index 00000000000..aef65e724c2
--- /dev/null
+++ b/spec/factories/application_settings.rb
@@ -0,0 +1,4 @@
+FactoryGirl.define do
+ factory :application_setting do
+ end
+end
diff --git a/spec/factories/projects.rb b/spec/factories/projects.rb
index e17e50db143..aef1c17a239 100644
--- a/spec/factories/projects.rb
+++ b/spec/factories/projects.rb
@@ -118,8 +118,8 @@ FactoryGirl.define do
builds_access_level = [evaluator.builds_access_level, evaluator.repository_access_level].min
merge_requests_access_level = [evaluator.merge_requests_access_level, evaluator.repository_access_level].min
- project.project_feature.
- update_attributes!(
+ project.project_feature
+ .update_attributes!(
wiki_access_level: evaluator.wiki_access_level,
builds_access_level: builds_access_level,
snippets_access_level: evaluator.snippets_access_level,
diff --git a/spec/features/abuse_report_spec.rb b/spec/features/abuse_report_spec.rb
index 1e11fb756b2..5e6cd64c5c1 100644
--- a/spec/features/abuse_report_spec.rb
+++ b/spec/features/abuse_report_spec.rb
@@ -4,7 +4,7 @@ feature 'Abuse reports', feature: true do
let(:another_user) { create(:user) }
before do
- login_as :user
+ gitlab_sign_in :user
end
scenario 'Report abuse' do
diff --git a/spec/features/admin/admin_abuse_reports_spec.rb b/spec/features/admin/admin_abuse_reports_spec.rb
index 340884fc986..3a6e356b0b0 100644
--- a/spec/features/admin/admin_abuse_reports_spec.rb
+++ b/spec/features/admin/admin_abuse_reports_spec.rb
@@ -5,7 +5,7 @@ describe "Admin::AbuseReports", feature: true, js: true do
context 'as an admin' do
before do
- login_as :admin
+ gitlab_sign_in :admin
end
describe 'if a user has been reported for abuse' do
diff --git a/spec/features/admin/admin_active_tab_spec.rb b/spec/features/admin/admin_active_tab_spec.rb
index 16064d60ce2..c74336d8221 100644
--- a/spec/features/admin/admin_active_tab_spec.rb
+++ b/spec/features/admin/admin_active_tab_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
RSpec.describe 'admin active tab' do
before do
- login_as :admin
+ gitlab_sign_in :admin
end
shared_examples 'page has active tab' do |title|
diff --git a/spec/features/admin/admin_appearance_spec.rb b/spec/features/admin/admin_appearance_spec.rb
index 595366ce352..d8fd4319328 100644
--- a/spec/features/admin/admin_appearance_spec.rb
+++ b/spec/features/admin/admin_appearance_spec.rb
@@ -4,7 +4,7 @@ feature 'Admin Appearance', feature: true do
let!(:appearance) { create(:appearance) }
scenario 'Create new appearance' do
- login_as :admin
+ gitlab_sign_in :admin
visit admin_appearances_path
fill_in 'appearance_title', with: 'MyCompany'
@@ -20,7 +20,7 @@ feature 'Admin Appearance', feature: true do
end
scenario 'Preview appearance' do
- login_as :admin
+ gitlab_sign_in :admin
visit admin_appearances_path
click_link "Preview"
@@ -34,7 +34,7 @@ feature 'Admin Appearance', feature: true do
end
scenario 'Appearance logo' do
- login_as :admin
+ gitlab_sign_in :admin
visit admin_appearances_path
attach_file(:appearance_logo, logo_fixture)
@@ -46,7 +46,7 @@ feature 'Admin Appearance', feature: true do
end
scenario 'Header logos' do
- login_as :admin
+ gitlab_sign_in :admin
visit admin_appearances_path
attach_file(:appearance_header_logo, logo_fixture)
diff --git a/spec/features/admin/admin_broadcast_messages_spec.rb b/spec/features/admin/admin_broadcast_messages_spec.rb
index d6c63f66a9b..da063bf7b74 100644
--- a/spec/features/admin/admin_broadcast_messages_spec.rb
+++ b/spec/features/admin/admin_broadcast_messages_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
feature 'Admin Broadcast Messages', feature: true do
before do
- login_as :admin
+ gitlab_sign_in :admin
create(:broadcast_message, :expired, message: 'Migration to new server')
visit admin_broadcast_messages_path
end
diff --git a/spec/features/admin/admin_browse_spam_logs_spec.rb b/spec/features/admin/admin_browse_spam_logs_spec.rb
index bee57472270..d9c4fc686b1 100644
--- a/spec/features/admin/admin_browse_spam_logs_spec.rb
+++ b/spec/features/admin/admin_browse_spam_logs_spec.rb
@@ -4,7 +4,7 @@ describe 'Admin browse spam logs' do
let!(:spam_log) { create(:spam_log, description: 'abcde ' * 20) }
before do
- login_as :admin
+ gitlab_sign_in :admin
end
scenario 'Browse spam logs' do
diff --git a/spec/features/admin/admin_browses_logs_spec.rb b/spec/features/admin/admin_browses_logs_spec.rb
index d880f3f07db..c734a2ef16d 100644
--- a/spec/features/admin/admin_browses_logs_spec.rb
+++ b/spec/features/admin/admin_browses_logs_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe 'Admin browses logs' do
before do
- login_as :admin
+ gitlab_sign_in :admin
end
it 'shows available log files' do
diff --git a/spec/features/admin/admin_builds_spec.rb b/spec/features/admin/admin_builds_spec.rb
index 999ce3611b5..e767081f3e5 100644
--- a/spec/features/admin/admin_builds_spec.rb
+++ b/spec/features/admin/admin_builds_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe 'Admin Builds' do
before do
- login_as :admin
+ gitlab_sign_in :admin
end
describe 'GET /admin/builds' do
diff --git a/spec/features/admin/admin_cohorts_spec.rb b/spec/features/admin/admin_cohorts_spec.rb
index dd14ffdb2ce..952e5475213 100644
--- a/spec/features/admin/admin_cohorts_spec.rb
+++ b/spec/features/admin/admin_cohorts_spec.rb
@@ -2,7 +2,7 @@ require 'rails_helper'
feature 'Admin cohorts page', feature: true do
before do
- login_as :admin
+ gitlab_sign_in :admin
end
scenario 'See users count per month' do
diff --git a/spec/features/admin/admin_conversational_development_index_spec.rb b/spec/features/admin/admin_conversational_development_index_spec.rb
index 739ab907a29..b484677a6df 100644
--- a/spec/features/admin/admin_conversational_development_index_spec.rb
+++ b/spec/features/admin/admin_conversational_development_index_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe 'Admin Conversational Development Index' do
before do
- login_as :admin
+ gitlab_sign_in :admin
end
context 'when usage ping is disabled' do
diff --git a/spec/features/admin/admin_deploy_keys_spec.rb b/spec/features/admin/admin_deploy_keys_spec.rb
index 5f5fa4e932a..81cddd03f80 100644
--- a/spec/features/admin/admin_deploy_keys_spec.rb
+++ b/spec/features/admin/admin_deploy_keys_spec.rb
@@ -5,7 +5,7 @@ RSpec.describe 'admin deploy keys', type: :feature do
let!(:another_deploy_key) { create(:another_deploy_key, public: true) }
before do
- login_as(:admin)
+ gitlab_sign_in(:admin)
end
it 'show all public deploy keys' do
diff --git a/spec/features/admin/admin_disables_git_access_protocol_spec.rb b/spec/features/admin/admin_disables_git_access_protocol_spec.rb
index e8e080ce3e2..679bf63e0fd 100644
--- a/spec/features/admin/admin_disables_git_access_protocol_spec.rb
+++ b/spec/features/admin/admin_disables_git_access_protocol_spec.rb
@@ -8,7 +8,7 @@ feature 'Admin disables Git access protocol', feature: true do
background do
stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false')
- login_as(admin)
+ gitlab_sign_in(admin)
end
context 'with HTTP disabled' do
diff --git a/spec/features/admin/admin_disables_two_factor_spec.rb b/spec/features/admin/admin_disables_two_factor_spec.rb
index 71be66303d2..5437da29979 100644
--- a/spec/features/admin/admin_disables_two_factor_spec.rb
+++ b/spec/features/admin/admin_disables_two_factor_spec.rb
@@ -2,7 +2,7 @@ require 'rails_helper'
feature 'Admin disables 2FA for a user', feature: true do
scenario 'successfully', js: true do
- login_as(:admin)
+ gitlab_sign_in(:admin)
user = create(:user, :two_factor)
edit_user(user)
@@ -17,7 +17,7 @@ feature 'Admin disables 2FA for a user', feature: true do
end
scenario 'for a user without 2FA enabled' do
- login_as(:admin)
+ gitlab_sign_in(:admin)
user = create(:user)
edit_user(user)
diff --git a/spec/features/admin/admin_groups_spec.rb b/spec/features/admin/admin_groups_spec.rb
index cf9d7bca255..8b0fafc5f07 100644
--- a/spec/features/admin/admin_groups_spec.rb
+++ b/spec/features/admin/admin_groups_spec.rb
@@ -6,7 +6,7 @@ feature 'Admin Groups', feature: true do
let(:internal) { Gitlab::VisibilityLevel::INTERNAL }
let(:user) { create :user }
let!(:group) { create :group }
- let!(:current_user) { login_as :admin }
+ let!(:current_user) { gitlab_sign_in :admin }
before do
stub_application_setting(default_group_visibility: internal)
diff --git a/spec/features/admin/admin_health_check_spec.rb b/spec/features/admin/admin_health_check_spec.rb
index 523afa2318f..75093aa4167 100644
--- a/spec/features/admin/admin_health_check_spec.rb
+++ b/spec/features/admin/admin_health_check_spec.rb
@@ -5,7 +5,7 @@ feature "Admin Health Check", feature: true do
before do
stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false')
- login_as :admin
+ gitlab_sign_in :admin
end
describe '#show' do
diff --git a/spec/features/admin/admin_hook_logs_spec.rb b/spec/features/admin/admin_hook_logs_spec.rb
index 5b67f4de6ac..ec80c420c79 100644
--- a/spec/features/admin/admin_hook_logs_spec.rb
+++ b/spec/features/admin/admin_hook_logs_spec.rb
@@ -6,7 +6,7 @@ feature 'Admin::HookLogs', feature: true do
let(:hook_log) { create(:web_hook_log, web_hook: system_hook, internal_error_message: 'some error') }
before do
- login_as :admin
+ gitlab_sign_in :admin
end
scenario 'show list of hook logs' do
diff --git a/spec/features/admin/admin_hooks_spec.rb b/spec/features/admin/admin_hooks_spec.rb
index 80f7ec43c06..c07c21bd6a1 100644
--- a/spec/features/admin/admin_hooks_spec.rb
+++ b/spec/features/admin/admin_hooks_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe 'Admin::Hooks', feature: true do
before do
@project = create(:project)
- login_as :admin
+ gitlab_sign_in :admin
@system_hook = create(:system_hook)
end
diff --git a/spec/features/admin/admin_labels_spec.rb b/spec/features/admin/admin_labels_spec.rb
index a9251db13e5..bb40918bd22 100644
--- a/spec/features/admin/admin_labels_spec.rb
+++ b/spec/features/admin/admin_labels_spec.rb
@@ -5,7 +5,7 @@ RSpec.describe 'admin issues labels' do
let!(:feature_label) { Label.create(title: 'feature', template: true) }
before do
- login_as :admin
+ gitlab_sign_in :admin
end
describe 'list' do
diff --git a/spec/features/admin/admin_manage_applications_spec.rb b/spec/features/admin/admin_manage_applications_spec.rb
index 0079125889b..ae41267e5fc 100644
--- a/spec/features/admin/admin_manage_applications_spec.rb
+++ b/spec/features/admin/admin_manage_applications_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
RSpec.describe 'admin manage applications', feature: true do
before do
- login_as :admin
+ gitlab_sign_in :admin
end
it do
diff --git a/spec/features/admin/admin_projects_spec.rb b/spec/features/admin/admin_projects_spec.rb
index 9d205104ebe..a4ce3e1d5ee 100644
--- a/spec/features/admin/admin_projects_spec.rb
+++ b/spec/features/admin/admin_projects_spec.rb
@@ -6,7 +6,7 @@ describe "Admin::Projects", feature: true do
let(:user) { create :user }
let!(:project) { create(:project) }
let!(:current_user) do
- login_as :admin
+ gitlab_sign_in :admin
end
describe "GET /admin/projects" do
@@ -57,8 +57,8 @@ describe "Admin::Projects", feature: true do
before do
create(:group, name: 'Web')
- allow_any_instance_of(Projects::TransferService).
- to receive(:move_uploads_to_new_namespace).and_return(true)
+ allow_any_instance_of(Projects::TransferService)
+ .to receive(:move_uploads_to_new_namespace).and_return(true)
end
it 'transfers project to group web', js: true do
diff --git a/spec/features/admin/admin_requests_profiles_spec.rb b/spec/features/admin/admin_requests_profiles_spec.rb
index e8ecb70306b..2bfe401521b 100644
--- a/spec/features/admin/admin_requests_profiles_spec.rb
+++ b/spec/features/admin/admin_requests_profiles_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe 'Admin::RequestsProfilesController', feature: true do
before do
FileUtils.mkdir_p(Gitlab::RequestProfiler::PROFILES_DIR)
- login_as(:admin)
+ gitlab_sign_in(:admin)
end
after do
diff --git a/spec/features/admin/admin_runners_spec.rb b/spec/features/admin/admin_runners_spec.rb
index bc11b090fdb..5b3323fed13 100644
--- a/spec/features/admin/admin_runners_spec.rb
+++ b/spec/features/admin/admin_runners_spec.rb
@@ -5,7 +5,7 @@ describe "Admin Runners" do
before do
stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false')
- login_as :admin
+ gitlab_sign_in :admin
end
describe "Runners page" do
diff --git a/spec/features/admin/admin_settings_spec.rb b/spec/features/admin/admin_settings_spec.rb
index 27bc25be580..2d6565e6d3b 100644
--- a/spec/features/admin/admin_settings_spec.rb
+++ b/spec/features/admin/admin_settings_spec.rb
@@ -5,7 +5,7 @@ feature 'Admin updates settings', feature: true do
before do
stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false')
- login_as :admin
+ gitlab_sign_in :admin
visit admin_application_settings_path
end
diff --git a/spec/features/admin/admin_system_info_spec.rb b/spec/features/admin/admin_system_info_spec.rb
index 15482347886..4efc7f0eb48 100644
--- a/spec/features/admin/admin_system_info_spec.rb
+++ b/spec/features/admin/admin_system_info_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe 'Admin System Info' do
before do
- login_as :admin
+ gitlab_sign_in :admin
end
describe 'GET /admin/system_info' do
diff --git a/spec/features/admin/admin_users_impersonation_tokens_spec.rb b/spec/features/admin/admin_users_impersonation_tokens_spec.rb
index 849ec829f75..231c094c91d 100644
--- a/spec/features/admin/admin_users_impersonation_tokens_spec.rb
+++ b/spec/features/admin/admin_users_impersonation_tokens_spec.rb
@@ -13,7 +13,7 @@ describe 'Admin > Users > Impersonation Tokens', feature: true, js: true do
end
before do
- login_as(admin)
+ gitlab_sign_in(admin)
end
describe "token creation" do
diff --git a/spec/features/admin/admin_users_spec.rb b/spec/features/admin/admin_users_spec.rb
index f72651667ee..6dbc697642f 100644
--- a/spec/features/admin/admin_users_spec.rb
+++ b/spec/features/admin/admin_users_spec.rb
@@ -5,7 +5,7 @@ describe "Admin::Users", feature: true do
create(:omniauth_user, provider: 'twitter', extern_uid: '123456')
end
- let!(:current_user) { login_as :admin }
+ let!(:current_user) { gitlab_sign_in :admin }
describe "GET /admin/users" do
before do
@@ -78,10 +78,10 @@ describe "Admin::Users", feature: true do
it "applies defaults to user" do
click_button "Create user"
user = User.find_by(username: 'bang')
- expect(user.projects_limit).
- to eq(Gitlab.config.gitlab.default_projects_limit)
- expect(user.can_create_group).
- to eq(Gitlab.config.gitlab.default_can_create_group)
+ expect(user.projects_limit)
+ .to eq(Gitlab.config.gitlab.default_projects_limit)
+ expect(user.can_create_group)
+ .to eq(Gitlab.config.gitlab.default_can_create_group)
end
it "creates user with valid data" do
diff --git a/spec/features/admin/admin_uses_repository_checks_spec.rb b/spec/features/admin/admin_uses_repository_checks_spec.rb
index ab5c42365fe..91d70435db8 100644
--- a/spec/features/admin/admin_uses_repository_checks_spec.rb
+++ b/spec/features/admin/admin_uses_repository_checks_spec.rb
@@ -5,7 +5,7 @@ feature 'Admin uses repository checks', feature: true do
before do
stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false')
- login_as :admin
+ gitlab_sign_in :admin
end
scenario 'to trigger a single check' do
diff --git a/spec/features/atom/dashboard_spec.rb b/spec/features/atom/dashboard_spec.rb
index 1df058b023c..2f4bb45d74b 100644
--- a/spec/features/atom/dashboard_spec.rb
+++ b/spec/features/atom/dashboard_spec.rb
@@ -35,8 +35,8 @@ describe "Dashboard Feed", feature: true do
end
it "has issue comment event" do
- expect(body).
- to have_content("#{user.name} commented on issue ##{issue.iid}")
+ expect(body)
+ .to have_content("#{user.name} commented on issue ##{issue.iid}")
end
end
end
diff --git a/spec/features/atom/issues_spec.rb b/spec/features/atom/issues_spec.rb
index a61231ea254..b94ad973fed 100644
--- a/spec/features/atom/issues_spec.rb
+++ b/spec/features/atom/issues_spec.rb
@@ -15,11 +15,11 @@ describe 'Issues Feed', feature: true do
context 'when authenticated' do
it 'renders atom feed' do
- login_with user
+ gitlab_sign_in user
visit namespace_project_issues_path(project.namespace, project, :atom)
- expect(response_headers['Content-Type']).
- to have_content('application/atom+xml')
+ expect(response_headers['Content-Type'])
+ .to have_content('application/atom+xml')
expect(body).to have_selector('title', text: "#{project.name} issues")
expect(body).to have_selector('author email', text: issue.author_public_email)
expect(body).to have_selector('assignees assignee email', text: issue.assignees.first.public_email)
@@ -33,8 +33,8 @@ describe 'Issues Feed', feature: true do
visit namespace_project_issues_path(project.namespace, project, :atom,
private_token: user.private_token)
- expect(response_headers['Content-Type']).
- to have_content('application/atom+xml')
+ expect(response_headers['Content-Type'])
+ .to have_content('application/atom+xml')
expect(body).to have_selector('title', text: "#{project.name} issues")
expect(body).to have_selector('author email', text: issue.author_public_email)
expect(body).to have_selector('assignees assignee email', text: issue.assignees.first.public_email)
@@ -48,8 +48,8 @@ describe 'Issues Feed', feature: true do
visit namespace_project_issues_path(project.namespace, project, :atom,
rss_token: user.rss_token)
- expect(response_headers['Content-Type']).
- to have_content('application/atom+xml')
+ expect(response_headers['Content-Type'])
+ .to have_content('application/atom+xml')
expect(body).to have_selector('title', text: "#{project.name} issues")
expect(body).to have_selector('author email', text: issue.author_public_email)
expect(body).to have_selector('assignees assignee email', text: issue.assignees.first.public_email)
diff --git a/spec/features/atom/users_spec.rb b/spec/features/atom/users_spec.rb
index fae5aaa52bd..44ae7204bcf 100644
--- a/spec/features/atom/users_spec.rb
+++ b/spec/features/atom/users_spec.rb
@@ -55,8 +55,8 @@ describe "User Feed", feature: true do
end
it 'has issue comment event' do
- expect(body).
- to have_content("#{safe_name} commented on issue ##{issue.iid}")
+ expect(body)
+ .to have_content("#{safe_name} commented on issue ##{issue.iid}")
end
it 'has XHTML summaries in issue descriptions' do
diff --git a/spec/features/auto_deploy_spec.rb b/spec/features/auto_deploy_spec.rb
index 1cf7396bbac..74f5f70702a 100644
--- a/spec/features/auto_deploy_spec.rb
+++ b/spec/features/auto_deploy_spec.rb
@@ -7,7 +7,7 @@ describe 'Auto deploy' do
before do
create :kubernetes_service, project: project
project.team << [user, :master]
- login_as user
+ gitlab_sign_in user
end
context 'when no deployment service is active' do
diff --git a/spec/features/boards/add_issues_modal_spec.rb b/spec/features/boards/add_issues_modal_spec.rb
index 2b8edac4f10..ba58af22841 100644
--- a/spec/features/boards/add_issues_modal_spec.rb
+++ b/spec/features/boards/add_issues_modal_spec.rb
@@ -14,7 +14,7 @@ describe 'Issue Boards add issue modal', :feature, :js do
before do
project.team << [user, :master]
- login_as(user)
+ gitlab_sign_in(user)
visit namespace_project_board_path(project.namespace, project, board)
wait_for_requests
diff --git a/spec/features/boards/boards_spec.rb b/spec/features/boards/boards_spec.rb
index 968cc9d9c80..87fc31d414c 100644
--- a/spec/features/boards/boards_spec.rb
+++ b/spec/features/boards/boards_spec.rb
@@ -12,7 +12,7 @@ describe 'Issue Boards', feature: true, js: true do
project.team << [user, :master]
project.team << [user2, :master]
- login_as(user)
+ gitlab_sign_in(user)
end
context 'no lists' do
@@ -247,13 +247,13 @@ describe 'Issue Boards', feature: true, js: true do
end
it 'issue moves from closed' do
- drag(list_from_index: 3, list_to_index: 2)
+ drag(list_from_index: 2, list_to_index: 3)
wait_for_board_cards(2, 8)
- wait_for_board_cards(3, 3)
- wait_for_board_cards(4, 0)
+ wait_for_board_cards(3, 1)
+ wait_for_board_cards(4, 2)
- expect(find('.board:nth-child(3)')).to have_content(issue8.title)
+ expect(find('.board:nth-child(4)')).to have_content(issue8.title)
end
context 'issue card' do
@@ -519,7 +519,7 @@ describe 'Issue Boards', feature: true, js: true do
context 'signed out user' do
before do
- logout
+ gitlab_sign_out
visit namespace_project_board_path(project.namespace, project, board)
wait_for_requests
end
@@ -542,8 +542,8 @@ describe 'Issue Boards', feature: true, js: true do
before do
project.team << [user_guest, :guest]
- logout
- login_as(user_guest)
+ gitlab_sign_out
+ gitlab_sign_in(user_guest)
visit namespace_project_board_path(project.namespace, project, board)
wait_for_requests
end
diff --git a/spec/features/boards/issue_ordering_spec.rb b/spec/features/boards/issue_ordering_spec.rb
index 1c289993e28..1e620061e5e 100644
--- a/spec/features/boards/issue_ordering_spec.rb
+++ b/spec/features/boards/issue_ordering_spec.rb
@@ -15,7 +15,7 @@ describe 'Issue Boards', :feature, :js do
before do
project.team << [user, :master]
- login_as(user)
+ gitlab_sign_in(user)
end
context 'un-ordered issues' do
diff --git a/spec/features/boards/keyboard_shortcut_spec.rb b/spec/features/boards/keyboard_shortcut_spec.rb
index c2167ba12cd..ed3b38e6a7e 100644
--- a/spec/features/boards/keyboard_shortcut_spec.rb
+++ b/spec/features/boards/keyboard_shortcut_spec.rb
@@ -6,7 +6,7 @@ describe 'Issue Boards shortcut', feature: true, js: true do
before do
create(:board, project: project)
- login_as :admin
+ gitlab_sign_in :admin
visit namespace_project_path(project.namespace, project)
end
diff --git a/spec/features/boards/modal_filter_spec.rb b/spec/features/boards/modal_filter_spec.rb
index b6de6143354..8899e1ef5e5 100644
--- a/spec/features/boards/modal_filter_spec.rb
+++ b/spec/features/boards/modal_filter_spec.rb
@@ -12,7 +12,7 @@ describe 'Issue Boards add issue modal filtering', :feature, :js do
before do
project.team << [user, :master]
- login_as(user)
+ gitlab_sign_in(user)
end
it 'shows empty state when no results found' do
diff --git a/spec/features/boards/new_issue_spec.rb b/spec/features/boards/new_issue_spec.rb
index 7ba60247587..77cd87d6601 100644
--- a/spec/features/boards/new_issue_spec.rb
+++ b/spec/features/boards/new_issue_spec.rb
@@ -10,7 +10,7 @@ describe 'Issue Boards new issue', feature: true, js: true do
before do
project.team << [user, :master]
- login_as(user)
+ gitlab_sign_in(user)
visit namespace_project_board_path(project.namespace, project, board)
wait_for_requests
diff --git a/spec/features/boards/sidebar_spec.rb b/spec/features/boards/sidebar_spec.rb
index 235e4899707..301c243febd 100644
--- a/spec/features/boards/sidebar_spec.rb
+++ b/spec/features/boards/sidebar_spec.rb
@@ -20,7 +20,7 @@ describe 'Issue Boards', feature: true, js: true do
project.team << [user, :master]
- login_as(user)
+ gitlab_sign_in(user)
visit namespace_project_board_path(project.namespace, project, board)
wait_for_requests
diff --git a/spec/features/boards/sub_group_project_spec.rb b/spec/features/boards/sub_group_project_spec.rb
index 4cd05010a93..d57ae6a71e7 100644
--- a/spec/features/boards/sub_group_project_spec.rb
+++ b/spec/features/boards/sub_group_project_spec.rb
@@ -13,7 +13,7 @@ describe 'Sub-group project issue boards', :feature, :js do
before do
project.add_master(user)
- login_as(user)
+ gitlab_sign_in(user)
visit namespace_project_board_path(project.namespace, project, board)
wait_for_requests
diff --git a/spec/features/calendar_spec.rb b/spec/features/calendar_spec.rb
index 1b6d8439f92..b2e72fc7dee 100644
--- a/spec/features/calendar_spec.rb
+++ b/spec/features/calendar_spec.rb
@@ -68,7 +68,7 @@ feature 'Contributions Calendar', :feature, :js do
end
before do
- login_as user
+ gitlab_sign_in user
end
describe 'calendar day selection' do
diff --git a/spec/features/ci_lint_spec.rb b/spec/features/ci_lint_spec.rb
index 3ebc432206a..de16ee3e567 100644
--- a/spec/features/ci_lint_spec.rb
+++ b/spec/features/ci_lint_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe 'CI Lint', js: true do
before do
- login_as :user
+ gitlab_sign_in :user
end
describe 'YAML parsing' do
diff --git a/spec/features/commits_spec.rb b/spec/features/commits_spec.rb
index 2772f05982a..0373f649ee8 100644
--- a/spec/features/commits_spec.rb
+++ b/spec/features/commits_spec.rb
@@ -4,10 +4,11 @@ describe 'Commits' do
include CiStatusHelper
let(:project) { create(:project, :repository) }
+ let(:user) { create(:user) }
describe 'CI' do
before do
- login_as :user
+ sign_in(user)
stub_ci_pipeline_to_return_yaml_file
end
@@ -27,7 +28,7 @@ describe 'Commits' do
let!(:status) { create(:generic_commit_status, pipeline: pipeline) }
before do
- project.team << [@user, :reporter]
+ project.team << [user, :reporter]
end
describe 'Commit builds' do
@@ -52,7 +53,7 @@ describe 'Commits' do
context 'when logged as developer' do
before do
- project.team << [@user, :developer]
+ project.team << [user, :developer]
end
describe 'Project commits' do
@@ -146,7 +147,7 @@ describe 'Commits' do
context "when logged as reporter" do
before do
- project.team << [@user, :reporter]
+ project.team << [user, :reporter]
build.update_attributes(artifacts_file: artifacts_file)
visit ci_status_path(pipeline)
end
@@ -187,11 +188,10 @@ describe 'Commits' do
context 'viewing commits for a branch' do
let(:branch_name) { 'master' }
- let(:user) { create(:user) }
before do
project.team << [user, :master]
- login_with(user)
+ sign_in(user)
visit namespace_project_commits_path(project.namespace, project, branch_name)
end
diff --git a/spec/features/container_registry_spec.rb b/spec/features/container_registry_spec.rb
index fa7adbe71ea..80d16539d5a 100644
--- a/spec/features/container_registry_spec.rb
+++ b/spec/features/container_registry_spec.rb
@@ -9,7 +9,7 @@ describe "Container Registry" do
end
before do
- login_as(user)
+ gitlab_sign_in(user)
project.add_developer(user)
stub_container_registry_config(enabled: true)
stub_container_registry_tags(repository: :any, tags: [])
diff --git a/spec/features/copy_as_gfm_spec.rb b/spec/features/copy_as_gfm_spec.rb
index 740f60c05cc..005c88f6bab 100644
--- a/spec/features/copy_as_gfm_spec.rb
+++ b/spec/features/copy_as_gfm_spec.rb
@@ -6,7 +6,7 @@ describe 'Copy as GFM', feature: true, js: true do
include ActionView::Helpers::JavaScriptHelper
before do
- login_as :admin
+ gitlab_sign_in :admin
end
describe 'Copying rendered GFM' do
diff --git a/spec/features/cycle_analytics_spec.rb b/spec/features/cycle_analytics_spec.rb
index b416bbd3c79..5a7ea975455 100644
--- a/spec/features/cycle_analytics_spec.rb
+++ b/spec/features/cycle_analytics_spec.rb
@@ -14,7 +14,7 @@ feature 'Cycle Analytics', feature: true, js: true do
before do
project.add_master(user)
- login_as(user)
+ gitlab_sign_in(user)
visit namespace_project_cycle_analytics_path(project.namespace, project)
wait_for_requests
@@ -38,7 +38,7 @@ feature 'Cycle Analytics', feature: true, js: true do
create_cycle
deploy_master
- login_as(user)
+ gitlab_sign_in(user)
visit namespace_project_cycle_analytics_path(project.namespace, project)
end
@@ -70,7 +70,7 @@ feature 'Cycle Analytics', feature: true, js: true do
user.update_attribute(:preferred_language, 'es')
project.team << [user, :master]
- login_as(user)
+ gitlab_sign_in(user)
visit namespace_project_cycle_analytics_path(project.namespace, project)
wait_for_requests
end
@@ -93,7 +93,7 @@ feature 'Cycle Analytics', feature: true, js: true do
create_cycle
deploy_master
- login_as(guest)
+ gitlab_sign_in(guest)
visit namespace_project_cycle_analytics_path(project.namespace, project)
wait_for_requests
end
diff --git a/spec/features/dashboard/active_tab_spec.rb b/spec/features/dashboard/active_tab_spec.rb
index ae750be4d4a..f7ddded10c1 100644
--- a/spec/features/dashboard/active_tab_spec.rb
+++ b/spec/features/dashboard/active_tab_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
RSpec.describe 'Dashboard Active Tab', js: true, feature: true do
before do
- login_as :user
+ gitlab_sign_in :user
end
shared_examples 'page has active tab' do |title|
diff --git a/spec/features/dashboard/activity_spec.rb b/spec/features/dashboard/activity_spec.rb
index 0764044260e..1e9cabe7850 100644
--- a/spec/features/dashboard/activity_spec.rb
+++ b/spec/features/dashboard/activity_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
RSpec.describe 'Dashboard Activity', feature: true do
before do
- login_as(create :user)
+ gitlab_sign_in(create :user)
visit activity_dashboard_path
end
diff --git a/spec/features/dashboard/archived_projects_spec.rb b/spec/features/dashboard/archived_projects_spec.rb
index f33bcbb5318..a5ba3e7e3cf 100644
--- a/spec/features/dashboard/archived_projects_spec.rb
+++ b/spec/features/dashboard/archived_projects_spec.rb
@@ -9,7 +9,7 @@ RSpec.describe 'Dashboard Archived Project', feature: true do
project.team << [user, :master]
archived_project.team << [user, :master]
- login_as(user)
+ gitlab_sign_in(user)
visit dashboard_projects_path
end
diff --git a/spec/features/dashboard/datetime_on_tooltips_spec.rb b/spec/features/dashboard/datetime_on_tooltips_spec.rb
index 1793e323588..6931d0a840e 100644
--- a/spec/features/dashboard/datetime_on_tooltips_spec.rb
+++ b/spec/features/dashboard/datetime_on_tooltips_spec.rb
@@ -4,7 +4,7 @@ feature 'Tooltips on .timeago dates', feature: true, js: true do
let(:user) { create(:user) }
let(:project) { create(:project, name: 'test', namespace: user.namespace) }
let(:created_date) { Date.yesterday.to_time }
- let(:expected_format) { created_date.strftime('%b %-d, %Y %l:%M%P') }
+ let(:expected_format) { created_date.in_time_zone.strftime('%b %-d, %Y %l:%M%P') }
context 'on the activity tab' do
before do
@@ -13,7 +13,7 @@ feature 'Tooltips on .timeago dates', feature: true, js: true do
Event.create( project: project, author_id: user.id, action: Event::JOINED,
updated_at: created_date, created_at: created_date)
- login_as user
+ gitlab_sign_in user
visit user_path(user)
wait_for_requests()
@@ -30,7 +30,7 @@ feature 'Tooltips on .timeago dates', feature: true, js: true do
project.team << [user, :master]
create(:snippet, author: user, updated_at: created_date, created_at: created_date)
- login_as user
+ gitlab_sign_in user
visit user_snippets_path(user)
wait_for_requests()
diff --git a/spec/features/dashboard/group_spec.rb b/spec/features/dashboard/group_spec.rb
index 8e20fdec8ad..2f7245950ec 100644
--- a/spec/features/dashboard/group_spec.rb
+++ b/spec/features/dashboard/group_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
RSpec.describe 'Dashboard Group', feature: true do
before do
- login_as(:user)
+ gitlab_sign_in(:user)
end
it 'creates new group', js: true do
diff --git a/spec/features/dashboard/groups_list_spec.rb b/spec/features/dashboard/groups_list_spec.rb
index 7eb254f8451..e520027bc38 100644
--- a/spec/features/dashboard/groups_list_spec.rb
+++ b/spec/features/dashboard/groups_list_spec.rb
@@ -10,7 +10,7 @@ describe 'Dashboard Groups page', js: true, feature: true do
group.add_owner(user)
nested_group.add_owner(user)
- login_as(user)
+ gitlab_sign_in(user)
visit dashboard_groups_path
expect(page).to have_content(group.full_name)
@@ -23,7 +23,7 @@ describe 'Dashboard Groups page', js: true, feature: true do
group.add_owner(user)
nested_group.add_owner(user)
- login_as(user)
+ gitlab_sign_in(user)
visit dashboard_groups_path
end
@@ -58,7 +58,7 @@ describe 'Dashboard Groups page', js: true, feature: true do
group.add_owner(user)
subgroup.add_owner(user)
- login_as(user)
+ gitlab_sign_in(user)
visit dashboard_groups_path
end
@@ -98,7 +98,7 @@ describe 'Dashboard Groups page', js: true, feature: true do
allow(Kaminari.config).to receive(:default_per_page).and_return(1)
- login_as(user)
+ gitlab_sign_in(user)
visit dashboard_groups_path
end
diff --git a/spec/features/dashboard/help_spec.rb b/spec/features/dashboard/help_spec.rb
index 2803f7ec62b..25b0f40c9cd 100644
--- a/spec/features/dashboard/help_spec.rb
+++ b/spec/features/dashboard/help_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
RSpec.describe 'Dashboard Help', feature: true do
before do
- login_as(:user)
+ gitlab_sign_in(:user)
end
it 'renders correctly markdown' do
diff --git a/spec/features/dashboard/issuables_counter_spec.rb b/spec/features/dashboard/issuables_counter_spec.rb
index 354267dbee7..8a8a20fd5b1 100644
--- a/spec/features/dashboard/issuables_counter_spec.rb
+++ b/spec/features/dashboard/issuables_counter_spec.rb
@@ -9,7 +9,7 @@ describe 'Navigation bar counter', feature: true, caching: true do
before do
issue.assignees = [user]
merge_request.update(assignee: user)
- login_as(user)
+ gitlab_sign_in(user)
end
it 'reflects dashboard issues count' do
diff --git a/spec/features/dashboard/issues_spec.rb b/spec/features/dashboard/issues_spec.rb
index 2cea6b1563e..a57962abbda 100644
--- a/spec/features/dashboard/issues_spec.rb
+++ b/spec/features/dashboard/issues_spec.rb
@@ -12,7 +12,7 @@ RSpec.describe 'Dashboard Issues', feature: true do
before do
[project, project_with_issues_disabled].each { |project| project.team << [current_user, :master] }
- login_as(current_user)
+ gitlab_sign_in(current_user)
visit issues_dashboard_path(assignee_id: current_user.id)
end
@@ -59,6 +59,11 @@ RSpec.describe 'Dashboard Issues', feature: true do
expect(page).to have_content(other_issue.title)
end
+ it 'state filter tabs work' do
+ find('#state-closed').click
+ expect(page).to have_current_path(issues_dashboard_url(assignee_id: current_user.id, scope: 'all', state: 'closed'), url: true)
+ end
+
it_behaves_like "it has an RSS button with current_user's RSS token"
it_behaves_like "an autodiscoverable RSS feed with current_user's RSS token"
end
diff --git a/spec/features/dashboard/label_filter_spec.rb b/spec/features/dashboard/label_filter_spec.rb
index 4cff12de854..88bbb9e75b9 100644
--- a/spec/features/dashboard/label_filter_spec.rb
+++ b/spec/features/dashboard/label_filter_spec.rb
@@ -11,7 +11,7 @@ describe 'Dashboard > label filter', feature: true, js: true do
project.labels << label
project2.labels << label2
- login_as(user)
+ gitlab_sign_in(user)
visit issues_dashboard_path
end
diff --git a/spec/features/dashboard/merge_requests_spec.rb b/spec/features/dashboard/merge_requests_spec.rb
index bcb52f602b0..69d5500848e 100644
--- a/spec/features/dashboard/merge_requests_spec.rb
+++ b/spec/features/dashboard/merge_requests_spec.rb
@@ -8,7 +8,7 @@ describe 'Dashboard Merge Requests' do
before do
[project, project_with_merge_requests_disabled].each { |project| project.team << [current_user, :master] }
- login_as(current_user)
+ gitlab_sign_in(current_user)
end
describe 'new merge request dropdown' do
diff --git a/spec/features/dashboard/milestone_filter_spec.rb b/spec/features/dashboard/milestone_filter_spec.rb
index b5b92c36895..295262980a6 100644
--- a/spec/features/dashboard/milestone_filter_spec.rb
+++ b/spec/features/dashboard/milestone_filter_spec.rb
@@ -9,7 +9,7 @@ describe 'Dashboard > milestone filter', :feature, :js do
let!(:issue2) { create :issue, author: user, project: project, milestone: milestone2 }
before do
- login_as(user)
+ gitlab_sign_in(user)
visit issues_dashboard_path(author_id: user.id)
end
diff --git a/spec/features/dashboard/milestone_tabs_spec.rb b/spec/features/dashboard/milestone_tabs_spec.rb
index 0c7b992c500..cc4193b180f 100644
--- a/spec/features/dashboard/milestone_tabs_spec.rb
+++ b/spec/features/dashboard/milestone_tabs_spec.rb
@@ -15,7 +15,7 @@ describe 'Dashboard milestone tabs', :js, :feature do
before do
project.add_master(user)
- login_as(user)
+ gitlab_sign_in(user)
visit dashboard_milestone_path(milestone.safe_title, title: milestone.title)
end
@@ -23,7 +23,7 @@ describe 'Dashboard milestone tabs', :js, :feature do
it 'loads merge requests async' do
click_link 'Merge Requests'
- expect(page).to have_selector('.merge_requests-sortable-list')
+ expect(page).to have_selector('.milestone-merge_requests-list')
end
it 'loads participants async' do
diff --git a/spec/features/dashboard/projects_spec.rb b/spec/features/dashboard/projects_spec.rb
index 3568954a548..2a8185ca669 100644
--- a/spec/features/dashboard/projects_spec.rb
+++ b/spec/features/dashboard/projects_spec.rb
@@ -7,7 +7,7 @@ RSpec.describe 'Dashboard Projects', feature: true do
before do
project.team << [user, :developer]
- login_as(user)
+ gitlab_sign_in(user)
end
it 'shows the project the user in a member of in the list' do
diff --git a/spec/features/dashboard/shortcuts_spec.rb b/spec/features/dashboard/shortcuts_spec.rb
index 349b948eaee..525b0e1b210 100644
--- a/spec/features/dashboard/shortcuts_spec.rb
+++ b/spec/features/dashboard/shortcuts_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
feature 'Dashboard shortcuts', :feature, :js do
context 'logged in' do
before do
- login_as :user
+ gitlab_sign_in :user
visit root_dashboard_path
end
diff --git a/spec/features/dashboard/snippets_spec.rb b/spec/features/dashboard/snippets_spec.rb
index c6ba118220a..0c069ae5cf0 100644
--- a/spec/features/dashboard/snippets_spec.rb
+++ b/spec/features/dashboard/snippets_spec.rb
@@ -6,7 +6,7 @@ describe 'Dashboard snippets', feature: true do
let!(:snippets) { create_list(:project_snippet, 2, :public, author: project.owner, project: project) }
before do
allow(Snippet).to receive(:default_per_page).and_return(1)
- login_as(project.owner)
+ gitlab_sign_in(project.owner)
visit dashboard_snippets_path
end
@@ -25,7 +25,7 @@ describe 'Dashboard snippets', feature: true do
end
before do
- login_as(user)
+ gitlab_sign_in(user)
visit dashboard_snippets_path
end
diff --git a/spec/features/dashboard/user_filters_projects_spec.rb b/spec/features/dashboard/user_filters_projects_spec.rb
index 34d6257f5fd..e9f34760143 100644
--- a/spec/features/dashboard/user_filters_projects_spec.rb
+++ b/spec/features/dashboard/user_filters_projects_spec.rb
@@ -9,7 +9,7 @@ describe 'Dashboard > User filters projects', :feature do
before do
project.team << [user, :master]
- login_as(user)
+ gitlab_sign_in(user)
end
describe 'filtering personal projects' do
diff --git a/spec/features/dashboard_issues_spec.rb b/spec/features/dashboard_issues_spec.rb
index 1c53f6dff06..c4dbaad2895 100644
--- a/spec/features/dashboard_issues_spec.rb
+++ b/spec/features/dashboard_issues_spec.rb
@@ -8,7 +8,7 @@ describe "Dashboard Issues filtering", feature: true, js: true do
context 'filtering by milestone' do
before do
project.team << [user, :master]
- login_as(user)
+ gitlab_sign_in(user)
create(:issue, project: project, author: user, assignees: [user])
create(:issue, project: project, author: user, assignees: [user], milestone: milestone)
diff --git a/spec/features/dashboard_milestones_spec.rb b/spec/features/dashboard_milestones_spec.rb
index f32fddbc9fa..b308a2297b9 100644
--- a/spec/features/dashboard_milestones_spec.rb
+++ b/spec/features/dashboard_milestones_spec.rb
@@ -17,7 +17,7 @@ feature 'Dashboard > Milestones', feature: true do
let!(:milestone) { create(:milestone, project: project) }
before do
project.team << [user, :master]
- login_with(user)
+ gitlab_sign_in(user)
visit dashboard_milestones_path
end
diff --git a/spec/features/discussion_comments/commit_spec.rb b/spec/features/discussion_comments/commit_spec.rb
index 96e0b78f6b9..96128061e4d 100644
--- a/spec/features/discussion_comments/commit_spec.rb
+++ b/spec/features/discussion_comments/commit_spec.rb
@@ -9,7 +9,7 @@ describe 'Discussion Comments Merge Request', :feature, :js do
before do
project.add_master(user)
- login_as(user)
+ gitlab_sign_in(user)
visit namespace_project_commit_path(project.namespace, project, sample_commit.id)
end
diff --git a/spec/features/discussion_comments/issue_spec.rb b/spec/features/discussion_comments/issue_spec.rb
index ccc9efccd18..d7c1cd12fb5 100644
--- a/spec/features/discussion_comments/issue_spec.rb
+++ b/spec/features/discussion_comments/issue_spec.rb
@@ -7,7 +7,7 @@ describe 'Discussion Comments Issue', :feature, :js do
before do
project.add_master(user)
- login_as(user)
+ gitlab_sign_in(user)
visit namespace_project_issue_path(project.namespace, project, issue)
end
diff --git a/spec/features/discussion_comments/merge_request_spec.rb b/spec/features/discussion_comments/merge_request_spec.rb
index f99ebeb9cd9..31fb9c72d25 100644
--- a/spec/features/discussion_comments/merge_request_spec.rb
+++ b/spec/features/discussion_comments/merge_request_spec.rb
@@ -7,7 +7,7 @@ describe 'Discussion Comments Merge Request', :feature, :js do
before do
project.add_master(user)
- login_as(user)
+ gitlab_sign_in(user)
visit namespace_project_merge_request_path(project.namespace, project, merge_request)
end
diff --git a/spec/features/discussion_comments/snippets_spec.rb b/spec/features/discussion_comments/snippets_spec.rb
index 19a306511b2..998d633c83d 100644
--- a/spec/features/discussion_comments/snippets_spec.rb
+++ b/spec/features/discussion_comments/snippets_spec.rb
@@ -7,7 +7,7 @@ describe 'Discussion Comments Issue', :feature, :js do
before do
project.add_master(user)
- login_as(user)
+ gitlab_sign_in(user)
visit namespace_project_snippet_path(project.namespace, project, snippet)
end
diff --git a/spec/features/expand_collapse_diffs_spec.rb b/spec/features/expand_collapse_diffs_spec.rb
index 36b0c371e6e..ea749528c11 100644
--- a/spec/features/expand_collapse_diffs_spec.rb
+++ b/spec/features/expand_collapse_diffs_spec.rb
@@ -10,7 +10,7 @@ feature 'Expand and collapse diffs', js: true, feature: true do
allow(Gitlab::Git::Diff).to receive(:size_limit).and_return(100.kilobytes)
allow(Gitlab::Git::Diff).to receive(:collapse_limit).and_return(10.kilobytes)
- login_as :admin
+ gitlab_sign_in :admin
# Ensure that undiffable.md is in .gitattributes
project.repository.copy_gitattributes(branch)
diff --git a/spec/features/explore/groups_list_spec.rb b/spec/features/explore/groups_list_spec.rb
index d4284ed099b..6be5dee0c3c 100644
--- a/spec/features/explore/groups_list_spec.rb
+++ b/spec/features/explore/groups_list_spec.rb
@@ -10,7 +10,7 @@ describe 'Explore Groups page', :js, :feature do
before do
group.add_owner(user)
- login_as(user)
+ gitlab_sign_in(user)
visit explore_groups_path
end
diff --git a/spec/features/explore/new_menu_spec.rb b/spec/features/explore/new_menu_spec.rb
index 15a6354211b..2d7e703688f 100644
--- a/spec/features/explore/new_menu_spec.rb
+++ b/spec/features/explore/new_menu_spec.rb
@@ -16,7 +16,7 @@ feature 'Top Plus Menu', feature: true, js: true do
context 'used by full user' do
before do
- login_as(user)
+ gitlab_sign_in(user)
end
scenario 'click on New project shows new project page' do
@@ -103,7 +103,7 @@ feature 'Top Plus Menu', feature: true, js: true do
context 'used by guest user' do
before do
- login_as(guest_user)
+ gitlab_sign_in(guest_user)
end
scenario 'click on New issue shows new issue page' do
diff --git a/spec/features/gitlab_flavored_markdown_spec.rb b/spec/features/gitlab_flavored_markdown_spec.rb
index 55092412340..2d13af2a52a 100644
--- a/spec/features/gitlab_flavored_markdown_spec.rb
+++ b/spec/features/gitlab_flavored_markdown_spec.rb
@@ -1,6 +1,7 @@
require 'spec_helper'
describe "GitLab Flavored Markdown", feature: true do
+ let(:user) { create(:user) }
let(:project) { create(:empty_project) }
let(:issue) { create(:issue, project: project) }
let(:fred) do
@@ -10,8 +11,8 @@ describe "GitLab Flavored Markdown", feature: true do
end
before do
- login_as(:user)
- project.add_developer(@user)
+ sign_in(user)
+ project.add_developer(user)
end
describe "for commits" do
@@ -19,8 +20,8 @@ describe "GitLab Flavored Markdown", feature: true do
let(:commit) { project.commit }
before do
- allow_any_instance_of(Commit).to receive(:title).
- and_return("fix #{issue.to_reference}\n\nask #{fred.to_reference} for details")
+ allow_any_instance_of(Commit).to receive(:title)
+ .and_return("fix #{issue.to_reference}\n\nask #{fred.to_reference} for details")
end
it "renders title in commits#index" do
@@ -51,12 +52,12 @@ describe "GitLab Flavored Markdown", feature: true do
describe "for issues", feature: true, js: true do
before do
@other_issue = create(:issue,
- author: @user,
- assignees: [@user],
+ author: user,
+ assignees: [user],
project: project)
@issue = create(:issue,
- author: @user,
- assignees: [@user],
+ author: user,
+ assignees: [user],
project: project,
title: "fix #{@other_issue.to_reference}",
description: "ask #{fred.to_reference} for details")
diff --git a/spec/features/global_search_spec.rb b/spec/features/global_search_spec.rb
index 4b22b07494d..54ebfe6cf77 100644
--- a/spec/features/global_search_spec.rb
+++ b/spec/features/global_search_spec.rb
@@ -6,7 +6,7 @@ feature 'Global search', feature: true do
before do
project.team << [user, :master]
- login_with(user)
+ gitlab_sign_in(user)
end
describe 'I search through the issues and I see pagination' do
diff --git a/spec/features/groups/activity_spec.rb b/spec/features/groups/activity_spec.rb
index 81f9c103e95..9f66a3d8c72 100644
--- a/spec/features/groups/activity_spec.rb
+++ b/spec/features/groups/activity_spec.rb
@@ -7,7 +7,7 @@ feature 'Group activity page', feature: true do
context 'when signed in' do
before do
user = create(:group_member, :developer, user: create(:user), group: group ).user
- login_as(user)
+ gitlab_sign_in(user)
visit path
end
diff --git a/spec/features/groups/empty_states_spec.rb b/spec/features/groups/empty_states_spec.rb
index fef8e41bffe..b1c7151dfa8 100644
--- a/spec/features/groups/empty_states_spec.rb
+++ b/spec/features/groups/empty_states_spec.rb
@@ -5,7 +5,7 @@ feature 'Groups Merge Requests Empty States' do
let(:user) { create(:group_member, :developer, user: create(:user), group: group ).user }
before do
- login_as(user)
+ gitlab_sign_in(user)
end
context 'group has a project' do
diff --git a/spec/features/groups/group_name_toggle_spec.rb b/spec/features/groups/group_name_toggle_spec.rb
index dfc3c84f29a..f450626c370 100644
--- a/spec/features/groups/group_name_toggle_spec.rb
+++ b/spec/features/groups/group_name_toggle_spec.rb
@@ -9,7 +9,7 @@ feature 'Group name toggle', feature: true, js: true do
SMALL_SCREEN = 300
before do
- login_as :user
+ gitlab_sign_in :user
end
it 'is not present if enough horizontal space' do
diff --git a/spec/features/groups/group_settings_spec.rb b/spec/features/groups/group_settings_spec.rb
index 6afde1d0bed..5ad777248ec 100644
--- a/spec/features/groups/group_settings_spec.rb
+++ b/spec/features/groups/group_settings_spec.rb
@@ -6,7 +6,7 @@ feature 'Edit group settings', feature: true do
background do
group.add_owner(user)
- login_as(user)
+ gitlab_sign_in(user)
end
describe 'when the group path is changed' do
diff --git a/spec/features/groups/labels/edit_spec.rb b/spec/features/groups/labels/edit_spec.rb
index 69281cecb7b..b33040ef843 100644
--- a/spec/features/groups/labels/edit_spec.rb
+++ b/spec/features/groups/labels/edit_spec.rb
@@ -7,7 +7,7 @@ feature 'Edit group label', feature: true do
background do
group.add_owner(user)
- login_as(user)
+ gitlab_sign_in(user)
visit edit_group_label_path(group, label)
end
diff --git a/spec/features/groups/members/last_owner_cannot_leave_group_spec.rb b/spec/features/groups/members/last_owner_cannot_leave_group_spec.rb
index be60b0489c7..5af94e4069b 100644
--- a/spec/features/groups/members/last_owner_cannot_leave_group_spec.rb
+++ b/spec/features/groups/members/last_owner_cannot_leave_group_spec.rb
@@ -6,7 +6,7 @@ feature 'Groups > Members > Last owner cannot leave group', feature: true do
background do
group.add_owner(owner)
- login_as(owner)
+ gitlab_sign_in(owner)
visit group_path(group)
end
diff --git a/spec/features/groups/members/list_spec.rb b/spec/features/groups/members/list_spec.rb
index f654fa16a06..5d00ed30c83 100644
--- a/spec/features/groups/members/list_spec.rb
+++ b/spec/features/groups/members/list_spec.rb
@@ -9,7 +9,7 @@ feature 'Groups members list', feature: true do
let(:nested_group) { create(:group, parent: group) }
background do
- login_as(user1)
+ gitlab_sign_in(user1)
end
scenario 'show members from current group and parent', :nested_groups do
diff --git a/spec/features/groups/members/member_cannot_request_access_to_his_project_spec.rb b/spec/features/groups/members/member_cannot_request_access_to_his_project_spec.rb
index 37c433cc09a..135bb3572bc 100644
--- a/spec/features/groups/members/member_cannot_request_access_to_his_project_spec.rb
+++ b/spec/features/groups/members/member_cannot_request_access_to_his_project_spec.rb
@@ -6,7 +6,7 @@ feature 'Groups > Members > Member cannot request access to his project', featur
background do
group.add_developer(member)
- login_as(member)
+ gitlab_sign_in(member)
visit group_path(group)
end
diff --git a/spec/features/groups/members/member_leaves_group_spec.rb b/spec/features/groups/members/member_leaves_group_spec.rb
index ac4d94658ae..40f3b166e74 100644
--- a/spec/features/groups/members/member_leaves_group_spec.rb
+++ b/spec/features/groups/members/member_leaves_group_spec.rb
@@ -8,7 +8,7 @@ feature 'Groups > Members > Member leaves group', feature: true do
background do
group.add_owner(owner)
group.add_developer(user)
- login_as(user)
+ gitlab_sign_in(user)
visit group_path(group)
end
diff --git a/spec/features/groups/members/owner_manages_access_requests_spec.rb b/spec/features/groups/members/owner_manages_access_requests_spec.rb
index dbe150823ba..4e4cf12e8af 100644
--- a/spec/features/groups/members/owner_manages_access_requests_spec.rb
+++ b/spec/features/groups/members/owner_manages_access_requests_spec.rb
@@ -8,7 +8,7 @@ feature 'Groups > Members > Owner manages access requests', feature: true do
background do
group.request_access(user)
group.add_owner(owner)
- login_as(owner)
+ gitlab_sign_in(owner)
end
scenario 'owner can see access requests' do
diff --git a/spec/features/groups/members/sorting_spec.rb b/spec/features/groups/members/sorting_spec.rb
index 902d3f789ff..719fa0b40b8 100644
--- a/spec/features/groups/members/sorting_spec.rb
+++ b/spec/features/groups/members/sorting_spec.rb
@@ -9,7 +9,7 @@ feature 'Groups > Members > Sorting', feature: true do
create(:group_member, :owner, user: owner, group: group, created_at: 5.days.ago)
create(:group_member, :developer, user: developer, group: group, created_at: 3.days.ago)
- login_as(owner)
+ gitlab_sign_in(owner)
end
scenario 'sorts alphabetically by default' do
diff --git a/spec/features/groups/members/user_requests_access_spec.rb b/spec/features/groups/members/user_requests_access_spec.rb
index e4b5ea91bd3..3813308c237 100644
--- a/spec/features/groups/members/user_requests_access_spec.rb
+++ b/spec/features/groups/members/user_requests_access_spec.rb
@@ -8,7 +8,7 @@ feature 'Groups > Members > User requests access', feature: true do
background do
group.add_owner(owner)
- login_as(user)
+ gitlab_sign_in(user)
visit group_path(group)
end
diff --git a/spec/features/groups/milestone_spec.rb b/spec/features/groups/milestone_spec.rb
index daa2c6afd63..330310eae6b 100644
--- a/spec/features/groups/milestone_spec.rb
+++ b/spec/features/groups/milestone_spec.rb
@@ -8,7 +8,7 @@ feature 'Group milestones', :feature, :js do
before do
Timecop.freeze
- login_as(user)
+ gitlab_sign_in(user)
end
after do
diff --git a/spec/features/groups/show_spec.rb b/spec/features/groups/show_spec.rb
index d3c49c37374..76575f61528 100644
--- a/spec/features/groups/show_spec.rb
+++ b/spec/features/groups/show_spec.rb
@@ -7,7 +7,7 @@ feature 'Group show page', feature: true do
context 'when signed in' do
before do
user = create(:group_member, :developer, user: create(:user), group: group ).user
- login_as(user)
+ gitlab_sign_in(user)
visit path
end
diff --git a/spec/features/groups_spec.rb b/spec/features/groups_spec.rb
index 5737ca39b4e..ecacca00a61 100644
--- a/spec/features/groups_spec.rb
+++ b/spec/features/groups_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
feature 'Group', feature: true do
before do
- login_as(:admin)
+ gitlab_sign_in(:admin)
end
matcher :have_namespace_error_message do
@@ -108,8 +108,8 @@ feature 'Group', feature: true do
before do
group.add_owner(user)
- logout
- login_as(user)
+ gitlab_sign_out
+ gitlab_sign_in(user)
visit subgroups_group_path(group)
click_link 'New Subgroup'
@@ -128,8 +128,8 @@ feature 'Group', feature: true do
it 'checks permissions to avoid exposing groups by parent_id' do
group = create(:group, :private, path: 'secret-group')
- logout
- login_as(:user)
+ gitlab_sign_out
+ gitlab_sign_in(:user)
visit new_group_path(parent_id: group.id)
expect(page).not_to have_content('secret-group')
diff --git a/spec/features/help_pages_spec.rb b/spec/features/help_pages_spec.rb
index 18102146b5f..b01ee1cf491 100644
--- a/spec/features/help_pages_spec.rb
+++ b/spec/features/help_pages_spec.rb
@@ -40,7 +40,7 @@ describe 'Help Pages', feature: true do
allow_any_instance_of(ApplicationSetting).to receive(:version_check_enabled) { true }
allow_any_instance_of(VersionCheck).to receive(:url) { '/version-check-url' }
- login_as :user
+ gitlab_sign_in :user
visit help_path
end
@@ -60,7 +60,7 @@ describe 'Help Pages', feature: true do
allow_any_instance_of(ApplicationSetting).to receive(:help_page_text) { "My Custom Text" }
allow_any_instance_of(ApplicationSetting).to receive(:help_page_support_url) { "http://example.com/help" }
- login_as :user
+ gitlab_sign_in(:user)
visit help_path
end
diff --git a/spec/features/issuables/issuable_list_spec.rb b/spec/features/issuables/issuable_list_spec.rb
index 414838fa22e..f3a5a8463d1 100644
--- a/spec/features/issuables/issuable_list_spec.rb
+++ b/spec/features/issuables/issuable_list_spec.rb
@@ -8,7 +8,7 @@ describe 'issuable list', feature: true do
before do
project.add_user(user, :developer)
- login_as(user)
+ gitlab_sign_in(user)
issuable_types.each { |type| create_issuables(type) }
end
diff --git a/spec/features/issues/award_emoji_spec.rb b/spec/features/issues/award_emoji_spec.rb
index 81ae54c7a10..6698e2c79a1 100644
--- a/spec/features/issues/award_emoji_spec.rb
+++ b/spec/features/issues/award_emoji_spec.rb
@@ -12,7 +12,7 @@ describe 'Awards Emoji', feature: true do
context 'authorized user' do
before do
project.team << [user, :master]
- login_as(user)
+ gitlab_sign_in(user)
end
describe 'visiting an issue with a legacy award emoji that is not valid anymore' do
@@ -81,13 +81,13 @@ describe 'Awards Emoji', feature: true do
end
end
- context 'execute /award slash command' do
+ context 'execute /award quick action' do
it 'toggles the emoji award on noteable', js: true do
- execute_slash_command('/award :100:')
+ execute_quick_action('/award :100:')
expect(find(noteable_award_counter)).to have_text("1")
- execute_slash_command('/award :100:')
+ execute_quick_action('/award :100:')
expect(page).not_to have_selector(noteable_award_counter)
end
@@ -105,7 +105,7 @@ describe 'Awards Emoji', feature: true do
end
end
- def execute_slash_command(cmd)
+ def execute_quick_action(cmd)
within('.js-main-target-form') do
fill_in 'note[note]', with: cmd
click_button 'Comment'
diff --git a/spec/features/issues/award_spec.rb b/spec/features/issues/award_spec.rb
index fcf22dd5033..a1c97caea20 100644
--- a/spec/features/issues/award_spec.rb
+++ b/spec/features/issues/award_spec.rb
@@ -7,7 +7,7 @@ feature 'Issue awards', js: true, feature: true do
describe 'logged in' do
before do
- login_as(user)
+ gitlab_sign_in(user)
visit namespace_project_issue_path(project.namespace, project, issue)
wait_for_requests
end
diff --git a/spec/features/issues/bulk_assignment_labels_spec.rb b/spec/features/issues/bulk_assignment_labels_spec.rb
index 95b4930cd32..a99c19cb787 100644
--- a/spec/features/issues/bulk_assignment_labels_spec.rb
+++ b/spec/features/issues/bulk_assignment_labels_spec.rb
@@ -13,7 +13,22 @@ feature 'Issues > Labels bulk assignment', feature: true do
before do
project.team << [user, :master]
- login_as user
+ gitlab_sign_in user
+ end
+
+ context 'sidebar' do
+ before do
+ enable_bulk_update
+ end
+
+ it 'is present when bulk edit is enabled' do
+ expect(page).to have_css('.issuable-sidebar')
+ end
+
+ it 'is not present when bulk edit is disabled' do
+ disable_bulk_update
+ expect(page).not_to have_css('.issuable-sidebar')
+ end
end
context 'can bulk assign' do
@@ -331,7 +346,7 @@ feature 'Issues > Labels bulk assignment', feature: true do
context 'as a guest' do
before do
- login_as user
+ gitlab_sign_in user
visit namespace_project_issues_path(project.namespace, project)
end
@@ -398,4 +413,8 @@ feature 'Issues > Labels bulk assignment', feature: true do
visit namespace_project_issues_path(project.namespace, project)
click_button 'Edit Issues'
end
+
+ def disable_bulk_update
+ click_button 'Cancel'
+ end
end
diff --git a/spec/features/issues/create_branch_merge_request_spec.rb b/spec/features/issues/create_branch_merge_request_spec.rb
index 1d7d8d291b2..aa538803dd8 100644
--- a/spec/features/issues/create_branch_merge_request_spec.rb
+++ b/spec/features/issues/create_branch_merge_request_spec.rb
@@ -8,7 +8,7 @@ feature 'Create Branch/Merge Request Dropdown on issue page', feature: true, js:
context 'for team members' do
before do
project.team << [user, :developer]
- login_as(user)
+ gitlab_sign_in(user)
end
it 'allows creating a merge request from the issue page' do
diff --git a/spec/features/issues/create_issue_for_discussions_in_merge_request_spec.rb b/spec/features/issues/create_issue_for_discussions_in_merge_request_spec.rb
index 24e2419b5ce..5f631043e15 100644
--- a/spec/features/issues/create_issue_for_discussions_in_merge_request_spec.rb
+++ b/spec/features/issues/create_issue_for_discussions_in_merge_request_spec.rb
@@ -9,7 +9,7 @@ feature 'Resolving all open discussions in a merge request from an issue', featu
describe 'as a user with access to the project' do
before do
project.team << [user, :master]
- login_as user
+ gitlab_sign_in user
visit namespace_project_merge_request_path(project.namespace, project, merge_request)
end
@@ -82,7 +82,7 @@ feature 'Resolving all open discussions in a merge request from an issue', featu
describe 'as a reporter' do
before do
project.team << [user, :reporter]
- login_as user
+ gitlab_sign_in user
visit new_namespace_project_issue_path(project.namespace, project, merge_request_to_resolve_discussions_of: merge_request.iid)
end
diff --git a/spec/features/issues/create_issue_for_single_discussion_in_merge_request_spec.rb b/spec/features/issues/create_issue_for_single_discussion_in_merge_request_spec.rb
index 3a5a79e03f4..9e9e214060f 100644
--- a/spec/features/issues/create_issue_for_single_discussion_in_merge_request_spec.rb
+++ b/spec/features/issues/create_issue_for_single_discussion_in_merge_request_spec.rb
@@ -9,7 +9,7 @@ feature 'Resolve an open discussion in a merge request by creating an issue', fe
describe 'As a user with access to the project' do
before do
project.team << [user, :master]
- login_as user
+ gitlab_sign_in user
visit namespace_project_merge_request_path(project.namespace, project, merge_request)
end
@@ -66,7 +66,7 @@ feature 'Resolve an open discussion in a merge request by creating an issue', fe
describe 'as a reporter' do
before do
project.team << [user, :reporter]
- login_as user
+ gitlab_sign_in user
visit new_namespace_project_issue_path(project.namespace, project,
merge_request_to_resolve_discussions_of: merge_request.iid,
discussion_to_resolve: discussion.id)
diff --git a/spec/features/issues/filtered_search/dropdown_assignee_spec.rb b/spec/features/issues/filtered_search/dropdown_assignee_spec.rb
index 44353d880c2..96f6739af2d 100644
--- a/spec/features/issues/filtered_search/dropdown_assignee_spec.rb
+++ b/spec/features/issues/filtered_search/dropdown_assignee_spec.rb
@@ -23,7 +23,7 @@ describe 'Dropdown assignee', :feature, :js do
project.team << [user, :master]
project.team << [user_john, :master]
project.team << [user_jacob, :master]
- login_as(user)
+ gitlab_sign_in(user)
create(:issue, project: project)
visit namespace_project_issues_path(project.namespace, project)
diff --git a/spec/features/issues/filtered_search/dropdown_author_spec.rb b/spec/features/issues/filtered_search/dropdown_author_spec.rb
index 6b707c4be4a..5ee824c662a 100644
--- a/spec/features/issues/filtered_search/dropdown_author_spec.rb
+++ b/spec/features/issues/filtered_search/dropdown_author_spec.rb
@@ -31,7 +31,7 @@ describe 'Dropdown author', js: true, feature: true do
project.team << [user, :master]
project.team << [user_john, :master]
project.team << [user_jacob, :master]
- login_as(user)
+ gitlab_sign_in(user)
create(:issue, project: project)
visit namespace_project_issues_path(project.namespace, project)
diff --git a/spec/features/issues/filtered_search/dropdown_hint_spec.rb b/spec/features/issues/filtered_search/dropdown_hint_spec.rb
index b9a37cfcc22..a05e4394ffd 100644
--- a/spec/features/issues/filtered_search/dropdown_hint_spec.rb
+++ b/spec/features/issues/filtered_search/dropdown_hint_spec.rb
@@ -14,7 +14,7 @@ describe 'Dropdown hint', :js, :feature do
before do
project.team << [user, :master]
- login_as(user)
+ gitlab_sign_in(user)
create(:issue, project: project)
visit namespace_project_issues_path(project.namespace, project)
diff --git a/spec/features/issues/filtered_search/dropdown_label_spec.rb b/spec/features/issues/filtered_search/dropdown_label_spec.rb
index abe5d61e38c..aec9d7ceb5d 100644
--- a/spec/features/issues/filtered_search/dropdown_label_spec.rb
+++ b/spec/features/issues/filtered_search/dropdown_label_spec.rb
@@ -34,7 +34,7 @@ describe 'Dropdown label', js: true, feature: true do
before do
project.add_master(user)
- login_as(user)
+ gitlab_sign_in(user)
create(:issue, project: project)
visit namespace_project_issues_path(project.namespace, project)
diff --git a/spec/features/issues/filtered_search/dropdown_milestone_spec.rb b/spec/features/issues/filtered_search/dropdown_milestone_spec.rb
index 448259057b0..b21f41946b7 100644
--- a/spec/features/issues/filtered_search/dropdown_milestone_spec.rb
+++ b/spec/features/issues/filtered_search/dropdown_milestone_spec.rb
@@ -30,7 +30,7 @@ describe 'Dropdown milestone', :feature, :js do
before do
project.team << [user, :master]
- login_as(user)
+ gitlab_sign_in(user)
create(:issue, project: project)
visit namespace_project_issues_path(project.namespace, project)
diff --git a/spec/features/issues/filtered_search/search_bar_spec.rb b/spec/features/issues/filtered_search/search_bar_spec.rb
index 3ea95aed0a6..806c732b935 100644
--- a/spec/features/issues/filtered_search/search_bar_spec.rb
+++ b/spec/features/issues/filtered_search/search_bar_spec.rb
@@ -9,7 +9,7 @@ describe 'Search bar', js: true, feature: true do
before do
project.team << [user, :master]
- login_as(user)
+ gitlab_sign_in(user)
create(:issue, project: project)
visit namespace_project_issues_path(project.namespace, project)
diff --git a/spec/features/issues/filtered_search/visual_tokens_spec.rb b/spec/features/issues/filtered_search/visual_tokens_spec.rb
index ff32b0c7d11..22488f34813 100644
--- a/spec/features/issues/filtered_search/visual_tokens_spec.rb
+++ b/spec/features/issues/filtered_search/visual_tokens_spec.rb
@@ -25,7 +25,7 @@ describe 'Visual tokens', js: true, feature: true do
before do
project.add_user(user, :master)
project.add_user(user_rock, :master)
- login_as(user)
+ gitlab_sign_in(user)
create(:issue, project: project)
visit namespace_project_issues_path(project.namespace, project)
diff --git a/spec/features/issues/form_spec.rb b/spec/features/issues/form_spec.rb
index 96d37e33f3d..b369ef1ff79 100644
--- a/spec/features/issues/form_spec.rb
+++ b/spec/features/issues/form_spec.rb
@@ -16,7 +16,7 @@ describe 'New/edit issue', :feature, :js do
before do
project.team << [user, :master]
project.team << [user2, :master]
- login_as(user)
+ gitlab_sign_in(user)
end
context 'new issue' do
@@ -210,6 +210,13 @@ describe 'New/edit issue', :feature, :js do
expect(find('.js-assignee-search')).to have_content(user2.name)
end
+
+ it 'description has autocomplete' do
+ find('#issue_description').native.send_keys('')
+ fill_in 'issue_description', with: '@'
+
+ expect(page).to have_selector('.atwho-view')
+ end
end
context 'edit issue' do
@@ -258,6 +265,13 @@ describe 'New/edit issue', :feature, :js do
end
end
end
+
+ it 'description has autocomplete' do
+ find('#issue_description').native.send_keys('')
+ fill_in 'issue_description', with: '@'
+
+ expect(page).to have_selector('.atwho-view')
+ end
end
describe 'sub-group project' do
diff --git a/spec/features/issues/gfm_autocomplete_spec.rb b/spec/features/issues/gfm_autocomplete_spec.rb
index 350473437a8..e61eb5233d0 100644
--- a/spec/features/issues/gfm_autocomplete_spec.rb
+++ b/spec/features/issues/gfm_autocomplete_spec.rb
@@ -8,7 +8,7 @@ feature 'GFM autocomplete', feature: true, js: true do
before do
project.team << [user, :master]
- login_as(user)
+ gitlab_sign_in(user)
visit namespace_project_issue_path(project.namespace, project, issue)
wait_for_requests
@@ -208,7 +208,7 @@ feature 'GFM autocomplete', feature: true, js: true do
expect(page).not_to have_selector('.atwho-view')
end
- it 'triggers autocomplete after selecting a slash command' do
+ it 'triggers autocomplete after selecting a quick action' do
note = find('#note_note')
page.within '.timeline-content-form' do
note.native.send_keys('')
diff --git a/spec/features/issues/issue_sidebar_spec.rb b/spec/features/issues/issue_sidebar_spec.rb
index 96c24750250..163bc4bb32f 100644
--- a/spec/features/issues/issue_sidebar_spec.rb
+++ b/spec/features/issues/issue_sidebar_spec.rb
@@ -10,7 +10,7 @@ feature 'Issue Sidebar', feature: true do
let!(:label) { create(:label, project: project, title: 'bug') }
before do
- login_as(user)
+ gitlab_sign_in(user)
end
context 'assignee', js: true do
diff --git a/spec/features/issues/markdown_toolbar_spec.rb b/spec/features/issues/markdown_toolbar_spec.rb
index c8c9c50396b..66d823ec9d0 100644
--- a/spec/features/issues/markdown_toolbar_spec.rb
+++ b/spec/features/issues/markdown_toolbar_spec.rb
@@ -6,7 +6,7 @@ feature 'Issue markdown toolbar', feature: true, js: true do
let(:user) { create(:user) }
before do
- login_as(user)
+ gitlab_sign_in(user)
visit namespace_project_issue_path(project.namespace, project, issue)
end
diff --git a/spec/features/issues/move_spec.rb b/spec/features/issues/move_spec.rb
index e75bf059218..21a7637fe7f 100644
--- a/spec/features/issues/move_spec.rb
+++ b/spec/features/issues/move_spec.rb
@@ -9,7 +9,7 @@ feature 'issue move to another project' do
create(:issue, description: text, project: old_project, author: user)
end
- background { login_as(user) }
+ background { gitlab_sign_in(user) }
context 'user does not have permission to move issue' do
background do
diff --git a/spec/features/issues/note_polling_spec.rb b/spec/features/issues/note_polling_spec.rb
index 2c0a6ffd3cb..bd31e44ef33 100644
--- a/spec/features/issues/note_polling_spec.rb
+++ b/spec/features/issues/note_polling_spec.rb
@@ -27,7 +27,7 @@ feature 'Issue notes polling', :feature, :js do
let!(:existing_note) { create(:note, noteable: issue, project: project, author: user, note: note_text) }
before do
- login_as(user)
+ gitlab_sign_in(user)
visit namespace_project_issue_path(project.namespace, project, issue)
end
@@ -93,7 +93,7 @@ feature 'Issue notes polling', :feature, :js do
let!(:existing_note) { create(:note, noteable: issue, project: project, author: user1, note: note_text) }
before do
- login_as(user2)
+ gitlab_sign_in(user2)
visit namespace_project_issue_path(project.namespace, project, issue)
end
@@ -114,7 +114,7 @@ feature 'Issue notes polling', :feature, :js do
let!(:system_note) { create(:system_note, noteable: issue, project: project, author: user, note: note_text) }
before do
- login_as(user)
+ gitlab_sign_in(user)
visit namespace_project_issue_path(project.namespace, project, issue)
end
diff --git a/spec/features/issues/notes_on_issues_spec.rb b/spec/features/issues/notes_on_issues_spec.rb
index 15c817cabac..f648295416f 100644
--- a/spec/features/issues/notes_on_issues_spec.rb
+++ b/spec/features/issues/notes_on_issues_spec.rb
@@ -9,7 +9,7 @@ describe 'Create notes on issues', :js, :feature do
before do
project.team << [user, :developer]
- login_as(user)
+ gitlab_sign_in(user)
visit namespace_project_issue_path(project.namespace, project, issue)
fill_in 'note[note]', with: note_text
diff --git a/spec/features/issues/spam_issues_spec.rb b/spec/features/issues/spam_issues_spec.rb
index 6001476d0ca..57c783790b5 100644
--- a/spec/features/issues/spam_issues_spec.rb
+++ b/spec/features/issues/spam_issues_spec.rb
@@ -18,7 +18,7 @@ describe 'New issue', feature: true, js: true do
)
project.team << [user, :master]
- login_as(user)
+ gitlab_sign_in(user)
end
context 'when identified as a spam' do
diff --git a/spec/features/issues/todo_spec.rb b/spec/features/issues/todo_spec.rb
index 3fde85b0a5c..a1c00dd64f6 100644
--- a/spec/features/issues/todo_spec.rb
+++ b/spec/features/issues/todo_spec.rb
@@ -7,7 +7,7 @@ feature 'Manually create a todo item from issue', feature: true, js: true do
before do
project.team << [user, :master]
- login_as(user)
+ gitlab_sign_in(user)
visit namespace_project_issue_path(project.namespace, project, issue)
end
diff --git a/spec/features/issues/update_issues_spec.rb b/spec/features/issues/update_issues_spec.rb
index 8595847d313..dc981406e4e 100644
--- a/spec/features/issues/update_issues_spec.rb
+++ b/spec/features/issues/update_issues_spec.rb
@@ -7,7 +7,7 @@ feature 'Multiple issue updating from issues#index', feature: true do
before do
project.team << [user, :master]
- login_as(user)
+ gitlab_sign_in(user)
end
context 'status', js: true do
diff --git a/spec/features/issues/user_uses_slash_commands_spec.rb b/spec/features/issues/user_uses_slash_commands_spec.rb
index d14c319707c..168cdd08137 100644
--- a/spec/features/issues/user_uses_slash_commands_spec.rb
+++ b/spec/features/issues/user_uses_slash_commands_spec.rb
@@ -1,9 +1,9 @@
require 'rails_helper'
-feature 'Issues > User uses slash commands', feature: true, js: true do
- include SlashCommandsHelpers
+feature 'Issues > User uses quick actions', feature: true, js: true do
+ include QuickActionsHelpers
- it_behaves_like 'issuable record that supports slash commands in its description and notes', :issue do
+ it_behaves_like 'issuable record that supports quick actions in its description and notes', :issue do
let(:issuable) { create(:issue, project: project) }
end
@@ -13,7 +13,7 @@ feature 'Issues > User uses slash commands', feature: true, js: true do
before do
project.team << [user, :master]
- login_with(user)
+ gitlab_sign_in(user)
visit namespace_project_issue_path(project.namespace, project, issue)
end
@@ -41,8 +41,8 @@ feature 'Issues > User uses slash commands', feature: true, js: true do
let(:guest) { create(:user) }
before do
project.team << [guest, :guest]
- logout
- login_with(guest)
+ gitlab_sign_out
+ gitlab_sign_in(guest)
visit namespace_project_issue_path(project.namespace, project, issue)
end
@@ -81,8 +81,8 @@ feature 'Issues > User uses slash commands', feature: true, js: true do
let(:guest) { create(:user) }
before do
project.team << [guest, :guest]
- logout
- login_with(guest)
+ gitlab_sign_out
+ gitlab_sign_in(guest)
visit namespace_project_issue_path(project.namespace, project, issue)
end
diff --git a/spec/features/issues_spec.rb b/spec/features/issues_spec.rb
index 2cff53539f3..f47b89fd718 100644
--- a/spec/features/issues_spec.rb
+++ b/spec/features/issues_spec.rb
@@ -5,20 +5,21 @@ describe 'Issues', feature: true do
include IssueHelpers
include SortingHelper
+ let(:user) { create(:user) }
let(:project) { create(:empty_project, :public) }
before do
- login_as :user
+ sign_in(user)
user2 = create(:user)
- project.team << [[@user, user2], :developer]
+ project.team << [[user, user2], :developer]
end
describe 'Edit issue' do
let!(:issue) do
create(:issue,
- author: @user,
- assignees: [@user],
+ author: user,
+ assignees: [user],
project: project)
end
@@ -35,15 +36,15 @@ describe 'Issues', feature: true do
describe 'Editing issue assignee' do
let!(:issue) do
create(:issue,
- author: @user,
- assignees: [@user],
+ author: user,
+ assignees: [user],
project: project)
end
it 'allows user to select unassigned', js: true do
visit edit_namespace_project_issue_path(project.namespace, project, issue)
- expect(page).to have_content "Assignee #{@user.name}"
+ expect(page).to have_content "Assignee #{user.name}"
first('.js-user-search').click
click_link 'Unassigned'
@@ -86,7 +87,7 @@ describe 'Issues', feature: true do
end
context 'on edit form' do
- let(:issue) { create(:issue, author: @user, project: project, due_date: Date.today.at_beginning_of_month.to_s) }
+ let(:issue) { create(:issue, author: user, project: project, due_date: Date.today.at_beginning_of_month.to_s) }
before do
visit edit_namespace_project_issue_path(project.namespace, project, issue)
@@ -131,10 +132,10 @@ describe 'Issues', feature: true do
describe 'Issue info' do
it 'excludes award_emoji from comment count' do
- issue = create(:issue, author: @user, assignees: [@user], project: project, title: 'foobar')
+ issue = create(:issue, author: user, assignees: [user], project: project, title: 'foobar')
create(:award_emoji, awardable: issue)
- visit namespace_project_issues_path(project.namespace, project, assignee_id: @user.id)
+ visit namespace_project_issues_path(project.namespace, project, assignee_id: user.id)
expect(page).to have_content 'foobar'
expect(page.all('.no-comments').first.text).to eq "0"
@@ -145,8 +146,8 @@ describe 'Issues', feature: true do
before do
%w(foobar barbaz gitlab).each do |title|
create(:issue,
- author: @user,
- assignees: [@user],
+ author: user,
+ assignees: [user],
project: project,
title: title)
end
@@ -168,7 +169,7 @@ describe 'Issues', feature: true do
end
it 'allows filtering by a specified assignee' do
- visit namespace_project_issues_path(project.namespace, project, assignee_id: @user.id)
+ visit namespace_project_issues_path(project.namespace, project, assignee_id: user.id)
expect(page).not_to have_content 'foobar'
expect(page).to have_content 'barbaz'
@@ -366,13 +367,13 @@ describe 'Issues', feature: true do
end
describe 'when I want to reset my incoming email token' do
- let(:project1) { create(:empty_project, namespace: @user.namespace) }
+ let(:project1) { create(:empty_project, namespace: user.namespace) }
let!(:issue) { create(:issue, project: project1) }
before do
stub_incoming_email_setting(enabled: true, address: "p+%{key}@gl.ab")
- project1.team << [@user, :master]
- visit namespace_project_issues_path(@user.namespace, project1)
+ project1.team << [user, :master]
+ visit namespace_project_issues_path(user.namespace, project1)
end
it 'changes incoming email address token', js: true do
@@ -383,7 +384,7 @@ describe 'Issues', feature: true do
wait_for_requests
expect(page).to have_no_field('issue_email', with: previous_token)
- new_token = project1.new_issue_address(@user.reload)
+ new_token = project1.new_issue_address(user.reload)
expect(page).to have_field(
'issue_email',
with: new_token
@@ -392,7 +393,7 @@ describe 'Issues', feature: true do
end
describe 'update labels from issue#show', js: true do
- let(:issue) { create(:issue, project: project, author: @user, assignees: [@user]) }
+ let(:issue) { create(:issue, project: project, author: user, assignees: [user]) }
let!(:label) { create(:label, project: project) }
before do
@@ -411,14 +412,14 @@ describe 'Issues', feature: true do
end
describe 'update assignee from issue#show' do
- let(:issue) { create(:issue, project: project, author: @user, assignees: [@user]) }
+ let(:issue) { create(:issue, project: project, author: user, assignees: [user]) }
context 'by authorized user' do
it 'allows user to select unassigned', js: true do
visit namespace_project_issue_path(project.namespace, project, issue)
page.within('.assignee') do
- expect(page).to have_content "#{@user.name}"
+ expect(page).to have_content "#{user.name}"
click_link 'Edit'
click_link 'Unassigned'
@@ -433,7 +434,7 @@ describe 'Issues', feature: true do
end
it 'allows user to select an assignee', js: true do
- issue2 = create(:issue, project: project, author: @user)
+ issue2 = create(:issue, project: project, author: user)
visit namespace_project_issue_path(project.namespace, project, issue2)
page.within('.assignee') do
@@ -445,28 +446,28 @@ describe 'Issues', feature: true do
end
page.within '.dropdown-menu-user' do
- click_link @user.name
+ click_link user.name
end
page.within('.assignee') do
- expect(page).to have_content @user.name
+ expect(page).to have_content user.name
end
end
it 'allows user to unselect themselves', js: true do
- issue2 = create(:issue, project: project, author: @user)
+ issue2 = create(:issue, project: project, author: user)
visit namespace_project_issue_path(project.namespace, project, issue2)
page.within '.assignee' do
click_link 'Edit'
- click_link @user.name
+ click_link user.name
page.within '.value .author' do
- expect(page).to have_content @user.name
+ expect(page).to have_content user.name
end
click_link 'Edit'
- click_link @user.name
+ click_link user.name
page.within '.value .assign-yourself' do
expect(page).to have_content "No assignee"
@@ -483,8 +484,8 @@ describe 'Issues', feature: true do
end
it 'shows assignee text', js: true do
- logout
- login_with guest
+ sign_out(:user)
+ sign_in(guest)
visit namespace_project_issue_path(project.namespace, project, issue)
expect(page).to have_content issue.assignees.first.name
@@ -493,7 +494,7 @@ describe 'Issues', feature: true do
end
describe 'update milestone from issue#show' do
- let!(:issue) { create(:issue, project: project, author: @user) }
+ let!(:issue) { create(:issue, project: project, author: user) }
let!(:milestone) { create(:milestone, project: project) }
context 'by authorized user' do
@@ -546,8 +547,8 @@ describe 'Issues', feature: true do
end
it 'shows milestone text', js: true do
- logout
- login_with guest
+ sign_out(:user)
+ sign_in(guest)
visit namespace_project_issue_path(project.namespace, project, issue)
expect(page).to have_content milestone.title
@@ -560,7 +561,7 @@ describe 'Issues', feature: true do
context 'by unauthenticated user' do
before do
- logout
+ sign_out(:user)
end
it 'redirects to signin then back to new issue after signin' do
@@ -570,7 +571,9 @@ describe 'Issues', feature: true do
expect(current_path).to eq new_user_session_path
- login_as :user
+ # NOTE: This is specifically testing the redirect after login, so we
+ # need the full login flow
+ gitlab_sign_in(create(:user))
expect(current_path).to eq new_namespace_project_issue_path(project.namespace, project)
end
@@ -599,7 +602,7 @@ describe 'Issues', feature: true do
before do
project.repository.create_file(
- @user,
+ user,
'.gitlab/issue_templates/bug.md',
'this is a test "bug" template',
message: 'added issue template',
@@ -628,7 +631,7 @@ describe 'Issues', feature: true do
it 'click the button to show modal for the new email' do
page.within '#issue-email-modal' do
- email = project.new_issue_address(@user)
+ email = project.new_issue_address(user)
expect(page).to have_selector("input[value='#{email}']")
end
@@ -636,7 +639,7 @@ describe 'Issues', feature: true do
end
context 'with existing issues' do
- let!(:issue) { create(:issue, project: project, author: @user) }
+ let!(:issue) { create(:issue, project: project, author: user) }
it_behaves_like 'show the email in the modal'
end
@@ -648,7 +651,7 @@ describe 'Issues', feature: true do
describe 'due date' do
context 'update due on issue#show', js: true do
- let(:issue) { create(:issue, project: project, author: @user, assignees: [@user]) }
+ let(:issue) { create(:issue, project: project, author: user, assignees: [user]) }
before do
visit namespace_project_issue_path(project.namespace, project, issue)
@@ -693,7 +696,7 @@ describe 'Issues', feature: true do
describe 'title issue#show', js: true do
it 'updates the title', js: true do
- issue = create(:issue, author: @user, assignees: [@user], project: project, title: 'new title')
+ issue = create(:issue, author: user, assignees: [user], project: project, title: 'new title')
visit namespace_project_issue_path(project.namespace, project, issue)
diff --git a/spec/features/login_spec.rb b/spec/features/login_spec.rb
index 4763f454810..53b8ba5b0f7 100644
--- a/spec/features/login_spec.rb
+++ b/spec/features/login_spec.rb
@@ -36,7 +36,7 @@ feature 'Login', feature: true do
it 'prevents the user from logging in' do
user = create(:user, :blocked)
- login_with(user)
+ gitlab_sign_in(user)
expect(page).to have_content('Your account has been blocked.')
end
@@ -44,19 +44,19 @@ feature 'Login', feature: true do
it 'does not update Devise trackable attributes', :redis do
user = create(:user, :blocked)
- expect { login_with(user) }.not_to change { user.reload.sign_in_count }
+ expect { gitlab_sign_in(user) }.not_to change { user.reload.sign_in_count }
end
end
describe 'with the ghost user' do
it 'disallows login' do
- login_with(User.ghost)
+ gitlab_sign_in(User.ghost)
expect(page).to have_content('Invalid Login or password.')
end
it 'does not update Devise trackable attributes', :redis do
- expect { login_with(User.ghost) }.not_to change { User.ghost.reload.sign_in_count }
+ expect { gitlab_sign_in(User.ghost) }.not_to change { User.ghost.reload.sign_in_count }
end
end
@@ -70,7 +70,7 @@ feature 'Login', feature: true do
let(:user) { create(:user, :two_factor) }
before do
- login_with(user, remember: true)
+ gitlab_sign_in(user, remember: true)
expect(page).to have_content('Two-Factor Authentication')
end
@@ -122,8 +122,8 @@ feature 'Login', feature: true do
end
it 'invalidates the used code' do
- expect { enter_code(codes.sample) }.
- to change { user.reload.otp_backup_codes.size }.by(-1)
+ expect { enter_code(codes.sample) }
+ .to change { user.reload.otp_backup_codes.size }.by(-1)
end
end
@@ -167,7 +167,7 @@ feature 'Login', feature: true do
it 'shows 2FA prompt after OAuth login' do
stub_omniauth_config(enabled: true, auto_link_saml_user: true, allow_single_sign_on: ['saml'], providers: [saml_config])
user = create(:omniauth_user, :two_factor, extern_uid: 'my-uid', provider: 'saml')
- login_via('saml', user, 'my-uid')
+ gitlab_sign_in_via('saml', user, 'my-uid')
expect(page).to have_content('Two-Factor Authentication')
enter_code(user.current_otp)
@@ -180,19 +180,19 @@ feature 'Login', feature: true do
let(:user) { create(:user) }
it 'allows basic login' do
- login_with(user)
+ gitlab_sign_in(user)
expect(current_path).to eq root_path
end
it 'does not show a "You are already signed in." error message' do
- login_with(user)
+ gitlab_sign_in(user)
expect(page).not_to have_content('You are already signed in.')
end
it 'blocks invalid login' do
user = create(:user, password: 'not-the-default')
- login_with(user)
+ gitlab_sign_in(user)
expect(page).to have_content('Invalid Login or password.')
end
end
@@ -209,7 +209,7 @@ feature 'Login', feature: true do
context 'with grace period defined' do
before do
stub_application_setting(two_factor_grace_period: 48)
- login_with(user)
+ gitlab_sign_in(user)
end
context 'within the grace period' do
@@ -246,7 +246,7 @@ feature 'Login', feature: true do
context 'without grace period defined' do
before do
stub_application_setting(two_factor_grace_period: 0)
- login_with(user)
+ gitlab_sign_in(user)
end
it 'redirects to two-factor configuration page' do
@@ -269,7 +269,7 @@ feature 'Login', feature: true do
context 'with grace period defined' do
before do
stub_application_setting(two_factor_grace_period: 48)
- login_with(user)
+ gitlab_sign_in(user)
end
context 'within the grace period' do
@@ -310,7 +310,7 @@ feature 'Login', feature: true do
context 'without grace period defined' do
before do
stub_application_setting(two_factor_grace_period: 0)
- login_with(user)
+ gitlab_sign_in(user)
end
it 'redirects to two-factor configuration page' do
diff --git a/spec/features/markdown_spec.rb b/spec/features/markdown_spec.rb
index ba930de937d..534be3ab5a7 100644
--- a/spec/features/markdown_spec.rb
+++ b/spec/features/markdown_spec.rb
@@ -58,8 +58,8 @@ describe 'GitLab Markdown', feature: true do
end
it 'allows Markdown in tables' do
- expect(doc.at_css('td:contains("Baz")').children.to_html).
- to eq '<strong>Baz</strong>'
+ expect(doc.at_css('td:contains("Baz")').children.to_html)
+ .to eq '<strong>Baz</strong>'
end
it 'parses fenced code blocks' do
@@ -158,14 +158,14 @@ describe 'GitLab Markdown', feature: true do
describe 'Edge Cases' do
it 'allows markup inside link elements' do
aggregate_failures do
- expect(doc.at_css('a[href="#link-emphasis"]').to_html).
- to eq %{<a href="#link-emphasis"><em>text</em></a>}
+ expect(doc.at_css('a[href="#link-emphasis"]').to_html)
+ .to eq %{<a href="#link-emphasis"><em>text</em></a>}
- expect(doc.at_css('a[href="#link-strong"]').to_html).
- to eq %{<a href="#link-strong"><strong>text</strong></a>}
+ expect(doc.at_css('a[href="#link-strong"]').to_html)
+ .to eq %{<a href="#link-strong"><strong>text</strong></a>}
- expect(doc.at_css('a[href="#link-code"]').to_html).
- to eq %{<a href="#link-code"><code>text</code></a>}
+ expect(doc.at_css('a[href="#link-code"]').to_html)
+ .to eq %{<a href="#link-code"><code>text</code></a>}
end
end
end
diff --git a/spec/features/merge_requests/assign_issues_spec.rb b/spec/features/merge_requests/assign_issues_spec.rb
index b306e2f5f75..cb835f533e0 100644
--- a/spec/features/merge_requests/assign_issues_spec.rb
+++ b/spec/features/merge_requests/assign_issues_spec.rb
@@ -13,7 +13,7 @@ feature 'Merge request issue assignment', js: true, feature: true do
end
def visit_merge_request(current_user = nil)
- login_as(current_user || user)
+ gitlab_sign_in(current_user || user)
visit namespace_project_merge_request_path(project.namespace, project, merge_request)
end
diff --git a/spec/features/merge_requests/award_spec.rb b/spec/features/merge_requests/award_spec.rb
index ac260e118d0..e9dd755b6af 100644
--- a/spec/features/merge_requests/award_spec.rb
+++ b/spec/features/merge_requests/award_spec.rb
@@ -7,7 +7,7 @@ feature 'Merge request awards', js: true, feature: true do
describe 'logged in' do
before do
- login_as(user)
+ gitlab_sign_in(user)
visit namespace_project_merge_request_path(project.namespace, project, merge_request)
end
diff --git a/spec/features/merge_requests/check_if_mergeable_with_unresolved_discussions_spec.rb b/spec/features/merge_requests/check_if_mergeable_with_unresolved_discussions_spec.rb
index fa306c02a43..060cfb8fdd1 100644
--- a/spec/features/merge_requests/check_if_mergeable_with_unresolved_discussions_spec.rb
+++ b/spec/features/merge_requests/check_if_mergeable_with_unresolved_discussions_spec.rb
@@ -6,7 +6,7 @@ feature 'Check if mergeable with unresolved discussions', js: true, feature: tru
let!(:merge_request) { create(:merge_request_with_diff_notes, source_project: project, author: user) }
before do
- login_as user
+ gitlab_sign_in user
project.team << [user, :master]
end
diff --git a/spec/features/merge_requests/cherry_pick_spec.rb b/spec/features/merge_requests/cherry_pick_spec.rb
index 6ba681e36f7..6ba96570e3d 100644
--- a/spec/features/merge_requests/cherry_pick_spec.rb
+++ b/spec/features/merge_requests/cherry_pick_spec.rb
@@ -7,7 +7,7 @@ describe 'Cherry-pick Merge Requests', js: true do
let(:merge_request) { create(:merge_request_with_diffs, source_project: project, author: user) }
before do
- login_as user
+ gitlab_sign_in user
project.team << [user, :master]
end
diff --git a/spec/features/merge_requests/closes_issues_spec.rb b/spec/features/merge_requests/closes_issues_spec.rb
index e627618042a..365b2555c35 100644
--- a/spec/features/merge_requests/closes_issues_spec.rb
+++ b/spec/features/merge_requests/closes_issues_spec.rb
@@ -20,7 +20,7 @@ feature 'Merge Request closing issues message', feature: true, js: true do
before do
project.team << [user, :master]
- login_as user
+ gitlab_sign_in user
visit namespace_project_merge_request_path(project.namespace, project, merge_request)
wait_for_requests
diff --git a/spec/features/merge_requests/conflicts_spec.rb b/spec/features/merge_requests/conflicts_spec.rb
index 9409c32104b..9c091befa27 100644
--- a/spec/features/merge_requests/conflicts_spec.rb
+++ b/spec/features/merge_requests/conflicts_spec.rb
@@ -79,7 +79,7 @@ feature 'Merge request conflict resolution', js: true, feature: true do
context 'can be resolved in the UI' do
before do
project.team << [user, :developer]
- login_as(user)
+ gitlab_sign_in(user)
end
context 'the conflicts are resolvable' do
@@ -164,7 +164,7 @@ feature 'Merge request conflict resolution', js: true, feature: true do
before do
project.team << [user, :developer]
- login_as(user)
+ gitlab_sign_in(user)
visit namespace_project_merge_request_path(project.namespace, project, merge_request)
end
diff --git a/spec/features/merge_requests/create_new_mr_spec.rb b/spec/features/merge_requests/create_new_mr_spec.rb
index 82987c768d1..8f7adbccaaa 100644
--- a/spec/features/merge_requests/create_new_mr_spec.rb
+++ b/spec/features/merge_requests/create_new_mr_spec.rb
@@ -7,7 +7,7 @@ feature 'Create New Merge Request', feature: true, js: true do
before do
project.team << [user, :master]
- login_as user
+ gitlab_sign_in user
end
it 'selects the source branch sha when a tag with the same name exists' do
diff --git a/spec/features/merge_requests/created_from_fork_spec.rb b/spec/features/merge_requests/created_from_fork_spec.rb
index b4327743383..69059dfa562 100644
--- a/spec/features/merge_requests/created_from_fork_spec.rb
+++ b/spec/features/merge_requests/created_from_fork_spec.rb
@@ -16,7 +16,7 @@ feature 'Merge request created from fork' do
background do
fork_project.team << [user, :master]
- login_as user
+ gitlab_sign_in user
end
scenario 'user can access merge request' do
diff --git a/spec/features/merge_requests/deleted_source_branch_spec.rb b/spec/features/merge_requests/deleted_source_branch_spec.rb
index 1723fb7d365..f2af3198319 100644
--- a/spec/features/merge_requests/deleted_source_branch_spec.rb
+++ b/spec/features/merge_requests/deleted_source_branch_spec.rb
@@ -8,7 +8,7 @@ describe 'Deleted source branch', feature: true, js: true do
let(:merge_request) { create(:merge_request) }
before do
- login_as user
+ gitlab_sign_in user
merge_request.project.team << [user, :master]
merge_request.update!(source_branch: 'this-branch-does-not-exist')
visit namespace_project_merge_request_path(
diff --git a/spec/features/merge_requests/diff_notes_avatars_spec.rb b/spec/features/merge_requests/diff_notes_avatars_spec.rb
index e23dc2cd940..989dfb71d10 100644
--- a/spec/features/merge_requests/diff_notes_avatars_spec.rb
+++ b/spec/features/merge_requests/diff_notes_avatars_spec.rb
@@ -20,7 +20,7 @@ feature 'Diff note avatars', feature: true, js: true do
before do
project.team << [user, :master]
- login_as user
+ gitlab_sign_in user
end
context 'discussion tab' do
diff --git a/spec/features/merge_requests/diff_notes_resolve_spec.rb b/spec/features/merge_requests/diff_notes_resolve_spec.rb
index 4d549f3bdbb..0f8ca6f90d1 100644
--- a/spec/features/merge_requests/diff_notes_resolve_spec.rb
+++ b/spec/features/merge_requests/diff_notes_resolve_spec.rb
@@ -19,7 +19,7 @@ feature 'Diff notes resolve', feature: true, js: true do
context 'no discussions' do
before do
project.team << [user, :master]
- login_as user
+ gitlab_sign_in user
note.destroy
visit_merge_request
end
@@ -33,7 +33,7 @@ feature 'Diff notes resolve', feature: true, js: true do
context 'as authorized user' do
before do
project.team << [user, :master]
- login_as user
+ gitlab_sign_in user
visit_merge_request
end
@@ -402,7 +402,7 @@ feature 'Diff notes resolve', feature: true, js: true do
before do
project.team << [guest, :guest]
- login_as guest
+ gitlab_sign_in guest
end
context 'someone elses merge request' do
diff --git a/spec/features/merge_requests/diffs_spec.rb b/spec/features/merge_requests/diffs_spec.rb
index 44013df3ea0..cb6cd6571a8 100644
--- a/spec/features/merge_requests/diffs_spec.rb
+++ b/spec/features/merge_requests/diffs_spec.rb
@@ -74,8 +74,7 @@ feature 'Diffs URL', js: true, feature: true do
context 'as author' do
it 'shows direct edit link' do
- login_as(author_user)
-
+ gitlab_sign_in(author_user)
visit diffs_namespace_project_merge_request_path(project.namespace, project, merge_request)
# Throws `Capybara::Poltergeist::InvalidSelector` if we try to use `#hash` syntax
@@ -85,8 +84,7 @@ feature 'Diffs URL', js: true, feature: true do
context 'as user who needs to fork' do
it 'shows fork/cancel confirmation' do
- login_as(user)
-
+ gitlab_sign_in(user)
visit diffs_namespace_project_merge_request_path(project.namespace, project, merge_request)
# Throws `Capybara::Poltergeist::InvalidSelector` if we try to use `#hash` syntax
diff --git a/spec/features/merge_requests/discussion_spec.rb b/spec/features/merge_requests/discussion_spec.rb
index 9db235f35ba..88ae257236c 100644
--- a/spec/features/merge_requests/discussion_spec.rb
+++ b/spec/features/merge_requests/discussion_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
feature 'Merge Request Discussions', feature: true do
before do
- login_as :admin
+ gitlab_sign_in :admin
end
describe "Diff discussions" do
diff --git a/spec/features/merge_requests/edit_mr_spec.rb b/spec/features/merge_requests/edit_mr_spec.rb
index c77a5c68bc6..804bf6967d6 100644
--- a/spec/features/merge_requests/edit_mr_spec.rb
+++ b/spec/features/merge_requests/edit_mr_spec.rb
@@ -8,7 +8,7 @@ feature 'Edit Merge Request', feature: true do
before do
project.team << [user, :master]
- login_as user
+ gitlab_sign_in user
visit edit_namespace_project_merge_request_path(project.namespace, project, merge_request)
end
diff --git a/spec/features/merge_requests/filter_by_labels_spec.rb b/spec/features/merge_requests/filter_by_labels_spec.rb
index 32a9082b9b9..9b677aeca0a 100644
--- a/spec/features/merge_requests/filter_by_labels_spec.rb
+++ b/spec/features/merge_requests/filter_by_labels_spec.rb
@@ -26,7 +26,7 @@ feature 'Issue filtering by Labels', feature: true, js: true do
mr3.labels << feature
project.team << [user, :master]
- login_as(user)
+ gitlab_sign_in(user)
visit namespace_project_merge_requests_path(project.namespace, project)
end
diff --git a/spec/features/merge_requests/filter_by_milestone_spec.rb b/spec/features/merge_requests/filter_by_milestone_spec.rb
index 265a0cfc198..79bca0c9de2 100644
--- a/spec/features/merge_requests/filter_by_milestone_spec.rb
+++ b/spec/features/merge_requests/filter_by_milestone_spec.rb
@@ -15,7 +15,7 @@ feature 'Merge Request filtering by Milestone', feature: true do
before do
project.team << [user, :master]
- login_as(user)
+ gitlab_sign_in(user)
end
scenario 'filters by no Milestone', js: true do
diff --git a/spec/features/merge_requests/filter_merge_requests_spec.rb b/spec/features/merge_requests/filter_merge_requests_spec.rb
index d086be70d69..c12edf1fdf3 100644
--- a/spec/features/merge_requests/filter_merge_requests_spec.rb
+++ b/spec/features/merge_requests/filter_merge_requests_spec.rb
@@ -14,7 +14,7 @@ describe 'Filter merge requests', feature: true do
before do
project.team << [user, :master]
group.add_developer(user)
- login_as(user)
+ gitlab_sign_in(user)
create(:merge_request, source_project: project, target_project: project)
visit namespace_project_merge_requests_path(project.namespace, project)
diff --git a/spec/features/merge_requests/form_spec.rb b/spec/features/merge_requests/form_spec.rb
index 00ef1ffdddc..1996c2fa09a 100644
--- a/spec/features/merge_requests/form_spec.rb
+++ b/spec/features/merge_requests/form_spec.rb
@@ -18,7 +18,7 @@ describe 'New/edit merge request', feature: true, js: true do
context 'owned projects' do
before do
- login_as(user)
+ gitlab_sign_in(user)
end
context 'new merge request' do
@@ -96,6 +96,13 @@ describe 'New/edit merge request', feature: true, js: true do
.to end_with(merge_request_path(merge_request))
end
end
+
+ it 'description has autocomplete' do
+ find('#merge_request_description').native.send_keys('')
+ fill_in 'merge_request_description', with: '@'
+
+ expect(page).to have_selector('.atwho-view')
+ end
end
context 'edit merge request' do
@@ -157,13 +164,20 @@ describe 'New/edit merge request', feature: true, js: true do
end
end
end
+
+ it 'description has autocomplete' do
+ find('#merge_request_description').native.send_keys('')
+ fill_in 'merge_request_description', with: '@'
+
+ expect(page).to have_selector('.atwho-view')
+ end
end
end
context 'forked project' do
before do
fork_project.team << [user, :master]
- login_as(user)
+ gitlab_sign_in(user)
end
context 'new merge request' do
diff --git a/spec/features/merge_requests/merge_commit_message_toggle_spec.rb b/spec/features/merge_requests/merge_commit_message_toggle_spec.rb
index 221ddb5873c..27ba380b005 100644
--- a/spec/features/merge_requests/merge_commit_message_toggle_spec.rb
+++ b/spec/features/merge_requests/merge_commit_message_toggle_spec.rb
@@ -34,7 +34,7 @@ feature 'Clicking toggle commit message link', feature: true, js: true do
before do
project.team << [user, :master]
- login_as user
+ gitlab_sign_in user
visit namespace_project_merge_request_path(project.namespace, project, merge_request)
diff --git a/spec/features/merge_requests/merge_immediately_with_pipeline_spec.rb b/spec/features/merge_requests/merge_immediately_with_pipeline_spec.rb
index 836a7b6e09a..8af7d985036 100644
--- a/spec/features/merge_requests/merge_immediately_with_pipeline_spec.rb
+++ b/spec/features/merge_requests/merge_immediately_with_pipeline_spec.rb
@@ -28,7 +28,7 @@ feature 'Merge immediately', :feature, :js do
end
before do
- login_as user
+ gitlab_sign_in user
visit namespace_project_merge_request_path(merge_request.project.namespace, merge_request.project, merge_request)
end
diff --git a/spec/features/merge_requests/merge_when_pipeline_succeeds_spec.rb b/spec/features/merge_requests/merge_when_pipeline_succeeds_spec.rb
index 09f889d4dd6..bfadd7cb81a 100644
--- a/spec/features/merge_requests/merge_when_pipeline_succeeds_spec.rb
+++ b/spec/features/merge_requests/merge_when_pipeline_succeeds_spec.rb
@@ -28,7 +28,7 @@ feature 'Merge When Pipeline Succeeds', :feature, :js do
end
before do
- login_as user
+ gitlab_sign_in user
visit_merge_request(merge_request)
end
@@ -121,7 +121,7 @@ feature 'Merge When Pipeline Succeeds', :feature, :js do
end
before do
- login_as user
+ gitlab_sign_in user
visit_merge_request(merge_request)
end
diff --git a/spec/features/merge_requests/mini_pipeline_graph_spec.rb b/spec/features/merge_requests/mini_pipeline_graph_spec.rb
index 3a11ea3c8b2..7664fbfbb4c 100644
--- a/spec/features/merge_requests/mini_pipeline_graph_spec.rb
+++ b/spec/features/merge_requests/mini_pipeline_graph_spec.rb
@@ -11,7 +11,7 @@ feature 'Mini Pipeline Graph', :js, :feature do
before do
build.run
- login_as(user)
+ gitlab_sign_in(user)
visit_merge_request
end
diff --git a/spec/features/merge_requests/only_allow_merge_if_build_succeeds_spec.rb b/spec/features/merge_requests/only_allow_merge_if_build_succeeds_spec.rb
index b1dc81a606a..5cd9a7fbe26 100644
--- a/spec/features/merge_requests/only_allow_merge_if_build_succeeds_spec.rb
+++ b/spec/features/merge_requests/only_allow_merge_if_build_succeeds_spec.rb
@@ -5,7 +5,7 @@ feature 'Only allow merge requests to be merged if the pipeline succeeds', featu
let(:project) { merge_request.target_project }
before do
- login_as merge_request.author
+ gitlab_sign_in merge_request.author
project.team << [merge_request.author, :master]
end
diff --git a/spec/features/merge_requests/pipelines_spec.rb b/spec/features/merge_requests/pipelines_spec.rb
index 744bd484a80..c2241317e04 100644
--- a/spec/features/merge_requests/pipelines_spec.rb
+++ b/spec/features/merge_requests/pipelines_spec.rb
@@ -7,7 +7,7 @@ feature 'Pipelines for Merge Requests', feature: true, js: true do
before do
project.team << [user, :master]
- login_as user
+ gitlab_sign_in user
end
context 'with pipelines' do
diff --git a/spec/features/merge_requests/target_branch_spec.rb b/spec/features/merge_requests/target_branch_spec.rb
index c154cf8ade9..4328d66c748 100644
--- a/spec/features/merge_requests/target_branch_spec.rb
+++ b/spec/features/merge_requests/target_branch_spec.rb
@@ -13,7 +13,7 @@ describe 'Target branch', feature: true, js: true do
end
before do
- login_as user
+ gitlab_sign_in user
project.team << [user, :master]
end
diff --git a/spec/features/merge_requests/toggle_whitespace_changes_spec.rb b/spec/features/merge_requests/toggle_whitespace_changes_spec.rb
index 0f98737b700..cba9a2cda99 100644
--- a/spec/features/merge_requests/toggle_whitespace_changes_spec.rb
+++ b/spec/features/merge_requests/toggle_whitespace_changes_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
feature 'Toggle Whitespace Changes', js: true, feature: true do
before do
- login_as :admin
+ gitlab_sign_in :admin
merge_request = create(:merge_request)
project = merge_request.source_project
visit diffs_namespace_project_merge_request_path(project.namespace, project, merge_request)
diff --git a/spec/features/merge_requests/toggler_behavior_spec.rb b/spec/features/merge_requests/toggler_behavior_spec.rb
index 3acd3f6a8b3..c4c06e9a7a0 100644
--- a/spec/features/merge_requests/toggler_behavior_spec.rb
+++ b/spec/features/merge_requests/toggler_behavior_spec.rb
@@ -8,7 +8,7 @@ feature 'toggler_behavior', js: true, feature: true do
let(:fragment_id) { "#note_#{note.id}" }
before do
- login_as :admin
+ gitlab_sign_in :admin
project = merge_request.source_project
page.current_window.resize_to(1000, 300)
visit "#{namespace_project_merge_request_path(project.namespace, project, merge_request)}#{fragment_id}"
diff --git a/spec/features/merge_requests/update_merge_requests_spec.rb b/spec/features/merge_requests/update_merge_requests_spec.rb
index bcdfdf78a44..d0418c74699 100644
--- a/spec/features/merge_requests/update_merge_requests_spec.rb
+++ b/spec/features/merge_requests/update_merge_requests_spec.rb
@@ -7,7 +7,7 @@ feature 'Multiple merge requests updating from merge_requests#index', feature: t
before do
project.team << [user, :master]
- login_as(user)
+ gitlab_sign_in(user)
end
context 'status', js: true do
diff --git a/spec/features/merge_requests/user_posts_diff_notes_spec.rb b/spec/features/merge_requests/user_posts_diff_notes_spec.rb
index 14bc549c9f9..ac7e0eb2727 100644
--- a/spec/features/merge_requests/user_posts_diff_notes_spec.rb
+++ b/spec/features/merge_requests/user_posts_diff_notes_spec.rb
@@ -7,7 +7,7 @@ feature 'Merge requests > User posts diff notes', :js do
before do
project.add_developer(user)
- login_as(user)
+ gitlab_sign_in(user)
end
let(:comment_button_class) { '.add-diff-note' }
diff --git a/spec/features/merge_requests/user_posts_notes_spec.rb b/spec/features/merge_requests/user_posts_notes_spec.rb
index 22552529b9e..12f987e12ea 100644
--- a/spec/features/merge_requests/user_posts_notes_spec.rb
+++ b/spec/features/merge_requests/user_posts_notes_spec.rb
@@ -13,7 +13,7 @@ describe 'Merge requests > User posts notes', :js do
end
before do
- login_as :admin
+ gitlab_sign_in :admin
visit namespace_project_merge_request_path(project.namespace, project, merge_request)
end
@@ -22,8 +22,8 @@ describe 'Merge requests > User posts notes', :js do
describe 'the note form' do
it 'is valid' do
is_expected.to have_css('.js-main-target-form', visible: true, count: 1)
- expect(find('.js-main-target-form .js-comment-button').value).
- to eq('Comment')
+ expect(find('.js-main-target-form .js-comment-button').value)
+ .to eq('Comment')
page.within('.js-main-target-form') do
expect(page).not_to have_link('Cancel')
end
@@ -123,8 +123,8 @@ describe 'Merge requests > User posts notes', :js do
page.within("#note_#{note.id}") do
is_expected.to have_css('.note_edited_ago')
- expect(find('.note_edited_ago').text).
- to match(/less than a minute ago/)
+ expect(find('.note_edited_ago').text)
+ .to match(/less than a minute ago/)
end
end
end
diff --git a/spec/features/merge_requests/user_sees_system_notes_spec.rb b/spec/features/merge_requests/user_sees_system_notes_spec.rb
index 55d0f9d728c..0d88a8172b0 100644
--- a/spec/features/merge_requests/user_sees_system_notes_spec.rb
+++ b/spec/features/merge_requests/user_sees_system_notes_spec.rb
@@ -11,7 +11,7 @@ feature 'Merge requests > User sees system notes' do
before do
user = create(:user)
private_project.add_developer(user)
- login_as(user)
+ gitlab_sign_in(user)
end
it 'shows the system note' do
diff --git a/spec/features/merge_requests/user_uses_slash_commands_spec.rb b/spec/features/merge_requests/user_uses_slash_commands_spec.rb
index 0e64a3e1a4b..71aa71e380e 100644
--- a/spec/features/merge_requests/user_uses_slash_commands_spec.rb
+++ b/spec/features/merge_requests/user_uses_slash_commands_spec.rb
@@ -1,14 +1,14 @@
require 'rails_helper'
-feature 'Merge Requests > User uses slash commands', feature: true, js: true do
- include SlashCommandsHelpers
+feature 'Merge Requests > User uses quick actions', feature: true, js: true do
+ include QuickActionsHelpers
let(:user) { create(:user) }
let(:project) { create(:project, :public) }
let(:merge_request) { create(:merge_request, source_project: project) }
let!(:milestone) { create(:milestone, project: project, title: 'ASAP') }
- it_behaves_like 'issuable record that supports slash commands in its description and notes', :merge_request do
+ it_behaves_like 'issuable record that supports quick actions in its description and notes', :merge_request do
let(:issuable) { create(:merge_request, source_project: project) }
let(:new_url_opts) { { merge_request: { source_branch: 'feature', target_branch: 'master' } } }
end
@@ -16,7 +16,7 @@ feature 'Merge Requests > User uses slash commands', feature: true, js: true do
describe 'merge-request-only commands' do
before do
project.team << [user, :master]
- login_with(user)
+ gitlab_sign_in(user)
visit namespace_project_merge_request_path(project.namespace, project, merge_request)
end
@@ -51,8 +51,8 @@ feature 'Merge Requests > User uses slash commands', feature: true, js: true do
let(:guest) { create(:user) }
before do
project.team << [guest, :guest]
- logout
- login_with(guest)
+ gitlab_sign_out
+ gitlab_sign_in(guest)
visit namespace_project_merge_request_path(project.namespace, project, merge_request)
end
@@ -97,8 +97,8 @@ feature 'Merge Requests > User uses slash commands', feature: true, js: true do
let(:guest) { create(:user) }
before do
project.team << [guest, :guest]
- logout
- login_with(guest)
+ gitlab_sign_out
+ gitlab_sign_in(guest)
visit namespace_project_merge_request_path(project.namespace, project, merge_request)
end
@@ -125,9 +125,9 @@ feature 'Merge Requests > User uses slash commands', feature: true, js: true do
let(:new_url_opts) { { merge_request: { source_branch: 'feature' } } }
before do
- logout
+ gitlab_sign_out
another_project.team << [user, :master]
- login_with(user)
+ gitlab_sign_in(user)
end
it 'changes target_branch in new merge_request' do
@@ -181,8 +181,8 @@ feature 'Merge Requests > User uses slash commands', feature: true, js: true do
let(:guest) { create(:user) }
before do
project.team << [guest, :guest]
- logout
- login_with(guest)
+ gitlab_sign_out
+ gitlab_sign_in(guest)
visit namespace_project_merge_request_path(project.namespace, project, merge_request)
end
diff --git a/spec/features/merge_requests/versions_spec.rb b/spec/features/merge_requests/versions_spec.rb
index aad522ee26e..04a72d3be34 100644
--- a/spec/features/merge_requests/versions_spec.rb
+++ b/spec/features/merge_requests/versions_spec.rb
@@ -8,7 +8,7 @@ feature 'Merge Request versions', js: true, feature: true do
let!(:merge_request_diff3) { merge_request.merge_request_diffs.create(head_commit_sha: '5937ac0a7beb003549fc5fd26fc247adbce4a52e') }
before do
- login_as :admin
+ gitlab_sign_in :admin
visit diffs_namespace_project_merge_request_path(project.namespace, project, merge_request)
end
diff --git a/spec/features/merge_requests/widget_deployments_spec.rb b/spec/features/merge_requests/widget_deployments_spec.rb
index 118ecd9cba5..e82e69c5f4a 100644
--- a/spec/features/merge_requests/widget_deployments_spec.rb
+++ b/spec/features/merge_requests/widget_deployments_spec.rb
@@ -12,7 +12,7 @@ feature 'Widget Deployments Header', feature: true, js: true do
given!(:manual) { }
background do
- login_as(user)
+ gitlab_sign_in(user)
project.team << [user, role]
visit namespace_project_merge_request_path(project.namespace, project, merge_request)
end
diff --git a/spec/features/merge_requests/widget_spec.rb b/spec/features/merge_requests/widget_spec.rb
index 4f3a5119915..3ac1f603de6 100644
--- a/spec/features/merge_requests/widget_spec.rb
+++ b/spec/features/merge_requests/widget_spec.rb
@@ -7,7 +7,7 @@ describe 'Merge request', :feature, :js do
before do
project.team << [user, :master]
- login_as(user)
+ gitlab_sign_in(user)
end
context 'new merge request' do
@@ -209,8 +209,8 @@ describe 'Merge request', :feature, :js do
before do
project.team << [user2, :master]
- logout
- login_as user2
+ gitlab_sign_out
+ gitlab_sign_in user2
merge_request.update(target_project: fork_project)
visit namespace_project_merge_request_path(project.namespace, project, merge_request)
end
diff --git a/spec/features/merge_requests/wip_message_spec.rb b/spec/features/merge_requests/wip_message_spec.rb
index 3311731b33b..72d001bf408 100644
--- a/spec/features/merge_requests/wip_message_spec.rb
+++ b/spec/features/merge_requests/wip_message_spec.rb
@@ -6,7 +6,7 @@ feature 'Work In Progress help message', feature: true do
before do
project.team << [user, :master]
- login_as(user)
+ gitlab_sign_in(user)
end
context 'with WIP commits' do
diff --git a/spec/features/milestone_spec.rb b/spec/features/milestone_spec.rb
index c07de01c594..58989581ffe 100644
--- a/spec/features/milestone_spec.rb
+++ b/spec/features/milestone_spec.rb
@@ -6,7 +6,7 @@ feature 'Milestone', feature: true do
before do
project.team << [user, :master]
- login_as(user)
+ gitlab_sign_in(user)
end
feature 'Create a milestone' do
diff --git a/spec/features/milestones/milestones_spec.rb b/spec/features/milestones/milestones_spec.rb
deleted file mode 100644
index c8a4d23f695..00000000000
--- a/spec/features/milestones/milestones_spec.rb
+++ /dev/null
@@ -1,109 +0,0 @@
-require 'rails_helper'
-
-describe 'Milestone draggable', feature: true, js: true do
- include DragTo
-
- let(:milestone) { create(:milestone, project: project, title: 8.14) }
- let(:project) { create(:empty_project, :public) }
- let(:user) { create(:user) }
-
- context 'issues' do
- let(:issue) { page.find_by_id('issues-list-unassigned').find('li') }
- let(:issue_target) { page.find_by_id('issues-list-ongoing') }
-
- it 'does not allow guest to drag issue' do
- create_and_drag_issue
-
- expect(issue_target).not_to have_selector('.issuable-row')
- end
-
- it 'does not allow authorized user to drag issue' do
- login_as(user)
- create_and_drag_issue
-
- expect(issue_target).not_to have_selector('.issuable-row')
- end
-
- it 'allows author to drag issue' do
- login_as(user)
- create_and_drag_issue(author: user)
-
- expect(issue_target).to have_selector('.issuable-row')
- end
-
- it 'allows admin to drag issue' do
- login_as(:admin)
- create_and_drag_issue
-
- expect(issue_target).to have_selector('.issuable-row')
- end
-
- it 'assigns issue when it has been dragged to ongoing list' do
- login_as(:admin)
- create_and_drag_issue
-
- expect(@issue.reload.assignees).not_to be_empty
- expect(page).to have_selector("#sortable_issue_#{@issue.iid} .assignee-icon img", count: 1)
- end
- end
-
- context 'merge requests' do
- let(:merge_request) { page.find_by_id('merge_requests-list-unassigned').find('li') }
- let(:merge_request_target) { page.find_by_id('merge_requests-list-ongoing') }
-
- it 'does not allow guest to drag merge request' do
- create_and_drag_merge_request
-
- expect(merge_request_target).not_to have_selector('.issuable-row')
- end
-
- it 'does not allow authorized user to drag merge request' do
- login_as(user)
- create_and_drag_merge_request
-
- expect(merge_request_target).not_to have_selector('.issuable-row')
- end
-
- it 'allows author to drag merge request' do
- login_as(user)
- create_and_drag_merge_request(author: user)
-
- expect(merge_request_target).to have_selector('.issuable-row')
- end
-
- it 'allows admin to drag merge request' do
- login_as(:admin)
- create_and_drag_merge_request
-
- expect(merge_request_target).to have_selector('.issuable-row')
- end
- end
-
- def create_and_drag_issue(params = {})
- @issue = create(:issue, params.merge(title: 'Foo', project: project, milestone: milestone))
-
- visit namespace_project_milestone_path(project.namespace, project, milestone)
- scroll_into_view('.milestone-content')
- drag_to(selector: '.issues-sortable-list', list_to_index: 1)
-
- wait_for_requests
- end
-
- def create_and_drag_merge_request(params = {})
- create(:merge_request, params.merge(title: 'Foo', source_project: project, target_project: project, milestone: milestone))
-
- visit namespace_project_milestone_path(project.namespace, project, milestone)
- page.find("a[href='#tab-merge-requests']").click
-
- wait_for_requests
-
- scroll_into_view('.milestone-content')
- drag_to(selector: '.merge_requests-sortable-list', list_to_index: 1)
-
- wait_for_requests
- end
-
- def scroll_into_view(selector)
- page.evaluate_script("document.querySelector('#{selector}').scrollIntoView();")
- end
-end
diff --git a/spec/features/milestones/show_spec.rb b/spec/features/milestones/show_spec.rb
index 227eb04ba72..cdf6cfba402 100644
--- a/spec/features/milestones/show_spec.rb
+++ b/spec/features/milestones/show_spec.rb
@@ -9,7 +9,7 @@ describe 'Milestone show', feature: true do
before do
project.add_user(user, :developer)
- login_as(user)
+ gitlab_sign_in(user)
end
def visit_milestone
diff --git a/spec/features/participants_autocomplete_spec.rb b/spec/features/participants_autocomplete_spec.rb
index 449ce80bc71..b8966cf621c 100644
--- a/spec/features/participants_autocomplete_spec.rb
+++ b/spec/features/participants_autocomplete_spec.rb
@@ -8,7 +8,7 @@ feature 'Member autocomplete', :js do
before do
note # actually create the note
- login_as(user)
+ gitlab_sign_in(user)
end
shared_examples "open suggestions when typing @" do
diff --git a/spec/features/profile_spec.rb b/spec/features/profile_spec.rb
index 7df628fd7a0..bb4263d83f3 100644
--- a/spec/features/profile_spec.rb
+++ b/spec/features/profile_spec.rb
@@ -4,7 +4,7 @@ describe 'Profile account page', feature: true do
let(:user) { create(:user) }
before do
- login_as(user)
+ gitlab_sign_in(user)
end
describe 'when signup is enabled' do
diff --git a/spec/features/profiles/account_spec.rb b/spec/features/profiles/account_spec.rb
index 89868c737f7..33fd29b429b 100644
--- a/spec/features/profiles/account_spec.rb
+++ b/spec/features/profiles/account_spec.rb
@@ -4,7 +4,7 @@ feature 'Profile > Account', feature: true do
given(:user) { create(:user, username: 'foo') }
before do
- login_as(user)
+ gitlab_sign_in(user)
end
describe 'Change username' do
diff --git a/spec/features/profiles/chat_names_spec.rb b/spec/features/profiles/chat_names_spec.rb
index 6f6f7029c0b..1a162d6be0e 100644
--- a/spec/features/profiles/chat_names_spec.rb
+++ b/spec/features/profiles/chat_names_spec.rb
@@ -5,7 +5,7 @@ feature 'Profile > Chat', feature: true do
given(:service) { create(:service) }
before do
- login_as(user)
+ gitlab_sign_in(user)
end
describe 'uses authorization link' do
diff --git a/spec/features/profiles/keys_spec.rb b/spec/features/profiles/keys_spec.rb
index 2f436f153aa..13f9afd4ce0 100644
--- a/spec/features/profiles/keys_spec.rb
+++ b/spec/features/profiles/keys_spec.rb
@@ -4,7 +4,7 @@ feature 'Profile > SSH Keys', feature: true do
let(:user) { create(:user) }
before do
- login_as(user)
+ gitlab_sign_in(user)
end
describe 'User adds a key' do
diff --git a/spec/features/profiles/oauth_applications_spec.rb b/spec/features/profiles/oauth_applications_spec.rb
index 1a5a9059dbd..a6f9beafe17 100644
--- a/spec/features/profiles/oauth_applications_spec.rb
+++ b/spec/features/profiles/oauth_applications_spec.rb
@@ -4,7 +4,7 @@ describe 'Profile > Applications', feature: true do
let(:user) { create(:user) }
before do
- login_as(user)
+ gitlab_sign_in(user)
end
describe 'User manages applications', js: true do
diff --git a/spec/features/profiles/password_spec.rb b/spec/features/profiles/password_spec.rb
index 4cbdd89d46f..2d36f3d020f 100644
--- a/spec/features/profiles/password_spec.rb
+++ b/spec/features/profiles/password_spec.rb
@@ -4,7 +4,7 @@ describe 'Profile > Password', feature: true do
let(:user) { create(:user, password_automatically_set: true) }
before do
- login_as(user)
+ gitlab_sign_in(user)
visit edit_profile_password_path
end
diff --git a/spec/features/profiles/personal_access_tokens_spec.rb b/spec/features/profiles/personal_access_tokens_spec.rb
index 7e2e685df26..d7acaaf1eb8 100644
--- a/spec/features/profiles/personal_access_tokens_spec.rb
+++ b/spec/features/profiles/personal_access_tokens_spec.rb
@@ -23,7 +23,7 @@ describe 'Profile > Personal Access Tokens', feature: true, js: true do
end
before do
- login_as(user)
+ gitlab_sign_in(user)
end
describe "token creation" do
diff --git a/spec/features/profiles/preferences_spec.rb b/spec/features/profiles/preferences_spec.rb
index d368bc4d753..8e7ef6bc110 100644
--- a/spec/features/profiles/preferences_spec.rb
+++ b/spec/features/profiles/preferences_spec.rb
@@ -4,7 +4,7 @@ describe 'Profile > Preferences', feature: true do
let(:user) { create(:user) }
before do
- login_as(user)
+ gitlab_sign_in(user)
visit profile_preferences_path
end
diff --git a/spec/features/profiles/user_changes_notified_of_own_activity_spec.rb b/spec/features/profiles/user_changes_notified_of_own_activity_spec.rb
index e05fbb3715c..c0092836e3b 100644
--- a/spec/features/profiles/user_changes_notified_of_own_activity_spec.rb
+++ b/spec/features/profiles/user_changes_notified_of_own_activity_spec.rb
@@ -4,7 +4,7 @@ feature 'Profile > Notifications > User changes notified_of_own_activity setting
let(:user) { create(:user) }
before do
- login_as(user)
+ gitlab_sign_in(user)
end
scenario 'User opts into receiving notifications about their own activity' do
diff --git a/spec/features/projects/activity/rss_spec.rb b/spec/features/projects/activity/rss_spec.rb
index 3c1de5c09b2..84c81d43448 100644
--- a/spec/features/projects/activity/rss_spec.rb
+++ b/spec/features/projects/activity/rss_spec.rb
@@ -12,7 +12,7 @@ feature 'Project Activity RSS' do
before do
user = create(:user)
project.team << [user, :developer]
- login_as(user)
+ gitlab_sign_in(user)
visit path
end
diff --git a/spec/features/projects/badges/coverage_spec.rb b/spec/features/projects/badges/coverage_spec.rb
index 01a95bf49ac..9624e1a71b0 100644
--- a/spec/features/projects/badges/coverage_spec.rb
+++ b/spec/features/projects/badges/coverage_spec.rb
@@ -7,7 +7,7 @@ feature 'test coverage badge' do
context 'when user has access to view badge' do
background do
project.team << [user, :developer]
- login_as(user)
+ gitlab_sign_in(user)
end
scenario 'user requests coverage badge image for pipeline' do
@@ -45,7 +45,7 @@ feature 'test coverage badge' do
end
context 'when user does not have access to view badge' do
- background { login_as(user) }
+ background { gitlab_sign_in(user) }
scenario 'user requests test coverage badge image' do
show_test_coverage_badge
diff --git a/spec/features/projects/badges/list_spec.rb b/spec/features/projects/badges/list_spec.rb
index ae9db0c0d6e..348748152bb 100644
--- a/spec/features/projects/badges/list_spec.rb
+++ b/spec/features/projects/badges/list_spec.rb
@@ -5,7 +5,7 @@ feature 'list of badges' do
user = create(:user)
project = create(:project)
project.team << [user, :master]
- login_as(user)
+ gitlab_sign_in(user)
visit namespace_project_pipelines_settings_path(project.namespace, project)
end
diff --git a/spec/features/projects/blobs/edit_spec.rb b/spec/features/projects/blobs/edit_spec.rb
index d04c3248ead..d0bc032ee93 100644
--- a/spec/features/projects/blobs/edit_spec.rb
+++ b/spec/features/projects/blobs/edit_spec.rb
@@ -14,7 +14,7 @@ feature 'Editing file blob', feature: true, js: true do
before do
project.team << [user, role]
- login_as(user)
+ gitlab_sign_in(user)
end
def edit_and_commit
@@ -61,7 +61,7 @@ feature 'Editing file blob', feature: true, js: true do
it 'redirects to sign in and returns' do
expect(page).to have_current_path(new_user_session_path)
- login_as(user)
+ gitlab_sign_in(user)
expect(page).to have_current_path(namespace_project_edit_blob_path(project.namespace, project, tree_join(branch, file_path)))
end
@@ -77,7 +77,7 @@ feature 'Editing file blob', feature: true, js: true do
it 'redirects to sign in and returns' do
expect(page).to have_current_path(new_user_session_path)
- login_as(user)
+ gitlab_sign_in(user)
expect(page).to have_current_path(namespace_project_blob_path(project.namespace, project, tree_join(branch, file_path)))
end
@@ -92,7 +92,7 @@ feature 'Editing file blob', feature: true, js: true do
project.team << [user, :developer]
project.repository.add_branch(user, protected_branch, 'master')
create(:protected_branch, project: project, name: protected_branch)
- login_as(user)
+ gitlab_sign_in(user)
end
context 'on some branch' do
@@ -122,7 +122,7 @@ feature 'Editing file blob', feature: true, js: true do
before do
project.team << [user, :master]
- login_as(user)
+ gitlab_sign_in(user)
visit namespace_project_edit_blob_path(project.namespace, project, tree_join(branch, file_path))
end
diff --git a/spec/features/projects/branches/download_buttons_spec.rb b/spec/features/projects/branches/download_buttons_spec.rb
index 92028c19361..d8c4d475a2c 100644
--- a/spec/features/projects/branches/download_buttons_spec.rb
+++ b/spec/features/projects/branches/download_buttons_spec.rb
@@ -22,7 +22,7 @@ feature 'Download buttons in branches page', feature: true do
end
background do
- login_as(user)
+ gitlab_sign_in(user)
project.team << [user, role]
end
diff --git a/spec/features/projects/branches/new_branch_ref_dropdown_spec.rb b/spec/features/projects/branches/new_branch_ref_dropdown_spec.rb
index c5e0a0f0517..406fa52e723 100644
--- a/spec/features/projects/branches/new_branch_ref_dropdown_spec.rb
+++ b/spec/features/projects/branches/new_branch_ref_dropdown_spec.rb
@@ -8,7 +8,7 @@ describe 'New Branch Ref Dropdown', :js, :feature do
before do
project.add_master(user)
- login_as(user)
+ gitlab_sign_in(user)
visit new_namespace_project_branch_path(project.namespace, project)
end
diff --git a/spec/features/projects/branches_spec.rb b/spec/features/projects/branches_spec.rb
index 7668ce5f8be..8694366de35 100644
--- a/spec/features/projects/branches_spec.rb
+++ b/spec/features/projects/branches_spec.rb
@@ -1,6 +1,7 @@
require 'spec_helper'
describe 'Branches', feature: true do
+ let(:user) { create(:user) }
let(:project) { create(:project, :public) }
let(:repository) { project.repository }
@@ -12,8 +13,8 @@ describe 'Branches', feature: true do
context 'logged in as developer' do
before do
- login_as :user
- project.team << [@user, :developer]
+ sign_in(user)
+ project.team << [user, :developer]
end
describe 'Initial branches page' do
@@ -27,7 +28,7 @@ describe 'Branches', feature: true do
it 'avoids a N+1 query in branches index' do
control_count = ActiveRecord::QueryRecorder.new { visit namespace_project_branches_path(project.namespace, project) }.count
- %w(one two three four five).each { |ref| repository.add_branch(@user, ref, 'master') }
+ %w(one two three four five).each { |ref| repository.add_branch(user, ref, 'master') }
expect { visit namespace_project_branches_path(project.namespace, project) }.not_to exceed_query_limit(control_count)
end
@@ -64,14 +65,14 @@ describe 'Branches', feature: true do
describe 'Delete protected branch' do
before do
- project.add_user(@user, :master)
+ project.add_user(user, :master)
visit namespace_project_protected_branches_path(project.namespace, project)
set_protected_branch_name('fix')
click_on "Protect"
within(".protected-branches-list") { expect(page).to have_content('fix') }
expect(ProtectedBranch.count).to eq(1)
- project.add_user(@user, :developer)
+ project.add_user(user, :developer)
end
it 'does not allow devleoper to removes protected branch', js: true do
@@ -87,8 +88,8 @@ describe 'Branches', feature: true do
context 'logged in as master' do
before do
- login_as :user
- project.team << [@user, :master]
+ sign_in(user)
+ project.team << [user, :master]
end
describe 'Delete protected branch' do
diff --git a/spec/features/projects/commit/builds_spec.rb b/spec/features/projects/commit/builds_spec.rb
index 268d420c594..e5b1f95f2b9 100644
--- a/spec/features/projects/commit/builds_spec.rb
+++ b/spec/features/projects/commit/builds_spec.rb
@@ -6,7 +6,7 @@ feature 'project commit pipelines', js: true do
background do
user = create(:user)
project.team << [user, :master]
- login_as(user)
+ gitlab_sign_in(user)
end
context 'when no builds triggered yet' do
diff --git a/spec/features/projects/commit/cherry_pick_spec.rb b/spec/features/projects/commit/cherry_pick_spec.rb
index bc7ca0ddd38..0d3fa72fbf5 100644
--- a/spec/features/projects/commit/cherry_pick_spec.rb
+++ b/spec/features/projects/commit/cherry_pick_spec.rb
@@ -1,14 +1,15 @@
require 'spec_helper'
describe 'Cherry-pick Commits' do
+ let(:user) { create(:user) }
let(:group) { create(:group) }
let(:project) { create(:project, namespace: group) }
let(:master_pickable_commit) { project.commit('7d3b0f7cff5f37573aea97cebfd5692ea1689924') }
let(:master_pickable_merge) { project.commit('e56497bb5f03a90a51293fc6d516788730953899') }
before do
- login_as :user
- project.team << [@user, :master]
+ sign_in(user)
+ project.team << [user, :master]
visit namespace_project_commit_path(project.namespace, project, master_pickable_commit.id)
end
diff --git a/spec/features/projects/commit/mini_pipeline_graph_spec.rb b/spec/features/projects/commit/mini_pipeline_graph_spec.rb
index f2de195eb7f..570a7ae7b16 100644
--- a/spec/features/projects/commit/mini_pipeline_graph_spec.rb
+++ b/spec/features/projects/commit/mini_pipeline_graph_spec.rb
@@ -5,7 +5,7 @@ feature 'Mini Pipeline Graph in Commit View', :js, :feature do
let(:project) { create(:project, :public) }
before do
- login_as(user)
+ gitlab_sign_in(user)
end
context 'when commit has pipelines' do
diff --git a/spec/features/projects/commit/rss_spec.rb b/spec/features/projects/commit/rss_spec.rb
index 03b6d560c96..f7548a56984 100644
--- a/spec/features/projects/commit/rss_spec.rb
+++ b/spec/features/projects/commit/rss_spec.rb
@@ -8,7 +8,7 @@ feature 'Project Commits RSS' do
before do
user = create(:user)
project.team << [user, :developer]
- login_as(user)
+ gitlab_sign_in(user)
visit path
end
diff --git a/spec/features/projects/compare_spec.rb b/spec/features/projects/compare_spec.rb
index ee6985ad993..4743d69fb75 100644
--- a/spec/features/projects/compare_spec.rb
+++ b/spec/features/projects/compare_spec.rb
@@ -6,7 +6,7 @@ describe "Compare", js: true do
before do
project.team << [user, :master]
- login_as user
+ gitlab_sign_in user
visit namespace_project_compare_index_path(project.namespace, project, from: "master", to: "master")
end
diff --git a/spec/features/projects/deploy_keys_spec.rb b/spec/features/projects/deploy_keys_spec.rb
index 06abfbbc86b..a31960639fe 100644
--- a/spec/features/projects/deploy_keys_spec.rb
+++ b/spec/features/projects/deploy_keys_spec.rb
@@ -6,7 +6,7 @@ describe 'Project deploy keys', :js, :feature do
before do
project.team << [user, :master]
- login_as(user)
+ gitlab_sign_in(user)
end
describe 'removing key' do
diff --git a/spec/features/projects/developer_views_empty_project_instructions_spec.rb b/spec/features/projects/developer_views_empty_project_instructions_spec.rb
index 0c51fe72ca4..a943f1e6a08 100644
--- a/spec/features/projects/developer_views_empty_project_instructions_spec.rb
+++ b/spec/features/projects/developer_views_empty_project_instructions_spec.rb
@@ -7,7 +7,7 @@ feature 'Developer views empty project instructions', feature: true do
background do
project.team << [developer, :developer]
- login_as(developer)
+ gitlab_sign_in(developer)
end
context 'without an SSH key' do
diff --git a/spec/features/projects/edit_spec.rb b/spec/features/projects/edit_spec.rb
index a263781c43c..ca202b95a44 100644
--- a/spec/features/projects/edit_spec.rb
+++ b/spec/features/projects/edit_spec.rb
@@ -6,7 +6,7 @@ feature 'Project edit', feature: true, js: true do
before do
project.team << [user, :master]
- login_as(user)
+ gitlab_sign_in(user)
visit edit_namespace_project_path(project.namespace, project)
end
diff --git a/spec/features/projects/environments/environment_metrics_spec.rb b/spec/features/projects/environments/environment_metrics_spec.rb
index ee925e811e1..b48dcf6c774 100644
--- a/spec/features/projects/environments/environment_metrics_spec.rb
+++ b/spec/features/projects/environments/environment_metrics_spec.rb
@@ -15,7 +15,7 @@ feature 'Environment > Metrics', :feature do
create(:deployment, environment: environment, deployable: build)
stub_all_prometheus_requests(environment.slug)
- login_as(user)
+ gitlab_sign_in(user)
visit_environment(environment)
end
diff --git a/spec/features/projects/environments/environment_spec.rb b/spec/features/projects/environments/environment_spec.rb
index 18b608c863e..7d565555f1f 100644
--- a/spec/features/projects/environments/environment_spec.rb
+++ b/spec/features/projects/environments/environment_spec.rb
@@ -6,7 +6,7 @@ feature 'Environment', :feature do
given(:role) { :developer }
background do
- login_as(user)
+ gitlab_sign_in(user)
project.team << [user, role]
end
diff --git a/spec/features/projects/environments/environments_spec.rb b/spec/features/projects/environments/environments_spec.rb
index 613b1edba36..83883dba0ba 100644
--- a/spec/features/projects/environments/environments_spec.rb
+++ b/spec/features/projects/environments/environments_spec.rb
@@ -7,7 +7,7 @@ feature 'Environments page', :feature, :js do
background do
project.team << [user, role]
- login_as(user)
+ gitlab_sign_in(user)
end
given!(:environment) { }
diff --git a/spec/features/projects/features_visibility_spec.rb b/spec/features/projects/features_visibility_spec.rb
index d76b5e4ef1b..db2790a4bce 100644
--- a/spec/features/projects/features_visibility_spec.rb
+++ b/spec/features/projects/features_visibility_spec.rb
@@ -9,7 +9,7 @@ describe 'Edit Project Settings', feature: true do
describe 'project features visibility selectors', js: true do
before do
project.team << [member, :master]
- login_as(member)
+ gitlab_sign_in(member)
end
tools = { builds: "pipelines", issues: "issues", wiki: "wiki", snippets: "snippets", merge_requests: "merge_requests" }
@@ -83,7 +83,7 @@ describe 'Edit Project Settings', feature: true do
context 'normal user' do
before do
- login_as(member)
+ gitlab_sign_in(member)
end
it 'renders 200 if tool is enabled' do
@@ -130,7 +130,7 @@ describe 'Edit Project Settings', feature: true do
context 'admin user' do
before do
non_member.update_attribute(:admin, true)
- login_as(non_member)
+ gitlab_sign_in(non_member)
end
it 'renders 404 if feature is disabled' do
@@ -156,7 +156,7 @@ describe 'Edit Project Settings', feature: true do
describe 'repository visibility', js: true do
before do
project.team << [member, :master]
- login_as(member)
+ gitlab_sign_in(member)
visit edit_namespace_project_path(project.namespace, project)
end
@@ -242,7 +242,7 @@ describe 'Edit Project Settings', feature: true do
before do
project.team << [member, :guest]
- login_as(member)
+ gitlab_sign_in(member)
visit namespace_project_path(project.namespace, project)
end
diff --git a/spec/features/projects/files/browse_files_spec.rb b/spec/features/projects/files/browse_files_spec.rb
index 30a1eedbb48..2a82c3ac179 100644
--- a/spec/features/projects/files/browse_files_spec.rb
+++ b/spec/features/projects/files/browse_files_spec.rb
@@ -6,7 +6,7 @@ feature 'user browses project', feature: true, js: true do
before do
project.team << [user, :master]
- login_with(user)
+ gitlab_sign_in(user)
visit namespace_project_tree_path(project.namespace, project, project.default_branch)
end
diff --git a/spec/features/projects/files/creating_a_file_spec.rb b/spec/features/projects/files/creating_a_file_spec.rb
index 69744ac3948..2a1cc01fe68 100644
--- a/spec/features/projects/files/creating_a_file_spec.rb
+++ b/spec/features/projects/files/creating_a_file_spec.rb
@@ -6,7 +6,7 @@ feature 'User wants to create a file', feature: true do
background do
project.team << [user, :master]
- login_as user
+ gitlab_sign_in user
visit namespace_project_new_blob_path(project.namespace, project, project.default_branch)
end
diff --git a/spec/features/projects/files/dockerfile_dropdown_spec.rb b/spec/features/projects/files/dockerfile_dropdown_spec.rb
index 93909e91d05..4f1b8588462 100644
--- a/spec/features/projects/files/dockerfile_dropdown_spec.rb
+++ b/spec/features/projects/files/dockerfile_dropdown_spec.rb
@@ -7,7 +7,7 @@ feature 'User wants to add a Dockerfile file', feature: true do
project = create(:project)
project.team << [user, :master]
- login_as user
+ gitlab_sign_in user
visit namespace_project_new_blob_path(project.namespace, project, 'master', file_name: 'Dockerfile')
end
diff --git a/spec/features/projects/files/download_buttons_spec.rb b/spec/features/projects/files/download_buttons_spec.rb
index d7c29a7e074..60182bfebe9 100644
--- a/spec/features/projects/files/download_buttons_spec.rb
+++ b/spec/features/projects/files/download_buttons_spec.rb
@@ -22,7 +22,7 @@ feature 'Download buttons in files tree', feature: true do
end
background do
- login_as(user)
+ gitlab_sign_in(user)
project.team << [user, role]
end
diff --git a/spec/features/projects/files/edit_file_soft_wrap_spec.rb b/spec/features/projects/files/edit_file_soft_wrap_spec.rb
index 012befa7990..6e361ac4312 100644
--- a/spec/features/projects/files/edit_file_soft_wrap_spec.rb
+++ b/spec/features/projects/files/edit_file_soft_wrap_spec.rb
@@ -5,7 +5,7 @@ feature 'User uses soft wrap whilst editing file', feature: true, js: true do
user = create(:user)
project = create(:project)
project.team << [user, :master]
- login_as user
+ gitlab_sign_in user
visit namespace_project_new_blob_path(project.namespace, project, 'master', file_name: 'test_file-name')
editor = find('.file-editor.code')
editor.click
diff --git a/spec/features/projects/files/editing_a_file_spec.rb b/spec/features/projects/files/editing_a_file_spec.rb
index 7a3afafec29..e97ff5fded7 100644
--- a/spec/features/projects/files/editing_a_file_spec.rb
+++ b/spec/features/projects/files/editing_a_file_spec.rb
@@ -17,7 +17,7 @@ feature 'User wants to edit a file', feature: true do
background do
project.team << [user, :master]
- login_as user
+ gitlab_sign_in user
visit namespace_project_edit_blob_path(project.namespace, project,
File.join(project.default_branch, '.gitignore'))
end
diff --git a/spec/features/projects/files/files_sort_submodules_with_folders_spec.rb b/spec/features/projects/files/files_sort_submodules_with_folders_spec.rb
index 5c8105de4cb..83a837fba44 100644
--- a/spec/features/projects/files/files_sort_submodules_with_folders_spec.rb
+++ b/spec/features/projects/files/files_sort_submodules_with_folders_spec.rb
@@ -6,7 +6,7 @@ feature 'User views files page', feature: true do
before do
project.team << [user, :master]
- login_as user
+ gitlab_sign_in user
visit namespace_project_tree_path(project.namespace, project, project.repository.root_ref)
end
diff --git a/spec/features/projects/files/find_file_keyboard_spec.rb b/spec/features/projects/files/find_file_keyboard_spec.rb
index ee42bcaec4b..6a914820ac9 100644
--- a/spec/features/projects/files/find_file_keyboard_spec.rb
+++ b/spec/features/projects/files/find_file_keyboard_spec.rb
@@ -6,7 +6,7 @@ feature 'Find file keyboard shortcuts', feature: true, js: true do
before do
project.team << [user, :master]
- login_as user
+ gitlab_sign_in user
visit namespace_project_find_file_path(project.namespace, project, project.repository.root_ref)
diff --git a/spec/features/projects/files/find_files_spec.rb b/spec/features/projects/files/find_files_spec.rb
index 716b7591b95..166ec5c921b 100644
--- a/spec/features/projects/files/find_files_spec.rb
+++ b/spec/features/projects/files/find_files_spec.rb
@@ -5,7 +5,7 @@ feature 'Find files button in the tree header', feature: true do
given(:project) { create(:project) }
background do
- login_as(user)
+ gitlab_sign_in(user)
project.team << [user, :developer]
end
diff --git a/spec/features/projects/files/gitignore_dropdown_spec.rb b/spec/features/projects/files/gitignore_dropdown_spec.rb
index e9f49453121..7f02ec6b73d 100644
--- a/spec/features/projects/files/gitignore_dropdown_spec.rb
+++ b/spec/features/projects/files/gitignore_dropdown_spec.rb
@@ -5,7 +5,7 @@ feature 'User wants to add a .gitignore file', feature: true do
user = create(:user)
project = create(:project)
project.team << [user, :master]
- login_as user
+ gitlab_sign_in user
visit namespace_project_new_blob_path(project.namespace, project, 'master', file_name: '.gitignore')
end
diff --git a/spec/features/projects/files/gitlab_ci_yml_dropdown_spec.rb b/spec/features/projects/files/gitlab_ci_yml_dropdown_spec.rb
index 031b89d0499..f4b17c2518c 100644
--- a/spec/features/projects/files/gitlab_ci_yml_dropdown_spec.rb
+++ b/spec/features/projects/files/gitlab_ci_yml_dropdown_spec.rb
@@ -5,7 +5,7 @@ feature 'User wants to add a .gitlab-ci.yml file', feature: true do
user = create(:user)
project = create(:project)
project.team << [user, :master]
- login_as user
+ gitlab_sign_in user
visit namespace_project_new_blob_path(project.namespace, project, 'master', file_name: '.gitlab-ci.yml')
end
diff --git a/spec/features/projects/files/project_owner_creates_license_file_spec.rb b/spec/features/projects/files/project_owner_creates_license_file_spec.rb
index 8d410cc3f2e..7daf016dd22 100644
--- a/spec/features/projects/files/project_owner_creates_license_file_spec.rb
+++ b/spec/features/projects/files/project_owner_creates_license_file_spec.rb
@@ -7,7 +7,7 @@ feature 'project owner creates a license file', feature: true, js: true do
project.repository.delete_file(project_master, 'LICENSE',
message: 'Remove LICENSE', branch_name: 'master')
project.team << [project_master, :master]
- login_as(project_master)
+ gitlab_sign_in(project_master)
visit namespace_project_path(project.namespace, project)
end
diff --git a/spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb b/spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb
index 8e197bccabf..eab19d52030 100644
--- a/spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb
+++ b/spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb
@@ -5,7 +5,7 @@ feature 'project owner sees a link to create a license file in empty project', f
let(:project) { create(:empty_project) }
background do
project.team << [project_master, :master]
- login_as(project_master)
+ gitlab_sign_in(project_master)
end
scenario 'project master creates a license file from a template' do
diff --git a/spec/features/projects/files/template_type_dropdown_spec.rb b/spec/features/projects/files/template_type_dropdown_spec.rb
index 9fcf12e6cb9..028a0919640 100644
--- a/spec/features/projects/files/template_type_dropdown_spec.rb
+++ b/spec/features/projects/files/template_type_dropdown_spec.rb
@@ -6,7 +6,7 @@ feature 'Template type dropdown selector', js: true do
before do
project.team << [user, :master]
- login_as user
+ gitlab_sign_in user
end
context 'editing a non-matching file' do
diff --git a/spec/features/projects/files/undo_template_spec.rb b/spec/features/projects/files/undo_template_spec.rb
index de10eec0557..4ccd123f46e 100644
--- a/spec/features/projects/files/undo_template_spec.rb
+++ b/spec/features/projects/files/undo_template_spec.rb
@@ -6,7 +6,7 @@ feature 'Template Undo Button', js: true do
before do
project.team << [user, :master]
- login_as user
+ gitlab_sign_in user
end
context 'editing a matching file and applying a template' do
diff --git a/spec/features/projects/gfm_autocomplete_load_spec.rb b/spec/features/projects/gfm_autocomplete_load_spec.rb
index 67bc9142356..aa4ed217a34 100644
--- a/spec/features/projects/gfm_autocomplete_load_spec.rb
+++ b/spec/features/projects/gfm_autocomplete_load_spec.rb
@@ -4,7 +4,7 @@ describe 'GFM autocomplete loading', feature: true, js: true do
let(:project) { create(:project) }
before do
- login_as :admin
+ gitlab_sign_in :admin
visit namespace_project_path(project.namespace, project)
end
diff --git a/spec/features/projects/group_links_spec.rb b/spec/features/projects/group_links_spec.rb
index 1b680a56492..778f5d61ae3 100644
--- a/spec/features/projects/group_links_spec.rb
+++ b/spec/features/projects/group_links_spec.rb
@@ -9,7 +9,7 @@ feature 'Project group links', :feature, :js do
background do
project.add_master(master)
- login_as(master)
+ gitlab_sign_in(master)
end
context 'setting an expiration date for a group link' do
diff --git a/spec/features/projects/guest_navigation_menu_spec.rb b/spec/features/projects/guest_navigation_menu_spec.rb
index b91c3eff478..e1f7f06c113 100644
--- a/spec/features/projects/guest_navigation_menu_spec.rb
+++ b/spec/features/projects/guest_navigation_menu_spec.rb
@@ -7,7 +7,7 @@ describe 'Guest navigation menu' do
before do
project.team << [guest, :guest]
- login_as(guest)
+ gitlab_sign_in(guest)
end
it 'shows allowed tabs only' do
diff --git a/spec/features/projects/import_export/export_file_spec.rb b/spec/features/projects/import_export/export_file_spec.rb
index 40caf89dd54..b5c64777934 100644
--- a/spec/features/projects/import_export/export_file_spec.rb
+++ b/spec/features/projects/import_export/export_file_spec.rb
@@ -33,7 +33,7 @@ feature 'Import/Export - project export integration test', feature: true, js: tr
context 'admin user' do
before do
- login_as(user)
+ gitlab_sign_in(user)
end
scenario 'exports a project successfully' do
diff --git a/spec/features/projects/import_export/import_file_spec.rb b/spec/features/projects/import_export/import_file_spec.rb
index 583f479ec18..a111aa87c52 100644
--- a/spec/features/projects/import_export/import_file_spec.rb
+++ b/spec/features/projects/import_export/import_file_spec.rb
@@ -19,7 +19,7 @@ feature 'Import/Export - project import integration test', feature: true, js: tr
let!(:namespace) { create(:namespace, name: "asd", owner: user) }
before do
- login_as(user)
+ gitlab_sign_in(user)
end
scenario 'user imports an exported project successfully' do
@@ -77,7 +77,7 @@ feature 'Import/Export - project import integration test', feature: true, js: tr
context 'when limited to the default user namespace' do
let(:user) { create(:user) }
before do
- login_as(user)
+ gitlab_sign_in(user)
end
scenario 'passes correct namespace ID in the URL' do
diff --git a/spec/features/projects/import_export/namespace_export_file_spec.rb b/spec/features/projects/import_export/namespace_export_file_spec.rb
index cb399ea55df..b0a68f0d61f 100644
--- a/spec/features/projects/import_export/namespace_export_file_spec.rb
+++ b/spec/features/projects/import_export/namespace_export_file_spec.rb
@@ -16,7 +16,7 @@ feature 'Import/Export - Namespace export file cleanup', feature: true, js: true
context 'admin user' do
before do
- login_as(:admin)
+ gitlab_sign_in(:admin)
end
context 'moving the namespace' do
diff --git a/spec/features/projects/import_export/test_project_export.tar.gz b/spec/features/projects/import_export/test_project_export.tar.gz
index 4efd5a26a82..e03e7b88174 100644
--- a/spec/features/projects/import_export/test_project_export.tar.gz
+++ b/spec/features/projects/import_export/test_project_export.tar.gz
Binary files differ
diff --git a/spec/features/projects/issuable_templates_spec.rb b/spec/features/projects/issuable_templates_spec.rb
index 3076c863dcb..26a09985312 100644
--- a/spec/features/projects/issuable_templates_spec.rb
+++ b/spec/features/projects/issuable_templates_spec.rb
@@ -6,7 +6,7 @@ feature 'issuable templates', feature: true, js: true do
before do
project.team << [user, :master]
- login_as user
+ gitlab_sign_in user
end
context 'user creates an issue using templates' do
@@ -124,11 +124,11 @@ feature 'issuable templates', feature: true, js: true do
let(:merge_request) { create(:merge_request, :with_diffs, source_project: fork_project, target_project: project) }
background do
- logout
+ gitlab_sign_out
project.team << [fork_user, :developer]
fork_project.team << [fork_user, :master]
create(:forked_project_link, forked_to_project: fork_project, forked_from_project: project)
- login_as fork_user
+ gitlab_sign_in fork_user
project.repository.create_file(
fork_user,
'.gitlab/merge_request_templates/feature-proposal.md',
diff --git a/spec/features/projects/issues/list_spec.rb b/spec/features/projects/issues/list_spec.rb
index 3137af074ca..b2db07a75ef 100644
--- a/spec/features/projects/issues/list_spec.rb
+++ b/spec/features/projects/issues/list_spec.rb
@@ -7,7 +7,7 @@ feature 'Issues List' do
background do
project.team << [user, :developer]
- login_as(user)
+ gitlab_sign_in(user)
end
scenario 'user does not see create new list button' do
diff --git a/spec/features/projects/issues/rss_spec.rb b/spec/features/projects/issues/rss_spec.rb
index f6852192aef..38733d39932 100644
--- a/spec/features/projects/issues/rss_spec.rb
+++ b/spec/features/projects/issues/rss_spec.rb
@@ -12,7 +12,7 @@ feature 'Project Issues RSS' do
before do
user = create(:user)
project.team << [user, :developer]
- login_as(user)
+ gitlab_sign_in(user)
visit path
end
diff --git a/spec/features/projects/jobs_spec.rb b/spec/features/projects/jobs_spec.rb
index 31c93c75d25..070cdbf1cef 100644
--- a/spec/features/projects/jobs_spec.rb
+++ b/spec/features/projects/jobs_spec.rb
@@ -17,7 +17,7 @@ feature 'Jobs', :feature do
before do
project.team << [user, user_access_level]
- login_as(user)
+ gitlab_sign_in(user)
end
describe "GET /:project/jobs" do
@@ -392,8 +392,8 @@ feature 'Jobs', :feature do
job.cancel!
project.update(visibility_level: Gitlab::VisibilityLevel::PUBLIC)
- logout_direct
- login_with(create(:user))
+ gitlab_sign_out_direct
+ gitlab_sign_in(create(:user))
visit namespace_project_job_path(project.namespace, project, job)
end
diff --git a/spec/features/projects/labels/issues_sorted_by_priority_spec.rb b/spec/features/projects/labels/issues_sorted_by_priority_spec.rb
index e2911a37e40..2c47758f30e 100644
--- a/spec/features/projects/labels/issues_sorted_by_priority_spec.rb
+++ b/spec/features/projects/labels/issues_sorted_by_priority_spec.rb
@@ -28,7 +28,7 @@ feature 'Issue prioritization', feature: true do
issue_2.labels << label_4
issue_1.labels << label_5
- login_as user
+ gitlab_sign_in user
visit namespace_project_issues_path(project.namespace, project, sort: 'label_priority')
# Ensure we are indicating that issues are sorted by priority
@@ -67,7 +67,7 @@ feature 'Issue prioritization', feature: true do
issue_4.labels << label_4 # 7
issue_6.labels << label_5 # 8 - No priority
- login_as user
+ gitlab_sign_in user
visit namespace_project_issues_path(project.namespace, project, sort: 'label_priority')
expect(page).to have_selector('.dropdown-toggle', text: 'Label priority')
diff --git a/spec/features/projects/labels/subscription_spec.rb b/spec/features/projects/labels/subscription_spec.rb
index 3130d87fba5..584dc294f05 100644
--- a/spec/features/projects/labels/subscription_spec.rb
+++ b/spec/features/projects/labels/subscription_spec.rb
@@ -10,7 +10,7 @@ feature 'Labels subscription', feature: true do
context 'when signed in' do
before do
project.team << [user, :developer]
- login_as user
+ gitlab_sign_in user
end
scenario 'users can subscribe/unsubscribe to labels', js: true do
diff --git a/spec/features/projects/labels/update_prioritization_spec.rb b/spec/features/projects/labels/update_prioritization_spec.rb
index 34fafe072a3..589bfb9fbc9 100644
--- a/spec/features/projects/labels/update_prioritization_spec.rb
+++ b/spec/features/projects/labels/update_prioritization_spec.rb
@@ -14,7 +14,7 @@ feature 'Prioritize labels', feature: true do
before do
project.team << [user, :developer]
- login_as user
+ gitlab_sign_in user
end
scenario 'user can prioritize a group label', js: true do
@@ -120,7 +120,7 @@ feature 'Prioritize labels', feature: true do
it 'does not prioritize labels' do
guest = create(:user)
- login_as guest
+ gitlab_sign_in guest
visit namespace_project_labels_path(project.namespace, project)
diff --git a/spec/features/projects/main/download_buttons_spec.rb b/spec/features/projects/main/download_buttons_spec.rb
index 02198ff3e41..514453db472 100644
--- a/spec/features/projects/main/download_buttons_spec.rb
+++ b/spec/features/projects/main/download_buttons_spec.rb
@@ -22,7 +22,7 @@ feature 'Download buttons in project main page', feature: true do
end
background do
- login_as(user)
+ gitlab_sign_in(user)
project.team << [user, role]
end
diff --git a/spec/features/projects/main/rss_spec.rb b/spec/features/projects/main/rss_spec.rb
index 53966229a2a..fee8cfe2c33 100644
--- a/spec/features/projects/main/rss_spec.rb
+++ b/spec/features/projects/main/rss_spec.rb
@@ -8,7 +8,7 @@ feature 'Project RSS' do
before do
user = create(:user)
project.team << [user, :developer]
- login_as(user)
+ gitlab_sign_in(user)
visit path
end
diff --git a/spec/features/projects/members/group_links_spec.rb b/spec/features/projects/members/group_links_spec.rb
index 3d253f01484..00d2a27597b 100644
--- a/spec/features/projects/members/group_links_spec.rb
+++ b/spec/features/projects/members/group_links_spec.rb
@@ -9,7 +9,7 @@ feature 'Projects > Members > Anonymous user sees members', feature: true, js: t
project.team << [user, :master]
@group_link = create(:project_group_link, project: project, group: group)
- login_as(user)
+ gitlab_sign_in(user)
visit namespace_project_settings_members_path(project.namespace, project)
end
diff --git a/spec/features/projects/members/group_member_cannot_leave_group_project_spec.rb b/spec/features/projects/members/group_member_cannot_leave_group_project_spec.rb
index b483ba4c54c..7e71dbc24c0 100644
--- a/spec/features/projects/members/group_member_cannot_leave_group_project_spec.rb
+++ b/spec/features/projects/members/group_member_cannot_leave_group_project_spec.rb
@@ -7,7 +7,7 @@ feature 'Projects > Members > Group member cannot leave group project', feature:
background do
group.add_developer(user)
- login_as(user)
+ gitlab_sign_in(user)
visit namespace_project_path(project.namespace, project)
end
diff --git a/spec/features/projects/members/group_member_cannot_request_access_to_his_group_project_spec.rb b/spec/features/projects/members/group_member_cannot_request_access_to_his_group_project_spec.rb
index ff9b6007806..60a5cd9ec63 100644
--- a/spec/features/projects/members/group_member_cannot_request_access_to_his_group_project_spec.rb
+++ b/spec/features/projects/members/group_member_cannot_request_access_to_his_group_project_spec.rb
@@ -41,7 +41,7 @@ feature 'Projects > Members > Group member cannot request access to his group pr
end
def login_and_visit_project_page(user)
- login_as(user)
+ gitlab_sign_in(user)
visit namespace_project_path(project.namespace, project)
end
end
diff --git a/spec/features/projects/members/group_members_spec.rb b/spec/features/projects/members/group_members_spec.rb
index 3385e5972ff..76fe6a00dab 100644
--- a/spec/features/projects/members/group_members_spec.rb
+++ b/spec/features/projects/members/group_members_spec.rb
@@ -13,7 +13,7 @@ feature 'Projects members', feature: true do
background do
project.team << [developer, :developer]
group.add_owner(user)
- login_as(user)
+ gitlab_sign_in(user)
end
context 'with a group invitee' do
diff --git a/spec/features/projects/members/group_requester_cannot_request_access_to_project_spec.rb b/spec/features/projects/members/group_requester_cannot_request_access_to_project_spec.rb
index bdeeef57273..66da28b07fe 100644
--- a/spec/features/projects/members/group_requester_cannot_request_access_to_project_spec.rb
+++ b/spec/features/projects/members/group_requester_cannot_request_access_to_project_spec.rb
@@ -8,7 +8,7 @@ feature 'Projects > Members > Group requester cannot request access to project',
background do
group.add_owner(owner)
- login_as(user)
+ gitlab_sign_in(user)
visit group_path(group)
perform_enqueued_jobs { click_link 'Request Access' }
visit namespace_project_path(project.namespace, project)
diff --git a/spec/features/projects/members/list_spec.rb b/spec/features/projects/members/list_spec.rb
index deea34214fb..9fdd7df0ee5 100644
--- a/spec/features/projects/members/list_spec.rb
+++ b/spec/features/projects/members/list_spec.rb
@@ -9,7 +9,7 @@ feature 'Project members list', feature: true do
let(:project) { create(:project, namespace: group) }
background do
- login_as(user1)
+ gitlab_sign_in(user1)
group.add_owner(user1)
end
diff --git a/spec/features/projects/members/master_adds_member_with_expiration_date_spec.rb b/spec/features/projects/members/master_adds_member_with_expiration_date_spec.rb
index 1e6f15d8258..21b48b7fdd1 100644
--- a/spec/features/projects/members/master_adds_member_with_expiration_date_spec.rb
+++ b/spec/features/projects/members/master_adds_member_with_expiration_date_spec.rb
@@ -10,7 +10,7 @@ feature 'Projects > Members > Master adds member with expiration date', feature:
background do
project.team << [master, :master]
- login_as(master)
+ gitlab_sign_in(master)
end
scenario 'expiration date is displayed in the members list' do
diff --git a/spec/features/projects/members/master_manages_access_requests_spec.rb b/spec/features/projects/members/master_manages_access_requests_spec.rb
index 143390b71cd..bd445e27243 100644
--- a/spec/features/projects/members/master_manages_access_requests_spec.rb
+++ b/spec/features/projects/members/master_manages_access_requests_spec.rb
@@ -8,7 +8,7 @@ feature 'Projects > Members > Master manages access requests', feature: true do
background do
project.request_access(user)
project.team << [master, :master]
- login_as(master)
+ gitlab_sign_in(master)
end
scenario 'master can see access requests' do
diff --git a/spec/features/projects/members/member_cannot_request_access_to_his_project_spec.rb b/spec/features/projects/members/member_cannot_request_access_to_his_project_spec.rb
index 9564347e733..703f5dff6b5 100644
--- a/spec/features/projects/members/member_cannot_request_access_to_his_project_spec.rb
+++ b/spec/features/projects/members/member_cannot_request_access_to_his_project_spec.rb
@@ -6,7 +6,7 @@ feature 'Projects > Members > Member cannot request access to his project', feat
background do
project.team << [member, :developer]
- login_as(member)
+ gitlab_sign_in(member)
visit namespace_project_path(project.namespace, project)
end
diff --git a/spec/features/projects/members/member_leaves_project_spec.rb b/spec/features/projects/members/member_leaves_project_spec.rb
index 5daa932e4e6..8e1788f7f2a 100644
--- a/spec/features/projects/members/member_leaves_project_spec.rb
+++ b/spec/features/projects/members/member_leaves_project_spec.rb
@@ -6,7 +6,7 @@ feature 'Projects > Members > Member leaves project', feature: true do
background do
project.team << [user, :developer]
- login_as(user)
+ gitlab_sign_in(user)
visit namespace_project_path(project.namespace, project)
end
diff --git a/spec/features/projects/members/owner_cannot_leave_project_spec.rb b/spec/features/projects/members/owner_cannot_leave_project_spec.rb
index b26d55c5d5d..70e4bb19c0f 100644
--- a/spec/features/projects/members/owner_cannot_leave_project_spec.rb
+++ b/spec/features/projects/members/owner_cannot_leave_project_spec.rb
@@ -4,7 +4,7 @@ feature 'Projects > Members > Owner cannot leave project', feature: true do
let(:project) { create(:project) }
background do
- login_as(project.owner)
+ gitlab_sign_in(project.owner)
visit namespace_project_path(project.namespace, project)
end
diff --git a/spec/features/projects/members/owner_cannot_request_access_to_his_project_spec.rb b/spec/features/projects/members/owner_cannot_request_access_to_his_project_spec.rb
index 4ca9272b9c1..0cd7e3afeda 100644
--- a/spec/features/projects/members/owner_cannot_request_access_to_his_project_spec.rb
+++ b/spec/features/projects/members/owner_cannot_request_access_to_his_project_spec.rb
@@ -4,7 +4,7 @@ feature 'Projects > Members > Owner cannot request access to his project', featu
let(:project) { create(:project) }
background do
- login_as(project.owner)
+ gitlab_sign_in(project.owner)
visit namespace_project_path(project.namespace, project)
end
diff --git a/spec/features/projects/members/sorting_spec.rb b/spec/features/projects/members/sorting_spec.rb
index d428f6fcf22..66d98ef8b90 100644
--- a/spec/features/projects/members/sorting_spec.rb
+++ b/spec/features/projects/members/sorting_spec.rb
@@ -8,7 +8,7 @@ feature 'Projects > Members > Sorting', feature: true do
background do
create(:project_member, :developer, user: developer, project: project, created_at: 3.days.ago)
- login_as(master)
+ gitlab_sign_in(master)
end
scenario 'sorts alphabetically by default' do
diff --git a/spec/features/projects/members/user_requests_access_spec.rb b/spec/features/projects/members/user_requests_access_spec.rb
index ec48a4bd726..081009f2325 100644
--- a/spec/features/projects/members/user_requests_access_spec.rb
+++ b/spec/features/projects/members/user_requests_access_spec.rb
@@ -6,7 +6,7 @@ feature 'Projects > Members > User requests access', feature: true do
let(:master) { project.owner }
background do
- login_as(user)
+ gitlab_sign_in(user)
visit namespace_project_path(project.namespace, project)
end
diff --git a/spec/features/projects/merge_request_button_spec.rb b/spec/features/projects/merge_request_button_spec.rb
index 1370ab1c521..6de8855016d 100644
--- a/spec/features/projects/merge_request_button_spec.rb
+++ b/spec/features/projects/merge_request_button_spec.rb
@@ -18,7 +18,7 @@ feature 'Merge Request button', feature: true do
context 'logged in as developer' do
before do
- login_as(user)
+ gitlab_sign_in(user)
project.team << [user, :developer]
end
@@ -52,7 +52,7 @@ feature 'Merge Request button', feature: true do
context 'logged in as non-member' do
before do
- login_as(user)
+ gitlab_sign_in(user)
end
it 'does not show Create merge request button' do
diff --git a/spec/features/projects/merge_requests/list_spec.rb b/spec/features/projects/merge_requests/list_spec.rb
index 7e8a796c55d..f2a2fd0311f 100644
--- a/spec/features/projects/merge_requests/list_spec.rb
+++ b/spec/features/projects/merge_requests/list_spec.rb
@@ -7,7 +7,7 @@ feature 'Merge Requests List' do
background do
project.team << [user, :developer]
- login_as(user)
+ gitlab_sign_in(user)
end
scenario 'user does not see create new list button' do
diff --git a/spec/features/projects/milestones/milestone_spec.rb b/spec/features/projects/milestones/milestone_spec.rb
index b4fc0edbde8..a02e4118784 100644
--- a/spec/features/projects/milestones/milestone_spec.rb
+++ b/spec/features/projects/milestones/milestone_spec.rb
@@ -6,7 +6,7 @@ feature 'Project milestone', :feature do
let(:milestone) { create(:milestone, project: project) }
before do
- login_as(user)
+ gitlab_sign_in(user)
end
context 'when project has enabled issues' do
diff --git a/spec/features/projects/milestones/milestones_sorting_spec.rb b/spec/features/projects/milestones/milestones_sorting_spec.rb
index da3eaed707a..2350089255d 100644
--- a/spec/features/projects/milestones/milestones_sorting_spec.rb
+++ b/spec/features/projects/milestones/milestones_sorting_spec.rb
@@ -15,7 +15,7 @@ feature 'Milestones sorting', :feature, :js do
due_date: 11.days.from_now,
created_at: 1.hour.ago,
title: "bbb", project: project)
- login_as(user)
+ gitlab_sign_in(user)
end
scenario 'visit project milestones and sort by due_date_asc' do
diff --git a/spec/features/projects/milestones/new_spec.rb b/spec/features/projects/milestones/new_spec.rb
new file mode 100644
index 00000000000..7403822c7fb
--- /dev/null
+++ b/spec/features/projects/milestones/new_spec.rb
@@ -0,0 +1,18 @@
+require 'spec_helper'
+
+feature 'Creating a new project milestone', :feature, :js do
+ let(:user) { create(:user) }
+ let(:project) { create(:empty_project, name: 'test', namespace: user.namespace) }
+
+ before do
+ login_as(user)
+ visit new_namespace_project_milestone_path(project.namespace, project)
+ end
+
+ it 'description has autocomplete' do
+ find('#milestone_description').native.send_keys('')
+ fill_in 'milestone_description', with: '@'
+
+ expect(page).to have_selector('.atwho-view')
+ end
+end
diff --git a/spec/features/projects/new_project_spec.rb b/spec/features/projects/new_project_spec.rb
index b1f9eb15667..37d9a97033b 100644
--- a/spec/features/projects/new_project_spec.rb
+++ b/spec/features/projects/new_project_spec.rb
@@ -4,7 +4,7 @@ feature "New project", feature: true do
let(:user) { create(:admin) }
before do
- login_as(user)
+ gitlab_sign_in(user)
end
context "Visibility level selector" do
diff --git a/spec/features/projects/pages_spec.rb b/spec/features/projects/pages_spec.rb
index 11793c0f303..e9a3cfb7f60 100644
--- a/spec/features/projects/pages_spec.rb
+++ b/spec/features/projects/pages_spec.rb
@@ -10,7 +10,7 @@ feature 'Pages', feature: true do
project.team << [user, role]
- login_as(user)
+ gitlab_sign_in(user)
end
shared_examples 'no pages deployed' do
diff --git a/spec/features/projects/pipeline_schedules_spec.rb b/spec/features/projects/pipeline_schedules_spec.rb
index 2d43f7a10bc..dfb973c37e5 100644
--- a/spec/features/projects/pipeline_schedules_spec.rb
+++ b/spec/features/projects/pipeline_schedules_spec.rb
@@ -12,7 +12,7 @@ feature 'Pipeline Schedules', :feature do
before do
project.add_master(user)
- login_as(user)
+ gitlab_sign_in(user)
visit_page
end
diff --git a/spec/features/projects/pipelines/pipeline_spec.rb b/spec/features/projects/pipelines/pipeline_spec.rb
index 12c5ad45baf..e182995922d 100644
--- a/spec/features/projects/pipelines/pipeline_spec.rb
+++ b/spec/features/projects/pipelines/pipeline_spec.rb
@@ -7,7 +7,7 @@ describe 'Pipeline', :feature, :js do
let(:user) { create(:user) }
before do
- login_as(user)
+ gitlab_sign_in(user)
project.team << [user, :developer]
end
diff --git a/spec/features/projects/pipelines/pipelines_spec.rb b/spec/features/projects/pipelines/pipelines_spec.rb
index db2d1a100a5..d36d073e022 100644
--- a/spec/features/projects/pipelines/pipelines_spec.rb
+++ b/spec/features/projects/pipelines/pipelines_spec.rb
@@ -7,7 +7,7 @@ describe 'Pipelines', :feature, :js do
let(:user) { create(:user) }
before do
- login_as(user)
+ gitlab_sign_in(user)
project.team << [user, :developer]
end
diff --git a/spec/features/projects/project_settings_spec.rb b/spec/features/projects/project_settings_spec.rb
index 2a9b32ea07e..baa38ff8cca 100644
--- a/spec/features/projects/project_settings_spec.rb
+++ b/spec/features/projects/project_settings_spec.rb
@@ -7,7 +7,7 @@ describe 'Edit Project Settings', feature: true do
let(:project) { create(:empty_project, namespace: user.namespace, path: 'gitlab', name: 'sample') }
before do
- login_as(user)
+ gitlab_sign_in(user)
end
describe 'Project settings section', js: true do
diff --git a/spec/features/projects/ref_switcher_spec.rb b/spec/features/projects/ref_switcher_spec.rb
index 04414490571..016a992bdcf 100644
--- a/spec/features/projects/ref_switcher_spec.rb
+++ b/spec/features/projects/ref_switcher_spec.rb
@@ -6,7 +6,7 @@ feature 'Ref switcher', feature: true, js: true do
before do
project.team << [user, :master]
- login_as(user)
+ gitlab_sign_in(user)
visit namespace_project_tree_path(project.namespace, project, 'master')
end
diff --git a/spec/features/projects/services/jira_service_spec.rb b/spec/features/projects/services/jira_service_spec.rb
index c96d87e5708..2ea50e8f672 100644
--- a/spec/features/projects/services/jira_service_spec.rb
+++ b/spec/features/projects/services/jira_service_spec.rb
@@ -20,7 +20,7 @@ feature 'Setup Jira service', :feature, :js do
before do
project.team << [user, :master]
- login_as(user)
+ gitlab_sign_in(user)
visit namespace_project_settings_integrations_path(project.namespace, project)
end
diff --git a/spec/features/projects/services/mattermost_slash_command_spec.rb b/spec/features/projects/services/mattermost_slash_command_spec.rb
index 1fe82222e59..d87985f1c92 100644
--- a/spec/features/projects/services/mattermost_slash_command_spec.rb
+++ b/spec/features/projects/services/mattermost_slash_command_spec.rb
@@ -9,7 +9,7 @@ feature 'Setup Mattermost slash commands', :feature, :js do
before do
stub_mattermost_setting(enabled: mattermost_enabled)
project.team << [user, :master]
- login_as(user)
+ gitlab_sign_in(user)
visit edit_namespace_project_service_path(project.namespace, project, service)
end
diff --git a/spec/features/projects/services/slack_service_spec.rb b/spec/features/projects/services/slack_service_spec.rb
index c0a4a1e4bf5..50707e6a49f 100644
--- a/spec/features/projects/services/slack_service_spec.rb
+++ b/spec/features/projects/services/slack_service_spec.rb
@@ -9,7 +9,7 @@ feature 'Projects > Slack service > Setup events', feature: true do
service.fields
service.update_attributes(push_channel: 1, issue_channel: 2, merge_request_channel: 3, note_channel: 4, tag_push_channel: 5, pipeline_channel: 6, wiki_page_channel: 7)
project.team << [user, :master]
- login_as(user)
+ gitlab_sign_in(user)
end
scenario 'user can filter events by channel' do
diff --git a/spec/features/projects/services/slack_slash_command_spec.rb b/spec/features/projects/services/slack_slash_command_spec.rb
index f53b820c460..3fae38c1799 100644
--- a/spec/features/projects/services/slack_slash_command_spec.rb
+++ b/spec/features/projects/services/slack_slash_command_spec.rb
@@ -7,7 +7,7 @@ feature 'Slack slash commands', feature: true do
background do
project.team << [user, :master]
- login_as(user)
+ gitlab_sign_in(user)
visit edit_namespace_project_service_path(project.namespace, project, service)
end
diff --git a/spec/features/projects/settings/integration_settings_spec.rb b/spec/features/projects/settings/integration_settings_spec.rb
index fbaea14a2be..a59374b37ea 100644
--- a/spec/features/projects/settings/integration_settings_spec.rb
+++ b/spec/features/projects/settings/integration_settings_spec.rb
@@ -7,7 +7,7 @@ feature 'Integration settings', feature: true do
let(:integrations_path) { namespace_project_settings_integrations_path(project.namespace, project) }
background do
- login_as(user)
+ gitlab_sign_in(user)
project.team << [user, role]
end
diff --git a/spec/features/projects/settings/merge_requests_settings_spec.rb b/spec/features/projects/settings/merge_requests_settings_spec.rb
index 321af416c91..f2af14ceab2 100644
--- a/spec/features/projects/settings/merge_requests_settings_spec.rb
+++ b/spec/features/projects/settings/merge_requests_settings_spec.rb
@@ -8,7 +8,7 @@ feature 'Project settings > Merge Requests', feature: true, js: true do
background do
project.team << [user, :master]
- login_as(user)
+ gitlab_sign_in(user)
end
context 'when Merge Request and Pipelines are initially enabled' do
diff --git a/spec/features/projects/settings/pipelines_settings_spec.rb b/spec/features/projects/settings/pipelines_settings_spec.rb
index 035c57eaa47..c33fbd49d21 100644
--- a/spec/features/projects/settings/pipelines_settings_spec.rb
+++ b/spec/features/projects/settings/pipelines_settings_spec.rb
@@ -8,7 +8,7 @@ feature "Pipelines settings", feature: true do
let(:role) { :developer }
background do
- login_as(user)
+ gitlab_sign_in(user)
project.team << [user, role]
visit namespace_project_pipelines_settings_path(project.namespace, project)
end
diff --git a/spec/features/projects/settings/repository_settings_spec.rb b/spec/features/projects/settings/repository_settings_spec.rb
index 4cc38c5286e..35cd0d6e832 100644
--- a/spec/features/projects/settings/repository_settings_spec.rb
+++ b/spec/features/projects/settings/repository_settings_spec.rb
@@ -7,7 +7,7 @@ feature 'Repository settings', feature: true do
background do
project.team << [user, role]
- login_as(user)
+ gitlab_sign_in(user)
end
context 'for developer' do
@@ -65,6 +65,23 @@ feature 'Repository settings', feature: true do
expect(page).to have_content('Write access allowed')
end
+ scenario 'edit a deploy key from projects user has access to' do
+ project2 = create(:project_empty_repo)
+ project2.team << [user, role]
+ project2.deploy_keys << private_deploy_key
+
+ visit namespace_project_settings_repository_path(project.namespace, project)
+
+ find('li', text: private_deploy_key.title).click_link('Edit')
+
+ fill_in 'deploy_key_title', with: 'updated_deploy_key'
+ check 'deploy_key_can_push'
+ click_button 'Save changes'
+
+ expect(page).to have_content('updated_deploy_key')
+ expect(page).to have_content('Write access allowed')
+ end
+
scenario 'remove an existing deploy key' do
project.deploy_keys << private_deploy_key
visit namespace_project_settings_repository_path(project.namespace, project)
diff --git a/spec/features/projects/settings/visibility_settings_spec.rb b/spec/features/projects/settings/visibility_settings_spec.rb
index fac4506bdf6..18c71dee41b 100644
--- a/spec/features/projects/settings/visibility_settings_spec.rb
+++ b/spec/features/projects/settings/visibility_settings_spec.rb
@@ -6,7 +6,7 @@ feature 'Visibility settings', feature: true, js: true do
context 'as owner' do
before do
- login_as(user)
+ gitlab_sign_in(user)
visit edit_namespace_project_path(project.namespace, project)
end
@@ -32,7 +32,7 @@ feature 'Visibility settings', feature: true, js: true do
before do
project.team << [master_user, :master]
- login_as(master_user)
+ gitlab_sign_in(master_user)
visit edit_namespace_project_path(project.namespace, project)
end
diff --git a/spec/features/projects/shortcuts_spec.rb b/spec/features/projects/shortcuts_spec.rb
index 54aa9c66a08..cec79277c33 100644
--- a/spec/features/projects/shortcuts_spec.rb
+++ b/spec/features/projects/shortcuts_spec.rb
@@ -7,7 +7,7 @@ feature 'Project shortcuts', feature: true do
describe 'On a project', js: true do
before do
project.team << [user, :master]
- login_as user
+ gitlab_sign_in user
visit namespace_project_path(project.namespace, project)
end
diff --git a/spec/features/projects/snippets/create_snippet_spec.rb b/spec/features/projects/snippets/create_snippet_spec.rb
index 5ac1ca45c74..c75d6dbc307 100644
--- a/spec/features/projects/snippets/create_snippet_spec.rb
+++ b/spec/features/projects/snippets/create_snippet_spec.rb
@@ -17,7 +17,7 @@ feature 'Create Snippet', :js, feature: true do
context 'when a user is authenticated' do
before do
project.team << [user, :master]
- login_as(user)
+ gitlab_sign_in(user)
visit namespace_project_snippets_path(project.namespace, project)
diff --git a/spec/features/projects/snippets/show_spec.rb b/spec/features/projects/snippets/show_spec.rb
index b844e60e5d5..9e73ba4123b 100644
--- a/spec/features/projects/snippets/show_spec.rb
+++ b/spec/features/projects/snippets/show_spec.rb
@@ -7,7 +7,7 @@ feature 'Project snippet', :js, feature: true do
before do
project.team << [user, :master]
- login_as(user)
+ gitlab_sign_in(user)
end
context 'Ruby file' do
diff --git a/spec/features/projects/snippets_spec.rb b/spec/features/projects/snippets_spec.rb
index 18689c17fe9..80dbffaffc7 100644
--- a/spec/features/projects/snippets_spec.rb
+++ b/spec/features/projects/snippets_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe 'Project snippets', feature: true do
+describe 'Project snippets', :js, feature: true do
context 'when the project has snippets' do
let(:project) { create(:empty_project, :public) }
let!(:snippets) { create_list(:project_snippet, 2, :public, author: project.owner, project: project) }
@@ -26,5 +26,19 @@ describe 'Project snippets', feature: true do
expect(page).to have_content(snippets[1].title)
end
end
+
+ context 'when submitting a note' do
+ before do
+ gitlab_sign_in :admin
+ visit namespace_project_snippet_path(project.namespace, project, snippets[0])
+ end
+
+ it 'should have autocomplete' do
+ find('#note_note').native.send_keys('')
+ fill_in 'note[note]', with: '@'
+
+ expect(page).to have_selector('.atwho-view')
+ end
+ end
end
end
diff --git a/spec/features/projects/sub_group_issuables_spec.rb b/spec/features/projects/sub_group_issuables_spec.rb
index e88907b8016..63eb97d5a92 100644
--- a/spec/features/projects/sub_group_issuables_spec.rb
+++ b/spec/features/projects/sub_group_issuables_spec.rb
@@ -8,7 +8,7 @@ describe 'Subgroup Issuables', :feature, :js, :nested_groups do
before do
project.add_master(user)
- login_as user
+ gitlab_sign_in user
end
it 'shows the full subgroup title when issues index page is empty' do
diff --git a/spec/features/projects/tags/download_buttons_spec.rb b/spec/features/projects/tags/download_buttons_spec.rb
index dd93d25c2c6..ca00a51aa3c 100644
--- a/spec/features/projects/tags/download_buttons_spec.rb
+++ b/spec/features/projects/tags/download_buttons_spec.rb
@@ -23,7 +23,7 @@ feature 'Download buttons in tags page', feature: true do
end
background do
- login_as(user)
+ gitlab_sign_in(user)
project.team << [user, role]
end
diff --git a/spec/features/projects/tree/rss_spec.rb b/spec/features/projects/tree/rss_spec.rb
index 9bf59c4139c..135584e5bf8 100644
--- a/spec/features/projects/tree/rss_spec.rb
+++ b/spec/features/projects/tree/rss_spec.rb
@@ -8,7 +8,7 @@ feature 'Project Tree RSS' do
before do
user = create(:user)
project.team << [user, :developer]
- login_as(user)
+ gitlab_sign_in(user)
visit path
end
diff --git a/spec/features/projects/user_create_dir_spec.rb b/spec/features/projects/user_create_dir_spec.rb
index aeb7e0b7c33..f375e1215db 100644
--- a/spec/features/projects/user_create_dir_spec.rb
+++ b/spec/features/projects/user_create_dir_spec.rb
@@ -6,7 +6,7 @@ feature 'New directory creation', feature: true, js: true do
given(:project) { create(:project) }
background do
- login_as(user)
+ gitlab_sign_in(user)
project.team << [user, role]
visit namespace_project_tree_path(project.namespace, project, 'master')
open_new_directory_modal
diff --git a/spec/features/projects/user_creates_project_spec.rb b/spec/features/projects/user_creates_project_spec.rb
new file mode 100644
index 00000000000..29f1eb8d73e
--- /dev/null
+++ b/spec/features/projects/user_creates_project_spec.rb
@@ -0,0 +1,27 @@
+require 'spec_helper'
+
+feature 'User creates a project', js: true do
+ let(:user) { create(:user) }
+
+ before do
+ sign_in(user)
+ create(:personal_key, user: user)
+ visit(new_project_path)
+ end
+
+ it 'creates a new project' do
+ fill_in(:project_path, with: 'Empty')
+
+ page.within('#content-body') do
+ click_button('Create project')
+ end
+
+ project = Project.last
+
+ expect(current_path).to eq(namespace_project_path(project.namespace, project))
+ expect(page).to have_content('Empty')
+ expect(page).to have_content('git init')
+ expect(page).to have_content('git remote')
+ expect(page).to have_content(project.url_to_repo)
+ end
+end
diff --git a/spec/features/projects/view_on_env_spec.rb b/spec/features/projects/view_on_env_spec.rb
index 640f1376548..f6a640b90b4 100644
--- a/spec/features/projects/view_on_env_spec.rb
+++ b/spec/features/projects/view_on_env_spec.rb
@@ -50,7 +50,7 @@ describe 'View on environment', js: true do
let(:merge_request) { create(:merge_request, :simple, source_project: project, source_branch: branch_name) }
before do
- login_as(user)
+ gitlab_sign_in(user)
visit diffs_namespace_project_merge_request_path(project.namespace, project, merge_request)
@@ -66,7 +66,7 @@ describe 'View on environment', js: true do
context 'when visiting a comparison for the branch' do
before do
- login_as(user)
+ gitlab_sign_in(user)
visit namespace_project_compare_path(project.namespace, project, from: 'master', to: branch_name)
@@ -80,7 +80,7 @@ describe 'View on environment', js: true do
context 'when visiting a comparison for the commit' do
before do
- login_as(user)
+ gitlab_sign_in(user)
visit namespace_project_compare_path(project.namespace, project, from: 'master', to: sha)
@@ -94,7 +94,7 @@ describe 'View on environment', js: true do
context 'when visiting a blob on the branch' do
before do
- login_as(user)
+ gitlab_sign_in(user)
visit namespace_project_blob_path(project.namespace, project, File.join(branch_name, file_path))
@@ -108,7 +108,7 @@ describe 'View on environment', js: true do
context 'when visiting a blob on the commit' do
before do
- login_as(user)
+ gitlab_sign_in(user)
visit namespace_project_blob_path(project.namespace, project, File.join(sha, file_path))
@@ -122,7 +122,7 @@ describe 'View on environment', js: true do
context 'when visiting the commit' do
before do
- login_as(user)
+ gitlab_sign_in(user)
visit namespace_project_commit_path(project.namespace, project, sha)
diff --git a/spec/features/projects/wiki/markdown_preview_spec.rb b/spec/features/projects/wiki/markdown_preview_spec.rb
index 94f6bb16730..fd6c09943e3 100644
--- a/spec/features/projects/wiki/markdown_preview_spec.rb
+++ b/spec/features/projects/wiki/markdown_preview_spec.rb
@@ -16,7 +16,7 @@ feature 'Projects > Wiki > User previews markdown changes', feature: true, js: t
project.team << [user, :master]
WikiPages::CreateService.new(project, user, title: 'home', content: 'Home page').execute
- login_as(user)
+ gitlab_sign_in(user)
visit namespace_project_path(project.namespace, project)
find('.shortcuts-wiki').trigger('click')
diff --git a/spec/features/projects/wiki/shortcuts_spec.rb b/spec/features/projects/wiki/shortcuts_spec.rb
index c1f6b0cce3b..ab0ed9b8204 100644
--- a/spec/features/projects/wiki/shortcuts_spec.rb
+++ b/spec/features/projects/wiki/shortcuts_spec.rb
@@ -8,7 +8,7 @@ feature 'Wiki shortcuts', :feature, :js do
end
before do
- login_as(user)
+ gitlab_sign_in(user)
visit namespace_project_wiki_path(project.namespace, project, wiki_page)
end
diff --git a/spec/features/projects/wiki/user_creates_wiki_page_spec.rb b/spec/features/projects/wiki/user_creates_wiki_page_spec.rb
index 8912d575878..a477dcf7ee9 100644
--- a/spec/features/projects/wiki/user_creates_wiki_page_spec.rb
+++ b/spec/features/projects/wiki/user_creates_wiki_page_spec.rb
@@ -5,7 +5,7 @@ feature 'Projects > Wiki > User creates wiki page', js: true, feature: true do
background do
project.team << [user, :master]
- login_as(user)
+ gitlab_sign_in(user)
visit namespace_project_path(project.namespace, project)
find('.shortcuts-wiki').trigger('click')
@@ -133,6 +133,22 @@ feature 'Projects > Wiki > User creates wiki page', js: true, feature: true do
expect(page).to have_content('My awesome wiki!')
end
end
+
+ scenario 'content has autocomplete', :js do
+ click_link 'New page'
+
+ page.within '#modal-new-wiki' do
+ fill_in :new_wiki_path, with: 'test-autocomplete'
+ click_button 'Create page'
+ end
+
+ page.within '.wiki-form' do
+ find('#wiki_content').native.send_keys('')
+ fill_in :wiki_content, with: '@'
+ end
+
+ expect(page).to have_selector('.atwho-view')
+ end
end
end
diff --git a/spec/features/projects/wiki/user_git_access_wiki_page_spec.rb b/spec/features/projects/wiki/user_git_access_wiki_page_spec.rb
index 95826e7e5be..7d31122af35 100644
--- a/spec/features/projects/wiki/user_git_access_wiki_page_spec.rb
+++ b/spec/features/projects/wiki/user_git_access_wiki_page_spec.rb
@@ -13,7 +13,7 @@ describe 'Projects > Wiki > User views Git access wiki page', :feature do
end
before do
- login_as(user)
+ gitlab_sign_in(user)
end
scenario 'Visit Wiki Page Current Commit' do
diff --git a/spec/features/projects/wiki/user_updates_wiki_page_spec.rb b/spec/features/projects/wiki/user_updates_wiki_page_spec.rb
index 86cf520ea80..64a30438681 100644
--- a/spec/features/projects/wiki/user_updates_wiki_page_spec.rb
+++ b/spec/features/projects/wiki/user_updates_wiki_page_spec.rb
@@ -5,11 +5,10 @@ feature 'Projects > Wiki > User updates wiki page', feature: true do
background do
project.team << [user, :master]
- login_as(user)
-
- visit namespace_project_path(project.namespace, project)
WikiPages::CreateService.new(project, user, title: 'home', content: 'Home page').execute
- click_link 'Wiki'
+ gitlab_sign_in(user)
+
+ visit namespace_project_wikis_path(project.namespace, project)
end
context 'in the user namespace' do
@@ -42,6 +41,15 @@ feature 'Projects > Wiki > User updates wiki page', feature: true do
expect(page).to have_content('Content can\'t be blank')
expect(find('textarea#wiki_content').value).to eq ''
end
+
+ scenario 'content has autocomplete', :js do
+ click_link 'Edit'
+
+ find('#wiki_content').native.send_keys('')
+ fill_in :wiki_content, with: '@'
+
+ expect(page).to have_selector('.atwho-view')
+ end
end
end
diff --git a/spec/features/projects/wiki/user_views_project_wiki_page_spec.rb b/spec/features/projects/wiki/user_views_project_wiki_page_spec.rb
index c17e06612de..8a88ab247f3 100644
--- a/spec/features/projects/wiki/user_views_project_wiki_page_spec.rb
+++ b/spec/features/projects/wiki/user_views_project_wiki_page_spec.rb
@@ -15,7 +15,7 @@ feature 'Projects > Wiki > User views the wiki page', feature: true do
background do
project.team << [user, :master]
- login_as(user)
+ gitlab_sign_in(user)
WikiPages::UpdateService.new(
project,
user,
diff --git a/spec/features/projects/wiki/user_views_wiki_in_project_page_spec.rb b/spec/features/projects/wiki/user_views_wiki_in_project_page_spec.rb
index 20219f3cc9a..36799925167 100644
--- a/spec/features/projects/wiki/user_views_wiki_in_project_page_spec.rb
+++ b/spec/features/projects/wiki/user_views_wiki_in_project_page_spec.rb
@@ -5,7 +5,7 @@ describe 'Projects > Wiki > User views wiki in project page', feature: true do
before do
project.team << [user, :master]
- login_as(user)
+ gitlab_sign_in(user)
end
context 'when repository is disabled for project' do
diff --git a/spec/features/projects_spec.rb b/spec/features/projects_spec.rb
index 060e19596ae..7e8a703db93 100644
--- a/spec/features/projects_spec.rb
+++ b/spec/features/projects_spec.rb
@@ -6,7 +6,7 @@ feature 'Project', feature: true do
let(:path) { namespace_project_path(project.namespace, project) }
before do
- login_as(:admin)
+ gitlab_sign_in(:admin)
end
it 'parses Markdown' do
@@ -39,7 +39,7 @@ feature 'Project', feature: true do
let(:project) { create(:empty_project, namespace: user.namespace) }
before do
- login_with user
+ gitlab_sign_in user
create(:forked_project_link, forked_to_project: project)
visit edit_namespace_project_path(project.namespace, project)
end
@@ -60,7 +60,7 @@ feature 'Project', feature: true do
let(:project) { create(:empty_project, namespace: user.namespace, name: 'project1') }
before do
- login_with(user)
+ gitlab_sign_in(user)
project.team << [user, :master]
visit edit_namespace_project_path(project.namespace, project)
end
@@ -79,7 +79,7 @@ feature 'Project', feature: true do
let(:project) { create(:empty_project, namespace: user.namespace) }
before do
- login_with(user)
+ gitlab_sign_in(user)
project.add_user(user, Gitlab::Access::MASTER)
visit namespace_project_path(project.namespace, project)
end
@@ -98,7 +98,7 @@ feature 'Project', feature: true do
context 'on issues page', js: true do
before do
- login_with(user)
+ gitlab_sign_in(user)
project.add_user(user, Gitlab::Access::MASTER)
project2.add_user(user, Gitlab::Access::MASTER)
visit namespace_project_issue_path(project.namespace, project, issue)
@@ -123,7 +123,7 @@ feature 'Project', feature: true do
before do
project.team << [user, :master]
- login_as user
+ gitlab_sign_in user
visit namespace_project_path(project.namespace, project)
end
diff --git a/spec/features/protected_branches_spec.rb b/spec/features/protected_branches_spec.rb
index aa9164dd979..20b8e10f0f7 100644
--- a/spec/features/protected_branches_spec.rb
+++ b/spec/features/protected_branches_spec.rb
@@ -5,7 +5,7 @@ feature 'Protected Branches', feature: true, js: true do
let(:project) { create(:project, :repository) }
before do
- login_as(user)
+ gitlab_sign_in(user)
end
def set_protected_branch_name(branch_name)
diff --git a/spec/features/protected_tags_spec.rb b/spec/features/protected_tags_spec.rb
index 63a20585776..73a80692154 100644
--- a/spec/features/protected_tags_spec.rb
+++ b/spec/features/protected_tags_spec.rb
@@ -5,7 +5,7 @@ feature 'Projected Tags', feature: true, js: true do
let(:project) { create(:project, :repository) }
before do
- login_as(user)
+ gitlab_sign_in(user)
end
def set_protected_tag_name(tag_name)
diff --git a/spec/features/reportable_note/commit_spec.rb b/spec/features/reportable_note/commit_spec.rb
index 39b1c4acf52..12049822753 100644
--- a/spec/features/reportable_note/commit_spec.rb
+++ b/spec/features/reportable_note/commit_spec.rb
@@ -8,7 +8,7 @@ describe 'Reportable note on commit', :feature, :js do
before do
project.add_master(user)
- login_as user
+ gitlab_sign_in(user)
end
context 'a normal note' do
diff --git a/spec/features/reportable_note/issue_spec.rb b/spec/features/reportable_note/issue_spec.rb
index 5f526818994..ca2a7f41496 100644
--- a/spec/features/reportable_note/issue_spec.rb
+++ b/spec/features/reportable_note/issue_spec.rb
@@ -8,7 +8,7 @@ describe 'Reportable note on issue', :feature, :js do
before do
project.add_master(user)
- login_as user
+ gitlab_sign_in(user)
visit namespace_project_issue_path(project.namespace, project, issue)
end
diff --git a/spec/features/reportable_note/merge_request_spec.rb b/spec/features/reportable_note/merge_request_spec.rb
index 6d053d26626..8e75b4af3eb 100644
--- a/spec/features/reportable_note/merge_request_spec.rb
+++ b/spec/features/reportable_note/merge_request_spec.rb
@@ -7,7 +7,7 @@ describe 'Reportable note on merge request', :feature, :js do
before do
project.add_master(user)
- login_as user
+ gitlab_sign_in(user)
visit namespace_project_merge_request_path(project.namespace, project, merge_request)
end
diff --git a/spec/features/reportable_note/snippets_spec.rb b/spec/features/reportable_note/snippets_spec.rb
index 3f1e0cf9097..5bee4a31379 100644
--- a/spec/features/reportable_note/snippets_spec.rb
+++ b/spec/features/reportable_note/snippets_spec.rb
@@ -6,7 +6,7 @@ describe 'Reportable note on snippets', :feature, :js do
before do
project.add_master(user)
- login_as user
+ gitlab_sign_in(user)
end
describe 'on project snippet' do
@@ -19,15 +19,4 @@ describe 'Reportable note on snippets', :feature, :js do
it_behaves_like 'reportable note'
end
-
- describe 'on personal snippet' do
- let(:snippet) { create(:personal_snippet, :public, author: user) }
- let!(:note) { create(:note_on_personal_snippet, noteable: snippet, author: user) }
-
- before do
- visit snippet_path(snippet)
- end
-
- it_behaves_like 'reportable note'
- end
end
diff --git a/spec/features/runners_spec.rb b/spec/features/runners_spec.rb
index e87d52f5c8f..ea18879b4bf 100644
--- a/spec/features/runners_spec.rb
+++ b/spec/features/runners_spec.rb
@@ -6,7 +6,7 @@ describe "Runners" do
let(:user) { create(:user) }
before do
- login_as(user)
+ gitlab_sign_in(user)
end
describe "specific runners" do
diff --git a/spec/features/search_spec.rb b/spec/features/search_spec.rb
index 89d4f536b20..64469f999af 100644
--- a/spec/features/search_spec.rb
+++ b/spec/features/search_spec.rb
@@ -9,7 +9,7 @@ describe "Search", feature: true do
let!(:issue2) { create(:issue, project: project, author: user) }
before do
- login_with(user)
+ gitlab_sign_in(user)
project.team << [user, :reporter]
visit search_path
end
diff --git a/spec/features/snippets/create_snippet_spec.rb b/spec/features/snippets/create_snippet_spec.rb
index ddd31ede064..ac5c14ed427 100644
--- a/spec/features/snippets/create_snippet_spec.rb
+++ b/spec/features/snippets/create_snippet_spec.rb
@@ -4,7 +4,7 @@ feature 'Create Snippet', :js, feature: true do
include DropzoneHelper
before do
- login_as :user
+ gitlab_sign_in :user
visit new_snippet_path
end
diff --git a/spec/features/snippets/edit_snippet_spec.rb b/spec/features/snippets/edit_snippet_spec.rb
index 89ae593db88..860e1b156d6 100644
--- a/spec/features/snippets/edit_snippet_spec.rb
+++ b/spec/features/snippets/edit_snippet_spec.rb
@@ -10,7 +10,7 @@ feature 'Edit Snippet', :js, feature: true do
let(:snippet) { create(:personal_snippet, :public, file_name: file_name, content: content, author: user) }
before do
- login_as(user)
+ gitlab_sign_in(user)
visit edit_snippet_path(snippet)
wait_for_requests
diff --git a/spec/features/snippets/explore_spec.rb b/spec/features/snippets/explore_spec.rb
index fd097fe2e74..ec75817b942 100644
--- a/spec/features/snippets/explore_spec.rb
+++ b/spec/features/snippets/explore_spec.rb
@@ -6,7 +6,7 @@ feature 'Explore Snippets', feature: true do
let!(:private_snippet) { create(:personal_snippet, :private) }
scenario 'User should see snippets that are not private' do
- login_as create(:user)
+ gitlab_sign_in create(:user)
visit explore_snippets_path
expect(page).to have_content(public_snippet.title)
@@ -15,7 +15,7 @@ feature 'Explore Snippets', feature: true do
end
scenario 'External user should see only public snippets' do
- login_as create(:user, :external)
+ gitlab_sign_in create(:user, :external)
visit explore_snippets_path
expect(page).to have_content(public_snippet.title)
diff --git a/spec/features/snippets/internal_snippet_spec.rb b/spec/features/snippets/internal_snippet_spec.rb
index 93382f4c359..3babb1c02cc 100644
--- a/spec/features/snippets/internal_snippet_spec.rb
+++ b/spec/features/snippets/internal_snippet_spec.rb
@@ -5,7 +5,7 @@ feature 'Internal Snippets', feature: true, js: true do
describe 'normal user' do
before do
- login_as :user
+ gitlab_sign_in :user
end
scenario 'sees internal snippets' do
diff --git a/spec/features/snippets/notes_on_personal_snippets_spec.rb b/spec/features/snippets/notes_on_personal_snippets_spec.rb
index 44b0c89fac7..d310e7501ec 100644
--- a/spec/features/snippets/notes_on_personal_snippets_spec.rb
+++ b/spec/features/snippets/notes_on_personal_snippets_spec.rb
@@ -14,7 +14,7 @@ describe 'Comments on personal snippets', :js, feature: true do
let!(:other_note) { create(:note_on_personal_snippet) }
before do
- login_as user
+ gitlab_sign_in user
visit snippet_path(snippet)
end
@@ -46,8 +46,8 @@ describe 'Comments on personal snippets', :js, feature: true do
context 'when submitting a note' do
it 'shows a valid form' do
is_expected.to have_css('.js-main-target-form', visible: true, count: 1)
- expect(find('.js-main-target-form .js-comment-button').value).
- to eq('Comment')
+ expect(find('.js-main-target-form .js-comment-button').value)
+ .to eq('Comment')
page.within('.js-main-target-form') do
expect(page).not_to have_link('Cancel')
@@ -70,6 +70,22 @@ describe 'Comments on personal snippets', :js, feature: true do
expect(find('div#notes')).to have_content('This is awesome!')
end
+
+ it 'should not have autocomplete' do
+ wait_for_requests
+ request_count_before = page.driver.network_traffic.count
+
+ find('#note_note').native.send_keys('')
+ fill_in 'note[note]', with: '@'
+
+ wait_for_requests
+ request_count_after = page.driver.network_traffic.count
+
+ # This selector probably won't be in place even if autocomplete was enabled
+ # but we want to make sure
+ expect(page).not_to have_selector('.atwho-view')
+ expect(request_count_before).to eq(request_count_after)
+ end
end
context 'when editing a note' do
diff --git a/spec/features/snippets/search_snippets_spec.rb b/spec/features/snippets/search_snippets_spec.rb
index 146cd3af848..4c21e7321f4 100644
--- a/spec/features/snippets/search_snippets_spec.rb
+++ b/spec/features/snippets/search_snippets_spec.rb
@@ -5,7 +5,7 @@ feature 'Search Snippets', feature: true do
public_snippet = create(:personal_snippet, :public, title: 'Beginning and Middle')
private_snippet = create(:personal_snippet, :private, title: 'Middle and End')
- login_as private_snippet.author
+ gitlab_sign_in private_snippet.author
visit dashboard_snippets_path
page.within '.search' do
@@ -41,7 +41,7 @@ feature 'Search Snippets', feature: true do
CONTENT
)
- login_as create(:user)
+ gitlab_sign_in create(:user)
visit dashboard_snippets_path
page.within '.search' do
diff --git a/spec/features/snippets/user_snippets_spec.rb b/spec/features/snippets/user_snippets_spec.rb
index 191c2fb9a22..b971c6aab53 100644
--- a/spec/features/snippets/user_snippets_spec.rb
+++ b/spec/features/snippets/user_snippets_spec.rb
@@ -7,7 +7,7 @@ feature 'User Snippets', feature: true do
let!(:private_snippet) { create(:personal_snippet, :private, author: author, title: "This is a private snippet") }
background do
- login_as author
+ gitlab_sign_in author
visit dashboard_snippets_path
end
diff --git a/spec/features/tags/master_creates_tag_spec.rb b/spec/features/tags/master_creates_tag_spec.rb
index af25eebed13..52db3583dac 100644
--- a/spec/features/tags/master_creates_tag_spec.rb
+++ b/spec/features/tags/master_creates_tag_spec.rb
@@ -6,62 +6,80 @@ feature 'Master creates tag', feature: true do
before do
project.team << [user, :master]
- login_with(user)
- visit namespace_project_tags_path(project.namespace, project)
+ gitlab_sign_in(user)
end
- scenario 'with an invalid name displays an error' do
- create_tag_in_form(tag: 'v 1.0', ref: 'master')
+ context 'from tag list' do
+ before do
+ visit namespace_project_tags_path(project.namespace, project)
+ end
- expect(page).to have_content 'Tag name invalid'
- end
+ scenario 'with an invalid name displays an error' do
+ create_tag_in_form(tag: 'v 1.0', ref: 'master')
- scenario 'with an invalid reference displays an error' do
- create_tag_in_form(tag: 'v2.0', ref: 'foo')
+ expect(page).to have_content 'Tag name invalid'
+ end
- expect(page).to have_content 'Target foo is invalid'
- end
+ scenario 'with an invalid reference displays an error' do
+ create_tag_in_form(tag: 'v2.0', ref: 'foo')
- scenario 'that already exists displays an error' do
- create_tag_in_form(tag: 'v1.1.0', ref: 'master')
+ expect(page).to have_content 'Target foo is invalid'
+ end
- expect(page).to have_content 'Tag v1.1.0 already exists'
- end
+ scenario 'that already exists displays an error' do
+ create_tag_in_form(tag: 'v1.1.0', ref: 'master')
+
+ expect(page).to have_content 'Tag v1.1.0 already exists'
+ end
- scenario 'with multiline message displays the message in a <pre> block' do
- create_tag_in_form(tag: 'v3.0', ref: 'master', message: "Awesome tag message\n\n- hello\n- world")
+ scenario 'with multiline message displays the message in a <pre> block' do
+ create_tag_in_form(tag: 'v3.0', ref: 'master', message: "Awesome tag message\n\n- hello\n- world")
- expect(current_path).to eq(
- namespace_project_tag_path(project.namespace, project, 'v3.0'))
- expect(page).to have_content 'v3.0'
- page.within 'pre.wrap' do
- expect(page).to have_content "Awesome tag message\n\n- hello\n- world"
+ expect(current_path).to eq(
+ namespace_project_tag_path(project.namespace, project, 'v3.0'))
+ expect(page).to have_content 'v3.0'
+ page.within 'pre.wrap' do
+ expect(page).to have_content "Awesome tag message\n\n- hello\n- world"
+ end
end
- end
- scenario 'with multiline release notes parses the release note as Markdown' do
- create_tag_in_form(tag: 'v4.0', ref: 'master', desc: "Awesome release notes\n\n- hello\n- world")
+ scenario 'with multiline release notes parses the release note as Markdown' do
+ create_tag_in_form(tag: 'v4.0', ref: 'master', desc: "Awesome release notes\n\n- hello\n- world")
- expect(current_path).to eq(
- namespace_project_tag_path(project.namespace, project, 'v4.0'))
- expect(page).to have_content 'v4.0'
- page.within '.description' do
- expect(page).to have_content 'Awesome release notes'
- expect(page).to have_selector('ul li', count: 2)
+ expect(current_path).to eq(
+ namespace_project_tag_path(project.namespace, project, 'v4.0'))
+ expect(page).to have_content 'v4.0'
+ page.within '.description' do
+ expect(page).to have_content 'Awesome release notes'
+ expect(page).to have_selector('ul li', count: 2)
+ end
+ end
+
+ scenario 'opens dropdown for ref', js: true do
+ click_link 'New tag'
+ ref_row = find('.form-group:nth-of-type(2) .col-sm-10')
+ page.within ref_row do
+ ref_input = find('[name="ref"]', visible: false)
+ expect(ref_input.value).to eq 'master'
+ expect(find('.dropdown-toggle-text')).to have_content 'master'
+
+ find('.js-branch-select').trigger('click')
+
+ expect(find('.dropdown-menu')).to have_content 'empty-branch'
+ end
end
end
- scenario 'opens dropdown for ref', js: true do
- click_link 'New tag'
- ref_row = find('.form-group:nth-of-type(2) .col-sm-10')
- page.within ref_row do
- ref_input = find('[name="ref"]', visible: false)
- expect(ref_input.value).to eq 'master'
- expect(find('.dropdown-toggle-text')).to have_content 'master'
+ context 'from new tag page' do
+ before do
+ visit new_namespace_project_tag_path(project.namespace, project)
+ end
- find('.js-branch-select').trigger('click')
+ it 'description has autocomplete', :js do
+ find('#release_description').native.send_keys('')
+ fill_in 'release_description', with: '@'
- expect(find('.dropdown-menu')).to have_content 'empty-branch'
+ expect(page).to have_selector('.atwho-view')
end
end
diff --git a/spec/features/tags/master_deletes_tag_spec.rb b/spec/features/tags/master_deletes_tag_spec.rb
index ccfafe6db7d..58f33e954f9 100644
--- a/spec/features/tags/master_deletes_tag_spec.rb
+++ b/spec/features/tags/master_deletes_tag_spec.rb
@@ -6,7 +6,7 @@ feature 'Master deletes tag', feature: true do
before do
project.team << [user, :master]
- login_with(user)
+ gitlab_sign_in(user)
visit namespace_project_tags_path(project.namespace, project)
end
diff --git a/spec/features/tags/master_updates_tag_spec.rb b/spec/features/tags/master_updates_tag_spec.rb
index 6b5b3122f72..18c8c4c511c 100644
--- a/spec/features/tags/master_updates_tag_spec.rb
+++ b/spec/features/tags/master_updates_tag_spec.rb
@@ -6,7 +6,7 @@ feature 'Master updates tag', feature: true do
before do
project.team << [user, :master]
- login_with(user)
+ gitlab_sign_in(user)
visit namespace_project_tags_path(project.namespace, project)
end
@@ -24,6 +24,17 @@ feature 'Master updates tag', feature: true do
expect(page).to have_content 'v1.1.0'
expect(page).to have_content 'Awesome release notes'
end
+
+ scenario 'description has autocomplete', :js do
+ page.within(first('.content-list .controls')) do
+ click_link 'Edit release notes'
+ end
+
+ find('#release_description').native.send_keys('')
+ fill_in 'release_description', with: '@'
+
+ expect(page).to have_selector('.atwho-view')
+ end
end
context 'from a specific tag page' do
diff --git a/spec/features/tags/master_views_tags_spec.rb b/spec/features/tags/master_views_tags_spec.rb
index 922ac15a2eb..3c21fa06694 100644
--- a/spec/features/tags/master_views_tags_spec.rb
+++ b/spec/features/tags/master_views_tags_spec.rb
@@ -5,7 +5,7 @@ feature 'Master views tags', feature: true do
before do
project.team << [user, :master]
- login_with(user)
+ gitlab_sign_in(user)
end
context 'when project has no tags' do
diff --git a/spec/features/todos/target_state_spec.rb b/spec/features/todos/target_state_spec.rb
index 32fa88a2b21..99b70b3d3a1 100644
--- a/spec/features/todos/target_state_spec.rb
+++ b/spec/features/todos/target_state_spec.rb
@@ -6,7 +6,7 @@ feature 'Todo target states', feature: true do
let(:project) { create(:project, visibility_level: Gitlab::VisibilityLevel::PUBLIC) }
before do
- login_as user
+ gitlab_sign_in user
end
scenario 'on a closed issue todo has closed label' do
diff --git a/spec/features/todos/todos_filtering_spec.rb b/spec/features/todos/todos_filtering_spec.rb
index bbfa4e08379..032fb479076 100644
--- a/spec/features/todos/todos_filtering_spec.rb
+++ b/spec/features/todos/todos_filtering_spec.rb
@@ -17,7 +17,7 @@ describe 'Dashboard > User filters todos', feature: true, js: true do
project_1.team << [user_1, :developer]
project_2.team << [user_1, :developer]
- login_as(user_1)
+ gitlab_sign_in(user_1)
visit dashboard_todos_path
end
diff --git a/spec/features/todos/todos_sorting_spec.rb b/spec/features/todos/todos_sorting_spec.rb
index f012d250887..498bbac6d14 100644
--- a/spec/features/todos/todos_sorting_spec.rb
+++ b/spec/features/todos/todos_sorting_spec.rb
@@ -32,7 +32,7 @@ describe "Dashboard > User sorts todos", feature: true do
issue_2.labels << label_3
issue_1.labels << label_2
- login_as(user)
+ gitlab_sign_in(user)
visit dashboard_todos_path
end
@@ -83,7 +83,7 @@ describe "Dashboard > User sorts todos", feature: true do
create(:todo, user: user, project: project, target: issue_2)
create(:todo, user: user, project: project, target: merge_request_1)
- login_as(user)
+ gitlab_sign_in(user)
visit dashboard_todos_path
end
diff --git a/spec/features/todos/todos_spec.rb b/spec/features/todos/todos_spec.rb
index feb2fe8a7d1..41b32bdedc3 100644
--- a/spec/features/todos/todos_spec.rb
+++ b/spec/features/todos/todos_spec.rb
@@ -9,7 +9,7 @@ describe 'Dashboard Todos', feature: true do
describe 'GET /dashboard/todos' do
context 'User does not have todos' do
before do
- login_as(user)
+ gitlab_sign_in(user)
visit dashboard_todos_path
end
it 'shows "All done" message' do
@@ -20,7 +20,7 @@ describe 'Dashboard Todos', feature: true do
context 'User has a todo', js: true do
before do
create(:todo, :mentioned, user: user, project: project, target: issue, author: author)
- login_as(user)
+ gitlab_sign_in(user)
visit dashboard_todos_path
end
@@ -101,7 +101,7 @@ describe 'Dashboard Todos', feature: true do
context 'User created todos for themself' do
before do
- login_as(user)
+ gitlab_sign_in(user)
end
context 'issue assigned todo' do
@@ -179,7 +179,7 @@ describe 'Dashboard Todos', feature: true do
context 'User has done todos', js: true do
before do
create(:todo, :mentioned, :done, user: user, project: project, target: issue, author: author)
- login_as(user)
+ gitlab_sign_in(user)
visit dashboard_todos_path(state: :done)
end
@@ -217,7 +217,7 @@ describe 'Dashboard Todos', feature: true do
note2 = create(:note_on_issue, note: "Test #{label2.to_reference(format: :name)}", noteable_id: issue2.id, noteable_type: 'Issue', project: project2)
create(:todo, :mentioned, project: project2, target: issue2, user: user, note_id: note2.id)
- login_as(user)
+ gitlab_sign_in(user)
visit dashboard_todos_path
end
@@ -233,7 +233,7 @@ describe 'Dashboard Todos', feature: true do
# Create just enough records to cause us to paginate
create_list(:todo, 2, :mentioned, user: user, project: project, target: issue, author: author)
- login_as(user)
+ gitlab_sign_in(user)
end
it 'is paginated' do
@@ -321,7 +321,7 @@ describe 'Dashboard Todos', feature: true do
deleted_project = create(:project, visibility_level: Gitlab::VisibilityLevel::PUBLIC, pending_delete: true)
create(:todo, :mentioned, user: user, project: deleted_project, target: issue, author: author)
create(:todo, :mentioned, user: user, project: deleted_project, target: issue, author: author, state: :done)
- login_as(user)
+ gitlab_sign_in(user)
visit dashboard_todos_path
end
@@ -337,7 +337,7 @@ describe 'Dashboard Todos', feature: true do
let!(:todo) { create(:todo, :build_failed, user: user, project: project, author: author) }
before do
- login_as user
+ gitlab_sign_in user
visit dashboard_todos_path
end
diff --git a/spec/features/triggers_spec.rb b/spec/features/triggers_spec.rb
index 2ea9992173d..5af2c0e9035 100644
--- a/spec/features/triggers_spec.rb
+++ b/spec/features/triggers_spec.rb
@@ -7,14 +7,13 @@ feature 'Triggers', feature: true, js: true do
let(:guest_user) { create(:user) }
before do
- login_as(user)
- end
+ sign_in(user)
- before do
@project = create(:empty_project)
@project.team << [user, :master]
@project.team << [user2, :master]
@project.team << [guest_user, :guest]
+
visit namespace_project_settings_ci_cd_path(@project.namespace, @project)
end
@@ -34,7 +33,7 @@ feature 'Triggers', feature: true, js: true do
# See if "trigger creation successful" message displayed and description and owner are correct
expect(page.find('.flash-notice')).to have_content 'Trigger was created successfully.'
expect(page.find('.triggers-list')).to have_content 'trigger desc'
- expect(page.find('.triggers-list .trigger-owner')).to have_content @user.name
+ expect(page.find('.triggers-list .trigger-owner')).to have_content user.name
end
end
@@ -62,7 +61,7 @@ feature 'Triggers', feature: true, js: true do
# See if "trigger updated successfully" message displayed and description and owner are correct
expect(page.find('.flash-notice')).to have_content 'Trigger was successfully updated.'
expect(page.find('.triggers-list')).to have_content new_trigger_title
- expect(page.find('.triggers-list .trigger-owner')).to have_content @user.name
+ expect(page.find('.triggers-list .trigger-owner')).to have_content user.name
end
scenario 'edit "legacy" trigger and save' do
@@ -99,7 +98,7 @@ feature 'Triggers', feature: true, js: true do
page.accept_confirm do
expect(page.find('.flash-notice')).to have_content 'Trigger was re-assigned.'
expect(page.find('.triggers-list')).to have_content trigger_title
- expect(page.find('.triggers-list .trigger-owner')).to have_content @user.name
+ expect(page.find('.triggers-list .trigger-owner')).to have_content user.name
end
end
end
@@ -158,7 +157,7 @@ feature 'Triggers', feature: true, js: true do
expect(page.find('.triggers-list')).not_to have_selector('button.btn-clipboard')
# See if trigger owner name doesn't match with current_user and trigger is non-editable
- expect(page.find('.triggers-list .trigger-owner')).not_to have_content @user.name
+ expect(page.find('.triggers-list .trigger-owner')).not_to have_content user.name
expect(page.find('.triggers-list')).not_to have_selector('a[title="Edit"]')
end
@@ -171,7 +170,7 @@ feature 'Triggers', feature: true, js: true do
expect(page.find('.triggers-list')).to have_selector('button.btn-clipboard')
# See if trigger owner name matches with current_user and is editable
- expect(page.find('.triggers-list .trigger-owner')).to have_content @user.name
+ expect(page.find('.triggers-list .trigger-owner')).to have_content user.name
expect(page.find('.triggers-list')).to have_selector('a[title="Edit"]')
end
end
diff --git a/spec/features/u2f_spec.rb b/spec/features/u2f_spec.rb
index dc21637967f..f3662cb184f 100644
--- a/spec/features/u2f_spec.rb
+++ b/spec/features/u2f_spec.rb
@@ -25,7 +25,7 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', :js do
let(:user) { create(:user) }
before do
- login_as(user)
+ gitlab_sign_in(user)
user.update_attribute(:otp_required_for_login, true)
end
@@ -93,10 +93,10 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', :js do
manage_two_factor_authentication
u2f_device = register_u2f_device
expect(page).to have_content('Your U2F device was registered')
- logout
+ gitlab_sign_out
# Second user
- user = login_as(:user)
+ user = gitlab_sign_in(:user)
user.update_attribute(:otp_required_for_login, true)
visit profile_account_path
manage_two_factor_authentication
@@ -147,18 +147,18 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', :js do
before do
# Register and logout
- login_as(user)
+ gitlab_sign_in(user)
user.update_attribute(:otp_required_for_login, true)
visit profile_account_path
manage_two_factor_authentication
@u2f_device = register_u2f_device
- logout
+ gitlab_sign_out
end
describe "when 2FA via OTP is disabled" do
it "allows logging in with the U2F device" do
user.update_attribute(:otp_required_for_login, false)
- login_with(user)
+ gitlab_sign_in(user)
@u2f_device.respond_to_u2f_authentication
@@ -170,7 +170,7 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', :js do
describe "when 2FA via OTP is enabled" do
it "allows logging in with the U2F device" do
user.update_attribute(:otp_required_for_login, true)
- login_with(user)
+ gitlab_sign_in(user)
@u2f_device.respond_to_u2f_authentication
@@ -180,7 +180,7 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', :js do
end
it 'persists remember_me value via hidden field' do
- login_with(user, remember: true)
+ gitlab_sign_in(user, remember: true)
@u2f_device.respond_to_u2f_authentication
expect(page).to have_content('We heard back from your U2F device')
@@ -195,15 +195,15 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', :js do
describe "but not the current user" do
it "does not allow logging in with that particular device" do
# Register current user with the different U2F device
- current_user = login_as(:user)
+ current_user = gitlab_sign_in(:user)
current_user.update_attribute(:otp_required_for_login, true)
visit profile_account_path
manage_two_factor_authentication
register_u2f_device(name: 'My other device')
- logout
+ gitlab_sign_out
# Try authenticating user with the old U2F device
- login_as(current_user)
+ gitlab_sign_in(current_user)
@u2f_device.respond_to_u2f_authentication
expect(page).to have_content('We heard back from your U2F device')
expect(page).to have_content('Authentication via U2F device failed')
@@ -213,15 +213,15 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', :js do
describe "and also the current user" do
it "allows logging in with that particular device" do
# Register current user with the same U2F device
- current_user = login_as(:user)
+ current_user = gitlab_sign_in(:user)
current_user.update_attribute(:otp_required_for_login, true)
visit profile_account_path
manage_two_factor_authentication
register_u2f_device(@u2f_device)
- logout
+ gitlab_sign_out
# Try authenticating user with the same U2F device
- login_as(current_user)
+ gitlab_sign_in(current_user)
@u2f_device.respond_to_u2f_authentication
expect(page).to have_content('We heard back from your U2F device')
@@ -233,7 +233,7 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', :js do
describe "when a given U2F device has not been registered" do
it "does not allow logging in with that particular device" do
unregistered_device = FakeU2fDevice.new(page, 'My device')
- login_as(user)
+ gitlab_sign_in(user)
unregistered_device.respond_to_u2f_authentication
expect(page).to have_content('We heard back from your U2F device')
@@ -244,7 +244,7 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', :js do
describe "when more than one device has been registered by the same user" do
it "allows logging in with either device" do
# Register first device
- user = login_as(:user)
+ user = gitlab_sign_in(:user)
user.update_attribute(:otp_required_for_login, true)
visit profile_two_factor_auth_path
expect(page).to have_content("Your U2F device needs to be set up.")
@@ -254,17 +254,17 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', :js do
visit profile_two_factor_auth_path
expect(page).to have_content("Your U2F device needs to be set up.")
second_device = register_u2f_device(name: 'My other device')
- logout
+ gitlab_sign_out
# Authenticate as both devices
[first_device, second_device].each do |device|
- login_as(user)
+ gitlab_sign_in(user)
device.respond_to_u2f_authentication
expect(page).to have_content('We heard back from your U2F device')
expect(page).to have_css('.sign-out-link', visible: false)
- logout
+ gitlab_sign_out
end
end
end
@@ -273,7 +273,7 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', :js do
let(:user) { create(:user) }
before do
- user = login_as(:user)
+ user = gitlab_sign_in(:user)
user.update_attribute(:otp_required_for_login, true)
visit profile_account_path
manage_two_factor_authentication
@@ -300,15 +300,15 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', :js do
before do
# Register and logout
- login_as(user)
+ gitlab_sign_in(user)
user.update_attribute(:otp_required_for_login, true)
visit profile_account_path
end
describe 'when no u2f device is registered' do
before do
- logout
- login_with(user)
+ gitlab_sign_out
+ gitlab_sign_in(user)
end
it 'shows the fallback otp code UI' do
@@ -320,8 +320,8 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', :js do
before do
manage_two_factor_authentication
@u2f_device = register_u2f_device
- logout
- login_with(user)
+ gitlab_sign_out
+ gitlab_sign_in(user)
end
it 'provides a button that shows the fallback otp code UI' do
diff --git a/spec/features/unsubscribe_links_spec.rb b/spec/features/unsubscribe_links_spec.rb
index 0a8db15c75f..352f8ba70ac 100644
--- a/spec/features/unsubscribe_links_spec.rb
+++ b/spec/features/unsubscribe_links_spec.rb
@@ -57,7 +57,7 @@ describe 'Unsubscribe links', feature: true do
context 'when logged in' do
before do
- login_as(recipient)
+ sign_in(recipient)
end
it 'unsubscribes from the issue when visiting the link from the email body' do
diff --git a/spec/features/uploads/user_uploads_avatar_to_group_spec.rb b/spec/features/uploads/user_uploads_avatar_to_group_spec.rb
index d9d6f2e2382..797b7b3d50d 100644
--- a/spec/features/uploads/user_uploads_avatar_to_group_spec.rb
+++ b/spec/features/uploads/user_uploads_avatar_to_group_spec.rb
@@ -5,7 +5,7 @@ feature 'User uploads avatar to group', feature: true do
user = create(:user)
group = create(:group)
group.add_owner(user)
- login_as(user)
+ gitlab_sign_in(user)
visit edit_group_path(group)
attach_file(
diff --git a/spec/features/uploads/user_uploads_avatar_to_profile_spec.rb b/spec/features/uploads/user_uploads_avatar_to_profile_spec.rb
index eb8dbd76aab..a3f8027f4da 100644
--- a/spec/features/uploads/user_uploads_avatar_to_profile_spec.rb
+++ b/spec/features/uploads/user_uploads_avatar_to_profile_spec.rb
@@ -3,7 +3,7 @@ require 'rails_helper'
feature 'User uploads avatar to profile', feature: true do
scenario 'they see their new avatar' do
user = create(:user)
- login_as(user)
+ gitlab_sign_in(user)
visit profile_path
attach_file(
diff --git a/spec/features/uploads/user_uploads_file_to_note_spec.rb b/spec/features/uploads/user_uploads_file_to_note_spec.rb
index 9332d3b88d2..77a1012762d 100644
--- a/spec/features/uploads/user_uploads_file_to_note_spec.rb
+++ b/spec/features/uploads/user_uploads_file_to_note_spec.rb
@@ -8,7 +8,7 @@ feature 'User uploads file to note', feature: true do
let(:issue) { create(:issue, project: project, author: user) }
before do
- login_as(user)
+ gitlab_sign_in(user)
visit namespace_project_issue_path(project.namespace, project, issue)
end
diff --git a/spec/features/user_callout_spec.rb b/spec/features/user_callout_spec.rb
index b84f834ff1e..7538a6e4a04 100644
--- a/spec/features/user_callout_spec.rb
+++ b/spec/features/user_callout_spec.rb
@@ -6,7 +6,7 @@ describe 'User Callouts', js: true do
let(:project) { create(:empty_project, path: 'gitlab', name: 'sample') }
before do
- login_as(user)
+ gitlab_sign_in(user)
project.team << [user, :master]
end
diff --git a/spec/features/user_can_display_performance_bar_spec.rb b/spec/features/user_can_display_performance_bar_spec.rb
index c2842255b86..1bd7e038939 100644
--- a/spec/features/user_can_display_performance_bar_spec.rb
+++ b/spec/features/user_can_display_performance_bar_spec.rb
@@ -57,7 +57,7 @@ describe 'User can display performacne bar', :js do
context 'when user is logged-in' do
before do
- login_as :user
+ gitlab_sign_in(create(:user))
visit root_path
end
diff --git a/spec/features/users/projects_spec.rb b/spec/features/users/projects_spec.rb
index 67ce4b44464..377b1a0148f 100644
--- a/spec/features/users/projects_spec.rb
+++ b/spec/features/users/projects_spec.rb
@@ -8,7 +8,7 @@ describe 'Projects tab on a user profile', :feature, :js do
before do
allow(Project).to receive(:default_per_page).and_return(1)
- login_as(user)
+ gitlab_sign_in(user)
visit user_path(user)
diff --git a/spec/features/users/rss_spec.rb b/spec/features/users/rss_spec.rb
index dbd5f66b55e..797b317a9bb 100644
--- a/spec/features/users/rss_spec.rb
+++ b/spec/features/users/rss_spec.rb
@@ -5,7 +5,7 @@ feature 'User RSS' do
context 'when signed in' do
before do
- login_as(create(:user))
+ gitlab_sign_in(create(:user))
visit path
end
diff --git a/spec/features/users/snippets_spec.rb b/spec/features/users/snippets_spec.rb
index 2e388115633..74c5cbd7887 100644
--- a/spec/features/users/snippets_spec.rb
+++ b/spec/features/users/snippets_spec.rb
@@ -24,7 +24,7 @@ describe 'Snippets tab on a user profile', feature: true, js: true do
let!(:other_snippet) { create(:snippet, :public) }
it 'contains only internal and public snippets of a user when a user is logged in' do
- login_as(:user)
+ gitlab_sign_in(:user)
visit user_path(user)
page.within('.user-profile-nav') { click_link 'Snippets' }
wait_for_requests
diff --git a/spec/features/users_spec.rb b/spec/features/users_spec.rb
index c241dae12cf..84af13d3e49 100644
--- a/spec/features/users_spec.rb
+++ b/spec/features/users_spec.rb
@@ -24,7 +24,7 @@ feature 'Users', feature: true, js: true do
user.reload
expect(user.reset_password_token).not_to be_nil
- login_with(user)
+ gitlab_sign_in(user)
expect(current_path).to eq root_path
user.reload
diff --git a/spec/features/variables_spec.rb b/spec/features/variables_spec.rb
index d0c982919db..85085bf305a 100644
--- a/spec/features/variables_spec.rb
+++ b/spec/features/variables_spec.rb
@@ -6,7 +6,7 @@ describe 'Project variables', js: true do
let(:variable) { create(:ci_variable, key: 'test_key', value: 'test value') }
before do
- login_as(user)
+ gitlab_sign_in(user)
project.team << [user, :master]
project.variables << variable
diff --git a/spec/finders/groups_finder_spec.rb b/spec/finders/groups_finder_spec.rb
index 5b3591550c1..9e70cccc3c4 100644
--- a/spec/finders/groups_finder_spec.rb
+++ b/spec/finders/groups_finder_spec.rb
@@ -38,28 +38,79 @@ describe GroupsFinder do
end
end
- context 'subgroups' do
+ context 'subgroups', :nested_groups do
let!(:parent_group) { create(:group, :public) }
let!(:public_subgroup) { create(:group, :public, parent: parent_group) }
let!(:internal_subgroup) { create(:group, :internal, parent: parent_group) }
let!(:private_subgroup) { create(:group, :private, parent: parent_group) }
context 'without a user' do
- it 'only returns public subgroups' do
- expect(described_class.new(nil, parent: parent_group).execute).to contain_exactly(public_subgroup)
+ it 'only returns parent and public subgroups' do
+ expect(described_class.new(nil).execute).to contain_exactly(parent_group, public_subgroup)
end
end
context 'with a user' do
- it 'returns public and internal subgroups' do
- expect(described_class.new(user, parent: parent_group).execute).to contain_exactly(public_subgroup, internal_subgroup)
+ subject { described_class.new(user).execute }
+
+ it 'returns parent, public, and internal subgroups' do
+ is_expected.to contain_exactly(parent_group, public_subgroup, internal_subgroup)
end
context 'being member' do
- it 'returns public subgroups, internal subgroups, and private subgroups user is member of' do
+ it 'returns parent, public subgroups, internal subgroups, and private subgroups user is member of' do
private_subgroup.add_guest(user)
- expect(described_class.new(user, parent: parent_group).execute).to contain_exactly(public_subgroup, internal_subgroup, private_subgroup)
+ is_expected.to contain_exactly(parent_group, public_subgroup, internal_subgroup, private_subgroup)
+ end
+ end
+
+ context 'parent group private' do
+ before do
+ parent_group.update_attribute(:visibility_level, Gitlab::VisibilityLevel::PRIVATE)
+ end
+
+ context 'being member of parent group' do
+ it 'returns all subgroups' do
+ parent_group.add_guest(user)
+
+ is_expected.to contain_exactly(parent_group, public_subgroup, internal_subgroup, private_subgroup)
+ end
+ end
+
+ context 'authorized to private project' do
+ context 'project one level deep' do
+ let!(:subproject) { create(:empty_project, :private, namespace: private_subgroup) }
+ before do
+ subproject.add_guest(user)
+ end
+
+ it 'includes the subgroup of the project' do
+ is_expected.to include(private_subgroup)
+ end
+
+ it 'does not include private subgroups deeper down' do
+ subsubgroup = create(:group, :private, parent: private_subgroup)
+
+ is_expected.not_to include(subsubgroup)
+ end
+ end
+
+ context 'project two levels deep' do
+ let!(:private_subsubgroup) { create(:group, :private, parent: private_subgroup) }
+ let!(:subsubproject) { create(:empty_project, :private, namespace: private_subsubgroup) }
+ before do
+ subsubproject.add_guest(user)
+ end
+
+ it 'returns all the ancestor groups' do
+ is_expected.to include(private_subsubgroup, private_subgroup, parent_group)
+ end
+
+ it 'returns the groups for a given parent' do
+ expect(described_class.new(user, parent: parent_group).execute).to include(private_subgroup)
+ end
+ end
end
end
end
diff --git a/spec/finders/issues_finder_spec.rb b/spec/finders/issues_finder_spec.rb
index 8f2d60f2f1b..8ace1fb5751 100644
--- a/spec/finders/issues_finder_spec.rb
+++ b/spec/finders/issues_finder_spec.rb
@@ -7,9 +7,9 @@ describe IssuesFinder do
set(:project2) { create(:empty_project) }
set(:milestone) { create(:milestone, project: project1) }
set(:label) { create(:label, project: project2) }
- set(:issue1) { create(:issue, author: user, assignees: [user], project: project1, milestone: milestone, title: 'gitlab') }
+ set(:issue1) { create(:issue, author: user, assignees: [user], project: project1, milestone: milestone, title: 'gitlab', created_at: 1.week.ago) }
set(:issue2) { create(:issue, author: user, assignees: [user], project: project2, description: 'gitlab') }
- set(:issue3) { create(:issue, author: user2, assignees: [user2], project: project2, title: 'tanuki', description: 'tanuki') }
+ set(:issue3) { create(:issue, author: user2, assignees: [user2], project: project2, title: 'tanuki', description: 'tanuki', created_at: 1.week.from_now) }
describe '#execute' do
set(:closed_issue) { create(:issue, author: user2, assignees: [user2], project: project2, state: 'closed') }
@@ -215,6 +215,24 @@ describe IssuesFinder do
end
end
+ context 'filtering by created_at' do
+ context 'through created_after' do
+ let(:params) { { created_after: issue3.created_at } }
+
+ it 'returns issues created on or after the given date' do
+ expect(issues).to contain_exactly(issue3)
+ end
+ end
+
+ context 'through created_before' do
+ let(:params) { { created_before: issue1.created_at + 1.second } }
+
+ it 'returns issues created on or before the given date' do
+ expect(issues).to contain_exactly(issue1)
+ end
+ end
+ end
+
context 'when the user is unauthorized' do
let(:search_user) { nil }
diff --git a/spec/finders/merge_requests_finder_spec.rb b/spec/finders/merge_requests_finder_spec.rb
index 58b7cd5e098..5eb26de6c92 100644
--- a/spec/finders/merge_requests_finder_spec.rb
+++ b/spec/finders/merge_requests_finder_spec.rb
@@ -46,5 +46,47 @@ describe MergeRequestsFinder do
expect(merge_requests).to contain_exactly(merge_request1)
end
+
+ context 'with created_after and created_before params' do
+ let(:project4) { create(:empty_project, forked_from_project: project1) }
+
+ let!(:new_merge_request) do
+ create(:merge_request,
+ :simple,
+ author: user,
+ created_at: 1.week.from_now,
+ source_project: project4,
+ target_project: project1)
+ end
+
+ let!(:old_merge_request) do
+ create(:merge_request,
+ :simple,
+ author: user,
+ created_at: 1.week.ago,
+ source_project: project4,
+ target_project: project4)
+ end
+
+ before do
+ project4.add_master(user)
+ end
+
+ it 'filters by created_after' do
+ params = { project_id: project1.id, created_after: new_merge_request.created_at }
+
+ merge_requests = described_class.new(user, params).execute
+
+ expect(merge_requests).to contain_exactly(new_merge_request)
+ end
+
+ it 'filters by created_before' do
+ params = { project_id: project4.id, created_before: old_merge_request.created_at + 1.second }
+
+ merge_requests = described_class.new(user, params).execute
+
+ expect(merge_requests).to contain_exactly(old_merge_request)
+ end
+ end
end
end
diff --git a/spec/fixtures/emails/html_empty_link.eml b/spec/fixtures/emails/html_empty_link.eml
new file mode 100644
index 00000000000..1672b98b925
--- /dev/null
+++ b/spec/fixtures/emails/html_empty_link.eml
@@ -0,0 +1,26 @@
+
+MIME-Version: 1.0
+Received: by 10.25.161.144 with HTTP; Tue, 7 Oct 2014 22:17:17 -0700 (PDT)
+X-Originating-IP: [117.207.85.84]
+In-Reply-To: <5434c8b52bb3a_623ff09fec70f049749@discourse-app.mail>
+References: <topic/35@discourse.techapj.com>
+ <5434c8b52bb3a_623ff09fec70f049749@discourse-app.mail>
+Date: Wed, 8 Oct 2014 10:47:17 +0530
+Delivered-To: arpit@techapj.com
+Message-ID: <CAOJeqne=SJ_LwN4sb-0Y95ejc2OpreVhdmcPn0TnmwSvTCYzzQ@mail.gmail.com>
+Subject: Re: [Discourse] [Meta] Welcome to techAPJ's Discourse!
+From: Arpit Jalan <arpit@techapj.com>
+To: Discourse <mail+e1c7f2a380e33840aeb654f075490bad@arpitjalan.com>Accept-Language: en-US
+Content-Language: en-US
+X-MS-Has-Attach:
+X-MS-TNEF-Correlator:
+x-originating-ip: [134.68.31.227]
+Content-Type: multipart/alternative;
+ boundary="_000_B0DFE1BEB3739743BC9B639D0E6BC8FF217A6341IUMSSGMBX104ads_"
+MIME-Version: 1.0
+
+--_000_B0DFE1BEB3739743BC9B639D0E6BC8FF217A6341IUMSSGMBX104ads_
+Content-Type: text/html; charset="utf-8"
+
+<a name="_MailEndCompose">no brackets!</a>
+--_000_B0DFE1BEB3739743BC9B639D0E6BC8FF217A6341IUMSSGMBX104ads_--
diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb
index cc7f889b927..56daeffde27 100644
--- a/spec/helpers/application_helper_spec.rb
+++ b/spec/helpers/application_helper_spec.rb
@@ -61,14 +61,14 @@ describe ApplicationHelper do
project = create(:empty_project, avatar: File.open(uploaded_image_temp_path))
avatar_url = "/uploads/system/project/avatar/#{project.id}/banana_sample.gif"
- expect(helper.project_icon(project.full_path).to_s).
- to eq "<img src=\"#{avatar_url}\" alt=\"Banana sample\" />"
+ expect(helper.project_icon(project.full_path).to_s)
+ .to eq "<img src=\"#{avatar_url}\" alt=\"Banana sample\" />"
allow(ActionController::Base).to receive(:asset_host).and_return(gitlab_host)
avatar_url = "#{gitlab_host}/uploads/system/project/avatar/#{project.id}/banana_sample.gif"
- expect(helper.project_icon(project.full_path).to_s).
- to eq "<img src=\"#{avatar_url}\" alt=\"Banana sample\" />"
+ expect(helper.project_icon(project.full_path).to_s)
+ .to eq "<img src=\"#{avatar_url}\" alt=\"Banana sample\" />"
end
it 'gives uploaded icon when present' do
@@ -82,42 +82,71 @@ describe ApplicationHelper do
end
describe 'avatar_icon' do
- it 'returns an url for the avatar' do
- user = create(:user, avatar: File.open(uploaded_image_temp_path))
-
- avatar_url = "/uploads/system/user/avatar/#{user.id}/banana_sample.gif"
-
- expect(helper.avatar_icon(user.email).to_s).to match(avatar_url)
-
- allow(ActionController::Base).to receive(:asset_host).and_return(gitlab_host)
- avatar_url = "#{gitlab_host}/uploads/system/user/avatar/#{user.id}/banana_sample.gif"
-
- expect(helper.avatar_icon(user.email).to_s).to match(avatar_url)
- end
-
- it 'returns an url for the avatar with relative url' do
- stub_config_setting(relative_url_root: '/gitlab')
- # Must be stubbed after the stub above, and separately
- stub_config_setting(url: Settings.send(:build_gitlab_url))
-
- user = create(:user, avatar: File.open(uploaded_image_temp_path))
-
- expect(helper.avatar_icon(user.email).to_s).
- to match("/gitlab/uploads/system/user/avatar/#{user.id}/banana_sample.gif")
- end
+ let(:user) { create(:user, avatar: File.open(uploaded_image_temp_path)) }
+
+ context 'using an email' do
+ context 'when there is a matching user' do
+ it 'returns a relative URL for the avatar' do
+ expect(helper.avatar_icon(user.email).to_s)
+ .to eq("/uploads/system/user/avatar/#{user.id}/banana_sample.gif")
+ end
+
+ context 'when an asset_host is set in the config' do
+ let(:asset_host) { 'http://assets' }
+
+ before do
+ allow(ActionController::Base).to receive(:asset_host).and_return(asset_host)
+ end
+
+ it 'returns an absolute URL on that asset host' do
+ expect(helper.avatar_icon(user.email, only_path: false).to_s)
+ .to eq("#{asset_host}/uploads/system/user/avatar/#{user.id}/banana_sample.gif")
+ end
+ end
+
+ context 'when only_path is set to false' do
+ it 'returns an absolute URL for the avatar' do
+ expect(helper.avatar_icon(user.email, only_path: false).to_s)
+ .to eq("#{gitlab_host}/uploads/system/user/avatar/#{user.id}/banana_sample.gif")
+ end
+ end
+
+ context 'when the GitLab instance is at a relative URL' do
+ before do
+ stub_config_setting(relative_url_root: '/gitlab')
+ # Must be stubbed after the stub above, and separately
+ stub_config_setting(url: Settings.send(:build_gitlab_url))
+ end
+
+ it 'returns a relative URL with the correct prefix' do
+ expect(helper.avatar_icon(user.email).to_s)
+ .to eq("/gitlab/uploads/system/user/avatar/#{user.id}/banana_sample.gif")
+ end
+ end
+ end
- it 'calls gravatar_icon when no User exists with the given email' do
- expect(helper).to receive(:gravatar_icon).with('foo@example.com', 20, 2)
+ context 'when no user exists for the email' do
+ it 'calls gravatar_icon' do
+ expect(helper).to receive(:gravatar_icon).with('foo@example.com', 20, 2)
- helper.avatar_icon('foo@example.com', 20, 2)
+ helper.avatar_icon('foo@example.com', 20, 2)
+ end
+ end
end
- describe 'using a User' do
- it 'returns an URL for the avatar' do
- user = create(:user, avatar: File.open(uploaded_image_temp_path))
+ describe 'using a user' do
+ context 'when only_path is true' do
+ it 'returns a relative URL for the avatar' do
+ expect(helper.avatar_icon(user, only_path: true).to_s)
+ .to eq("/uploads/system/user/avatar/#{user.id}/banana_sample.gif")
+ end
+ end
- expect(helper.avatar_icon(user).to_s).
- to match("/uploads/system/user/avatar/#{user.id}/banana_sample.gif")
+ context 'when only_path is false' do
+ it 'returns an absolute URL for the avatar' do
+ expect(helper.avatar_icon(user, only_path: false).to_s)
+ .to eq("#{gitlab_host}/uploads/system/user/avatar/#{user.id}/banana_sample.gif")
+ end
end
end
end
@@ -147,22 +176,22 @@ describe ApplicationHelper do
it 'returns a valid Gravatar URL' do
stub_config_setting(https: false)
- expect(helper.gravatar_icon(user_email)).
- to match('http://www.gravatar.com/avatar/b58c6f14d292556214bd64909bcdb118')
+ expect(helper.gravatar_icon(user_email))
+ .to match('http://www.gravatar.com/avatar/b58c6f14d292556214bd64909bcdb118')
end
it 'uses HTTPs when configured' do
stub_config_setting(https: true)
- expect(helper.gravatar_icon(user_email)).
- to match('https://secure.gravatar.com')
+ expect(helper.gravatar_icon(user_email))
+ .to match('https://secure.gravatar.com')
end
it 'returns custom gravatar path when gravatar_url is set' do
stub_gravatar_setting(plain_url: 'http://example.local/?s=%{size}&hash=%{hash}')
- expect(gravatar_icon(user_email, 20)).
- to eq('http://example.local/?s=40&hash=b58c6f14d292556214bd64909bcdb118')
+ expect(gravatar_icon(user_email, 20))
+ .to eq('http://example.local/?s=40&hash=b58c6f14d292556214bd64909bcdb118')
end
it 'accepts a custom size argument' do
@@ -234,8 +263,8 @@ describe ApplicationHelper do
end
it 'accepts a custom html_class' do
- expect(element(html_class: 'custom_class').attr('class')).
- to eq 'js-timeago custom_class'
+ expect(element(html_class: 'custom_class').attr('class'))
+ .to eq 'js-timeago custom_class'
end
it 'accepts a custom tooltip placement' do
diff --git a/spec/helpers/broadcast_messages_helper_spec.rb b/spec/helpers/broadcast_messages_helper_spec.rb
index c6e3c5c2368..9bec0f9f432 100644
--- a/spec/helpers/broadcast_messages_helper_spec.rb
+++ b/spec/helpers/broadcast_messages_helper_spec.rb
@@ -33,8 +33,8 @@ describe BroadcastMessagesHelper do
it 'allows custom style' do
broadcast_message = double(color: '#f2dede', font: '#b94a48')
- expect(helper.broadcast_message_style(broadcast_message)).
- to match('background-color: #f2dede; color: #b94a48')
+ expect(helper.broadcast_message_style(broadcast_message))
+ .to match('background-color: #f2dede; color: #b94a48')
end
end
diff --git a/spec/helpers/commits_helper_spec.rb b/spec/helpers/commits_helper_spec.rb
index a2c008790f9..c245bb439db 100644
--- a/spec/helpers/commits_helper_spec.rb
+++ b/spec/helpers/commits_helper_spec.rb
@@ -9,8 +9,8 @@ describe CommitsHelper do
author_email: 'my@email.com" onmouseover="alert(1)'
)
- expect(helper.commit_author_link(commit)).
- not_to include('onmouseover="alert(1)"')
+ expect(helper.commit_author_link(commit))
+ .not_to include('onmouseover="alert(1)"')
end
end
@@ -22,8 +22,8 @@ describe CommitsHelper do
committer_email: 'my@email.com" onmouseover="alert(1)'
)
- expect(helper.commit_committer_link(commit)).
- not_to include('onmouseover="alert(1)"')
+ expect(helper.commit_committer_link(commit))
+ .not_to include('onmouseover="alert(1)"')
end
end
diff --git a/spec/helpers/diff_helper_spec.rb b/spec/helpers/diff_helper_spec.rb
index 0ac030d3171..0d909e6e140 100644
--- a/spec/helpers/diff_helper_spec.rb
+++ b/spec/helpers/diff_helper_spec.rb
@@ -148,12 +148,21 @@ describe DiffHelper do
it 'puts comments on added lines' do
left = Gitlab::Diff::Line.new('\\nonewline', 'old-nonewline', 3, 3, 3)
- right = Gitlab::Diff::Line.new('new line', 'add', 3, 3, 3)
+ right = Gitlab::Diff::Line.new('new line', 'new', 3, 3, 3)
result = helper.parallel_diff_discussions(left, right, diff_file)
expect(result).to eq([nil, 'comment'])
end
+
+ it 'puts comments on unchanged lines' do
+ left = Gitlab::Diff::Line.new('unchanged line', nil, 3, 3, 3)
+ right = Gitlab::Diff::Line.new('unchanged line', nil, 3, 3, 3)
+
+ result = helper.parallel_diff_discussions(left, right, diff_file)
+
+ expect(result).to eq(['comment', nil])
+ end
end
describe "#diff_match_line" do
diff --git a/spec/helpers/form_helper_spec.rb b/spec/helpers/form_helper_spec.rb
index b20373a96fb..18cf0031d5f 100644
--- a/spec/helpers/form_helper_spec.rb
+++ b/spec/helpers/form_helper_spec.rb
@@ -11,18 +11,18 @@ describe FormHelper do
it 'renders an alert div' do
model = double(errors: errors_stub('Error 1'))
- expect(helper.form_errors(model)).
- to include('<div class="alert alert-danger" id="error_explanation">')
+ expect(helper.form_errors(model))
+ .to include('<div class="alert alert-danger" id="error_explanation">')
end
it 'contains a summary message' do
single_error = double(errors: errors_stub('A'))
multi_errors = double(errors: errors_stub('A', 'B', 'C'))
- expect(helper.form_errors(single_error)).
- to include('<h4>The form contains the following error:')
- expect(helper.form_errors(multi_errors)).
- to include('<h4>The form contains the following errors:')
+ expect(helper.form_errors(single_error))
+ .to include('<h4>The form contains the following error:')
+ expect(helper.form_errors(multi_errors))
+ .to include('<h4>The form contains the following errors:')
end
it 'renders each message' do
diff --git a/spec/helpers/groups_helper_spec.rb b/spec/helpers/groups_helper_spec.rb
index 0337afa4452..a7c06e577a2 100644
--- a/spec/helpers/groups_helper_spec.rb
+++ b/spec/helpers/groups_helper_spec.rb
@@ -8,8 +8,8 @@ describe GroupsHelper do
group = create(:group)
group.avatar = fixture_file_upload(avatar_file_path)
group.save!
- expect(group_icon(group.path).to_s).
- to match("/uploads/system/group/avatar/#{group.id}/banana_sample.gif")
+ expect(group_icon(group.path).to_s)
+ .to match("/uploads/system/group/avatar/#{group.id}/banana_sample.gif")
end
it 'gives default avatar_icon when no avatar is present' do
diff --git a/spec/helpers/import_helper_spec.rb b/spec/helpers/import_helper_spec.rb
index 10f293cddf5..9afff47f4e9 100644
--- a/spec/helpers/import_helper_spec.rb
+++ b/spec/helpers/import_helper_spec.rb
@@ -29,21 +29,21 @@ describe ImportHelper do
context 'when provider is "github"' do
context 'when provider does not specify a custom URL' do
it 'uses default GitHub URL' do
- allow(Gitlab.config.omniauth).to receive(:providers).
- and_return([Settingslogic.new('name' => 'github')])
+ allow(Gitlab.config.omniauth).to receive(:providers)
+ .and_return([Settingslogic.new('name' => 'github')])
- expect(helper.provider_project_link('github', 'octocat/Hello-World')).
- to include('href="https://github.com/octocat/Hello-World"')
+ expect(helper.provider_project_link('github', 'octocat/Hello-World'))
+ .to include('href="https://github.com/octocat/Hello-World"')
end
end
context 'when provider specify a custom URL' do
it 'uses custom URL' do
- allow(Gitlab.config.omniauth).to receive(:providers).
- and_return([Settingslogic.new('name' => 'github', 'url' => 'https://github.company.com')])
+ allow(Gitlab.config.omniauth).to receive(:providers)
+ .and_return([Settingslogic.new('name' => 'github', 'url' => 'https://github.company.com')])
- expect(helper.provider_project_link('github', 'octocat/Hello-World')).
- to include('href="https://github.company.com/octocat/Hello-World"')
+ expect(helper.provider_project_link('github', 'octocat/Hello-World'))
+ .to include('href="https://github.company.com/octocat/Hello-World"')
end
end
end
@@ -54,8 +54,8 @@ describe ImportHelper do
end
it 'uses given host' do
- expect(helper.provider_project_link('gitea', 'octocat/Hello-World')).
- to include('href="https://try.gitea.io/octocat/Hello-World"')
+ expect(helper.provider_project_link('gitea', 'octocat/Hello-World'))
+ .to include('href="https://try.gitea.io/octocat/Hello-World"')
end
end
end
diff --git a/spec/helpers/issuables_helper_spec.rb b/spec/helpers/issuables_helper_spec.rb
index 8fcf7f5fa15..15cb620199d 100644
--- a/spec/helpers/issuables_helper_spec.rb
+++ b/spec/helpers/issuables_helper_spec.rb
@@ -40,23 +40,23 @@ describe IssuablesHelper do
end
it 'returns "Open" when state is :opened' do
- expect(helper.issuables_state_counter_text(:issues, :opened)).
- to eq('<span>Open</span> <span class="badge">42</span>')
+ expect(helper.issuables_state_counter_text(:issues, :opened))
+ .to eq('<span>Open</span> <span class="badge">42</span>')
end
it 'returns "Closed" when state is :closed' do
- expect(helper.issuables_state_counter_text(:issues, :closed)).
- to eq('<span>Closed</span> <span class="badge">42</span>')
+ expect(helper.issuables_state_counter_text(:issues, :closed))
+ .to eq('<span>Closed</span> <span class="badge">42</span>')
end
it 'returns "Merged" when state is :merged' do
- expect(helper.issuables_state_counter_text(:merge_requests, :merged)).
- to eq('<span>Merged</span> <span class="badge">42</span>')
+ expect(helper.issuables_state_counter_text(:merge_requests, :merged))
+ .to eq('<span>Merged</span> <span class="badge">42</span>')
end
it 'returns "All" when state is :all' do
- expect(helper.issuables_state_counter_text(:merge_requests, :all)).
- to eq('<span>All</span> <span class="badge">42</span>')
+ expect(helper.issuables_state_counter_text(:merge_requests, :all))
+ .to eq('<span>All</span> <span class="badge">42</span>')
end
end
@@ -81,13 +81,13 @@ describe IssuablesHelper do
expect(helper).to receive(:params).twice.and_return(params)
expect(helper).to receive(:issuables_count_for_state).with(:issues, :opened).and_return(42)
- expect(helper.issuables_state_counter_text(:issues, :opened)).
- to eq('<span>Open</span> <span class="badge">42</span>')
+ expect(helper.issuables_state_counter_text(:issues, :opened))
+ .to eq('<span>Open</span> <span class="badge">42</span>')
expect(helper).not_to receive(:issuables_count_for_state)
- expect(helper.issuables_state_counter_text(:issues, :opened)).
- to eq('<span>Open</span> <span class="badge">42</span>')
+ expect(helper.issuables_state_counter_text(:issues, :opened))
+ .to eq('<span>Open</span> <span class="badge">42</span>')
end
it 'does not take some keys into account in the cache key' do
@@ -100,8 +100,8 @@ describe IssuablesHelper do
}.with_indifferent_access)
expect(helper).to receive(:issuables_count_for_state).with(:issues, :opened).and_return(42)
- expect(helper.issuables_state_counter_text(:issues, :opened)).
- to eq('<span>Open</span> <span class="badge">42</span>')
+ expect(helper.issuables_state_counter_text(:issues, :opened))
+ .to eq('<span>Open</span> <span class="badge">42</span>')
expect(helper).to receive(:params).and_return({
author_id: '11',
@@ -112,22 +112,22 @@ describe IssuablesHelper do
}.with_indifferent_access)
expect(helper).not_to receive(:issuables_count_for_state)
- expect(helper.issuables_state_counter_text(:issues, :opened)).
- to eq('<span>Open</span> <span class="badge">42</span>')
+ expect(helper.issuables_state_counter_text(:issues, :opened))
+ .to eq('<span>Open</span> <span class="badge">42</span>')
end
it 'does not take params order into account in the cache key' do
expect(helper).to receive(:params).and_return('author_id' => '11', 'state' => 'opened')
expect(helper).to receive(:issuables_count_for_state).with(:issues, :opened).and_return(42)
- expect(helper.issuables_state_counter_text(:issues, :opened)).
- to eq('<span>Open</span> <span class="badge">42</span>')
+ expect(helper.issuables_state_counter_text(:issues, :opened))
+ .to eq('<span>Open</span> <span class="badge">42</span>')
expect(helper).to receive(:params).and_return('state' => 'opened', 'author_id' => '11')
expect(helper).not_to receive(:issuables_count_for_state)
- expect(helper.issuables_state_counter_text(:issues, :opened)).
- to eq('<span>Open</span> <span class="badge">42</span>')
+ expect(helper.issuables_state_counter_text(:issues, :opened))
+ .to eq('<span>Open</span> <span class="badge">42</span>')
end
end
end
diff --git a/spec/helpers/issues_helper_spec.rb b/spec/helpers/issues_helper_spec.rb
index 540cb0ab1e0..00db98fd9d2 100644
--- a/spec/helpers/issues_helper_spec.rb
+++ b/spec/helpers/issues_helper_spec.rb
@@ -93,8 +93,8 @@ describe IssuesHelper do
award = build_stubbed(:award_emoji, user: build_stubbed(:user, name: 'Jane'))
awards = Array.new(5, award).push(my_award)
- expect(award_user_list(awards, current_user, limit: 2)).
- to eq("You, Jane, and 4 more.")
+ expect(award_user_list(awards, current_user, limit: 2))
+ .to eq("You, Jane, and 4 more.")
end
end
diff --git a/spec/helpers/labels_helper_spec.rb b/spec/helpers/labels_helper_spec.rb
index 7cf535fadae..a8d6044fda7 100644
--- a/spec/helpers/labels_helper_spec.rb
+++ b/spec/helpers/labels_helper_spec.rb
@@ -55,8 +55,8 @@ describe LabelsHelper do
context 'without block' do
it 'uses render_colored_label as the link content' do
- expect(self).to receive(:render_colored_label).
- with(label, tooltip: true).and_return('Foo')
+ expect(self).to receive(:render_colored_label)
+ .with(label, tooltip: true).and_return('Foo')
expect(link_to_label(label)).to match('Foo')
end
end
diff --git a/spec/helpers/markup_helper_spec.rb b/spec/helpers/markup_helper_spec.rb
index 2a0de0b0656..b4226f96a04 100644
--- a/spec/helpers/markup_helper_spec.rb
+++ b/spec/helpers/markup_helper_spec.rb
@@ -68,8 +68,8 @@ describe MarkupHelper do
expect(doc.css('a')[0].text).to eq 'This should finally fix '
# First issue link
- expect(doc.css('a')[1].attr('href')).
- to eq namespace_project_issue_path(project.namespace, project, issues[0])
+ expect(doc.css('a')[1].attr('href'))
+ .to eq namespace_project_issue_path(project.namespace, project, issues[0])
expect(doc.css('a')[1].text).to eq issues[0].to_reference
# Internal commit link
@@ -77,8 +77,8 @@ describe MarkupHelper do
expect(doc.css('a')[2].text).to eq ' and '
# Second issue link
- expect(doc.css('a')[3].attr('href')).
- to eq namespace_project_issue_path(project.namespace, project, issues[1])
+ expect(doc.css('a')[3].attr('href'))
+ .to eq namespace_project_issue_path(project.namespace, project, issues[1])
expect(doc.css('a')[3].text).to eq issues[1].to_reference
# Trailing commit link
@@ -98,8 +98,8 @@ describe MarkupHelper do
it "escapes HTML passed in as the body" do
actual = "This is a <h1>test</h1> - see #{issues[0].to_reference}"
- expect(helper.link_to_gfm(actual, link)).
- to match('&lt;h1&gt;test&lt;/h1&gt;')
+ expect(helper.link_to_gfm(actual, link))
+ .to match('&lt;h1&gt;test&lt;/h1&gt;')
end
it 'ignores reference links when they are the entire body' do
@@ -110,8 +110,8 @@ describe MarkupHelper do
it 'replaces commit message with emoji to link' do
actual = link_to_gfm(':book: Book', '/foo')
- expect(actual).
- to eq '<gl-emoji title="open book" data-name="book" data-unicode-version="6.0">📖</gl-emoji><a href="/foo"> Book</a>'
+ expect(actual)
+ .to eq '<gl-emoji title="open book" data-name="book" data-unicode-version="6.0">📖</gl-emoji><a href="/foo"> Book</a>'
end
end
diff --git a/spec/helpers/merge_requests_helper_spec.rb b/spec/helpers/merge_requests_helper_spec.rb
index f2c9d927388..493a4ff9a93 100644
--- a/spec/helpers/merge_requests_helper_spec.rb
+++ b/spec/helpers/merge_requests_helper_spec.rb
@@ -15,8 +15,8 @@ describe MergeRequestsHelper do
end
it 'does not include api credentials in a link' do
- allow(ci_service).
- to receive(:build_page).and_return("http://secretuser:secretpass@jenkins.example.com:8888/job/test1/scm/bySHA1/12d65c")
+ allow(ci_service)
+ .to receive(:build_page).and_return("http://secretuser:secretpass@jenkins.example.com:8888/job/test1/scm/bySHA1/12d65c")
expect(helper.ci_build_details_path(merge_request)).not_to match("secret")
end
end
diff --git a/spec/helpers/page_layout_helper_spec.rb b/spec/helpers/page_layout_helper_spec.rb
index dff2784f21f..95b4032616e 100644
--- a/spec/helpers/page_layout_helper_spec.rb
+++ b/spec/helpers/page_layout_helper_spec.rb
@@ -86,8 +86,8 @@ describe PageLayoutHelper do
it 'raises ArgumentError when given more than two attributes' do
map = { foo: 'foo', bar: 'bar', baz: 'baz' }
- expect { helper.page_card_attributes(map) }.
- to raise_error(ArgumentError, /more than two attributes/)
+ expect { helper.page_card_attributes(map) }
+ .to raise_error(ArgumentError, /more than two attributes/)
end
it 'rejects blank values' do
diff --git a/spec/helpers/preferences_helper_spec.rb b/spec/helpers/preferences_helper_spec.rb
index 2c0e9975f73..a04c87b08eb 100644
--- a/spec/helpers/preferences_helper_spec.rb
+++ b/spec/helpers/preferences_helper_spec.rb
@@ -29,15 +29,15 @@ describe PreferencesHelper do
describe 'user_color_scheme' do
context 'with a user' do
it "returns user's scheme's css_class" do
- allow(helper).to receive(:current_user).
- and_return(double(color_scheme_id: 3))
+ allow(helper).to receive(:current_user)
+ .and_return(double(color_scheme_id: 3))
expect(helper.user_color_scheme).to eq 'solarized-light'
end
it 'returns the default when id is invalid' do
- allow(helper).to receive(:current_user).
- and_return(double(color_scheme_id: Gitlab::ColorSchemes.count + 5))
+ allow(helper).to receive(:current_user)
+ .and_return(double(color_scheme_id: Gitlab::ColorSchemes.count + 5))
end
end
@@ -45,8 +45,8 @@ describe PreferencesHelper do
it 'returns the default theme' do
stub_user
- expect(helper.user_color_scheme).
- to eq Gitlab::ColorSchemes.default.css_class
+ expect(helper.user_color_scheme)
+ .to eq Gitlab::ColorSchemes.default.css_class
end
end
end
@@ -55,8 +55,8 @@ describe PreferencesHelper do
if messages.empty?
allow(helper).to receive(:current_user).and_return(nil)
else
- allow(helper).to receive(:current_user).
- and_return(double('user', messages))
+ allow(helper).to receive(:current_user)
+ .and_return(double('user', messages))
end
end
diff --git a/spec/javascripts/commit/pipelines/pipelines_spec.js b/spec/javascripts/commit/pipelines/pipelines_spec.js
index ebfd60198b2..694f94efcff 100644
--- a/spec/javascripts/commit/pipelines/pipelines_spec.js
+++ b/spec/javascripts/commit/pipelines/pipelines_spec.js
@@ -1,15 +1,15 @@
import Vue from 'vue';
-import PipelinesTable from '~/commit/pipelines/pipelines_table';
+import pipelinesTable from '~/commit/pipelines/pipelines_table.vue';
describe('Pipelines table in Commits and Merge requests', () => {
const jsonFixtureName = 'pipelines/pipelines.json';
let pipeline;
+ let PipelinesTable;
- preloadFixtures('static/pipelines_table.html.raw');
preloadFixtures(jsonFixtureName);
beforeEach(() => {
- loadFixtures('static/pipelines_table.html.raw');
+ PipelinesTable = Vue.extend(pipelinesTable);
const pipelines = getJSONFixture(jsonFixtureName).pipelines;
pipeline = pipelines.find(p => p.id === 1);
});
@@ -26,8 +26,11 @@ describe('Pipelines table in Commits and Merge requests', () => {
Vue.http.interceptors.push(pipelinesEmptyResponse);
this.component = new PipelinesTable({
- el: document.querySelector('#commit-pipeline-table-view'),
- });
+ propsData: {
+ endpoint: 'endpoint',
+ helpPagePath: 'foo',
+ },
+ }).$mount();
});
afterEach(function () {
@@ -58,8 +61,11 @@ describe('Pipelines table in Commits and Merge requests', () => {
Vue.http.interceptors.push(pipelinesResponse);
this.component = new PipelinesTable({
- el: document.querySelector('#commit-pipeline-table-view'),
- });
+ propsData: {
+ endpoint: 'endpoint',
+ helpPagePath: 'foo',
+ },
+ }).$mount();
});
afterEach(() => {
@@ -92,8 +98,11 @@ describe('Pipelines table in Commits and Merge requests', () => {
Vue.http.interceptors.push(pipelinesErrorResponse);
this.component = new PipelinesTable({
- el: document.querySelector('#commit-pipeline-table-view'),
- });
+ propsData: {
+ endpoint: 'endpoint',
+ helpPagePath: 'foo',
+ },
+ }).$mount();
});
afterEach(function () {
diff --git a/spec/javascripts/datetime_utility_spec.js b/spec/javascripts/datetime_utility_spec.js
index e54ea11b08c..3391cade541 100644
--- a/spec/javascripts/datetime_utility_spec.js
+++ b/spec/javascripts/datetime_utility_spec.js
@@ -16,6 +16,10 @@ import { timeIntervalInWords } from '~/lib/utils/datetime_utility';
const date = new Date();
date.setFullYear(date.getFullYear() + 1);
+ // Add a day to prevent a transient error. If date is even 1 second
+ // short of a full year, timeFor will return '11 months remaining'
+ date.setDate(date.getDate() + 1);
+
expect(
gl.utils.timeFor(date),
).toBe('1 year remaining');
diff --git a/spec/javascripts/deploy_keys/components/key_spec.js b/spec/javascripts/deploy_keys/components/key_spec.js
index a4b98f6140d..5b64cbb2dfc 100644
--- a/spec/javascripts/deploy_keys/components/key_spec.js
+++ b/spec/javascripts/deploy_keys/components/key_spec.js
@@ -14,6 +14,7 @@ describe('Deploy keys key', () => {
propsData: {
deployKey,
store,
+ endpoint: 'https://test.host/dummy/endpoint',
},
}).$mount();
};
diff --git a/spec/javascripts/deploy_keys/components/keys_panel_spec.js b/spec/javascripts/deploy_keys/components/keys_panel_spec.js
index a69b39c35c4..08357d2b547 100644
--- a/spec/javascripts/deploy_keys/components/keys_panel_spec.js
+++ b/spec/javascripts/deploy_keys/components/keys_panel_spec.js
@@ -17,6 +17,7 @@ describe('Deploy keys panel', () => {
keys: data.enabled_keys,
showHelpBox: true,
store,
+ endpoint: 'https://test.host/dummy/endpoint',
},
}).$mount();
diff --git a/spec/javascripts/filtered_search/filtered_search_dropdown_manager_spec.js b/spec/javascripts/filtered_search/filtered_search_dropdown_manager_spec.js
index c92a147b937..9e2076dc383 100644
--- a/spec/javascripts/filtered_search/filtered_search_dropdown_manager_spec.js
+++ b/spec/javascripts/filtered_search/filtered_search_dropdown_manager_spec.js
@@ -4,6 +4,10 @@ import '~/filtered_search/filtered_search_tokenizer';
import '~/filtered_search/filtered_search_dropdown_manager';
describe('Filtered Search Dropdown Manager', () => {
+ beforeEach(() => {
+ spyOn(jQuery, 'ajax');
+ });
+
describe('addWordToInput', () => {
function getInputValue() {
return document.querySelector('.filtered-search').value;
diff --git a/spec/javascripts/filtered_search/filtered_search_manager_spec.js b/spec/javascripts/filtered_search/filtered_search_manager_spec.js
index 6d00d71f145..8d239c9cc3f 100644
--- a/spec/javascripts/filtered_search/filtered_search_manager_spec.js
+++ b/spec/javascripts/filtered_search/filtered_search_manager_spec.js
@@ -1,6 +1,7 @@
import * as recentSearchesStoreSrc from '~/filtered_search/stores/recent_searches_store';
import RecentSearchesService from '~/filtered_search/services/recent_searches_service';
import RecentSearchesServiceError from '~/filtered_search/services/recent_searches_service_error';
+import RecentSearchesRoot from '~/filtered_search/recent_searches_root';
import '~/lib/utils/url_utility';
import '~/lib/utils/common_utils';
import '~/filtered_search/filtered_search_token_keys';
@@ -71,6 +72,7 @@ describe('Filtered Search Manager', () => {
beforeEach(() => {
spyOn(RecentSearchesService, 'isAvailable').and.returnValue(isLocalStorageAvailable);
spyOn(recentSearchesStoreSrc, 'default');
+ spyOn(RecentSearchesRoot.prototype, 'render');
filteredSearchManager = new gl.FilteredSearchManager();
filteredSearchManager.setup();
@@ -104,6 +106,7 @@ describe('Filtered Search Manager', () => {
it('should blur button', () => {
const e = {
+ preventDefault: () => {},
currentTarget: {
blur: () => {},
},
@@ -116,6 +119,7 @@ describe('Filtered Search Manager', () => {
it('should not call search if there is no state', () => {
const e = {
+ preventDefault: () => {},
currentTarget: {
blur: () => {},
},
@@ -127,6 +131,7 @@ describe('Filtered Search Manager', () => {
it('should call search when there is state', () => {
const e = {
+ preventDefault: () => {},
currentTarget: {
blur: () => {},
dataset: {
diff --git a/spec/javascripts/fixtures/merge_requests.rb b/spec/javascripts/fixtures/merge_requests.rb
index a746a776548..0715f4d5f6b 100644
--- a/spec/javascripts/fixtures/merge_requests.rb
+++ b/spec/javascripts/fixtures/merge_requests.rb
@@ -55,13 +55,20 @@ describe Projects::MergeRequestsController, '(JavaScript fixtures)', type: :cont
render_merge_request(example.description, merge_request)
end
+ it 'merge_requests/changes_tab_with_comments.json' do |example|
+ create(:diff_note_on_merge_request, project: project, author: admin, position: position, noteable: merge_request)
+ create(:note_on_merge_request, author: admin, project: project, noteable: merge_request)
+ render_merge_request(example.description, merge_request, action: :diffs, format: :json)
+ end
+
private
- def render_merge_request(fixture_file_name, merge_request)
- get :show,
+ def render_merge_request(fixture_file_name, merge_request, action: :show, format: :html)
+ get action,
namespace_id: project.namespace.to_param,
project_id: project,
- id: merge_request.to_param
+ id: merge_request.to_param,
+ format: format
expect(response).to be_success
store_frontend_fixture(response, fixture_file_name)
diff --git a/spec/javascripts/fixtures/pipelines_table.html.haml b/spec/javascripts/fixtures/pipelines_table.html.haml
deleted file mode 100644
index ad1682704bb..00000000000
--- a/spec/javascripts/fixtures/pipelines_table.html.haml
+++ /dev/null
@@ -1 +0,0 @@
-#commit-pipeline-table-view{ data: { endpoint: "endpoint", "help-page-path": "foo" } }
diff --git a/spec/javascripts/issue_show/components/app_spec.js b/spec/javascripts/issue_show/components/app_spec.js
index 2ccc4f16192..276e01fc82f 100644
--- a/spec/javascripts/issue_show/components/app_spec.js
+++ b/spec/javascripts/issue_show/components/app_spec.js
@@ -51,7 +51,6 @@ describe('Issuable output', () => {
});
afterEach(() => {
- Vue.http.interceptors = _.without(Vue.http.interceptors, issueShowInterceptor);
});
it('should render a title/description/edited and update title/description/edited on update', (done) => {
diff --git a/spec/javascripts/issue_show/components/description_spec.js b/spec/javascripts/issue_show/components/description_spec.js
index 408349cc42d..f3fdbff01a6 100644
--- a/spec/javascripts/issue_show/components/description_spec.js
+++ b/spec/javascripts/issue_show/components/description_spec.js
@@ -95,5 +95,33 @@ describe('Description component', () => {
done();
});
});
+
+ it('clears task status text when no tasks are present', (done) => {
+ vm.taskStatus = '0 of 0';
+
+ setTimeout(() => {
+ expect(
+ document.querySelector('.issuable-meta #task_status').textContent.trim(),
+ ).toBe('');
+
+ done();
+ });
+ });
+ });
+
+ it('applies syntax highlighting and math when description changed', (done) => {
+ spyOn(vm, 'renderGFM').and.callThrough();
+ spyOn($.prototype, 'renderGFM').and.callThrough();
+ vm.descriptionHtml = 'changed';
+
+ Vue.nextTick(() => {
+ setTimeout(() => {
+ expect(vm.$refs['gfm-content']).toBeDefined();
+ expect(vm.renderGFM).toHaveBeenCalled();
+ expect($.prototype.renderGFM).toHaveBeenCalled();
+
+ done();
+ });
+ });
});
});
diff --git a/spec/javascripts/merge_request_notes_spec.js b/spec/javascripts/merge_request_notes_spec.js
index e54acfa8e44..b6d0ce02c4f 100644
--- a/spec/javascripts/merge_request_notes_spec.js
+++ b/spec/javascripts/merge_request_notes_spec.js
@@ -7,54 +7,92 @@ import '~/render_gfm';
import '~/render_math';
import '~/notes';
+const upArrowKeyCode = 38;
+
describe('Merge request notes', () => {
window.gon = window.gon || {};
window.gl = window.gl || {};
gl.utils = gl.utils || {};
- const fixture = 'merge_requests/diff_comment.html.raw';
- preloadFixtures(fixture);
+ const discussionTabFixture = 'merge_requests/diff_comment.html.raw';
+ const changesTabJsonFixture = 'merge_requests/changes_tab_with_comments.json';
+ preloadFixtures(discussionTabFixture, changesTabJsonFixture);
- beforeEach(() => {
- loadFixtures(fixture);
- gl.utils.disableButtonIfEmptyField = _.noop;
- window.project_uploads_path = 'http://test.host/uploads';
- $('body').data('page', 'projects:merge_requests:show');
- window.gon.current_user_id = $('.note:last').data('author-id');
+ describe('Discussion tab with diff comments', () => {
+ beforeEach(() => {
+ loadFixtures(discussionTabFixture);
+ gl.utils.disableButtonIfEmptyField = _.noop;
+ window.project_uploads_path = 'http://test.host/uploads';
+ $('body').data('page', 'projects:merge_requests:show');
+ window.gon.current_user_id = $('.note:last').data('author-id');
- return new Notes('', []);
- });
+ return new Notes('', []);
+ });
+
+ describe('up arrow', () => {
+ it('edits last comment when triggered in main form', () => {
+ const upArrowEvent = $.Event('keydown');
+ upArrowEvent.which = upArrowKeyCode;
+
+ spyOnEvent('.note:last .js-note-edit', 'click');
+
+ $('.js-note-text').trigger(upArrowEvent);
+
+ expect('click').toHaveBeenTriggeredOn('.note:last .js-note-edit');
+ });
+
+ it('edits last comment in discussion when triggered in discussion form', (done) => {
+ const upArrowEvent = $.Event('keydown');
+ upArrowEvent.which = upArrowKeyCode;
+
+ spyOnEvent('.note-discussion .js-note-edit', 'click');
+
+ $('.js-discussion-reply-button').click();
- describe('up arrow', () => {
- it('edits last comment when triggered in main form', () => {
- const upArrowEvent = $.Event('keydown');
- upArrowEvent.which = 38;
+ setTimeout(() => {
+ expect(
+ $('.note-discussion .js-note-text'),
+ ).toExist();
- spyOnEvent('.note:last .js-note-edit', 'click');
+ $('.note-discussion .js-note-text').trigger(upArrowEvent);
- $('.js-note-text').trigger(upArrowEvent);
+ expect('click').toHaveBeenTriggeredOn('.note-discussion .js-note-edit');
- expect('click').toHaveBeenTriggeredOn('.note:last .js-note-edit');
+ done();
+ });
+ });
});
+ });
- it('edits last comment in discussion when triggered in discussion form', (done) => {
- const upArrowEvent = $.Event('keydown');
- upArrowEvent.which = 38;
+ describe('Changes tab with diff comments', () => {
+ beforeEach(() => {
+ const diffsResponse = getJSONFixture(changesTabJsonFixture);
+ const noteFormHtml = `<form class="js-new-note-form">
+ <textarea class="js-note-text"></textarea>
+ </form>`;
+ setFixtures(diffsResponse.html + noteFormHtml);
+ $('body').data('page', 'projects:merge_requests:show');
+ window.gon.current_user_id = $('.note:last').data('author-id');
+
+ return new Notes('', []);
+ });
- spyOnEvent('.note-discussion .js-note-edit', 'click');
+ describe('up arrow', () => {
+ it('edits last comment in discussion when triggered in discussion form', (done) => {
+ const upArrowEvent = $.Event('keydown');
+ upArrowEvent.which = upArrowKeyCode;
- $('.js-discussion-reply-button').click();
+ spyOnEvent('.note:last .js-note-edit', 'click');
- setTimeout(() => {
- expect(
- $('.note-discussion .js-note-text'),
- ).toExist();
+ $('.js-discussion-reply-button').trigger('click');
- $('.note-discussion .js-note-text').trigger(upArrowEvent);
+ setTimeout(() => {
+ $('.js-note-text').trigger(upArrowEvent);
- expect('click').toHaveBeenTriggeredOn('.note-discussion .js-note-edit');
+ expect('click').toHaveBeenTriggeredOn('.note:last .js-note-edit');
- done();
+ done();
+ });
});
});
});
diff --git a/spec/javascripts/notes_spec.js b/spec/javascripts/notes_spec.js
index c6f218e4dac..5ece4ed080b 100644
--- a/spec/javascripts/notes_spec.js
+++ b/spec/javascripts/notes_spec.js
@@ -176,7 +176,7 @@ import '~/notes';
Notes.updateNoteTargetSelector($note);
- expect($note.toggleClass).toHaveBeenCalledWith('target', null);
+ expect($note.toggleClass).toHaveBeenCalledWith('target', false);
});
});
@@ -595,46 +595,46 @@ import '~/notes';
});
});
- describe('hasSlashCommands', () => {
+ describe('hasQuickActions', () => {
beforeEach(() => {
this.notes = new Notes('', []);
});
- it('should return true when comment begins with a slash command', () => {
+ it('should return true when comment begins with a quick action', () => {
const sampleComment = '/wip\n/milestone %1.0\n/merge\n/unassign Merging this';
- const hasSlashCommands = this.notes.hasSlashCommands(sampleComment);
+ const hasQuickActions = this.notes.hasQuickActions(sampleComment);
- expect(hasSlashCommands).toBeTruthy();
+ expect(hasQuickActions).toBeTruthy();
});
- it('should return false when comment does NOT begin with a slash command', () => {
+ it('should return false when comment does NOT begin with a quick action', () => {
const sampleComment = 'Hey, /unassign Merging this';
- const hasSlashCommands = this.notes.hasSlashCommands(sampleComment);
+ const hasQuickActions = this.notes.hasQuickActions(sampleComment);
- expect(hasSlashCommands).toBeFalsy();
+ expect(hasQuickActions).toBeFalsy();
});
- it('should return false when comment does NOT have any slash commands', () => {
+ it('should return false when comment does NOT have any quick actions', () => {
const sampleComment = 'Looking good, Awesome!';
- const hasSlashCommands = this.notes.hasSlashCommands(sampleComment);
+ const hasQuickActions = this.notes.hasQuickActions(sampleComment);
- expect(hasSlashCommands).toBeFalsy();
+ expect(hasQuickActions).toBeFalsy();
});
});
- describe('stripSlashCommands', () => {
- it('should strip slash commands from the comment which begins with a slash command', () => {
+ describe('stripQuickActions', () => {
+ it('should strip quick actions from the comment which begins with a quick action', () => {
this.notes = new Notes();
const sampleComment = '/wip\n/milestone %1.0\n/merge\n/unassign Merging this';
- const stripedComment = this.notes.stripSlashCommands(sampleComment);
+ const stripedComment = this.notes.stripQuickActions(sampleComment);
expect(stripedComment).toBe('');
});
- it('should strip slash commands from the comment but leaves plain comment if it is present', () => {
+ it('should strip quick actions from the comment but leaves plain comment if it is present', () => {
this.notes = new Notes();
const sampleComment = '/wip\n/milestone %1.0\n/merge\n/unassign\nMerging this';
- const stripedComment = this.notes.stripSlashCommands(sampleComment);
+ const stripedComment = this.notes.stripQuickActions(sampleComment);
expect(stripedComment).toBe('Merging this');
});
@@ -642,14 +642,14 @@ import '~/notes';
it('should NOT strip string that has slashes within', () => {
this.notes = new Notes();
const sampleComment = 'http://127.0.0.1:3000/root/gitlab-shell/issues/1';
- const stripedComment = this.notes.stripSlashCommands(sampleComment);
+ const stripedComment = this.notes.stripQuickActions(sampleComment);
expect(stripedComment).toBe(sampleComment);
});
});
- describe('getSlashCommandDescription', () => {
- const availableSlashCommands = [
+ describe('getQuickActionDescription', () => {
+ const availableQuickActions = [
{ name: 'close', description: 'Close this issue', params: [] },
{ name: 'title', description: 'Change title', params: [{}] },
{ name: 'estimate', description: 'Set time estimate', params: [{}] }
@@ -659,19 +659,19 @@ import '~/notes';
this.notes = new Notes();
});
- it('should return executing slash command description when note has single slash command', () => {
+ it('should return executing quick action description when note has single quick action', () => {
const sampleComment = '/close';
- expect(this.notes.getSlashCommandDescription(sampleComment, availableSlashCommands)).toBe('Applying command to close this issue');
+ expect(this.notes.getQuickActionDescription(sampleComment, availableQuickActions)).toBe('Applying command to close this issue');
});
- it('should return generic multiple slash command description when note has multiple slash commands', () => {
+ it('should return generic multiple quick action description when note has multiple quick actions', () => {
const sampleComment = '/close\n/title [Duplicate] Issue foobar';
- expect(this.notes.getSlashCommandDescription(sampleComment, availableSlashCommands)).toBe('Applying multiple commands');
+ expect(this.notes.getQuickActionDescription(sampleComment, availableQuickActions)).toBe('Applying multiple commands');
});
- it('should return generic slash command description when available slash commands list is not populated', () => {
+ it('should return generic quick action description when available quick actions list is not populated', () => {
const sampleComment = '/close\n/title [Duplicate] Issue foobar';
- expect(this.notes.getSlashCommandDescription(sampleComment)).toBe('Applying command');
+ expect(this.notes.getQuickActionDescription(sampleComment)).toBe('Applying command');
});
});
diff --git a/spec/javascripts/pipelines/async_button_spec.js b/spec/javascripts/pipelines/async_button_spec.js
index 28c9c7ab282..48620898357 100644
--- a/spec/javascripts/pipelines/async_button_spec.js
+++ b/spec/javascripts/pipelines/async_button_spec.js
@@ -1,25 +1,20 @@
import Vue from 'vue';
import asyncButtonComp from '~/pipelines/components/async_button.vue';
+import eventHub from '~/pipelines/event_hub';
describe('Pipelines Async Button', () => {
let component;
- let spy;
let AsyncButtonComponent;
beforeEach(() => {
AsyncButtonComponent = Vue.extend(asyncButtonComp);
- spy = jasmine.createSpy('spy').and.returnValue(Promise.resolve());
-
component = new AsyncButtonComponent({
propsData: {
endpoint: '/foo',
title: 'Foo',
icon: 'fa fa-foo',
cssClass: 'bar',
- service: {
- postAction: spy,
- },
},
}).$mount();
});
@@ -33,7 +28,7 @@ describe('Pipelines Async Button', () => {
});
it('should render the provided title', () => {
- expect(component.$el.getAttribute('title')).toContain('Foo');
+ expect(component.$el.getAttribute('data-original-title')).toContain('Foo');
expect(component.$el.getAttribute('aria-label')).toContain('Foo');
});
@@ -41,37 +36,12 @@ describe('Pipelines Async Button', () => {
expect(component.$el.getAttribute('class')).toContain('bar');
});
- it('should call the service when it is clicked with the provided endpoint', () => {
- component.$el.click();
- expect(spy).toHaveBeenCalledWith('/foo');
- });
-
- it('should hide loading if request fails', () => {
- spy = jasmine.createSpy('spy').and.returnValue(Promise.reject());
-
- component = new AsyncButtonComponent({
- propsData: {
- endpoint: '/foo',
- title: 'Foo',
- icon: 'fa fa-foo',
- cssClass: 'bar',
- dataAttributes: {
- 'data-foo': 'foo',
- },
- service: {
- postAction: spy,
- },
- },
- }).$mount();
-
- component.$el.click();
- expect(component.$el.querySelector('.fa-spinner')).toBe(null);
- });
-
describe('With confirm dialog', () => {
it('should call the service when confimation is positive', () => {
spyOn(window, 'confirm').and.returnValue(true);
- spy = jasmine.createSpy('spy').and.returnValue(Promise.resolve());
+ eventHub.$on('postAction', (endpoint) => {
+ expect(endpoint).toEqual('/foo');
+ });
component = new AsyncButtonComponent({
propsData: {
@@ -79,15 +49,11 @@ describe('Pipelines Async Button', () => {
title: 'Foo',
icon: 'fa fa-foo',
cssClass: 'bar',
- service: {
- postAction: spy,
- },
confirmActionMessage: 'bar',
},
}).$mount();
component.$el.click();
- expect(spy).toHaveBeenCalledWith('/foo');
});
});
});
diff --git a/spec/javascripts/pipelines/pipelines_actions_spec.js b/spec/javascripts/pipelines/pipelines_actions_spec.js
index 8a58b77f1e3..72fb0a8f9ef 100644
--- a/spec/javascripts/pipelines/pipelines_actions_spec.js
+++ b/spec/javascripts/pipelines/pipelines_actions_spec.js
@@ -3,7 +3,6 @@ import pipelinesActionsComp from '~/pipelines/components/pipelines_actions.vue';
describe('Pipelines Actions dropdown', () => {
let component;
- let spy;
let actions;
let ActionsComponent;
@@ -22,14 +21,9 @@ describe('Pipelines Actions dropdown', () => {
},
];
- spy = jasmine.createSpy('spy').and.returnValue(Promise.resolve());
-
component = new ActionsComponent({
propsData: {
actions,
- service: {
- postAction: spy,
- },
},
}).$mount();
});
@@ -40,31 +34,6 @@ describe('Pipelines Actions dropdown', () => {
).toEqual(actions.length);
});
- it('should call the service when an action is clicked', () => {
- component.$el.querySelector('.js-pipeline-dropdown-manual-actions').click();
- component.$el.querySelector('.js-pipeline-action-link').click();
-
- expect(spy).toHaveBeenCalledWith(actions[0].path);
- });
-
- it('should hide loading if request fails', () => {
- spy = jasmine.createSpy('spy').and.returnValue(Promise.reject());
-
- component = new ActionsComponent({
- propsData: {
- actions,
- service: {
- postAction: spy,
- },
- },
- }).$mount();
-
- component.$el.querySelector('.js-pipeline-dropdown-manual-actions').click();
- component.$el.querySelector('.js-pipeline-action-link').click();
-
- expect(component.$el.querySelector('.fa-spinner')).toEqual(null);
- });
-
it('should render a disabled action when it\'s not playable', () => {
expect(
component.$el.querySelector('.dropdown-menu li:last-child button').getAttribute('disabled'),
diff --git a/spec/javascripts/vue_shared/components/pipelines_table_row_spec.js b/spec/javascripts/pipelines/pipelines_table_row_spec.js
index 9475ee28a03..7ce39dca112 100644
--- a/spec/javascripts/vue_shared/components/pipelines_table_row_spec.js
+++ b/spec/javascripts/pipelines/pipelines_table_row_spec.js
@@ -1,5 +1,5 @@
import Vue from 'vue';
-import tableRowComp from '~/vue_shared/components/pipelines_table_row.vue';
+import tableRowComp from '~/pipelines/components/pipelines_table_row.vue';
describe('Pipelines Table Row', () => {
const jsonFixtureName = 'pipelines/pipelines.json';
diff --git a/spec/javascripts/vue_shared/components/pipelines_table_spec.js b/spec/javascripts/pipelines/pipelines_table_spec.js
index 4c35d702004..3afe89c8db4 100644
--- a/spec/javascripts/vue_shared/components/pipelines_table_spec.js
+++ b/spec/javascripts/pipelines/pipelines_table_spec.js
@@ -1,5 +1,5 @@
import Vue from 'vue';
-import pipelinesTableComp from '~/vue_shared/components/pipelines_table.vue';
+import pipelinesTableComp from '~/pipelines/components/pipelines_table.vue';
import '~/lib/utils/datetime_utility';
describe('Pipelines Table', () => {
@@ -22,7 +22,6 @@ describe('Pipelines Table', () => {
component = new PipelinesTableComponent({
propsData: {
pipelines: [],
- service: {},
},
}).$mount();
});
@@ -48,7 +47,6 @@ describe('Pipelines Table', () => {
const component = new PipelinesTableComponent({
propsData: {
pipelines: [],
- service: {},
},
}).$mount();
expect(component.$el.querySelectorAll('.commit.gl-responsive-table-row').length).toEqual(0);
@@ -58,10 +56,8 @@ describe('Pipelines Table', () => {
describe('with data', () => {
it('should render rows', () => {
const component = new PipelinesTableComponent({
- el: document.querySelector('.test-dom-element'),
propsData: {
pipelines: [pipeline],
- service: {},
},
}).$mount();
diff --git a/spec/javascripts/project_title_spec.js b/spec/javascripts/project_title_spec.js
index 3dba2e817ff..cc336180ff7 100644
--- a/spec/javascripts/project_title_spec.js
+++ b/spec/javascripts/project_title_spec.js
@@ -1,4 +1,3 @@
-/* eslint-disable space-before-function-paren, no-unused-expressions, no-return-assign, no-param-reassign, no-var, new-cap, wrap-iife, no-unused-vars, quotes, jasmine/no-expect-in-setup-teardown, max-len */
/* global Project */
import 'select2/select2';
@@ -7,47 +6,52 @@ import '~/api';
import '~/project_select';
import '~/project';
-(function() {
- describe('Project Title', function() {
- preloadFixtures('issues/open-issue.html.raw');
- loadJSONFixtures('projects.json');
+describe('Project Title', () => {
+ preloadFixtures('issues/open-issue.html.raw');
+ loadJSONFixtures('projects.json');
- beforeEach(function() {
- loadFixtures('issues/open-issue.html.raw');
+ beforeEach(() => {
+ loadFixtures('issues/open-issue.html.raw');
- window.gon = {};
- window.gon.api_version = 'v3';
+ window.gon = {};
+ window.gon.api_version = 'v3';
- return this.project = new Project();
- });
+ // eslint-disable-next-line no-new
+ new Project();
+ });
- describe('project list', function() {
- var fakeAjaxResponse = function fakeAjaxResponse(req) {
- var d;
- expect(req.url).toBe('/api/v3/projects.json?simple=true');
- expect(req.data).toEqual({ search: '', order_by: 'last_activity_at', per_page: 20, membership: true });
- d = $.Deferred();
- d.resolve(this.projects_data);
- return d.promise();
- };
-
- beforeEach((function(_this) {
- return function() {
- _this.projects_data = getJSONFixture('projects.json');
- return spyOn(jQuery, 'ajax').and.callFake(fakeAjaxResponse.bind(_this));
- };
- })(this));
- it('toggles dropdown', function() {
- var menu = $('.js-dropdown-menu-projects');
- $('.js-projects-dropdown-toggle').click();
- expect(menu).toHaveClass('open');
- menu.find('.dropdown-menu-close-icon').click();
- expect(menu).not.toHaveClass('open');
+ describe('project list', () => {
+ let reqUrl;
+ let reqData;
+
+ beforeEach(() => {
+ const fakeResponseData = getJSONFixture('projects.json');
+ spyOn(jQuery, 'ajax').and.callFake((req) => {
+ const def = $.Deferred();
+ reqUrl = req.url;
+ reqData = req.data;
+ def.resolve(fakeResponseData);
+ return def.promise();
});
});
- afterEach(() => {
- window.gon = {};
+ it('toggles dropdown', () => {
+ const $menu = $('.js-dropdown-menu-projects');
+ $('.js-projects-dropdown-toggle').click();
+ expect($menu).toHaveClass('open');
+ expect(reqUrl).toBe('/api/v3/projects.json?simple=true');
+ expect(reqData).toEqual({
+ search: '',
+ order_by: 'last_activity_at',
+ per_page: 20,
+ membership: true,
+ });
+ $menu.find('.dropdown-menu-close-icon').click();
+ expect($menu).not.toHaveClass('open');
});
});
-}).call(window);
+
+ afterEach(() => {
+ window.gon = {};
+ });
+});
diff --git a/spec/javascripts/test_bundle.js b/spec/javascripts/test_bundle.js
index 2c34402576b..f0d51bd0902 100644
--- a/spec/javascripts/test_bundle.js
+++ b/spec/javascripts/test_bundle.js
@@ -1,8 +1,14 @@
+/* eslint-disable jasmine/no-global-setup */
import $ from 'jquery';
import _ from 'underscore';
import 'jasmine-jquery';
import '~/commons';
+import Vue from 'vue';
+import VueResource from 'vue-resource';
+
+Vue.use(VueResource);
+
// enable test fixtures
jasmine.getFixtures().fixturesPath = '/base/spec/javascripts/fixtures';
jasmine.getJSONFixtures().fixturesPath = '/base/spec/javascripts/fixtures';
@@ -16,6 +22,32 @@ window.gl = window.gl || {};
window.gl.TEST_HOST = 'http://test.host';
window.gon = window.gon || {};
+// HACK: Chrome 59 disconnects if there are too many synchronous tests in a row
+// because it appears to lock up the thread that communicates to Karma's socket
+// This async beforeEach gets called on every spec and releases the JS thread long
+// enough for the socket to continue to communicate.
+// The downside is that it creates a minor performance penalty in the time it takes
+// to run our unit tests.
+beforeEach(done => done());
+
+beforeAll(() => {
+ const origError = console.error;
+ spyOn(console, 'error').and.callFake((message) => {
+ if (/^\[Vue warn\]/.test(message)) {
+ fail(message);
+ } else {
+ origError(message);
+ }
+ });
+});
+
+const builtinVueHttpInterceptors = Vue.http.interceptors.slice();
+
+beforeEach(() => {
+ // restore interceptors so we have no remaining ones from previous tests
+ Vue.http.interceptors = builtinVueHttpInterceptors.slice();
+});
+
// render all of our tests
const testsContext = require.context('.', true, /_spec$/);
testsContext.keys().forEach(function (path) {
diff --git a/spec/lib/banzai/cross_project_reference_spec.rb b/spec/lib/banzai/cross_project_reference_spec.rb
index deaabceef1c..787212581e2 100644
--- a/spec/lib/banzai/cross_project_reference_spec.rb
+++ b/spec/lib/banzai/cross_project_reference_spec.rb
@@ -24,8 +24,8 @@ describe Banzai::CrossProjectReference, lib: true do
it 'returns the referenced project' do
project2 = double('referenced project')
- expect(Project).to receive(:find_by_full_path).
- with('cross/reference').and_return(project2)
+ expect(Project).to receive(:find_by_full_path)
+ .with('cross/reference').and_return(project2)
expect(project_from_ref('cross/reference')).to eq project2
end
diff --git a/spec/lib/banzai/filter/abstract_reference_filter_spec.rb b/spec/lib/banzai/filter/abstract_reference_filter_spec.rb
index 787c2372c5b..27532f96f56 100644
--- a/spec/lib/banzai/filter/abstract_reference_filter_spec.rb
+++ b/spec/lib/banzai/filter/abstract_reference_filter_spec.rb
@@ -23,11 +23,11 @@ describe Banzai::Filter::AbstractReferenceFilter do
doc = Nokogiri::HTML.fragment('')
filter = described_class.new(doc, project: project)
- expect(filter).to receive(:references_per_project).
- and_return({ project.path_with_namespace => Set.new(%w[1]) })
+ expect(filter).to receive(:references_per_project)
+ .and_return({ project.path_with_namespace => Set.new(%w[1]) })
- expect(filter.projects_per_reference).
- to eq({ project.path_with_namespace => project })
+ expect(filter.projects_per_reference)
+ .to eq({ project.path_with_namespace => project })
end
end
@@ -37,26 +37,26 @@ describe Banzai::Filter::AbstractReferenceFilter do
context 'with RequestStore disabled' do
it 'returns a list of Projects for a list of paths' do
- expect(filter.find_projects_for_paths([project.path_with_namespace])).
- to eq([project])
+ expect(filter.find_projects_for_paths([project.path_with_namespace]))
+ .to eq([project])
end
it "return an empty array for paths that don't exist" do
- expect(filter.find_projects_for_paths(['nonexistent/project'])).
- to eq([])
+ expect(filter.find_projects_for_paths(['nonexistent/project']))
+ .to eq([])
end
end
context 'with RequestStore enabled', :request_store do
it 'returns a list of Projects for a list of paths' do
- expect(filter.find_projects_for_paths([project.path_with_namespace])).
- to eq([project])
+ expect(filter.find_projects_for_paths([project.path_with_namespace]))
+ .to eq([project])
end
context "when no project with that path exists" do
it "returns no value" do
- expect(filter.find_projects_for_paths(['nonexistent/project'])).
- to eq([])
+ expect(filter.find_projects_for_paths(['nonexistent/project']))
+ .to eq([])
end
it "adds the ref to the project refs cache" do
@@ -75,8 +75,8 @@ describe Banzai::Filter::AbstractReferenceFilter do
end
it "return an empty array for paths that don't exist" do
- expect(filter.find_projects_for_paths(['nonexistent/project'])).
- to eq([])
+ expect(filter.find_projects_for_paths(['nonexistent/project']))
+ .to eq([])
end
end
end
diff --git a/spec/lib/banzai/filter/commit_range_reference_filter_spec.rb b/spec/lib/banzai/filter/commit_range_reference_filter_spec.rb
index deadc36524c..fc67c7ec3c4 100644
--- a/spec/lib/banzai/filter/commit_range_reference_filter_spec.rb
+++ b/spec/lib/banzai/filter/commit_range_reference_filter_spec.rb
@@ -28,15 +28,15 @@ describe Banzai::Filter::CommitRangeReferenceFilter, lib: true do
it 'links to a valid two-dot reference' do
doc = reference_filter("See #{reference2}")
- expect(doc.css('a').first.attr('href')).
- to eq urls.namespace_project_compare_url(project.namespace, project, range2.to_param)
+ expect(doc.css('a').first.attr('href'))
+ .to eq urls.namespace_project_compare_url(project.namespace, project, range2.to_param)
end
it 'links to a valid three-dot reference' do
doc = reference_filter("See #{reference}")
- expect(doc.css('a').first.attr('href')).
- to eq urls.namespace_project_compare_url(project.namespace, project, range.to_param)
+ expect(doc.css('a').first.attr('href'))
+ .to eq urls.namespace_project_compare_url(project.namespace, project, range.to_param)
end
it 'links to a valid short ID' do
@@ -105,15 +105,15 @@ describe Banzai::Filter::CommitRangeReferenceFilter, lib: true do
it 'links to a valid reference' do
doc = reference_filter("See #{reference}")
- expect(doc.css('a').first.attr('href')).
- to eq urls.namespace_project_compare_url(project2.namespace, project2, range.to_param)
+ expect(doc.css('a').first.attr('href'))
+ .to eq urls.namespace_project_compare_url(project2.namespace, project2, range.to_param)
end
it 'link has valid text' do
doc = reference_filter("Fixed (#{reference}.)")
- expect(doc.css('a').first.text).
- to eql("#{project2.path_with_namespace}@#{commit1.short_id}...#{commit2.short_id}")
+ expect(doc.css('a').first.text)
+ .to eql("#{project2.path_with_namespace}@#{commit1.short_id}...#{commit2.short_id}")
end
it 'has valid text' do
@@ -140,15 +140,15 @@ describe Banzai::Filter::CommitRangeReferenceFilter, lib: true do
it 'links to a valid reference' do
doc = reference_filter("See #{reference}")
- expect(doc.css('a').first.attr('href')).
- to eq urls.namespace_project_compare_url(project2.namespace, project2, range.to_param)
+ expect(doc.css('a').first.attr('href'))
+ .to eq urls.namespace_project_compare_url(project2.namespace, project2, range.to_param)
end
it 'link has valid text' do
doc = reference_filter("Fixed (#{reference}.)")
- expect(doc.css('a').first.text).
- to eql("#{project2.path}@#{commit1.short_id}...#{commit2.short_id}")
+ expect(doc.css('a').first.text)
+ .to eql("#{project2.path}@#{commit1.short_id}...#{commit2.short_id}")
end
it 'has valid text' do
@@ -175,15 +175,15 @@ describe Banzai::Filter::CommitRangeReferenceFilter, lib: true do
it 'links to a valid reference' do
doc = reference_filter("See #{reference}")
- expect(doc.css('a').first.attr('href')).
- to eq urls.namespace_project_compare_url(project2.namespace, project2, range.to_param)
+ expect(doc.css('a').first.attr('href'))
+ .to eq urls.namespace_project_compare_url(project2.namespace, project2, range.to_param)
end
it 'link has valid text' do
doc = reference_filter("Fixed (#{reference}.)")
- expect(doc.css('a').first.text).
- to eql("#{project2.path}@#{commit1.short_id}...#{commit2.short_id}")
+ expect(doc.css('a').first.text)
+ .to eql("#{project2.path}@#{commit1.short_id}...#{commit2.short_id}")
end
it 'has valid text' do
@@ -214,8 +214,8 @@ describe Banzai::Filter::CommitRangeReferenceFilter, lib: true do
it 'links to a valid reference' do
doc = reference_filter("See #{reference}")
- expect(doc.css('a').first.attr('href')).
- to eq reference
+ expect(doc.css('a').first.attr('href'))
+ .to eq reference
end
it 'links with adjacent text' do
diff --git a/spec/lib/banzai/filter/commit_reference_filter_spec.rb b/spec/lib/banzai/filter/commit_reference_filter_spec.rb
index a19aac61229..c4d8d3b6682 100644
--- a/spec/lib/banzai/filter/commit_reference_filter_spec.rb
+++ b/spec/lib/banzai/filter/commit_reference_filter_spec.rb
@@ -26,8 +26,8 @@ describe Banzai::Filter::CommitReferenceFilter, lib: true do
doc = reference_filter("See #{reference[0...size]}")
expect(doc.css('a').first.text).to eq commit.short_id
- expect(doc.css('a').first.attr('href')).
- to eq urls.namespace_project_commit_url(project.namespace, project, reference)
+ expect(doc.css('a').first.attr('href'))
+ .to eq urls.namespace_project_commit_url(project.namespace, project, reference)
end
end
@@ -180,8 +180,8 @@ describe Banzai::Filter::CommitReferenceFilter, lib: true do
it 'links to a valid reference' do
doc = reference_filter("See #{reference}")
- expect(doc.css('a').first.attr('href')).
- to eq urls.namespace_project_commit_url(project2.namespace, project2, commit.id)
+ expect(doc.css('a').first.attr('href'))
+ .to eq urls.namespace_project_commit_url(project2.namespace, project2, commit.id)
end
it 'links with adjacent text' do
diff --git a/spec/lib/banzai/filter/external_issue_reference_filter_spec.rb b/spec/lib/banzai/filter/external_issue_reference_filter_spec.rb
index 76cefe112fb..a4bb043f8f1 100644
--- a/spec/lib/banzai/filter/external_issue_reference_filter_spec.rb
+++ b/spec/lib/banzai/filter/external_issue_reference_filter_spec.rb
@@ -58,8 +58,8 @@ describe Banzai::Filter::ExternalIssueReferenceFilter, lib: true do
end
it 'escapes the title attribute' do
- allow(project.external_issue_tracker).to receive(:title).
- and_return(%{"></a>whatever<a title="})
+ allow(project.external_issue_tracker).to receive(:title)
+ .and_return(%{"></a>whatever<a title="})
doc = filter("Issue #{reference}")
expect(doc.text).to eq "Issue #{reference}"
diff --git a/spec/lib/banzai/filter/issue_reference_filter_spec.rb b/spec/lib/banzai/filter/issue_reference_filter_spec.rb
index f1082495fcc..e5c1deb338b 100644
--- a/spec/lib/banzai/filter/issue_reference_filter_spec.rb
+++ b/spec/lib/banzai/filter/issue_reference_filter_spec.rb
@@ -49,8 +49,8 @@ describe Banzai::Filter::IssueReferenceFilter, lib: true do
it 'links to a valid reference' do
doc = reference_filter("Fixed #{reference}")
- expect(doc.css('a').first.attr('href')).
- to eq helper.url_for_issue(issue.iid, project)
+ expect(doc.css('a').first.attr('href'))
+ .to eq helper.url_for_issue(issue.iid, project)
end
it 'links with adjacent text' do
@@ -137,9 +137,9 @@ describe Banzai::Filter::IssueReferenceFilter, lib: true do
let(:reference) { "#{project2.path_with_namespace}##{issue.iid}" }
it 'ignores valid references when cross-reference project uses external tracker' do
- expect_any_instance_of(described_class).to receive(:find_object).
- with(project2, issue.iid).
- and_return(nil)
+ expect_any_instance_of(described_class).to receive(:find_object)
+ .with(project2, issue.iid)
+ .and_return(nil)
exp = act = "Issue #{reference}"
expect(reference_filter(act).to_html).to eq exp
@@ -148,8 +148,8 @@ describe Banzai::Filter::IssueReferenceFilter, lib: true do
it 'links to a valid reference' do
doc = reference_filter("See #{reference}")
- expect(doc.css('a').first.attr('href')).
- to eq helper.url_for_issue(issue.iid, project2)
+ expect(doc.css('a').first.attr('href'))
+ .to eq helper.url_for_issue(issue.iid, project2)
end
it 'link has valid text' do
@@ -181,9 +181,9 @@ describe Banzai::Filter::IssueReferenceFilter, lib: true do
let(:reference) { "#{project2.path_with_namespace}##{issue.iid}" }
it 'ignores valid references when cross-reference project uses external tracker' do
- expect_any_instance_of(described_class).to receive(:find_object).
- with(project2, issue.iid).
- and_return(nil)
+ expect_any_instance_of(described_class).to receive(:find_object)
+ .with(project2, issue.iid)
+ .and_return(nil)
exp = act = "Issue #{reference}"
expect(reference_filter(act).to_html).to eq exp
@@ -192,8 +192,8 @@ describe Banzai::Filter::IssueReferenceFilter, lib: true do
it 'links to a valid reference' do
doc = reference_filter("See #{reference}")
- expect(doc.css('a').first.attr('href')).
- to eq helper.url_for_issue(issue.iid, project2)
+ expect(doc.css('a').first.attr('href'))
+ .to eq helper.url_for_issue(issue.iid, project2)
end
it 'link has valid text' do
@@ -225,9 +225,9 @@ describe Banzai::Filter::IssueReferenceFilter, lib: true do
let(:reference) { "#{project2.path}##{issue.iid}" }
it 'ignores valid references when cross-reference project uses external tracker' do
- expect_any_instance_of(described_class).to receive(:find_object).
- with(project2, issue.iid).
- and_return(nil)
+ expect_any_instance_of(described_class).to receive(:find_object)
+ .with(project2, issue.iid)
+ .and_return(nil)
exp = act = "Issue #{reference}"
expect(reference_filter(act).to_html).to eq exp
@@ -236,8 +236,8 @@ describe Banzai::Filter::IssueReferenceFilter, lib: true do
it 'links to a valid reference' do
doc = reference_filter("See #{reference}")
- expect(doc.css('a').first.attr('href')).
- to eq helper.url_for_issue(issue.iid, project2)
+ expect(doc.css('a').first.attr('href'))
+ .to eq helper.url_for_issue(issue.iid, project2)
end
it 'link has valid text' do
@@ -270,8 +270,8 @@ describe Banzai::Filter::IssueReferenceFilter, lib: true do
it 'links to a valid reference' do
doc = reference_filter("See #{reference}")
- expect(doc.css('a').first.attr('href')).
- to eq reference
+ expect(doc.css('a').first.attr('href'))
+ .to eq reference
end
it 'links with adjacent text' do
@@ -292,8 +292,8 @@ describe Banzai::Filter::IssueReferenceFilter, lib: true do
it 'links to a valid reference' do
doc = reference_filter("See #{reference_link}")
- expect(doc.css('a').first.attr('href')).
- to eq helper.url_for_issue(issue.iid, project2)
+ expect(doc.css('a').first.attr('href'))
+ .to eq helper.url_for_issue(issue.iid, project2)
end
it 'links with adjacent text' do
@@ -314,8 +314,8 @@ describe Banzai::Filter::IssueReferenceFilter, lib: true do
it 'links to a valid reference' do
doc = reference_filter("See #{reference_link}")
- expect(doc.css('a').first.attr('href')).
- to eq helper.url_for_issue(issue.iid, project2) + "#note_123"
+ expect(doc.css('a').first.attr('href'))
+ .to eq helper.url_for_issue(issue.iid, project2) + "#note_123"
end
it 'links with adjacent text' do
@@ -330,14 +330,14 @@ describe Banzai::Filter::IssueReferenceFilter, lib: true do
doc = Nokogiri::HTML.fragment('')
filter = described_class.new(doc, project: project)
- expect(filter).to receive(:projects_per_reference).
- and_return({ project.path_with_namespace => project })
+ expect(filter).to receive(:projects_per_reference)
+ .and_return({ project.path_with_namespace => project })
- expect(filter).to receive(:references_per_project).
- and_return({ project.path_with_namespace => Set.new([issue.iid]) })
+ expect(filter).to receive(:references_per_project)
+ .and_return({ project.path_with_namespace => Set.new([issue.iid]) })
- expect(filter.issues_per_project).
- to eq({ project => { issue.iid => issue } })
+ expect(filter.issues_per_project)
+ .to eq({ project => { issue.iid => issue } })
end
end
@@ -348,14 +348,14 @@ describe Banzai::Filter::IssueReferenceFilter, lib: true do
expect(project).to receive(:default_issues_tracker?).and_return(false)
- expect(filter).to receive(:projects_per_reference).
- and_return({ project.path_with_namespace => project })
+ expect(filter).to receive(:projects_per_reference)
+ .and_return({ project.path_with_namespace => project })
- expect(filter).to receive(:references_per_project).
- and_return({ project.path_with_namespace => Set.new([1]) })
+ expect(filter).to receive(:references_per_project)
+ .and_return({ project.path_with_namespace => Set.new([1]) })
- expect(filter.issues_per_project[project][1]).
- to be_an_instance_of(ExternalIssue)
+ expect(filter.issues_per_project[project][1])
+ .to be_an_instance_of(ExternalIssue)
end
end
end
diff --git a/spec/lib/banzai/filter/label_reference_filter_spec.rb b/spec/lib/banzai/filter/label_reference_filter_spec.rb
index 284641fb20a..cb3cf982351 100644
--- a/spec/lib/banzai/filter/label_reference_filter_spec.rb
+++ b/spec/lib/banzai/filter/label_reference_filter_spec.rb
@@ -72,8 +72,8 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do
it 'links to a valid reference' do
doc = reference_filter("See #{reference}")
- expect(doc.css('a').first.attr('href')).to eq urls.
- namespace_project_issues_url(project.namespace, project, label_name: label.name)
+ expect(doc.css('a').first.attr('href')).to eq urls
+ .namespace_project_issues_url(project.namespace, project, label_name: label.name)
end
it 'links with adjacent text' do
@@ -95,8 +95,8 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do
it 'links to a valid reference' do
doc = reference_filter("See #{reference}")
- expect(doc.css('a').first.attr('href')).to eq urls.
- namespace_project_issues_url(project.namespace, project, label_name: label.name)
+ expect(doc.css('a').first.attr('href')).to eq urls
+ .namespace_project_issues_url(project.namespace, project, label_name: label.name)
expect(doc.text).to eq 'See gfm'
end
@@ -119,8 +119,8 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do
it 'links to a valid reference' do
doc = reference_filter("See #{reference}")
- expect(doc.css('a').first.attr('href')).to eq urls.
- namespace_project_issues_url(project.namespace, project, label_name: label.name)
+ expect(doc.css('a').first.attr('href')).to eq urls
+ .namespace_project_issues_url(project.namespace, project, label_name: label.name)
expect(doc.text).to eq 'See 2fa'
end
@@ -143,8 +143,8 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do
it 'links to a valid reference' do
doc = reference_filter("See #{reference}")
- expect(doc.css('a').first.attr('href')).to eq urls.
- namespace_project_issues_url(project.namespace, project, label_name: label.name)
+ expect(doc.css('a').first.attr('href')).to eq urls
+ .namespace_project_issues_url(project.namespace, project, label_name: label.name)
expect(doc.text).to eq 'See ?g.fm&'
end
@@ -168,8 +168,8 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do
it 'links to a valid reference' do
doc = reference_filter("See #{reference}")
- expect(doc.css('a').first.attr('href')).to eq urls.
- namespace_project_issues_url(project.namespace, project, label_name: label.name)
+ expect(doc.css('a').first.attr('href')).to eq urls
+ .namespace_project_issues_url(project.namespace, project, label_name: label.name)
expect(doc.text).to eq 'See gfm references'
end
@@ -192,8 +192,8 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do
it 'links to a valid reference' do
doc = reference_filter("See #{reference}")
- expect(doc.css('a').first.attr('href')).to eq urls.
- namespace_project_issues_url(project.namespace, project, label_name: label.name)
+ expect(doc.css('a').first.attr('href')).to eq urls
+ .namespace_project_issues_url(project.namespace, project, label_name: label.name)
expect(doc.text).to eq 'See 2 factor authentication'
end
@@ -216,8 +216,8 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do
it 'links to a valid reference' do
doc = reference_filter("See #{reference}")
- expect(doc.css('a').first.attr('href')).to eq urls.
- namespace_project_issues_url(project.namespace, project, label_name: label.name)
+ expect(doc.css('a').first.attr('href')).to eq urls
+ .namespace_project_issues_url(project.namespace, project, label_name: label.name)
expect(doc.text).to eq 'See g.fm & references?'
end
@@ -287,8 +287,8 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do
it 'links to a valid reference' do
doc = reference_filter("See #{reference}")
- expect(doc.css('a').first.attr('href')).to eq urls.
- namespace_project_issues_url(project.namespace, project, label_name: label.name)
+ expect(doc.css('a').first.attr('href')).to eq urls
+ .namespace_project_issues_url(project.namespace, project, label_name: label.name)
end
it 'links with adjacent text' do
@@ -324,8 +324,8 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do
it 'links to a valid reference' do
doc = reference_filter("See #{reference}", project: project)
- expect(doc.css('a').first.attr('href')).to eq urls.
- namespace_project_issues_url(project.namespace, project, label_name: group_label.name)
+ expect(doc.css('a').first.attr('href')).to eq urls
+ .namespace_project_issues_url(project.namespace, project, label_name: group_label.name)
expect(doc.text).to eq 'See gfm references'
end
@@ -347,8 +347,8 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do
it 'links to a valid reference' do
doc = reference_filter("See #{reference}", project: project)
- expect(doc.css('a').first.attr('href')).to eq urls.
- namespace_project_issues_url(project.namespace, project, label_name: group_label.name)
+ expect(doc.css('a').first.attr('href')).to eq urls
+ .namespace_project_issues_url(project.namespace, project, label_name: group_label.name)
expect(doc.text).to eq "See gfm references"
end
@@ -447,8 +447,8 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do
end
it 'has valid color' do
- expect(result.css('a span').first.attr('style')).
- to match /background-color: #00ff00/
+ expect(result.css('a span').first.attr('style'))
+ .to match /background-color: #00ff00/
end
it 'has valid link text' do
@@ -483,18 +483,18 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do
end
it 'has valid color' do
- expect(result.css('a span').first.attr('style')).
- to match /background-color: #00ff00/
+ expect(result.css('a span').first.attr('style'))
+ .to match /background-color: #00ff00/
end
it 'has valid link text' do
- expect(result.css('a').first.text).
- to eq "#{group_label.name} in #{another_project.name_with_namespace}"
+ expect(result.css('a').first.text)
+ .to eq "#{group_label.name} in #{another_project.name_with_namespace}"
end
it 'has valid text' do
- expect(result.text).
- to eq "See #{group_label.name} in #{another_project.name_with_namespace}"
+ expect(result.text)
+ .to eq "See #{group_label.name} in #{another_project.name_with_namespace}"
end
it 'ignores invalid IDs on the referenced label' do
@@ -513,25 +513,25 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do
let!(:result) { reference_filter("See #{reference}", project: project) }
it 'points to referenced project issues page' do
- expect(result.css('a').first.attr('href')).
- to eq urls.namespace_project_issues_url(another_project.namespace,
+ expect(result.css('a').first.attr('href'))
+ .to eq urls.namespace_project_issues_url(another_project.namespace,
another_project,
label_name: group_label.name)
end
it 'has valid color' do
- expect(result.css('a span').first.attr('style')).
- to match /background-color: #00ff00/
+ expect(result.css('a span').first.attr('style'))
+ .to match /background-color: #00ff00/
end
it 'has valid link text' do
- expect(result.css('a').first.text).
- to eq "#{group_label.name} in #{another_project.name}"
+ expect(result.css('a').first.text)
+ .to eq "#{group_label.name} in #{another_project.name}"
end
it 'has valid text' do
- expect(result.text).
- to eq "See #{group_label.name} in #{another_project.name}"
+ expect(result.text)
+ .to eq "See #{group_label.name} in #{another_project.name}"
end
it 'ignores invalid IDs on the referenced label' do
@@ -590,8 +590,8 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do
end
it 'has valid color' do
- expect(result.css('a span').first.attr('style')).
- to match /background-color: #00ff00/
+ expect(result.css('a span').first.attr('style'))
+ .to match /background-color: #00ff00/
end
it 'has valid link text' do
diff --git a/spec/lib/banzai/filter/merge_request_reference_filter_spec.rb b/spec/lib/banzai/filter/merge_request_reference_filter_spec.rb
index 40232f6e426..cd91681551e 100644
--- a/spec/lib/banzai/filter/merge_request_reference_filter_spec.rb
+++ b/spec/lib/banzai/filter/merge_request_reference_filter_spec.rb
@@ -36,8 +36,8 @@ describe Banzai::Filter::MergeRequestReferenceFilter, lib: true do
it 'links to a valid reference' do
doc = reference_filter("See #{reference}")
- expect(doc.css('a').first.attr('href')).to eq urls.
- namespace_project_merge_request_url(project.namespace, project, merge)
+ expect(doc.css('a').first.attr('href')).to eq urls
+ .namespace_project_merge_request_url(project.namespace, project, merge)
end
it 'links with adjacent text' do
@@ -107,8 +107,8 @@ describe Banzai::Filter::MergeRequestReferenceFilter, lib: true do
it 'links to a valid reference' do
doc = reference_filter("See #{reference}")
- expect(doc.css('a').first.attr('href')).
- to eq urls.namespace_project_merge_request_url(project2.namespace,
+ expect(doc.css('a').first.attr('href'))
+ .to eq urls.namespace_project_merge_request_url(project2.namespace,
project2, merge)
end
@@ -141,8 +141,8 @@ describe Banzai::Filter::MergeRequestReferenceFilter, lib: true do
it 'links to a valid reference' do
doc = reference_filter("See #{reference}")
- expect(doc.css('a').first.attr('href')).
- to eq urls.namespace_project_merge_request_url(project2.namespace,
+ expect(doc.css('a').first.attr('href'))
+ .to eq urls.namespace_project_merge_request_url(project2.namespace,
project2, merge)
end
@@ -175,8 +175,8 @@ describe Banzai::Filter::MergeRequestReferenceFilter, lib: true do
it 'links to a valid reference' do
doc = reference_filter("See #{reference}")
- expect(doc.css('a').first.attr('href')).
- to eq urls.namespace_project_merge_request_url(project2.namespace,
+ expect(doc.css('a').first.attr('href'))
+ .to eq urls.namespace_project_merge_request_url(project2.namespace,
project2, merge)
end
@@ -208,8 +208,8 @@ describe Banzai::Filter::MergeRequestReferenceFilter, lib: true do
it 'links to a valid reference' do
doc = reference_filter("See #{reference}")
- expect(doc.css('a').first.attr('href')).
- to eq reference
+ expect(doc.css('a').first.attr('href'))
+ .to eq reference
end
it 'links with adjacent text' do
diff --git a/spec/lib/banzai/filter/milestone_reference_filter_spec.rb b/spec/lib/banzai/filter/milestone_reference_filter_spec.rb
index a317c751d32..fe88b9cb73e 100644
--- a/spec/lib/banzai/filter/milestone_reference_filter_spec.rb
+++ b/spec/lib/banzai/filter/milestone_reference_filter_spec.rb
@@ -44,16 +44,16 @@ describe Banzai::Filter::MilestoneReferenceFilter, lib: true do
link = doc.css('a').first.attr('href')
expect(link).not_to match %r(https?://)
- expect(link).to eq urls.
- namespace_project_milestone_path(project.namespace, project, milestone)
+ expect(link).to eq urls
+ .namespace_project_milestone_path(project.namespace, project, milestone)
end
context 'Integer-based references' do
it 'links to a valid reference' do
doc = reference_filter("See #{reference}")
- expect(doc.css('a').first.attr('href')).to eq urls.
- namespace_project_milestone_url(project.namespace, project, milestone)
+ expect(doc.css('a').first.attr('href')).to eq urls
+ .namespace_project_milestone_url(project.namespace, project, milestone)
end
it 'links with adjacent text' do
@@ -75,8 +75,8 @@ describe Banzai::Filter::MilestoneReferenceFilter, lib: true do
it 'links to a valid reference' do
doc = reference_filter("See #{reference}")
- expect(doc.css('a').first.attr('href')).to eq urls.
- namespace_project_milestone_url(project.namespace, project, milestone)
+ expect(doc.css('a').first.attr('href')).to eq urls
+ .namespace_project_milestone_url(project.namespace, project, milestone)
expect(doc.text).to eq 'See gfm'
end
@@ -99,8 +99,8 @@ describe Banzai::Filter::MilestoneReferenceFilter, lib: true do
it 'links to a valid reference' do
doc = reference_filter("See #{reference}")
- expect(doc.css('a').first.attr('href')).to eq urls.
- namespace_project_milestone_url(project.namespace, project, milestone)
+ expect(doc.css('a').first.attr('href')).to eq urls
+ .namespace_project_milestone_url(project.namespace, project, milestone)
expect(doc.text).to eq 'See gfm references'
end
@@ -122,8 +122,8 @@ describe Banzai::Filter::MilestoneReferenceFilter, lib: true do
it 'links to a valid reference' do
doc = reference_filter("See #{reference}")
- expect(doc.css('a').first.attr('href')).to eq urls.
- namespace_project_milestone_url(project.namespace, project, milestone)
+ expect(doc.css('a').first.attr('href')).to eq urls
+ .namespace_project_milestone_url(project.namespace, project, milestone)
end
it 'links with adjacent text' do
@@ -156,8 +156,8 @@ describe Banzai::Filter::MilestoneReferenceFilter, lib: true do
let!(:result) { reference_filter("See #{reference}") }
it 'points to referenced project milestone page' do
- expect(result.css('a').first.attr('href')).to eq urls.
- namespace_project_milestone_url(another_project.namespace,
+ expect(result.css('a').first.attr('href')).to eq urls
+ .namespace_project_milestone_url(another_project.namespace,
another_project,
milestone)
end
@@ -165,15 +165,15 @@ describe Banzai::Filter::MilestoneReferenceFilter, lib: true do
it 'link has valid text' do
doc = reference_filter("See (#{reference}.)")
- expect(doc.css('a').first.text).
- to eq("#{milestone.name} in #{another_project.path_with_namespace}")
+ expect(doc.css('a').first.text)
+ .to eq("#{milestone.name} in #{another_project.path_with_namespace}")
end
it 'has valid text' do
doc = reference_filter("See (#{reference}.)")
- expect(doc.text).
- to eq("See (#{milestone.name} in #{another_project.path_with_namespace}.)")
+ expect(doc.text)
+ .to eq("See (#{milestone.name} in #{another_project.path_with_namespace}.)")
end
it 'escapes the name attribute' do
@@ -181,8 +181,8 @@ describe Banzai::Filter::MilestoneReferenceFilter, lib: true do
doc = reference_filter("See #{reference}")
- expect(doc.css('a').first.text).
- to eq "#{milestone.name} in #{another_project.path_with_namespace}"
+ expect(doc.css('a').first.text)
+ .to eq "#{milestone.name} in #{another_project.path_with_namespace}"
end
end
@@ -195,8 +195,8 @@ describe Banzai::Filter::MilestoneReferenceFilter, lib: true do
let!(:result) { reference_filter("See #{reference}") }
it 'points to referenced project milestone page' do
- expect(result.css('a').first.attr('href')).to eq urls.
- namespace_project_milestone_url(another_project.namespace,
+ expect(result.css('a').first.attr('href')).to eq urls
+ .namespace_project_milestone_url(another_project.namespace,
another_project,
milestone)
end
@@ -204,15 +204,15 @@ describe Banzai::Filter::MilestoneReferenceFilter, lib: true do
it 'link has valid text' do
doc = reference_filter("See (#{reference}.)")
- expect(doc.css('a').first.text).
- to eq("#{milestone.name} in #{another_project.path}")
+ expect(doc.css('a').first.text)
+ .to eq("#{milestone.name} in #{another_project.path}")
end
it 'has valid text' do
doc = reference_filter("See (#{reference}.)")
- expect(doc.text).
- to eq("See (#{milestone.name} in #{another_project.path}.)")
+ expect(doc.text)
+ .to eq("See (#{milestone.name} in #{another_project.path}.)")
end
it 'escapes the name attribute' do
@@ -220,8 +220,8 @@ describe Banzai::Filter::MilestoneReferenceFilter, lib: true do
doc = reference_filter("See #{reference}")
- expect(doc.css('a').first.text).
- to eq "#{milestone.name} in #{another_project.path}"
+ expect(doc.css('a').first.text)
+ .to eq "#{milestone.name} in #{another_project.path}"
end
end
@@ -234,8 +234,8 @@ describe Banzai::Filter::MilestoneReferenceFilter, lib: true do
let!(:result) { reference_filter("See #{reference}") }
it 'points to referenced project milestone page' do
- expect(result.css('a').first.attr('href')).to eq urls.
- namespace_project_milestone_url(another_project.namespace,
+ expect(result.css('a').first.attr('href')).to eq urls
+ .namespace_project_milestone_url(another_project.namespace,
another_project,
milestone)
end
@@ -243,15 +243,15 @@ describe Banzai::Filter::MilestoneReferenceFilter, lib: true do
it 'link has valid text' do
doc = reference_filter("See (#{reference}.)")
- expect(doc.css('a').first.text).
- to eq("#{milestone.name} in #{another_project.path}")
+ expect(doc.css('a').first.text)
+ .to eq("#{milestone.name} in #{another_project.path}")
end
it 'has valid text' do
doc = reference_filter("See (#{reference}.)")
- expect(doc.text).
- to eq("See (#{milestone.name} in #{another_project.path}.)")
+ expect(doc.text)
+ .to eq("See (#{milestone.name} in #{another_project.path}.)")
end
it 'escapes the name attribute' do
@@ -259,8 +259,8 @@ describe Banzai::Filter::MilestoneReferenceFilter, lib: true do
doc = reference_filter("See #{reference}")
- expect(doc.css('a').first.text).
- to eq "#{milestone.name} in #{another_project.path}"
+ expect(doc.css('a').first.text)
+ .to eq "#{milestone.name} in #{another_project.path}"
end
end
end
diff --git a/spec/lib/banzai/filter/redactor_filter_spec.rb b/spec/lib/banzai/filter/redactor_filter_spec.rb
index 97504aebed5..b81cdbb8957 100644
--- a/spec/lib/banzai/filter/redactor_filter_spec.rb
+++ b/spec/lib/banzai/filter/redactor_filter_spec.rb
@@ -33,9 +33,9 @@ describe Banzai::Filter::RedactorFilter, lib: true do
end
before do
- allow(Banzai::ReferenceParser).to receive(:[]).
- with('test').
- and_return(parser_class)
+ allow(Banzai::ReferenceParser).to receive(:[])
+ .with('test')
+ .and_return(parser_class)
end
context 'valid projects' do
diff --git a/spec/lib/banzai/filter/reference_filter_spec.rb b/spec/lib/banzai/filter/reference_filter_spec.rb
index 55e681f6faf..ba0fa4a609a 100644
--- a/spec/lib/banzai/filter/reference_filter_spec.rb
+++ b/spec/lib/banzai/filter/reference_filter_spec.rb
@@ -8,8 +8,8 @@ describe Banzai::Filter::ReferenceFilter, lib: true do
document = Nokogiri::HTML.fragment('<a href="foo">foo</a>')
filter = described_class.new(document, project: project)
- expect { |b| filter.each_node(&b) }.
- to yield_with_args(an_instance_of(Nokogiri::XML::Element))
+ expect { |b| filter.each_node(&b) }
+ .to yield_with_args(an_instance_of(Nokogiri::XML::Element))
end
it 'returns an Enumerator when no block is given' do
diff --git a/spec/lib/banzai/filter/relative_link_filter_spec.rb b/spec/lib/banzai/filter/relative_link_filter_spec.rb
index 1957ba739e2..1ce7bd7706e 100644
--- a/spec/lib/banzai/filter/relative_link_filter_spec.rb
+++ b/spec/lib/banzai/filter/relative_link_filter_spec.rb
@@ -72,15 +72,15 @@ describe Banzai::Filter::RelativeLinkFilter, lib: true do
it 'ignores ref if commit is passed' do
doc = filter(link('non/existent.file'), commit: project.commit('empty-branch') )
- expect(doc.at_css('a')['href']).
- to eq "/#{project_path}/#{ref}/non/existent.file" # non-existent files have no leading blob/raw/tree
+ expect(doc.at_css('a')['href'])
+ .to eq "/#{project_path}/#{ref}/non/existent.file" # non-existent files have no leading blob/raw/tree
end
shared_examples :valid_repository do
it 'rebuilds absolute URL for a file in the repo' do
doc = filter(link('/doc/api/README.md'))
- expect(doc.at_css('a')['href']).
- to eq "/#{project_path}/blob/#{ref}/doc/api/README.md"
+ expect(doc.at_css('a')['href'])
+ .to eq "/#{project_path}/blob/#{ref}/doc/api/README.md"
end
it 'ignores absolute URLs with two leading slashes' do
@@ -90,71 +90,71 @@ describe Banzai::Filter::RelativeLinkFilter, lib: true do
it 'rebuilds relative URL for a file in the repo' do
doc = filter(link('doc/api/README.md'))
- expect(doc.at_css('a')['href']).
- to eq "/#{project_path}/blob/#{ref}/doc/api/README.md"
+ expect(doc.at_css('a')['href'])
+ .to eq "/#{project_path}/blob/#{ref}/doc/api/README.md"
end
it 'rebuilds relative URL for a file in the repo with leading ./' do
doc = filter(link('./doc/api/README.md'))
- expect(doc.at_css('a')['href']).
- to eq "/#{project_path}/blob/#{ref}/doc/api/README.md"
+ expect(doc.at_css('a')['href'])
+ .to eq "/#{project_path}/blob/#{ref}/doc/api/README.md"
end
it 'rebuilds relative URL for a file in the repo up one directory' do
relative_link = link('../api/README.md')
doc = filter(relative_link, requested_path: 'doc/update/7.14-to-8.0.md')
- expect(doc.at_css('a')['href']).
- to eq "/#{project_path}/blob/#{ref}/doc/api/README.md"
+ expect(doc.at_css('a')['href'])
+ .to eq "/#{project_path}/blob/#{ref}/doc/api/README.md"
end
it 'rebuilds relative URL for a file in the repo up multiple directories' do
relative_link = link('../../../api/README.md')
doc = filter(relative_link, requested_path: 'doc/foo/bar/baz/README.md')
- expect(doc.at_css('a')['href']).
- to eq "/#{project_path}/blob/#{ref}/doc/api/README.md"
+ expect(doc.at_css('a')['href'])
+ .to eq "/#{project_path}/blob/#{ref}/doc/api/README.md"
end
it 'rebuilds relative URL for a file in the repository root' do
relative_link = link('../README.md')
doc = filter(relative_link, requested_path: 'doc/some-file.md')
- expect(doc.at_css('a')['href']).
- to eq "/#{project_path}/blob/#{ref}/README.md"
+ expect(doc.at_css('a')['href'])
+ .to eq "/#{project_path}/blob/#{ref}/README.md"
end
it 'rebuilds relative URL for a file in the repo with an anchor' do
doc = filter(link('README.md#section'))
- expect(doc.at_css('a')['href']).
- to eq "/#{project_path}/blob/#{ref}/README.md#section"
+ expect(doc.at_css('a')['href'])
+ .to eq "/#{project_path}/blob/#{ref}/README.md#section"
end
it 'rebuilds relative URL for a directory in the repo' do
doc = filter(link('doc/api/'))
- expect(doc.at_css('a')['href']).
- to eq "/#{project_path}/tree/#{ref}/doc/api"
+ expect(doc.at_css('a')['href'])
+ .to eq "/#{project_path}/tree/#{ref}/doc/api"
end
it 'rebuilds relative URL for an image in the repo' do
doc = filter(image('files/images/logo-black.png'))
- expect(doc.at_css('img')['src']).
- to eq "/#{project_path}/raw/#{ref}/files/images/logo-black.png"
+ expect(doc.at_css('img')['src'])
+ .to eq "/#{project_path}/raw/#{ref}/files/images/logo-black.png"
end
it 'rebuilds relative URL for link to an image in the repo' do
doc = filter(link('files/images/logo-black.png'))
- expect(doc.at_css('a')['href']).
- to eq "/#{project_path}/raw/#{ref}/files/images/logo-black.png"
+ expect(doc.at_css('a')['href'])
+ .to eq "/#{project_path}/raw/#{ref}/files/images/logo-black.png"
end
it 'rebuilds relative URL for a video in the repo' do
doc = filter(video('files/videos/intro.mp4'), commit: project.commit('video'), ref: 'video')
- expect(doc.at_css('video')['src']).
- to eq "/#{project_path}/raw/video/files/videos/intro.mp4"
+ expect(doc.at_css('video')['src'])
+ .to eq "/#{project_path}/raw/video/files/videos/intro.mp4"
end
it 'does not modify relative URL with an anchor only' do
diff --git a/spec/lib/banzai/filter/sanitization_filter_spec.rb b/spec/lib/banzai/filter/sanitization_filter_spec.rb
index fb7862f49a2..a8a0aa6d395 100644
--- a/spec/lib/banzai/filter/sanitization_filter_spec.rb
+++ b/spec/lib/banzai/filter/sanitization_filter_spec.rb
@@ -221,8 +221,8 @@ describe Banzai::Filter::SanitizationFilter, lib: true do
end
it 'disallows invalid URIs' do
- expect(Addressable::URI).to receive(:parse).with('foo://example.com').
- and_raise(Addressable::URI::InvalidURIError)
+ expect(Addressable::URI).to receive(:parse).with('foo://example.com')
+ .and_raise(Addressable::URI::InvalidURIError)
input = '<a href="foo://example.com">Foo</a>'
output = filter(input)
diff --git a/spec/lib/banzai/filter/snippet_reference_filter_spec.rb b/spec/lib/banzai/filter/snippet_reference_filter_spec.rb
index e036514d283..e851120bc3a 100644
--- a/spec/lib/banzai/filter/snippet_reference_filter_spec.rb
+++ b/spec/lib/banzai/filter/snippet_reference_filter_spec.rb
@@ -22,8 +22,8 @@ describe Banzai::Filter::SnippetReferenceFilter, lib: true do
it 'links to a valid reference' do
doc = reference_filter("See #{reference}")
- expect(doc.css('a').first.attr('href')).to eq urls.
- namespace_project_snippet_url(project.namespace, project, snippet)
+ expect(doc.css('a').first.attr('href')).to eq urls
+ .namespace_project_snippet_url(project.namespace, project, snippet)
end
it 'links with adjacent text' do
@@ -88,8 +88,8 @@ describe Banzai::Filter::SnippetReferenceFilter, lib: true do
it 'links to a valid reference' do
doc = reference_filter("See #{reference}")
- expect(doc.css('a').first.attr('href')).
- to eq urls.namespace_project_snippet_url(project2.namespace, project2, snippet)
+ expect(doc.css('a').first.attr('href'))
+ .to eq urls.namespace_project_snippet_url(project2.namespace, project2, snippet)
end
it 'link has valid text' do
@@ -121,8 +121,8 @@ describe Banzai::Filter::SnippetReferenceFilter, lib: true do
it 'links to a valid reference' do
doc = reference_filter("See #{reference}")
- expect(doc.css('a').first.attr('href')).
- to eq urls.namespace_project_snippet_url(project2.namespace, project2, snippet)
+ expect(doc.css('a').first.attr('href'))
+ .to eq urls.namespace_project_snippet_url(project2.namespace, project2, snippet)
end
it 'link has valid text' do
@@ -154,8 +154,8 @@ describe Banzai::Filter::SnippetReferenceFilter, lib: true do
it 'links to a valid reference' do
doc = reference_filter("See #{reference}")
- expect(doc.css('a').first.attr('href')).
- to eq urls.namespace_project_snippet_url(project2.namespace, project2, snippet)
+ expect(doc.css('a').first.attr('href'))
+ .to eq urls.namespace_project_snippet_url(project2.namespace, project2, snippet)
end
it 'link has valid text' do
@@ -186,8 +186,8 @@ describe Banzai::Filter::SnippetReferenceFilter, lib: true do
it 'links to a valid reference' do
doc = reference_filter("See #{reference}")
- expect(doc.css('a').first.attr('href')).
- to eq urls.namespace_project_snippet_url(project2.namespace, project2, snippet)
+ expect(doc.css('a').first.attr('href'))
+ .to eq urls.namespace_project_snippet_url(project2.namespace, project2, snippet)
end
it 'links with adjacent text' do
diff --git a/spec/lib/banzai/filter/upload_link_filter_spec.rb b/spec/lib/banzai/filter/upload_link_filter_spec.rb
index 639cac6406a..6327ca8bbfd 100644
--- a/spec/lib/banzai/filter/upload_link_filter_spec.rb
+++ b/spec/lib/banzai/filter/upload_link_filter_spec.rb
@@ -51,22 +51,22 @@ describe Banzai::Filter::UploadLinkFilter, lib: true do
context 'with a valid repository' do
it 'rebuilds relative URL for a link' do
doc = filter(link('/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg'))
- expect(doc.at_css('a')['href']).
- to eq "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg"
+ expect(doc.at_css('a')['href'])
+ .to eq "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg"
doc = filter(nested_link('/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg'))
- expect(doc.at_css('a')['href']).
- to eq "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg"
+ expect(doc.at_css('a')['href'])
+ .to eq "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg"
end
it 'rebuilds relative URL for an image' do
doc = filter(image('/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg'))
- expect(doc.at_css('img')['src']).
- to eq "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg"
+ expect(doc.at_css('img')['src'])
+ .to eq "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg"
doc = filter(nested_image('/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg'))
- expect(doc.at_css('img')['src']).
- to eq "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg"
+ expect(doc.at_css('img')['src'])
+ .to eq "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg"
end
it 'does not modify absolute URL' do
@@ -79,10 +79,10 @@ describe Banzai::Filter::UploadLinkFilter, lib: true do
escaped = Addressable::URI.escape(path)
# Stub these methods so the file doesn't actually need to be in the repo
- allow_any_instance_of(described_class).
- to receive(:file_exists?).and_return(true)
- allow_any_instance_of(described_class).
- to receive(:image?).with(path).and_return(true)
+ allow_any_instance_of(described_class)
+ .to receive(:file_exists?).and_return(true)
+ allow_any_instance_of(described_class)
+ .to receive(:image?).with(path).and_return(true)
doc = filter(image(escaped))
expect(doc.at_css('img')['src']).to match "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/uploads/%ED%95%9C%EA%B8%80.png"
diff --git a/spec/lib/banzai/note_renderer_spec.rb b/spec/lib/banzai/note_renderer_spec.rb
index 49556074278..32764bee5eb 100644
--- a/spec/lib/banzai/note_renderer_spec.rb
+++ b/spec/lib/banzai/note_renderer_spec.rb
@@ -8,15 +8,15 @@ describe Banzai::NoteRenderer do
wiki = double(:wiki)
user = double(:user)
- expect(Banzai::ObjectRenderer).to receive(:new).
- with(project, user,
+ expect(Banzai::ObjectRenderer).to receive(:new)
+ .with(project, user,
requested_path: 'foo',
project_wiki: wiki,
- ref: 'bar').
- and_call_original
+ ref: 'bar')
+ .and_call_original
- expect_any_instance_of(Banzai::ObjectRenderer).
- to receive(:render).with([note], :note)
+ expect_any_instance_of(Banzai::ObjectRenderer)
+ .to receive(:render).with([note], :note)
described_class.render([note], project, user, 'foo', wiki, 'bar')
end
diff --git a/spec/lib/banzai/redactor_spec.rb b/spec/lib/banzai/redactor_spec.rb
index e6f2963193c..81ae5685b10 100644
--- a/spec/lib/banzai/redactor_spec.rb
+++ b/spec/lib/banzai/redactor_spec.rb
@@ -12,11 +12,11 @@ describe Banzai::Redactor do
end
it 'redacts an array of documents' do
- doc1 = Nokogiri::HTML.
- fragment('<a class="gfm" data-reference-type="issue">foo</a>')
+ doc1 = Nokogiri::HTML
+ .fragment('<a class="gfm" data-reference-type="issue">foo</a>')
- doc2 = Nokogiri::HTML.
- fragment('<a class="gfm" data-reference-type="issue">bar</a>')
+ doc2 = Nokogiri::HTML
+ .fragment('<a class="gfm" data-reference-type="issue">bar</a>')
redacted_data = redactor.redact([doc1, doc2])
@@ -93,9 +93,9 @@ describe Banzai::Redactor do
doc = Nokogiri::HTML.fragment('<a href="foo">foo</a>')
node = doc.children[0]
- expect(redactor).to receive(:nodes_visible_to_user).
- with([node]).
- and_return(Set.new)
+ expect(redactor).to receive(:nodes_visible_to_user)
+ .with([node])
+ .and_return(Set.new)
redactor.redact_document_nodes([{ document: doc, nodes: [node] }])
@@ -108,10 +108,10 @@ describe Banzai::Redactor do
doc = Nokogiri::HTML.fragment('<a data-reference-type="issue"></a>')
node = doc.children[0]
- expect_any_instance_of(Banzai::ReferenceParser::IssueParser).
- to receive(:nodes_visible_to_user).
- with(user, [node]).
- and_return([node])
+ expect_any_instance_of(Banzai::ReferenceParser::IssueParser)
+ .to receive(:nodes_visible_to_user)
+ .with(user, [node])
+ .and_return([node])
expect(redactor.nodes_visible_to_user([node])).to eq(Set.new([node]))
end
diff --git a/spec/lib/banzai/reference_parser/base_parser_spec.rb b/spec/lib/banzai/reference_parser/base_parser_spec.rb
index 76fab93821a..b444ca05b8e 100644
--- a/spec/lib/banzai/reference_parser/base_parser_spec.rb
+++ b/spec/lib/banzai/reference_parser/base_parser_spec.rb
@@ -54,8 +54,8 @@ describe Banzai::ReferenceParser::BaseParser, lib: true do
describe '#referenced_by' do
context 'when references_relation is implemented' do
it 'returns a collection of objects' do
- links = Nokogiri::HTML.fragment("<a data-foo='#{user.id}'></a>").
- children
+ links = Nokogiri::HTML.fragment("<a data-foo='#{user.id}'></a>")
+ .children
expect(subject).to receive(:references_relation).and_return(User)
expect(subject.referenced_by(links)).to eq([user])
@@ -66,8 +66,8 @@ describe Banzai::ReferenceParser::BaseParser, lib: true do
it 'raises NotImplementedError' do
links = Nokogiri::HTML.fragment('<a data-foo="1"></a>').children
- expect { subject.referenced_by(links) }.
- to raise_error(NotImplementedError)
+ expect { subject.referenced_by(links) }
+ .to raise_error(NotImplementedError)
end
end
end
@@ -80,8 +80,8 @@ describe Banzai::ReferenceParser::BaseParser, lib: true do
describe '#gather_attributes_per_project' do
it 'returns a Hash containing attribute values per project' do
- link = Nokogiri::HTML.fragment('<a data-project="1" data-foo="2"></a>').
- children[0]
+ link = Nokogiri::HTML.fragment('<a data-project="1" data-foo="2"></a>')
+ .children[0]
hash = subject.gather_attributes_per_project([link], 'data-foo')
@@ -95,19 +95,19 @@ describe Banzai::ReferenceParser::BaseParser, lib: true do
it 'returns a Hash grouping objects per node' do
link = double(:link)
- expect(link).to receive(:has_attribute?).
- with('data-user').
- and_return(true)
+ expect(link).to receive(:has_attribute?)
+ .with('data-user')
+ .and_return(true)
- expect(link).to receive(:attr).
- with('data-user').
- and_return(user.id.to_s)
+ expect(link).to receive(:attr)
+ .with('data-user')
+ .and_return(user.id.to_s)
nodes = [link]
- expect(subject).to receive(:unique_attribute_values).
- with(nodes, 'data-user').
- and_return([user.id.to_s])
+ expect(subject).to receive(:unique_attribute_values)
+ .with(nodes, 'data-user')
+ .and_return([user.id.to_s])
hash = subject.grouped_objects_for_nodes(nodes, User, 'data-user')
@@ -117,20 +117,20 @@ describe Banzai::ReferenceParser::BaseParser, lib: true do
it 'returns an empty Hash when entry does not exist in the database', :request_store do
link = double(:link)
- expect(link).to receive(:has_attribute?).
- with('data-user').
- and_return(true)
+ expect(link).to receive(:has_attribute?)
+ .with('data-user')
+ .and_return(true)
- expect(link).to receive(:attr).
- with('data-user').
- and_return('1')
+ expect(link).to receive(:attr)
+ .with('data-user')
+ .and_return('1')
nodes = [link]
bad_id = user.id + 100
- expect(subject).to receive(:unique_attribute_values).
- with(nodes, 'data-user').
- and_return([bad_id.to_s])
+ expect(subject).to receive(:unique_attribute_values)
+ .with(nodes, 'data-user')
+ .and_return([bad_id.to_s])
hash = subject.grouped_objects_for_nodes(nodes, User, 'data-user')
@@ -142,15 +142,15 @@ describe Banzai::ReferenceParser::BaseParser, lib: true do
it 'returns an Array of unique values' do
link = double(:link)
- expect(link).to receive(:has_attribute?).
- with('data-foo').
- twice.
- and_return(true)
+ expect(link).to receive(:has_attribute?)
+ .with('data-foo')
+ .twice
+ .and_return(true)
- expect(link).to receive(:attr).
- with('data-foo').
- twice.
- and_return('1')
+ expect(link).to receive(:attr)
+ .with('data-foo')
+ .twice
+ .and_return('1')
nodes = [link, link]
@@ -167,9 +167,9 @@ describe Banzai::ReferenceParser::BaseParser, lib: true do
instance = dummy.new(project, user)
document = Nokogiri::HTML.fragment('<a class="gfm"></a><a class="gfm" data-reference-type="test"></a>')
- expect(instance).to receive(:gather_references).
- with([document.children[1]]).
- and_return([user])
+ expect(instance).to receive(:gather_references)
+ .with([document.children[1]])
+ .and_return([user])
expect(instance.process([document])).to eq([user])
end
@@ -179,9 +179,9 @@ describe Banzai::ReferenceParser::BaseParser, lib: true do
let(:link) { double(:link) }
it 'does not process links a user can not reference' do
- expect(subject).to receive(:nodes_user_can_reference).
- with(user, [link]).
- and_return([])
+ expect(subject).to receive(:nodes_user_can_reference)
+ .with(user, [link])
+ .and_return([])
expect(subject).to receive(:referenced_by).with([])
@@ -189,13 +189,13 @@ describe Banzai::ReferenceParser::BaseParser, lib: true do
end
it 'does not process links a user can not see' do
- expect(subject).to receive(:nodes_user_can_reference).
- with(user, [link]).
- and_return([link])
+ expect(subject).to receive(:nodes_user_can_reference)
+ .with(user, [link])
+ .and_return([link])
- expect(subject).to receive(:nodes_visible_to_user).
- with(user, [link]).
- and_return([])
+ expect(subject).to receive(:nodes_visible_to_user)
+ .with(user, [link])
+ .and_return([])
expect(subject).to receive(:referenced_by).with([])
@@ -203,13 +203,13 @@ describe Banzai::ReferenceParser::BaseParser, lib: true do
end
it 'returns the references if a user can reference and see a link' do
- expect(subject).to receive(:nodes_user_can_reference).
- with(user, [link]).
- and_return([link])
+ expect(subject).to receive(:nodes_user_can_reference)
+ .with(user, [link])
+ .and_return([link])
- expect(subject).to receive(:nodes_visible_to_user).
- with(user, [link]).
- and_return([link])
+ expect(subject).to receive(:nodes_visible_to_user)
+ .with(user, [link])
+ .and_return([link])
expect(subject).to receive(:referenced_by).with([link])
@@ -221,8 +221,8 @@ describe Banzai::ReferenceParser::BaseParser, lib: true do
it 'delegates the permissions check to the Ability class' do
user = double(:user)
- expect(Ability).to receive(:allowed?).
- with(user, :read_project, project)
+ expect(Ability).to receive(:allowed?)
+ .with(user, :read_project, project)
subject.can?(user, :read_project, project)
end
@@ -230,8 +230,8 @@ describe Banzai::ReferenceParser::BaseParser, lib: true do
describe '#find_projects_for_hash_keys' do
it 'returns a list of Projects' do
- expect(subject.find_projects_for_hash_keys(project.id => project)).
- to eq([project])
+ expect(subject.find_projects_for_hash_keys(project.id => project))
+ .to eq([project])
end
end
@@ -243,8 +243,8 @@ describe Banzai::ReferenceParser::BaseParser, lib: true do
expect(collection).to receive(:where).twice.and_call_original
2.times do
- expect(subject.collection_objects_for_ids(collection, [user.id])).
- to eq([user])
+ expect(subject.collection_objects_for_ids(collection, [user.id]))
+ .to eq([user])
end
end
end
@@ -258,8 +258,8 @@ describe Banzai::ReferenceParser::BaseParser, lib: true do
end
it 'queries the collection on the first call' do
- expect(subject.collection_objects_for_ids(User, [user.id])).
- to eq([user])
+ expect(subject.collection_objects_for_ids(User, [user.id]))
+ .to eq([user])
end
it 'does not query previously queried objects' do
@@ -268,34 +268,34 @@ describe Banzai::ReferenceParser::BaseParser, lib: true do
expect(collection).to receive(:where).once.and_call_original
2.times do
- expect(subject.collection_objects_for_ids(collection, [user.id])).
- to eq([user])
+ expect(subject.collection_objects_for_ids(collection, [user.id]))
+ .to eq([user])
end
end
it 'casts String based IDs to Fixnums before querying objects' do
2.times do
- expect(subject.collection_objects_for_ids(User, [user.id.to_s])).
- to eq([user])
+ expect(subject.collection_objects_for_ids(User, [user.id.to_s]))
+ .to eq([user])
end
end
it 'queries any additional objects after the first call' do
other_user = create(:user)
- expect(subject.collection_objects_for_ids(User, [user.id])).
- to eq([user])
+ expect(subject.collection_objects_for_ids(User, [user.id]))
+ .to eq([user])
- expect(subject.collection_objects_for_ids(User, [user.id, other_user.id])).
- to eq([user, other_user])
+ expect(subject.collection_objects_for_ids(User, [user.id, other_user.id]))
+ .to eq([user, other_user])
end
it 'caches objects on a per collection class basis' do
- expect(subject.collection_objects_for_ids(User, [user.id])).
- to eq([user])
+ expect(subject.collection_objects_for_ids(User, [user.id]))
+ .to eq([user])
- expect(subject.collection_objects_for_ids(Project, [project.id])).
- to eq([project])
+ expect(subject.collection_objects_for_ids(Project, [project.id]))
+ .to eq([project])
end
end
end
diff --git a/spec/lib/banzai/reference_parser/commit_parser_spec.rb b/spec/lib/banzai/reference_parser/commit_parser_spec.rb
index 583ce63a8ab..a314a6119cb 100644
--- a/spec/lib/banzai/reference_parser/commit_parser_spec.rb
+++ b/spec/lib/banzai/reference_parser/commit_parser_spec.rb
@@ -32,30 +32,30 @@ describe Banzai::ReferenceParser::CommitParser, lib: true do
it 'returns an Array of commits' do
commit = double(:commit)
- allow_any_instance_of(Project).to receive(:valid_repo?).
- and_return(true)
+ allow_any_instance_of(Project).to receive(:valid_repo?)
+ .and_return(true)
- expect(subject).to receive(:find_commits).
- with(project, ['123']).
- and_return([commit])
+ expect(subject).to receive(:find_commits)
+ .with(project, ['123'])
+ .and_return([commit])
expect(subject.referenced_by([link])).to eq([commit])
end
it 'returns an empty Array when the commit could not be found' do
- allow_any_instance_of(Project).to receive(:valid_repo?).
- and_return(true)
+ allow_any_instance_of(Project).to receive(:valid_repo?)
+ .and_return(true)
- expect(subject).to receive(:find_commits).
- with(project, ['123']).
- and_return([])
+ expect(subject).to receive(:find_commits)
+ .with(project, ['123'])
+ .and_return([])
expect(subject.referenced_by([link])).to eq([])
end
it 'skips projects without valid repositories' do
- allow_any_instance_of(Project).to receive(:valid_repo?).
- and_return(false)
+ allow_any_instance_of(Project).to receive(:valid_repo?)
+ .and_return(false)
expect(subject.referenced_by([link])).to eq([])
end
@@ -63,8 +63,8 @@ describe Banzai::ReferenceParser::CommitParser, lib: true do
context 'when the link does not have a data-commit attribute' do
it 'returns an empty Array' do
- allow_any_instance_of(Project).to receive(:valid_repo?).
- and_return(true)
+ allow_any_instance_of(Project).to receive(:valid_repo?)
+ .and_return(true)
expect(subject.referenced_by([link])).to eq([])
end
@@ -73,8 +73,8 @@ describe Banzai::ReferenceParser::CommitParser, lib: true do
context 'when the link does not have a data-project attribute' do
it 'returns an empty Array' do
- allow_any_instance_of(Project).to receive(:valid_repo?).
- and_return(true)
+ allow_any_instance_of(Project).to receive(:valid_repo?)
+ .and_return(true)
expect(subject.referenced_by([link])).to eq([])
end
diff --git a/spec/lib/banzai/reference_parser/commit_range_parser_spec.rb b/spec/lib/banzai/reference_parser/commit_range_parser_spec.rb
index 8c0f5d7df97..5dca5e784da 100644
--- a/spec/lib/banzai/reference_parser/commit_range_parser_spec.rb
+++ b/spec/lib/banzai/reference_parser/commit_range_parser_spec.rb
@@ -32,17 +32,17 @@ describe Banzai::ReferenceParser::CommitRangeParser, lib: true do
it 'returns an Array of commit ranges' do
range = double(:range)
- expect(subject).to receive(:find_object).
- with(project, '123..456').
- and_return(range)
+ expect(subject).to receive(:find_object)
+ .with(project, '123..456')
+ .and_return(range)
expect(subject.referenced_by([link])).to eq([range])
end
it 'returns an empty Array when the commit range could not be found' do
- expect(subject).to receive(:find_object).
- with(project, '123..456').
- and_return(nil)
+ expect(subject).to receive(:find_object)
+ .with(project, '123..456')
+ .and_return(nil)
expect(subject.referenced_by([link])).to eq([])
end
@@ -88,17 +88,17 @@ describe Banzai::ReferenceParser::CommitRangeParser, lib: true do
it 'returns an Array of range objects' do
range = double(:commit)
- expect(subject).to receive(:find_object).
- with(project, '123..456').
- and_return(range)
+ expect(subject).to receive(:find_object)
+ .with(project, '123..456')
+ .and_return(range)
expect(subject.find_ranges(project, ['123..456'])).to eq([range])
end
it 'skips ranges that could not be found' do
- expect(subject).to receive(:find_object).
- with(project, '123..456').
- and_return(nil)
+ expect(subject).to receive(:find_object)
+ .with(project, '123..456')
+ .and_return(nil)
expect(subject.find_ranges(project, ['123..456'])).to eq([])
end
diff --git a/spec/lib/banzai/reference_parser/issue_parser_spec.rb b/spec/lib/banzai/reference_parser/issue_parser_spec.rb
index 7031c47231c..58e1a0c1bc1 100644
--- a/spec/lib/banzai/reference_parser/issue_parser_spec.rb
+++ b/spec/lib/banzai/reference_parser/issue_parser_spec.rb
@@ -18,17 +18,17 @@ describe Banzai::ReferenceParser::IssueParser, lib: true do
it_behaves_like "referenced feature visibility", "issues"
it 'returns the nodes when the user can read the issue' do
- expect(Ability).to receive(:issues_readable_by_user).
- with([issue], user).
- and_return([issue])
+ expect(Ability).to receive(:issues_readable_by_user)
+ .with([issue], user)
+ .and_return([issue])
expect(subject.nodes_visible_to_user(user, [link])).to eq([link])
end
it 'returns an empty Array when the user can not read the issue' do
- expect(Ability).to receive(:issues_readable_by_user).
- with([issue], user).
- and_return([])
+ expect(Ability).to receive(:issues_readable_by_user)
+ .with([issue], user)
+ .and_return([])
expect(subject.nodes_visible_to_user(user, [link])).to eq([])
end
diff --git a/spec/lib/banzai/reference_parser/user_parser_spec.rb b/spec/lib/banzai/reference_parser/user_parser_spec.rb
index 4d560667342..dfebb971f3a 100644
--- a/spec/lib/banzai/reference_parser/user_parser_spec.rb
+++ b/spec/lib/banzai/reference_parser/user_parser_spec.rb
@@ -96,17 +96,17 @@ describe Banzai::ReferenceParser::UserParser, lib: true do
end
it 'returns the nodes if the user can read the group' do
- expect(Ability).to receive(:allowed?).
- with(user, :read_group, group).
- and_return(true)
+ expect(Ability).to receive(:allowed?)
+ .with(user, :read_group, group)
+ .and_return(true)
expect(subject.nodes_visible_to_user(user, [link])).to eq([link])
end
it 'returns an empty Array if the user can not read the group' do
- expect(Ability).to receive(:allowed?).
- with(user, :read_group, group).
- and_return(false)
+ expect(Ability).to receive(:allowed?)
+ .with(user, :read_group, group)
+ .and_return(false)
expect(subject.nodes_visible_to_user(user, [link])).to eq([])
end
@@ -129,9 +129,9 @@ describe Banzai::ReferenceParser::UserParser, lib: true do
link['data-project'] = other_project.id.to_s
- expect(Ability).to receive(:allowed?).
- with(user, :read_project, other_project).
- and_return(true)
+ expect(Ability).to receive(:allowed?)
+ .with(user, :read_project, other_project)
+ .and_return(true)
expect(subject.nodes_visible_to_user(user, [link])).to eq([link])
end
@@ -141,9 +141,9 @@ describe Banzai::ReferenceParser::UserParser, lib: true do
link['data-project'] = other_project.id.to_s
- expect(Ability).to receive(:allowed?).
- with(user, :read_project, other_project).
- and_return(false)
+ expect(Ability).to receive(:allowed?)
+ .with(user, :read_project, other_project)
+ .and_return(false)
expect(subject.nodes_visible_to_user(user, [link])).to eq([])
end
diff --git a/spec/lib/container_registry/blob_spec.rb b/spec/lib/container_registry/blob_spec.rb
index ab010c6dfeb..175fd2e7e13 100644
--- a/spec/lib/container_registry/blob_spec.rb
+++ b/spec/lib/container_registry/blob_spec.rb
@@ -72,8 +72,8 @@ describe ContainerRegistry::Blob do
describe '#data' do
context 'when locally stored' do
before do
- stub_request(:get, 'http://registry.gitlab/v2/group/test/image/blobs/sha256:0123456789012345').
- to_return(
+ stub_request(:get, 'http://registry.gitlab/v2/group/test/image/blobs/sha256:0123456789012345')
+ .to_return(
status: 200,
headers: { 'Content-Type' => 'application/json' },
body: '{"key":"value"}')
@@ -97,9 +97,9 @@ describe ContainerRegistry::Blob do
context 'for a valid address' do
before do
- stub_request(:get, location).
- with { |request| !request.headers.include?('Authorization') }.
- to_return(
+ stub_request(:get, location)
+ .with { |request| !request.headers.include?('Authorization') }
+ .to_return(
status: 200,
headers: { 'Content-Type' => 'application/json' },
body: '{"key":"value"}')
diff --git a/spec/lib/container_registry/client_spec.rb b/spec/lib/container_registry/client_spec.rb
index ec03b533383..3df33f48adb 100644
--- a/spec/lib/container_registry/client_spec.rb
+++ b/spec/lib/container_registry/client_spec.rb
@@ -8,28 +8,28 @@ describe ContainerRegistry::Client do
describe '#blob' do
it 'GET /v2/:name/blobs/:digest' do
- stub_request(:get, "http://container-registry/v2/group/test/blobs/sha256:0123456789012345").
- with(headers: {
+ stub_request(:get, "http://container-registry/v2/group/test/blobs/sha256:0123456789012345")
+ .with(headers: {
'Accept' => 'application/octet-stream',
'Authorization' => "bearer #{token}"
- }).
- to_return(status: 200, body: "Blob")
+ })
+ .to_return(status: 200, body: "Blob")
expect(client.blob('group/test', 'sha256:0123456789012345')).to eq('Blob')
end
it 'follows 307 redirect for GET /v2/:name/blobs/:digest' do
- stub_request(:get, "http://container-registry/v2/group/test/blobs/sha256:0123456789012345").
- with(headers: {
+ stub_request(:get, "http://container-registry/v2/group/test/blobs/sha256:0123456789012345")
+ .with(headers: {
'Accept' => 'application/octet-stream',
'Authorization' => "bearer #{token}"
- }).
- to_return(status: 307, body: "", headers: { Location: 'http://redirected' })
+ })
+ .to_return(status: 307, body: "", headers: { Location: 'http://redirected' })
# We should probably use hash_excluding here, but that requires an update to WebMock:
# https://github.com/bblimke/webmock/blob/master/lib/webmock/matchers/hash_excluding_matcher.rb
- stub_request(:get, "http://redirected/").
- with { |request| !request.headers.include?('Authorization') }.
- to_return(status: 200, body: "Successfully redirected")
+ stub_request(:get, "http://redirected/")
+ .with { |request| !request.headers.include?('Authorization') }
+ .to_return(status: 200, body: "Successfully redirected")
response = client.blob('group/test', 'sha256:0123456789012345')
diff --git a/spec/lib/container_registry/tag_spec.rb b/spec/lib/container_registry/tag_spec.rb
index f8fffbdca41..cb4ae3be525 100644
--- a/spec/lib/container_registry/tag_spec.rb
+++ b/spec/lib/container_registry/tag_spec.rb
@@ -60,9 +60,9 @@ describe ContainerRegistry::Tag do
context 'manifest processing' do
context 'schema v1' do
before do
- stub_request(:get, 'http://registry.gitlab/v2/group/test/manifests/tag').
- with(headers: headers).
- to_return(
+ stub_request(:get, 'http://registry.gitlab/v2/group/test/manifests/tag')
+ .with(headers: headers)
+ .to_return(
status: 200,
body: File.read(Rails.root + 'spec/fixtures/container_registry/tag_manifest_1.json'),
headers: { 'Content-Type' => 'application/vnd.docker.distribution.manifest.v1+prettyjws' })
@@ -97,9 +97,9 @@ describe ContainerRegistry::Tag do
context 'schema v2' do
before do
- stub_request(:get, 'http://registry.gitlab/v2/group/test/manifests/tag').
- with(headers: headers).
- to_return(
+ stub_request(:get, 'http://registry.gitlab/v2/group/test/manifests/tag')
+ .with(headers: headers)
+ .to_return(
status: 200,
body: File.read(Rails.root + 'spec/fixtures/container_registry/tag_manifest.json'),
headers: { 'Content-Type' => 'application/vnd.docker.distribution.manifest.v2+json' })
@@ -134,9 +134,9 @@ describe ContainerRegistry::Tag do
context 'when locally stored' do
before do
- stub_request(:get, 'http://registry.gitlab/v2/group/test/blobs/sha256:d7a513a663c1a6dcdba9ed832ca53c02ac2af0c333322cd6ca92936d1d9917ac').
- with(headers: { 'Accept' => 'application/octet-stream' }).
- to_return(
+ stub_request(:get, 'http://registry.gitlab/v2/group/test/blobs/sha256:d7a513a663c1a6dcdba9ed832ca53c02ac2af0c333322cd6ca92936d1d9917ac')
+ .with(headers: { 'Accept' => 'application/octet-stream' })
+ .to_return(
status: 200,
body: File.read(Rails.root + 'spec/fixtures/container_registry/config_blob.json'))
end
@@ -146,14 +146,14 @@ describe ContainerRegistry::Tag do
context 'when externally stored' do
before do
- stub_request(:get, 'http://registry.gitlab/v2/group/test/blobs/sha256:d7a513a663c1a6dcdba9ed832ca53c02ac2af0c333322cd6ca92936d1d9917ac').
- with(headers: { 'Accept' => 'application/octet-stream' }).
- to_return(
+ stub_request(:get, 'http://registry.gitlab/v2/group/test/blobs/sha256:d7a513a663c1a6dcdba9ed832ca53c02ac2af0c333322cd6ca92936d1d9917ac')
+ .with(headers: { 'Accept' => 'application/octet-stream' })
+ .to_return(
status: 307,
headers: { 'Location' => 'http://external.com/blob/file' })
- stub_request(:get, 'http://external.com/blob/file').
- to_return(
+ stub_request(:get, 'http://external.com/blob/file')
+ .to_return(
status: 200,
body: File.read(Rails.root + 'spec/fixtures/container_registry/config_blob.json'))
end
diff --git a/spec/lib/extracts_path_spec.rb b/spec/lib/extracts_path_spec.rb
index 2b26a318583..f2132d485ab 100644
--- a/spec/lib/extracts_path_spec.rb
+++ b/spec/lib/extracts_path_spec.rb
@@ -14,8 +14,8 @@ describe ExtractsPath, lib: true do
repo = double(ref_names: ['master', 'foo/bar/baz', 'v1.0.0', 'v2.0.0',
'release/app', 'release/app/v1.0.0'])
allow(project).to receive(:repository).and_return(repo)
- allow(project).to receive(:path_with_namespace).
- and_return('gitlab/gitlab-ci')
+ allow(project).to receive(:path_with_namespace)
+ .and_return('gitlab/gitlab-ci')
allow(request).to receive(:format=)
end
diff --git a/spec/lib/feature_spec.rb b/spec/lib/feature_spec.rb
index 1d92a5cb33f..5cc3a3745e4 100644
--- a/spec/lib/feature_spec.rb
+++ b/spec/lib/feature_spec.rb
@@ -6,8 +6,8 @@ describe Feature, lib: true do
let(:key) { 'my_feature' }
it 'returns the Flipper feature' do
- expect_any_instance_of(Flipper::DSL).to receive(:feature).with(key).
- and_return(feature)
+ expect_any_instance_of(Flipper::DSL).to receive(:feature).with(key)
+ .and_return(feature)
expect(described_class.get(key)).to be(feature)
end
@@ -17,8 +17,8 @@ describe Feature, lib: true do
let(:features) { Set.new }
it 'returns the Flipper features as an array' do
- expect_any_instance_of(Flipper::DSL).to receive(:features).
- and_return(features)
+ expect_any_instance_of(Flipper::DSL).to receive(:features)
+ .and_return(features)
expect(described_class.all).to eq(features.to_a)
end
diff --git a/spec/lib/gitlab/background_migration_spec.rb b/spec/lib/gitlab/background_migration_spec.rb
index f2073b9bcb3..64f82fe27b2 100644
--- a/spec/lib/gitlab/background_migration_spec.rb
+++ b/spec/lib/gitlab/background_migration_spec.rb
@@ -5,9 +5,9 @@ describe Gitlab::BackgroundMigration do
it 'steals jobs from a queue' do
queue = [double(:job, args: ['Foo', [10, 20]])]
- allow(Sidekiq::Queue).to receive(:new).
- with(BackgroundMigrationWorker.sidekiq_options['queue']).
- and_return(queue)
+ allow(Sidekiq::Queue).to receive(:new)
+ .with(BackgroundMigrationWorker.sidekiq_options['queue'])
+ .and_return(queue)
expect(queue[0]).to receive(:delete)
@@ -19,9 +19,9 @@ describe Gitlab::BackgroundMigration do
it 'does not steal jobs for a different migration' do
queue = [double(:job, args: ['Foo', [10, 20]])]
- allow(Sidekiq::Queue).to receive(:new).
- with(BackgroundMigrationWorker.sidekiq_options['queue']).
- and_return(queue)
+ allow(Sidekiq::Queue).to receive(:new)
+ .with(BackgroundMigrationWorker.sidekiq_options['queue'])
+ .and_return(queue)
expect(described_class).not_to receive(:perform)
@@ -36,9 +36,9 @@ describe Gitlab::BackgroundMigration do
instance = double(:instance)
klass = double(:klass, new: instance)
- expect(described_class).to receive(:const_get).
- with('Foo').
- and_return(klass)
+ expect(described_class).to receive(:const_get)
+ .with('Foo')
+ .and_return(klass)
expect(instance).to receive(:perform).with(10, 20)
diff --git a/spec/lib/gitlab/bitbucket_import/importer_spec.rb b/spec/lib/gitlab/bitbucket_import/importer_spec.rb
index a7ee7f53a6b..d8beb05601c 100644
--- a/spec/lib/gitlab/bitbucket_import/importer_spec.rb
+++ b/spec/lib/gitlab/bitbucket_import/importer_spec.rb
@@ -86,11 +86,9 @@ describe Gitlab::BitbucketImport::Importer, lib: true do
headers: { "Content-Type" => "application/json" },
body: issues_statuses_sample_data.to_json)
- stub_request(:get, "https://api.bitbucket.org/2.0/repositories/namespace/repo?pagelen=50&sort=created_on").
- with(headers: { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Authorization' => 'Bearer', 'User-Agent' => 'Faraday v0.9.2' }).
- to_return(status: 200,
- body: "",
- headers: {})
+ stub_request(:get, "https://api.bitbucket.org/2.0/repositories/namespace/repo?pagelen=50&sort=created_on")
+ .with(headers: { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Authorization' => 'Bearer', 'User-Agent' => 'Faraday v0.9.2' })
+ .to_return(status: 200, body: "", headers: {})
sample_issues_statuses.each_with_index do |issue, index|
stub_request(
diff --git a/spec/lib/gitlab/cache/ci/project_pipeline_status_spec.rb b/spec/lib/gitlab/cache/ci/project_pipeline_status_spec.rb
index cfb5cba054e..07db6c3a640 100644
--- a/spec/lib/gitlab/cache/ci/project_pipeline_status_spec.rb
+++ b/spec/lib/gitlab/cache/ci/project_pipeline_status_spec.rb
@@ -37,11 +37,11 @@ describe Gitlab::Cache::Ci::ProjectPipelineStatus, :redis do
loaded_from_cache: false
)
- expect(described_class).to receive(:new).
- with(project_without_status,
+ expect(described_class).to receive(:new)
+ .with(project_without_status,
pipeline_info: empty_status,
- loaded_from_cache: false).
- and_return(fake_pipeline)
+ loaded_from_cache: false)
+ .and_return(fake_pipeline)
expect(fake_pipeline).to receive(:load_from_project)
expect(fake_pipeline).to receive(:store_in_cache)
@@ -112,12 +112,12 @@ describe Gitlab::Cache::Ci::ProjectPipelineStatus, :redis do
pipeline = build_stubbed(:ci_pipeline,
sha: '123456', status: 'success', ref: 'master')
fake_status = double
- expect(described_class).to receive(:new).
- with(pipeline.project,
+ expect(described_class).to receive(:new)
+ .with(pipeline.project,
pipeline_info: {
sha: '123456', status: 'success', ref: 'master'
- }).
- and_return(fake_status)
+ })
+ .and_return(fake_status)
expect(fake_status).to receive(:store_in_cache_if_needed)
diff --git a/spec/lib/gitlab/ci/build/artifacts/metadata_spec.rb b/spec/lib/gitlab/ci/build/artifacts/metadata_spec.rb
index eea01f91879..6a52ae01b2f 100644
--- a/spec/lib/gitlab/ci/build/artifacts/metadata_spec.rb
+++ b/spec/lib/gitlab/ci/build/artifacts/metadata_spec.rb
@@ -33,8 +33,8 @@ describe Gitlab::Ci::Build::Artifacts::Metadata do
subject { metadata('other_artifacts_0.1.2/').find_entries! }
it 'matches correct paths' do
- expect(subject.keys).
- to contain_exactly 'other_artifacts_0.1.2/',
+ expect(subject.keys)
+ .to contain_exactly 'other_artifacts_0.1.2/',
'other_artifacts_0.1.2/doc_sample.txt',
'other_artifacts_0.1.2/another-subdirectory/'
end
@@ -44,8 +44,8 @@ describe Gitlab::Ci::Build::Artifacts::Metadata do
subject { metadata('other_artifacts_0.1.2/another-subdirectory/').find_entries! }
it 'matches correct paths' do
- expect(subject.keys).
- to contain_exactly 'other_artifacts_0.1.2/another-subdirectory/',
+ expect(subject.keys)
+ .to contain_exactly 'other_artifacts_0.1.2/another-subdirectory/',
'other_artifacts_0.1.2/another-subdirectory/empty_directory/',
'other_artifacts_0.1.2/another-subdirectory/banana_sample.gif'
end
@@ -55,8 +55,8 @@ describe Gitlab::Ci::Build::Artifacts::Metadata do
subject { metadata('other_artifacts_0.1.2/', recursive: true).find_entries! }
it 'matches correct paths' do
- expect(subject.keys).
- to contain_exactly 'other_artifacts_0.1.2/',
+ expect(subject.keys)
+ .to contain_exactly 'other_artifacts_0.1.2/',
'other_artifacts_0.1.2/doc_sample.txt',
'other_artifacts_0.1.2/another-subdirectory/',
'other_artifacts_0.1.2/another-subdirectory/empty_directory/',
diff --git a/spec/lib/gitlab/closing_issue_extractor_spec.rb b/spec/lib/gitlab/closing_issue_extractor_spec.rb
index 97af1c2523d..ca68010cb89 100644
--- a/spec/lib/gitlab/closing_issue_extractor_spec.rb
+++ b/spec/lib/gitlab/closing_issue_extractor_spec.rb
@@ -306,58 +306,58 @@ describe Gitlab::ClosingIssueExtractor, lib: true do
it 'fetches issues in single line message' do
message = "Closes #{reference} and fix #{reference2}"
- expect(subject.closed_by_message(message)).
- to match_array([issue, other_issue])
+ expect(subject.closed_by_message(message))
+ .to match_array([issue, other_issue])
end
it 'fetches comma-separated issues references in single line message' do
message = "Closes #{reference}, closes #{reference2}"
- expect(subject.closed_by_message(message)).
- to match_array([issue, other_issue])
+ expect(subject.closed_by_message(message))
+ .to match_array([issue, other_issue])
end
it 'fetches comma-separated issues numbers in single line message' do
message = "Closes #{reference}, #{reference2} and #{reference3}"
- expect(subject.closed_by_message(message)).
- to match_array([issue, other_issue, third_issue])
+ expect(subject.closed_by_message(message))
+ .to match_array([issue, other_issue, third_issue])
end
it 'fetches issues in multi-line message' do
message = "Awesome commit (closes #{reference})\nAlso fixes #{reference2}"
- expect(subject.closed_by_message(message)).
- to match_array([issue, other_issue])
+ expect(subject.closed_by_message(message))
+ .to match_array([issue, other_issue])
end
it 'fetches issues in hybrid message' do
message = "Awesome commit (closes #{reference})\n"\
"Also fixing issues #{reference2}, #{reference3} and #4"
- expect(subject.closed_by_message(message)).
- to match_array([issue, other_issue, third_issue])
+ expect(subject.closed_by_message(message))
+ .to match_array([issue, other_issue, third_issue])
end
it "fetches cross-project references" do
message = "Closes #{reference} and #{cross_reference}"
- expect(subject.closed_by_message(message)).
- to match_array([issue, issue2])
+ expect(subject.closed_by_message(message))
+ .to match_array([issue, issue2])
end
it "fetches cross-project URL references" do
message = "Closes #{urls.namespace_project_issue_url(issue2.project.namespace, issue2.project, issue2)} and #{reference}"
- expect(subject.closed_by_message(message)).
- to match_array([issue, issue2])
+ expect(subject.closed_by_message(message))
+ .to match_array([issue, issue2])
end
it "ignores invalid cross-project URL references" do
message = "Closes https://google.com#{urls.namespace_project_issue_path(issue2.project.namespace, issue2.project, issue2)} and #{reference}"
- expect(subject.closed_by_message(message)).
- to match_array([issue])
+ expect(subject.closed_by_message(message))
+ .to match_array([issue])
end
end
end
diff --git a/spec/lib/gitlab/conflict/file_spec.rb b/spec/lib/gitlab/conflict/file_spec.rb
index 780ac0ad97e..585eeb77bd5 100644
--- a/spec/lib/gitlab/conflict/file_spec.rb
+++ b/spec/lib/gitlab/conflict/file_spec.rb
@@ -43,8 +43,8 @@ describe Gitlab::Conflict::File, lib: true do
end
it 'returns a file containing only the chosen parts of the resolved sections' do
- expect(resolved_lines.chunk { |line| line.type || 'both' }.map(&:first)).
- to eq(%w(both new both old both new both))
+ expect(resolved_lines.chunk { |line| line.type || 'both' }.map(&:first))
+ .to eq(%w(both new both old both new both))
end
end
@@ -52,14 +52,14 @@ describe Gitlab::Conflict::File, lib: true do
empty_hash = section_keys.map { |key| [key, nil] }.to_h
invalid_hash = section_keys.map { |key| [key, 'invalid'] }.to_h
- expect { conflict_file.resolve_lines({}) }.
- to raise_error(Gitlab::Conflict::File::MissingResolution)
+ expect { conflict_file.resolve_lines({}) }
+ .to raise_error(Gitlab::Conflict::File::MissingResolution)
- expect { conflict_file.resolve_lines(empty_hash) }.
- to raise_error(Gitlab::Conflict::File::MissingResolution)
+ expect { conflict_file.resolve_lines(empty_hash) }
+ .to raise_error(Gitlab::Conflict::File::MissingResolution)
- expect { conflict_file.resolve_lines(invalid_hash) }.
- to raise_error(Gitlab::Conflict::File::MissingResolution)
+ expect { conflict_file.resolve_lines(invalid_hash) }
+ .to raise_error(Gitlab::Conflict::File::MissingResolution)
end
end
@@ -250,8 +250,8 @@ FILE
describe '#as_json' do
it 'includes the blob path for the file' do
- expect(conflict_file.as_json[:blob_path]).
- to eq("/#{project.full_path}/blob/#{our_commit.oid}/files/ruby/regex.rb")
+ expect(conflict_file.as_json[:blob_path])
+ .to eq("/#{project.full_path}/blob/#{our_commit.oid}/files/ruby/regex.rb")
end
it 'includes the blob icon for the file' do
@@ -264,8 +264,8 @@ FILE
end
it 'includes the detected language of the conflict file' do
- expect(conflict_file.as_json(full_content: true)[:blob_ace_mode]).
- to eq('ruby')
+ expect(conflict_file.as_json(full_content: true)[:blob_ace_mode])
+ .to eq('ruby')
end
end
end
diff --git a/spec/lib/gitlab/conflict/parser_spec.rb b/spec/lib/gitlab/conflict/parser_spec.rb
index 2570f95dd21..aed57b75789 100644
--- a/spec/lib/gitlab/conflict/parser_spec.rb
+++ b/spec/lib/gitlab/conflict/parser_spec.rb
@@ -122,18 +122,18 @@ CONFLICT
context 'when the file contents include conflict delimiters' do
context 'when there is a non-start delimiter first' do
it 'raises UnexpectedDelimiter when there is a middle delimiter first' do
- expect { parse_text('=======') }.
- to raise_error(Gitlab::Conflict::Parser::UnexpectedDelimiter)
+ expect { parse_text('=======') }
+ .to raise_error(Gitlab::Conflict::Parser::UnexpectedDelimiter)
end
it 'raises UnexpectedDelimiter when there is an end delimiter first' do
- expect { parse_text('>>>>>>> README.md') }.
- to raise_error(Gitlab::Conflict::Parser::UnexpectedDelimiter)
+ expect { parse_text('>>>>>>> README.md') }
+ .to raise_error(Gitlab::Conflict::Parser::UnexpectedDelimiter)
end
it 'does not raise when there is an end delimiter for a different path first' do
- expect { parse_text('>>>>>>> some-other-path.md') }.
- not_to raise_error
+ expect { parse_text('>>>>>>> some-other-path.md') }
+ .not_to raise_error
end
end
@@ -142,18 +142,18 @@ CONFLICT
let(:end_text) { "\n=======\n>>>>>>> README.md" }
it 'raises UnexpectedDelimiter when it is followed by an end delimiter' do
- expect { parse_text(start_text + '>>>>>>> README.md' + end_text) }.
- to raise_error(Gitlab::Conflict::Parser::UnexpectedDelimiter)
+ expect { parse_text(start_text + '>>>>>>> README.md' + end_text) }
+ .to raise_error(Gitlab::Conflict::Parser::UnexpectedDelimiter)
end
it 'raises UnexpectedDelimiter when it is followed by another start delimiter' do
- expect { parse_text(start_text + start_text + end_text) }.
- to raise_error(Gitlab::Conflict::Parser::UnexpectedDelimiter)
+ expect { parse_text(start_text + start_text + end_text) }
+ .to raise_error(Gitlab::Conflict::Parser::UnexpectedDelimiter)
end
it 'does not raise when it is followed by a start delimiter for a different path' do
- expect { parse_text(start_text + '>>>>>>> some-other-path.md' + end_text) }.
- not_to raise_error
+ expect { parse_text(start_text + '>>>>>>> some-other-path.md' + end_text) }
+ .not_to raise_error
end
end
@@ -162,59 +162,59 @@ CONFLICT
let(:end_text) { "\n>>>>>>> README.md" }
it 'raises UnexpectedDelimiter when it is followed by another middle delimiter' do
- expect { parse_text(start_text + '=======' + end_text) }.
- to raise_error(Gitlab::Conflict::Parser::UnexpectedDelimiter)
+ expect { parse_text(start_text + '=======' + end_text) }
+ .to raise_error(Gitlab::Conflict::Parser::UnexpectedDelimiter)
end
it 'raises UnexpectedDelimiter when it is followed by a start delimiter' do
- expect { parse_text(start_text + start_text + end_text) }.
- to raise_error(Gitlab::Conflict::Parser::UnexpectedDelimiter)
+ expect { parse_text(start_text + start_text + end_text) }
+ .to raise_error(Gitlab::Conflict::Parser::UnexpectedDelimiter)
end
it 'does not raise when it is followed by a start delimiter for another path' do
- expect { parse_text(start_text + '<<<<<<< some-other-path.md' + end_text) }.
- not_to raise_error
+ expect { parse_text(start_text + '<<<<<<< some-other-path.md' + end_text) }
+ .not_to raise_error
end
end
it 'raises MissingEndDelimiter when there is no end delimiter at the end' do
start_text = "<<<<<<< README.md\n=======\n"
- expect { parse_text(start_text) }.
- to raise_error(Gitlab::Conflict::Parser::MissingEndDelimiter)
+ expect { parse_text(start_text) }
+ .to raise_error(Gitlab::Conflict::Parser::MissingEndDelimiter)
- expect { parse_text(start_text + '>>>>>>> some-other-path.md') }.
- to raise_error(Gitlab::Conflict::Parser::MissingEndDelimiter)
+ expect { parse_text(start_text + '>>>>>>> some-other-path.md') }
+ .to raise_error(Gitlab::Conflict::Parser::MissingEndDelimiter)
end
end
context 'other file types' do
it 'raises UnmergeableFile when lines is blank, indicating a binary file' do
- expect { parse_text('') }.
- to raise_error(Gitlab::Conflict::Parser::UnmergeableFile)
+ expect { parse_text('') }
+ .to raise_error(Gitlab::Conflict::Parser::UnmergeableFile)
- expect { parse_text(nil) }.
- to raise_error(Gitlab::Conflict::Parser::UnmergeableFile)
+ expect { parse_text(nil) }
+ .to raise_error(Gitlab::Conflict::Parser::UnmergeableFile)
end
it 'raises UnmergeableFile when the file is over 200 KB' do
- expect { parse_text('a' * 204801) }.
- to raise_error(Gitlab::Conflict::Parser::UnmergeableFile)
+ expect { parse_text('a' * 204801) }
+ .to raise_error(Gitlab::Conflict::Parser::UnmergeableFile)
end
# All text from Rugged has an encoding of ASCII_8BIT, so force that in
# these strings.
context 'when the file contains UTF-8 characters' do
it 'does not raise' do
- expect { parse_text("Espa\xC3\xB1a".force_encoding(Encoding::ASCII_8BIT)) }.
- not_to raise_error
+ expect { parse_text("Espa\xC3\xB1a".force_encoding(Encoding::ASCII_8BIT)) }
+ .not_to raise_error
end
end
context 'when the file contains non-UTF-8 characters' do
it 'raises UnsupportedEncoding' do
- expect { parse_text("a\xC4\xFC".force_encoding(Encoding::ASCII_8BIT)) }.
- to raise_error(Gitlab::Conflict::Parser::UnsupportedEncoding)
+ expect { parse_text("a\xC4\xFC".force_encoding(Encoding::ASCII_8BIT)) }
+ .to raise_error(Gitlab::Conflict::Parser::UnsupportedEncoding)
end
end
end
diff --git a/spec/lib/gitlab/current_settings_spec.rb b/spec/lib/gitlab/current_settings_spec.rb
index fda39d78610..a566f24f6a6 100644
--- a/spec/lib/gitlab/current_settings_spec.rb
+++ b/spec/lib/gitlab/current_settings_spec.rb
@@ -32,6 +32,37 @@ describe Gitlab::CurrentSettings do
expect(current_application_settings).to be_a(ApplicationSetting)
end
+
+ context 'with migrations pending' do
+ before do
+ expect(ActiveRecord::Migrator).to receive(:needs_migration?).and_return(true)
+ end
+
+ it 'returns an in-memory ApplicationSetting object' do
+ settings = current_application_settings
+
+ expect(settings).to be_a(OpenStruct)
+ expect(settings.sign_in_enabled?).to eq(settings.sign_in_enabled)
+ expect(settings.sign_up_enabled?).to eq(settings.sign_up_enabled)
+ end
+
+ it 'uses the existing database settings and falls back to defaults' do
+ db_settings = create(:application_setting,
+ home_page_url: 'http://mydomain.com',
+ signup_enabled: false)
+ settings = current_application_settings
+ app_defaults = ApplicationSetting.last
+
+ expect(settings).to be_a(OpenStruct)
+ expect(settings.home_page_url).to eq(db_settings.home_page_url)
+ expect(settings.signup_enabled?).to be_falsey
+ expect(settings.signup_enabled).to be_falsey
+
+ # Check that unspecified values use the defaults
+ settings.reject! { |key, _| [:home_page_url, :signup_enabled].include? key }
+ settings.each { |key, _| expect(settings[key]).to eq(app_defaults[key]) }
+ end
+ end
end
context 'with DB unavailable' do
diff --git a/spec/lib/gitlab/data_builder/push_spec.rb b/spec/lib/gitlab/data_builder/push_spec.rb
index e59cba35b2f..73936969832 100644
--- a/spec/lib/gitlab/data_builder/push_spec.rb
+++ b/spec/lib/gitlab/data_builder/push_spec.rb
@@ -47,8 +47,8 @@ describe Gitlab::DataBuilder::Push, lib: true do
include_examples 'deprecated repository hook data'
it 'does not raise an error when given nil commits' do
- expect { described_class.build(spy, spy, spy, spy, spy, nil) }.
- not_to raise_error
+ expect { described_class.build(spy, spy, spy, spy, spy, nil) }
+ .not_to raise_error
end
end
end
diff --git a/spec/lib/gitlab/database/migration_helpers_spec.rb b/spec/lib/gitlab/database/migration_helpers_spec.rb
index 30aa463faf8..6a0485112c1 100644
--- a/spec/lib/gitlab/database/migration_helpers_spec.rb
+++ b/spec/lib/gitlab/database/migration_helpers_spec.rb
@@ -57,15 +57,15 @@ describe Gitlab::Database::MigrationHelpers, lib: true do
end
it 'creates the index concurrently' do
- expect(model).to receive(:add_index).
- with(:users, :foo, algorithm: :concurrently)
+ expect(model).to receive(:add_index)
+ .with(:users, :foo, algorithm: :concurrently)
model.add_concurrent_index(:users, :foo)
end
it 'creates unique index concurrently' do
- expect(model).to receive(:add_index).
- with(:users, :foo, { algorithm: :concurrently, unique: true })
+ expect(model).to receive(:add_index)
+ .with(:users, :foo, { algorithm: :concurrently, unique: true })
model.add_concurrent_index(:users, :foo, unique: true)
end
@@ -75,8 +75,8 @@ describe Gitlab::Database::MigrationHelpers, lib: true do
it 'creates a regular index' do
expect(Gitlab::Database).to receive(:postgresql?).and_return(false)
- expect(model).to receive(:add_index).
- with(:users, :foo, {})
+ expect(model).to receive(:add_index)
+ .with(:users, :foo, {})
model.add_concurrent_index(:users, :foo)
end
@@ -87,8 +87,8 @@ describe Gitlab::Database::MigrationHelpers, lib: true do
it 'raises RuntimeError' do
expect(model).to receive(:transaction_open?).and_return(true)
- expect { model.add_concurrent_index(:users, :foo) }.
- to raise_error(RuntimeError)
+ expect { model.add_concurrent_index(:users, :foo) }
+ .to raise_error(RuntimeError)
end
end
end
@@ -106,15 +106,15 @@ describe Gitlab::Database::MigrationHelpers, lib: true do
end
it 'removes the index concurrently by column name' do
- expect(model).to receive(:remove_index).
- with(:users, { algorithm: :concurrently, column: :foo })
+ expect(model).to receive(:remove_index)
+ .with(:users, { algorithm: :concurrently, column: :foo })
model.remove_concurrent_index(:users, :foo)
end
it 'removes the index concurrently by index name' do
- expect(model).to receive(:remove_index).
- with(:users, { algorithm: :concurrently, name: "index_x_by_y" })
+ expect(model).to receive(:remove_index)
+ .with(:users, { algorithm: :concurrently, name: "index_x_by_y" })
model.remove_concurrent_index_by_name(:users, "index_x_by_y")
end
@@ -124,8 +124,8 @@ describe Gitlab::Database::MigrationHelpers, lib: true do
it 'removes an index' do
expect(Gitlab::Database).to receive(:postgresql?).and_return(false)
- expect(model).to receive(:remove_index).
- with(:users, { column: :foo })
+ expect(model).to receive(:remove_index)
+ .with(:users, { column: :foo })
model.remove_concurrent_index(:users, :foo)
end
@@ -136,8 +136,8 @@ describe Gitlab::Database::MigrationHelpers, lib: true do
it 'raises RuntimeError' do
expect(model).to receive(:transaction_open?).and_return(true)
- expect { model.remove_concurrent_index(:users, :foo) }.
- to raise_error(RuntimeError)
+ expect { model.remove_concurrent_index(:users, :foo) }
+ .to raise_error(RuntimeError)
end
end
end
@@ -162,8 +162,8 @@ describe Gitlab::Database::MigrationHelpers, lib: true do
it 'creates a regular foreign key' do
allow(Gitlab::Database).to receive(:mysql?).and_return(true)
- expect(model).to receive(:add_foreign_key).
- with(:projects, :users, column: :user_id, on_delete: :cascade)
+ expect(model).to receive(:add_foreign_key)
+ .with(:projects, :users, column: :user_id, on_delete: :cascade)
model.add_concurrent_foreign_key(:projects, :users, column: :user_id)
end
@@ -307,16 +307,16 @@ describe Gitlab::Database::MigrationHelpers, lib: true do
expect(model).to receive(:transaction).and_yield
- expect(model).to receive(:add_column).
- with(:projects, :foo, :integer, default: nil)
+ expect(model).to receive(:add_column)
+ .with(:projects, :foo, :integer, default: nil)
- expect(model).to receive(:change_column_default).
- with(:projects, :foo, 10)
+ expect(model).to receive(:change_column_default)
+ .with(:projects, :foo, 10)
end
it 'adds the column while allowing NULL values' do
- expect(model).to receive(:update_column_in_batches).
- with(:projects, :foo, 10)
+ expect(model).to receive(:update_column_in_batches)
+ .with(:projects, :foo, 10)
expect(model).not_to receive(:change_column_null)
@@ -326,22 +326,22 @@ describe Gitlab::Database::MigrationHelpers, lib: true do
end
it 'adds the column while not allowing NULL values' do
- expect(model).to receive(:update_column_in_batches).
- with(:projects, :foo, 10)
+ expect(model).to receive(:update_column_in_batches)
+ .with(:projects, :foo, 10)
- expect(model).to receive(:change_column_null).
- with(:projects, :foo, false)
+ expect(model).to receive(:change_column_null)
+ .with(:projects, :foo, false)
model.add_column_with_default(:projects, :foo, :integer, default: 10)
end
it 'removes the added column whenever updating the rows fails' do
- expect(model).to receive(:update_column_in_batches).
- with(:projects, :foo, 10).
- and_raise(RuntimeError)
+ expect(model).to receive(:update_column_in_batches)
+ .with(:projects, :foo, 10)
+ .and_raise(RuntimeError)
- expect(model).to receive(:remove_column).
- with(:projects, :foo)
+ expect(model).to receive(:remove_column)
+ .with(:projects, :foo)
expect do
model.add_column_with_default(:projects, :foo, :integer, default: 10)
@@ -349,12 +349,12 @@ describe Gitlab::Database::MigrationHelpers, lib: true do
end
it 'removes the added column whenever changing a column NULL constraint fails' do
- expect(model).to receive(:change_column_null).
- with(:projects, :foo, false).
- and_raise(RuntimeError)
+ expect(model).to receive(:change_column_null)
+ .with(:projects, :foo, false)
+ .and_raise(RuntimeError)
- expect(model).to receive(:remove_column).
- with(:projects, :foo)
+ expect(model).to receive(:remove_column)
+ .with(:projects, :foo)
expect do
model.add_column_with_default(:projects, :foo, :integer, default: 10)
@@ -370,8 +370,8 @@ describe Gitlab::Database::MigrationHelpers, lib: true do
allow(model).to receive(:change_column_null).with(:projects, :foo, false)
allow(model).to receive(:change_column_default).with(:projects, :foo, 10)
- expect(model).to receive(:add_column).
- with(:projects, :foo, :integer, default: nil, limit: 8)
+ expect(model).to receive(:add_column)
+ .with(:projects, :foo, :integer, default: nil, limit: 8)
model.add_column_with_default(:projects, :foo, :integer, default: 10, limit: 8)
end
@@ -394,8 +394,8 @@ describe Gitlab::Database::MigrationHelpers, lib: true do
it 'raises RuntimeError' do
allow(model).to receive(:transaction_open?).and_return(true)
- expect { model.rename_column_concurrently(:users, :old, :new) }.
- to raise_error(RuntimeError)
+ expect { model.rename_column_concurrently(:users, :old, :new) }
+ .to raise_error(RuntimeError)
end
end
@@ -426,17 +426,17 @@ describe Gitlab::Database::MigrationHelpers, lib: true do
it 'renames a column concurrently' do
allow(Gitlab::Database).to receive(:postgresql?).and_return(false)
- expect(model).to receive(:install_rename_triggers_for_mysql).
- with(trigger_name, 'users', 'old', 'new')
+ expect(model).to receive(:install_rename_triggers_for_mysql)
+ .with(trigger_name, 'users', 'old', 'new')
- expect(model).to receive(:add_column).
- with(:users, :new, :integer,
+ expect(model).to receive(:add_column)
+ .with(:users, :new, :integer,
limit: old_column.limit,
precision: old_column.precision,
scale: old_column.scale)
- expect(model).to receive(:change_column_default).
- with(:users, :new, old_column.default)
+ expect(model).to receive(:change_column_default)
+ .with(:users, :new, old_column.default)
expect(model).to receive(:update_column_in_batches)
@@ -453,17 +453,17 @@ describe Gitlab::Database::MigrationHelpers, lib: true do
it 'renames a column concurrently' do
allow(Gitlab::Database).to receive(:postgresql?).and_return(true)
- expect(model).to receive(:install_rename_triggers_for_postgresql).
- with(trigger_name, 'users', 'old', 'new')
+ expect(model).to receive(:install_rename_triggers_for_postgresql)
+ .with(trigger_name, 'users', 'old', 'new')
- expect(model).to receive(:add_column).
- with(:users, :new, :integer,
+ expect(model).to receive(:add_column)
+ .with(:users, :new, :integer,
limit: old_column.limit,
precision: old_column.precision,
scale: old_column.scale)
- expect(model).to receive(:change_column_default).
- with(:users, :new, old_column.default)
+ expect(model).to receive(:change_column_default)
+ .with(:users, :new, old_column.default)
expect(model).to receive(:update_column_in_batches)
@@ -482,8 +482,8 @@ describe Gitlab::Database::MigrationHelpers, lib: true do
it 'cleans up the renaming procedure for PostgreSQL' do
allow(Gitlab::Database).to receive(:postgresql?).and_return(true)
- expect(model).to receive(:remove_rename_triggers_for_postgresql).
- with(:users, /trigger_.{12}/)
+ expect(model).to receive(:remove_rename_triggers_for_postgresql)
+ .with(:users, /trigger_.{12}/)
expect(model).to receive(:remove_column).with(:users, :old)
@@ -493,8 +493,8 @@ describe Gitlab::Database::MigrationHelpers, lib: true do
it 'cleans up the renaming procedure for MySQL' do
allow(Gitlab::Database).to receive(:postgresql?).and_return(false)
- expect(model).to receive(:remove_rename_triggers_for_mysql).
- with(/trigger_.{12}/)
+ expect(model).to receive(:remove_rename_triggers_for_mysql)
+ .with(/trigger_.{12}/)
expect(model).to receive(:remove_column).with(:users, :old)
@@ -504,8 +504,8 @@ describe Gitlab::Database::MigrationHelpers, lib: true do
describe '#change_column_type_concurrently' do
it 'changes the column type' do
- expect(model).to receive(:rename_column_concurrently).
- with('users', 'username', 'username_for_type_change', type: :text)
+ expect(model).to receive(:rename_column_concurrently)
+ .with('users', 'username', 'username_for_type_change', type: :text)
model.change_column_type_concurrently('users', 'username', :text)
end
@@ -513,11 +513,11 @@ describe Gitlab::Database::MigrationHelpers, lib: true do
describe '#cleanup_concurrent_column_type_change' do
it 'cleans up the type changing procedure' do
- expect(model).to receive(:cleanup_concurrent_column_rename).
- with('users', 'username', 'username_for_type_change')
+ expect(model).to receive(:cleanup_concurrent_column_rename)
+ .with('users', 'username', 'username_for_type_change')
- expect(model).to receive(:rename_column).
- with('users', 'username_for_type_change', 'username')
+ expect(model).to receive(:rename_column)
+ .with('users', 'username_for_type_change', 'username')
model.cleanup_concurrent_column_type_change('users', 'username')
end
@@ -525,11 +525,11 @@ describe Gitlab::Database::MigrationHelpers, lib: true do
describe '#install_rename_triggers_for_postgresql' do
it 'installs the triggers for PostgreSQL' do
- expect(model).to receive(:execute).
- with(/CREATE OR REPLACE FUNCTION foo()/m)
+ expect(model).to receive(:execute)
+ .with(/CREATE OR REPLACE FUNCTION foo()/m)
- expect(model).to receive(:execute).
- with(/CREATE TRIGGER foo/m)
+ expect(model).to receive(:execute)
+ .with(/CREATE TRIGGER foo/m)
model.install_rename_triggers_for_postgresql('foo', :users, :old, :new)
end
@@ -537,11 +537,11 @@ describe Gitlab::Database::MigrationHelpers, lib: true do
describe '#install_rename_triggers_for_mysql' do
it 'installs the triggers for MySQL' do
- expect(model).to receive(:execute).
- with(/CREATE TRIGGER foo_insert.+ON users/m)
+ expect(model).to receive(:execute)
+ .with(/CREATE TRIGGER foo_insert.+ON users/m)
- expect(model).to receive(:execute).
- with(/CREATE TRIGGER foo_update.+ON users/m)
+ expect(model).to receive(:execute)
+ .with(/CREATE TRIGGER foo_update.+ON users/m)
model.install_rename_triggers_for_mysql('foo', :users, :old, :new)
end
@@ -567,8 +567,8 @@ describe Gitlab::Database::MigrationHelpers, lib: true do
describe '#rename_trigger_name' do
it 'returns a String' do
- expect(model.rename_trigger_name(:users, :foo, :bar)).
- to match(/trigger_.{12}/)
+ expect(model.rename_trigger_name(:users, :foo, :bar))
+ .to match(/trigger_.{12}/)
end
end
@@ -607,11 +607,11 @@ describe Gitlab::Database::MigrationHelpers, lib: true do
lengths: [],
orders: [])
- allow(model).to receive(:indexes_for).with(:issues, 'project_id').
- and_return([index])
+ allow(model).to receive(:indexes_for).with(:issues, 'project_id')
+ .and_return([index])
- expect(model).to receive(:add_concurrent_index).
- with(:issues,
+ expect(model).to receive(:add_concurrent_index)
+ .with(:issues,
%w(gl_project_id),
unique: false,
name: 'index_on_issues_gl_project_id',
@@ -634,11 +634,11 @@ describe Gitlab::Database::MigrationHelpers, lib: true do
lengths: [],
orders: [])
- allow(model).to receive(:indexes_for).with(:issues, 'project_id').
- and_return([index])
+ allow(model).to receive(:indexes_for).with(:issues, 'project_id')
+ .and_return([index])
- expect(model).to receive(:add_concurrent_index).
- with(:issues,
+ expect(model).to receive(:add_concurrent_index)
+ .with(:issues,
%w(gl_project_id foobar),
unique: false,
name: 'index_on_issues_gl_project_id_foobar',
@@ -661,11 +661,11 @@ describe Gitlab::Database::MigrationHelpers, lib: true do
lengths: [],
orders: [])
- allow(model).to receive(:indexes_for).with(:issues, 'project_id').
- and_return([index])
+ allow(model).to receive(:indexes_for).with(:issues, 'project_id')
+ .and_return([index])
- expect(model).to receive(:add_concurrent_index).
- with(:issues,
+ expect(model).to receive(:add_concurrent_index)
+ .with(:issues,
%w(gl_project_id),
unique: false,
name: 'index_on_issues_gl_project_id',
@@ -689,11 +689,11 @@ describe Gitlab::Database::MigrationHelpers, lib: true do
lengths: [],
orders: [])
- allow(model).to receive(:indexes_for).with(:issues, 'project_id').
- and_return([index])
+ allow(model).to receive(:indexes_for).with(:issues, 'project_id')
+ .and_return([index])
- expect(model).to receive(:add_concurrent_index).
- with(:issues,
+ expect(model).to receive(:add_concurrent_index)
+ .with(:issues,
%w(gl_project_id),
unique: false,
name: 'index_on_issues_gl_project_id',
@@ -717,11 +717,11 @@ describe Gitlab::Database::MigrationHelpers, lib: true do
lengths: [],
orders: [])
- allow(model).to receive(:indexes_for).with(:issues, 'project_id').
- and_return([index])
+ allow(model).to receive(:indexes_for).with(:issues, 'project_id')
+ .and_return([index])
- expect(model).to receive(:add_concurrent_index).
- with(:issues,
+ expect(model).to receive(:add_concurrent_index)
+ .with(:issues,
%w(gl_project_id),
unique: false,
name: 'index_on_issues_gl_project_id',
@@ -745,11 +745,11 @@ describe Gitlab::Database::MigrationHelpers, lib: true do
lengths: [],
orders: [])
- allow(model).to receive(:indexes_for).with(:issues, 'project_id').
- and_return([index])
+ allow(model).to receive(:indexes_for).with(:issues, 'project_id')
+ .and_return([index])
- expect { model.copy_indexes(:issues, :project_id, :gl_project_id) }.
- to raise_error(RuntimeError)
+ expect { model.copy_indexes(:issues, :project_id, :gl_project_id) }
+ .to raise_error(RuntimeError)
end
end
end
@@ -761,11 +761,11 @@ describe Gitlab::Database::MigrationHelpers, lib: true do
to_table: 'projects',
on_delete: :cascade)
- allow(model).to receive(:foreign_keys_for).with(:issues, :project_id).
- and_return([fk])
+ allow(model).to receive(:foreign_keys_for).with(:issues, :project_id)
+ .and_return([fk])
- expect(model).to receive(:add_concurrent_foreign_key).
- with('issues', 'projects', column: :gl_project_id, on_delete: :cascade)
+ expect(model).to receive(:add_concurrent_foreign_key)
+ .with('issues', 'projects', column: :gl_project_id, on_delete: :cascade)
model.copy_foreign_keys(:issues, :project_id, :gl_project_id)
end
@@ -790,8 +790,8 @@ describe Gitlab::Database::MigrationHelpers, lib: true do
end
it 'builds the sql with correct functions' do
- expect(model.replace_sql(Arel::Table.new(:users)[:first_name], "Alice", "Eve").to_s).
- to include('regexp_replace')
+ expect(model.replace_sql(Arel::Table.new(:users)[:first_name], "Alice", "Eve").to_s)
+ .to include('regexp_replace')
end
end
@@ -801,8 +801,8 @@ describe Gitlab::Database::MigrationHelpers, lib: true do
end
it 'builds the sql with the correct functions' do
- expect(model.replace_sql(Arel::Table.new(:users)[:first_name], "Alice", "Eve").to_s).
- to include('locate', 'insert')
+ expect(model.replace_sql(Arel::Table.new(:users)[:first_name], "Alice", "Eve").to_s)
+ .to include('locate', 'insert')
end
end
diff --git a/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_namespaces_spec.rb b/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_namespaces_spec.rb
index ce2b5d620fd..aa63f6f9805 100644
--- a/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_namespaces_spec.rb
+++ b/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_namespaces_spec.rb
@@ -21,8 +21,8 @@ describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameNamespaces do
parent = create(:group, path: 'parent')
child = create(:group, path: 'the-path', parent: parent)
- found_ids = subject.namespaces_for_paths(type: :child).
- map(&:id)
+ found_ids = subject.namespaces_for_paths(type: :child)
+ .map(&:id)
expect(found_ids).to contain_exactly(child.id)
end
@@ -38,8 +38,8 @@ describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameNamespaces do
path: 'the-path',
parent: create(:group))
- found_ids = subject.namespaces_for_paths(type: :child).
- map(&:id)
+ found_ids = subject.namespaces_for_paths(type: :child)
+ .map(&:id)
expect(found_ids).to contain_exactly(namespace.id)
end
@@ -53,8 +53,8 @@ describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameNamespaces do
path: 'the-path',
parent: create(:group))
- found_ids = subject.namespaces_for_paths(type: :child).
- map(&:id)
+ found_ids = subject.namespaces_for_paths(type: :child)
+ .map(&:id)
expect(found_ids).to contain_exactly(namespace.id)
end
@@ -68,8 +68,8 @@ describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameNamespaces do
path: 'the-path',
parent: create(:group))
- found_ids = subject.namespaces_for_paths(type: :top_level).
- map(&:id)
+ found_ids = subject.namespaces_for_paths(type: :top_level)
+ .map(&:id)
expect(found_ids).to contain_exactly(root_namespace.id)
end
@@ -81,8 +81,8 @@ describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameNamespaces do
path: 'the-path',
parent: create(:group))
- found_ids = subject.namespaces_for_paths(type: :top_level).
- map(&:id)
+ found_ids = subject.namespaces_for_paths(type: :top_level)
+ .map(&:id)
expect(found_ids).to contain_exactly(root_namespace.id)
end
@@ -140,9 +140,9 @@ describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameNamespaces do
let(:namespace) { create(:group, name: 'the-path') }
it 'renames paths & routes for the namespace' do
- expect(subject).to receive(:rename_path_for_routable).
- with(namespace).
- and_call_original
+ expect(subject).to receive(:rename_path_for_routable)
+ .with(namespace)
+ .and_call_original
subject.rename_namespace(namespace)
@@ -211,15 +211,15 @@ describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameNamespaces do
end
it 'renames top level namespaces the namespace' do
- expect(subject).to receive(:rename_namespace).
- with(migration_namespace(top_level_namespace))
+ expect(subject).to receive(:rename_namespace)
+ .with(migration_namespace(top_level_namespace))
subject.rename_namespaces(type: :top_level)
end
it 'renames child namespaces' do
- expect(subject).to receive(:rename_namespace).
- with(migration_namespace(child_namespace))
+ expect(subject).to receive(:rename_namespace)
+ .with(migration_namespace(child_namespace))
subject.rename_namespaces(type: :child)
end
diff --git a/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_projects_spec.rb b/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_projects_spec.rb
index 59e8de2712d..9a6ed98898d 100644
--- a/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_projects_spec.rb
+++ b/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_projects_spec.rb
@@ -13,8 +13,8 @@ describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameProjects do
namespace = create(:namespace, path: 'hello')
project = create(:empty_project, path: 'THE-path', namespace: namespace)
- result_ids = described_class.new(['Hello/the-path'], migration).
- projects_for_paths.map(&:id)
+ result_ids = described_class.new(['Hello/the-path'], migration)
+ .projects_for_paths.map(&:id)
expect(result_ids).to contain_exactly(project.id)
end
@@ -39,8 +39,8 @@ describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameProjects do
end
it 'invalidates the markdown cache of related projects' do
- expect(subject).to receive(:remove_cached_html_for_projects).
- with(projects.map(&:id))
+ expect(subject).to receive(:remove_cached_html_for_projects)
+ .with(projects.map(&:id))
subject.rename_projects
end
@@ -54,9 +54,9 @@ describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameProjects do
end
it 'renames path & route for the project' do
- expect(subject).to receive(:rename_path_for_routable).
- with(project).
- and_call_original
+ expect(subject).to receive(:rename_path_for_routable)
+ .with(project)
+ .and_call_original
subject.rename_project(project)
@@ -64,24 +64,24 @@ describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameProjects do
end
it 'moves the wiki & the repo' do
- expect(subject).to receive(:move_repository).
- with(project, 'known-parent/the-path.wiki', 'known-parent/the-path0.wiki')
- expect(subject).to receive(:move_repository).
- with(project, 'known-parent/the-path', 'known-parent/the-path0')
+ expect(subject).to receive(:move_repository)
+ .with(project, 'known-parent/the-path.wiki', 'known-parent/the-path0.wiki')
+ expect(subject).to receive(:move_repository)
+ .with(project, 'known-parent/the-path', 'known-parent/the-path0')
subject.rename_project(project)
end
it 'moves uploads' do
- expect(subject).to receive(:move_uploads).
- with('known-parent/the-path', 'known-parent/the-path0')
+ expect(subject).to receive(:move_uploads)
+ .with('known-parent/the-path', 'known-parent/the-path0')
subject.rename_project(project)
end
it 'moves pages' do
- expect(subject).to receive(:move_pages).
- with('known-parent/the-path', 'known-parent/the-path0')
+ expect(subject).to receive(:move_pages)
+ .with('known-parent/the-path', 'known-parent/the-path0')
subject.rename_project(project)
end
diff --git a/spec/lib/gitlab/database/rename_reserved_paths_migration/v1_spec.rb b/spec/lib/gitlab/database/rename_reserved_paths_migration/v1_spec.rb
index f8cc1eb91ec..bdd3af4ad44 100644
--- a/spec/lib/gitlab/database/rename_reserved_paths_migration/v1_spec.rb
+++ b/spec/lib/gitlab/database/rename_reserved_paths_migration/v1_spec.rb
@@ -3,11 +3,11 @@ require 'spec_helper'
shared_examples 'renames child namespaces' do |type|
it 'renames namespaces' do
rename_namespaces = double
- expect(described_class::RenameNamespaces).
- to receive(:new).with(['first-path', 'second-path'], subject).
- and_return(rename_namespaces)
- expect(rename_namespaces).to receive(:rename_namespaces).
- with(type: :child)
+ expect(described_class::RenameNamespaces)
+ .to receive(:new).with(['first-path', 'second-path'], subject)
+ .and_return(rename_namespaces)
+ expect(rename_namespaces).to receive(:rename_namespaces)
+ .with(type: :child)
subject.rename_wildcard_paths(['first-path', 'second-path'])
end
@@ -29,9 +29,9 @@ describe Gitlab::Database::RenameReservedPathsMigration::V1 do
it 'should rename projects' do
rename_projects = double
- expect(described_class::RenameProjects).
- to receive(:new).with(['the-path'], subject).
- and_return(rename_projects)
+ expect(described_class::RenameProjects)
+ .to receive(:new).with(['the-path'], subject)
+ .and_return(rename_projects)
expect(rename_projects).to receive(:rename_projects)
@@ -42,11 +42,11 @@ describe Gitlab::Database::RenameReservedPathsMigration::V1 do
describe '#rename_root_paths' do
it 'should rename namespaces' do
rename_namespaces = double
- expect(described_class::RenameNamespaces).
- to receive(:new).with(['the-path'], subject).
- and_return(rename_namespaces)
- expect(rename_namespaces).to receive(:rename_namespaces).
- with(type: :top_level)
+ expect(described_class::RenameNamespaces)
+ .to receive(:new).with(['the-path'], subject)
+ .and_return(rename_namespaces)
+ expect(rename_namespaces).to receive(:rename_namespaces)
+ .with(type: :top_level)
subject.rename_root_paths('the-path')
end
diff --git a/spec/lib/gitlab/database_spec.rb b/spec/lib/gitlab/database_spec.rb
index 26e5d73d333..5e6206b96c7 100644
--- a/spec/lib/gitlab/database_spec.rb
+++ b/spec/lib/gitlab/database_spec.rb
@@ -34,8 +34,8 @@ describe Gitlab::Database, lib: true do
describe '.version' do
context "on mysql" do
it "extracts the version number" do
- allow(described_class).to receive(:database_version).
- and_return("5.7.12-standard")
+ allow(described_class).to receive(:database_version)
+ .and_return("5.7.12-standard")
expect(described_class.version).to eq '5.7.12-standard'
end
@@ -43,8 +43,8 @@ describe Gitlab::Database, lib: true do
context "on postgresql" do
it "extracts the version number" do
- allow(described_class).to receive(:database_version).
- and_return("PostgreSQL 9.4.4 on x86_64-apple-darwin14.3.0")
+ allow(described_class).to receive(:database_version)
+ .and_return("PostgreSQL 9.4.4 on x86_64-apple-darwin14.3.0")
expect(described_class.version).to eq '9.4.4'
end
@@ -129,6 +129,55 @@ describe Gitlab::Database, lib: true do
end
end
+ describe '.bulk_insert' do
+ before do
+ allow(described_class).to receive(:connection).and_return(connection)
+ allow(connection).to receive(:quote_column_name, &:itself)
+ allow(connection).to receive(:quote, &:itself)
+ allow(connection).to receive(:execute)
+ end
+
+ let(:connection) { double(:connection) }
+
+ let(:rows) do
+ [
+ { a: 1, b: 2, c: 3 },
+ { c: 6, a: 4, b: 5 }
+ ]
+ end
+
+ it 'does nothing with empty rows' do
+ expect(connection).not_to receive(:execute)
+
+ described_class.bulk_insert('test', [])
+ end
+
+ it 'uses the ordering from the first row' do
+ expect(connection).to receive(:execute) do |sql|
+ expect(sql).to include('(1, 2, 3)')
+ expect(sql).to include('(4, 5, 6)')
+ end
+
+ described_class.bulk_insert('test', rows)
+ end
+
+ it 'quotes column names' do
+ expect(connection).to receive(:quote_column_name).with(:a)
+ expect(connection).to receive(:quote_column_name).with(:b)
+ expect(connection).to receive(:quote_column_name).with(:c)
+
+ described_class.bulk_insert('test', rows)
+ end
+
+ it 'quotes values' do
+ 1.upto(6) do |i|
+ expect(connection).to receive(:quote).with(i)
+ end
+
+ described_class.bulk_insert('test', rows)
+ end
+ end
+
describe '.create_connection_pool' do
it 'creates a new connection pool with specific pool size' do
pool = described_class.create_connection_pool(5)
diff --git a/spec/lib/gitlab/downtime_check_spec.rb b/spec/lib/gitlab/downtime_check_spec.rb
index 42d895e548e..1f1e4e0216c 100644
--- a/spec/lib/gitlab/downtime_check_spec.rb
+++ b/spec/lib/gitlab/downtime_check_spec.rb
@@ -11,12 +11,12 @@ describe Gitlab::DowntimeCheck do
context 'when a migration does not specify if downtime is required' do
it 'raises RuntimeError' do
- expect(subject).to receive(:class_for_migration_file).
- with(path).
- and_return(Class.new)
+ expect(subject).to receive(:class_for_migration_file)
+ .with(path)
+ .and_return(Class.new)
- expect { subject.check([path]) }.
- to raise_error(RuntimeError, /it requires downtime/)
+ expect { subject.check([path]) }
+ .to raise_error(RuntimeError, /it requires downtime/)
end
end
@@ -25,12 +25,12 @@ describe Gitlab::DowntimeCheck do
it 'raises RuntimeError' do
stub_const('TestMigration::DOWNTIME', true)
- expect(subject).to receive(:class_for_migration_file).
- with(path).
- and_return(TestMigration)
+ expect(subject).to receive(:class_for_migration_file)
+ .with(path)
+ .and_return(TestMigration)
- expect { subject.check([path]) }.
- to raise_error(RuntimeError, /no reason was given/)
+ expect { subject.check([path]) }
+ .to raise_error(RuntimeError, /no reason was given/)
end
end
@@ -39,9 +39,9 @@ describe Gitlab::DowntimeCheck do
stub_const('TestMigration::DOWNTIME', true)
stub_const('TestMigration::DOWNTIME_REASON', 'foo')
- expect(subject).to receive(:class_for_migration_file).
- with(path).
- and_return(TestMigration)
+ expect(subject).to receive(:class_for_migration_file)
+ .with(path)
+ .and_return(TestMigration)
messages = subject.check([path])
@@ -65,9 +65,9 @@ describe Gitlab::DowntimeCheck do
expect(subject).to receive(:require).with(path)
- expect(subject).to receive(:class_for_migration_file).
- with(path).
- and_return(TestMigration)
+ expect(subject).to receive(:class_for_migration_file)
+ .with(path)
+ .and_return(TestMigration)
expect(subject).to receive(:puts).with(an_instance_of(String))
diff --git a/spec/lib/gitlab/email/handler/create_note_handler_spec.rb b/spec/lib/gitlab/email/handler/create_note_handler_spec.rb
index 3f79eaf7afb..cd0309e248d 100644
--- a/spec/lib/gitlab/email/handler/create_note_handler_spec.rb
+++ b/spec/lib/gitlab/email/handler/create_note_handler_spec.rb
@@ -91,7 +91,7 @@ describe Gitlab::Email::Handler::CreateNoteHandler, lib: true do
end
end
- context 'when the note contains slash commands' do
+ context 'when the note contains quick actions' do
let!(:email_raw) { fixture_file("emails/commands_in_reply.eml") }
context 'and current user cannot update noteable' do
diff --git a/spec/lib/gitlab/email/reply_parser_spec.rb b/spec/lib/gitlab/email/reply_parser_spec.rb
index 28698e89c33..2ea5e6460a3 100644
--- a/spec/lib/gitlab/email/reply_parser_spec.rb
+++ b/spec/lib/gitlab/email/reply_parser_spec.rb
@@ -20,8 +20,8 @@ describe Gitlab::Email::ReplyParser, lib: true do
end
it "properly renders plaintext-only email" do
- expect(test_parse_body(fixture_file("emails/plaintext_only.eml"))).
- to eq(
+ expect(test_parse_body(fixture_file("emails/plaintext_only.eml")))
+ .to eq(
<<-BODY.strip_heredoc.chomp
### reply from default mail client in Windows 8.1 Metro
@@ -46,8 +46,8 @@ describe Gitlab::Email::ReplyParser, lib: true do
end
it "handles multiple paragraphs" do
- expect(test_parse_body(fixture_file("emails/paragraphs.eml"))).
- to eq(
+ expect(test_parse_body(fixture_file("emails/paragraphs.eml")))
+ .to eq(
<<-BODY.strip_heredoc.chomp
Is there any reason the *old* candy can't be be kept in silos while the new candy
is imported into *new* silos?
@@ -61,8 +61,8 @@ describe Gitlab::Email::ReplyParser, lib: true do
end
it "handles multiple paragraphs when parsing html" do
- expect(test_parse_body(fixture_file("emails/html_paragraphs.eml"))).
- to eq(
+ expect(test_parse_body(fixture_file("emails/html_paragraphs.eml")))
+ .to eq(
<<-BODY.strip_heredoc.chomp
Awesome!
@@ -74,8 +74,8 @@ describe Gitlab::Email::ReplyParser, lib: true do
end
it "handles newlines" do
- expect(test_parse_body(fixture_file("emails/newlines.eml"))).
- to eq(
+ expect(test_parse_body(fixture_file("emails/newlines.eml")))
+ .to eq(
<<-BODY.strip_heredoc.chomp
This is my reply.
It is my best reply.
@@ -85,8 +85,8 @@ describe Gitlab::Email::ReplyParser, lib: true do
end
it "handles inline reply" do
- expect(test_parse_body(fixture_file("emails/inline_reply.eml"))).
- to eq(
+ expect(test_parse_body(fixture_file("emails/inline_reply.eml")))
+ .to eq(
<<-BODY.strip_heredoc.chomp
> techAPJ <https://meta.discourse.org/users/techapj>
> November 28
@@ -132,8 +132,8 @@ describe Gitlab::Email::ReplyParser, lib: true do
end
it "properly renders email reply from gmail web client" do
- expect(test_parse_body(fixture_file("emails/gmail_web.eml"))).
- to eq(
+ expect(test_parse_body(fixture_file("emails/gmail_web.eml")))
+ .to eq(
<<-BODY.strip_heredoc.chomp
### This is a reply from standard GMail in Google Chrome.
@@ -151,8 +151,8 @@ describe Gitlab::Email::ReplyParser, lib: true do
end
it "properly renders email reply from iOS default mail client" do
- expect(test_parse_body(fixture_file("emails/ios_default.eml"))).
- to eq(
+ expect(test_parse_body(fixture_file("emails/ios_default.eml")))
+ .to eq(
<<-BODY.strip_heredoc.chomp
### this is a reply from iOS default mail
@@ -166,8 +166,8 @@ describe Gitlab::Email::ReplyParser, lib: true do
end
it "properly renders email reply from Android 5 gmail client" do
- expect(test_parse_body(fixture_file("emails/android_gmail.eml"))).
- to eq(
+ expect(test_parse_body(fixture_file("emails/android_gmail.eml")))
+ .to eq(
<<-BODY.strip_heredoc.chomp
### this is a reply from Android 5 gmail
@@ -184,8 +184,8 @@ describe Gitlab::Email::ReplyParser, lib: true do
end
it "properly renders email reply from Windows 8.1 Metro default mail client" do
- expect(test_parse_body(fixture_file("emails/windows_8_metro.eml"))).
- to eq(
+ expect(test_parse_body(fixture_file("emails/windows_8_metro.eml")))
+ .to eq(
<<-BODY.strip_heredoc.chomp
### reply from default mail client in Windows 8.1 Metro
@@ -208,5 +208,9 @@ describe Gitlab::Email::ReplyParser, lib: true do
it "properly renders html-only email from MS Outlook" do
expect(test_parse_body(fixture_file("emails/outlook_html.eml"))).to eq("Microsoft Outlook 2010")
end
+
+ it "does not wrap links with no href in unnecessary brackets" do
+ expect(test_parse_body(fixture_file("emails/html_empty_link.eml"))).to eq("no brackets!")
+ end
end
end
diff --git a/spec/lib/gitlab/etag_caching/middleware_spec.rb b/spec/lib/gitlab/etag_caching/middleware_spec.rb
index 4acf4f047f1..4a54d641b4e 100644
--- a/spec/lib/gitlab/etag_caching/middleware_spec.rb
+++ b/spec/lib/gitlab/etag_caching/middleware_spec.rb
@@ -108,8 +108,8 @@ describe Gitlab::EtagCaching::Middleware do
context 'when polling is disabled' do
before do
- allow(Gitlab::PollingInterval).to receive(:polling_enabled?).
- and_return(false)
+ allow(Gitlab::PollingInterval).to receive(:polling_enabled?)
+ .and_return(false)
end
it 'returns status code 429' do
diff --git a/spec/lib/gitlab/fake_application_settings_spec.rb b/spec/lib/gitlab/fake_application_settings_spec.rb
new file mode 100644
index 00000000000..b793176d84a
--- /dev/null
+++ b/spec/lib/gitlab/fake_application_settings_spec.rb
@@ -0,0 +1,32 @@
+require 'spec_helper'
+
+describe Gitlab::FakeApplicationSettings do
+ let(:defaults) { { signin_enabled: false, foobar: 'asdf', signup_enabled: true, 'test?' => 123 } }
+
+ subject { described_class.new(defaults) }
+
+ it 'wraps OpenStruct variables properly' do
+ expect(subject.signin_enabled).to be_falsey
+ expect(subject.signup_enabled).to be_truthy
+ expect(subject.foobar).to eq('asdf')
+ end
+
+ it 'defines predicate methods' do
+ expect(subject.signin_enabled?).to be_falsey
+ expect(subject.signup_enabled?).to be_truthy
+ end
+
+ it 'predicate method changes when value is updated' do
+ subject.signin_enabled = true
+
+ expect(subject.signin_enabled?).to be_truthy
+ end
+
+ it 'does not define a predicate method' do
+ expect(subject.foobar?).to be_nil
+ end
+
+ it 'does not override an existing predicate method' do
+ expect(subject.test?).to eq(123)
+ end
+end
diff --git a/spec/lib/gitlab/file_detector_spec.rb b/spec/lib/gitlab/file_detector_spec.rb
index e5ba13bbaf8..695fd6f8573 100644
--- a/spec/lib/gitlab/file_detector_spec.rb
+++ b/spec/lib/gitlab/file_detector_spec.rb
@@ -3,13 +3,13 @@ require 'spec_helper'
describe Gitlab::FileDetector do
describe '.types_in_paths' do
it 'returns the file types for the given paths' do
- expect(described_class.types_in_paths(%w(README.md CHANGELOG VERSION VERSION))).
- to eq(%i{readme changelog version})
+ expect(described_class.types_in_paths(%w(README.md CHANGELOG VERSION VERSION)))
+ .to eq(%i{readme changelog version})
end
it 'does not include unrecognized file paths' do
- expect(described_class.types_in_paths(%w(README.md foo.txt))).
- to eq(%i{readme})
+ expect(described_class.types_in_paths(%w(README.md foo.txt)))
+ .to eq(%i{readme})
end
end
diff --git a/spec/lib/gitlab/git/attributes_spec.rb b/spec/lib/gitlab/git/attributes_spec.rb
index 1cfd8db09a5..b715fc3410a 100644
--- a/spec/lib/gitlab/git/attributes_spec.rb
+++ b/spec/lib/gitlab/git/attributes_spec.rb
@@ -14,13 +14,13 @@ describe Gitlab::Git::Attributes, seed_helper: true do
end
it 'returns a Hash containing multiple attributes' do
- expect(subject.attributes('test.sh')).
- to eq({ 'eol' => 'lf', 'gitlab-language' => 'shell' })
+ expect(subject.attributes('test.sh'))
+ .to eq({ 'eol' => 'lf', 'gitlab-language' => 'shell' })
end
it 'returns a Hash containing attributes for a file with multiple extensions' do
- expect(subject.attributes('test.haml.html')).
- to eq({ 'gitlab-language' => 'haml' })
+ expect(subject.attributes('test.haml.html'))
+ .to eq({ 'gitlab-language' => 'haml' })
end
it 'returns a Hash containing attributes for a file in a directory' do
@@ -28,8 +28,8 @@ describe Gitlab::Git::Attributes, seed_helper: true do
end
it 'returns a Hash containing attributes with query string parameters' do
- expect(subject.attributes('foo.cgi')).
- to eq({ 'key' => 'value?p1=v1&p2=v2' })
+ expect(subject.attributes('foo.cgi'))
+ .to eq({ 'key' => 'value?p1=v1&p2=v2' })
end
it 'returns a Hash containing the attributes for an absolute path' do
@@ -39,11 +39,11 @@ describe Gitlab::Git::Attributes, seed_helper: true do
it 'returns a Hash containing the attributes when a pattern is defined using an absolute path' do
# When a path is given without a leading slash it should still match
# patterns defined with a leading slash.
- expect(subject.attributes('foo.png')).
- to eq({ 'gitlab-language' => 'png' })
+ expect(subject.attributes('foo.png'))
+ .to eq({ 'gitlab-language' => 'png' })
- expect(subject.attributes('/foo.png')).
- to eq({ 'gitlab-language' => 'png' })
+ expect(subject.attributes('/foo.png'))
+ .to eq({ 'gitlab-language' => 'png' })
end
it 'returns an empty Hash for a defined path without attributes' do
@@ -74,8 +74,8 @@ describe Gitlab::Git::Attributes, seed_helper: true do
end
it 'parses an entry that uses a tab to separate the pattern and attributes' do
- expect(subject.patterns[File.join(path, '*.md')]).
- to eq({ 'gitlab-language' => 'markdown' })
+ expect(subject.patterns[File.join(path, '*.md')])
+ .to eq({ 'gitlab-language' => 'markdown' })
end
it 'stores patterns in reverse order' do
@@ -91,9 +91,9 @@ describe Gitlab::Git::Attributes, seed_helper: true do
end
it 'does not parse anything when the attributes file does not exist' do
- expect(File).to receive(:exist?).
- with(File.join(path, 'info/attributes')).
- and_return(false)
+ expect(File).to receive(:exist?)
+ .with(File.join(path, 'info/attributes'))
+ .and_return(false)
expect(subject.patterns).to eq({})
end
@@ -115,13 +115,13 @@ describe Gitlab::Git::Attributes, seed_helper: true do
it 'parses multiple attributes' do
input = 'boolean key=value -negated'
- expect(subject.parse_attributes(input)).
- to eq({ 'boolean' => true, 'key' => 'value', 'negated' => false })
+ expect(subject.parse_attributes(input))
+ .to eq({ 'boolean' => true, 'key' => 'value', 'negated' => false })
end
it 'parses attributes with query string parameters' do
- expect(subject.parse_attributes('foo=bar?baz=1')).
- to eq({ 'foo' => 'bar?baz=1' })
+ expect(subject.parse_attributes('foo=bar?baz=1'))
+ .to eq({ 'foo' => 'bar?baz=1' })
end
end
@@ -133,9 +133,9 @@ describe Gitlab::Git::Attributes, seed_helper: true do
end
it 'does not yield when the attributes file does not exist' do
- expect(File).to receive(:exist?).
- with(File.join(path, 'info/attributes')).
- and_return(false)
+ expect(File).to receive(:exist?)
+ .with(File.join(path, 'info/attributes'))
+ .and_return(false)
expect { |b| subject.each_line(&b) }.not_to yield_control
end
diff --git a/spec/lib/gitlab/git/blob_spec.rb b/spec/lib/gitlab/git/blob_spec.rb
index e6a07a58d73..58d3ee6b488 100644
--- a/spec/lib/gitlab/git/blob_spec.rb
+++ b/spec/lib/gitlab/git/blob_spec.rb
@@ -15,7 +15,7 @@ describe Gitlab::Git::Blob, seed_helper: true do
end
end
- describe '.find' do
+ shared_examples 'finding blobs' do
context 'file in subdir' do
let(:blob) { Gitlab::Git::Blob.find(repository, SeedRepo::Commit::ID, "files/ruby/popen.rb") }
@@ -92,15 +92,25 @@ describe Gitlab::Git::Blob, seed_helper: true do
end
it 'marks the blob as binary' do
- expect(Gitlab::Git::Blob).to receive(:new).
- with(hash_including(binary: true)).
- and_call_original
+ expect(Gitlab::Git::Blob).to receive(:new)
+ .with(hash_including(binary: true))
+ .and_call_original
expect(blob).to be_binary
end
end
end
+ describe '.find' do
+ context 'when project_raw_show Gitaly feature is enabled' do
+ it_behaves_like 'finding blobs'
+ end
+
+ context 'when project_raw_show Gitaly feature is disabled', skip_gitaly_mock: true do
+ it_behaves_like 'finding blobs'
+ end
+ end
+
describe '.raw' do
let(:raw_blob) { Gitlab::Git::Blob.raw(repository, SeedRepo::RubyBlob::ID) }
it { expect(raw_blob.id).to eq(SeedRepo::RubyBlob::ID) }
diff --git a/spec/lib/gitlab/git/branch_spec.rb b/spec/lib/gitlab/git/branch_spec.rb
index 9eac7660cd1..9dba4397e79 100644
--- a/spec/lib/gitlab/git/branch_spec.rb
+++ b/spec/lib/gitlab/git/branch_spec.rb
@@ -45,8 +45,8 @@ describe Gitlab::Git::Branch, seed_helper: true do
let(:branch) { described_class.new(repository, 'foo', gitaly_branch) }
it 'parses Gitaly::FindLocalBranchResponse correctly' do
- expect(Gitlab::Git::Commit).to receive(:decorate).
- with(hash_including(attributes)).and_call_original
+ expect(Gitlab::Git::Commit).to receive(:decorate)
+ .with(hash_including(attributes)).and_call_original
expect(branch.dereferenced_target.message.encoding).to be(Encoding::UTF_8)
end
diff --git a/spec/lib/gitlab/git/diff_collection_spec.rb b/spec/lib/gitlab/git/diff_collection_spec.rb
index a9a7bba2c05..d20298fa139 100644
--- a/spec/lib/gitlab/git/diff_collection_spec.rb
+++ b/spec/lib/gitlab/git/diff_collection_spec.rb
@@ -325,8 +325,8 @@ describe Gitlab::Git::DiffCollection, seed_helper: true do
end
it 'yields Diff instances even when they are too large' do
- expect { |b| collection.each(&b) }.
- to yield_with_args(an_instance_of(Gitlab::Git::Diff))
+ expect { |b| collection.each(&b) }
+ .to yield_with_args(an_instance_of(Gitlab::Git::Diff))
end
it 'prunes diffs that are too large' do
@@ -348,8 +348,8 @@ describe Gitlab::Git::DiffCollection, seed_helper: true do
let(:expanded) { true }
it 'yields Diff instances even when they are quite big' do
- expect { |b| subject.each(&b) }.
- to yield_with_args(an_instance_of(Gitlab::Git::Diff))
+ expect { |b| subject.each(&b) }
+ .to yield_with_args(an_instance_of(Gitlab::Git::Diff))
end
it 'does not prune diffs' do
@@ -367,8 +367,8 @@ describe Gitlab::Git::DiffCollection, seed_helper: true do
let(:expanded) { false }
it 'yields Diff instances even when they are quite big' do
- expect { |b| subject.each(&b) }.
- to yield_with_args(an_instance_of(Gitlab::Git::Diff))
+ expect { |b| subject.each(&b) }
+ .to yield_with_args(an_instance_of(Gitlab::Git::Diff))
end
it 'prunes diffs that are quite big' do
@@ -454,8 +454,8 @@ describe Gitlab::Git::DiffCollection, seed_helper: true do
let(:limits) { false }
it 'yields Diff instances even when they are quite big' do
- expect { |b| subject.each(&b) }.
- to yield_with_args(an_instance_of(Gitlab::Git::Diff))
+ expect { |b| subject.each(&b) }
+ .to yield_with_args(an_instance_of(Gitlab::Git::Diff))
end
it 'does not prune diffs' do
diff --git a/spec/lib/gitlab/git/diff_spec.rb b/spec/lib/gitlab/git/diff_spec.rb
index da213f617cc..5627562abfb 100644
--- a/spec/lib/gitlab/git/diff_spec.rb
+++ b/spec/lib/gitlab/git/diff_spec.rb
@@ -90,7 +90,7 @@ EOT
let(:diff) { described_class.new(@rugged_diff) }
it 'initializes the diff' do
- expect(diff.to_hash).to eq(@raw_diff_hash.merge(too_large: nil))
+ expect(diff.to_hash).to eq(@raw_diff_hash)
end
it 'does not prune the diff' do
@@ -100,8 +100,8 @@ EOT
context 'using a diff that is too large' do
it 'prunes the diff' do
- expect_any_instance_of(String).to receive(:bytesize).
- and_return(1024 * 1024 * 1024)
+ expect_any_instance_of(String).to receive(:bytesize)
+ .and_return(1024 * 1024 * 1024)
diff = described_class.new(@rugged_diff)
@@ -130,8 +130,8 @@ EOT
context 'using a large binary diff' do
it 'does not prune the diff' do
- expect_any_instance_of(Rugged::Diff::Delta).to receive(:binary?).
- and_return(true)
+ expect_any_instance_of(Rugged::Diff::Delta).to receive(:binary?)
+ .and_return(true)
diff = described_class.new(@rugged_diff)
diff --git a/spec/lib/gitlab/git/gitmodules_parser_spec.rb b/spec/lib/gitlab/git/gitmodules_parser_spec.rb
new file mode 100644
index 00000000000..143aa2218c9
--- /dev/null
+++ b/spec/lib/gitlab/git/gitmodules_parser_spec.rb
@@ -0,0 +1,28 @@
+require 'spec_helper'
+
+describe Gitlab::Git::GitmodulesParser do
+ it 'should parse a .gitmodules file correctly' do
+ parser = described_class.new(<<-'GITMODULES'.strip_heredoc)
+ [submodule "vendor/libgit2"]
+ path = vendor/libgit2
+ [submodule "vendor/libgit2"]
+ url = https://github.com/nodegit/libgit2.git
+
+ # a comment
+ [submodule "moved"]
+ path = new/path
+ url = https://example.com/some/project
+ [submodule "bogus"]
+ url = https://example.com/another/project
+ GITMODULES
+
+ modules = parser.parse
+
+ expect(modules).to eq({
+ 'vendor/libgit2' => { 'name' => 'vendor/libgit2',
+ 'url' => 'https://github.com/nodegit/libgit2.git' },
+ 'new/path' => { 'name' => 'moved',
+ 'url' => 'https://example.com/some/project' }
+ })
+ end
+end
diff --git a/spec/lib/gitlab/git/repository_spec.rb b/spec/lib/gitlab/git/repository_spec.rb
index eee4c9eab6d..703b0c2c202 100644
--- a/spec/lib/gitlab/git/repository_spec.rb
+++ b/spec/lib/gitlab/git/repository_spec.rb
@@ -41,14 +41,14 @@ describe Gitlab::Git::Repository, seed_helper: true do
end
it 'wraps GRPC not found' do
- expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:default_branch_name).
- and_raise(GRPC::NotFound)
+ expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:default_branch_name)
+ .and_raise(GRPC::NotFound)
expect { repository.root_ref }.to raise_error(Gitlab::Git::Repository::NoRepository)
end
it 'wraps GRPC exceptions' do
- expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:default_branch_name).
- and_raise(GRPC::Unknown)
+ expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:default_branch_name)
+ .and_raise(GRPC::Unknown)
expect { repository.root_ref }.to raise_error(Gitlab::Git::CommandError)
end
end
@@ -141,14 +141,14 @@ describe Gitlab::Git::Repository, seed_helper: true do
end
it 'wraps GRPC not found' do
- expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:branch_names).
- and_raise(GRPC::NotFound)
+ expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:branch_names)
+ .and_raise(GRPC::NotFound)
expect { subject }.to raise_error(Gitlab::Git::Repository::NoRepository)
end
it 'wraps GRPC other exceptions' do
- expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:branch_names).
- and_raise(GRPC::Unknown)
+ expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:branch_names)
+ .and_raise(GRPC::Unknown)
expect { subject }.to raise_error(Gitlab::Git::CommandError)
end
end
@@ -184,14 +184,14 @@ describe Gitlab::Git::Repository, seed_helper: true do
end
it 'wraps GRPC not found' do
- expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:tag_names).
- and_raise(GRPC::NotFound)
+ expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:tag_names)
+ .and_raise(GRPC::NotFound)
expect { subject }.to raise_error(Gitlab::Git::Repository::NoRepository)
end
it 'wraps GRPC exceptions' do
- expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:tag_names).
- and_raise(GRPC::Unknown)
+ expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:tag_names)
+ .and_raise(GRPC::Unknown)
expect { subject }.to raise_error(Gitlab::Git::CommandError)
end
end
@@ -358,7 +358,7 @@ describe Gitlab::Git::Repository, seed_helper: true do
expect(submodule).to eq([
"six", {
"id" => "409f37c4f05865e4fb208c771485f211a22c4c2d",
- "path" => "six",
+ "name" => "six",
"url" => "git://github.com/randx/six.git"
}
])
@@ -366,14 +366,14 @@ describe Gitlab::Git::Repository, seed_helper: true do
it 'should handle nested submodules correctly' do
nested = submodules['nested/six']
- expect(nested['path']).to eq('nested/six')
+ expect(nested['name']).to eq('nested/six')
expect(nested['url']).to eq('git://github.com/randx/six.git')
expect(nested['id']).to eq('24fb71c79fcabc63dfd8832b12ee3bf2bf06b196')
end
it 'should handle deeply nested submodules correctly' do
nested = submodules['deeper/nested/six']
- expect(nested['path']).to eq('deeper/nested/six')
+ expect(nested['name']).to eq('deeper/nested/six')
expect(nested['url']).to eq('git://github.com/randx/six.git')
expect(nested['id']).to eq('24fb71c79fcabc63dfd8832b12ee3bf2bf06b196')
end
@@ -393,7 +393,7 @@ describe Gitlab::Git::Repository, seed_helper: true do
expect(submodules.first).to eq([
"six", {
"id" => "409f37c4f05865e4fb208c771485f211a22c4c2d",
- "path" => "six",
+ "name" => "six",
"url" => "git://github.com/randx/six.git"
}
])
@@ -472,8 +472,8 @@ describe Gitlab::Git::Repository, seed_helper: true do
end
it "should move the tip of the master branch to the correct commit" do
- new_tip = @normal_repo.rugged.references["refs/heads/master"].
- target.oid
+ new_tip = @normal_repo.rugged.references["refs/heads/master"]
+ .target.oid
expect(new_tip).to eq(reset_commit)
end
@@ -1306,20 +1306,20 @@ describe Gitlab::Git::Repository, seed_helper: true do
end
it 'gets the branches from GitalyClient' do
- expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:local_branches).
- and_return([])
+ expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:local_branches)
+ .and_return([])
@repo.local_branches
end
it 'wraps GRPC not found' do
- expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:local_branches).
- and_raise(GRPC::NotFound)
+ expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:local_branches)
+ .and_raise(GRPC::NotFound)
expect { @repo.local_branches }.to raise_error(Gitlab::Git::Repository::NoRepository)
end
it 'wraps GRPC exceptions' do
- expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:local_branches).
- and_raise(GRPC::Unknown)
+ expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:local_branches)
+ .and_raise(GRPC::Unknown)
expect { @repo.local_branches }.to raise_error(Gitlab::Git::CommandError)
end
end
diff --git a/spec/lib/gitlab/git_access_spec.rb b/spec/lib/gitlab/git_access_spec.rb
index 3dcc20c48e8..9a86cfa66e4 100644
--- a/spec/lib/gitlab/git_access_spec.rb
+++ b/spec/lib/gitlab/git_access_spec.rb
@@ -3,11 +3,12 @@ require 'spec_helper'
describe Gitlab::GitAccess, lib: true do
let(:pull_access_check) { access.check('git-upload-pack', '_any') }
let(:push_access_check) { access.check('git-receive-pack', '_any') }
- let(:access) { Gitlab::GitAccess.new(actor, project, protocol, authentication_abilities: authentication_abilities) }
+ let(:access) { Gitlab::GitAccess.new(actor, project, protocol, authentication_abilities: authentication_abilities, redirected_path: redirected_path) }
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
let(:actor) { user }
let(:protocol) { 'ssh' }
+ let(:redirected_path) { nil }
let(:authentication_abilities) do
[
:read_project,
@@ -162,6 +163,46 @@ describe Gitlab::GitAccess, lib: true do
end
end
+ describe '#check_project_moved!' do
+ before do
+ project.team << [user, :master]
+ end
+
+ context 'when a redirect was not followed to find the project' do
+ context 'pull code' do
+ it { expect { pull_access_check }.not_to raise_error }
+ end
+
+ context 'push code' do
+ it { expect { push_access_check }.not_to raise_error }
+ end
+ end
+
+ context 'when a redirect was followed to find the project' do
+ let(:redirected_path) { 'some/other-path' }
+
+ context 'pull code' do
+ it { expect { pull_access_check }.to raise_not_found(/Project '#{redirected_path}' was moved to '#{project.full_path}'/) }
+ it { expect { pull_access_check }.to raise_not_found(/git remote set-url origin #{project.ssh_url_to_repo}/) }
+
+ context 'http protocol' do
+ let(:protocol) { 'http' }
+ it { expect { pull_access_check }.to raise_not_found(/git remote set-url origin #{project.http_url_to_repo}/) }
+ end
+ end
+
+ context 'push code' do
+ it { expect { push_access_check }.to raise_not_found(/Project '#{redirected_path}' was moved to '#{project.full_path}'/) }
+ it { expect { push_access_check }.to raise_not_found(/git remote set-url origin #{project.ssh_url_to_repo}/) }
+
+ context 'http protocol' do
+ let(:protocol) { 'http' }
+ it { expect { push_access_check }.to raise_not_found(/git remote set-url origin #{project.http_url_to_repo}/) }
+ end
+ end
+ end
+ end
+
describe '#check_command_disabled!' do
before do
project.team << [user, :master]
diff --git a/spec/lib/gitlab/git_access_wiki_spec.rb b/spec/lib/gitlab/git_access_wiki_spec.rb
index a1eb95750ba..797ec8cb23e 100644
--- a/spec/lib/gitlab/git_access_wiki_spec.rb
+++ b/spec/lib/gitlab/git_access_wiki_spec.rb
@@ -1,9 +1,10 @@
require 'spec_helper'
describe Gitlab::GitAccessWiki, lib: true do
- let(:access) { Gitlab::GitAccessWiki.new(user, project, 'web', authentication_abilities: authentication_abilities) }
+ let(:access) { Gitlab::GitAccessWiki.new(user, project, 'web', authentication_abilities: authentication_abilities, redirected_path: redirected_path) }
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
+ let(:redirected_path) { nil }
let(:authentication_abilities) do
[
:read_project,
diff --git a/spec/lib/gitlab/gitaly_client/commit_spec.rb b/spec/lib/gitlab/gitaly_client/commit_spec.rb
index cf1bc74779e..dff5b25c712 100644
--- a/spec/lib/gitlab/gitaly_client/commit_spec.rb
+++ b/spec/lib/gitlab/gitaly_client/commit_spec.rb
@@ -16,7 +16,7 @@ describe Gitlab::GitalyClient::Commit do
right_commit_id: commit.id
)
- expect_any_instance_of(Gitaly::Diff::Stub).to receive(:commit_diff).with(request)
+ expect_any_instance_of(Gitaly::Diff::Stub).to receive(:commit_diff).with(request, kind_of(Hash))
described_class.new(repository).diff_from_parent(commit)
end
@@ -31,7 +31,7 @@ describe Gitlab::GitalyClient::Commit do
right_commit_id: initial_commit.id
)
- expect_any_instance_of(Gitaly::Diff::Stub).to receive(:commit_diff).with(request)
+ expect_any_instance_of(Gitaly::Diff::Stub).to receive(:commit_diff).with(request, kind_of(Hash))
described_class.new(repository).diff_from_parent(initial_commit)
end
@@ -61,7 +61,7 @@ describe Gitlab::GitalyClient::Commit do
right_commit_id: commit.id
)
- expect_any_instance_of(Gitaly::Diff::Stub).to receive(:commit_delta).with(request).and_return([])
+ expect_any_instance_of(Gitaly::Diff::Stub).to receive(:commit_delta).with(request, kind_of(Hash)).and_return([])
described_class.new(repository).commit_deltas(commit)
end
@@ -76,7 +76,7 @@ describe Gitlab::GitalyClient::Commit do
right_commit_id: initial_commit.id
)
- expect_any_instance_of(Gitaly::Diff::Stub).to receive(:commit_delta).with(request).and_return([])
+ expect_any_instance_of(Gitaly::Diff::Stub).to receive(:commit_delta).with(request, kind_of(Hash)).and_return([])
described_class.new(repository).commit_deltas(initial_commit)
end
diff --git a/spec/lib/gitlab/gitaly_client/notifications_spec.rb b/spec/lib/gitlab/gitaly_client/notifications_spec.rb
index e5c9e06a15e..7404ffe0f06 100644
--- a/spec/lib/gitlab/gitaly_client/notifications_spec.rb
+++ b/spec/lib/gitlab/gitaly_client/notifications_spec.rb
@@ -8,8 +8,8 @@ describe Gitlab::GitalyClient::Notifications do
subject { described_class.new(project.repository) }
it 'sends a post_receive message' do
- expect_any_instance_of(Gitaly::Notifications::Stub).
- to receive(:post_receive).with(gitaly_request_with_path(storage_name, relative_path))
+ expect_any_instance_of(Gitaly::Notifications::Stub)
+ .to receive(:post_receive).with(gitaly_request_with_path(storage_name, relative_path), kind_of(Hash))
subject.post_receive
end
diff --git a/spec/lib/gitlab/gitaly_client/ref_spec.rb b/spec/lib/gitlab/gitaly_client/ref_spec.rb
index 2ea44ef74b0..42dba2ff874 100644
--- a/spec/lib/gitlab/gitaly_client/ref_spec.rb
+++ b/spec/lib/gitlab/gitaly_client/ref_spec.rb
@@ -19,10 +19,10 @@ describe Gitlab::GitalyClient::Ref do
describe '#branch_names' do
it 'sends a find_all_branch_names message' do
- expect_any_instance_of(Gitaly::Ref::Stub).
- to receive(:find_all_branch_names).
- with(gitaly_request_with_path(storage_name, relative_path)).
- and_return([])
+ expect_any_instance_of(Gitaly::Ref::Stub)
+ .to receive(:find_all_branch_names)
+ .with(gitaly_request_with_path(storage_name, relative_path), kind_of(Hash))
+ .and_return([])
client.branch_names
end
@@ -30,10 +30,10 @@ describe Gitlab::GitalyClient::Ref do
describe '#tag_names' do
it 'sends a find_all_tag_names message' do
- expect_any_instance_of(Gitaly::Ref::Stub).
- to receive(:find_all_tag_names).
- with(gitaly_request_with_path(storage_name, relative_path)).
- and_return([])
+ expect_any_instance_of(Gitaly::Ref::Stub)
+ .to receive(:find_all_tag_names)
+ .with(gitaly_request_with_path(storage_name, relative_path), kind_of(Hash))
+ .and_return([])
client.tag_names
end
@@ -41,10 +41,10 @@ describe Gitlab::GitalyClient::Ref do
describe '#default_branch_name' do
it 'sends a find_default_branch_name message' do
- expect_any_instance_of(Gitaly::Ref::Stub).
- to receive(:find_default_branch_name).
- with(gitaly_request_with_path(storage_name, relative_path)).
- and_return(double(name: 'foo'))
+ expect_any_instance_of(Gitaly::Ref::Stub)
+ .to receive(:find_default_branch_name)
+ .with(gitaly_request_with_path(storage_name, relative_path), kind_of(Hash))
+ .and_return(double(name: 'foo'))
client.default_branch_name
end
@@ -52,19 +52,19 @@ describe Gitlab::GitalyClient::Ref do
describe '#local_branches' do
it 'sends a find_local_branches message' do
- expect_any_instance_of(Gitaly::Ref::Stub).
- to receive(:find_local_branches).
- with(gitaly_request_with_path(storage_name, relative_path)).
- and_return([])
+ expect_any_instance_of(Gitaly::Ref::Stub)
+ .to receive(:find_local_branches)
+ .with(gitaly_request_with_path(storage_name, relative_path), kind_of(Hash))
+ .and_return([])
client.local_branches
end
it 'parses and sends the sort parameter' do
- expect_any_instance_of(Gitaly::Ref::Stub).
- to receive(:find_local_branches).
- with(gitaly_request_with_params(sort_by: :UPDATED_DESC)).
- and_return([])
+ expect_any_instance_of(Gitaly::Ref::Stub)
+ .to receive(:find_local_branches)
+ .with(gitaly_request_with_params(sort_by: :UPDATED_DESC), kind_of(Hash))
+ .and_return([])
client.local_branches(sort_by: 'updated_desc')
end
diff --git a/spec/lib/gitlab/gitlab_import/importer_spec.rb b/spec/lib/gitlab/gitlab_import/importer_spec.rb
index 9b499b593d3..4f588da0a83 100644
--- a/spec/lib/gitlab/gitlab_import/importer_spec.rb
+++ b/spec/lib/gitlab/gitlab_import/importer_spec.rb
@@ -45,8 +45,8 @@ describe Gitlab::GitlabImport::Importer, lib: true do
def stub_request(path, body)
url = "https://gitlab.com/api/v3/projects/asd%2Fvim/#{path}?page=1&per_page=100"
- WebMock.stub_request(:get, url).
- to_return(
+ WebMock.stub_request(:get, url)
+ .to_return(
headers: { 'Content-Type' => 'application/json' },
body: body
)
diff --git a/spec/lib/gitlab/group_hierarchy_spec.rb b/spec/lib/gitlab/group_hierarchy_spec.rb
index 5d0ed1522b3..08010c2d0e2 100644
--- a/spec/lib/gitlab/group_hierarchy_spec.rb
+++ b/spec/lib/gitlab/group_hierarchy_spec.rb
@@ -17,6 +17,12 @@ describe Gitlab::GroupHierarchy, :postgresql do
it 'includes all of the ancestors' do
expect(relation).to include(parent, child1)
end
+
+ it 'uses ancestors_base #initialize argument' do
+ relation = described_class.new(Group.where(id: child2.id), Group.none).base_and_ancestors
+
+ expect(relation).to include(parent, child1, child2)
+ end
end
describe '#base_and_descendants' do
@@ -31,6 +37,12 @@ describe Gitlab::GroupHierarchy, :postgresql do
it 'includes all the descendants' do
expect(relation).to include(child1, child2)
end
+
+ it 'uses descendants_base #initialize argument' do
+ relation = described_class.new(Group.none, Group.where(id: parent.id)).base_and_descendants
+
+ expect(relation).to include(parent, child1, child2)
+ end
end
describe '#all_groups' do
@@ -49,5 +61,17 @@ describe Gitlab::GroupHierarchy, :postgresql do
it 'includes the descendants' do
expect(relation).to include(child2)
end
+
+ it 'uses ancestors_base #initialize argument for ancestors' do
+ relation = described_class.new(Group.where(id: child1.id), Group.where(id: Group.maximum(:id).succ)).all_groups
+
+ expect(relation).to include(parent)
+ end
+
+ it 'uses descendants_base #initialize argument for descendants' do
+ relation = described_class.new(Group.where(id: Group.maximum(:id).succ), Group.where(id: child1.id)).all_groups
+
+ expect(relation).to include(child2)
+ end
end
end
diff --git a/spec/lib/gitlab/highlight_spec.rb b/spec/lib/gitlab/highlight_spec.rb
index fdc5b484ef1..07687b470c5 100644
--- a/spec/lib/gitlab/highlight_spec.rb
+++ b/spec/lib/gitlab/highlight_spec.rb
@@ -51,8 +51,8 @@ describe Gitlab::Highlight, lib: true do
end
it 'links dependencies via DependencyLinker' do
- expect(Gitlab::DependencyLinker).to receive(:link).
- with('file.name', 'Contents', anything).and_call_original
+ expect(Gitlab::DependencyLinker).to receive(:link)
+ .with('file.name', 'Contents', anything).and_call_original
described_class.highlight('file.name', 'Contents')
end
diff --git a/spec/lib/gitlab/identifier_spec.rb b/spec/lib/gitlab/identifier_spec.rb
index bb758a8a202..29912da2e25 100644
--- a/spec/lib/gitlab/identifier_spec.rb
+++ b/spec/lib/gitlab/identifier_spec.rb
@@ -12,8 +12,8 @@ describe Gitlab::Identifier do
describe '#identify' do
context 'without an identifier' do
it 'identifies the user using a commit' do
- expect(identifier).to receive(:identify_using_commit).
- with(project, '123')
+ expect(identifier).to receive(:identify_using_commit)
+ .with(project, '123')
identifier.identify('', project, '123')
end
@@ -21,8 +21,8 @@ describe Gitlab::Identifier do
context 'with a user identifier' do
it 'identifies the user using a user ID' do
- expect(identifier).to receive(:identify_using_user).
- with("user-#{user.id}")
+ expect(identifier).to receive(:identify_using_user)
+ .with("user-#{user.id}")
identifier.identify("user-#{user.id}", project, '123')
end
@@ -30,8 +30,8 @@ describe Gitlab::Identifier do
context 'with an SSH key identifier' do
it 'identifies the user using an SSH key ID' do
- expect(identifier).to receive(:identify_using_ssh_key).
- with("key-#{key.id}")
+ expect(identifier).to receive(:identify_using_ssh_key)
+ .with("key-#{key.id}")
identifier.identify("key-#{key.id}", project, '123')
end
diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml
index 412eb33b35b..a5f09f1856e 100644
--- a/spec/lib/gitlab/import_export/all_models.yml
+++ b/spec/lib/gitlab/import_export/all_models.yml
@@ -88,6 +88,9 @@ merge_requests:
- head_pipeline
merge_request_diff:
- merge_request
+- merge_request_diff_files
+merge_request_diff_files:
+- merge_request_diff
pipelines:
- project
- user
diff --git a/spec/lib/gitlab/import_export/project.json b/spec/lib/gitlab/import_export/project.json
index e3599d6fe59..98c117b4cd8 100644
--- a/spec/lib/gitlab/import_export/project.json
+++ b/spec/lib/gitlab/import_export/project.json
@@ -2821,9 +2821,11 @@
"committer_email": "dmitriy.zaporozhets@gmail.com"
}
],
- "utf8_st_diffs": [
+ "merge_request_diff_files": [
{
- "diff": "Binary files a/.DS_Store and /dev/null differ\n",
+ "merge_request_diff_id": 27,
+ "relative_order": 0,
+ "utf8_diff": "Binary files a/.DS_Store and /dev/null differ\n",
"new_path": ".DS_Store",
"old_path": ".DS_Store",
"a_mode": "100644",
@@ -2834,7 +2836,9 @@
"too_large": false
},
{
- "diff": "--- a/.gitignore\n+++ b/.gitignore\n@@ -17,3 +17,4 @@ rerun.txt\n pickle-email-*.html\n .project\n config/initializers/secret_token.rb\n+.DS_Store\n",
+ "merge_request_diff_id": 27,
+ "relative_order": 1,
+ "utf8_diff": "--- a/.gitignore\n+++ b/.gitignore\n@@ -17,3 +17,4 @@ rerun.txt\n pickle-email-*.html\n .project\n config/initializers/secret_token.rb\n+.DS_Store\n",
"new_path": ".gitignore",
"old_path": ".gitignore",
"a_mode": "100644",
@@ -2845,7 +2849,9 @@
"too_large": false
},
{
- "diff": "--- a/.gitmodules\n+++ b/.gitmodules\n@@ -1,3 +1,9 @@\n [submodule \"six\"]\n \tpath = six\n \turl = git://github.com/randx/six.git\n+[submodule \"gitlab-shell\"]\n+\tpath = gitlab-shell\n+\turl = https://github.com/gitlabhq/gitlab-shell.git\n+[submodule \"gitlab-grack\"]\n+\tpath = gitlab-grack\n+\turl = https://gitlab.com/gitlab-org/gitlab-grack.git\n",
+ "merge_request_diff_id": 27,
+ "relative_order": 2,
+ "utf8_diff": "--- a/.gitmodules\n+++ b/.gitmodules\n@@ -1,3 +1,9 @@\n [submodule \"six\"]\n \tpath = six\n \turl = git://github.com/randx/six.git\n+[submodule \"gitlab-shell\"]\n+\tpath = gitlab-shell\n+\turl = https://github.com/gitlabhq/gitlab-shell.git\n+[submodule \"gitlab-grack\"]\n+\tpath = gitlab-grack\n+\turl = https://gitlab.com/gitlab-org/gitlab-grack.git\n",
"new_path": ".gitmodules",
"old_path": ".gitmodules",
"a_mode": "100644",
@@ -2856,7 +2862,9 @@
"too_large": false
},
{
- "diff": "Binary files a/files/.DS_Store and /dev/null differ\n",
+ "merge_request_diff_id": 27,
+ "relative_order": 3,
+ "utf8_diff": "Binary files a/files/.DS_Store and /dev/null differ\n",
"new_path": "files/.DS_Store",
"old_path": "files/.DS_Store",
"a_mode": "100644",
@@ -2867,7 +2875,9 @@
"too_large": false
},
{
- "diff": "--- /dev/null\n+++ b/files/ruby/feature.rb\n@@ -0,0 +1,4 @@\n+# This file was changed in feature branch\n+# We put different code here to make merge conflict\n+class Conflict\n+end\n",
+ "merge_request_diff_id": 27,
+ "relative_order": 4,
+ "utf8_diff": "--- /dev/null\n+++ b/files/ruby/feature.rb\n@@ -0,0 +1,4 @@\n+# This file was changed in feature branch\n+# We put different code here to make merge conflict\n+class Conflict\n+end\n",
"new_path": "files/ruby/feature.rb",
"old_path": "files/ruby/feature.rb",
"a_mode": "0",
@@ -2878,7 +2888,9 @@
"too_large": false
},
{
- "diff": "--- a/files/ruby/popen.rb\n+++ b/files/ruby/popen.rb\n@@ -6,12 +6,18 @@ module Popen\n \n def popen(cmd, path=nil)\n unless cmd.is_a?(Array)\n- raise \"System commands must be given as an array of strings\"\n+ raise RuntimeError, \"System commands must be given as an array of strings\"\n end\n \n path ||= Dir.pwd\n- vars = { \"PWD\" =\u003e path }\n- options = { chdir: path }\n+\n+ vars = {\n+ \"PWD\" =\u003e path\n+ }\n+\n+ options = {\n+ chdir: path\n+ }\n \n unless File.directory?(path)\n FileUtils.mkdir_p(path)\n@@ -19,6 +25,7 @@ module Popen\n \n @cmd_output = \"\"\n @cmd_status = 0\n+\n Open3.popen3(vars, *cmd, options) do |stdin, stdout, stderr, wait_thr|\n @cmd_output \u003c\u003c stdout.read\n @cmd_output \u003c\u003c stderr.read\n",
+ "merge_request_diff_id": 27,
+ "relative_order": 5,
+ "utf8_diff": "--- a/files/ruby/popen.rb\n+++ b/files/ruby/popen.rb\n@@ -6,12 +6,18 @@ module Popen\n \n def popen(cmd, path=nil)\n unless cmd.is_a?(Array)\n- raise \"System commands must be given as an array of strings\"\n+ raise RuntimeError, \"System commands must be given as an array of strings\"\n end\n \n path ||= Dir.pwd\n- vars = { \"PWD\" =\u003e path }\n- options = { chdir: path }\n+\n+ vars = {\n+ \"PWD\" =\u003e path\n+ }\n+\n+ options = {\n+ chdir: path\n+ }\n \n unless File.directory?(path)\n FileUtils.mkdir_p(path)\n@@ -19,6 +25,7 @@ module Popen\n \n @cmd_output = \"\"\n @cmd_status = 0\n+\n Open3.popen3(vars, *cmd, options) do |stdin, stdout, stderr, wait_thr|\n @cmd_output \u003c\u003c stdout.read\n @cmd_output \u003c\u003c stderr.read\n",
"new_path": "files/ruby/popen.rb",
"old_path": "files/ruby/popen.rb",
"a_mode": "100644",
@@ -2889,7 +2901,9 @@
"too_large": false
},
{
- "diff": "--- a/files/ruby/regex.rb\n+++ b/files/ruby/regex.rb\n@@ -19,14 +19,12 @@ module Gitlab\n end\n \n def archive_formats_regex\n- #|zip|tar| tar.gz | tar.bz2 |\n- /(zip|tar|tar\\.gz|tgz|gz|tar\\.bz2|tbz|tbz2|tb2|bz2)/\n+ /(zip|tar|7z|tar\\.gz|tgz|gz|tar\\.bz2|tbz|tbz2|tb2|bz2)/\n end\n \n def git_reference_regex\n # Valid git ref regex, see:\n # https://www.kernel.org/pub/software/scm/git/docs/git-check-ref-format.html\n-\n %r{\n (?!\n (?# doesn't begins with)\n",
+ "merge_request_diff_id": 27,
+ "relative_order": 6,
+ "utf8_diff": "--- a/files/ruby/regex.rb\n+++ b/files/ruby/regex.rb\n@@ -19,14 +19,12 @@ module Gitlab\n end\n \n def archive_formats_regex\n- #|zip|tar| tar.gz | tar.bz2 |\n- /(zip|tar|tar\\.gz|tgz|gz|tar\\.bz2|tbz|tbz2|tb2|bz2)/\n+ /(zip|tar|7z|tar\\.gz|tgz|gz|tar\\.bz2|tbz|tbz2|tb2|bz2)/\n end\n \n def git_reference_regex\n # Valid git ref regex, see:\n # https://www.kernel.org/pub/software/scm/git/docs/git-check-ref-format.html\n-\n %r{\n (?!\n (?# doesn't begins with)\n",
"new_path": "files/ruby/regex.rb",
"old_path": "files/ruby/regex.rb",
"a_mode": "100644",
@@ -2900,7 +2914,9 @@
"too_large": false
},
{
- "diff": "--- /dev/null\n+++ b/gitlab-grack\n@@ -0,0 +1 @@\n+Subproject commit 645f6c4c82fd3f5e06f67134450a570b795e55a6\n",
+ "merge_request_diff_id": 27,
+ "relative_order": 7,
+ "utf8_diff": "--- /dev/null\n+++ b/gitlab-grack\n@@ -0,0 +1 @@\n+Subproject commit 645f6c4c82fd3f5e06f67134450a570b795e55a6\n",
"new_path": "gitlab-grack",
"old_path": "gitlab-grack",
"a_mode": "0",
@@ -2911,7 +2927,9 @@
"too_large": false
},
{
- "diff": "--- /dev/null\n+++ b/gitlab-shell\n@@ -0,0 +1 @@\n+Subproject commit 79bceae69cb5750d6567b223597999bfa91cb3b9\n",
+ "merge_request_diff_id": 27,
+ "relative_order": 8,
+ "utf8_diff": "--- /dev/null\n+++ b/gitlab-shell\n@@ -0,0 +1 @@\n+Subproject commit 79bceae69cb5750d6567b223597999bfa91cb3b9\n",
"new_path": "gitlab-shell",
"old_path": "gitlab-shell",
"a_mode": "0",
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 14338515892..c11b15a811b 100644
--- a/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb
+++ b/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb
@@ -86,8 +86,13 @@ describe Gitlab::ImportExport::ProjectTreeRestorer, services: true do
it 'has the correct data for merge request st_diffs' do
# makes sure we are renaming the custom method +utf8_st_diffs+ into +st_diffs+
+ # one MergeRequestDiff uses the new format, where st_diffs is expected to be nil
- expect(MergeRequestDiff.where.not(st_diffs: nil).count).to eq(9)
+ expect(MergeRequestDiff.where.not(st_diffs: nil).count).to eq(8)
+ end
+
+ it 'has the correct data for merge request diff files' do
+ expect(MergeRequestDiffFile.where.not(diff: nil).count).to eq(9)
end
it 'has the correct time for merge request st_commits' do
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 5aeb29b7fec..e52f79513f1 100644
--- a/spec/lib/gitlab/import_export/project_tree_saver_spec.rb
+++ b/spec/lib/gitlab/import_export/project_tree_saver_spec.rb
@@ -83,6 +83,10 @@ describe Gitlab::ImportExport::ProjectTreeSaver, services: true do
expect(saved_project_json['merge_requests'].first['merge_request_diff']['utf8_st_diffs']).not_to be_nil
end
+ it 'has merge request diff files' do
+ expect(saved_project_json['merge_requests'].first['merge_request_diff']['merge_request_diff_files']).not_to be_empty
+ end
+
it 'has merge requests comments' do
expect(saved_project_json['merge_requests'].first['notes']).not_to be_empty
end
@@ -145,6 +149,12 @@ describe Gitlab::ImportExport::ProjectTreeSaver, services: true do
expect(project_tree_saver.save).to be true
end
+ it 'does not complain about non UTF-8 characters in MR diff files' do
+ ActiveRecord::Base.connection.execute("UPDATE merge_request_diff_files SET diff = '---\n- :diff: !binary |-\n LS0tIC9kZXYvbnVsbAorKysgYi9pbWFnZXMvbnVjb3IucGRmCkBAIC0wLDAg\n KzEsMTY3OSBAQAorJVBERi0xLjUNJeLjz9MNCisxIDAgb2JqDTw8L01ldGFk\n YXR'")
+
+ expect(project_tree_saver.save).to be true
+ end
+
context 'group members' do
let(:user2) { create(:user, email: 'group@member.com') }
let(:member_emails) do
diff --git a/spec/lib/gitlab/import_export/safe_model_attributes.yml b/spec/lib/gitlab/import_export/safe_model_attributes.yml
index 50ff6ecc1e0..fadd3ad1330 100644
--- a/spec/lib/gitlab/import_export/safe_model_attributes.yml
+++ b/spec/lib/gitlab/import_export/safe_model_attributes.yml
@@ -172,6 +172,17 @@ MergeRequestDiff:
- real_size
- head_commit_sha
- start_commit_sha
+MergeRequestDiffFile:
+- merge_request_diff_id
+- relative_order
+- new_file
+- renamed_file
+- deleted_file
+- new_path
+- old_path
+- a_mode
+- b_mode
+- too_large
Ci::Pipeline:
- id
- project_id
diff --git a/spec/lib/gitlab/job_waiter_spec.rb b/spec/lib/gitlab/job_waiter_spec.rb
index 780f5b1f8d7..6186cec2689 100644
--- a/spec/lib/gitlab/job_waiter_spec.rb
+++ b/spec/lib/gitlab/job_waiter_spec.rb
@@ -4,8 +4,8 @@ describe Gitlab::JobWaiter do
describe '#wait' do
let(:waiter) { described_class.new(%w(a)) }
it 'returns when all jobs have been completed' do
- expect(Gitlab::SidekiqStatus).to receive(:all_completed?).with(%w(a)).
- and_return(true)
+ expect(Gitlab::SidekiqStatus).to receive(:all_completed?).with(%w(a))
+ .and_return(true)
expect(waiter).not_to receive(:sleep)
@@ -13,9 +13,9 @@ describe Gitlab::JobWaiter do
end
it 'sleeps between checking the job statuses' do
- expect(Gitlab::SidekiqStatus).to receive(:all_completed?).
- with(%w(a)).
- and_return(false, true)
+ expect(Gitlab::SidekiqStatus).to receive(:all_completed?)
+ .with(%w(a))
+ .and_return(false, true)
expect(waiter).to receive(:sleep).with(described_class::INTERVAL)
diff --git a/spec/lib/gitlab/ldap/authentication_spec.rb b/spec/lib/gitlab/ldap/authentication_spec.rb
index b8f3290e84c..f689b47fec4 100644
--- a/spec/lib/gitlab/ldap/authentication_spec.rb
+++ b/spec/lib/gitlab/ldap/authentication_spec.rb
@@ -16,8 +16,8 @@ describe Gitlab::LDAP::Authentication, lib: true do
# try only to fake the LDAP call
adapter = double('adapter', dn: dn).as_null_object
- allow_any_instance_of(described_class).
- to receive(:adapter).and_return(adapter)
+ allow_any_instance_of(described_class)
+ .to receive(:adapter).and_return(adapter)
expect(described_class.login(login, password)).to be_truthy
end
@@ -25,8 +25,8 @@ describe Gitlab::LDAP::Authentication, lib: true do
it "is false if the user does not exist" do
# try only to fake the LDAP call
adapter = double('adapter', dn: dn).as_null_object
- allow_any_instance_of(described_class).
- to receive(:adapter).and_return(adapter)
+ allow_any_instance_of(described_class)
+ .to receive(:adapter).and_return(adapter)
expect(described_class.login(login, password)).to be_falsey
end
@@ -36,8 +36,8 @@ describe Gitlab::LDAP::Authentication, lib: true do
# try only to fake the LDAP call
adapter = double('adapter', bind_as: nil).as_null_object
- allow_any_instance_of(described_class).
- to receive(:adapter).and_return(adapter)
+ allow_any_instance_of(described_class)
+ .to receive(:adapter).and_return(adapter)
expect(described_class.login(login, password)).to be_falsey
end
diff --git a/spec/lib/gitlab/ldap/user_spec.rb b/spec/lib/gitlab/ldap/user_spec.rb
index f0a1dd22fee..b796d8bf076 100644
--- a/spec/lib/gitlab/ldap/user_spec.rb
+++ b/spec/lib/gitlab/ldap/user_spec.rb
@@ -167,8 +167,8 @@ describe Gitlab::LDAP::User, lib: true do
describe 'blocking' do
def configure_block(value)
- allow_any_instance_of(Gitlab::LDAP::Config).
- to receive(:block_auto_created_users).and_return(value)
+ allow_any_instance_of(Gitlab::LDAP::Config)
+ .to receive(:block_auto_created_users).and_return(value)
end
context 'signup' do
diff --git a/spec/lib/gitlab/metrics/instrumentation_spec.rb b/spec/lib/gitlab/metrics/instrumentation_spec.rb
index a986cb520fb..4b19ee19103 100644
--- a/spec/lib/gitlab/metrics/instrumentation_spec.rb
+++ b/spec/lib/gitlab/metrics/instrumentation_spec.rb
@@ -78,11 +78,11 @@ describe Gitlab::Metrics::Instrumentation do
end
it 'tracks the call duration upon calling the method' do
- allow(Gitlab::Metrics).to receive(:method_call_threshold).
- and_return(0)
+ allow(Gitlab::Metrics).to receive(:method_call_threshold)
+ .and_return(0)
- allow(described_class).to receive(:transaction).
- and_return(transaction)
+ allow(described_class).to receive(:transaction)
+ .and_return(transaction)
expect_any_instance_of(Gitlab::Metrics::MethodCall).to receive(:measure)
@@ -90,8 +90,8 @@ describe Gitlab::Metrics::Instrumentation do
end
it 'does not track method calls below a given duration threshold' do
- allow(Gitlab::Metrics).to receive(:method_call_threshold).
- and_return(100)
+ allow(Gitlab::Metrics).to receive(:method_call_threshold)
+ .and_return(100)
expect(transaction).not_to receive(:add_metric)
@@ -137,8 +137,8 @@ describe Gitlab::Metrics::Instrumentation do
before do
allow(Gitlab::Metrics).to receive(:enabled?).and_return(true)
- described_class.
- instrument_instance_method(@dummy, :bar)
+ described_class
+ .instrument_instance_method(@dummy, :bar)
end
it 'instruments instances of the Class' do
@@ -156,11 +156,11 @@ describe Gitlab::Metrics::Instrumentation do
end
it 'tracks the call duration upon calling the method' do
- allow(Gitlab::Metrics).to receive(:method_call_threshold).
- and_return(0)
+ allow(Gitlab::Metrics).to receive(:method_call_threshold)
+ .and_return(0)
- allow(described_class).to receive(:transaction).
- and_return(transaction)
+ allow(described_class).to receive(:transaction)
+ .and_return(transaction)
expect_any_instance_of(Gitlab::Metrics::MethodCall).to receive(:measure)
@@ -168,8 +168,8 @@ describe Gitlab::Metrics::Instrumentation do
end
it 'does not track method calls below a given duration threshold' do
- allow(Gitlab::Metrics).to receive(:method_call_threshold).
- and_return(100)
+ allow(Gitlab::Metrics).to receive(:method_call_threshold)
+ .and_return(100)
expect(transaction).not_to receive(:add_metric)
@@ -183,8 +183,8 @@ describe Gitlab::Metrics::Instrumentation do
end
it 'does not instrument the method' do
- described_class.
- instrument_instance_method(@dummy, :bar)
+ described_class
+ .instrument_instance_method(@dummy, :bar)
expect(described_class.instrumented?(@dummy)).to eq(false)
end
diff --git a/spec/lib/gitlab/metrics/rack_middleware_spec.rb b/spec/lib/gitlab/metrics/rack_middleware_spec.rb
index fb470ea7568..ec415f2bd85 100644
--- a/spec/lib/gitlab/metrics/rack_middleware_spec.rb
+++ b/spec/lib/gitlab/metrics/rack_middleware_spec.rb
@@ -26,8 +26,8 @@ describe Gitlab::Metrics::RackMiddleware do
allow(app).to receive(:call).with(env)
- expect(middleware).to receive(:tag_controller).
- with(an_instance_of(Gitlab::Metrics::Transaction), env)
+ expect(middleware).to receive(:tag_controller)
+ .with(an_instance_of(Gitlab::Metrics::Transaction), env)
middleware.call(env)
end
@@ -40,8 +40,8 @@ describe Gitlab::Metrics::RackMiddleware do
allow(app).to receive(:call).with(env)
- expect(middleware).to receive(:tag_endpoint).
- with(an_instance_of(Gitlab::Metrics::Transaction), env)
+ expect(middleware).to receive(:tag_endpoint)
+ .with(an_instance_of(Gitlab::Metrics::Transaction), env)
middleware.call(env)
end
@@ -49,8 +49,8 @@ describe Gitlab::Metrics::RackMiddleware do
it 'tracks any raised exceptions' do
expect(app).to receive(:call).with(env).and_raise(RuntimeError)
- expect_any_instance_of(Gitlab::Metrics::Transaction).
- to receive(:add_event).with(:rails_exception)
+ expect_any_instance_of(Gitlab::Metrics::Transaction)
+ .to receive(:add_event).with(:rails_exception)
expect { middleware.call(env) }.to raise_error(RuntimeError)
end
diff --git a/spec/lib/gitlab/metrics/sampler_spec.rb b/spec/lib/gitlab/metrics/sampler_spec.rb
index 1ab923b58cf..d07ce6f81af 100644
--- a/spec/lib/gitlab/metrics/sampler_spec.rb
+++ b/spec/lib/gitlab/metrics/sampler_spec.rb
@@ -38,8 +38,8 @@ describe Gitlab::Metrics::Sampler do
describe '#flush' do
it 'schedules the metrics using Sidekiq' do
- expect(Gitlab::Metrics).to receive(:submit_metrics).
- with([an_instance_of(Hash)])
+ expect(Gitlab::Metrics).to receive(:submit_metrics)
+ .with([an_instance_of(Hash)])
sampler.sample_memory_usage
sampler.flush
@@ -48,12 +48,12 @@ describe Gitlab::Metrics::Sampler do
describe '#sample_memory_usage' do
it 'adds a metric containing the memory usage' do
- expect(Gitlab::Metrics::System).to receive(:memory_usage).
- and_return(9000)
+ expect(Gitlab::Metrics::System).to receive(:memory_usage)
+ .and_return(9000)
- expect(sampler).to receive(:add_metric).
- with(/memory_usage/, value: 9000).
- and_call_original
+ expect(sampler).to receive(:add_metric)
+ .with(/memory_usage/, value: 9000)
+ .and_call_original
sampler.sample_memory_usage
end
@@ -61,12 +61,12 @@ describe Gitlab::Metrics::Sampler do
describe '#sample_file_descriptors' do
it 'adds a metric containing the amount of open file descriptors' do
- expect(Gitlab::Metrics::System).to receive(:file_descriptor_count).
- and_return(4)
+ expect(Gitlab::Metrics::System).to receive(:file_descriptor_count)
+ .and_return(4)
- expect(sampler).to receive(:add_metric).
- with(/file_descriptors/, value: 4).
- and_call_original
+ expect(sampler).to receive(:add_metric)
+ .with(/file_descriptors/, value: 4)
+ .and_call_original
sampler.sample_file_descriptors
end
@@ -75,10 +75,10 @@ describe Gitlab::Metrics::Sampler do
if Gitlab::Metrics.mri?
describe '#sample_objects' do
it 'adds a metric containing the amount of allocated objects' do
- expect(sampler).to receive(:add_metric).
- with(/object_counts/, an_instance_of(Hash), an_instance_of(Hash)).
- at_least(:once).
- and_call_original
+ expect(sampler).to receive(:add_metric)
+ .with(/object_counts/, an_instance_of(Hash), an_instance_of(Hash))
+ .at_least(:once)
+ .and_call_original
sampler.sample_objects
end
@@ -86,8 +86,8 @@ describe Gitlab::Metrics::Sampler do
it 'ignores classes without a name' do
expect(Allocations).to receive(:to_hash).and_return({ Class.new => 4 })
- expect(sampler).not_to receive(:add_metric).
- with('object_counts', an_instance_of(Hash), type: nil)
+ expect(sampler).not_to receive(:add_metric)
+ .with('object_counts', an_instance_of(Hash), type: nil)
sampler.sample_objects
end
@@ -98,9 +98,9 @@ describe Gitlab::Metrics::Sampler do
it 'adds a metric containing garbage collection statistics' do
expect(GC::Profiler).to receive(:total_time).and_return(0.24)
- expect(sampler).to receive(:add_metric).
- with(/gc_statistics/, an_instance_of(Hash)).
- and_call_original
+ expect(sampler).to receive(:add_metric)
+ .with(/gc_statistics/, an_instance_of(Hash))
+ .and_call_original
sampler.sample_gc
end
@@ -110,9 +110,9 @@ describe Gitlab::Metrics::Sampler do
it 'prefixes the series name for a Rails process' do
expect(sampler).to receive(:sidekiq?).and_return(false)
- expect(Gitlab::Metrics::Metric).to receive(:new).
- with('rails_cats', { value: 10 }, {}).
- and_call_original
+ expect(Gitlab::Metrics::Metric).to receive(:new)
+ .with('rails_cats', { value: 10 }, {})
+ .and_call_original
sampler.add_metric('cats', value: 10)
end
@@ -120,9 +120,9 @@ describe Gitlab::Metrics::Sampler do
it 'prefixes the series name for a Sidekiq process' do
expect(sampler).to receive(:sidekiq?).and_return(true)
- expect(Gitlab::Metrics::Metric).to receive(:new).
- with('sidekiq_cats', { value: 10 }, {}).
- and_call_original
+ expect(Gitlab::Metrics::Metric).to receive(:new)
+ .with('sidekiq_cats', { value: 10 }, {})
+ .and_call_original
sampler.add_metric('cats', value: 10)
end
diff --git a/spec/lib/gitlab/metrics/sidekiq_middleware_spec.rb b/spec/lib/gitlab/metrics/sidekiq_middleware_spec.rb
index acaba785606..b576d7173f5 100644
--- a/spec/lib/gitlab/metrics/sidekiq_middleware_spec.rb
+++ b/spec/lib/gitlab/metrics/sidekiq_middleware_spec.rb
@@ -8,12 +8,12 @@ describe Gitlab::Metrics::SidekiqMiddleware do
it 'tracks the transaction' do
worker = double(:worker, class: double(:class, name: 'TestWorker'))
- expect(Gitlab::Metrics::Transaction).to receive(:new).
- with('TestWorker#perform').
- and_call_original
+ expect(Gitlab::Metrics::Transaction).to receive(:new)
+ .with('TestWorker#perform')
+ .and_call_original
- expect_any_instance_of(Gitlab::Metrics::Transaction).to receive(:set).
- with(:sidekiq_queue_duration, instance_of(Float))
+ expect_any_instance_of(Gitlab::Metrics::Transaction).to receive(:set)
+ .with(:sidekiq_queue_duration, instance_of(Float))
expect_any_instance_of(Gitlab::Metrics::Transaction).to receive(:finish)
@@ -23,12 +23,12 @@ describe Gitlab::Metrics::SidekiqMiddleware do
it 'tracks the transaction (for messages without `enqueued_at`)' do
worker = double(:worker, class: double(:class, name: 'TestWorker'))
- expect(Gitlab::Metrics::Transaction).to receive(:new).
- with('TestWorker#perform').
- and_call_original
+ expect(Gitlab::Metrics::Transaction).to receive(:new)
+ .with('TestWorker#perform')
+ .and_call_original
- expect_any_instance_of(Gitlab::Metrics::Transaction).to receive(:set).
- with(:sidekiq_queue_duration, instance_of(Float))
+ expect_any_instance_of(Gitlab::Metrics::Transaction).to receive(:set)
+ .with(:sidekiq_queue_duration, instance_of(Float))
expect_any_instance_of(Gitlab::Metrics::Transaction).to receive(:finish)
@@ -38,17 +38,17 @@ describe Gitlab::Metrics::SidekiqMiddleware do
it 'tracks any raised exceptions' do
worker = double(:worker, class: double(:class, name: 'TestWorker'))
- expect_any_instance_of(Gitlab::Metrics::Transaction).
- to receive(:run).and_raise(RuntimeError)
+ expect_any_instance_of(Gitlab::Metrics::Transaction)
+ .to receive(:run).and_raise(RuntimeError)
- expect_any_instance_of(Gitlab::Metrics::Transaction).
- to receive(:add_event).with(:sidekiq_exception)
+ expect_any_instance_of(Gitlab::Metrics::Transaction)
+ .to receive(:add_event).with(:sidekiq_exception)
- expect_any_instance_of(Gitlab::Metrics::Transaction).
- to receive(:finish)
+ expect_any_instance_of(Gitlab::Metrics::Transaction)
+ .to receive(:finish)
- expect { middleware.call(worker, message, :test) }.
- to raise_error(RuntimeError)
+ expect { middleware.call(worker, message, :test) }
+ .to raise_error(RuntimeError)
end
end
end
diff --git a/spec/lib/gitlab/metrics/subscribers/action_view_spec.rb b/spec/lib/gitlab/metrics/subscribers/action_view_spec.rb
index 0695c5ce096..e7b595405a8 100644
--- a/spec/lib/gitlab/metrics/subscribers/action_view_spec.rb
+++ b/spec/lib/gitlab/metrics/subscribers/action_view_spec.rb
@@ -21,11 +21,11 @@ describe Gitlab::Metrics::Subscribers::ActionView do
values = { duration: 2.1 }
tags = { view: 'app/views/x.html.haml' }
- expect(transaction).to receive(:increment).
- with(:view_duration, 2.1)
+ expect(transaction).to receive(:increment)
+ .with(:view_duration, 2.1)
- expect(transaction).to receive(:add_metric).
- with(described_class::SERIES, values, tags)
+ expect(transaction).to receive(:add_metric)
+ .with(described_class::SERIES, values, tags)
subscriber.render_template(event)
end
diff --git a/spec/lib/gitlab/metrics/subscribers/active_record_spec.rb b/spec/lib/gitlab/metrics/subscribers/active_record_spec.rb
index 49699ffe28f..ce6587e993f 100644
--- a/spec/lib/gitlab/metrics/subscribers/active_record_spec.rb
+++ b/spec/lib/gitlab/metrics/subscribers/active_record_spec.rb
@@ -12,8 +12,8 @@ describe Gitlab::Metrics::Subscribers::ActiveRecord do
describe '#sql' do
describe 'without a current transaction' do
it 'simply returns' do
- expect_any_instance_of(Gitlab::Metrics::Transaction).
- not_to receive(:increment)
+ expect_any_instance_of(Gitlab::Metrics::Transaction)
+ .not_to receive(:increment)
subscriber.sql(event)
end
@@ -21,15 +21,15 @@ describe Gitlab::Metrics::Subscribers::ActiveRecord do
describe 'with a current transaction' do
it 'increments the :sql_duration value' do
- expect(subscriber).to receive(:current_transaction).
- at_least(:once).
- and_return(transaction)
+ expect(subscriber).to receive(:current_transaction)
+ .at_least(:once)
+ .and_return(transaction)
- expect(transaction).to receive(:increment).
- with(:sql_duration, 0.2)
+ expect(transaction).to receive(:increment)
+ .with(:sql_duration, 0.2)
- expect(transaction).to receive(:increment).
- with(:sql_count, 1)
+ expect(transaction).to receive(:increment)
+ .with(:sql_count, 1)
subscriber.sql(event)
end
diff --git a/spec/lib/gitlab/metrics/subscribers/rails_cache_spec.rb b/spec/lib/gitlab/metrics/subscribers/rails_cache_spec.rb
index d986c6fac43..f04dc8dcc02 100644
--- a/spec/lib/gitlab/metrics/subscribers/rails_cache_spec.rb
+++ b/spec/lib/gitlab/metrics/subscribers/rails_cache_spec.rb
@@ -8,26 +8,26 @@ describe Gitlab::Metrics::Subscribers::RailsCache do
describe '#cache_read' do
it 'increments the cache_read duration' do
- expect(subscriber).to receive(:increment).
- with(:cache_read, event.duration)
+ expect(subscriber).to receive(:increment)
+ .with(:cache_read, event.duration)
subscriber.cache_read(event)
end
context 'with a transaction' do
before do
- allow(subscriber).to receive(:current_transaction).
- and_return(transaction)
+ allow(subscriber).to receive(:current_transaction)
+ .and_return(transaction)
end
context 'with hit event' do
let(:event) { double(:event, duration: 15.2, payload: { hit: true }) }
it 'increments the cache_read_hit count' do
- expect(transaction).to receive(:increment).
- with(:cache_read_hit_count, 1)
- expect(transaction).to receive(:increment).
- with(any_args).at_least(1) # Other calls
+ expect(transaction).to receive(:increment)
+ .with(:cache_read_hit_count, 1)
+ expect(transaction).to receive(:increment)
+ .with(any_args).at_least(1) # Other calls
subscriber.cache_read(event)
end
@@ -36,8 +36,8 @@ describe Gitlab::Metrics::Subscribers::RailsCache do
let(:event) { double(:event, duration: 15.2, payload: { hit: true, super_operation: :fetch }) }
it 'does not increment cache read miss' do
- expect(transaction).not_to receive(:increment).
- with(:cache_read_hit_count, 1)
+ expect(transaction).not_to receive(:increment)
+ .with(:cache_read_hit_count, 1)
subscriber.cache_read(event)
end
@@ -48,10 +48,10 @@ describe Gitlab::Metrics::Subscribers::RailsCache do
let(:event) { double(:event, duration: 15.2, payload: { hit: false }) }
it 'increments the cache_read_miss count' do
- expect(transaction).to receive(:increment).
- with(:cache_read_miss_count, 1)
- expect(transaction).to receive(:increment).
- with(any_args).at_least(1) # Other calls
+ expect(transaction).to receive(:increment)
+ .with(:cache_read_miss_count, 1)
+ expect(transaction).to receive(:increment)
+ .with(any_args).at_least(1) # Other calls
subscriber.cache_read(event)
end
@@ -60,8 +60,8 @@ describe Gitlab::Metrics::Subscribers::RailsCache do
let(:event) { double(:event, duration: 15.2, payload: { hit: false, super_operation: :fetch }) }
it 'does not increment cache read miss' do
- expect(transaction).not_to receive(:increment).
- with(:cache_read_miss_count, 1)
+ expect(transaction).not_to receive(:increment)
+ .with(:cache_read_miss_count, 1)
subscriber.cache_read(event)
end
@@ -72,8 +72,8 @@ describe Gitlab::Metrics::Subscribers::RailsCache do
describe '#cache_write' do
it 'increments the cache_write duration' do
- expect(subscriber).to receive(:increment).
- with(:cache_write, event.duration)
+ expect(subscriber).to receive(:increment)
+ .with(:cache_write, event.duration)
subscriber.cache_write(event)
end
@@ -81,8 +81,8 @@ describe Gitlab::Metrics::Subscribers::RailsCache do
describe '#cache_delete' do
it 'increments the cache_delete duration' do
- expect(subscriber).to receive(:increment).
- with(:cache_delete, event.duration)
+ expect(subscriber).to receive(:increment)
+ .with(:cache_delete, event.duration)
subscriber.cache_delete(event)
end
@@ -90,8 +90,8 @@ describe Gitlab::Metrics::Subscribers::RailsCache do
describe '#cache_exist?' do
it 'increments the cache_exists duration' do
- expect(subscriber).to receive(:increment).
- with(:cache_exists, event.duration)
+ expect(subscriber).to receive(:increment)
+ .with(:cache_exists, event.duration)
subscriber.cache_exist?(event)
end
@@ -108,13 +108,13 @@ describe Gitlab::Metrics::Subscribers::RailsCache do
context 'with a transaction' do
before do
- allow(subscriber).to receive(:current_transaction).
- and_return(transaction)
+ allow(subscriber).to receive(:current_transaction)
+ .and_return(transaction)
end
it 'increments the cache_read_hit count' do
- expect(transaction).to receive(:increment).
- with(:cache_read_hit_count, 1)
+ expect(transaction).to receive(:increment)
+ .with(:cache_read_hit_count, 1)
subscriber.cache_fetch_hit(event)
end
@@ -132,13 +132,13 @@ describe Gitlab::Metrics::Subscribers::RailsCache do
context 'with a transaction' do
before do
- allow(subscriber).to receive(:current_transaction).
- and_return(transaction)
+ allow(subscriber).to receive(:current_transaction)
+ .and_return(transaction)
end
it 'increments the cache_fetch_miss count' do
- expect(transaction).to receive(:increment).
- with(:cache_read_miss_count, 1)
+ expect(transaction).to receive(:increment)
+ .with(:cache_read_miss_count, 1)
subscriber.cache_generate(event)
end
@@ -156,22 +156,22 @@ describe Gitlab::Metrics::Subscribers::RailsCache do
context 'with a transaction' do
before do
- allow(subscriber).to receive(:current_transaction).
- and_return(transaction)
+ allow(subscriber).to receive(:current_transaction)
+ .and_return(transaction)
end
it 'increments the total and specific cache duration' do
- expect(transaction).to receive(:increment).
- with(:cache_duration, event.duration)
+ expect(transaction).to receive(:increment)
+ .with(:cache_duration, event.duration)
- expect(transaction).to receive(:increment).
- with(:cache_count, 1)
+ expect(transaction).to receive(:increment)
+ .with(:cache_count, 1)
- expect(transaction).to receive(:increment).
- with(:cache_delete_duration, event.duration)
+ expect(transaction).to receive(:increment)
+ .with(:cache_delete_duration, event.duration)
- expect(transaction).to receive(:increment).
- with(:cache_delete_count, 1)
+ expect(transaction).to receive(:increment)
+ .with(:cache_delete_count, 1)
subscriber.increment(:cache_delete, event.duration)
end
diff --git a/spec/lib/gitlab/metrics/transaction_spec.rb b/spec/lib/gitlab/metrics/transaction_spec.rb
index 0c5a6246d85..3779af81512 100644
--- a/spec/lib/gitlab/metrics/transaction_spec.rb
+++ b/spec/lib/gitlab/metrics/transaction_spec.rb
@@ -39,8 +39,8 @@ describe Gitlab::Metrics::Transaction do
describe '#add_metric' do
it 'adds a metric to the transaction' do
- expect(Gitlab::Metrics::Metric).to receive(:new).
- with('rails_foo', { number: 10 }, {})
+ expect(Gitlab::Metrics::Metric).to receive(:new)
+ .with('rails_foo', { number: 10 }, {})
transaction.add_metric('foo', number: 10)
end
@@ -61,8 +61,8 @@ describe Gitlab::Metrics::Transaction do
values = { duration: 0.0, time: 3, allocated_memory: a_kind_of(Numeric) }
- expect(transaction).to receive(:add_metric).
- with('transactions', values, {})
+ expect(transaction).to receive(:add_metric)
+ .with('transactions', values, {})
transaction.track_self
end
@@ -78,8 +78,8 @@ describe Gitlab::Metrics::Transaction do
allocated_memory: a_kind_of(Numeric)
}
- expect(transaction).to receive(:add_metric).
- with('transactions', values, {})
+ expect(transaction).to receive(:add_metric)
+ .with('transactions', values, {})
transaction.track_self
end
@@ -109,8 +109,8 @@ describe Gitlab::Metrics::Transaction do
allocated_memory: a_kind_of(Numeric)
}
- expect(transaction).to receive(:add_metric).
- with('transactions', values, {})
+ expect(transaction).to receive(:add_metric)
+ .with('transactions', values, {})
transaction.track_self
end
@@ -120,8 +120,8 @@ describe Gitlab::Metrics::Transaction do
it 'submits the metrics to Sidekiq' do
transaction.track_self
- expect(Gitlab::Metrics).to receive(:submit_metrics).
- with([an_instance_of(Hash)])
+ expect(Gitlab::Metrics).to receive(:submit_metrics)
+ .with([an_instance_of(Hash)])
transaction.submit
end
@@ -137,8 +137,8 @@ describe Gitlab::Metrics::Transaction do
timestamp: a_kind_of(Integer)
}
- expect(Gitlab::Metrics).to receive(:submit_metrics).
- with([hash])
+ expect(Gitlab::Metrics).to receive(:submit_metrics)
+ .with([hash])
transaction.submit
end
@@ -154,8 +154,8 @@ describe Gitlab::Metrics::Transaction do
timestamp: a_kind_of(Integer)
}
- expect(Gitlab::Metrics).to receive(:submit_metrics).
- with([hash])
+ expect(Gitlab::Metrics).to receive(:submit_metrics)
+ .with([hash])
transaction.submit
end
diff --git a/spec/lib/gitlab/metrics_spec.rb b/spec/lib/gitlab/metrics_spec.rb
index 5a87b906609..599b8807d8d 100644
--- a/spec/lib/gitlab/metrics_spec.rb
+++ b/spec/lib/gitlab/metrics_spec.rb
@@ -15,6 +15,36 @@ describe Gitlab::Metrics do
end
end
+ describe '.prometheus_metrics_enabled_unmemoized' do
+ subject { described_class.send(:prometheus_metrics_enabled_unmemoized) }
+
+ context 'prometheus metrics enabled in config' do
+ before do
+ allow(described_class).to receive(:current_application_settings).and_return(prometheus_metrics_enabled: true)
+ end
+
+ context 'when metrics folder is present' do
+ before do
+ allow(described_class).to receive(:metrics_folder_present?).and_return(true)
+ end
+
+ it 'metrics are enabled' do
+ expect(subject).to eq(true)
+ end
+ end
+
+ context 'when metrics folder is missing' do
+ before do
+ allow(described_class).to receive(:metrics_folder_present?).and_return(false)
+ end
+
+ it 'metrics are disabled' do
+ expect(subject).to eq(false)
+ end
+ end
+ end
+ end
+
describe '.prometheus_metrics_enabled?' do
it 'returns a boolean' do
expect(described_class.prometheus_metrics_enabled?).to be_in([true, false])
@@ -42,8 +72,8 @@ describe Gitlab::Metrics do
describe '.prepare_metrics' do
it 'returns a Hash with the keys as Symbols' do
- metrics = described_class.
- prepare_metrics([{ 'values' => {}, 'tags' => {} }])
+ metrics = described_class
+ .prepare_metrics([{ 'values' => {}, 'tags' => {} }])
expect(metrics).to eq([{ values: {}, tags: {} }])
end
@@ -88,19 +118,19 @@ describe Gitlab::Metrics do
let(:transaction) { Gitlab::Metrics::Transaction.new }
before do
- allow(described_class).to receive(:current_transaction).
- and_return(transaction)
+ allow(described_class).to receive(:current_transaction)
+ .and_return(transaction)
end
it 'adds a metric to the current transaction' do
- expect(transaction).to receive(:increment).
- with('foo_real_time', a_kind_of(Numeric))
+ expect(transaction).to receive(:increment)
+ .with('foo_real_time', a_kind_of(Numeric))
- expect(transaction).to receive(:increment).
- with('foo_cpu_time', a_kind_of(Numeric))
+ expect(transaction).to receive(:increment)
+ .with('foo_cpu_time', a_kind_of(Numeric))
- expect(transaction).to receive(:increment).
- with('foo_call_count', 1)
+ expect(transaction).to receive(:increment)
+ .with('foo_call_count', 1)
described_class.measure(:foo) { 10 }
end
@@ -116,8 +146,8 @@ describe Gitlab::Metrics do
describe '.tag_transaction' do
context 'without a transaction' do
it 'does nothing' do
- expect_any_instance_of(Gitlab::Metrics::Transaction).
- not_to receive(:add_tag)
+ expect_any_instance_of(Gitlab::Metrics::Transaction)
+ .not_to receive(:add_tag)
described_class.tag_transaction(:foo, 'bar')
end
@@ -127,11 +157,11 @@ describe Gitlab::Metrics do
let(:transaction) { Gitlab::Metrics::Transaction.new }
it 'adds the tag to the transaction' do
- expect(described_class).to receive(:current_transaction).
- and_return(transaction)
+ expect(described_class).to receive(:current_transaction)
+ .and_return(transaction)
- expect(transaction).to receive(:add_tag).
- with(:foo, 'bar')
+ expect(transaction).to receive(:add_tag)
+ .with(:foo, 'bar')
described_class.tag_transaction(:foo, 'bar')
end
@@ -141,8 +171,8 @@ describe Gitlab::Metrics do
describe '.action=' do
context 'without a transaction' do
it 'does nothing' do
- expect_any_instance_of(Gitlab::Metrics::Transaction).
- not_to receive(:action=)
+ expect_any_instance_of(Gitlab::Metrics::Transaction)
+ .not_to receive(:action=)
described_class.action = 'foo'
end
@@ -152,8 +182,8 @@ describe Gitlab::Metrics do
it 'sets the action of a transaction' do
trans = Gitlab::Metrics::Transaction.new
- expect(described_class).to receive(:current_transaction).
- and_return(trans)
+ expect(described_class).to receive(:current_transaction)
+ .and_return(trans)
expect(trans).to receive(:action=).with('foo')
@@ -171,8 +201,8 @@ describe Gitlab::Metrics do
describe '.add_event' do
context 'without a transaction' do
it 'does nothing' do
- expect_any_instance_of(Gitlab::Metrics::Transaction).
- not_to receive(:add_event)
+ expect_any_instance_of(Gitlab::Metrics::Transaction)
+ .not_to receive(:add_event)
described_class.add_event(:meow)
end
@@ -184,8 +214,8 @@ describe Gitlab::Metrics do
expect(transaction).to receive(:add_event).with(:meow)
- expect(described_class).to receive(:current_transaction).
- and_return(transaction)
+ expect(described_class).to receive(:current_transaction)
+ .and_return(transaction)
described_class.add_event(:meow)
end
diff --git a/spec/lib/gitlab/project_authorizations_spec.rb b/spec/lib/gitlab/project_authorizations_spec.rb
index 67321f43710..9ce33685697 100644
--- a/spec/lib/gitlab/project_authorizations_spec.rb
+++ b/spec/lib/gitlab/project_authorizations_spec.rb
@@ -34,8 +34,8 @@ describe Gitlab::ProjectAuthorizations do
end
it 'includes the correct projects' do
- expect(authorizations.pluck(:project_id)).
- to include(owned_project.id, other_project.id, group_project.id)
+ expect(authorizations.pluck(:project_id))
+ .to include(owned_project.id, other_project.id, group_project.id)
end
it 'includes the correct access levels' do
diff --git a/spec/lib/gitlab/slash_commands/command_definition_spec.rb b/spec/lib/gitlab/quick_actions/command_definition_spec.rb
index 5b9173d3d3f..f44a562dc63 100644
--- a/spec/lib/gitlab/slash_commands/command_definition_spec.rb
+++ b/spec/lib/gitlab/quick_actions/command_definition_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe Gitlab::SlashCommands::CommandDefinition do
+describe Gitlab::QuickActions::CommandDefinition do
subject { described_class.new(:command) }
describe "#all_names" do
diff --git a/spec/lib/gitlab/slash_commands/dsl_spec.rb b/spec/lib/gitlab/quick_actions/dsl_spec.rb
index 33b49a5ddf9..a4bb3f911d7 100644
--- a/spec/lib/gitlab/slash_commands/dsl_spec.rb
+++ b/spec/lib/gitlab/quick_actions/dsl_spec.rb
@@ -1,9 +1,9 @@
require 'spec_helper'
-describe Gitlab::SlashCommands::Dsl do
+describe Gitlab::QuickActions::Dsl do
before :all do
DummyClass = Struct.new(:project) do
- include Gitlab::SlashCommands::Dsl # rubocop:disable RSpec/DescribedClass
+ include Gitlab::QuickActions::Dsl # rubocop:disable RSpec/DescribedClass
desc 'A command with no args'
command :no_args, :none do
diff --git a/spec/lib/gitlab/slash_commands/extractor_spec.rb b/spec/lib/gitlab/quick_actions/extractor_spec.rb
index d7f77486b3e..9d32938e155 100644
--- a/spec/lib/gitlab/slash_commands/extractor_spec.rb
+++ b/spec/lib/gitlab/quick_actions/extractor_spec.rb
@@ -1,9 +1,9 @@
require 'spec_helper'
-describe Gitlab::SlashCommands::Extractor do
+describe Gitlab::QuickActions::Extractor do
let(:definitions) do
Class.new do
- include Gitlab::SlashCommands::Dsl
+ include Gitlab::QuickActions::Dsl
command(:reopen, :open) { }
command(:assign) { }
diff --git a/spec/lib/gitlab/regex_spec.rb b/spec/lib/gitlab/regex_spec.rb
index 0bee892fe0c..979f4fefcb6 100644
--- a/spec/lib/gitlab/regex_spec.rb
+++ b/spec/lib/gitlab/regex_spec.rb
@@ -21,6 +21,18 @@ describe Gitlab::Regex, lib: true do
end
describe '.environment_slug_regex' do
+ subject { described_class.environment_name_regex }
+
+ it { is_expected.to match('foo') }
+ it { is_expected.to match('foo-1') }
+ it { is_expected.to match('FOO') }
+ it { is_expected.to match('foo/1') }
+ it { is_expected.to match('foo.1') }
+ it { is_expected.not_to match('9&foo') }
+ it { is_expected.not_to match('foo-^') }
+ end
+
+ describe '.environment_slug_regex' do
subject { described_class.environment_slug_regex }
it { is_expected.to match('foo') }
diff --git a/spec/lib/gitlab/repo_path_spec.rb b/spec/lib/gitlab/repo_path_spec.rb
index f9025397107..efea4f429bf 100644
--- a/spec/lib/gitlab/repo_path_spec.rb
+++ b/spec/lib/gitlab/repo_path_spec.rb
@@ -4,24 +4,44 @@ describe ::Gitlab::RepoPath do
describe '.parse' do
set(:project) { create(:project) }
- it 'parses a full repository path' do
- expect(described_class.parse(project.repository.path)).to eq([project, false])
- end
+ context 'a repository storage path' do
+ it 'parses a full repository path' do
+ expect(described_class.parse(project.repository.path)).to eq([project, false, nil])
+ end
- it 'parses a full wiki path' do
- expect(described_class.parse(project.wiki.repository.path)).to eq([project, true])
+ it 'parses a full wiki path' do
+ expect(described_class.parse(project.wiki.repository.path)).to eq([project, true, nil])
+ end
end
- it 'parses a relative repository path' do
- expect(described_class.parse(project.full_path + '.git')).to eq([project, false])
- end
+ context 'a relative path' do
+ it 'parses a relative repository path' do
+ expect(described_class.parse(project.full_path + '.git')).to eq([project, false, nil])
+ end
- it 'parses a relative wiki path' do
- expect(described_class.parse(project.full_path + '.wiki.git')).to eq([project, true])
- end
+ it 'parses a relative wiki path' do
+ expect(described_class.parse(project.full_path + '.wiki.git')).to eq([project, true, nil])
+ end
+
+ it 'parses a relative path starting with /' do
+ expect(described_class.parse('/' + project.full_path + '.git')).to eq([project, false, nil])
+ end
+
+ context 'of a redirected project' do
+ let(:redirect) { project.route.create_redirect('foo/bar') }
+
+ it 'parses a relative repository path' do
+ expect(described_class.parse(redirect.path + '.git')).to eq([project, false, 'foo/bar'])
+ end
+
+ it 'parses a relative wiki path' do
+ expect(described_class.parse(redirect.path + '.wiki.git')).to eq([project, true, 'foo/bar.wiki'])
+ end
- it 'parses a relative path starting with /' do
- expect(described_class.parse('/' + project.full_path + '.git')).to eq([project, false])
+ it 'parses a relative path starting with /' do
+ expect(described_class.parse('/' + redirect.path + '.git')).to eq([project, false, 'foo/bar'])
+ end
+ end
end
end
@@ -43,4 +63,33 @@ describe ::Gitlab::RepoPath do
)
end
end
+
+ describe '.find_project' do
+ let(:project) { create(:empty_project) }
+ let(:redirect) { project.route.create_redirect('foo/bar/baz') }
+
+ context 'when finding a project by its canonical path' do
+ context 'when the cases match' do
+ it 'returns the project and false' do
+ expect(described_class.find_project(project.full_path)).to eq([project, false])
+ end
+ end
+
+ context 'when the cases do not match' do
+ # This is slightly different than web behavior because on the web it is
+ # easy and safe to redirect someone to the correctly-cased URL. For git
+ # requests, we should accept wrongly-cased URLs because it is a pain to
+ # block people's git operations and force them to update remote URLs.
+ it 'returns the project and false' do
+ expect(described_class.find_project(project.full_path.upcase)).to eq([project, false])
+ end
+ end
+ end
+
+ context 'when finding a project via a redirect' do
+ it 'returns the project and true' do
+ expect(described_class.find_project(redirect.path)).to eq([project, true])
+ end
+ end
+ end
end
diff --git a/spec/lib/gitlab/route_map_spec.rb b/spec/lib/gitlab/route_map_spec.rb
index 2370f56a613..21c00c6e5b8 100644
--- a/spec/lib/gitlab/route_map_spec.rb
+++ b/spec/lib/gitlab/route_map_spec.rb
@@ -4,43 +4,43 @@ describe Gitlab::RouteMap, lib: true do
describe '#initialize' do
context 'when the data is not YAML' do
it 'raises an error' do
- expect { described_class.new('"') }.
- to raise_error(Gitlab::RouteMap::FormatError, /valid YAML/)
+ expect { described_class.new('"') }
+ .to raise_error(Gitlab::RouteMap::FormatError, /valid YAML/)
end
end
context 'when the data is not a YAML array' do
it 'raises an error' do
- expect { described_class.new(YAML.dump('foo')) }.
- to raise_error(Gitlab::RouteMap::FormatError, /an array/)
+ expect { described_class.new(YAML.dump('foo')) }
+ .to raise_error(Gitlab::RouteMap::FormatError, /an array/)
end
end
context 'when an entry is not a hash' do
it 'raises an error' do
- expect { described_class.new(YAML.dump(['foo'])) }.
- to raise_error(Gitlab::RouteMap::FormatError, /a hash/)
+ expect { described_class.new(YAML.dump(['foo'])) }
+ .to raise_error(Gitlab::RouteMap::FormatError, /a hash/)
end
end
context 'when an entry does not have a source key' do
it 'raises an error' do
- expect { described_class.new(YAML.dump([{ 'public' => 'index.html' }])) }.
- to raise_error(Gitlab::RouteMap::FormatError, /source key/)
+ expect { described_class.new(YAML.dump([{ 'public' => 'index.html' }])) }
+ .to raise_error(Gitlab::RouteMap::FormatError, /source key/)
end
end
context 'when an entry does not have a public key' do
it 'raises an error' do
- expect { described_class.new(YAML.dump([{ 'source' => '/index\.html/' }])) }.
- to raise_error(Gitlab::RouteMap::FormatError, /public key/)
+ expect { described_class.new(YAML.dump([{ 'source' => '/index\.html/' }])) }
+ .to raise_error(Gitlab::RouteMap::FormatError, /public key/)
end
end
context 'when an entry source is not a valid regex' do
it 'raises an error' do
- expect { described_class.new(YAML.dump([{ 'source' => '/[/', 'public' => 'index.html' }])) }.
- to raise_error(Gitlab::RouteMap::FormatError, /regular expression/)
+ expect { described_class.new(YAML.dump([{ 'source' => '/[/', 'public' => 'index.html' }])) }
+ .to raise_error(Gitlab::RouteMap::FormatError, /regular expression/)
end
end
diff --git a/spec/lib/gitlab/sherlock/file_sample_spec.rb b/spec/lib/gitlab/sherlock/file_sample_spec.rb
index cadf8bbce78..4989d14def3 100644
--- a/spec/lib/gitlab/sherlock/file_sample_spec.rb
+++ b/spec/lib/gitlab/sherlock/file_sample_spec.rb
@@ -35,8 +35,8 @@ describe Gitlab::Sherlock::FileSample, lib: true do
describe '#relative_path' do
it 'returns the relative path' do
- expect(sample.relative_path).
- to eq('spec/lib/gitlab/sherlock/file_sample_spec.rb')
+ expect(sample.relative_path)
+ .to eq('spec/lib/gitlab/sherlock/file_sample_spec.rb')
end
end
diff --git a/spec/lib/gitlab/sherlock/line_profiler_spec.rb b/spec/lib/gitlab/sherlock/line_profiler_spec.rb
index d57627bba2b..39c6b2a4844 100644
--- a/spec/lib/gitlab/sherlock/line_profiler_spec.rb
+++ b/spec/lib/gitlab/sherlock/line_profiler_spec.rb
@@ -20,9 +20,9 @@ describe Gitlab::Sherlock::LineProfiler, lib: true do
describe '#profile_mri' do
it 'returns an Array containing the return value and profiling samples' do
- allow(profiler).to receive(:lineprof).
- and_yield.
- and_return({ __FILE__ => [[0, 0, 0, 0]] })
+ allow(profiler).to receive(:lineprof)
+ .and_yield
+ .and_return({ __FILE__ => [[0, 0, 0, 0]] })
retval, samples = profiler.profile_mri { 42 }
diff --git a/spec/lib/gitlab/sherlock/middleware_spec.rb b/spec/lib/gitlab/sherlock/middleware_spec.rb
index 2bbeb25ce98..b98ab0b14a2 100644
--- a/spec/lib/gitlab/sherlock/middleware_spec.rb
+++ b/spec/lib/gitlab/sherlock/middleware_spec.rb
@@ -72,8 +72,8 @@ describe Gitlab::Sherlock::Middleware, lib: true do
'REQUEST_URI' => '/cats'
}
- expect(middleware.transaction_from_env(env)).
- to be_an_instance_of(Gitlab::Sherlock::Transaction)
+ expect(middleware.transaction_from_env(env))
+ .to be_an_instance_of(Gitlab::Sherlock::Transaction)
end
end
end
diff --git a/spec/lib/gitlab/sherlock/query_spec.rb b/spec/lib/gitlab/sherlock/query_spec.rb
index 0a620428138..d97b5eef573 100644
--- a/spec/lib/gitlab/sherlock/query_spec.rb
+++ b/spec/lib/gitlab/sherlock/query_spec.rb
@@ -13,8 +13,8 @@ describe Gitlab::Sherlock::Query, lib: true do
sql = 'SELECT COUNT(*) FROM users WHERE id = $1'
bindings = [[double(:column), 10]]
- query = described_class.
- new_with_bindings(sql, bindings, started_at, finished_at)
+ query = described_class
+ .new_with_bindings(sql, bindings, started_at, finished_at)
expect(query.query).to eq('SELECT COUNT(*) FROM users WHERE id = 10;')
end
diff --git a/spec/lib/gitlab/sherlock/transaction_spec.rb b/spec/lib/gitlab/sherlock/transaction_spec.rb
index 9fe18f253f0..6ae1aa20ea7 100644
--- a/spec/lib/gitlab/sherlock/transaction_spec.rb
+++ b/spec/lib/gitlab/sherlock/transaction_spec.rb
@@ -109,8 +109,8 @@ describe Gitlab::Sherlock::Transaction, lib: true do
query1 = Gitlab::Sherlock::Query.new('SELECT 1', start_time, start_time)
- query2 = Gitlab::Sherlock::Query.
- new('SELECT 2', start_time, start_time + 5)
+ query2 = Gitlab::Sherlock::Query
+ .new('SELECT 2', start_time, start_time + 5)
transaction.queries << query1
transaction.queries << query2
@@ -162,11 +162,11 @@ describe Gitlab::Sherlock::Transaction, lib: true do
describe '#profile_lines' do
describe 'when line profiling is enabled' do
it 'yields the block using the line profiler' do
- allow(Gitlab::Sherlock).to receive(:enable_line_profiler?).
- and_return(true)
+ allow(Gitlab::Sherlock).to receive(:enable_line_profiler?)
+ .and_return(true)
- allow_any_instance_of(Gitlab::Sherlock::LineProfiler).
- to receive(:profile).and_return('cats are amazing', [])
+ allow_any_instance_of(Gitlab::Sherlock::LineProfiler)
+ .to receive(:profile).and_return('cats are amazing', [])
retval = transaction.profile_lines { 'cats are amazing' }
@@ -176,8 +176,8 @@ describe Gitlab::Sherlock::Transaction, lib: true do
describe 'when line profiling is disabled' do
it 'yields the block' do
- allow(Gitlab::Sherlock).to receive(:enable_line_profiler?).
- and_return(false)
+ allow(Gitlab::Sherlock).to receive(:enable_line_profiler?)
+ .and_return(false)
retval = transaction.profile_lines { 'cats are amazing' }
@@ -196,8 +196,8 @@ describe Gitlab::Sherlock::Transaction, lib: true do
end
it 'tracks executed queries' do
- expect(transaction).to receive(:track_query).
- with('SELECT 1', [], time, time)
+ expect(transaction).to receive(:track_query)
+ .with('SELECT 1', [], time, time)
subscription.publish('test', time, time, nil, query_data)
end
@@ -205,8 +205,8 @@ describe Gitlab::Sherlock::Transaction, lib: true do
it 'only tracks queries triggered from the transaction thread' do
expect(transaction).not_to receive(:track_query)
- Thread.new { subscription.publish('test', time, time, nil, query_data) }.
- join
+ Thread.new { subscription.publish('test', time, time, nil, query_data) }
+ .join
end
end
@@ -228,8 +228,8 @@ describe Gitlab::Sherlock::Transaction, lib: true do
it 'only tracks views rendered from the transaction thread' do
expect(transaction).not_to receive(:track_view)
- Thread.new { subscription.publish('test', time, time, nil, view_data) }.
- join
+ Thread.new { subscription.publish('test', time, time, nil, view_data) }
+ .join
end
end
end
diff --git a/spec/lib/gitlab/sidekiq_status/client_middleware_spec.rb b/spec/lib/gitlab/sidekiq_status/client_middleware_spec.rb
index 6307f8c16a3..37d9e1d3e6b 100644
--- a/spec/lib/gitlab/sidekiq_status/client_middleware_spec.rb
+++ b/spec/lib/gitlab/sidekiq_status/client_middleware_spec.rb
@@ -5,8 +5,8 @@ describe Gitlab::SidekiqStatus::ClientMiddleware do
it 'tracks the job in Redis' do
expect(Gitlab::SidekiqStatus).to receive(:set).with('123', Gitlab::SidekiqStatus::DEFAULT_EXPIRATION)
- described_class.new.
- call('Foo', { 'jid' => '123' }, double(:queue), double(:pool)) { nil }
+ described_class.new
+ .call('Foo', { 'jid' => '123' }, double(:queue), double(:pool)) { nil }
end
end
end
diff --git a/spec/lib/gitlab/sidekiq_status/server_middleware_spec.rb b/spec/lib/gitlab/sidekiq_status/server_middleware_spec.rb
index 80728197b8c..04e09d3dec8 100644
--- a/spec/lib/gitlab/sidekiq_status/server_middleware_spec.rb
+++ b/spec/lib/gitlab/sidekiq_status/server_middleware_spec.rb
@@ -5,8 +5,8 @@ describe Gitlab::SidekiqStatus::ServerMiddleware do
it 'stops tracking of a job upon completion' do
expect(Gitlab::SidekiqStatus).to receive(:unset).with('123')
- ret = described_class.new.
- call(double(:worker), { 'jid' => '123' }, double(:queue)) { 10 }
+ ret = described_class.new
+ .call(double(:worker), { 'jid' => '123' }, double(:queue)) { 10 }
expect(ret).to eq(10)
end
diff --git a/spec/lib/gitlab/chat_commands/command_spec.rb b/spec/lib/gitlab/slash_commands/command_spec.rb
index 13e6953147b..28d7f9858c3 100644
--- a/spec/lib/gitlab/chat_commands/command_spec.rb
+++ b/spec/lib/gitlab/slash_commands/command_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe Gitlab::ChatCommands::Command, service: true do
+describe Gitlab::SlashCommands::Command, service: true do
let(:project) { create(:empty_project) }
let(:user) { create(:user) }
@@ -93,19 +93,19 @@ describe Gitlab::ChatCommands::Command, service: true do
context 'IssueShow is triggered' do
let(:params) { { text: 'issue show 123' } }
- it { is_expected.to eq(Gitlab::ChatCommands::IssueShow) }
+ it { is_expected.to eq(Gitlab::SlashCommands::IssueShow) }
end
context 'IssueCreate is triggered' do
let(:params) { { text: 'issue create my title' } }
- it { is_expected.to eq(Gitlab::ChatCommands::IssueNew) }
+ it { is_expected.to eq(Gitlab::SlashCommands::IssueNew) }
end
context 'IssueSearch is triggered' do
let(:params) { { text: 'issue search my query' } }
- it { is_expected.to eq(Gitlab::ChatCommands::IssueSearch) }
+ it { is_expected.to eq(Gitlab::SlashCommands::IssueSearch) }
end
end
end
diff --git a/spec/lib/gitlab/chat_commands/deploy_spec.rb b/spec/lib/gitlab/slash_commands/deploy_spec.rb
index 46dbdeae37c..d919f7260db 100644
--- a/spec/lib/gitlab/chat_commands/deploy_spec.rb
+++ b/spec/lib/gitlab/slash_commands/deploy_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe Gitlab::ChatCommands::Deploy, service: true do
+describe Gitlab::SlashCommands::Deploy, service: true do
describe '#execute' do
let(:project) { create(:empty_project) }
let(:user) { create(:user) }
diff --git a/spec/lib/gitlab/chat_commands/issue_new_spec.rb b/spec/lib/gitlab/slash_commands/issue_new_spec.rb
index 84c22328064..4de50d4a8bb 100644
--- a/spec/lib/gitlab/chat_commands/issue_new_spec.rb
+++ b/spec/lib/gitlab/slash_commands/issue_new_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe Gitlab::ChatCommands::IssueNew, service: true do
+describe Gitlab::SlashCommands::IssueNew, service: true do
describe '#execute' do
let(:project) { create(:empty_project) }
let(:user) { create(:user) }
diff --git a/spec/lib/gitlab/chat_commands/issue_search_spec.rb b/spec/lib/gitlab/slash_commands/issue_search_spec.rb
index 551ccb79a58..06fff0afc50 100644
--- a/spec/lib/gitlab/chat_commands/issue_search_spec.rb
+++ b/spec/lib/gitlab/slash_commands/issue_search_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe Gitlab::ChatCommands::IssueSearch, service: true do
+describe Gitlab::SlashCommands::IssueSearch, service: true do
describe '#execute' do
let!(:issue) { create(:issue, project: project, title: 'find me') }
let!(:confidential) { create(:issue, :confidential, project: project, title: 'mepmep find') }
diff --git a/spec/lib/gitlab/chat_commands/issue_show_spec.rb b/spec/lib/gitlab/slash_commands/issue_show_spec.rb
index 1f20d0a44ce..1899f664ccd 100644
--- a/spec/lib/gitlab/chat_commands/issue_show_spec.rb
+++ b/spec/lib/gitlab/slash_commands/issue_show_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe Gitlab::ChatCommands::IssueShow, service: true do
+describe Gitlab::SlashCommands::IssueShow, service: true do
describe '#execute' do
let(:issue) { create(:issue, project: project) }
let(:project) { create(:empty_project) }
diff --git a/spec/lib/gitlab/chat_commands/presenters/access_spec.rb b/spec/lib/gitlab/slash_commands/presenters/access_spec.rb
index ae41d75ab0c..ef3d217f7be 100644
--- a/spec/lib/gitlab/chat_commands/presenters/access_spec.rb
+++ b/spec/lib/gitlab/slash_commands/presenters/access_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe Gitlab::ChatCommands::Presenters::Access do
+describe Gitlab::SlashCommands::Presenters::Access do
describe '#access_denied' do
subject { described_class.new.access_denied }
diff --git a/spec/lib/gitlab/chat_commands/presenters/deploy_spec.rb b/spec/lib/gitlab/slash_commands/presenters/deploy_spec.rb
index dc2dd300072..dee3c77db27 100644
--- a/spec/lib/gitlab/chat_commands/presenters/deploy_spec.rb
+++ b/spec/lib/gitlab/slash_commands/presenters/deploy_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe Gitlab::ChatCommands::Presenters::Deploy do
+describe Gitlab::SlashCommands::Presenters::Deploy do
let(:build) { create(:ci_build) }
describe '#present' do
diff --git a/spec/lib/gitlab/chat_commands/presenters/issue_new_spec.rb b/spec/lib/gitlab/slash_commands/presenters/issue_new_spec.rb
index 17fcdbc2452..7f81ebb47db 100644
--- a/spec/lib/gitlab/chat_commands/presenters/issue_new_spec.rb
+++ b/spec/lib/gitlab/slash_commands/presenters/issue_new_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe Gitlab::ChatCommands::Presenters::IssueNew do
+describe Gitlab::SlashCommands::Presenters::IssueNew do
let(:project) { create(:empty_project) }
let(:issue) { create(:issue, project: project) }
let(:attachment) { subject[:attachments].first }
diff --git a/spec/lib/gitlab/chat_commands/presenters/issue_search_spec.rb b/spec/lib/gitlab/slash_commands/presenters/issue_search_spec.rb
index 3799a324db4..7e57a0addcb 100644
--- a/spec/lib/gitlab/chat_commands/presenters/issue_search_spec.rb
+++ b/spec/lib/gitlab/slash_commands/presenters/issue_search_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe Gitlab::ChatCommands::Presenters::IssueSearch do
+describe Gitlab::SlashCommands::Presenters::IssueSearch do
let(:project) { create(:empty_project) }
let(:message) { subject[:text] }
diff --git a/spec/lib/gitlab/chat_commands/presenters/issue_show_spec.rb b/spec/lib/gitlab/slash_commands/presenters/issue_show_spec.rb
index 3916fc704a4..2a6ed860737 100644
--- a/spec/lib/gitlab/chat_commands/presenters/issue_show_spec.rb
+++ b/spec/lib/gitlab/slash_commands/presenters/issue_show_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe Gitlab::ChatCommands::Presenters::IssueShow do
+describe Gitlab::SlashCommands::Presenters::IssueShow do
let(:project) { create(:empty_project) }
let(:issue) { create(:issue, project: project) }
let(:attachment) { subject[:attachments].first }
diff --git a/spec/lib/gitlab/url_builder_spec.rb b/spec/lib/gitlab/url_builder_spec.rb
index e8a37e8d77b..e9a6e273516 100644
--- a/spec/lib/gitlab/url_builder_spec.rb
+++ b/spec/lib/gitlab/url_builder_spec.rb
@@ -112,8 +112,8 @@ describe Gitlab::UrlBuilder, lib: true do
it 'returns a proper URL' do
project = build_stubbed(:empty_project)
- expect { described_class.build(project) }.
- to raise_error(NotImplementedError, 'No URL builder defined for Project')
+ expect { described_class.build(project) }
+ .to raise_error(NotImplementedError, 'No URL builder defined for Project')
end
end
end
diff --git a/spec/lib/gitlab/view/presenter/delegated_spec.rb b/spec/lib/gitlab/view/presenter/delegated_spec.rb
index e9d4af54389..940a2ce6ebd 100644
--- a/spec/lib/gitlab/view/presenter/delegated_spec.rb
+++ b/spec/lib/gitlab/view/presenter/delegated_spec.rb
@@ -18,8 +18,8 @@ describe Gitlab::View::Presenter::Delegated do
end
it 'raise an error if the presentee already respond to method' do
- expect { presenter_class.new(project, user: 'Jane Doe') }.
- to raise_error Gitlab::View::Presenter::CannotOverrideMethodError
+ expect { presenter_class.new(project, user: 'Jane Doe') }
+ .to raise_error Gitlab::View::Presenter::CannotOverrideMethodError
end
end
diff --git a/spec/lib/gitlab/visibility_level_spec.rb b/spec/lib/gitlab/visibility_level_spec.rb
index 3255c6f1ef7..84d2484cc8a 100644
--- a/spec/lib/gitlab/visibility_level_spec.rb
+++ b/spec/lib/gitlab/visibility_level_spec.rb
@@ -18,4 +18,35 @@ describe Gitlab::VisibilityLevel, lib: true do
expect(described_class.level_value(100)).to eq(Gitlab::VisibilityLevel::PRIVATE)
end
end
+
+ describe '.levels_for_user' do
+ it 'returns all levels for an admin' do
+ user = double(:user, admin?: true)
+
+ expect(described_class.levels_for_user(user))
+ .to eq([Gitlab::VisibilityLevel::PRIVATE,
+ Gitlab::VisibilityLevel::INTERNAL,
+ Gitlab::VisibilityLevel::PUBLIC])
+ end
+
+ it 'returns INTERNAL and PUBLIC for internal users' do
+ user = double(:user, admin?: false, external?: false)
+
+ expect(described_class.levels_for_user(user))
+ .to eq([Gitlab::VisibilityLevel::INTERNAL,
+ Gitlab::VisibilityLevel::PUBLIC])
+ end
+
+ it 'returns PUBLIC for external users' do
+ user = double(:user, admin?: false, external?: true)
+
+ expect(described_class.levels_for_user(user))
+ .to eq([Gitlab::VisibilityLevel::PUBLIC])
+ end
+
+ it 'returns PUBLIC when no user is given' do
+ expect(described_class.levels_for_user)
+ .to eq([Gitlab::VisibilityLevel::PUBLIC])
+ end
+ end
end
diff --git a/spec/lib/gitlab/workhorse_spec.rb b/spec/lib/gitlab/workhorse_spec.rb
index ad19998dff4..493ff3bb5fb 100644
--- a/spec/lib/gitlab/workhorse_spec.rb
+++ b/spec/lib/gitlab/workhorse_spec.rb
@@ -202,7 +202,11 @@ describe Gitlab::Workhorse, lib: true do
context 'when Gitaly is enabled' do
let(:gitaly_params) do
{
- GitalyAddress: Gitlab::GitalyClient.address('default')
+ GitalyAddress: Gitlab::GitalyClient.address('default'),
+ GitalyServer: {
+ address: Gitlab::GitalyClient.address('default'),
+ token: Gitlab::GitalyClient.token('default')
+ }
}
end
@@ -212,7 +216,6 @@ describe Gitlab::Workhorse, lib: true do
it 'includes a Repository param' do
repo_param = { Repository: {
- path: '', # deprecated field; grpc automatically creates it anyway
storage_name: 'default',
relative_path: project.full_path + '.git'
} }
diff --git a/spec/lib/mattermost/command_spec.rb b/spec/lib/mattermost/command_spec.rb
index 4b5938edeb9..369e7b181b9 100644
--- a/spec/lib/mattermost/command_spec.rb
+++ b/spec/lib/mattermost/command_spec.rb
@@ -6,8 +6,8 @@ describe Mattermost::Command do
before do
Mattermost::Session.base_uri('http://mattermost.example.com')
- allow_any_instance_of(Mattermost::Client).to receive(:with_session).
- and_yield(Mattermost::Session.new(nil))
+ allow_any_instance_of(Mattermost::Client).to receive(:with_session)
+ .and_yield(Mattermost::Session.new(nil))
end
describe '#create' do
@@ -20,12 +20,12 @@ describe Mattermost::Command do
context 'for valid trigger word' do
before do
- stub_request(:post, 'http://mattermost.example.com/api/v3/teams/abc/commands/create').
- with(body: {
+ stub_request(:post, 'http://mattermost.example.com/api/v3/teams/abc/commands/create')
+ .with(body: {
team_id: 'abc',
trigger: 'gitlab'
- }.to_json).
- to_return(
+ }.to_json)
+ .to_return(
status: 200,
headers: { 'Content-Type' => 'application/json' },
body: { token: 'token' }.to_json
@@ -39,8 +39,8 @@ describe Mattermost::Command do
context 'for error message' do
before do
- stub_request(:post, 'http://mattermost.example.com/api/v3/teams/abc/commands/create').
- to_return(
+ stub_request(:post, 'http://mattermost.example.com/api/v3/teams/abc/commands/create')
+ .to_return(
status: 500,
headers: { 'Content-Type' => 'application/json' },
body: {
diff --git a/spec/lib/mattermost/session_spec.rb b/spec/lib/mattermost/session_spec.rb
index 74d12e37181..be3908e8f6a 100644
--- a/spec/lib/mattermost/session_spec.rb
+++ b/spec/lib/mattermost/session_spec.rb
@@ -21,8 +21,8 @@ describe Mattermost::Session, type: :request do
describe '#with session' do
let(:location) { 'http://location.tld' }
let!(:stub) do
- WebMock.stub_request(:get, "#{mattermost_url}/api/v3/oauth/gitlab/login").
- to_return(headers: { 'location' => location }, status: 307)
+ WebMock.stub_request(:get, "#{mattermost_url}/api/v3/oauth/gitlab/login")
+ .to_return(headers: { 'location' => location }, status: 307)
end
context 'without oauth uri' do
@@ -60,9 +60,9 @@ describe Mattermost::Session, type: :request do
end
before do
- WebMock.stub_request(:get, "#{mattermost_url}/signup/gitlab/complete").
- with(query: hash_including({ 'state' => state })).
- to_return do |request|
+ WebMock.stub_request(:get, "#{mattermost_url}/signup/gitlab/complete")
+ .with(query: hash_including({ 'state' => state }))
+ .to_return do |request|
post "/oauth/token",
client_id: doorkeeper.uid,
client_secret: doorkeeper.secret,
@@ -75,8 +75,8 @@ describe Mattermost::Session, type: :request do
end
end
- WebMock.stub_request(:post, "#{mattermost_url}/api/v3/users/logout").
- to_return(headers: { Authorization: 'token thisworksnow' }, status: 200)
+ WebMock.stub_request(:post, "#{mattermost_url}/api/v3/users/logout")
+ .to_return(headers: { Authorization: 'token thisworksnow' }, status: 200)
end
it 'can setup a session' do
diff --git a/spec/lib/mattermost/team_spec.rb b/spec/lib/mattermost/team_spec.rb
index ac493fdb20f..e638ad7a2c9 100644
--- a/spec/lib/mattermost/team_spec.rb
+++ b/spec/lib/mattermost/team_spec.rb
@@ -4,8 +4,8 @@ describe Mattermost::Team do
before do
Mattermost::Session.base_uri('http://mattermost.example.com')
- allow_any_instance_of(Mattermost::Client).to receive(:with_session).
- and_yield(Mattermost::Session.new(nil))
+ allow_any_instance_of(Mattermost::Client).to receive(:with_session)
+ .and_yield(Mattermost::Session.new(nil))
end
describe '#all' do
@@ -30,8 +30,8 @@ describe Mattermost::Team do
end
before do
- stub_request(:get, 'http://mattermost.example.com/api/v3/teams/all').
- to_return(
+ stub_request(:get, 'http://mattermost.example.com/api/v3/teams/all')
+ .to_return(
status: 200,
headers: { 'Content-Type' => 'application/json' },
body: response.to_json
@@ -45,8 +45,8 @@ describe Mattermost::Team do
context 'for error message' do
before do
- stub_request(:get, 'http://mattermost.example.com/api/v3/teams/all').
- to_return(
+ stub_request(:get, 'http://mattermost.example.com/api/v3/teams/all')
+ .to_return(
status: 500,
headers: { 'Content-Type' => 'application/json' },
body: {
diff --git a/spec/mailers/abuse_report_mailer_spec.rb b/spec/mailers/abuse_report_mailer_spec.rb
index eb433c38873..bda892083b3 100644
--- a/spec/mailers/abuse_report_mailer_spec.rb
+++ b/spec/mailers/abuse_report_mailer_spec.rb
@@ -30,8 +30,8 @@ describe AbuseReportMailer do
it 'returns early' do
stub_application_setting(admin_notification_email: nil)
- expect { described_class.notify(spy).deliver_now }.
- not_to change { ActionMailer::Base.deliveries.count }
+ expect { described_class.notify(spy).deliver_now }
+ .not_to change { ActionMailer::Base.deliveries.count }
end
end
end
diff --git a/spec/migrations/migrate_build_stage_reference_spec.rb b/spec/migrations/migrate_build_stage_reference_again_spec.rb
index 80b321860c2..6be480ce58e 100644
--- a/spec/migrations/migrate_build_stage_reference_spec.rb
+++ b/spec/migrations/migrate_build_stage_reference_again_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
-require Rails.root.join('db', 'post_migrate', '20170526185921_migrate_build_stage_reference.rb')
+require Rails.root.join('db', 'post_migrate', '20170526190000_migrate_build_stage_reference_again.rb')
-describe MigrateBuildStageReference, :migration do
+describe MigrateBuildStageReferenceAgain, :migration do
##
# Create test data - pipeline and CI/CD jobs.
#
diff --git a/spec/migrations/migrate_process_commit_worker_jobs_spec.rb b/spec/migrations/migrate_process_commit_worker_jobs_spec.rb
index 3db57595fa6..4223d2337a8 100644
--- a/spec/migrations/migrate_process_commit_worker_jobs_spec.rb
+++ b/spec/migrations/migrate_process_commit_worker_jobs_spec.rb
@@ -11,33 +11,33 @@ describe MigrateProcessCommitWorkerJobs do
describe 'Project' do
describe 'find_including_path' do
it 'returns Project instances' do
- expect(described_class::Project.find_including_path(project.id)).
- to be_an_instance_of(described_class::Project)
+ expect(described_class::Project.find_including_path(project.id))
+ .to be_an_instance_of(described_class::Project)
end
it 'selects the full path for every Project' do
- migration_project = described_class::Project.
- find_including_path(project.id)
+ migration_project = described_class::Project
+ .find_including_path(project.id)
- expect(migration_project[:path_with_namespace]).
- to eq(project.path_with_namespace)
+ expect(migration_project[:path_with_namespace])
+ .to eq(project.path_with_namespace)
end
end
describe '#repository_storage_path' do
it 'returns the storage path for the repository' do
- migration_project = described_class::Project.
- find_including_path(project.id)
+ migration_project = described_class::Project
+ .find_including_path(project.id)
- expect(File.directory?(migration_project.repository_storage_path)).
- to eq(true)
+ expect(File.directory?(migration_project.repository_storage_path))
+ .to eq(true)
end
end
describe '#repository_path' do
it 'returns the path to the repository' do
- migration_project = described_class::Project.
- find_including_path(project.id)
+ migration_project = described_class::Project
+ .find_including_path(project.id)
expect(File.directory?(migration_project.repository_path)).to eq(true)
end
@@ -45,11 +45,11 @@ describe MigrateProcessCommitWorkerJobs do
describe '#repository' do
it 'returns a Rugged::Repository' do
- migration_project = described_class::Project.
- find_including_path(project.id)
+ migration_project = described_class::Project
+ .find_including_path(project.id)
- expect(migration_project.repository).
- to be_an_instance_of(Rugged::Repository)
+ expect(migration_project.repository)
+ .to be_an_instance_of(Rugged::Repository)
end
end
end
@@ -73,9 +73,9 @@ describe MigrateProcessCommitWorkerJobs do
end
it 'skips jobs using a project that no longer exists' do
- allow(described_class::Project).to receive(:find_including_path).
- with(project.id).
- and_return(nil)
+ allow(described_class::Project).to receive(:find_including_path)
+ .with(project.id)
+ .and_return(nil)
migration.up
@@ -83,9 +83,9 @@ describe MigrateProcessCommitWorkerJobs do
end
it 'skips jobs using commits that no longer exist' do
- allow_any_instance_of(Rugged::Repository).to receive(:lookup).
- with(commit.oid).
- and_raise(Rugged::OdbError)
+ allow_any_instance_of(Rugged::Repository).to receive(:lookup)
+ .with(commit.oid)
+ .and_raise(Rugged::OdbError)
migration.up
@@ -99,12 +99,12 @@ describe MigrateProcessCommitWorkerJobs do
end
it 'encodes data to UTF-8' do
- allow_any_instance_of(Rugged::Repository).to receive(:lookup).
- with(commit.oid).
- and_return(commit)
+ allow_any_instance_of(Rugged::Repository).to receive(:lookup)
+ .with(commit.oid)
+ .and_return(commit)
- allow(commit).to receive(:message).
- and_return('김치'.force_encoding('BINARY'))
+ allow(commit).to receive(:message)
+ .and_return('김치'.force_encoding('BINARY'))
migration.up
diff --git a/spec/migrations/turn_nested_groups_into_regular_groups_for_mysql_spec.rb b/spec/migrations/turn_nested_groups_into_regular_groups_for_mysql_spec.rb
index 175bf1876b2..42109fd0743 100644
--- a/spec/migrations/turn_nested_groups_into_regular_groups_for_mysql_spec.rb
+++ b/spec/migrations/turn_nested_groups_into_regular_groups_for_mysql_spec.rb
@@ -31,8 +31,8 @@ describe TurnNestedGroupsIntoRegularGroupsForMysql do
end
it 'adds members of parent groups as members to the migrated group' do
- is_member = child_group.members.
- where(user_id: member, access_level: Gitlab::Access::DEVELOPER).any?
+ is_member = child_group.members
+ .where(user_id: member, access_level: Gitlab::Access::DEVELOPER).any?
expect(is_member).to eq(true)
end
@@ -44,21 +44,21 @@ describe TurnNestedGroupsIntoRegularGroupsForMysql do
end
it 'renames projects of the nested group' do
- expect(updated_project.path_with_namespace).
- to eq("#{parent_group.name}-#{child_group.name}/#{updated_project.path}")
+ expect(updated_project.path_with_namespace)
+ .to eq("#{parent_group.name}-#{child_group.name}/#{updated_project.path}")
end
it 'renames the repository of any projects' do
- expect(updated_project.repository.path).
- to end_with("#{parent_group.name}-#{child_group.name}/#{updated_project.path}.git")
+ expect(updated_project.repository.path)
+ .to end_with("#{parent_group.name}-#{child_group.name}/#{updated_project.path}.git")
expect(File.directory?(updated_project.repository.path)).to eq(true)
end
it 'creates a redirect route for renamed projects' do
- exists = RedirectRoute.
- where(source_type: 'Project', source_id: project.id).
- any?
+ exists = RedirectRoute
+ .where(source_type: 'Project', source_id: project.id)
+ .any?
expect(exists).to eq(true)
end
diff --git a/spec/models/ability_spec.rb b/spec/models/ability_spec.rb
index 92d70cfc64c..090f9e70c50 100644
--- a/spec/models/ability_spec.rb
+++ b/spec/models/ability_spec.rb
@@ -69,8 +69,8 @@ describe Ability, lib: true do
project = create(:empty_project, :public)
user = build(:user)
- expect(described_class.users_that_can_read_project([user], project)).
- to eq([user])
+ expect(described_class.users_that_can_read_project([user], project))
+ .to eq([user])
end
end
@@ -80,8 +80,8 @@ describe Ability, lib: true do
it 'returns users that are administrators' do
user = build(:user, admin: true)
- expect(described_class.users_that_can_read_project([user], project)).
- to eq([user])
+ expect(described_class.users_that_can_read_project([user], project))
+ .to eq([user])
end
it 'returns internal users while skipping external users' do
@@ -89,8 +89,8 @@ describe Ability, lib: true do
user2 = build(:user, external: true)
users = [user1, user2]
- expect(described_class.users_that_can_read_project(users, project)).
- to eq([user1])
+ expect(described_class.users_that_can_read_project(users, project))
+ .to eq([user1])
end
it 'returns external users if they are the project owner' do
@@ -100,8 +100,8 @@ describe Ability, lib: true do
expect(project).to receive(:owner).twice.and_return(user1)
- expect(described_class.users_that_can_read_project(users, project)).
- to eq([user1])
+ expect(described_class.users_that_can_read_project(users, project))
+ .to eq([user1])
end
it 'returns external users if they are project members' do
@@ -111,8 +111,8 @@ describe Ability, lib: true do
expect(project.team).to receive(:members).twice.and_return([user1])
- expect(described_class.users_that_can_read_project(users, project)).
- to eq([user1])
+ expect(described_class.users_that_can_read_project(users, project))
+ .to eq([user1])
end
it 'returns an empty Array if all users are external users without access' do
@@ -120,8 +120,8 @@ describe Ability, lib: true do
user2 = build(:user, external: true)
users = [user1, user2]
- expect(described_class.users_that_can_read_project(users, project)).
- to eq([])
+ expect(described_class.users_that_can_read_project(users, project))
+ .to eq([])
end
end
@@ -131,8 +131,8 @@ describe Ability, lib: true do
it 'returns users that are administrators' do
user = build(:user, admin: true)
- expect(described_class.users_that_can_read_project([user], project)).
- to eq([user])
+ expect(described_class.users_that_can_read_project([user], project))
+ .to eq([user])
end
it 'returns external users if they are the project owner' do
@@ -142,8 +142,8 @@ describe Ability, lib: true do
expect(project).to receive(:owner).twice.and_return(user1)
- expect(described_class.users_that_can_read_project(users, project)).
- to eq([user1])
+ expect(described_class.users_that_can_read_project(users, project))
+ .to eq([user1])
end
it 'returns external users if they are project members' do
@@ -153,8 +153,8 @@ describe Ability, lib: true do
expect(project.team).to receive(:members).twice.and_return([user1])
- expect(described_class.users_that_can_read_project(users, project)).
- to eq([user1])
+ expect(described_class.users_that_can_read_project(users, project))
+ .to eq([user1])
end
it 'returns an empty Array if all users are internal users without access' do
@@ -162,8 +162,8 @@ describe Ability, lib: true do
user2 = build(:user)
users = [user1, user2]
- expect(described_class.users_that_can_read_project(users, project)).
- to eq([])
+ expect(described_class.users_that_can_read_project(users, project))
+ .to eq([])
end
it 'returns an empty Array if all users are external users without access' do
@@ -171,8 +171,8 @@ describe Ability, lib: true do
user2 = build(:user, external: true)
users = [user1, user2]
- expect(described_class.users_that_can_read_project(users, project)).
- to eq([])
+ expect(described_class.users_that_can_read_project(users, project))
+ .to eq([])
end
end
end
@@ -210,8 +210,8 @@ describe Ability, lib: true do
user = build(:user, admin: true)
issue = build(:issue)
- expect(described_class.issues_readable_by_user([issue], user)).
- to eq([issue])
+ expect(described_class.issues_readable_by_user([issue], user))
+ .to eq([issue])
end
end
@@ -222,8 +222,8 @@ describe Ability, lib: true do
expect(issue).to receive(:readable_by?).with(user).and_return(true)
- expect(described_class.issues_readable_by_user([issue], user)).
- to eq([issue])
+ expect(described_class.issues_readable_by_user([issue], user))
+ .to eq([issue])
end
it 'returns an empty Array when no issues are readable' do
@@ -244,8 +244,8 @@ describe Ability, lib: true do
expect(hidden_issue).to receive(:publicly_visible?).and_return(false)
expect(visible_issue).to receive(:publicly_visible?).and_return(true)
- issues = described_class.
- issues_readable_by_user([hidden_issue, visible_issue])
+ issues = described_class
+ .issues_readable_by_user([hidden_issue, visible_issue])
expect(issues).to eq([visible_issue])
end
diff --git a/spec/models/abuse_report_spec.rb b/spec/models/abuse_report_spec.rb
index 90aec2b45e6..c1bf5551fe0 100644
--- a/spec/models/abuse_report_spec.rb
+++ b/spec/models/abuse_report_spec.rb
@@ -36,8 +36,8 @@ RSpec.describe AbuseReport, type: :model do
describe '#notify' do
it 'delivers' do
- expect(AbuseReportMailer).to receive(:notify).with(subject.id).
- and_return(spy)
+ expect(AbuseReportMailer).to receive(:notify).with(subject.id)
+ .and_return(spy)
subject.notify
end
diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb
index 3816422fec6..488697f74eb 100644
--- a/spec/models/ci/build_spec.rb
+++ b/spec/models/ci/build_spec.rb
@@ -451,42 +451,6 @@ describe Ci::Build, :models do
end
end
- describe '#environment_url' do
- subject { job.environment_url }
-
- context 'when yaml environment uses $CI_COMMIT_REF_NAME' do
- let(:job) do
- create(:ci_build,
- ref: 'master',
- options: { environment: { url: 'http://review/$CI_COMMIT_REF_NAME' } })
- end
-
- it { is_expected.to eq('http://review/master') }
- end
-
- context 'when yaml environment uses yaml_variables containing symbol keys' do
- let(:job) do
- create(:ci_build,
- yaml_variables: [{ key: :APP_HOST, value: 'host' }],
- options: { environment: { url: 'http://review/$APP_HOST' } })
- end
-
- it { is_expected.to eq('http://review/host') }
- end
-
- context 'when yaml environment does not have url' do
- let(:job) { create(:ci_build, environment: 'staging') }
-
- let!(:environment) do
- create(:environment, project: job.project, name: job.environment)
- end
-
- it 'returns the external_url from persisted environment' do
- is_expected.to eq(environment.external_url)
- end
- end
- end
-
describe '#starts_environment?' do
subject { build.starts_environment? }
@@ -899,8 +863,8 @@ describe Ci::Build, :models do
pipeline2 = create(:ci_pipeline, project: project)
@build2 = create(:ci_build, pipeline: pipeline2)
- allow(@merge_request).to receive(:commits_sha).
- and_return([pipeline.sha, pipeline2.sha])
+ allow(@merge_request).to receive(:commits_sha)
+ .and_return([pipeline.sha, pipeline2.sha])
allow(MergeRequest).to receive_message_chain(:includes, :where, :reorder).and_return([@merge_request])
end
@@ -1292,10 +1256,20 @@ describe Ci::Build, :models do
context 'when the URL was set from the job' do
before do
- build.update(options: { environment: { url: 'http://host/$CI_JOB_NAME' } })
+ build.update(options: { environment: { url: url } })
end
it_behaves_like 'containing environment variables'
+
+ context 'when variables are used in the URL, it does not expand' do
+ let(:url) { 'http://$CI_PROJECT_NAME-$CI_ENVIRONMENT_SLUG' }
+
+ it_behaves_like 'containing environment variables'
+
+ it 'puts $CI_ENVIRONMENT_URL in the last so all other variables are available to be used when runners are trying to expand it' do
+ expect(subject.last).to eq(environment_variables.last)
+ end
+ end
end
context 'when the URL was not set from the job, but environment' do
diff --git a/spec/models/ci/pipeline_schedule_spec.rb b/spec/models/ci/pipeline_schedule_spec.rb
index b00e7a73571..56817baf79d 100644
--- a/spec/models/ci/pipeline_schedule_spec.rb
+++ b/spec/models/ci/pipeline_schedule_spec.rb
@@ -40,8 +40,8 @@ describe Ci::PipelineSchedule, models: true do
context 'when creates new pipeline schedule' do
let(:expected_next_run_at) do
- Gitlab::Ci::CronParser.new(pipeline_schedule.cron, pipeline_schedule.cron_timezone).
- next_time_from(Time.now)
+ Gitlab::Ci::CronParser.new(pipeline_schedule.cron, pipeline_schedule.cron_timezone)
+ .next_time_from(Time.now)
end
it 'updates next_run_at automatically' do
@@ -53,8 +53,8 @@ describe Ci::PipelineSchedule, models: true do
let(:new_cron) { '0 0 1 1 *' }
let(:expected_next_run_at) do
- Gitlab::Ci::CronParser.new(new_cron, pipeline_schedule.cron_timezone).
- next_time_from(Time.now)
+ Gitlab::Ci::CronParser.new(new_cron, pipeline_schedule.cron_timezone)
+ .next_time_from(Time.now)
end
it 'updates next_run_at automatically' do
@@ -72,8 +72,8 @@ describe Ci::PipelineSchedule, models: true do
let(:future_time) { 10.days.from_now }
let(:expected_next_run_at) do
- Gitlab::Ci::CronParser.new(pipeline_schedule.cron, pipeline_schedule.cron_timezone).
- next_time_from(future_time)
+ Gitlab::Ci::CronParser.new(pipeline_schedule.cron, pipeline_schedule.cron_timezone)
+ .next_time_from(future_time)
end
it 'points to proper next_run_at' do
diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb
index e86cbe8498a..dab8e8ca432 100644
--- a/spec/models/ci/pipeline_spec.rb
+++ b/spec/models/ci/pipeline_spec.rb
@@ -608,8 +608,8 @@ describe Ci::Pipeline, models: true do
it 'returns the latest pipeline for the same ref and different sha' do
expect(pipelines.map(&:sha)).to contain_exactly('A', 'B', 'C')
- expect(pipelines.map(&:status)).
- to contain_exactly('success', 'failed', 'skipped')
+ expect(pipelines.map(&:status))
+ .to contain_exactly('success', 'failed', 'skipped')
end
end
@@ -618,8 +618,8 @@ describe Ci::Pipeline, models: true do
it 'returns the latest pipeline for ref and different sha' do
expect(pipelines.map(&:sha)).to contain_exactly('A', 'B')
- expect(pipelines.map(&:status)).
- to contain_exactly('success', 'failed')
+ expect(pipelines.map(&:status))
+ .to contain_exactly('success', 'failed')
end
end
end
@@ -654,8 +654,8 @@ describe Ci::Pipeline, models: true do
end
it 'returns the latest successful pipeline' do
- expect(described_class.latest_successful_for('ref')).
- to eq(latest_successful_pipeline)
+ expect(described_class.latest_successful_for('ref'))
+ .to eq(latest_successful_pipeline)
end
end
@@ -1201,8 +1201,8 @@ describe Ci::Pipeline, models: true do
before do
project.team << [pipeline.user, Gitlab::Access::DEVELOPER]
- pipeline.user.global_notification_setting.
- update(level: 'custom', failed_pipeline: true, success_pipeline: true)
+ pipeline.user.global_notification_setting
+ .update(level: 'custom', failed_pipeline: true, success_pipeline: true)
reset_delivered_emails!
diff --git a/spec/models/ci/variable_spec.rb b/spec/models/ci/variable_spec.rb
index 077b10227d7..83494af24ba 100644
--- a/spec/models/ci/variable_spec.rb
+++ b/spec/models/ci/variable_spec.rb
@@ -54,8 +54,8 @@ describe Ci::Variable, models: true do
it 'fails to decrypt if iv is incorrect' do
subject.encrypted_value_iv = SecureRandom.hex
subject.instance_variable_set(:@value, nil)
- expect { subject.value }.
- to raise_error(OpenSSL::Cipher::CipherError, 'bad decrypt')
+ expect { subject.value }
+ .to raise_error(OpenSSL::Cipher::CipherError, 'bad decrypt')
end
end
diff --git a/spec/models/commit_range_spec.rb b/spec/models/commit_range_spec.rb
index e4bddf67096..ba9c3f66d21 100644
--- a/spec/models/commit_range_spec.rb
+++ b/spec/models/commit_range_spec.rb
@@ -147,9 +147,9 @@ describe CommitRange, models: true do
note: commit1.revert_description(user),
project: issue.project)
- expect_any_instance_of(Commit).to receive(:reverts_commit?).
- with(commit1, user).
- and_return(true)
+ expect_any_instance_of(Commit).to receive(:reverts_commit?)
+ .with(commit1, user)
+ .and_return(true)
expect(commit1.has_been_reverted?(user, issue)).to eq(true)
end
diff --git a/spec/models/concerns/case_sensitivity_spec.rb b/spec/models/concerns/case_sensitivity_spec.rb
index 92fdc5cd65d..a6fccb668e3 100644
--- a/spec/models/concerns/case_sensitivity_spec.rb
+++ b/spec/models/concerns/case_sensitivity_spec.rb
@@ -15,13 +15,13 @@ describe CaseSensitivity, models: true do
it 'returns the criteria for a column and a value' do
criteria = double(:criteria)
- expect(connection).to receive(:quote_table_name).
- with(:foo).
- and_return('"foo"')
+ expect(connection).to receive(:quote_table_name)
+ .with(:foo)
+ .and_return('"foo"')
- expect(model).to receive(:where).
- with(%q{LOWER("foo") = LOWER(:value)}, value: 'bar').
- and_return(criteria)
+ expect(model).to receive(:where)
+ .with(%q{LOWER("foo") = LOWER(:value)}, value: 'bar')
+ .and_return(criteria)
expect(model.iwhere(foo: 'bar')).to eq(criteria)
end
@@ -29,13 +29,13 @@ describe CaseSensitivity, models: true do
it 'returns the criteria for a column with a table, and a value' do
criteria = double(:criteria)
- expect(connection).to receive(:quote_table_name).
- with(:'foo.bar').
- and_return('"foo"."bar"')
+ expect(connection).to receive(:quote_table_name)
+ .with(:'foo.bar')
+ .and_return('"foo"."bar"')
- expect(model).to receive(:where).
- with(%q{LOWER("foo"."bar") = LOWER(:value)}, value: 'bar').
- and_return(criteria)
+ expect(model).to receive(:where)
+ .with(%q{LOWER("foo"."bar") = LOWER(:value)}, value: 'bar')
+ .and_return(criteria)
expect(model.iwhere('foo.bar'.to_sym => 'bar')).to eq(criteria)
end
@@ -46,21 +46,21 @@ describe CaseSensitivity, models: true do
initial = double(:criteria)
final = double(:criteria)
- expect(connection).to receive(:quote_table_name).
- with(:foo).
- and_return('"foo"')
+ expect(connection).to receive(:quote_table_name)
+ .with(:foo)
+ .and_return('"foo"')
- expect(connection).to receive(:quote_table_name).
- with(:bar).
- and_return('"bar"')
+ expect(connection).to receive(:quote_table_name)
+ .with(:bar)
+ .and_return('"bar"')
- expect(model).to receive(:where).
- with(%q{LOWER("foo") = LOWER(:value)}, value: 'bar').
- and_return(initial)
+ expect(model).to receive(:where)
+ .with(%q{LOWER("foo") = LOWER(:value)}, value: 'bar')
+ .and_return(initial)
- expect(initial).to receive(:where).
- with(%q{LOWER("bar") = LOWER(:value)}, value: 'baz').
- and_return(final)
+ expect(initial).to receive(:where)
+ .with(%q{LOWER("bar") = LOWER(:value)}, value: 'baz')
+ .and_return(final)
got = model.iwhere(foo: 'bar', bar: 'baz')
@@ -71,21 +71,21 @@ describe CaseSensitivity, models: true do
initial = double(:criteria)
final = double(:criteria)
- expect(connection).to receive(:quote_table_name).
- with(:'foo.bar').
- and_return('"foo"."bar"')
+ expect(connection).to receive(:quote_table_name)
+ .with(:'foo.bar')
+ .and_return('"foo"."bar"')
- expect(connection).to receive(:quote_table_name).
- with(:'foo.baz').
- and_return('"foo"."baz"')
+ expect(connection).to receive(:quote_table_name)
+ .with(:'foo.baz')
+ .and_return('"foo"."baz"')
- expect(model).to receive(:where).
- with(%q{LOWER("foo"."bar") = LOWER(:value)}, value: 'bar').
- and_return(initial)
+ expect(model).to receive(:where)
+ .with(%q{LOWER("foo"."bar") = LOWER(:value)}, value: 'bar')
+ .and_return(initial)
- expect(initial).to receive(:where).
- with(%q{LOWER("foo"."baz") = LOWER(:value)}, value: 'baz').
- and_return(final)
+ expect(initial).to receive(:where)
+ .with(%q{LOWER("foo"."baz") = LOWER(:value)}, value: 'baz')
+ .and_return(final)
got = model.iwhere('foo.bar'.to_sym => 'bar',
'foo.baz'.to_sym => 'baz')
@@ -105,13 +105,13 @@ describe CaseSensitivity, models: true do
it 'returns the criteria for a column and a value' do
criteria = double(:criteria)
- expect(connection).to receive(:quote_table_name).
- with(:foo).
- and_return('`foo`')
+ expect(connection).to receive(:quote_table_name)
+ .with(:foo)
+ .and_return('`foo`')
- expect(model).to receive(:where).
- with(%q{`foo` = :value}, value: 'bar').
- and_return(criteria)
+ expect(model).to receive(:where)
+ .with(%q{`foo` = :value}, value: 'bar')
+ .and_return(criteria)
expect(model.iwhere(foo: 'bar')).to eq(criteria)
end
@@ -119,16 +119,16 @@ describe CaseSensitivity, models: true do
it 'returns the criteria for a column with a table, and a value' do
criteria = double(:criteria)
- expect(connection).to receive(:quote_table_name).
- with(:'foo.bar').
- and_return('`foo`.`bar`')
+ expect(connection).to receive(:quote_table_name)
+ .with(:'foo.bar')
+ .and_return('`foo`.`bar`')
- expect(model).to receive(:where).
- with(%q{`foo`.`bar` = :value}, value: 'bar').
- and_return(criteria)
+ expect(model).to receive(:where)
+ .with(%q{`foo`.`bar` = :value}, value: 'bar')
+ .and_return(criteria)
- expect(model.iwhere('foo.bar'.to_sym => 'bar')).
- to eq(criteria)
+ expect(model.iwhere('foo.bar'.to_sym => 'bar'))
+ .to eq(criteria)
end
end
@@ -137,21 +137,21 @@ describe CaseSensitivity, models: true do
initial = double(:criteria)
final = double(:criteria)
- expect(connection).to receive(:quote_table_name).
- with(:foo).
- and_return('`foo`')
+ expect(connection).to receive(:quote_table_name)
+ .with(:foo)
+ .and_return('`foo`')
- expect(connection).to receive(:quote_table_name).
- with(:bar).
- and_return('`bar`')
+ expect(connection).to receive(:quote_table_name)
+ .with(:bar)
+ .and_return('`bar`')
- expect(model).to receive(:where).
- with(%q{`foo` = :value}, value: 'bar').
- and_return(initial)
+ expect(model).to receive(:where)
+ .with(%q{`foo` = :value}, value: 'bar')
+ .and_return(initial)
- expect(initial).to receive(:where).
- with(%q{`bar` = :value}, value: 'baz').
- and_return(final)
+ expect(initial).to receive(:where)
+ .with(%q{`bar` = :value}, value: 'baz')
+ .and_return(final)
got = model.iwhere(foo: 'bar', bar: 'baz')
@@ -162,21 +162,21 @@ describe CaseSensitivity, models: true do
initial = double(:criteria)
final = double(:criteria)
- expect(connection).to receive(:quote_table_name).
- with(:'foo.bar').
- and_return('`foo`.`bar`')
+ expect(connection).to receive(:quote_table_name)
+ .with(:'foo.bar')
+ .and_return('`foo`.`bar`')
- expect(connection).to receive(:quote_table_name).
- with(:'foo.baz').
- and_return('`foo`.`baz`')
+ expect(connection).to receive(:quote_table_name)
+ .with(:'foo.baz')
+ .and_return('`foo`.`baz`')
- expect(model).to receive(:where).
- with(%q{`foo`.`bar` = :value}, value: 'bar').
- and_return(initial)
+ expect(model).to receive(:where)
+ .with(%q{`foo`.`bar` = :value}, value: 'bar')
+ .and_return(initial)
- expect(initial).to receive(:where).
- with(%q{`foo`.`baz` = :value}, value: 'baz').
- and_return(final)
+ expect(initial).to receive(:where)
+ .with(%q{`foo`.`baz` = :value}, value: 'baz')
+ .and_return(final)
got = model.iwhere('foo.bar'.to_sym => 'bar',
'foo.baz'.to_sym => 'baz')
diff --git a/spec/models/concerns/has_status_spec.rb b/spec/models/concerns/has_status_spec.rb
index 67dae7cf4c0..101567998c9 100644
--- a/spec/models/concerns/has_status_spec.rb
+++ b/spec/models/concerns/has_status_spec.rb
@@ -168,8 +168,8 @@ describe HasStatus do
describe ".#{status}" do
it 'contains the job' do
- expect(CommitStatus.public_send(status).all).
- to contain_exactly(job)
+ expect(CommitStatus.public_send(status).all)
+ .to contain_exactly(job)
end
end
diff --git a/spec/models/concerns/issuable_spec.rb b/spec/models/concerns/issuable_spec.rb
index 1a9bda64191..ac9303370ab 100644
--- a/spec/models/concerns/issuable_spec.rb
+++ b/spec/models/concerns/issuable_spec.rb
@@ -69,8 +69,8 @@ describe Issuable do
let!(:searchable_issue) { create(:issue, title: "Searchable issue") }
it 'returns notes with a matching title' do
- expect(issuable_class.search(searchable_issue.title)).
- to eq([searchable_issue])
+ expect(issuable_class.search(searchable_issue.title))
+ .to eq([searchable_issue])
end
it 'returns notes with a partially matching title' do
@@ -78,8 +78,8 @@ describe Issuable do
end
it 'returns notes with a matching title regardless of the casing' do
- expect(issuable_class.search(searchable_issue.title.upcase)).
- to eq([searchable_issue])
+ expect(issuable_class.search(searchable_issue.title.upcase))
+ .to eq([searchable_issue])
end
end
@@ -89,8 +89,8 @@ describe Issuable do
end
it 'returns notes with a matching title' do
- expect(issuable_class.full_search(searchable_issue.title)).
- to eq([searchable_issue])
+ expect(issuable_class.full_search(searchable_issue.title))
+ .to eq([searchable_issue])
end
it 'returns notes with a partially matching title' do
@@ -98,23 +98,23 @@ describe Issuable do
end
it 'returns notes with a matching title regardless of the casing' do
- expect(issuable_class.full_search(searchable_issue.title.upcase)).
- to eq([searchable_issue])
+ expect(issuable_class.full_search(searchable_issue.title.upcase))
+ .to eq([searchable_issue])
end
it 'returns notes with a matching description' do
- expect(issuable_class.full_search(searchable_issue.description)).
- to eq([searchable_issue])
+ expect(issuable_class.full_search(searchable_issue.description))
+ .to eq([searchable_issue])
end
it 'returns notes with a partially matching description' do
- expect(issuable_class.full_search(searchable_issue.description)).
- to eq([searchable_issue])
+ expect(issuable_class.full_search(searchable_issue.description))
+ .to eq([searchable_issue])
end
it 'returns notes with a matching description regardless of the casing' do
- expect(issuable_class.full_search(searchable_issue.description.upcase)).
- to eq([searchable_issue])
+ expect(issuable_class.full_search(searchable_issue.description.upcase))
+ .to eq([searchable_issue])
end
end
diff --git a/spec/models/concerns/milestoneish_spec.rb b/spec/models/concerns/milestoneish_spec.rb
index 675b730c557..cefe7fb6fea 100644
--- a/spec/models/concerns/milestoneish_spec.rb
+++ b/spec/models/concerns/milestoneish_spec.rb
@@ -19,12 +19,43 @@ describe Milestone, 'Milestoneish' do
let!(:closed_security_issue_3) { create(:issue, :confidential, :closed, project: project, author: author, milestone: milestone) }
let!(:closed_security_issue_4) { create(:issue, :confidential, :closed, project: project, assignees: [assignee], milestone: milestone) }
let!(:merge_request) { create(:merge_request, source_project: project, target_project: project, milestone: milestone) }
+ let(:label_1) { create(:label, title: 'label_1', project: project, priority: 1) }
+ let(:label_2) { create(:label, title: 'label_2', project: project, priority: 2) }
+ let(:label_3) { create(:label, title: 'label_3', project: project) }
before do
project.team << [member, :developer]
project.team << [guest, :guest]
end
+ describe '#sorted_issues' do
+ it 'sorts issues by label priority' do
+ issue.labels << label_1
+ security_issue_1.labels << label_2
+ closed_issue_1.labels << label_3
+
+ issues = milestone.sorted_issues(member)
+
+ expect(issues.first).to eq(issue)
+ expect(issues.second).to eq(security_issue_1)
+ expect(issues.third).not_to eq(closed_issue_1)
+ end
+ end
+
+ describe '#sorted_merge_requests' do
+ it 'sorts merge requests by label priority' do
+ merge_request_1 = create(:labeled_merge_request, labels: [label_2], source_project: project, source_branch: 'branch_1', milestone: milestone)
+ merge_request_2 = create(:labeled_merge_request, labels: [label_1], source_project: project, source_branch: 'branch_2', milestone: milestone)
+ merge_request_3 = create(:labeled_merge_request, labels: [label_3], source_project: project, source_branch: 'branch_3', milestone: milestone)
+
+ merge_requests = milestone.sorted_merge_requests
+
+ expect(merge_requests.first).to eq(merge_request_2)
+ expect(merge_requests.second).to eq(merge_request_1)
+ expect(merge_requests.third).to eq(merge_request_3)
+ end
+ end
+
describe '#closed_items_count' do
it 'does not count confidential issues for non project members' do
expect(milestone.closed_items_count(non_member)).to eq 2
diff --git a/spec/models/concerns/resolvable_discussion_spec.rb b/spec/models/concerns/resolvable_discussion_spec.rb
index 18327fe262d..3934992c143 100644
--- a/spec/models/concerns/resolvable_discussion_spec.rb
+++ b/spec/models/concerns/resolvable_discussion_spec.rb
@@ -306,22 +306,22 @@ describe Discussion, ResolvableDiscussion, models: true do
it "doesn't change resolved_at on the resolved note" do
expect(first_note.resolved_at).not_to be_nil
- expect { subject.resolve!(current_user) }.
- not_to change { first_note.reload.resolved_at }
+ expect { subject.resolve!(current_user) }
+ .not_to change { first_note.reload.resolved_at }
end
it "doesn't change resolved_by on the resolved note" do
expect(first_note.resolved_by).to eq(user)
- expect { subject.resolve!(current_user) }.
- not_to change { first_note.reload && first_note.resolved_by }
+ expect { subject.resolve!(current_user) }
+ .not_to change { first_note.reload && first_note.resolved_by }
end
it "doesn't change the resolved state on the resolved note" do
expect(first_note.resolved?).to be true
- expect { subject.resolve!(current_user) }.
- not_to change { first_note.reload && first_note.resolved? }
+ expect { subject.resolve!(current_user) }
+ .not_to change { first_note.reload && first_note.resolved? }
end
it "sets resolved_at on the unresolved note" do
diff --git a/spec/models/event_spec.rb b/spec/models/event_spec.rb
index b8cb967c4cc..10b9bf9f43a 100644
--- a/spec/models/event_spec.rb
+++ b/spec/models/event_spec.rb
@@ -266,8 +266,8 @@ describe Event, models: true do
it 'does not update the project' do
project.update(last_activity_at: Time.now)
- expect(project).not_to receive(:update_column).
- with(:last_activity_at, a_kind_of(Time))
+ expect(project).not_to receive(:update_column)
+ .with(:last_activity_at, a_kind_of(Time))
create_push_event(project, project.owner)
end
diff --git a/spec/models/group_spec.rb b/spec/models/group_spec.rb
index 449b7c2f7d7..4de1683b21c 100644
--- a/spec/models/group_spec.rb
+++ b/spec/models/group_spec.rb
@@ -374,8 +374,8 @@ describe Group, models: true do
group.add_user(master, GroupMember::MASTER)
group.add_user(developer, GroupMember::DEVELOPER)
- expect(group.user_ids_for_project_authorizations).
- to include(master.id, developer.id)
+ expect(group.user_ids_for_project_authorizations)
+ .to include(master.id, developer.id)
end
end
diff --git a/spec/models/issue_collection_spec.rb b/spec/models/issue_collection_spec.rb
index 93c2c538e10..04d23d4c4fd 100644
--- a/spec/models/issue_collection_spec.rb
+++ b/spec/models/issue_collection_spec.rb
@@ -50,8 +50,8 @@ describe IssueCollection do
context 'using a user that is the owner of a project' do
it 'returns the issues of the project' do
- expect(collection.updatable_by_user(project.namespace.owner)).
- to eq([issue1, issue2])
+ expect(collection.updatable_by_user(project.namespace.owner))
+ .to eq([issue1, issue2])
end
end
end
diff --git a/spec/models/issue_spec.rb b/spec/models/issue_spec.rb
index 12e7d646382..bf97c6ececd 100644
--- a/spec/models/issue_spec.rb
+++ b/spec/models/issue_spec.rb
@@ -33,8 +33,8 @@ describe Issue, models: true do
let!(:issue4) { create(:issue, project: project, relative_position: 200) }
it 'returns ordered list' do
- expect(project.issues.order_by_position_and_priority).
- to match [issue3, issue4, issue1, issue2]
+ expect(project.issues.order_by_position_and_priority)
+ .to match [issue3, issue4, issue1, issue2]
end
end
@@ -43,16 +43,16 @@ describe Issue, models: true do
allow(subject).to receive(:author).and_return(double(name: 'Robert'))
allow(subject).to receive(:assignees).and_return([])
- expect(subject.card_attributes).
- to eq({ 'Author' => 'Robert', 'Assignee' => '' })
+ expect(subject.card_attributes)
+ .to eq({ 'Author' => 'Robert', 'Assignee' => '' })
end
it 'includes the assignee name' do
allow(subject).to receive(:author).and_return(double(name: 'Robert'))
allow(subject).to receive(:assignees).and_return([double(name: 'Douwe')])
- expect(subject.card_attributes).
- to eq({ 'Author' => 'Robert', 'Assignee' => 'Douwe' })
+ expect(subject.card_attributes)
+ .to eq({ 'Author' => 'Robert', 'Assignee' => 'Douwe' })
end
end
@@ -299,8 +299,8 @@ describe Issue, models: true do
let(:user) { build(:admin) }
before do
- allow(subject.project.repository).to receive(:branch_names).
- and_return(["mpempe", "#{subject.iid}mepmep", subject.to_branch_name, "#{subject.iid}-branch"])
+ allow(subject.project.repository).to receive(:branch_names)
+ .and_return(["mpempe", "#{subject.iid}mepmep", subject.to_branch_name, "#{subject.iid}-branch"])
# Without this stub, the `create(:merge_request)` above fails because it can't find
# the source branch. This seems like a reasonable compromise, in comparison with
@@ -322,8 +322,8 @@ describe Issue, models: true do
end
it 'excludes stable branches from the related branches' do
- allow(subject.project.repository).to receive(:branch_names).
- and_return(["#{subject.iid}-0-stable"])
+ allow(subject.project.repository).to receive(:branch_names)
+ .and_return(["#{subject.iid}-0-stable"])
expect(subject.related_branches(user)).to eq []
end
diff --git a/spec/models/key_spec.rb b/spec/models/key_spec.rb
index f1e2a2cc518..f27920f9feb 100644
--- a/spec/models/key_spec.rb
+++ b/spec/models/key_spec.rb
@@ -34,8 +34,8 @@ describe Key, models: true do
context 'when key was not updated during the last day' do
before do
- allow_any_instance_of(Gitlab::ExclusiveLease).to receive(:try_obtain).
- and_return('000000')
+ allow_any_instance_of(Gitlab::ExclusiveLease).to receive(:try_obtain)
+ .and_return('000000')
end
it 'enqueues a UseKeyWorker job' do
@@ -46,8 +46,8 @@ describe Key, models: true do
context 'when key was updated during the last day' do
before do
- allow_any_instance_of(Gitlab::ExclusiveLease).to receive(:try_obtain).
- and_return(false)
+ allow_any_instance_of(Gitlab::ExclusiveLease).to receive(:try_obtain)
+ .and_return(false)
end
it 'does not enqueue a UseKeyWorker job' do
diff --git a/spec/models/label_spec.rb b/spec/models/label_spec.rb
index 84867e3d96b..31190fe5685 100644
--- a/spec/models/label_spec.rb
+++ b/spec/models/label_spec.rb
@@ -59,8 +59,8 @@ describe Label, models: true do
describe '#text_color' do
it 'uses default color if color is missing' do
- expect(LabelsHelper).to receive(:text_color_for_bg).with(Label::DEFAULT_COLOR).
- and_return(spy)
+ expect(LabelsHelper).to receive(:text_color_for_bg).with(Label::DEFAULT_COLOR)
+ .and_return(spy)
label = described_class.new(color: nil)
diff --git a/spec/models/member_spec.rb b/spec/models/member_spec.rb
index ccc3deac199..494a88368ba 100644
--- a/spec/models/member_spec.rb
+++ b/spec/models/member_spec.rb
@@ -83,8 +83,8 @@ describe Member, models: true do
@accepted_invite_member = create(:project_member, :developer,
project: project,
invite_token: '1234',
- invite_email: 'toto2@example.com').
- tap { |u| u.accept_invite!(accepted_invite_user) }
+ invite_email: 'toto2@example.com')
+ .tap { |u| u.accept_invite!(accepted_invite_user) }
requested_user = create(:user).tap { |u| project.request_access(u) }
@requested_member = project.requesters.find_by(user_id: requested_user.id)
@@ -265,8 +265,8 @@ describe Member, models: true do
expect(source.users).not_to include(user)
expect(source.requesters.exists?(user_id: user)).to be_truthy
- expect { described_class.add_user(source, user, :master) }.
- to raise_error(Gitlab::Access::AccessDeniedError)
+ expect { described_class.add_user(source, user, :master) }
+ .to raise_error(Gitlab::Access::AccessDeniedError)
expect(source.users.reload).not_to include(user)
expect(source.requesters.reload.exists?(user_id: user)).to be_truthy
diff --git a/spec/models/members/group_member_spec.rb b/spec/models/members/group_member_spec.rb
index 17765b25856..37014268a70 100644
--- a/spec/models/members/group_member_spec.rb
+++ b/spec/models/members/group_member_spec.rb
@@ -33,8 +33,8 @@ describe GroupMember, models: true do
it "sends email to user" do
membership = build(:group_member)
- allow(membership).to receive(:notification_service).
- and_return(double('NotificationService').as_null_object)
+ allow(membership).to receive(:notification_service)
+ .and_return(double('NotificationService').as_null_object)
expect(membership).to receive(:notification_service)
membership.save
@@ -44,8 +44,8 @@ describe GroupMember, models: true do
describe "#after_update" do
before do
@group_member = create :group_member
- allow(@group_member).to receive(:notification_service).
- and_return(double('NotificationService').as_null_object)
+ allow(@group_member).to receive(:notification_service)
+ .and_return(double('NotificationService').as_null_object)
end
it "sends email to user" do
diff --git a/spec/models/merge_request_diff_file_spec.rb b/spec/models/merge_request_diff_file_spec.rb
new file mode 100644
index 00000000000..7276f5b5061
--- /dev/null
+++ b/spec/models/merge_request_diff_file_spec.rb
@@ -0,0 +1,11 @@
+require 'rails_helper'
+
+describe MergeRequestDiffFile, type: :model do
+ describe '#utf8_diff' do
+ it 'does not raise error when a hash value is in binary' do
+ subject.diff = "\x05\x00\x68\x65\x6c\x6c\x6f"
+
+ expect { subject.utf8_diff }.not_to raise_error
+ end
+ end
+end
diff --git a/spec/models/merge_request_diff_spec.rb b/spec/models/merge_request_diff_spec.rb
index 25f7062860b..4ad4abaa572 100644
--- a/spec/models/merge_request_diff_spec.rb
+++ b/spec/models/merge_request_diff_spec.rb
@@ -37,7 +37,7 @@ describe MergeRequestDiff, models: true do
context 'when the raw diffs are empty' do
before do
- mr_diff.update_attributes(st_diffs: '')
+ MergeRequestDiffFile.delete_all(merge_request_diff_id: mr_diff.id)
end
it 'returns an empty DiffCollection' do
@@ -48,6 +48,7 @@ describe MergeRequestDiff, models: true do
context 'when the raw diffs have invalid content' do
before do
+ MergeRequestDiffFile.delete_all(merge_request_diff_id: mr_diff.id)
mr_diff.update_attributes(st_diffs: ["--broken-diff"])
end
diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb
index cd2f11dec96..1240c9745e2 100644
--- a/spec/models/merge_request_spec.rb
+++ b/spec/models/merge_request_spec.rb
@@ -92,16 +92,16 @@ describe MergeRequest, models: true do
allow(subject).to receive(:author).and_return(double(name: 'Robert'))
allow(subject).to receive(:assignee).and_return(nil)
- expect(subject.card_attributes).
- to eq({ 'Author' => 'Robert', 'Assignee' => nil })
+ expect(subject.card_attributes)
+ .to eq({ 'Author' => 'Robert', 'Assignee' => nil })
end
it 'includes the assignee name' do
allow(subject).to receive(:author).and_return(double(name: 'Robert'))
allow(subject).to receive(:assignee).and_return(double(name: 'Douwe'))
- expect(subject.card_attributes).
- to eq({ 'Author' => 'Robert', 'Assignee' => 'Douwe' })
+ expect(subject.card_attributes)
+ .to eq({ 'Author' => 'Robert', 'Assignee' => 'Douwe' })
end
end
@@ -361,8 +361,8 @@ describe MergeRequest, models: true do
end
it 'accesses the set of issues that will be closed on acceptance' do
- allow(subject.project).to receive(:default_branch).
- and_return(subject.target_branch)
+ allow(subject.project).to receive(:default_branch)
+ .and_return(subject.target_branch)
closed = subject.closes_issues
@@ -388,8 +388,8 @@ describe MergeRequest, models: true do
subject.description = "Is related to #{mentioned_issue.to_reference} and #{closing_issue.to_reference}"
allow(subject).to receive(:commits).and_return([commit])
- allow(subject.project).to receive(:default_branch).
- and_return(subject.target_branch)
+ allow(subject.project).to receive(:default_branch)
+ .and_return(subject.target_branch)
expect(subject.issues_mentioned_but_not_closing(subject.author)).to match_array([mentioned_issue])
end
@@ -537,8 +537,8 @@ describe MergeRequest, models: true do
subject.project.team << [subject.author, :developer]
subject.description = "This issue Closes #{issue.to_reference}"
- allow(subject.project).to receive(:default_branch).
- and_return(subject.target_branch)
+ allow(subject.project).to receive(:default_branch)
+ .and_return(subject.target_branch)
expect(subject.merge_commit_message)
.to match("Closes #{issue.to_reference}")
@@ -663,18 +663,18 @@ describe MergeRequest, models: true do
end
it 'caches the output' do
- expect(subject).to receive(:compute_diverged_commits_count).
- once.
- and_return(2)
+ expect(subject).to receive(:compute_diverged_commits_count)
+ .once
+ .and_return(2)
subject.diverged_commits_count
subject.diverged_commits_count
end
it 'invalidates the cache when the source sha changes' do
- expect(subject).to receive(:compute_diverged_commits_count).
- twice.
- and_return(2)
+ expect(subject).to receive(:compute_diverged_commits_count)
+ .twice
+ .and_return(2)
subject.diverged_commits_count
allow(subject).to receive(:source_branch_sha).and_return('123abc')
@@ -682,9 +682,9 @@ describe MergeRequest, models: true do
end
it 'invalidates the cache when the target sha changes' do
- expect(subject).to receive(:compute_diverged_commits_count).
- twice.
- and_return(2)
+ expect(subject).to receive(:compute_diverged_commits_count)
+ .twice
+ .and_return(2)
subject.diverged_commits_count
allow(subject).to receive(:target_branch_sha).and_return('123abc')
@@ -706,8 +706,8 @@ describe MergeRequest, models: true do
describe '#commits_sha' do
before do
- allow(subject.merge_request_diff).to receive(:commits_sha).
- and_return(['sha1'])
+ allow(subject.merge_request_diff).to receive(:commits_sha)
+ .and_return(['sha1'])
end
it 'delegates to merge request diff' do
@@ -1397,7 +1397,7 @@ describe MergeRequest, models: true do
end
end
- describe '#mergeable_with_slash_command?' do
+ describe '#mergeable_with_quick_action?' do
def create_pipeline(status)
pipeline = create(:ci_pipeline_with_one_job,
project: project,
@@ -1421,21 +1421,21 @@ describe MergeRequest, models: true do
context 'when autocomplete_precheck is set to true' do
it 'is mergeable by developer' do
- expect(merge_request.mergeable_with_slash_command?(developer, autocomplete_precheck: true)).to be_truthy
+ expect(merge_request.mergeable_with_quick_action?(developer, autocomplete_precheck: true)).to be_truthy
end
it 'is not mergeable by normal user' do
- expect(merge_request.mergeable_with_slash_command?(user, autocomplete_precheck: true)).to be_falsey
+ expect(merge_request.mergeable_with_quick_action?(user, autocomplete_precheck: true)).to be_falsey
end
end
context 'when autocomplete_precheck is set to false' do
it 'is mergeable by developer' do
- expect(merge_request.mergeable_with_slash_command?(developer, last_diff_sha: mr_sha)).to be_truthy
+ expect(merge_request.mergeable_with_quick_action?(developer, last_diff_sha: mr_sha)).to be_truthy
end
it 'is not mergeable by normal user' do
- expect(merge_request.mergeable_with_slash_command?(user, last_diff_sha: mr_sha)).to be_falsey
+ expect(merge_request.mergeable_with_quick_action?(user, last_diff_sha: mr_sha)).to be_falsey
end
context 'closed MR' do
@@ -1444,7 +1444,7 @@ describe MergeRequest, models: true do
end
it 'is not mergeable' do
- expect(merge_request.mergeable_with_slash_command?(developer, last_diff_sha: mr_sha)).to be_falsey
+ expect(merge_request.mergeable_with_quick_action?(developer, last_diff_sha: mr_sha)).to be_falsey
end
end
@@ -1454,19 +1454,19 @@ describe MergeRequest, models: true do
end
it 'is not mergeable' do
- expect(merge_request.mergeable_with_slash_command?(developer, last_diff_sha: mr_sha)).to be_falsey
+ expect(merge_request.mergeable_with_quick_action?(developer, last_diff_sha: mr_sha)).to be_falsey
end
end
context 'sha differs from the MR diff_head_sha' do
it 'is not mergeable' do
- expect(merge_request.mergeable_with_slash_command?(developer, last_diff_sha: 'some other sha')).to be_falsey
+ expect(merge_request.mergeable_with_quick_action?(developer, last_diff_sha: 'some other sha')).to be_falsey
end
end
context 'sha is not provided' do
it 'is not mergeable' do
- expect(merge_request.mergeable_with_slash_command?(developer)).to be_falsey
+ expect(merge_request.mergeable_with_quick_action?(developer)).to be_falsey
end
end
@@ -1476,7 +1476,7 @@ describe MergeRequest, models: true do
end
it 'is mergeable' do
- expect(merge_request.mergeable_with_slash_command?(developer, last_diff_sha: mr_sha)).to be_truthy
+ expect(merge_request.mergeable_with_quick_action?(developer, last_diff_sha: mr_sha)).to be_truthy
end
end
@@ -1486,7 +1486,7 @@ describe MergeRequest, models: true do
end
it 'is not mergeable' do
- expect(merge_request.mergeable_with_slash_command?(developer, last_diff_sha: mr_sha)).to be_falsey
+ expect(merge_request.mergeable_with_quick_action?(developer, last_diff_sha: mr_sha)).to be_falsey
end
end
@@ -1496,7 +1496,7 @@ describe MergeRequest, models: true do
end
it 'is mergeable' do
- expect(merge_request.mergeable_with_slash_command?(developer, last_diff_sha: mr_sha)).to be_truthy
+ expect(merge_request.mergeable_with_quick_action?(developer, last_diff_sha: mr_sha)).to be_truthy
end
end
end
@@ -1504,8 +1504,8 @@ describe MergeRequest, models: true do
describe '#has_commits?' do
before do
- allow(subject.merge_request_diff).to receive(:commits_count).
- and_return(2)
+ allow(subject.merge_request_diff).to receive(:commits_count)
+ .and_return(2)
end
it 'returns true when merge request diff has commits' do
@@ -1515,8 +1515,8 @@ describe MergeRequest, models: true do
describe '#has_no_commits?' do
before do
- allow(subject.merge_request_diff).to receive(:commits_count).
- and_return(0)
+ allow(subject.merge_request_diff).to receive(:commits_count)
+ .and_return(0)
end
it 'returns true when merge request diff has 0 commits' do
diff --git a/spec/models/milestone_spec.rb b/spec/models/milestone_spec.rb
index aa1ce89ffd7..45953023a36 100644
--- a/spec/models/milestone_spec.rb
+++ b/spec/models/milestone_spec.rb
@@ -144,35 +144,6 @@ describe Milestone, models: true do
end
end
- describe '#sort_issues' do
- let(:milestone) { create(:milestone) }
-
- let(:issue1) { create(:issue, milestone: milestone, position: 1) }
- let(:issue2) { create(:issue, milestone: milestone, position: 2) }
- let(:issue3) { create(:issue, milestone: milestone, position: 3) }
- let(:issue4) { create(:issue, position: 42) }
-
- it 'sorts the given issues' do
- milestone.sort_issues([issue3.id, issue2.id, issue1.id])
-
- issue1.reload
- issue2.reload
- issue3.reload
-
- expect(issue1.position).to eq(3)
- expect(issue2.position).to eq(2)
- expect(issue3.position).to eq(1)
- end
-
- it 'ignores issues not part of the milestone' do
- milestone.sort_issues([issue3.id, issue2.id, issue1.id, issue4.id])
-
- issue4.reload
-
- expect(issue4.position).to eq(42)
- end
- end
-
describe '.search' do
let(:milestone) { create(:milestone, title: 'foo', description: 'bar') }
@@ -193,13 +164,13 @@ describe Milestone, models: true do
end
it 'returns milestones with a partially matching description' do
- expect(described_class.search(milestone.description[0..2])).
- to eq([milestone])
+ expect(described_class.search(milestone.description[0..2]))
+ .to eq([milestone])
end
it 'returns milestones with a matching description regardless of the casing' do
- expect(described_class.search(milestone.description.upcase)).
- to eq([milestone])
+ expect(described_class.search(milestone.description.upcase))
+ .to eq([milestone])
end
end
diff --git a/spec/models/namespace_spec.rb b/spec/models/namespace_spec.rb
index 145c7ad5770..e7c3acf19eb 100644
--- a/spec/models/namespace_spec.rb
+++ b/spec/models/namespace_spec.rb
@@ -325,8 +325,8 @@ describe Namespace, models: true do
describe '#user_ids_for_project_authorizations' do
it 'returns the user IDs for which to refresh authorizations' do
- expect(namespace.user_ids_for_project_authorizations).
- to eq([namespace.owner_id])
+ expect(namespace.user_ids_for_project_authorizations)
+ .to eq([namespace.owner_id])
end
end
diff --git a/spec/models/note_spec.rb b/spec/models/note_spec.rb
index d4d4fc86343..e2b80cb6e61 100644
--- a/spec/models/note_spec.rb
+++ b/spec/models/note_spec.rb
@@ -152,8 +152,8 @@ describe Note, models: true do
let!(:note2) { create(:note_on_issue) }
it "reads the rendered note body from the cache" do
- expect(Banzai::Renderer).to receive(:cache_collection_render).
- with([{
+ expect(Banzai::Renderer).to receive(:cache_collection_render)
+ .with([{
text: note1.note,
context: {
skip_project_check: false,
@@ -164,8 +164,8 @@ describe Note, models: true do
}
}]).and_call_original
- expect(Banzai::Renderer).to receive(:cache_collection_render).
- with([{
+ expect(Banzai::Renderer).to receive(:cache_collection_render)
+ .with([{
text: note2.note,
context: {
skip_project_check: false,
@@ -406,8 +406,8 @@ describe Note, models: true do
let(:note) { build(:note_on_project_snippet) }
before do
- expect(Banzai::Renderer).to receive(:cacheless_render_field).
- with(note, :note, { skip_project_check: false }).and_return(html)
+ expect(Banzai::Renderer).to receive(:cacheless_render_field)
+ .with(note, :note, { skip_project_check: false }).and_return(html)
note.save
end
@@ -421,8 +421,8 @@ describe Note, models: true do
let(:note) { build(:note_on_personal_snippet) }
before do
- expect(Banzai::Renderer).to receive(:cacheless_render_field).
- with(note, :note, { skip_project_check: true }).and_return(html)
+ expect(Banzai::Renderer).to receive(:cacheless_render_field)
+ .with(note, :note, { skip_project_check: true }).and_return(html)
note.save
end
diff --git a/spec/models/project_authorization_spec.rb b/spec/models/project_authorization_spec.rb
index cd0a4a94809..ee6bdc39c8c 100644
--- a/spec/models/project_authorization_spec.rb
+++ b/spec/models/project_authorization_spec.rb
@@ -7,8 +7,8 @@ describe ProjectAuthorization do
describe '.insert_authorizations' do
it 'inserts the authorizations' do
- described_class.
- insert_authorizations([[user.id, project1.id, Gitlab::Access::MASTER]])
+ described_class
+ .insert_authorizations([[user.id, project1.id, Gitlab::Access::MASTER]])
expect(user.project_authorizations.count).to eq(1)
end
diff --git a/spec/models/project_feature_spec.rb b/spec/models/project_feature_spec.rb
index 09a4448d387..580c83c12c0 100644
--- a/spec/models/project_feature_spec.rb
+++ b/spec/models/project_feature_spec.rb
@@ -4,6 +4,18 @@ describe ProjectFeature do
let(:project) { create(:empty_project) }
let(:user) { create(:user) }
+ describe '.quoted_access_level_column' do
+ it 'returns the table name and quoted column name for a feature' do
+ expected = if Gitlab::Database.postgresql?
+ '"project_features"."issues_access_level"'
+ else
+ '`project_features`.`issues_access_level`'
+ end
+
+ expect(described_class.quoted_access_level_column(:issues)).to eq(expected)
+ end
+ end
+
describe '#feature_available?' do
let(:features) { %w(issues wiki builds merge_requests snippets repository) }
diff --git a/spec/models/project_services/chat_message/pipeline_message_spec.rb b/spec/models/project_services/chat_message/pipeline_message_spec.rb
index 7d2599dc703..43b02568cb9 100644
--- a/spec/models/project_services/chat_message/pipeline_message_spec.rb
+++ b/spec/models/project_services/chat_message/pipeline_message_spec.rb
@@ -62,7 +62,7 @@ describe ChatMessage::PipelineMessage do
def build_message(status_text = status, name = user[:name])
"<http://example.gitlab.com|project_name>:" \
" Pipeline <http://example.gitlab.com/pipelines/123|#123>" \
- " of branch `<http://example.gitlab.com/commits/develop|develop>`" \
+ " of branch <http://example.gitlab.com/commits/develop|develop>" \
" by #{name} #{status_text} in 02:00:10"
end
end
@@ -81,7 +81,7 @@ describe ChatMessage::PipelineMessage do
expect(subject.pretext).to be_empty
expect(subject.attachments).to eq(message)
expect(subject.activity).to eq({
- title: 'Pipeline [#123](http://example.gitlab.com/pipelines/123) of branch `[develop](http://example.gitlab.com/commits/develop)` by hacker passed',
+ title: 'Pipeline [#123](http://example.gitlab.com/pipelines/123) of branch [develop](http://example.gitlab.com/commits/develop) by hacker passed',
subtitle: 'in [project_name](http://example.gitlab.com)',
text: 'in 02:00:10',
image: ''
@@ -98,7 +98,7 @@ describe ChatMessage::PipelineMessage do
expect(subject.pretext).to be_empty
expect(subject.attachments).to eq(message)
expect(subject.activity).to eq({
- title: 'Pipeline [#123](http://example.gitlab.com/pipelines/123) of branch `[develop](http://example.gitlab.com/commits/develop)` by hacker failed',
+ title: 'Pipeline [#123](http://example.gitlab.com/pipelines/123) of branch [develop](http://example.gitlab.com/commits/develop) by hacker failed',
subtitle: 'in [project_name](http://example.gitlab.com)',
text: 'in 02:00:10',
image: ''
@@ -113,7 +113,7 @@ describe ChatMessage::PipelineMessage do
expect(subject.pretext).to be_empty
expect(subject.attachments).to eq(message)
expect(subject.activity).to eq({
- title: 'Pipeline [#123](http://example.gitlab.com/pipelines/123) of branch `[develop](http://example.gitlab.com/commits/develop)` by API failed',
+ title: 'Pipeline [#123](http://example.gitlab.com/pipelines/123) of branch [develop](http://example.gitlab.com/commits/develop) by API failed',
subtitle: 'in [project_name](http://example.gitlab.com)',
text: 'in 02:00:10',
image: ''
@@ -125,7 +125,7 @@ describe ChatMessage::PipelineMessage do
def build_markdown_message(status_text = status, name = user[:name])
"[project_name](http://example.gitlab.com):" \
" Pipeline [#123](http://example.gitlab.com/pipelines/123)" \
- " of branch `[develop](http://example.gitlab.com/commits/develop)`" \
+ " of branch [develop](http://example.gitlab.com/commits/develop)" \
" by #{name} #{status_text} in 02:00:10"
end
end
diff --git a/spec/models/project_services/chat_message/push_message_spec.rb b/spec/models/project_services/chat_message/push_message_spec.rb
index e38117b75f6..c794f659c41 100644
--- a/spec/models/project_services/chat_message/push_message_spec.rb
+++ b/spec/models/project_services/chat_message/push_message_spec.rb
@@ -28,7 +28,7 @@ describe ChatMessage::PushMessage, models: true do
context 'without markdown' do
it 'returns a message regarding pushes' do
expect(subject.pretext).to eq(
- 'test.user pushed to branch `<http://url.com/commits/master|master>` of '\
+ 'test.user pushed to branch <http://url.com/commits/master|master> of '\
'<http://url.com|project_name> (<http://url.com/compare/before...after|Compare changes>)')
expect(subject.attachments).to eq([{
text: "<http://url1.com|abcdefgh>: message1 - author1\n\n"\
@@ -45,7 +45,7 @@ describe ChatMessage::PushMessage, models: true do
it 'returns a message regarding pushes' do
expect(subject.pretext).to eq(
- 'test.user pushed to branch `[master](http://url.com/commits/master)` of [project_name](http://url.com) ([Compare changes](http://url.com/compare/before...after))')
+ 'test.user pushed to branch [master](http://url.com/commits/master) of [project_name](http://url.com) ([Compare changes](http://url.com/compare/before...after))')
expect(subject.attachments).to eq(
"[abcdefgh](http://url1.com): message1 - author1\n\n[12345678](http://url2.com): message2 - author2")
expect(subject.activity).to eq({
@@ -74,7 +74,7 @@ describe ChatMessage::PushMessage, models: true do
context 'without markdown' do
it 'returns a message regarding pushes' do
expect(subject.pretext).to eq('test.user pushed new tag ' \
- '`<http://url.com/commits/new_tag|new_tag>` to ' \
+ '<http://url.com/commits/new_tag|new_tag> to ' \
'<http://url.com|project_name>')
expect(subject.attachments).to be_empty
end
@@ -87,7 +87,7 @@ describe ChatMessage::PushMessage, models: true do
it 'returns a message regarding pushes' do
expect(subject.pretext).to eq(
- 'test.user pushed new tag `[new_tag](http://url.com/commits/new_tag)` to [project_name](http://url.com)')
+ 'test.user pushed new tag [new_tag](http://url.com/commits/new_tag) to [project_name](http://url.com)')
expect(subject.attachments).to be_empty
expect(subject.activity).to eq({
title: 'test.user created tag',
@@ -107,7 +107,7 @@ describe ChatMessage::PushMessage, models: true do
context 'without markdown' do
it 'returns a message regarding a new branch' do
expect(subject.pretext).to eq(
- 'test.user pushed new branch `<http://url.com/commits/master|master>` to '\
+ 'test.user pushed new branch <http://url.com/commits/master|master> to '\
'<http://url.com|project_name>')
expect(subject.attachments).to be_empty
end
@@ -120,7 +120,7 @@ describe ChatMessage::PushMessage, models: true do
it 'returns a message regarding a new branch' do
expect(subject.pretext).to eq(
- 'test.user pushed new branch `[master](http://url.com/commits/master)` to [project_name](http://url.com)')
+ 'test.user pushed new branch [master](http://url.com/commits/master) to [project_name](http://url.com)')
expect(subject.attachments).to be_empty
expect(subject.activity).to eq({
title: 'test.user created branch',
@@ -140,7 +140,7 @@ describe ChatMessage::PushMessage, models: true do
context 'without markdown' do
it 'returns a message regarding a removed branch' do
expect(subject.pretext).to eq(
- 'test.user removed branch `master` from <http://url.com|project_name>')
+ 'test.user removed branch master from <http://url.com|project_name>')
expect(subject.attachments).to be_empty
end
end
@@ -152,7 +152,7 @@ describe ChatMessage::PushMessage, models: true do
it 'returns a message regarding a removed branch' do
expect(subject.pretext).to eq(
- 'test.user removed branch `master` from [project_name](http://url.com)')
+ 'test.user removed branch master from [project_name](http://url.com)')
expect(subject.attachments).to be_empty
expect(subject.activity).to eq({
title: 'test.user removed branch',
diff --git a/spec/models/project_services/mattermost_slash_commands_service_spec.rb b/spec/models/project_services/mattermost_slash_commands_service_spec.rb
index f9531be5d25..fa38d23e82f 100644
--- a/spec/models/project_services/mattermost_slash_commands_service_spec.rb
+++ b/spec/models/project_services/mattermost_slash_commands_service_spec.rb
@@ -11,8 +11,8 @@ describe MattermostSlashCommandsService, :models do
before do
Mattermost::Session.base_uri("http://mattermost.example.com")
- allow_any_instance_of(Mattermost::Client).to receive(:with_session).
- and_yield(Mattermost::Session.new(nil))
+ allow_any_instance_of(Mattermost::Client).to receive(:with_session)
+ .and_yield(Mattermost::Session.new(nil))
end
describe '#configure' do
@@ -24,8 +24,8 @@ describe MattermostSlashCommandsService, :models do
context 'the requests succeeds' do
before do
- stub_request(:post, 'http://mattermost.example.com/api/v3/teams/abc/commands/create').
- with(body: {
+ stub_request(:post, 'http://mattermost.example.com/api/v3/teams/abc/commands/create')
+ .with(body: {
team_id: 'abc',
trigger: 'gitlab',
url: 'http://trigger.url',
@@ -37,8 +37,8 @@ describe MattermostSlashCommandsService, :models do
display_name: "GitLab / #{project.name_with_namespace}",
method: 'P',
username: 'GitLab'
- }.to_json).
- to_return(
+ }.to_json)
+ .to_return(
status: 200,
headers: { 'Content-Type' => 'application/json' },
body: { token: 'token' }.to_json
@@ -58,8 +58,8 @@ describe MattermostSlashCommandsService, :models do
context 'an error is received' do
before do
- stub_request(:post, 'http://mattermost.example.com/api/v3/teams/abc/commands/create').
- to_return(
+ stub_request(:post, 'http://mattermost.example.com/api/v3/teams/abc/commands/create')
+ .to_return(
status: 500,
headers: { 'Content-Type' => 'application/json' },
body: {
@@ -88,8 +88,8 @@ describe MattermostSlashCommandsService, :models do
context 'the requests succeeds' do
before do
- stub_request(:get, 'http://mattermost.example.com/api/v3/teams/all').
- to_return(
+ stub_request(:get, 'http://mattermost.example.com/api/v3/teams/all')
+ .to_return(
status: 200,
headers: { 'Content-Type' => 'application/json' },
body: { 'list' => true }.to_json
@@ -103,8 +103,8 @@ describe MattermostSlashCommandsService, :models do
context 'an error is received' do
before do
- stub_request(:get, 'http://mattermost.example.com/api/v3/teams/all').
- to_return(
+ stub_request(:get, 'http://mattermost.example.com/api/v3/teams/all')
+ .to_return(
status: 500,
headers: { 'Content-Type' => 'application/json' },
body: {
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index 63333b7af1f..d7fcadb895e 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -1195,23 +1195,23 @@ describe Project, models: true do
it 'renames a repository' do
stub_container_registry_config(enabled: false)
- expect(gitlab_shell).to receive(:mv_repository).
- ordered.
- with(project.repository_storage_path, "#{project.namespace.full_path}/foo", "#{project.full_path}").
- and_return(true)
+ expect(gitlab_shell).to receive(:mv_repository)
+ .ordered
+ .with(project.repository_storage_path, "#{project.namespace.full_path}/foo", "#{project.full_path}")
+ .and_return(true)
- expect(gitlab_shell).to receive(:mv_repository).
- ordered.
- with(project.repository_storage_path, "#{project.namespace.full_path}/foo.wiki", "#{project.full_path}.wiki").
- and_return(true)
+ expect(gitlab_shell).to receive(:mv_repository)
+ .ordered
+ .with(project.repository_storage_path, "#{project.namespace.full_path}/foo.wiki", "#{project.full_path}.wiki")
+ .and_return(true)
- expect_any_instance_of(SystemHooksService).
- to receive(:execute_hooks_for).
- with(project, :rename)
+ expect_any_instance_of(SystemHooksService)
+ .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_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)
@@ -1239,13 +1239,13 @@ describe Project, models: true do
let(:wiki) { double(:wiki, exists?: true) }
it 'expires the caches of the repository and wiki' do
- allow(Repository).to receive(:new).
- with('foo', project).
- and_return(repo)
+ allow(Repository).to receive(:new)
+ .with('foo', project)
+ .and_return(repo)
- allow(Repository).to receive(:new).
- with('foo.wiki', project).
- and_return(wiki)
+ allow(Repository).to receive(:new)
+ .with('foo.wiki', project)
+ .and_return(wiki)
expect(repo).to receive(:before_delete)
expect(wiki).to receive(:before_delete)
@@ -1296,9 +1296,9 @@ describe Project, models: true do
context 'using a regular repository' do
it 'creates the repository' do
- expect(shell).to receive(:add_repository).
- with(project.repository_storage_path, project.path_with_namespace).
- and_return(true)
+ expect(shell).to receive(:add_repository)
+ .with(project.repository_storage_path, project.path_with_namespace)
+ .and_return(true)
expect(project.repository).to receive(:after_create)
@@ -1306,9 +1306,9 @@ describe Project, models: true do
end
it 'adds an error if the repository could not be created' do
- expect(shell).to receive(:add_repository).
- with(project.repository_storage_path, project.path_with_namespace).
- and_return(false)
+ expect(shell).to receive(:add_repository)
+ .with(project.repository_storage_path, project.path_with_namespace)
+ .and_return(false)
expect(project.repository).not_to receive(:after_create)
@@ -1564,8 +1564,8 @@ describe Project, models: true do
let(:project) { forked_project_link.forked_to_project }
it 'schedules a RepositoryForkWorker job' do
- expect(RepositoryForkWorker).to receive(:perform_async).
- with(project.id, forked_from_project.repository_storage_path,
+ expect(RepositoryForkWorker).to receive(:perform_async)
+ .with(project.id, forked_from_project.repository_storage_path,
forked_from_project.path_with_namespace, project.namespace.full_path)
project.add_import_job
@@ -2041,15 +2041,15 @@ describe Project, models: true do
error_message = 'Failed to replace merge_requests because one or more of the new records could not be saved.'\
' Validate fork Source project is not a fork of the target project'
- expect { project.append_or_update_attribute(:merge_requests, [create(:merge_request)]) }.
- to raise_error(ActiveRecord::RecordNotSaved, error_message)
+ expect { project.append_or_update_attribute(:merge_requests, [create(:merge_request)]) }
+ .to raise_error(ActiveRecord::RecordNotSaved, error_message)
end
it 'updates the project succesfully' do
merge_request = create(:merge_request, target_project: project, source_project: project)
- expect { project.append_or_update_attribute(:merge_requests, [merge_request]) }.
- not_to raise_error
+ expect { project.append_or_update_attribute(:merge_requests, [merge_request]) }
+ .not_to raise_error
end
end
@@ -2060,4 +2060,36 @@ describe Project, models: true do
expect(project.last_repository_updated_at.to_i).to eq(project.created_at.to_i)
end
end
+
+ describe '.public_or_visible_to_user' do
+ let!(:user) { create(:user) }
+
+ let!(:private_project) do
+ create(:empty_project, :private, creator: user, namespace: user.namespace)
+ end
+
+ let!(:public_project) { create(:empty_project, :public) }
+
+ context 'with a user' do
+ let(:projects) do
+ Project.all.public_or_visible_to_user(user)
+ end
+
+ it 'includes projects the user has access to' do
+ expect(projects).to include(private_project)
+ end
+
+ it 'includes projects the user can see' do
+ expect(projects).to include(public_project)
+ end
+ end
+
+ context 'without a user' do
+ it 'only includes public projects' do
+ projects = Project.all.public_or_visible_to_user
+
+ expect(projects).to eq([public_project])
+ end
+ end
+ end
end
diff --git a/spec/models/project_team_spec.rb b/spec/models/project_team_spec.rb
index ea3cd5fe10a..49f2f8c0ad1 100644
--- a/spec/models/project_team_spec.rb
+++ b/spec/models/project_team_spec.rb
@@ -100,8 +100,8 @@ describe ProjectTeam, models: true do
group_access: Gitlab::Access::GUEST
)
- expect(project.team.members).
- to contain_exactly(group_member.user, project.owner)
+ expect(project.team.members)
+ .to contain_exactly(group_member.user, project.owner)
end
it 'returns invited members of a group of a specified level' do
diff --git a/spec/models/project_wiki_spec.rb b/spec/models/project_wiki_spec.rb
index 3f5f4eea4a1..bf74ac5ea25 100644
--- a/spec/models/project_wiki_spec.rb
+++ b/spec/models/project_wiki_spec.rb
@@ -149,15 +149,15 @@ describe ProjectWiki, models: true do
describe '#find_file' do
before do
file = Gollum::File.new(subject.wiki)
- allow_any_instance_of(Gollum::Wiki).
- to receive(:file).with('image.jpg', 'master', true).
- and_return(file)
- allow_any_instance_of(Gollum::File).
- to receive(:mime_type).
- and_return('image/jpeg')
- allow_any_instance_of(Gollum::Wiki).
- to receive(:file).with('non-existant', 'master', true).
- and_return(nil)
+ allow_any_instance_of(Gollum::Wiki)
+ .to receive(:file).with('image.jpg', 'master', true)
+ .and_return(file)
+ allow_any_instance_of(Gollum::File)
+ .to receive(:mime_type)
+ .and_return('image/jpeg')
+ allow_any_instance_of(Gollum::Wiki)
+ .to receive(:file).with('non-existant', 'master', true)
+ .and_return(nil)
end
after do
@@ -268,9 +268,9 @@ describe ProjectWiki, models: true do
describe '#create_repo!' do
it 'creates a repository' do
- expect(subject).to receive(:init_repo).
- with(subject.path_with_namespace).
- and_return(true)
+ expect(subject).to receive(:init_repo)
+ .with(subject.path_with_namespace)
+ .and_return(true)
expect(subject.repository).to receive(:after_create)
diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb
index a6d4d92c450..3e984ec7588 100644
--- a/spec/models/repository_spec.rb
+++ b/spec/models/repository_spec.rb
@@ -111,8 +111,8 @@ describe Repository, models: true do
describe '#ref_name_for_sha' do
it 'returns the ref' do
- allow(repository.raw_repository).to receive(:ref_name_for_sha).
- and_return('refs/environments/production/77')
+ allow(repository.raw_repository).to receive(:ref_name_for_sha)
+ .and_return('refs/environments/production/77')
expect(repository.ref_name_for_sha('bla', '0' * 40)).to eq 'refs/environments/production/77'
end
@@ -593,8 +593,8 @@ describe Repository, models: true do
user, 'LICENSE', 'Copyright!',
message: 'Add LICENSE', branch_name: 'master')
- allow(repository).to receive(:file_on_head).
- and_raise(Rugged::ReferenceError)
+ allow(repository).to receive(:file_on_head)
+ .and_raise(Rugged::ReferenceError)
expect(repository.license_blob).to be_nil
end
@@ -779,8 +779,8 @@ describe Repository, models: true do
context 'when pre hooks were successful' do
it 'runs without errors' do
- expect_any_instance_of(GitHooksService).to receive(:execute).
- with(user, project.repository.path_to_repo, old_rev, blank_sha, 'refs/heads/feature')
+ expect_any_instance_of(GitHooksService).to receive(:execute)
+ .with(user, project.repository.path_to_repo, old_rev, blank_sha, 'refs/heads/feature')
expect { repository.rm_branch(user, 'feature') }.not_to raise_error
end
@@ -822,14 +822,14 @@ describe Repository, models: true do
before do
service = GitHooksService.new
expect(GitHooksService).to receive(:new).and_return(service)
- expect(service).to receive(:execute).
- with(
+ expect(service).to receive(:execute)
+ .with(
user,
repository.path_to_repo,
old_rev,
new_rev,
- 'refs/heads/feature').
- and_yield(service).and_return(true)
+ 'refs/heads/feature')
+ .and_yield(service).and_return(true)
end
it 'runs without errors' do
@@ -923,8 +923,8 @@ describe Repository, models: true do
expect(repository).not_to receive(:expire_emptiness_caches)
expect(repository).to receive(:expire_branches_cache)
- GitOperationService.new(user, repository).
- with_branch('new-feature') do
+ GitOperationService.new(user, repository)
+ .with_branch('new-feature') do
new_rev
end
end
@@ -1007,8 +1007,8 @@ describe Repository, models: true do
end
it 'does nothing' do
- expect(repository.raw_repository).not_to receive(:autocrlf=).
- with(:input)
+ expect(repository.raw_repository).not_to receive(:autocrlf=)
+ .with(:input)
GitOperationService.new(nil, repository).send(:update_autocrlf_option)
end
@@ -1027,9 +1027,9 @@ describe Repository, models: true do
end
it 'caches the output' do
- expect(repository.raw_repository).to receive(:empty?).
- once.
- and_return(false)
+ expect(repository.raw_repository).to receive(:empty?)
+ .once
+ .and_return(false)
repository.empty?
repository.empty?
@@ -1042,9 +1042,9 @@ describe Repository, models: true do
end
it 'caches the output' do
- expect(repository.raw_repository).to receive(:root_ref).
- once.
- and_return('master')
+ expect(repository.raw_repository).to receive(:root_ref)
+ .once
+ .and_return('master')
repository.root_ref
repository.root_ref
@@ -1055,9 +1055,9 @@ describe Repository, models: true do
it 'expires the root reference cache' do
repository.root_ref
- expect(repository.raw_repository).to receive(:root_ref).
- once.
- and_return('foo')
+ expect(repository.raw_repository).to receive(:root_ref)
+ .once
+ .and_return('foo')
repository.expire_root_ref_cache
@@ -1071,17 +1071,17 @@ describe Repository, models: true do
let(:cache) { repository.send(:cache) }
it 'expires the cache for all branches' do
- expect(cache).to receive(:expire).
- at_least(repository.branches.length * 2).
- times
+ expect(cache).to receive(:expire)
+ .at_least(repository.branches.length * 2)
+ .times
repository.expire_branch_cache
end
it 'expires the cache for all branches when the root branch is given' do
- expect(cache).to receive(:expire).
- at_least(repository.branches.length * 2).
- times
+ expect(cache).to receive(:expire)
+ .at_least(repository.branches.length * 2)
+ .times
repository.expire_branch_cache(repository.root_ref)
end
@@ -1344,12 +1344,12 @@ describe Repository, models: true do
describe '#after_push_commit' do
it 'expires statistics caches' do
- expect(repository).to receive(:expire_statistics_caches).
- and_call_original
+ expect(repository).to receive(:expire_statistics_caches)
+ .and_call_original
- expect(repository).to receive(:expire_branch_cache).
- with('master').
- and_call_original
+ expect(repository).to receive(:expire_branch_cache)
+ .with('master')
+ .and_call_original
repository.after_push_commit('master')
end
@@ -1434,9 +1434,9 @@ describe Repository, models: true do
describe '#expire_branches_cache' do
it 'expires the cache' do
- expect(repository).to receive(:expire_method_caches).
- with(%i(branch_names branch_count)).
- and_call_original
+ expect(repository).to receive(:expire_method_caches)
+ .with(%i(branch_names branch_count))
+ .and_call_original
repository.expire_branches_cache
end
@@ -1444,9 +1444,9 @@ describe Repository, models: true do
describe '#expire_tags_cache' do
it 'expires the cache' do
- expect(repository).to receive(:expire_method_caches).
- with(%i(tag_names tag_count)).
- and_call_original
+ expect(repository).to receive(:expire_method_caches)
+ .with(%i(tag_names tag_count))
+ .and_call_original
repository.expire_tags_cache
end
@@ -1457,11 +1457,11 @@ describe Repository, models: true do
let(:user) { build_stubbed(:user) }
it 'creates the tag using rugged' do
- expect(repository.rugged.tags).to receive(:create).
- with('8.5', repository.commit('master').id,
+ expect(repository.rugged.tags).to receive(:create)
+ .with('8.5', repository.commit('master').id,
hash_including(message: 'foo',
- tagger: hash_including(name: user.name, email: user.email))).
- and_call_original
+ tagger: hash_including(name: user.name, email: user.email)))
+ .and_call_original
repository.add_tag(user, '8.5', 'master', 'foo')
end
@@ -1478,8 +1478,8 @@ describe Repository, models: true do
update_hook = Gitlab::Git::Hook.new('update', repository.path_to_repo)
post_receive_hook = Gitlab::Git::Hook.new('post-receive', repository.path_to_repo)
- allow(Gitlab::Git::Hook).to receive(:new).
- and_return(pre_receive_hook, update_hook, post_receive_hook)
+ allow(Gitlab::Git::Hook).to receive(:new)
+ .and_return(pre_receive_hook, update_hook, post_receive_hook)
allow(pre_receive_hook).to receive(:trigger).and_call_original
allow(update_hook).to receive(:trigger).and_call_original
@@ -1490,12 +1490,12 @@ describe Repository, models: true do
commit_sha = repository.commit('master').id
tag_sha = tag.target
- expect(pre_receive_hook).to have_received(:trigger).
- with(anything, anything, commit_sha, anything)
- expect(update_hook).to have_received(:trigger).
- with(anything, anything, commit_sha, anything)
- expect(post_receive_hook).to have_received(:trigger).
- with(anything, anything, tag_sha, anything)
+ expect(pre_receive_hook).to have_received(:trigger)
+ .with(anything, anything, commit_sha, anything)
+ expect(update_hook).to have_received(:trigger)
+ .with(anything, anything, commit_sha, anything)
+ expect(post_receive_hook).to have_received(:trigger)
+ .with(anything, anything, tag_sha, anything)
end
end
@@ -1529,25 +1529,25 @@ describe Repository, models: true do
describe '#avatar' do
it 'returns nil if repo does not exist' do
- expect(repository).to receive(:file_on_head).
- and_raise(Rugged::ReferenceError)
+ expect(repository).to receive(:file_on_head)
+ .and_raise(Rugged::ReferenceError)
expect(repository.avatar).to eq(nil)
end
it 'returns the first avatar file found in the repository' do
- expect(repository).to receive(:file_on_head).
- with(:avatar).
- and_return(double(:tree, path: 'logo.png'))
+ expect(repository).to receive(:file_on_head)
+ .with(:avatar)
+ .and_return(double(:tree, path: 'logo.png'))
expect(repository.avatar).to eq('logo.png')
end
it 'caches the output' do
- expect(repository).to receive(:file_on_head).
- with(:avatar).
- once.
- and_return(double(:tree, path: 'logo.png'))
+ expect(repository).to receive(:file_on_head)
+ .with(:avatar)
+ .once
+ .and_return(double(:tree, path: 'logo.png'))
2.times { expect(repository.avatar).to eq('logo.png') }
end
@@ -1607,24 +1607,24 @@ describe Repository, models: true do
describe '#contribution_guide', caching: true do
it 'returns and caches the output' do
- expect(repository).to receive(:file_on_head).
- with(:contributing).
- and_return(Gitlab::Git::Tree.new(path: 'CONTRIBUTING.md')).
- once
+ expect(repository).to receive(:file_on_head)
+ .with(:contributing)
+ .and_return(Gitlab::Git::Tree.new(path: 'CONTRIBUTING.md'))
+ .once
2.times do
- expect(repository.contribution_guide).
- to be_an_instance_of(Gitlab::Git::Tree)
+ expect(repository.contribution_guide)
+ .to be_an_instance_of(Gitlab::Git::Tree)
end
end
end
describe '#gitignore', caching: true do
it 'returns and caches the output' do
- expect(repository).to receive(:file_on_head).
- with(:gitignore).
- and_return(Gitlab::Git::Tree.new(path: '.gitignore')).
- once
+ expect(repository).to receive(:file_on_head)
+ .with(:gitignore)
+ .and_return(Gitlab::Git::Tree.new(path: '.gitignore'))
+ .once
2.times do
expect(repository.gitignore).to be_an_instance_of(Gitlab::Git::Tree)
@@ -1634,10 +1634,10 @@ describe Repository, models: true do
describe '#koding_yml', caching: true do
it 'returns and caches the output' do
- expect(repository).to receive(:file_on_head).
- with(:koding).
- and_return(Gitlab::Git::Tree.new(path: '.koding.yml')).
- once
+ expect(repository).to receive(:file_on_head)
+ .with(:koding)
+ .and_return(Gitlab::Git::Tree.new(path: '.koding.yml'))
+ .once
2.times do
expect(repository.koding_yml).to be_an_instance_of(Gitlab::Git::Tree)
@@ -1673,8 +1673,8 @@ describe Repository, models: true do
describe '#expire_statistics_caches' do
it 'expires the caches' do
- expect(repository).to receive(:expire_method_caches).
- with(%i(size commit_count))
+ expect(repository).to receive(:expire_method_caches)
+ .with(%i(size commit_count))
repository.expire_statistics_caches
end
@@ -1691,8 +1691,8 @@ describe Repository, models: true do
describe '#expire_all_method_caches' do
it 'expires the caches of all methods' do
- expect(repository).to receive(:expire_method_caches).
- with(Repository::CACHED_METHODS)
+ expect(repository).to receive(:expire_method_caches)
+ .with(Repository::CACHED_METHODS)
repository.expire_all_method_caches
end
@@ -1717,8 +1717,8 @@ describe Repository, models: true do
context 'with an existing repository' do
it 'returns a Gitlab::Git::Tree' do
- expect(repository.file_on_head(:readme)).
- to be_an_instance_of(Gitlab::Git::Tree)
+ expect(repository.file_on_head(:readme))
+ .to be_an_instance_of(Gitlab::Git::Tree)
end
end
end
@@ -1856,8 +1856,8 @@ describe Repository, models: true do
describe '#refresh_method_caches' do
it 'refreshes the caches of the given types' do
- expect(repository).to receive(:expire_method_caches).
- with(%i(rendered_readme license_blob license_key license))
+ expect(repository).to receive(:expire_method_caches)
+ .with(%i(rendered_readme license_blob license_key license))
expect(repository).to receive(:rendered_readme)
expect(repository).to receive(:license_blob)
diff --git a/spec/models/upload_spec.rb b/spec/models/upload_spec.rb
index 4c832c87d6a..2dea2c6015f 100644
--- a/spec/models/upload_spec.rb
+++ b/spec/models/upload_spec.rb
@@ -54,8 +54,8 @@ describe Upload, type: :model do
uploader: 'AvatarUploader'
)
- expect { described_class.remove_path(__FILE__) }.
- to change { described_class.count }.from(1).to(0)
+ expect { described_class.remove_path(__FILE__) }
+ .to change { described_class.count }.from(1).to(0)
end
end
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 1a1bbd60504..314f8781867 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -451,6 +451,40 @@ describe User, models: true do
end
end
+ describe '#ensure_user_rights_and_limits' do
+ describe 'with external user' do
+ let(:user) { create(:user, external: true) }
+
+ it 'receives callback when external changes' do
+ expect(user).to receive(:ensure_user_rights_and_limits)
+
+ user.update_attributes(external: false)
+ end
+
+ it 'ensures correct rights and limits for user' do
+ stub_config_setting(default_can_create_group: true)
+
+ expect { user.update_attributes(external: false) }.to change { user.can_create_group }.to(true)
+ .and change { user.projects_limit }.to(current_application_settings.default_projects_limit)
+ end
+ end
+
+ describe 'without external user' do
+ let(:user) { create(:user, external: false) }
+
+ it 'receives callback when external changes' do
+ expect(user).to receive(:ensure_user_rights_and_limits)
+
+ user.update_attributes(external: true)
+ end
+
+ it 'ensures correct rights and limits for user' do
+ expect { user.update_attributes(external: true) }.to change { user.can_create_group }.to(false)
+ .and change { user.projects_limit }.to(0)
+ end
+ end
+ end
+
describe 'rss token' do
it 'ensures an rss token on read' do
user = create(:user, rss_token: nil)
@@ -878,8 +912,8 @@ describe User, models: true do
describe '.find_by_username!' do
it 'raises RecordNotFound' do
- expect { described_class.find_by_username!('JohnDoe') }.
- to raise_error(ActiveRecord::RecordNotFound)
+ expect { described_class.find_by_username!('JohnDoe') }
+ .to raise_error(ActiveRecord::RecordNotFound)
end
it 'is case-insensitive' do
@@ -1523,8 +1557,8 @@ describe User, models: true do
end
it 'returns the projects when using an ActiveRecord relation' do
- projects = user.
- projects_with_reporter_access_limited_to(Project.select(:id))
+ projects = user
+ .projects_with_reporter_access_limited_to(Project.select(:id))
expect(projects).to eq([project1])
end
diff --git a/spec/models/wiki_page_spec.rb b/spec/models/wiki_page_spec.rb
index 753dc938c52..4a73552b8a6 100644
--- a/spec/models/wiki_page_spec.rb
+++ b/spec/models/wiki_page_spec.rb
@@ -61,8 +61,8 @@ describe WikiPage, models: true do
actual_order =
grouped_entries.map do |page_or_dir|
get_slugs(page_or_dir)
- end.
- flatten
+ end
+ .flatten
expect(actual_order).to eq(expected_order)
end
end
diff --git a/spec/policies/project_policy_spec.rb b/spec/policies/project_policy_spec.rb
index 848fd547e10..d70e15f006b 100644
--- a/spec/policies/project_policy_spec.rb
+++ b/spec/policies/project_policy_spec.rb
@@ -80,8 +80,8 @@ describe ProjectPolicy, models: true do
expect(project.team.member?(issue.author)).to eq(false)
- expect(BasePolicy.class_for(project).abilities(user, project).can_set).
- not_to include(:read_issue)
+ expect(BasePolicy.class_for(project).abilities(user, project).can_set)
+ .not_to include(:read_issue)
expect(Ability.allowed?(user, :read_issue, project)).to be_falsy
end
diff --git a/spec/presenters/ci/build_presenter_spec.rb b/spec/presenters/ci/build_presenter_spec.rb
index 2190ab0e82e..518e97d17a1 100644
--- a/spec/presenters/ci/build_presenter_spec.rb
+++ b/spec/presenters/ci/build_presenter_spec.rb
@@ -47,8 +47,8 @@ describe Ci::BuildPresenter do
context 'when build is erased' do
before do
expect(presenter).to receive(:erased_by_user?).and_return(true)
- expect(build).to receive(:erased_by).
- and_return(double(:user, name: 'John Doe'))
+ expect(build).to receive(:erased_by)
+ .and_return(double(:user, name: 'John Doe'))
end
it 'returns the name of the eraser' do
diff --git a/spec/requests/api/deploy_keys_spec.rb b/spec/requests/api/deploy_keys_spec.rb
index 9c260f88f56..32439981b60 100644
--- a/spec/requests/api/deploy_keys_spec.rb
+++ b/spec/requests/api/deploy_keys_spec.rb
@@ -160,6 +160,16 @@ describe API::DeployKeys do
expect(json_response['title']).to eq('new title')
expect(json_response['can_push']).to eq(true)
end
+
+ it 'updates a private ssh key from projects user has access with correct attributes' do
+ create(:deploy_keys_project, project: project2, deploy_key: private_deploy_key)
+
+ put api("/projects/#{project.id}/deploy_keys/#{private_deploy_key.id}", admin), { title: 'new title', can_push: true }
+
+ expect(json_response['id']).to eq(private_deploy_key.id)
+ expect(json_response['title']).to eq('new title')
+ expect(json_response['can_push']).to eq(true)
+ end
end
describe 'DELETE /projects/:id/deploy_keys/:key_id' do
diff --git a/spec/requests/api/files_spec.rb b/spec/requests/api/files_spec.rb
index c5ec8be4f21..9e268adf950 100644
--- a/spec/requests/api/files_spec.rb
+++ b/spec/requests/api/files_spec.rb
@@ -205,8 +205,8 @@ describe API::Files do
end
it "returns a 400 if editor fails to create file" do
- allow_any_instance_of(Repository).to receive(:create_file).
- and_raise(Repository::CommitError, 'Cannot create file')
+ allow_any_instance_of(Repository).to receive(:create_file)
+ .and_raise(Repository::CommitError, 'Cannot create file')
post api(route("any%2Etxt"), user), valid_params
diff --git a/spec/requests/api/groups_spec.rb b/spec/requests/api/groups_spec.rb
index bb53796cbd7..656f098aea8 100644
--- a/spec/requests/api/groups_spec.rb
+++ b/spec/requests/api/groups_spec.rb
@@ -513,8 +513,8 @@ describe API::Groups do
let(:project_path) { project.full_path.gsub('/', '%2F') }
before(:each) do
- allow_any_instance_of(Projects::TransferService).
- to receive(:execute).and_return(true)
+ allow_any_instance_of(Projects::TransferService)
+ .to receive(:execute).and_return(true)
end
context "when authenticated as user" do
diff --git a/spec/requests/api/internal_spec.rb b/spec/requests/api/internal_spec.rb
index 86e15d896df..6deaea956e0 100644
--- a/spec/requests/api/internal_spec.rb
+++ b/spec/requests/api/internal_spec.rb
@@ -321,8 +321,6 @@ describe API::Internal do
end
context "archived project" do
- let(:personal_project) { create(:empty_project, namespace: user.namespace) }
-
before do
project.team << [user, :developer]
project.archive!
@@ -445,6 +443,42 @@ describe API::Internal do
expect(json_response['status']).to be_truthy
end
end
+
+ context 'the project path was changed' do
+ let!(:old_path_to_repo) { project.repository.path_to_repo }
+ let!(:old_full_path) { project.full_path }
+ let(:project_moved_message) do
+ <<-MSG.strip_heredoc
+ Project '#{old_full_path}' was moved to '#{project.full_path}'.
+
+ Please update your Git remote and try again:
+
+ git remote set-url origin #{project.ssh_url_to_repo}
+ MSG
+ end
+
+ before do
+ project.team << [user, :developer]
+ project.path = 'new_path'
+ project.save!
+ end
+
+ it 'rejects the push' do
+ push_with_path(key, old_path_to_repo)
+
+ expect(response).to have_http_status(200)
+ expect(json_response['status']).to be_falsey
+ expect(json_response['message']).to eq(project_moved_message)
+ end
+
+ it 'rejects the SSH pull' do
+ pull_with_path(key, old_path_to_repo)
+
+ expect(response).to have_http_status(200)
+ expect(json_response['status']).to be_falsey
+ expect(json_response['message']).to eq(project_moved_message)
+ end
+ end
end
describe 'GET /internal/merge_request_urls' do
@@ -587,6 +621,17 @@ describe API::Internal do
)
end
+ def pull_with_path(key, path_to_repo, protocol = 'ssh')
+ post(
+ api("/internal/allowed"),
+ key_id: key.id,
+ project: path_to_repo,
+ action: 'git-upload-pack',
+ secret_token: secret_token,
+ protocol: protocol
+ )
+ end
+
def push(key, project, protocol = 'ssh', env: nil)
post(
api("/internal/allowed"),
@@ -600,6 +645,19 @@ describe API::Internal do
)
end
+ def push_with_path(key, path_to_repo, protocol = 'ssh', env: nil)
+ post(
+ api("/internal/allowed"),
+ changes: 'd14d6c0abdd253381df51a723d58691b2ee1ab08 570e7b2abdd848b95f2f578043fc23bd6f6fd24d refs/heads/master',
+ key_id: key.id,
+ project: path_to_repo,
+ action: 'git-receive-pack',
+ secret_token: secret_token,
+ protocol: protocol,
+ env: env
+ )
+ end
+
def archive(key, project)
post(
api("/internal/allowed"),
diff --git a/spec/requests/api/merge_requests_spec.rb b/spec/requests/api/merge_requests_spec.rb
index 16e5efb2f5b..4d0bd67c571 100644
--- a/spec/requests/api/merge_requests_spec.rb
+++ b/spec/requests/api/merge_requests_spec.rb
@@ -334,14 +334,13 @@ describe API::MergeRequests do
target_branch: 'master',
author: user,
labels: 'label, label2',
- milestone_id: milestone.id,
- remove_source_branch: true
+ milestone_id: milestone.id
expect(response).to have_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)
- expect(json_response['force_remove_source_branch']).to be_truthy
+ expect(json_response['force_remove_source_branch']).to be_falsy
end
it "returns 422 when source_branch equals target_branch" do
@@ -404,6 +403,27 @@ describe API::MergeRequests do
expect(response).to have_http_status(409)
end
end
+
+ context 'accepts remove_source_branch parameter' do
+ let(:params) do
+ { title: 'Test merge_request',
+ source_branch: 'markdown',
+ target_branch: 'master',
+ author: user }
+ end
+
+ it 'sets force_remove_source_branch to false' do
+ post api("/projects/#{project.id}/merge_requests", user), params.merge(remove_source_branch: false)
+
+ expect(json_response['force_remove_source_branch']).to be_falsy
+ end
+
+ it 'sets force_remove_source_branch to true' do
+ post api("/projects/#{project.id}/merge_requests", user), params.merge(remove_source_branch: true)
+
+ expect(json_response['force_remove_source_branch']).to be_truthy
+ end
+ end
end
context 'forked projects' do
@@ -540,8 +560,8 @@ describe API::MergeRequests do
end
it "returns 406 if branch can't be merged" do
- allow_any_instance_of(MergeRequest).
- to receive(:can_be_merged?).and_return(false)
+ allow_any_instance_of(MergeRequest)
+ .to receive(:can_be_merged?).and_return(false)
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/merge", user)
diff --git a/spec/requests/api/milestones_spec.rb b/spec/requests/api/milestones_spec.rb
index 40934c25afc..ab5ea3e8f2c 100644
--- a/spec/requests/api/milestones_spec.rb
+++ b/spec/requests/api/milestones_spec.rb
@@ -5,6 +5,9 @@ describe API::Milestones do
let!(:project) { create(:empty_project, namespace: user.namespace ) }
let!(:closed_milestone) { create(:closed_milestone, project: project, title: 'version1', description: 'closed milestone') }
let!(:milestone) { create(:milestone, project: project, title: 'version2', description: 'open milestone') }
+ let(:label_1) { create(:label, title: 'label_1', project: project, priority: 1) }
+ let(:label_2) { create(:label, title: 'label_2', project: project, priority: 2) }
+ let(:label_3) { create(:label, title: 'label_3', project: project) }
before do
project.team << [user, :developer]
@@ -228,6 +231,18 @@ describe API::Milestones do
expect(json_response.first['milestone']['title']).to eq(milestone.title)
end
+ it 'returns project issues sorted by label priority' do
+ issue_1 = create(:labeled_issue, project: project, milestone: milestone, labels: [label_3])
+ issue_2 = create(:labeled_issue, project: project, milestone: milestone, labels: [label_1])
+ issue_3 = create(:labeled_issue, project: project, milestone: milestone, labels: [label_2])
+
+ get api("/projects/#{project.id}/milestones/#{milestone.id}/issues", user)
+
+ expect(json_response.first['id']).to eq(issue_2.id)
+ expect(json_response.second['id']).to eq(issue_3.id)
+ expect(json_response.third['id']).to eq(issue_1.id)
+ end
+
it 'matches V4 response schema for a list of issues' do
get api("/projects/#{project.id}/milestones/#{milestone.id}/issues", user)
@@ -244,8 +259,8 @@ describe API::Milestones do
describe 'confidential issues' do
let(:public_project) { create(:empty_project, :public) }
let(:milestone) { create(:milestone, project: public_project) }
- let(:issue) { create(:issue, project: public_project, position: 2) }
- let(:confidential_issue) { create(:issue, confidential: true, project: public_project, position: 1) }
+ let(:issue) { create(:issue, project: public_project) }
+ let(:confidential_issue) { create(:issue, confidential: true, project: public_project) }
before do
public_project.team << [user, :developer]
@@ -285,7 +300,10 @@ describe API::Milestones do
expect(json_response.map { |issue| issue['id'] }).to include(issue.id)
end
- it 'returns issues ordered by position asc' do
+ it 'returns issues ordered by label priority' do
+ issue.labels << label_2
+ confidential_issue.labels << label_1
+
get api("/projects/#{public_project.id}/milestones/#{milestone.id}/issues", user)
expect(response).to have_http_status(200)
@@ -299,8 +317,8 @@ describe API::Milestones do
end
describe 'GET /projects/:id/milestones/:milestone_id/merge_requests' do
- let(:merge_request) { create(:merge_request, source_project: project, position: 2) }
- let(:another_merge_request) { create(:merge_request, :simple, source_project: project, position: 1) }
+ let(:merge_request) { create(:merge_request, source_project: project) }
+ let(:another_merge_request) { create(:merge_request, :simple, source_project: project) }
before do
milestone.merge_requests << merge_request
@@ -318,6 +336,18 @@ describe API::Milestones do
expect(json_response.first['milestone']['title']).to eq(milestone.title)
end
+ it 'returns project merge_requests sorted by label priority' do
+ merge_request_1 = create(:labeled_merge_request, source_branch: 'branch_1', source_project: project, milestone: milestone, labels: [label_2])
+ merge_request_2 = create(:labeled_merge_request, source_branch: 'branch_2', source_project: project, milestone: milestone, labels: [label_1])
+ merge_request_3 = create(:labeled_merge_request, source_branch: 'branch_3', source_project: project, milestone: milestone, labels: [label_3])
+
+ get api("/projects/#{project.id}/milestones/#{milestone.id}/merge_requests", user)
+
+ expect(json_response.first['id']).to eq(merge_request_2.id)
+ expect(json_response.second['id']).to eq(merge_request_1.id)
+ expect(json_response.third['id']).to eq(merge_request_3.id)
+ end
+
it 'returns a 404 error if milestone id not found' do
get api("/projects/#{project.id}/milestones/1234/merge_requests", user)
@@ -339,6 +369,8 @@ describe API::Milestones do
it 'returns merge_requests ordered by position asc' do
milestone.merge_requests << another_merge_request
+ another_merge_request.labels << label_1
+ merge_request.labels << label_2
get api("/projects/#{project.id}/milestones/#{milestone.id}/merge_requests", user)
diff --git a/spec/requests/api/notes_spec.rb b/spec/requests/api/notes_spec.rb
index 03f2b5950ee..4701ad585c9 100644
--- a/spec/requests/api/notes_spec.rb
+++ b/spec/requests/api/notes_spec.rb
@@ -13,8 +13,8 @@ describe API::Notes do
# For testing the cross-reference of a private issue in a public issue
let(:private_user) { create(:user) }
let(:private_project) do
- create(:empty_project, namespace: private_user.namespace).
- tap { |p| p.team << [private_user, :master] }
+ create(:empty_project, namespace: private_user.namespace)
+ .tap { |p| p.team << [private_user, :master] }
end
let(:private_issue) { create(:issue, project: private_project) }
diff --git a/spec/requests/api/project_snippets_spec.rb b/spec/requests/api/project_snippets_spec.rb
index 4d4631322b1..518639f45a2 100644
--- a/spec/requests/api/project_snippets_spec.rb
+++ b/spec/requests/api/project_snippets_spec.rb
@@ -102,23 +102,23 @@ describe API::ProjectSnippets do
context 'when the snippet is private' do
it 'creates the snippet' do
- expect { create_snippet(project, visibility: 'private') }.
- to change { Snippet.count }.by(1)
+ expect { create_snippet(project, visibility: 'private') }
+ .to change { Snippet.count }.by(1)
end
end
context 'when the snippet is public' do
it 'rejects the snippet' do
- expect { create_snippet(project, visibility: 'public') }.
- not_to change { Snippet.count }
+ expect { create_snippet(project, visibility: 'public') }
+ .not_to change { Snippet.count }
expect(response).to have_http_status(400)
expect(json_response['message']).to eq({ "error" => "Spam detected" })
end
it 'creates a spam log' do
- expect { create_snippet(project, visibility: 'public') }.
- to change { SpamLog.count }.by(1)
+ expect { create_snippet(project, visibility: 'public') }
+ .to change { SpamLog.count }.by(1)
end
end
end
@@ -166,8 +166,8 @@ describe API::ProjectSnippets do
let(:visibility_level) { Snippet::PRIVATE }
it 'creates the snippet' do
- expect { update_snippet(title: 'Foo') }.
- to change { snippet.reload.title }.to('Foo')
+ expect { update_snippet(title: 'Foo') }
+ .to change { snippet.reload.title }.to('Foo')
end
end
@@ -175,13 +175,13 @@ describe API::ProjectSnippets do
let(:visibility_level) { Snippet::PUBLIC }
it 'rejects the snippet' do
- expect { update_snippet(title: 'Foo') }.
- not_to change { snippet.reload.title }
+ expect { update_snippet(title: 'Foo') }
+ .not_to change { snippet.reload.title }
end
it 'creates a spam log' do
- expect { update_snippet(title: 'Foo') }.
- to change { SpamLog.count }.by(1)
+ expect { update_snippet(title: 'Foo') }
+ .to change { SpamLog.count }.by(1)
end
end
@@ -189,16 +189,16 @@ describe API::ProjectSnippets do
let(:visibility_level) { Snippet::PRIVATE }
it 'rejects the snippet' do
- expect { update_snippet(title: 'Foo', visibility: 'public') }.
- not_to change { snippet.reload.title }
+ expect { update_snippet(title: 'Foo', visibility: 'public') }
+ .not_to change { snippet.reload.title }
expect(response).to have_http_status(400)
expect(json_response['message']).to eq({ "error" => "Spam detected" })
end
it 'creates a spam log' do
- expect { update_snippet(title: 'Foo', visibility: 'public') }.
- to change { SpamLog.count }.by(1)
+ expect { update_snippet(title: 'Foo', visibility: 'public') }
+ .to change { SpamLog.count }.by(1)
end
end
end
diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb
index d92262a4c99..fd7ff0b9cff 100644
--- a/spec/requests/api/projects_spec.rb
+++ b/spec/requests/api/projects_spec.rb
@@ -288,15 +288,15 @@ describe API::Projects do
context 'maximum number of projects reached' do
it 'does not create new project and respond with 403' 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 { post api('/projects', user2), name: 'foo' }
+ .to change {Project.count}.by(0)
expect(response).to have_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 { post api('/projects', user), name: 'Foo Project' }
+ .to change { Project.count }.by(1)
expect(response).to have_http_status(201)
project = Project.first
@@ -306,8 +306,8 @@ describe API::Projects do
end
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 { post api('/projects', user), path: 'foo_project' }
+ .to change { Project.count }.by(1)
expect(response).to have_http_status(201)
project = Project.first
@@ -317,8 +317,8 @@ describe API::Projects do
end
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 { post api('/projects', user), path: 'path-project-Foo', name: 'Foo Project' }
+ .to change { Project.count }.by(1)
expect(response).to have_http_status(201)
project = Project.first
@@ -491,8 +491,8 @@ describe API::Projects do
end
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 { 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)
project = Project.first
@@ -502,8 +502,8 @@ describe API::Projects do
end
it 'responds with 400 on failure and not project' do
- expect { post api("/projects/user/#{user.id}", admin) }.
- not_to change { Project.count }
+ expect { post api("/projects/user/#{user.id}", admin) }
+ .not_to change { Project.count }
expect(response).to have_http_status(400)
expect(json_response['error']).to eq('name is missing')
@@ -740,8 +740,8 @@ describe API::Projects do
get api("/projects", user)
expect(response).to have_http_status(200)
- expect(json_response.first['permissions']['project_access']['access_level']).
- to eq(Gitlab::Access::MASTER)
+ expect(json_response.first['permissions']['project_access']['access_level'])
+ .to eq(Gitlab::Access::MASTER)
expect(json_response.first['permissions']['group_access']).to be_nil
end
end
@@ -752,8 +752,8 @@ describe API::Projects do
get api("/projects/#{project.id}", user)
expect(response).to have_http_status(200)
- expect(json_response['permissions']['project_access']['access_level']).
- to eq(Gitlab::Access::MASTER)
+ expect(json_response['permissions']['project_access']['access_level'])
+ .to eq(Gitlab::Access::MASTER)
expect(json_response['permissions']['group_access']).to be_nil
end
end
@@ -770,8 +770,8 @@ describe API::Projects do
expect(response).to have_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)
+ expect(json_response['permissions']['group_access']['access_level'])
+ .to eq(Gitlab::Access::OWNER)
end
end
end
diff --git a/spec/requests/api/runner_spec.rb b/spec/requests/api/runner_spec.rb
index d554c242916..339a57a1f20 100644
--- a/spec/requests/api/runner_spec.rb
+++ b/spec/requests/api/runner_spec.rb
@@ -414,8 +414,8 @@ describe API::Runner do
context 'when concurrently updating a job' do
before do
- expect_any_instance_of(Ci::Build).to receive(:run!).
- and_raise(ActiveRecord::StaleObjectError.new(nil, nil))
+ expect_any_instance_of(Ci::Build).to receive(:run!)
+ .and_raise(ActiveRecord::StaleObjectError.new(nil, nil))
end
it 'returns a conflict' do
diff --git a/spec/requests/api/snippets_spec.rb b/spec/requests/api/snippets_spec.rb
index 8741cbd4e80..b20a187acfe 100644
--- a/spec/requests/api/snippets_spec.rb
+++ b/spec/requests/api/snippets_spec.rb
@@ -142,23 +142,23 @@ describe API::Snippets do
context 'when the snippet is private' do
it 'creates the snippet' do
- expect { create_snippet(visibility: 'private') }.
- to change { Snippet.count }.by(1)
+ expect { create_snippet(visibility: 'private') }
+ .to change { Snippet.count }.by(1)
end
end
context 'when the snippet is public' do
it 'rejects the shippet' do
- expect { create_snippet(visibility: 'public') }.
- not_to change { Snippet.count }
+ expect { create_snippet(visibility: 'public') }
+ .not_to change { Snippet.count }
expect(response).to have_http_status(400)
expect(json_response['message']).to eq({ "error" => "Spam detected" })
end
it 'creates a spam log' do
- expect { create_snippet(visibility: 'public') }.
- to change { SpamLog.count }.by(1)
+ expect { create_snippet(visibility: 'public') }
+ .to change { SpamLog.count }.by(1)
end
end
end
@@ -216,8 +216,8 @@ describe API::Snippets do
let(:visibility_level) { Snippet::PRIVATE }
it 'updates the snippet' do
- expect { update_snippet(title: 'Foo') }.
- to change { snippet.reload.title }.to('Foo')
+ expect { update_snippet(title: 'Foo') }
+ .to change { snippet.reload.title }.to('Foo')
end
end
@@ -225,16 +225,16 @@ describe API::Snippets do
let(:visibility_level) { Snippet::PUBLIC }
it 'rejects the shippet' do
- expect { update_snippet(title: 'Foo') }.
- not_to change { snippet.reload.title }
+ expect { update_snippet(title: 'Foo') }
+ .not_to change { snippet.reload.title }
expect(response).to have_http_status(400)
expect(json_response['message']).to eq({ "error" => "Spam detected" })
end
it 'creates a spam log' do
- expect { update_snippet(title: 'Foo') }.
- to change { SpamLog.count }.by(1)
+ expect { update_snippet(title: 'Foo') }
+ .to change { SpamLog.count }.by(1)
end
end
@@ -242,13 +242,13 @@ describe API::Snippets do
let(:visibility_level) { Snippet::PRIVATE }
it 'rejects the snippet' do
- expect { update_snippet(title: 'Foo', visibility: 'public') }.
- not_to change { snippet.reload.title }
+ expect { update_snippet(title: 'Foo', visibility: 'public') }
+ .not_to change { snippet.reload.title }
end
it 'creates a spam log' do
- expect { update_snippet(title: 'Foo', visibility: 'public') }.
- to change { SpamLog.count }.by(1)
+ expect { update_snippet(title: 'Foo', visibility: 'public') }
+ .to change { SpamLog.count }.by(1)
end
end
end
diff --git a/spec/requests/api/users_spec.rb b/spec/requests/api/users_spec.rb
index 9dc4b6972a6..18000d91795 100644
--- a/spec/requests/api/users_spec.rb
+++ b/spec/requests/api/users_spec.rb
@@ -11,7 +11,7 @@ describe API::Users do
let(:not_existing_user_id) { (User.maximum('id') || 0 ) + 10 }
let(:not_existing_pat_id) { (PersonalAccessToken.maximum('id') || 0 ) + 10 }
- describe "GET /users" do
+ describe 'GET /users' do
context "when unauthenticated" do
it "returns authentication error" do
get api("/users")
@@ -76,6 +76,12 @@ describe API::Users do
expect(response).to have_http_status(403)
end
+
+ it 'does not reveal the `is_admin` flag of the user' do
+ get api('/users', user)
+
+ expect(json_response.first.keys).not_to include 'is_admin'
+ end
end
context "when admin" do
@@ -92,6 +98,7 @@ describe API::Users do
expect(json_response.first.keys).to include 'two_factor_enabled'
expect(json_response.first.keys).to include 'last_sign_in_at'
expect(json_response.first.keys).to include 'confirmed_at'
+ expect(json_response.first.keys).to include 'is_admin'
end
it "returns an array of external users" do
@@ -282,14 +289,14 @@ describe API::Users do
bio: 'g' * 256,
projects_limit: -1
expect(response).to have_http_status(400)
- expect(json_response['message']['password']).
- to eq(['is too short (minimum is 8 characters)'])
- expect(json_response['message']['bio']).
- to eq(['is too long (maximum is 255 characters)'])
- expect(json_response['message']['projects_limit']).
- to eq(['must be greater than or equal to 0'])
- expect(json_response['message']['username']).
- to eq([Gitlab::PathRegex.namespace_format_message])
+ expect(json_response['message']['password'])
+ .to eq(['is too short (minimum is 8 characters)'])
+ expect(json_response['message']['bio'])
+ .to eq(['is too long (maximum is 255 characters)'])
+ expect(json_response['message']['projects_limit'])
+ .to eq(['must be greater than or equal to 0'])
+ expect(json_response['message']['username'])
+ .to eq([Gitlab::PathRegex.namespace_format_message])
end
it "is not available for non admin users" do
@@ -377,6 +384,16 @@ describe API::Users do
expect(user.reload.organization).to eq('GitLab')
end
+ it 'updates user with avatar' do
+ put api("/users/#{user.id}", admin), { avatar: fixture_file_upload(Rails.root + 'spec/fixtures/banana_sample.gif', 'image/gif') }
+
+ user.reload
+
+ expect(user.avatar).to be_present
+ expect(response).to have_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)
@@ -461,14 +478,14 @@ describe API::Users do
bio: 'g' * 256,
projects_limit: -1
expect(response).to have_http_status(400)
- expect(json_response['message']['password']).
- to eq(['is too short (minimum is 8 characters)'])
- expect(json_response['message']['bio']).
- to eq(['is too long (maximum is 255 characters)'])
- expect(json_response['message']['projects_limit']).
- to eq(['must be greater than or equal to 0'])
- expect(json_response['message']['username']).
- to eq([Gitlab::PathRegex.namespace_format_message])
+ expect(json_response['message']['password'])
+ .to eq(['is too short (minimum is 8 characters)'])
+ expect(json_response['message']['bio'])
+ .to eq(['is too long (maximum is 255 characters)'])
+ expect(json_response['message']['projects_limit'])
+ .to eq(['must be greater than or equal to 0'])
+ expect(json_response['message']['username'])
+ .to eq([Gitlab::PathRegex.namespace_format_message])
end
it 'returns 400 if provider is missing for identity update' do
diff --git a/spec/requests/api/v3/files_spec.rb b/spec/requests/api/v3/files_spec.rb
index 378ca1720ff..8b2d165c763 100644
--- a/spec/requests/api/v3/files_spec.rb
+++ b/spec/requests/api/v3/files_spec.rb
@@ -126,8 +126,8 @@ describe API::V3::Files do
end
it "returns a 400 if editor fails to create file" do
- allow_any_instance_of(Repository).to receive(:create_file).
- and_raise(Repository::CommitError, 'Cannot create file')
+ allow_any_instance_of(Repository).to receive(:create_file)
+ .and_raise(Repository::CommitError, 'Cannot create file')
post v3_api("/projects/#{project.id}/repository/files", user), valid_params
diff --git a/spec/requests/api/v3/groups_spec.rb b/spec/requests/api/v3/groups_spec.rb
index 98e8c954909..63c5707b2e4 100644
--- a/spec/requests/api/v3/groups_spec.rb
+++ b/spec/requests/api/v3/groups_spec.rb
@@ -505,8 +505,8 @@ describe API::V3::Groups do
let(:project_path) { "#{project.namespace.path}%2F#{project.path}" }
before(:each) do
- allow_any_instance_of(Projects::TransferService).
- to receive(:execute).and_return(true)
+ allow_any_instance_of(Projects::TransferService)
+ .to receive(:execute).and_return(true)
end
context "when authenticated as user" do
diff --git a/spec/requests/api/v3/merge_requests_spec.rb b/spec/requests/api/v3/merge_requests_spec.rb
index f6ff96be566..4f9e63f2ace 100644
--- a/spec/requests/api/v3/merge_requests_spec.rb
+++ b/spec/requests/api/v3/merge_requests_spec.rb
@@ -432,8 +432,8 @@ describe API::MergeRequests do
end
it "returns 406 if branch can't be merged" do
- allow_any_instance_of(MergeRequest).
- to receive(:can_be_merged?).and_return(false)
+ allow_any_instance_of(MergeRequest)
+ .to receive(:can_be_merged?).and_return(false)
put v3_api("/projects/#{project.id}/merge_requests/#{merge_request.id}/merge", user)
diff --git a/spec/requests/api/v3/notes_spec.rb b/spec/requests/api/v3/notes_spec.rb
index 2bae4a60931..b5f98a9a545 100644
--- a/spec/requests/api/v3/notes_spec.rb
+++ b/spec/requests/api/v3/notes_spec.rb
@@ -13,8 +13,8 @@ describe API::V3::Notes do
# For testing the cross-reference of a private issue in a public issue
let(:private_user) { create(:user) }
let(:private_project) do
- create(:empty_project, namespace: private_user.namespace).
- tap { |p| p.team << [private_user, :master] }
+ create(:empty_project, namespace: private_user.namespace)
+ .tap { |p| p.team << [private_user, :master] }
end
let(:private_issue) { create(:issue, project: private_project) }
diff --git a/spec/requests/api/v3/project_snippets_spec.rb b/spec/requests/api/v3/project_snippets_spec.rb
index 365e7365fda..1950c64c690 100644
--- a/spec/requests/api/v3/project_snippets_spec.rb
+++ b/spec/requests/api/v3/project_snippets_spec.rb
@@ -85,23 +85,23 @@ describe API::ProjectSnippets do
context 'when the snippet is private' do
it 'creates the snippet' do
- expect { create_snippet(project, visibility_level: Snippet::PRIVATE) }.
- to change { Snippet.count }.by(1)
+ expect { create_snippet(project, visibility_level: Snippet::PRIVATE) }
+ .to change { Snippet.count }.by(1)
end
end
context 'when the snippet is public' do
it 'rejects the shippet' do
- expect { create_snippet(project, visibility_level: Snippet::PUBLIC) }.
- not_to change { Snippet.count }
+ expect { create_snippet(project, visibility_level: Snippet::PUBLIC) }
+ .not_to change { Snippet.count }
expect(response).to have_http_status(400)
expect(json_response['message']).to eq({ "error" => "Spam detected" })
end
it 'creates a spam log' do
- expect { create_snippet(project, visibility_level: Snippet::PUBLIC) }.
- to change { SpamLog.count }.by(1)
+ expect { create_snippet(project, visibility_level: Snippet::PUBLIC) }
+ .to change { SpamLog.count }.by(1)
end
end
end
@@ -147,8 +147,8 @@ describe API::ProjectSnippets do
let(:visibility_level) { Snippet::PRIVATE }
it 'creates the snippet' do
- expect { update_snippet(title: 'Foo') }.
- to change { snippet.reload.title }.to('Foo')
+ expect { update_snippet(title: 'Foo') }
+ .to change { snippet.reload.title }.to('Foo')
end
end
@@ -156,13 +156,13 @@ describe API::ProjectSnippets do
let(:visibility_level) { Snippet::PUBLIC }
it 'rejects the snippet' do
- expect { update_snippet(title: 'Foo') }.
- not_to change { snippet.reload.title }
+ expect { update_snippet(title: 'Foo') }
+ .not_to change { snippet.reload.title }
end
it 'creates a spam log' do
- expect { update_snippet(title: 'Foo') }.
- to change { SpamLog.count }.by(1)
+ expect { update_snippet(title: 'Foo') }
+ .to change { SpamLog.count }.by(1)
end
end
@@ -170,16 +170,16 @@ describe API::ProjectSnippets do
let(:visibility_level) { Snippet::PRIVATE }
it 'rejects the snippet' do
- expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) }.
- not_to change { snippet.reload.title }
+ expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) }
+ .not_to change { snippet.reload.title }
expect(response).to have_http_status(400)
expect(json_response['message']).to eq({ "error" => "Spam detected" })
end
it 'creates a spam log' do
- expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) }.
- to change { SpamLog.count }.by(1)
+ expect { update_snippet(title: 'Foo', visibility_level: Snippet::PUBLIC) }
+ .to change { SpamLog.count }.by(1)
end
end
end
diff --git a/spec/requests/api/v3/projects_spec.rb b/spec/requests/api/v3/projects_spec.rb
index 47cca4275af..cb74868324c 100644
--- a/spec/requests/api/v3/projects_spec.rb
+++ b/spec/requests/api/v3/projects_spec.rb
@@ -124,6 +124,36 @@ describe API::V3::Projects do
end
end
+ context 'and using archived' do
+ let!(:archived_project) { create(:empty_project, creator_id: user.id, namespace: user.namespace, archived: true) }
+
+ it 'returns archived project' do
+ get v3_api('/projects?archived=true', user)
+
+ expect(response).to have_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)
+ end
+
+ it 'returns non-archived project' do
+ get v3_api('/projects?archived=false', user)
+
+ expect(response).to have_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)
+ end
+
+ it 'returns all project' do
+ get v3_api('/projects', user)
+
+ expect(response).to have_http_status(200)
+ expect(json_response).to be_an Array
+ expect(json_response.length).to eq(2)
+ end
+ end
+
context 'and using sorting' do
before do
project2
@@ -301,15 +331,15 @@ describe API::V3::Projects do
context 'maximum number of projects reached' do
it 'does not create new project and respond with 403' 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 { post v3_api('/projects', user2), name: 'foo' }
+ .to change {Project.count}.by(0)
expect(response).to have_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 { post v3_api('/projects', user), name: 'Foo Project' }
+ .to change { Project.count }.by(1)
expect(response).to have_http_status(201)
project = Project.first
@@ -319,8 +349,8 @@ describe API::V3::Projects do
end
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 { post v3_api('/projects', user), path: 'foo_project' }
+ .to change { Project.count }.by(1)
expect(response).to have_http_status(201)
project = Project.first
@@ -330,8 +360,8 @@ describe API::V3::Projects do
end
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 { post v3_api('/projects', user), path: 'foo-Project', name: 'Foo Project' }
+ .to change { Project.count }.by(1)
expect(response).to have_http_status(201)
project = Project.first
@@ -489,8 +519,8 @@ describe API::V3::Projects do
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 { post v3_api("/projects/user/#{user.id}", admin) }
+ .not_to change { Project.count }
expect(response).to have_http_status(400)
expect(json_response['error']).to eq('name is missing')
@@ -716,8 +746,8 @@ describe API::V3::Projects do
get v3_api("/projects", user)
expect(response).to have_http_status(200)
- expect(json_response.first['permissions']['project_access']['access_level']).
- to eq(Gitlab::Access::MASTER)
+ expect(json_response.first['permissions']['project_access']['access_level'])
+ .to eq(Gitlab::Access::MASTER)
expect(json_response.first['permissions']['group_access']).to be_nil
end
end
@@ -728,8 +758,8 @@ describe API::V3::Projects do
get v3_api("/projects/#{project.id}", user)
expect(response).to have_http_status(200)
- expect(json_response['permissions']['project_access']['access_level']).
- to eq(Gitlab::Access::MASTER)
+ expect(json_response['permissions']['project_access']['access_level'])
+ .to eq(Gitlab::Access::MASTER)
expect(json_response['permissions']['group_access']).to be_nil
end
end
@@ -744,8 +774,8 @@ describe API::V3::Projects do
expect(response).to have_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)
+ expect(json_response['permissions']['group_access']['access_level'])
+ .to eq(Gitlab::Access::OWNER)
end
end
end
diff --git a/spec/requests/api/v3/snippets_spec.rb b/spec/requests/api/v3/snippets_spec.rb
index 4f02b7b1a54..1bc2258ebd3 100644
--- a/spec/requests/api/v3/snippets_spec.rb
+++ b/spec/requests/api/v3/snippets_spec.rb
@@ -112,21 +112,21 @@ describe API::V3::Snippets do
context 'when the snippet is private' do
it 'creates the snippet' do
- expect { create_snippet(visibility_level: Snippet::PRIVATE) }.
- to change { Snippet.count }.by(1)
+ expect { create_snippet(visibility_level: Snippet::PRIVATE) }
+ .to change { Snippet.count }.by(1)
end
end
context 'when the snippet is public' do
it 'rejects the shippet' do
- expect { create_snippet(visibility_level: Snippet::PUBLIC) }.
- not_to change { Snippet.count }
+ expect { create_snippet(visibility_level: Snippet::PUBLIC) }
+ .not_to change { Snippet.count }
expect(response).to have_http_status(400)
end
it 'creates a spam log' do
- expect { create_snippet(visibility_level: Snippet::PUBLIC) }.
- to change { SpamLog.count }.by(1)
+ expect { create_snippet(visibility_level: Snippet::PUBLIC) }
+ .to change { SpamLog.count }.by(1)
end
end
end
diff --git a/spec/requests/api/v3/users_spec.rb b/spec/requests/api/v3/users_spec.rb
index e9c57f7c6c3..6d7401f9764 100644
--- a/spec/requests/api/v3/users_spec.rb
+++ b/spec/requests/api/v3/users_spec.rb
@@ -7,6 +7,38 @@ describe API::V3::Users do
let(:email) { create(:email, user: user) }
let(:ldap_blocked_user) { create(:omniauth_user, provider: 'ldapmain', state: 'ldap_blocked') }
+ describe 'GET /users' do
+ context 'when authenticated' do
+ it 'returns an array of users' do
+ get v3_api('/users', user)
+
+ expect(response).to have_http_status(200)
+ expect(response).to include_pagination_headers
+ expect(json_response).to be_an Array
+ username = user.username
+ expect(json_response.detect do |user|
+ user['username'] == username
+ end['username']).to eq(username)
+ end
+ end
+
+ context 'when authenticated as user' do
+ it 'does not reveal the `is_admin` flag of the user' do
+ get v3_api('/users', user)
+
+ expect(json_response.first.keys).not_to include 'is_admin'
+ end
+ end
+
+ context 'when authenticated as admin' do
+ it 'reveals the `is_admin` flag of the user' do
+ get v3_api('/users', admin)
+
+ expect(json_response.first.keys).to include 'is_admin'
+ end
+ end
+ end
+
describe 'GET /user/:id/keys' do
before { admin }
diff --git a/spec/requests/ci/api/builds_spec.rb b/spec/requests/ci/api/builds_spec.rb
index 83c675792f4..c969d08d0dd 100644
--- a/spec/requests/ci/api/builds_spec.rb
+++ b/spec/requests/ci/api/builds_spec.rb
@@ -91,8 +91,8 @@ describe Ci::API::Builds do
context 'when concurrently updating build' do
before do
- expect_any_instance_of(Ci::Build).to receive(:run!).
- and_raise(ActiveRecord::StaleObjectError.new(nil, nil))
+ expect_any_instance_of(Ci::Build).to receive(:run!)
+ .and_raise(ActiveRecord::StaleObjectError.new(nil, nil))
end
it 'returns a conflict' do
@@ -670,8 +670,8 @@ describe Ci::API::Builds do
build.reload
expect(response).to have_http_status(201)
expect(json_response['artifacts_expire_at']).not_to be_empty
- expect(build.artifacts_expire_at).
- to be_within(5.minutes).of(7.days.from_now)
+ expect(build.artifacts_expire_at)
+ .to be_within(5.minutes).of(7.days.from_now)
end
end
diff --git a/spec/requests/git_http_spec.rb b/spec/requests/git_http_spec.rb
index dce78faefc9..185679e1a0f 100644
--- a/spec/requests/git_http_spec.rb
+++ b/spec/requests/git_http_spec.rb
@@ -316,6 +316,26 @@ describe 'Git HTTP requests', lib: true do
it_behaves_like 'pushes require Basic HTTP Authentication'
end
end
+
+ context 'and the user requests a redirected path' do
+ let!(:redirect) { project.route.create_redirect('foo/bar') }
+ let(:path) { "#{redirect.path}.git" }
+ let(:project_moved_message) do
+ <<-MSG.strip_heredoc
+ Project '#{redirect.path}' was moved to '#{project.full_path}'.
+
+ Please update your Git remote and try again:
+
+ git remote set-url origin #{project.http_url_to_repo}
+ MSG
+ end
+
+ it 'downloads get status 404 with "project was moved" message' do
+ clone_get(path, {})
+ expect(response).to have_http_status(:not_found)
+ expect(response.body).to match(project_moved_message)
+ end
+ end
end
context "when the project is private" do
@@ -463,8 +483,8 @@ describe 'Git HTTP requests', lib: true do
context 'when LDAP is configured' do
before do
allow(Gitlab::LDAP::Config).to receive(:enabled?).and_return(true)
- allow_any_instance_of(Gitlab::LDAP::Authentication).
- to receive(:login).and_return(nil)
+ allow_any_instance_of(Gitlab::LDAP::Authentication)
+ .to receive(:login).and_return(nil)
end
it 'does not display the personal access token error message' do
@@ -505,6 +525,33 @@ describe 'Git HTTP requests', lib: true do
Rack::Attack::Allow2Ban.reset(ip, options)
end
end
+
+ context 'and the user requests a redirected path' do
+ let!(:redirect) { project.route.create_redirect('foo/bar') }
+ let(:path) { "#{redirect.path}.git" }
+ let(:project_moved_message) do
+ <<-MSG.strip_heredoc
+ Project '#{redirect.path}' was moved to '#{project.full_path}'.
+
+ Please update your Git remote and try again:
+
+ git remote set-url origin #{project.http_url_to_repo}
+ MSG
+ end
+
+ 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.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.body).to match(project_moved_message)
+ end
+ end
+ end
end
context "when the user doesn't have access to the project" do
@@ -680,7 +727,7 @@ describe 'Git HTTP requests', lib: true do
end
context "POST git-receive-pack" do
- it "failes to find a route" do
+ it "fails to find a route" do
expect { push_post(project.path_with_namespace) }.to raise_error(ActionController::RoutingError)
end
end
diff --git a/spec/rubocop/cop/migration/update_column_in_batches_spec.rb b/spec/rubocop/cop/migration/update_column_in_batches_spec.rb
index 968dcd6232e..38b8f439a55 100644
--- a/spec/rubocop/cop/migration/update_column_in_batches_spec.rb
+++ b/spec/rubocop/cop/migration/update_column_in_batches_spec.rb
@@ -54,8 +54,8 @@ describe RuboCop::Cop::Migration::UpdateColumnInBatches do
aggregate_failures do
expect(cop.offenses.size).to eq(1)
expect(cop.offenses.map(&:line)).to eq([2])
- expect(cop.offenses.first.message).
- to include("`#{relative_spec_filepath}`")
+ expect(cop.offenses.first.message)
+ .to include("`#{relative_spec_filepath}`")
end
end
end
diff --git a/spec/services/create_deployment_service_spec.rb b/spec/services/create_deployment_service_spec.rb
index 6cf4342ad4c..dfab6ebf372 100644
--- a/spec/services/create_deployment_service_spec.rb
+++ b/spec/services/create_deployment_service_spec.rb
@@ -122,6 +122,61 @@ describe CreateDeploymentService, services: true do
end
end
+ describe '#expanded_environment_url' do
+ subject { service.send(:expanded_environment_url) }
+
+ context 'when yaml environment uses $CI_COMMIT_REF_NAME' do
+ let(:job) do
+ create(:ci_build,
+ ref: 'master',
+ options: { environment: { url: 'http://review/$CI_COMMIT_REF_NAME' } })
+ end
+
+ it { is_expected.to eq('http://review/master') }
+ end
+
+ context 'when yaml environment uses $CI_ENVIRONMENT_SLUG' do
+ let(:job) do
+ create(:ci_build,
+ ref: 'master',
+ environment: 'production',
+ options: { environment: { url: 'http://review/$CI_ENVIRONMENT_SLUG' } })
+ end
+
+ let!(:environment) do
+ create(:environment,
+ project: job.project,
+ name: 'production',
+ slug: 'prod-slug',
+ external_url: 'http://review/old')
+ end
+
+ it { is_expected.to eq('http://review/prod-slug') }
+ end
+
+ context 'when yaml environment uses yaml_variables containing symbol keys' do
+ let(:job) do
+ create(:ci_build,
+ yaml_variables: [{ key: :APP_HOST, value: 'host' }],
+ options: { environment: { url: 'http://review/$APP_HOST' } })
+ end
+
+ it { is_expected.to eq('http://review/host') }
+ end
+
+ context 'when yaml environment does not have url' do
+ let(:job) { create(:ci_build, environment: 'staging') }
+
+ let!(:environment) do
+ create(:environment, project: job.project, name: job.environment)
+ end
+
+ it 'returns the external_url from persisted environment' do
+ is_expected.to be_nil
+ end
+ end
+ end
+
describe 'processing of builds' do
shared_examples 'does not create deployment' do
it 'does not create a new deployment' do
diff --git a/spec/services/files/update_service_spec.rb b/spec/services/files/update_service_spec.rb
index 16bca66766a..cc950ae6bb3 100644
--- a/spec/services/files/update_service_spec.rb
+++ b/spec/services/files/update_service_spec.rb
@@ -32,8 +32,8 @@ describe Files::UpdateService do
let(:last_commit_sha) { "foo" }
it "returns a hash with the correct error message and a :error status " do
- expect { subject.execute }.
- to raise_error(Files::UpdateService::FileChangedError,
+ expect { subject.execute }
+ .to raise_error(Files::UpdateService::FileChangedError,
"You are attempting to update a file that has changed since you started editing it.")
end
end
diff --git a/spec/services/git_push_service_spec.rb b/spec/services/git_push_service_spec.rb
index bcd1fb64ab9..ca827fc0f39 100644
--- a/spec/services/git_push_service_spec.rb
+++ b/spec/services/git_push_service_spec.rb
@@ -158,8 +158,8 @@ describe GitPushService, services: true do
context "Updates merge requests" do
it "when pushing a new branch for the first time" do
- expect(UpdateMergeRequestsWorker).to receive(:perform_async).
- with(project.id, user.id, @blankrev, 'newrev', 'refs/heads/master')
+ expect(UpdateMergeRequestsWorker).to receive(:perform_async)
+ .with(project.id, user.id, @blankrev, 'newrev', 'refs/heads/master')
execute_service(project, user, @blankrev, 'newrev', 'refs/heads/master' )
end
end
@@ -283,8 +283,8 @@ describe GitPushService, services: true do
author_email: commit_author.email
)
- allow_any_instance_of(ProcessCommitWorker).to receive(:build_commit).
- and_return(commit)
+ allow_any_instance_of(ProcessCommitWorker).to receive(:build_commit)
+ .and_return(commit)
allow(project.repository).to receive(:commits_between).and_return([commit])
end
@@ -341,8 +341,8 @@ describe GitPushService, services: true do
committed_date: commit_time
)
- allow_any_instance_of(ProcessCommitWorker).to receive(:build_commit).
- and_return(commit)
+ allow_any_instance_of(ProcessCommitWorker).to receive(:build_commit)
+ .and_return(commit)
allow(project.repository).to receive(:commits_between).and_return([commit])
end
@@ -377,11 +377,11 @@ describe GitPushService, services: true do
author_email: commit_author.email
)
- allow(project.repository).to receive(:commits_between).
- and_return([closing_commit])
+ allow(project.repository).to receive(:commits_between)
+ .and_return([closing_commit])
- allow_any_instance_of(ProcessCommitWorker).to receive(:build_commit).
- and_return(closing_commit)
+ allow_any_instance_of(ProcessCommitWorker).to receive(:build_commit)
+ .and_return(closing_commit)
project.team << [commit_author, :master]
end
@@ -403,8 +403,8 @@ describe GitPushService, services: true do
end
it "doesn't close issues when external issue tracker is in use" do
- allow_any_instance_of(Project).to receive(:default_issues_tracker?).
- and_return(false)
+ allow_any_instance_of(Project).to receive(:default_issues_tracker?)
+ .and_return(false)
external_issue_tracker = double(title: 'My Tracker', issue_path: issue.iid, reference_pattern: project.issue_reference_pattern)
allow_any_instance_of(Project).to receive(:external_issue_tracker).and_return(external_issue_tracker)
@@ -598,13 +598,13 @@ describe GitPushService, services: true do
commit = double(:commit)
diff = double(:diff, new_path: 'README.md')
- expect(commit).to receive(:raw_deltas).
- and_return([diff])
+ expect(commit).to receive(:raw_deltas)
+ .and_return([diff])
service.push_commits = [commit]
- expect(ProjectCacheWorker).to receive(:perform_async).
- with(project.id, %i(readme), %i(commit_count repository_size))
+ expect(ProjectCacheWorker).to receive(:perform_async)
+ .with(project.id, %i(readme), %i(commit_count repository_size))
service.update_caches
end
@@ -616,9 +616,9 @@ describe GitPushService, services: true do
end
it 'does not flush any conditional caches' do
- expect(ProjectCacheWorker).to receive(:perform_async).
- with(project.id, [], %i(commit_count repository_size)).
- and_call_original
+ expect(ProjectCacheWorker).to receive(:perform_async)
+ .with(project.id, [], %i(commit_count repository_size))
+ .and_call_original
service.update_caches
end
@@ -635,8 +635,8 @@ describe GitPushService, services: true do
end
it 'only schedules a limited number of commits' do
- allow(service).to receive(:push_commits).
- and_return(Array.new(1000, double(:commit, to_hash: {}, matches_cross_reference_regex?: true)))
+ allow(service).to receive(:push_commits)
+ .and_return(Array.new(1000, double(:commit, to_hash: {}, matches_cross_reference_regex?: true)))
expect(ProcessCommitWorker).to receive(:perform_async).exactly(100).times
@@ -644,8 +644,8 @@ describe GitPushService, services: true do
end
it "skips commits which don't include cross-references" do
- allow(service).to receive(:push_commits).
- and_return([double(:commit, to_hash: {}, matches_cross_reference_regex?: false)])
+ allow(service).to receive(:push_commits)
+ .and_return([double(:commit, to_hash: {}, matches_cross_reference_regex?: false)])
expect(ProcessCommitWorker).not_to receive(:perform_async)
diff --git a/spec/services/issues/close_service_spec.rb b/spec/services/issues/close_service_spec.rb
index be0e829880e..d6f4c694069 100644
--- a/spec/services/issues/close_service_spec.rb
+++ b/spec/services/issues/close_service_spec.rb
@@ -18,26 +18,26 @@ describe Issues::CloseService, services: true do
let(:service) { described_class.new(project, user) }
it 'checks if the user is authorized to update the issue' do
- expect(service).to receive(:can?).with(user, :update_issue, issue).
- and_call_original
+ expect(service).to receive(:can?).with(user, :update_issue, issue)
+ .and_call_original
service.execute(issue)
end
it 'does not close the issue when the user is not authorized to do so' do
- allow(service).to receive(:can?).with(user, :update_issue, issue).
- and_return(false)
+ allow(service).to receive(:can?).with(user, :update_issue, issue)
+ .and_return(false)
expect(service).not_to receive(:close_issue)
expect(service.execute(issue)).to eq(issue)
end
it 'closes the issue when the user is authorized to do so' do
- allow(service).to receive(:can?).with(user, :update_issue, issue).
- and_return(true)
+ allow(service).to receive(:can?).with(user, :update_issue, issue)
+ .and_return(true)
- expect(service).to receive(:close_issue).
- with(issue, commit: nil, notifications: true, system_note: true)
+ expect(service).to receive(:close_issue)
+ .with(issue, commit: nil, notifications: true, system_note: true)
service.execute(issue)
end
diff --git a/spec/services/issues/create_service_spec.rb b/spec/services/issues/create_service_spec.rb
index 370bd352200..ae9d2b2855d 100644
--- a/spec/services/issues/create_service_spec.rb
+++ b/spec/services/issues/create_service_spec.rb
@@ -206,9 +206,9 @@ describe Issues::CreateService, services: true do
end
end
- it_behaves_like 'new issuable record that supports slash commands'
+ it_behaves_like 'new issuable record that supports quick actions'
- context 'Slash commands' do
+ context 'Quick actions' do
context 'with assignee and milestone in params and command' do
let(:opts) do
{
diff --git a/spec/services/labels/promote_service_spec.rb b/spec/services/labels/promote_service_spec.rb
index 4b90ad19640..500afdfb916 100644
--- a/spec/services/labels/promote_service_spec.rb
+++ b/spec/services/labels/promote_service_spec.rb
@@ -66,9 +66,9 @@ describe Labels::PromoteService, services: true do
end
it 'recreates the label as a group label' do
- expect { service.execute(project_label_1_1) }.
- to change(project_1.labels, :count).by(-1).
- and change(group_1.labels, :count).by(1)
+ expect { service.execute(project_label_1_1) }
+ .to change(project_1.labels, :count).by(-1)
+ .and change(group_1.labels, :count).by(1)
expect(new_label).not_to be_nil
end
diff --git a/spec/services/members/destroy_service_spec.rb b/spec/services/members/destroy_service_spec.rb
index 41450c67d7e..9ab7839430c 100644
--- a/spec/services/members/destroy_service_spec.rb
+++ b/spec/services/members/destroy_service_spec.rb
@@ -104,8 +104,8 @@ describe Members::DestroyService, services: true do
let(:params) { { id: project.members.find_by!(user_id: user.id).id } }
it 'destroys the member' do
- expect { described_class.new(project, user, params).execute }.
- to change { project.members.count }.by(-1)
+ expect { described_class.new(project, user, params).execute }
+ .to change { project.members.count }.by(-1)
end
end
end
diff --git a/spec/services/merge_requests/close_service_spec.rb b/spec/services/merge_requests/close_service_spec.rb
index 154f30aac3b..074d4672b06 100644
--- a/spec/services/merge_requests/close_service_spec.rb
+++ b/spec/services/merge_requests/close_service_spec.rb
@@ -32,8 +32,8 @@ describe MergeRequests::CloseService, services: true do
it { expect(@merge_request).to be_closed }
it 'executes hooks with close action' do
- expect(service).to have_received(:execute_hooks).
- with(@merge_request, 'close')
+ expect(service).to have_received(:execute_hooks)
+ .with(@merge_request, 'close')
end
it 'sends email to user2 about assign of new merge_request' do
diff --git a/spec/services/merge_requests/conflicts/resolve_service_spec.rb b/spec/services/merge_requests/conflicts/resolve_service_spec.rb
index c77e6e9cd50..6f49a65d795 100644
--- a/spec/services/merge_requests/conflicts/resolve_service_spec.rb
+++ b/spec/services/merge_requests/conflicts/resolve_service_spec.rb
@@ -64,9 +64,9 @@ describe MergeRequests::Conflicts::ResolveService do
end
it 'creates a commit with the correct parents' do
- expect(merge_request.source_branch_head.parents.map(&:id)).
- to eq(%w(1450cd639e0bc6721eb02800169e464f212cde06
- 824be604a34828eb682305f0d963056cfac87b2d))
+ expect(merge_request.source_branch_head.parents.map(&:id))
+ .to eq(%w(1450cd639e0bc6721eb02800169e464f212cde06
+ 824be604a34828eb682305f0d963056cfac87b2d))
end
end
@@ -129,9 +129,8 @@ describe MergeRequests::Conflicts::ResolveService do
it 'creates a commit with the correct parents' do
resolve_conflicts
- expect(merge_request_from_fork.source_branch_head.parents.map(&:id)).
- to eq(['404fa3fc7c2c9b5dacff102f353bdf55b1be2813',
- target_head])
+ expect(merge_request_from_fork.source_branch_head.parents.map(&:id))
+ .to eq(['404fa3fc7c2c9b5dacff102f353bdf55b1be2813', target_head])
end
end
end
@@ -169,9 +168,9 @@ describe MergeRequests::Conflicts::ResolveService do
end
it 'creates a commit with the correct parents' do
- expect(merge_request.source_branch_head.parents.map(&:id)).
- to eq(%w(1450cd639e0bc6721eb02800169e464f212cde06
- 824be604a34828eb682305f0d963056cfac87b2d))
+ expect(merge_request.source_branch_head.parents.map(&:id))
+ .to eq(%w(1450cd639e0bc6721eb02800169e464f212cde06
+ 824be604a34828eb682305f0d963056cfac87b2d))
end
it 'sets the content to the content given' do
@@ -204,8 +203,8 @@ describe MergeRequests::Conflicts::ResolveService do
end
it 'raises a MissingResolution error' do
- expect { service.execute(user, invalid_params) }.
- to raise_error(Gitlab::Conflict::File::MissingResolution)
+ expect { service.execute(user, invalid_params) }
+ .to raise_error(Gitlab::Conflict::File::MissingResolution)
end
end
@@ -230,8 +229,8 @@ describe MergeRequests::Conflicts::ResolveService do
end
it 'raises a MissingResolution error' do
- expect { service.execute(user, invalid_params) }.
- to raise_error(Gitlab::Conflict::File::MissingResolution)
+ expect { service.execute(user, invalid_params) }
+ .to raise_error(Gitlab::Conflict::File::MissingResolution)
end
end
@@ -250,8 +249,8 @@ describe MergeRequests::Conflicts::ResolveService do
end
it 'raises a MissingFiles error' do
- expect { service.execute(user, invalid_params) }.
- to raise_error(described_class::MissingFiles)
+ expect { service.execute(user, invalid_params) }
+ .to raise_error(described_class::MissingFiles)
end
end
end
diff --git a/spec/services/merge_requests/create_service_spec.rb b/spec/services/merge_requests/create_service_spec.rb
index 13fee953e41..36a2b672473 100644
--- a/spec/services/merge_requests/create_service_spec.rb
+++ b/spec/services/merge_requests/create_service_spec.rb
@@ -83,9 +83,9 @@ describe MergeRequests::CreateService, services: true do
let!(:pipeline_3) { create(:ci_pipeline, project: project, ref: "other_branch", project_id: project.id) }
before do
- project.merge_requests.
- where(source_branch: opts[:source_branch], target_branch: opts[:target_branch]).
- destroy_all
+ project.merge_requests
+ .where(source_branch: opts[:source_branch], target_branch: opts[:target_branch])
+ .destroy_all
end
it 'sets head pipeline' do
@@ -108,7 +108,7 @@ describe MergeRequests::CreateService, services: true do
end
end
- it_behaves_like 'new issuable record that supports slash commands' do
+ it_behaves_like 'new issuable record that supports quick actions' do
let(:default_params) do
{
source_branch: 'feature',
@@ -117,7 +117,7 @@ describe MergeRequests::CreateService, services: true do
end
end
- context 'Slash commands' do
+ context 'Quick actions' do
context 'with assignee and milestone in params and command' do
let(:merge_request) { described_class.new(project, user, opts).execute }
let(:milestone) { create(:milestone, project: project) }
diff --git a/spec/services/merge_requests/merge_service_spec.rb b/spec/services/merge_requests/merge_service_spec.rb
index b3b188a805f..711059208c1 100644
--- a/spec/services/merge_requests/merge_service_spec.rb
+++ b/spec/services/merge_requests/merge_service_spec.rb
@@ -141,9 +141,9 @@ describe MergeRequests::MergeService, services: true do
end
it 'removes the source branch' do
- expect(DeleteBranchService).to receive(:new).
- with(merge_request.source_project, merge_request.author).
- and_call_original
+ expect(DeleteBranchService).to receive(:new)
+ .with(merge_request.source_project, merge_request.author)
+ .and_call_original
service.execute(merge_request)
end
end
diff --git a/spec/services/merge_requests/refresh_service_spec.rb b/spec/services/merge_requests/refresh_service_spec.rb
index 1f109eab268..671a932441e 100644
--- a/spec/services/merge_requests/refresh_service_spec.rb
+++ b/spec/services/merge_requests/refresh_service_spec.rb
@@ -57,8 +57,8 @@ describe MergeRequests::RefreshService, services: true do
end
it 'executes hooks with update action' do
- expect(refresh_service).to have_received(:execute_hooks).
- with(@merge_request, 'update', @oldrev)
+ expect(refresh_service).to have_received(:execute_hooks)
+ .with(@merge_request, 'update', @oldrev)
expect(@merge_request.notes).not_to be_empty
expect(@merge_request).to be_open
@@ -83,8 +83,8 @@ describe MergeRequests::RefreshService, services: true do
end
it 'executes hooks with update action' do
- expect(refresh_service).to have_received(:execute_hooks).
- with(@merge_request, 'update', @oldrev)
+ expect(refresh_service).to have_received(:execute_hooks)
+ .with(@merge_request, 'update', @oldrev)
expect(@merge_request.notes).not_to be_empty
expect(@merge_request).to be_open
@@ -146,8 +146,8 @@ describe MergeRequests::RefreshService, services: true do
end
it 'executes hooks with update action' do
- expect(refresh_service).to have_received(:execute_hooks).
- with(@fork_merge_request, 'update', @oldrev)
+ expect(refresh_service).to have_received(:execute_hooks)
+ .with(@fork_merge_request, 'update', @oldrev)
expect(@merge_request.notes).to be_empty
expect(@merge_request).to be_open
@@ -228,8 +228,8 @@ describe MergeRequests::RefreshService, services: true do
let(:refresh_service) { service.new(@fork_project, @user) }
it 'refreshes the merge request' do
- expect(refresh_service).to receive(:execute_hooks).
- with(@fork_merge_request, 'update', Gitlab::Git::BLANK_SHA)
+ expect(refresh_service).to receive(:execute_hooks)
+ .with(@fork_merge_request, 'update', Gitlab::Git::BLANK_SHA)
allow_any_instance_of(Repository).to receive(:merge_base).and_return(@oldrev)
refresh_service.execute(Gitlab::Git::BLANK_SHA, @newrev, 'refs/heads/master')
diff --git a/spec/services/merge_requests/reopen_service_spec.rb b/spec/services/merge_requests/reopen_service_spec.rb
index b6d4db2f922..6cc403bdb7f 100644
--- a/spec/services/merge_requests/reopen_service_spec.rb
+++ b/spec/services/merge_requests/reopen_service_spec.rb
@@ -31,8 +31,8 @@ describe MergeRequests::ReopenService, services: true do
it { expect(merge_request).to be_reopened }
it 'executes hooks with reopen action' do
- expect(service).to have_received(:execute_hooks).
- with(merge_request, 'reopen')
+ expect(service).to have_received(:execute_hooks)
+ .with(merge_request, 'reopen')
end
it 'sends email to user2 about reopen of merge_request' do
diff --git a/spec/services/merge_requests/update_service_spec.rb b/spec/services/merge_requests/update_service_spec.rb
index fd46020bbdb..ec15b5cac14 100644
--- a/spec/services/merge_requests/update_service_spec.rb
+++ b/spec/services/merge_requests/update_service_spec.rb
@@ -78,8 +78,8 @@ describe MergeRequests::UpdateService, services: true do
end
it 'executes hooks with update action' do
- expect(service).to have_received(:execute_hooks).
- with(@merge_request, 'update')
+ expect(service).to have_received(:execute_hooks)
+ .with(@merge_request, 'update')
end
it 'sends email to user2 about assign of new merge request and email to user3 about merge request unassignment' do
@@ -195,8 +195,8 @@ describe MergeRequests::UpdateService, services: true do
head_pipeline_of: merge_request
)
- expect(MergeRequests::MergeWhenPipelineSucceedsService).to receive(:new).with(project, user).
- and_return(service_mock)
+ expect(MergeRequests::MergeWhenPipelineSucceedsService).to receive(:new).with(project, user)
+ .and_return(service_mock)
expect(service_mock).to receive(:execute).with(merge_request)
end
diff --git a/spec/services/notes/slash_commands_service_spec.rb b/spec/services/notes/quick_actions_service_spec.rb
index d5ffc1908a9..9a98499826f 100644
--- a/spec/services/notes/slash_commands_service_spec.rb
+++ b/spec/services/notes/quick_actions_service_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe Notes::SlashCommandsService, services: true do
+describe Notes::QuickActionsService, services: true do
shared_context 'note on noteable' do
let(:project) { create(:empty_project) }
let(:master) { create(:user).tap { |u| project.team << [u, :master] } }
@@ -11,7 +11,7 @@ describe Notes::SlashCommandsService, services: true do
end
end
- shared_examples 'note on noteable that does not support slash commands' do
+ shared_examples 'note on noteable that does not support quick actions' do
include_context 'note on noteable'
before do
@@ -45,7 +45,7 @@ describe Notes::SlashCommandsService, services: true do
end
end
- shared_examples 'note on noteable that supports slash commands' do
+ shared_examples 'note on noteable that supports quick actions' do
include_context 'note on noteable'
before do
@@ -210,15 +210,15 @@ describe Notes::SlashCommandsService, services: true do
describe '#execute' do
let(:service) { described_class.new(project, master) }
- it_behaves_like 'note on noteable that supports slash commands' do
+ it_behaves_like 'note on noteable that supports quick actions' do
let(:note) { build(:note_on_issue, project: project) }
end
- it_behaves_like 'note on noteable that supports slash commands' do
+ it_behaves_like 'note on noteable that supports quick actions' do
let(:note) { build(:note_on_merge_request, project: project) }
end
- it_behaves_like 'note on noteable that does not support slash commands' do
+ it_behaves_like 'note on noteable that does not support quick actions' do
let(:note) { build(:note_on_commit, project: project) }
end
end
diff --git a/spec/services/preview_markdown_service_spec.rb b/spec/services/preview_markdown_service_spec.rb
index b2fb5c91313..4fd9cb23ae1 100644
--- a/spec/services/preview_markdown_service_spec.rb
+++ b/spec/services/preview_markdown_service_spec.rb
@@ -19,24 +19,24 @@ describe PreviewMarkdownService do
end
end
- context 'new note with slash commands' do
+ context 'new note with quick actions' do
let(:issue) { create(:issue, project: project) }
let(:params) do
{
text: "Please do it\n/assign #{user.to_reference}",
- slash_commands_target_type: 'Issue',
- slash_commands_target_id: issue.id
+ quick_actions_target_type: 'Issue',
+ quick_actions_target_id: issue.id
}
end
let(:service) { described_class.new(project, user, params) }
- it 'removes slash commands from text' do
+ it 'removes quick actions from text' do
result = service.execute
expect(result[:text]).to eq 'Please do it'
end
- it 'explains slash commands effect' do
+ it 'explains quick actions effect' do
result = service.execute
expect(result[:commands]).to eq "Assigns #{user.to_reference}."
@@ -47,21 +47,21 @@ describe PreviewMarkdownService do
let(:params) do
{
text: "My work\n/estimate 2y",
- slash_commands_target_type: 'MergeRequest'
+ quick_actions_target_type: 'MergeRequest'
}
end
let(:service) { described_class.new(project, user, params) }
- it 'removes slash commands from text' do
+ it 'removes quick actions from text' do
result = service.execute
expect(result[:text]).to eq 'My work'
end
- it 'explains slash commands effect' do
+ it 'explains quick actions effect' do
result = service.execute
expect(result[:commands]).to eq 'Sets time estimate to 2y.'
- end
+ end
end
end
diff --git a/spec/services/projects/housekeeping_service_spec.rb b/spec/services/projects/housekeeping_service_spec.rb
index fff12beed71..ebed802708d 100644
--- a/spec/services/projects/housekeeping_service_spec.rb
+++ b/spec/services/projects/housekeeping_service_spec.rb
@@ -66,14 +66,14 @@ describe Projects::HousekeepingService do
allow(subject).to receive(:lease_key).and_return(:the_lease_key)
# At push 200
- expect(GitGarbageCollectWorker).to receive(:perform_async).with(project.id, :gc, :the_lease_key, :the_uuid).
- exactly(1).times
+ expect(GitGarbageCollectWorker).to receive(:perform_async).with(project.id, :gc, :the_lease_key, :the_uuid)
+ .exactly(1).times
# At push 50, 100, 150
- expect(GitGarbageCollectWorker).to receive(:perform_async).with(project.id, :full_repack, :the_lease_key, :the_uuid).
- exactly(3).times
+ expect(GitGarbageCollectWorker).to receive(:perform_async).with(project.id, :full_repack, :the_lease_key, :the_uuid)
+ .exactly(3).times
# At push 10, 20, ... (except those above)
- expect(GitGarbageCollectWorker).to receive(:perform_async).with(project.id, :incremental_repack, :the_lease_key, :the_uuid).
- exactly(16).times
+ expect(GitGarbageCollectWorker).to receive(:perform_async).with(project.id, :incremental_repack, :the_lease_key, :the_uuid)
+ .exactly(16).times
201.times do
subject.increment!
diff --git a/spec/services/projects/import_service_spec.rb b/spec/services/projects/import_service_spec.rb
index 44db299812f..e855de38037 100644
--- a/spec/services/projects/import_service_spec.rb
+++ b/spec/services/projects/import_service_spec.rb
@@ -111,11 +111,11 @@ describe Projects::ImportService, services: true do
end
it 'flushes various caches' do
- allow_any_instance_of(Repository).to receive(:fetch_remote).
- and_return(true)
+ allow_any_instance_of(Repository).to receive(:fetch_remote)
+ .and_return(true)
- allow_any_instance_of(Gitlab::GithubImport::Importer).to receive(:execute).
- and_return(true)
+ allow_any_instance_of(Gitlab::GithubImport::Importer).to receive(:execute)
+ .and_return(true)
expect_any_instance_of(Repository).to receive(:expire_content_cache)
diff --git a/spec/services/projects/propagate_service_template_spec.rb b/spec/services/projects/propagate_service_template_spec.rb
index 8a6a9f09f74..a6d43c4f0f1 100644
--- a/spec/services/projects/propagate_service_template_spec.rb
+++ b/spec/services/projects/propagate_service_template_spec.rb
@@ -60,8 +60,8 @@ describe Projects::PropagateServiceTemplate, services: true do
Service.build_from_template(project.id, service_template).save!
Service.build_from_template(project.id, other_service).save!
- expect { described_class.propagate(service_template) }.
- not_to change { Service.count }
+ expect { described_class.propagate(service_template) }
+ .not_to change { Service.count }
end
it 'creates the service containing the template attributes' do
@@ -90,8 +90,8 @@ describe Projects::PropagateServiceTemplate, services: true do
it 'updates the project external tracker' do
service_template.update!(category: 'issue_tracker', default: false)
- expect { described_class.propagate(service_template) }.
- to change { project.reload.has_external_issue_tracker }.to(true)
+ expect { described_class.propagate(service_template) }
+ .to change { project.reload.has_external_issue_tracker }.to(true)
end
end
@@ -99,8 +99,8 @@ describe Projects::PropagateServiceTemplate, services: true do
it 'updates the project external tracker' do
service_template.update!(type: 'ExternalWikiService')
- expect { described_class.propagate(service_template) }.
- to change { project.reload.has_external_wiki }.to(true)
+ expect { described_class.propagate(service_template) }
+ .to change { project.reload.has_external_wiki }.to(true)
end
end
end
diff --git a/spec/services/projects/transfer_service_spec.rb b/spec/services/projects/transfer_service_spec.rb
index 5d2f4cf17fb..76c52d55ae5 100644
--- a/spec/services/projects/transfer_service_spec.rb
+++ b/spec/services/projects/transfer_service_spec.rb
@@ -7,10 +7,10 @@ describe Projects::TransferService, services: true do
context 'namespace -> namespace' do
before do
- allow_any_instance_of(Gitlab::UploadsTransfer).
- to receive(:move_project).and_return(true)
- allow_any_instance_of(Gitlab::PagesTransfer).
- to receive(:move_project).and_return(true)
+ allow_any_instance_of(Gitlab::UploadsTransfer)
+ .to receive(:move_project).and_return(true)
+ allow_any_instance_of(Gitlab::PagesTransfer)
+ .to receive(:move_project).and_return(true)
group.add_owner(user)
@result = transfer_project(project, user, group)
end
@@ -19,6 +19,67 @@ describe Projects::TransferService, services: true do
it { expect(project.namespace).to eq(group) }
end
+ context 'when transfer succeeds' do
+ before do
+ group.add_owner(user)
+ end
+
+ it 'sends notifications' do
+ expect_any_instance_of(NotificationService).to receive(:project_was_moved)
+
+ transfer_project(project, user, group)
+ end
+
+ it 'executes system hooks' do
+ expect_any_instance_of(Projects::TransferService).to receive(:execute_system_hooks)
+
+ transfer_project(project, user, group)
+ end
+ end
+
+ context 'when transfer fails' do
+ let!(:original_path) { project_path(project) }
+
+ def attempt_project_transfer
+ expect do
+ transfer_project(project, user, group)
+ end.to raise_error(ActiveRecord::ActiveRecordError)
+ end
+
+ before do
+ group.add_owner(user)
+
+ expect_any_instance_of(Labels::TransferService).to receive(:execute).and_raise(ActiveRecord::StatementInvalid, "PG ERROR")
+ end
+
+ def project_path(project)
+ File.join(project.repository_storage_path, "#{project.path_with_namespace}.git")
+ end
+
+ def current_path
+ project_path(project)
+ end
+
+ it 'rolls back repo location' do
+ attempt_project_transfer
+
+ expect(Dir.exist?(original_path)).to be_truthy
+ expect(original_path).to eq current_path
+ end
+
+ it "doesn't send move notifications" do
+ expect_any_instance_of(NotificationService).not_to receive(:project_was_moved)
+
+ attempt_project_transfer
+ end
+
+ it "doesn't run system hooks" do
+ expect_any_instance_of(Projects::TransferService).not_to receive(:execute_system_hooks)
+
+ attempt_project_transfer
+ end
+ end
+
context 'namespace -> no namespace' do
before do
@result = transfer_project(project, user, nil)
@@ -112,9 +173,9 @@ describe Projects::TransferService, services: true do
end
it 'only schedules a single job for every user' do
- expect(UserProjectAccessChangedService).to receive(:new).
- with([owner.id, group_member.id]).
- and_call_original
+ expect(UserProjectAccessChangedService).to receive(:new)
+ .with([owner.id, group_member.id])
+ .and_call_original
transfer_project(project, owner, group)
end
diff --git a/spec/services/projects/unlink_fork_service_spec.rb b/spec/services/projects/unlink_fork_service_spec.rb
index 23f5555d3e0..d34652bd7ac 100644
--- a/spec/services/projects/unlink_fork_service_spec.rb
+++ b/spec/services/projects/unlink_fork_service_spec.rb
@@ -12,9 +12,9 @@ describe Projects::UnlinkForkService, services: true do
let(:mr_close_service) { MergeRequests::CloseService.new(fork_project, user) }
before do
- allow(MergeRequests::CloseService).to receive(:new).
- with(fork_project, user).
- and_return(mr_close_service)
+ allow(MergeRequests::CloseService).to receive(:new)
+ .with(fork_project, user)
+ .and_return(mr_close_service)
end
it 'close all pending merge requests' do
diff --git a/spec/services/slash_commands/interpret_service_spec.rb b/spec/services/quick_actions/interpret_service_spec.rb
index c12fb1a6e53..c9e63efbc14 100644
--- a/spec/services/slash_commands/interpret_service_spec.rb
+++ b/spec/services/quick_actions/interpret_service_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe SlashCommands::InterpretService, services: true do
+describe QuickActions::InterpretService, services: true do
let(:project) { create(:empty_project, :public) }
let(:developer) { create(:user) }
let(:developer2) { create(:user) }
diff --git a/spec/services/submit_usage_ping_service_spec.rb b/spec/services/submit_usage_ping_service_spec.rb
index 63a1e78f274..817fa4262d5 100644
--- a/spec/services/submit_usage_ping_service_spec.rb
+++ b/spec/services/submit_usage_ping_service_spec.rb
@@ -92,8 +92,8 @@ describe SubmitUsagePingService do
end
def stub_response(body)
- stub_request(:post, 'https://version.gitlab.com/usage_data').
- to_return(
+ stub_request(:post, 'https://version.gitlab.com/usage_data')
+ .to_return(
headers: { 'Content-Type' => 'application/json' },
body: body.to_json
)
diff --git a/spec/services/system_note_service_spec.rb b/spec/services/system_note_service_spec.rb
index 9295c09aefc..8d3dafafab2 100644
--- a/spec/services/system_note_service_spec.rb
+++ b/spec/services/system_note_service_spec.rb
@@ -333,8 +333,8 @@ describe SystemNoteService, services: true do
end
it 'sets the note text' do
- expect(subject.note).
- to eq "changed title from **{-Old title-}** to **{+Lorem ipsum+}**"
+ expect(subject.note)
+ .to eq "changed title from **{-Old title-}** to **{+Lorem ipsum+}**"
end
end
end
@@ -521,8 +521,8 @@ describe SystemNoteService, services: true do
context 'when mentioner is not a MergeRequest' do
it 'is falsey' do
mentioner = noteable.dup
- expect(described_class.cross_reference_disallowed?(noteable, mentioner)).
- to be_falsey
+ expect(described_class.cross_reference_disallowed?(noteable, mentioner))
+ .to be_falsey
end
end
@@ -533,14 +533,14 @@ describe SystemNoteService, services: true do
it 'is truthy when noteable is in commits' do
expect(mentioner).to receive(:commits).and_return([noteable])
- expect(described_class.cross_reference_disallowed?(noteable, mentioner)).
- to be_truthy
+ expect(described_class.cross_reference_disallowed?(noteable, mentioner))
+ .to be_truthy
end
it 'is falsey when noteable is not in commits' do
expect(mentioner).to receive(:commits).and_return([])
- expect(described_class.cross_reference_disallowed?(noteable, mentioner)).
- to be_falsey
+ expect(described_class.cross_reference_disallowed?(noteable, mentioner))
+ .to be_falsey
end
end
@@ -548,8 +548,8 @@ describe SystemNoteService, services: true do
let(:noteable) { ExternalIssue.new('EXT-1234', project) }
it 'is truthy' do
mentioner = noteable.dup
- expect(described_class.cross_reference_disallowed?(noteable, mentioner)).
- to be_truthy
+ expect(described_class.cross_reference_disallowed?(noteable, mentioner))
+ .to be_truthy
end
end
end
@@ -566,13 +566,13 @@ describe SystemNoteService, services: true do
end
it 'is truthy when already mentioned' do
- expect(described_class.cross_reference_exists?(noteable, commit0)).
- to be_truthy
+ expect(described_class.cross_reference_exists?(noteable, commit0))
+ .to be_truthy
end
it 'is falsey when not already mentioned' do
- expect(described_class.cross_reference_exists?(noteable, commit1)).
- to be_falsey
+ expect(described_class.cross_reference_exists?(noteable, commit1))
+ .to be_falsey
end
context 'legacy capitalized cross reference' do
@@ -583,8 +583,8 @@ describe SystemNoteService, services: true do
end
it 'is truthy when already mentioned' do
- expect(described_class.cross_reference_exists?(noteable, commit0)).
- to be_truthy
+ expect(described_class.cross_reference_exists?(noteable, commit0))
+ .to be_truthy
end
end
end
@@ -596,13 +596,13 @@ describe SystemNoteService, services: true do
end
it 'is truthy when already mentioned' do
- expect(described_class.cross_reference_exists?(commit0, commit1)).
- to be_truthy
+ expect(described_class.cross_reference_exists?(commit0, commit1))
+ .to be_truthy
end
it 'is falsey when not already mentioned' do
- expect(described_class.cross_reference_exists?(commit1, commit0)).
- to be_falsey
+ expect(described_class.cross_reference_exists?(commit1, commit0))
+ .to be_falsey
end
context 'legacy capitalized cross reference' do
@@ -613,8 +613,8 @@ describe SystemNoteService, services: true do
end
it 'is truthy when already mentioned' do
- expect(described_class.cross_reference_exists?(commit0, commit1)).
- to be_truthy
+ expect(described_class.cross_reference_exists?(commit0, commit1))
+ .to be_truthy
end
end
end
@@ -629,8 +629,8 @@ describe SystemNoteService, services: true do
end
it 'is true when a fork mentions an external issue' do
- expect(described_class.cross_reference_exists?(noteable, commit2)).
- to be true
+ expect(described_class.cross_reference_exists?(noteable, commit2))
+ .to be true
end
context 'legacy capitalized cross reference' do
@@ -640,8 +640,8 @@ describe SystemNoteService, services: true do
end
it 'is true when a fork mentions an external issue' do
- expect(described_class.cross_reference_exists?(noteable, commit2)).
- to be true
+ expect(described_class.cross_reference_exists?(noteable, commit2))
+ .to be true
end
end
end
diff --git a/spec/services/tags/create_service_spec.rb b/spec/services/tags/create_service_spec.rb
index b9121b1de49..9f143cc5667 100644
--- a/spec/services/tags/create_service_spec.rb
+++ b/spec/services/tags/create_service_spec.rb
@@ -26,9 +26,9 @@ describe Tags::CreateService, services: true do
context 'when tag already exists' do
it 'returns an error' do
- expect(repository).to receive(:add_tag).
- with(user, 'v1.1.0', 'master', 'Foo').
- and_raise(Rugged::TagError)
+ expect(repository).to receive(:add_tag)
+ .with(user, 'v1.1.0', 'master', 'Foo')
+ .and_raise(Rugged::TagError)
response = service.execute('v1.1.0', 'master', 'Foo')
@@ -39,9 +39,9 @@ describe Tags::CreateService, services: true do
context 'when pre-receive hook fails' do
it 'returns an error' do
- expect(repository).to receive(:add_tag).
- with(user, 'v1.1.0', 'master', 'Foo').
- and_raise(GitHooksService::PreReceiveError, 'something went wrong')
+ expect(repository).to receive(:add_tag)
+ .with(user, 'v1.1.0', 'master', 'Foo')
+ .and_raise(GitHooksService::PreReceiveError, 'something went wrong')
response = service.execute('v1.1.0', 'master', 'Foo')
diff --git a/spec/services/user_project_access_changed_service_spec.rb b/spec/services/user_project_access_changed_service_spec.rb
index b4efe7de431..14a5e40350a 100644
--- a/spec/services/user_project_access_changed_service_spec.rb
+++ b/spec/services/user_project_access_changed_service_spec.rb
@@ -3,8 +3,8 @@ require 'spec_helper'
describe UserProjectAccessChangedService do
describe '#execute' do
it 'schedules the user IDs' do
- expect(AuthorizedProjectsWorker).to receive(:bulk_perform_and_wait).
- with([[1], [2]])
+ expect(AuthorizedProjectsWorker).to receive(:bulk_perform_and_wait)
+ .with([[1], [2]])
described_class.new([1, 2]).execute
end
diff --git a/spec/services/users/activity_service_spec.rb b/spec/services/users/activity_service_spec.rb
index 8d67ebe3231..2e009d4ce1c 100644
--- a/spec/services/users/activity_service_spec.rb
+++ b/spec/services/users/activity_service_spec.rb
@@ -41,8 +41,8 @@ describe Users::ActivityService, services: true do
end
def last_hour_user_ids
- Gitlab::UserActivities.new.
- select { |k, v| v >= 1.hour.ago.to_i.to_s }.
- map { |k, _| k.to_i }
+ Gitlab::UserActivities.new
+ .select { |k, v| v >= 1.hour.ago.to_i.to_s }
+ .map { |k, _| k.to_i }
end
end
diff --git a/spec/services/users/refresh_authorized_projects_service_spec.rb b/spec/services/users/refresh_authorized_projects_service_spec.rb
index 8c40d25e00c..b65cadbb2f5 100644
--- a/spec/services/users/refresh_authorized_projects_service_spec.rb
+++ b/spec/services/users/refresh_authorized_projects_service_spec.rb
@@ -10,11 +10,11 @@ describe Users::RefreshAuthorizedProjectsService do
describe '#execute', :redis do
it 'refreshes the authorizations using a lease' do
- expect_any_instance_of(Gitlab::ExclusiveLease).to receive(:try_obtain).
- and_return('foo')
+ expect_any_instance_of(Gitlab::ExclusiveLease).to receive(:try_obtain)
+ .and_return('foo')
- expect(Gitlab::ExclusiveLease).to receive(:cancel).
- with(an_instance_of(String), 'foo')
+ expect(Gitlab::ExclusiveLease).to receive(:cancel)
+ .with(an_instance_of(String), 'foo')
expect(service).to receive(:execute_without_lease)
@@ -29,11 +29,11 @@ describe Users::RefreshAuthorizedProjectsService do
it 'updates the authorized projects of the user' do
project2 = create(:empty_project)
- to_remove = user.project_authorizations.
- create!(project: project2, access_level: Gitlab::Access::MASTER)
+ to_remove = user.project_authorizations
+ .create!(project: project2, access_level: Gitlab::Access::MASTER)
- expect(service).to receive(:update_authorizations).
- with([to_remove.project_id], [[user.id, project.id, Gitlab::Access::MASTER]])
+ expect(service).to receive(:update_authorizations)
+ .with([to_remove.project_id], [[user.id, project.id, Gitlab::Access::MASTER]])
service.execute_without_lease
end
@@ -41,11 +41,11 @@ describe Users::RefreshAuthorizedProjectsService do
it 'sets the access level of a project to the highest available level' do
user.project_authorizations.delete_all
- to_remove = user.project_authorizations.
- create!(project: project, access_level: Gitlab::Access::DEVELOPER)
+ to_remove = user.project_authorizations
+ .create!(project: project, access_level: Gitlab::Access::DEVELOPER)
- expect(service).to receive(:update_authorizations).
- with([to_remove.project_id], [[user.id, project.id, Gitlab::Access::MASTER]])
+ expect(service).to receive(:update_authorizations)
+ .with([to_remove.project_id], [[user.id, project.id, Gitlab::Access::MASTER]])
service.execute_without_lease
end
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 01ac3cbd3f6..fdef6fd5221 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -44,6 +44,7 @@ RSpec.configure do |config|
config.include Devise::Test::ControllerHelpers, type: :controller
config.include Devise::Test::ControllerHelpers, type: :view
+ config.include Devise::Test::IntegrationHelpers, type: :feature
config.include Warden::Test::Helpers, type: :request
config.include LoginHelpers, type: :feature
config.include SearchHelpers, type: :feature
diff --git a/spec/support/capybara.rb b/spec/support/capybara.rb
index c34e76fa72f..3e5d6cf1364 100644
--- a/spec/support/capybara.rb
+++ b/spec/support/capybara.rb
@@ -35,4 +35,14 @@ RSpec.configure do |config|
TestEnv.eager_load_driver_server
$capybara_server_already_started = true
end
+
+ config.after(:each, :js) do |example|
+ # capybara/rspec already calls Capybara.reset_sessions! in an `after` hook,
+ # but `block_and_wait_for_requests_complete` is called before it so by
+ # calling it explicitely here, we prevent any new requests from being fired
+ # See https://github.com/teamcapybara/capybara/blob/ffb41cfad620de1961bb49b1562a9fa9b28c0903/lib/capybara/rspec.rb#L20-L25
+ # We don't reset the session when the example failed, because we need capybara-screenshot to have access to it.
+ Capybara.reset_sessions! unless example.exception
+ block_and_wait_for_requests_complete
+ end
end
diff --git a/spec/support/chat_slash_commands_shared_examples.rb b/spec/support/chat_slash_commands_shared_examples.rb
index 4dfa29849ee..978b0b9cc30 100644
--- a/spec/support/chat_slash_commands_shared_examples.rb
+++ b/spec/support/chat_slash_commands_shared_examples.rb
@@ -87,7 +87,7 @@ RSpec.shared_examples 'chat slash commands service' do
end
it 'triggers the command' do
- expect_any_instance_of(Gitlab::ChatCommands::Command).to receive(:execute)
+ expect_any_instance_of(Gitlab::SlashCommands::Command).to receive(:execute)
subject.trigger(params)
end
diff --git a/spec/support/controllers/githubish_import_controller_shared_examples.rb b/spec/support/controllers/githubish_import_controller_shared_examples.rb
index d6b40db09ce..a8d9566b4e4 100644
--- a/spec/support/controllers/githubish_import_controller_shared_examples.rb
+++ b/spec/support/controllers/githubish_import_controller_shared_examples.rb
@@ -14,8 +14,8 @@ shared_examples 'a GitHub-ish import controller: POST personal_access_token' do
it "updates access token" do
token = 'asdfasdf9876'
- allow_any_instance_of(Gitlab::GithubImport::Client).
- to receive(:user).and_return(true)
+ allow_any_instance_of(Gitlab::GithubImport::Client)
+ .to receive(:user).and_return(true)
post :personal_access_token, personal_access_token: token
@@ -79,8 +79,8 @@ shared_examples 'a GitHub-ish import controller: GET status' do
end
it "handles an invalid access token" do
- allow_any_instance_of(Gitlab::GithubImport::Client).
- to receive(:repos).and_raise(Octokit::Unauthorized)
+ allow_any_instance_of(Gitlab::GithubImport::Client)
+ .to receive(:repos).and_raise(Octokit::Unauthorized)
get :status
@@ -110,9 +110,9 @@ shared_examples 'a GitHub-ish import controller: POST create' do
context "when the repository owner is the provider user" do
context "when the provider user and GitLab user's usernames match" do
it "takes the current user's namespace" do
- expect(Gitlab::GithubImport::ProjectCreator).
- to receive(:new).with(provider_repo, provider_repo.name, user.namespace, user, access_params, type: provider).
- and_return(double(execute: true))
+ expect(Gitlab::GithubImport::ProjectCreator)
+ .to receive(:new).with(provider_repo, provider_repo.name, user.namespace, user, access_params, type: provider)
+ .and_return(double(execute: true))
post :create, format: :js
end
@@ -122,9 +122,9 @@ shared_examples 'a GitHub-ish import controller: POST create' do
let(:provider_username) { "someone_else" }
it "takes the current user's namespace" do
- expect(Gitlab::GithubImport::ProjectCreator).
- to receive(:new).with(provider_repo, provider_repo.name, user.namespace, user, access_params, type: provider).
- and_return(double(execute: true))
+ expect(Gitlab::GithubImport::ProjectCreator)
+ .to receive(:new).with(provider_repo, provider_repo.name, user.namespace, user, access_params, type: provider)
+ .and_return(double(execute: true))
post :create, format: :js
end
@@ -144,9 +144,9 @@ shared_examples 'a GitHub-ish import controller: POST create' do
context "when the namespace is owned by the GitLab user" do
it "takes the existing namespace" do
- expect(Gitlab::GithubImport::ProjectCreator).
- to receive(:new).with(provider_repo, provider_repo.name, existing_namespace, user, access_params, type: provider).
- and_return(double(execute: true))
+ expect(Gitlab::GithubImport::ProjectCreator)
+ .to receive(:new).with(provider_repo, provider_repo.name, existing_namespace, user, access_params, type: provider)
+ .and_return(double(execute: true))
post :create, format: :js
end
@@ -159,9 +159,9 @@ shared_examples 'a GitHub-ish import controller: POST create' do
end
it "creates a project using user's namespace" do
- expect(Gitlab::GithubImport::ProjectCreator).
- to receive(:new).with(provider_repo, provider_repo.name, user.namespace, user, access_params, type: provider).
- and_return(double(execute: true))
+ expect(Gitlab::GithubImport::ProjectCreator)
+ .to receive(:new).with(provider_repo, provider_repo.name, user.namespace, user, access_params, type: provider)
+ .and_return(double(execute: true))
post :create, format: :js
end
@@ -171,16 +171,16 @@ shared_examples 'a GitHub-ish import controller: POST create' do
context "when a namespace with the provider user's username doesn't exist" do
context "when current user can create namespaces" do
it "creates the namespace" do
- expect(Gitlab::GithubImport::ProjectCreator).
- to receive(:new).and_return(double(execute: true))
+ expect(Gitlab::GithubImport::ProjectCreator)
+ .to receive(:new).and_return(double(execute: true))
expect { post :create, target_namespace: provider_repo.name, format: :js }.to change(Namespace, :count).by(1)
end
it "takes the new namespace" do
- expect(Gitlab::GithubImport::ProjectCreator).
- to receive(:new).with(provider_repo, provider_repo.name, an_instance_of(Group), user, access_params, type: provider).
- and_return(double(execute: true))
+ expect(Gitlab::GithubImport::ProjectCreator)
+ .to receive(:new).with(provider_repo, provider_repo.name, an_instance_of(Group), user, access_params, type: provider)
+ .and_return(double(execute: true))
post :create, target_namespace: provider_repo.name, format: :js
end
@@ -192,16 +192,16 @@ shared_examples 'a GitHub-ish import controller: POST create' do
end
it "doesn't create the namespace" do
- expect(Gitlab::GithubImport::ProjectCreator).
- to receive(:new).and_return(double(execute: true))
+ expect(Gitlab::GithubImport::ProjectCreator)
+ .to receive(:new).and_return(double(execute: true))
expect { post :create, format: :js }.not_to change(Namespace, :count)
end
it "takes the current user's namespace" do
- expect(Gitlab::GithubImport::ProjectCreator).
- to receive(:new).with(provider_repo, provider_repo.name, user.namespace, user, access_params, type: provider).
- and_return(double(execute: true))
+ expect(Gitlab::GithubImport::ProjectCreator)
+ .to receive(:new).with(provider_repo, provider_repo.name, user.namespace, user, access_params, type: provider)
+ .and_return(double(execute: true))
post :create, format: :js
end
@@ -217,17 +217,17 @@ shared_examples 'a GitHub-ish import controller: POST create' do
end
it 'takes the selected namespace and name' do
- expect(Gitlab::GithubImport::ProjectCreator).
- to receive(:new).with(provider_repo, test_name, test_namespace, user, access_params, type: provider).
- and_return(double(execute: true))
+ expect(Gitlab::GithubImport::ProjectCreator)
+ .to receive(:new).with(provider_repo, test_name, test_namespace, user, access_params, type: provider)
+ .and_return(double(execute: true))
post :create, { target_namespace: test_namespace.name, new_name: test_name, format: :js }
end
it 'takes the selected name and default namespace' do
- expect(Gitlab::GithubImport::ProjectCreator).
- to receive(:new).with(provider_repo, test_name, user.namespace, user, access_params, type: provider).
- and_return(double(execute: true))
+ expect(Gitlab::GithubImport::ProjectCreator)
+ .to receive(:new).with(provider_repo, test_name, user.namespace, user, access_params, type: provider)
+ .and_return(double(execute: true))
post :create, { new_name: test_name, format: :js }
end
@@ -243,9 +243,9 @@ shared_examples 'a GitHub-ish import controller: POST create' do
end
it 'takes the selected namespace and name' do
- expect(Gitlab::GithubImport::ProjectCreator).
- to receive(:new).with(provider_repo, test_name, nested_namespace, user, access_params, type: provider).
- and_return(double(execute: true))
+ expect(Gitlab::GithubImport::ProjectCreator)
+ .to receive(:new).with(provider_repo, test_name, nested_namespace, user, access_params, type: provider)
+ .and_return(double(execute: true))
post :create, { target_namespace: nested_namespace.full_path, new_name: test_name, format: :js }
end
@@ -255,26 +255,26 @@ shared_examples 'a GitHub-ish import controller: POST create' do
let(:test_name) { 'test_name' }
it 'takes the selected namespace and name' do
- expect(Gitlab::GithubImport::ProjectCreator).
- to receive(:new).with(provider_repo, test_name, kind_of(Namespace), user, access_params, type: provider).
- and_return(double(execute: true))
+ expect(Gitlab::GithubImport::ProjectCreator)
+ .to receive(:new).with(provider_repo, test_name, kind_of(Namespace), user, access_params, type: provider)
+ .and_return(double(execute: true))
post :create, { target_namespace: 'foo/bar', new_name: test_name, format: :js }
end
it 'creates the namespaces' do
- allow(Gitlab::GithubImport::ProjectCreator).
- to receive(:new).with(provider_repo, test_name, kind_of(Namespace), user, access_params, type: provider).
- and_return(double(execute: true))
+ allow(Gitlab::GithubImport::ProjectCreator)
+ .to receive(:new).with(provider_repo, test_name, kind_of(Namespace), user, access_params, type: provider)
+ .and_return(double(execute: true))
expect { post :create, { target_namespace: 'foo/bar', new_name: test_name, format: :js } }
.to change { Namespace.count }.by(2)
end
it 'new namespace has the right parent' do
- allow(Gitlab::GithubImport::ProjectCreator).
- to receive(:new).with(provider_repo, test_name, kind_of(Namespace), user, access_params, type: provider).
- and_return(double(execute: true))
+ allow(Gitlab::GithubImport::ProjectCreator)
+ .to receive(:new).with(provider_repo, test_name, kind_of(Namespace), user, access_params, type: provider)
+ .and_return(double(execute: true))
post :create, { target_namespace: 'foo/bar', new_name: test_name, format: :js }
@@ -287,17 +287,17 @@ shared_examples 'a GitHub-ish import controller: POST create' do
let!(:parent_namespace) { create(:group, name: 'foo', owner: user) }
it 'takes the selected namespace and name' do
- expect(Gitlab::GithubImport::ProjectCreator).
- to receive(:new).with(provider_repo, test_name, kind_of(Namespace), user, access_params, type: provider).
- and_return(double(execute: true))
+ expect(Gitlab::GithubImport::ProjectCreator)
+ .to receive(:new).with(provider_repo, test_name, kind_of(Namespace), user, access_params, type: provider)
+ .and_return(double(execute: true))
post :create, { target_namespace: 'foo/foobar/bar', new_name: test_name, format: :js }
end
it 'creates the namespaces' do
- allow(Gitlab::GithubImport::ProjectCreator).
- to receive(:new).with(provider_repo, test_name, kind_of(Namespace), user, access_params, type: provider).
- and_return(double(execute: true))
+ allow(Gitlab::GithubImport::ProjectCreator)
+ .to receive(:new).with(provider_repo, test_name, kind_of(Namespace), user, access_params, type: provider)
+ .and_return(double(execute: true))
expect { post :create, { target_namespace: 'foo/foobar/bar', new_name: test_name, format: :js } }
.to change { Namespace.count }.by(2)
diff --git a/spec/support/features/issuable_slash_commands_shared_examples.rb b/spec/support/features/issuable_slash_commands_shared_examples.rb
index fa82dc5e9f9..50869099bb7 100644
--- a/spec/support/features/issuable_slash_commands_shared_examples.rb
+++ b/spec/support/features/issuable_slash_commands_shared_examples.rb
@@ -1,8 +1,8 @@
# Specifications for behavior common to all objects with executable attributes.
# It takes a `issuable_type`, and expect an `issuable`.
-shared_examples 'issuable record that supports slash commands in its description and notes' do |issuable_type|
- include SlashCommandsHelpers
+shared_examples 'issuable record that supports quick actions in its description and notes' do |issuable_type|
+ include QuickActionsHelpers
let(:master) { create(:user) }
let(:assignee) { create(:user, username: 'bob') }
@@ -17,7 +17,7 @@ shared_examples 'issuable record that supports slash commands in its description
project.team << [master, :master]
project.team << [assignee, :developer]
project.team << [guest, :guest]
- login_with(master)
+ gitlab_sign_in(master)
end
after do
@@ -105,8 +105,8 @@ shared_examples 'issuable record that supports slash commands in its description
context "when current user cannot close #{issuable_type}" do
before do
- logout
- login_with(guest)
+ gitlab_sign_out
+ gitlab_sign_in(guest)
visit public_send("namespace_project_#{issuable_type}_path", project.namespace, project, issuable)
end
@@ -140,8 +140,8 @@ shared_examples 'issuable record that supports slash commands in its description
context "when current user cannot reopen #{issuable_type}" do
before do
- logout
- login_with(guest)
+ gitlab_sign_out
+ gitlab_sign_in(guest)
visit public_send("namespace_project_#{issuable_type}_path", project.namespace, project, issuable)
end
@@ -170,8 +170,8 @@ shared_examples 'issuable record that supports slash commands in its description
context "when current user cannot change title of #{issuable_type}" do
before do
- logout
- login_with(guest)
+ gitlab_sign_out
+ gitlab_sign_in(guest)
visit public_send("namespace_project_#{issuable_type}_path", project.namespace, project, issuable)
end
@@ -260,7 +260,7 @@ shared_examples 'issuable record that supports slash commands in its description
end
describe "preview of note on #{issuable_type}" do
- it 'removes slash commands from note and explains them' do
+ it 'removes quick actions from note and explains them' do
visit public_send("namespace_project_#{issuable_type}_path", project.namespace, project, issuable)
page.within('.js-main-target-form') do
diff --git a/spec/support/features/reportable_note_shared_examples.rb b/spec/support/features/reportable_note_shared_examples.rb
index 0d80c95e826..27e079c01dd 100644
--- a/spec/support/features/reportable_note_shared_examples.rb
+++ b/spec/support/features/reportable_note_shared_examples.rb
@@ -13,9 +13,7 @@ shared_examples 'reportable note' do
it 'dropdown has Edit, Report and Delete links' do
dropdown = comment.find(more_actions_selector)
-
- dropdown.click
- dropdown.find('.dropdown-menu li', match: :first)
+ open_dropdown(dropdown)
expect(dropdown).to have_button('Edit comment')
expect(dropdown).to have_link('Report as abuse', href: abuse_report_path)
@@ -24,13 +22,16 @@ shared_examples 'reportable note' do
it 'Report button links to a report page' do
dropdown = comment.find(more_actions_selector)
-
- dropdown.click
- dropdown.find('.dropdown-menu li', match: :first)
+ open_dropdown(dropdown)
dropdown.click_link('Report as abuse')
expect(find('#user_name')['value']).to match(note.author.username)
expect(find('#abuse_report_message')['value']).to match(noteable_note_url(note))
end
+
+ def open_dropdown(dropdown)
+ dropdown.click
+ dropdown.find('.dropdown-menu li', match: :first)
+ end
end
diff --git a/spec/support/filtered_search_helpers.rb b/spec/support/filtered_search_helpers.rb
index 37cc308e613..d21c4324d9e 100644
--- a/spec/support/filtered_search_helpers.rb
+++ b/spec/support/filtered_search_helpers.rb
@@ -14,6 +14,9 @@ module FilteredSearchHelpers
filtered_search.set(search)
if submit
+ # Wait for the lazy author/assignee tokens that
+ # swap out the username with an avatar and name
+ wait_for_requests
filtered_search.send_keys(:enter)
end
end
diff --git a/spec/support/login_helpers.rb b/spec/support/login_helpers.rb
index e6da852e728..879386b5437 100644
--- a/spec/support/login_helpers.rb
+++ b/spec/support/login_helpers.rb
@@ -6,15 +6,15 @@ module LoginHelpers
# Examples:
#
# # Create a user automatically
- # login_as(:user)
+ # gitlab_sign_in(:user)
#
# # Create an admin automatically
- # login_as(:admin)
+ # gitlab_sign_in(:admin)
#
# # Provide an existing User record
# user = create(:user)
- # login_as(user)
- def login_as(user_or_role)
+ # gitlab_sign_in(user)
+ def gitlab_sign_in(user_or_role, **kwargs)
@user =
if user_or_role.is_a?(User)
user_or_role
@@ -22,26 +22,44 @@ module LoginHelpers
create(user_or_role)
end
- login_with(@user)
+ gitlab_sign_in_with(@user, **kwargs)
end
- # Internal: Login as the specified user
+ def gitlab_sign_in_via(provider, user, uid)
+ mock_auth_hash(provider, uid, user.email)
+ visit new_user_session_path
+ click_link provider
+ end
+
+ # Requires Javascript driver.
+ def gitlab_sign_out
+ find(".header-user-dropdown-toggle").click
+ click_link "Sign out"
+ # check the sign_in button
+ expect(page).to have_button('Sign in')
+ end
+
+ # Logout without JavaScript driver
+ def gitlab_sign_out_direct
+ page.driver.submit :delete, '/users/sign_out', {}
+ end
+
+ private
+
+ # Private: Login as the specified user
#
# user - User instance to login with
# remember - Whether or not to check "Remember me" (default: false)
- def login_with(user, remember: false)
+ def gitlab_sign_in_with(user, remember: false)
visit new_user_session_path
+
fill_in "user_login", with: user.email
fill_in "user_password", with: "12345678"
check 'user_remember_me' if remember
+
click_button "Sign in"
- Thread.current[:current_user] = user
- end
- def login_via(provider, user, uid)
- mock_auth_hash(provider, uid, user.email)
- visit new_user_session_path
- click_link provider
+ Thread.current[:current_user] = user
end
def mock_auth_hash(provider, uid, email)
@@ -71,17 +89,4 @@ module LoginHelpers
})
Rails.application.env_config['omniauth.auth'] = OmniAuth.config.mock_auth[:saml]
end
-
- # Requires Javascript driver.
- def logout
- find(".header-user-dropdown-toggle").click
- click_link "Sign out"
- # check the sign_in button
- expect(page).to have_button('Sign in')
- end
-
- # Logout without JavaScript driver
- def logout_direct
- page.driver.submit :delete, '/users/sign_out', {}
- end
end
diff --git a/spec/support/mentionable_shared_examples.rb b/spec/support/mentionable_shared_examples.rb
index 87936bb4859..3ac201f1fb1 100644
--- a/spec/support/mentionable_shared_examples.rb
+++ b/spec/support/mentionable_shared_examples.rb
@@ -81,8 +81,8 @@ shared_examples 'a mentionable' do
ext_issue, ext_mr, ext_commit]
mentioned_objects.each do |referenced|
- expect(SystemNoteService).to receive(:cross_reference).
- with(referenced, subject.local_reference, author)
+ expect(SystemNoteService).to receive(:cross_reference)
+ .with(referenced, subject.local_reference, author)
end
subject.create_cross_references!
@@ -127,15 +127,15 @@ shared_examples 'an editable mentionable' do
# These three objects were already referenced, and should not receive new
# notes
[mentioned_issue, mentioned_commit, ext_issue].each do |oldref|
- expect(SystemNoteService).not_to receive(:cross_reference).
- with(oldref, any_args)
+ expect(SystemNoteService).not_to receive(:cross_reference)
+ .with(oldref, any_args)
end
# These two issues are new and should receive reference notes
# In the case of MergeRequests remember that cannot mention commits included in the MergeRequest
new_issues.each do |newref|
- expect(SystemNoteService).to receive(:cross_reference).
- with(newref, subject.local_reference, author)
+ expect(SystemNoteService).to receive(:cross_reference)
+ .with(newref, subject.local_reference, author)
end
set_mentionable_text.call(new_text)
diff --git a/spec/support/project_features_apply_to_issuables_shared_examples.rb b/spec/support/project_features_apply_to_issuables_shared_examples.rb
index f8b7d0527ba..81b51509e0b 100644
--- a/spec/support/project_features_apply_to_issuables_shared_examples.rb
+++ b/spec/support/project_features_apply_to_issuables_shared_examples.rb
@@ -18,7 +18,7 @@ shared_examples 'project features apply to issuables' do |klass|
before do
_ = issuable
- login_as(user) if user
+ gitlab_sign_in(user) if user
visit path
end
diff --git a/spec/support/slash_commands_helpers.rb b/spec/support/quick_actions_helpers.rb
index 4bfe481115f..d2aaae7518f 100644
--- a/spec/support/slash_commands_helpers.rb
+++ b/spec/support/quick_actions_helpers.rb
@@ -1,4 +1,4 @@
-module SlashCommandsHelpers
+module QuickActionsHelpers
def write_note(text)
Sidekiq::Testing.fake! do
page.within('.js-main-target-form') do
diff --git a/spec/support/reactive_caching_helpers.rb b/spec/support/reactive_caching_helpers.rb
index 98eb57f8b54..34124f02133 100644
--- a/spec/support/reactive_caching_helpers.rb
+++ b/spec/support/reactive_caching_helpers.rb
@@ -35,8 +35,8 @@ module ReactiveCachingHelpers
end
def expect_reactive_cache_update_queued(subject)
- expect(ReactiveCachingWorker).
- to receive(:perform_in).
- with(subject.class.reactive_cache_refresh_interval, subject.class, subject.id)
+ expect(ReactiveCachingWorker)
+ .to receive(:perform_in)
+ .with(subject.class.reactive_cache_refresh_interval, subject.class, subject.id)
end
end
diff --git a/spec/support/services/issuable_create_service_slash_commands_shared_examples.rb b/spec/support/services/issuable_create_service_slash_commands_shared_examples.rb
index 5e6f9f323a1..9399745f900 100644
--- a/spec/support/services/issuable_create_service_slash_commands_shared_examples.rb
+++ b/spec/support/services/issuable_create_service_slash_commands_shared_examples.rb
@@ -1,7 +1,7 @@
# Specifications for behavior common to all objects with executable attributes.
# It can take a `default_params`.
-shared_examples 'new issuable record that supports slash commands' do
+shared_examples 'new issuable record that supports quick actions' do
let!(:project) { create(:project, :repository) }
let(:user) { create(:user).tap { |u| project.team << [u, :master] } }
let(:assignee) { create(:user) }
diff --git a/spec/support/services_shared_context.rb b/spec/support/services_shared_context.rb
index 66c93890e31..7457484a932 100644
--- a/spec/support/services_shared_context.rb
+++ b/spec/support/services_shared_context.rb
@@ -6,9 +6,9 @@ Service.available_services_names.each do |service|
let(:service_fields) { service_klass.new.fields }
let(:service_attrs_list) { service_fields.inject([]) {|arr, hash| arr << hash[:name].to_sym } }
let(:service_attrs_list_without_passwords) do
- service_fields.
- select { |field| field[:type] != 'password' }.
- map { |field| field[:name].to_sym}
+ service_fields
+ .select { |field| field[:type] != 'password' }
+ .map { |field| field[:name].to_sym}
end
let(:service_attrs) do
service_attrs_list.inject({}) do |hash, k|
diff --git a/spec/support/slack_mattermost_notifications_shared_examples.rb b/spec/support/slack_mattermost_notifications_shared_examples.rb
index a7deb038703..044c09d5fde 100644
--- a/spec/support/slack_mattermost_notifications_shared_examples.rb
+++ b/spec/support/slack_mattermost_notifications_shared_examples.rb
@@ -108,9 +108,9 @@ RSpec.shared_examples 'slack or mattermost notifications' do
it 'uses the username as an option for slack when configured' do
allow(chat_service).to receive(:username).and_return(username)
- expect(Slack::Notifier).to receive(:new).
- with(webhook_url, username: username).
- and_return(
+ expect(Slack::Notifier).to receive(:new)
+ .with(webhook_url, username: username)
+ .and_return(
double(:slack_service).as_null_object
)
@@ -119,9 +119,9 @@ RSpec.shared_examples 'slack or mattermost notifications' do
it 'uses the channel as an option when it is configured' do
allow(chat_service).to receive(:channel).and_return(channel)
- expect(Slack::Notifier).to receive(:new).
- with(webhook_url, channel: channel).
- and_return(
+ expect(Slack::Notifier).to receive(:new)
+ .with(webhook_url, channel: channel)
+ .and_return(
double(:slack_service).as_null_object
)
chat_service.execute(push_sample_data)
@@ -131,9 +131,9 @@ RSpec.shared_examples 'slack or mattermost notifications' do
it "uses the right channel for push event" do
chat_service.update_attributes(push_channel: "random")
- expect(Slack::Notifier).to receive(:new).
- with(webhook_url, channel: "random").
- and_return(
+ expect(Slack::Notifier).to receive(:new)
+ .with(webhook_url, channel: "random")
+ .and_return(
double(:slack_service).as_null_object
)
@@ -143,9 +143,9 @@ RSpec.shared_examples 'slack or mattermost notifications' do
it "uses the right channel for merge request event" do
chat_service.update_attributes(merge_request_channel: "random")
- expect(Slack::Notifier).to receive(:new).
- with(webhook_url, channel: "random").
- and_return(
+ expect(Slack::Notifier).to receive(:new)
+ .with(webhook_url, channel: "random")
+ .and_return(
double(:slack_service).as_null_object
)
@@ -155,9 +155,9 @@ RSpec.shared_examples 'slack or mattermost notifications' do
it "uses the right channel for issue event" do
chat_service.update_attributes(issue_channel: "random")
- expect(Slack::Notifier).to receive(:new).
- with(webhook_url, channel: "random").
- and_return(
+ expect(Slack::Notifier).to receive(:new)
+ .with(webhook_url, channel: "random")
+ .and_return(
double(:slack_service).as_null_object
)
@@ -167,9 +167,9 @@ RSpec.shared_examples 'slack or mattermost notifications' do
it "uses the right channel for wiki event" do
chat_service.update_attributes(wiki_page_channel: "random")
- expect(Slack::Notifier).to receive(:new).
- with(webhook_url, channel: "random").
- and_return(
+ expect(Slack::Notifier).to receive(:new)
+ .with(webhook_url, channel: "random")
+ .and_return(
double(:slack_service).as_null_object
)
@@ -186,9 +186,9 @@ RSpec.shared_examples 'slack or mattermost notifications' do
note_data = Gitlab::DataBuilder::Note.build(issue_note, user)
- expect(Slack::Notifier).to receive(:new).
- with(webhook_url, channel: "random").
- and_return(
+ expect(Slack::Notifier).to receive(:new)
+ .with(webhook_url, channel: "random")
+ .and_return(
double(:slack_service).as_null_object
)
diff --git a/spec/support/stub_configuration.rb b/spec/support/stub_configuration.rb
index b39a23bd18a..48f454c7187 100644
--- a/spec/support/stub_configuration.rb
+++ b/spec/support/stub_configuration.rb
@@ -5,8 +5,8 @@ module StubConfiguration
# Stubbing both of these because we're not yet consistent with how we access
# current application settings
allow_any_instance_of(ApplicationSetting).to receive_messages(messages)
- allow(Gitlab::CurrentSettings.current_application_settings).
- to receive_messages(messages)
+ allow(Gitlab::CurrentSettings.current_application_settings)
+ .to receive_messages(messages)
end
def stub_config_setting(messages)
diff --git a/spec/support/stub_gitlab_calls.rb b/spec/support/stub_gitlab_calls.rb
index ded2d593059..78a2ff73746 100644
--- a/spec/support/stub_gitlab_calls.rb
+++ b/spec/support/stub_gitlab_calls.rb
@@ -68,22 +68,22 @@ module StubGitlabCalls
def stub_session
f = File.read(Rails.root.join('spec/support/gitlab_stubs/session.json'))
- stub_request(:post, "#{gitlab_url}api/v3/session.json").
- with(body: "{\"email\":\"test@test.com\",\"password\":\"123456\"}",
- headers: { 'Content-Type' => 'application/json' }).
- to_return(status: 201, body: f, headers: { 'Content-Type' => 'application/json' })
+ stub_request(:post, "#{gitlab_url}api/v3/session.json")
+ .with(body: "{\"email\":\"test@test.com\",\"password\":\"123456\"}",
+ headers: { 'Content-Type' => 'application/json' })
+ .to_return(status: 201, body: f, headers: { 'Content-Type' => 'application/json' })
end
def stub_user
f = File.read(Rails.root.join('spec/support/gitlab_stubs/user.json'))
- stub_request(:get, "#{gitlab_url}api/v3/user?private_token=Wvjy2Krpb7y8xi93owUz").
- with(headers: { 'Content-Type' => 'application/json' }).
- to_return(status: 200, body: f, headers: { 'Content-Type' => 'application/json' })
+ stub_request(:get, "#{gitlab_url}api/v3/user?private_token=Wvjy2Krpb7y8xi93owUz")
+ .with(headers: { 'Content-Type' => 'application/json' })
+ .to_return(status: 200, body: f, headers: { 'Content-Type' => 'application/json' })
- stub_request(:get, "#{gitlab_url}api/v3/user?access_token=some_token").
- with(headers: { 'Content-Type' => 'application/json' }).
- to_return(status: 200, body: f, headers: { 'Content-Type' => 'application/json' })
+ stub_request(:get, "#{gitlab_url}api/v3/user?access_token=some_token")
+ .with(headers: { 'Content-Type' => 'application/json' })
+ .to_return(status: 200, body: f, headers: { 'Content-Type' => 'application/json' })
end
def stub_project_8
@@ -99,21 +99,21 @@ module StubGitlabCalls
def stub_projects
f = File.read(Rails.root.join('spec/support/gitlab_stubs/projects.json'))
- stub_request(:get, "#{gitlab_url}api/v3/projects.json?archived=false&ci_enabled_first=true&private_token=Wvjy2Krpb7y8xi93owUz").
- with(headers: { 'Content-Type' => 'application/json' }).
- to_return(status: 200, body: f, headers: { 'Content-Type' => 'application/json' })
+ stub_request(:get, "#{gitlab_url}api/v3/projects.json?archived=false&ci_enabled_first=true&private_token=Wvjy2Krpb7y8xi93owUz")
+ .with(headers: { 'Content-Type' => 'application/json' })
+ .to_return(status: 200, body: f, headers: { 'Content-Type' => 'application/json' })
end
def stub_projects_owned
- stub_request(:get, "#{gitlab_url}api/v3/projects/owned.json?archived=false&ci_enabled_first=true&private_token=Wvjy2Krpb7y8xi93owUz").
- with(headers: { 'Content-Type' => 'application/json' }).
- to_return(status: 200, body: "", headers: {})
+ stub_request(:get, "#{gitlab_url}api/v3/projects/owned.json?archived=false&ci_enabled_first=true&private_token=Wvjy2Krpb7y8xi93owUz")
+ .with(headers: { 'Content-Type' => 'application/json' })
+ .to_return(status: 200, body: "", headers: {})
end
def stub_ci_enable
- stub_request(:put, "#{gitlab_url}api/v3/projects/2/services/gitlab-ci.json?private_token=Wvjy2Krpb7y8xi93owUz").
- with(headers: { 'Content-Type' => 'application/json' }).
- to_return(status: 200, body: "", headers: {})
+ stub_request(:put, "#{gitlab_url}api/v3/projects/2/services/gitlab-ci.json?private_token=Wvjy2Krpb7y8xi93owUz")
+ .with(headers: { 'Content-Type' => 'application/json' })
+ .to_return(status: 200, body: "", headers: {})
end
def project_hash_array
diff --git a/spec/support/test_env.rb b/spec/support/test_env.rb
index 3f472e59c49..1c5267c290b 100644
--- a/spec/support/test_env.rb
+++ b/spec/support/test_env.rb
@@ -83,13 +83,13 @@ module TestEnv
end
def disable_mailer
- allow_any_instance_of(NotificationService).to receive(:mailer).
- and_return(double.as_null_object)
+ allow_any_instance_of(NotificationService).to receive(:mailer)
+ .and_return(double.as_null_object)
end
def enable_mailer
- allow_any_instance_of(NotificationService).to receive(:mailer).
- and_call_original
+ allow_any_instance_of(NotificationService).to receive(:mailer)
+ .and_call_original
end
def disable_pre_receive
diff --git a/spec/support/time_tracking_shared_examples.rb b/spec/support/time_tracking_shared_examples.rb
index b407b8097d2..0fa74f911f6 100644
--- a/spec/support/time_tracking_shared_examples.rb
+++ b/spec/support/time_tracking_shared_examples.rb
@@ -54,7 +54,7 @@ shared_examples 'issuable time tracker' do
it 'shows the help state when icon is clicked' do
page.within '.time-tracking-component-wrap' do
find('.help-button').click
- expect(page).to have_content 'Track time with slash commands'
+ expect(page).to have_content 'Track time with quick actions'
expect(page).to have_content 'Learn more'
end
end
@@ -64,7 +64,7 @@ shared_examples 'issuable time tracker' do
find('.help-button').click
find('.close-help-button').click
- expect(page).not_to have_content 'Track time with slash commands'
+ expect(page).not_to have_content 'Track time with quick actions'
expect(page).not_to have_content 'Learn more'
end
end
@@ -78,8 +78,8 @@ shared_examples 'issuable time tracker' do
end
end
-def submit_time(slash_command)
- fill_in 'note[note]', with: slash_command
+def submit_time(quick_action)
+ fill_in 'note[note]', with: quick_action
find('.js-comment-submit-button').trigger('click')
wait_for_requests
end
diff --git a/spec/support/update_invalid_issuable.rb b/spec/support/update_invalid_issuable.rb
index 365c34448ac..1490287681b 100644
--- a/spec/support/update_invalid_issuable.rb
+++ b/spec/support/update_invalid_issuable.rb
@@ -21,8 +21,8 @@ shared_examples 'update invalid issuable' do |klass|
context 'when updating causes conflicts' do
before do
- allow_any_instance_of(issuable.class).to receive(:save).
- and_raise(ActiveRecord::StaleObjectError.new(issuable, :save))
+ allow_any_instance_of(issuable.class).to receive(:save)
+ .and_raise(ActiveRecord::StaleObjectError.new(issuable, :save))
end
it 'renders edit when format is html' do
diff --git a/spec/support/user_activities_helpers.rb b/spec/support/user_activities_helpers.rb
index f7ca9a31edd..44feb104644 100644
--- a/spec/support/user_activities_helpers.rb
+++ b/spec/support/user_activities_helpers.rb
@@ -1,7 +1,7 @@
module UserActivitiesHelpers
def user_activity(user)
- Gitlab::UserActivities.new.
- find { |k, _| k == user.id.to_s }&.
+ Gitlab::UserActivities.new
+ .find { |k, _| k == user.id.to_s }&.
second
end
end
diff --git a/spec/support/wait_for_requests.rb b/spec/support/wait_for_requests.rb
index 1cbe609c0e0..b5c3c0f55b8 100644
--- a/spec/support/wait_for_requests.rb
+++ b/spec/support/wait_for_requests.rb
@@ -53,9 +53,3 @@ module WaitForRequests
Capybara.current_driver == Capybara.javascript_driver
end
end
-
-RSpec.configure do |config|
- config.after(:each, :js) do
- block_and_wait_for_requests_complete
- end
-end
diff --git a/spec/tasks/gitlab/backup_rake_spec.rb b/spec/tasks/gitlab/backup_rake_spec.rb
index 1e5f55a738a..71580a788d0 100644
--- a/spec/tasks/gitlab/backup_rake_spec.rb
+++ b/spec/tasks/gitlab/backup_rake_spec.rb
@@ -47,24 +47,24 @@ describe 'gitlab:app namespace rake task' do
allow(Kernel).to receive(:system).and_return(true)
allow(FileUtils).to receive(:cp_r).and_return(true)
allow(FileUtils).to receive(:mv).and_return(true)
- allow(Rake::Task["gitlab:shell:setup"]).
- to receive(:invoke).and_return(true)
+ allow(Rake::Task["gitlab:shell:setup"])
+ .to receive(:invoke).and_return(true)
ENV['force'] = 'yes'
end
let(:gitlab_version) { Gitlab::VERSION }
it 'fails on mismatch' do
- allow(YAML).to receive(:load_file).
- and_return({ gitlab_version: "not #{gitlab_version}" })
+ allow(YAML).to receive(:load_file)
+ .and_return({ gitlab_version: "not #{gitlab_version}" })
- expect { run_rake_task('gitlab:backup:restore') }.
- to raise_error(SystemExit)
+ expect { run_rake_task('gitlab:backup:restore') }
+ .to raise_error(SystemExit)
end
it 'invokes restoration on match' do
- allow(YAML).to receive(:load_file).
- and_return({ gitlab_version: gitlab_version })
+ allow(YAML).to receive(:load_file)
+ .and_return({ gitlab_version: gitlab_version })
expect(Rake::Task['gitlab:db:drop_tables']).to receive(:invoke)
expect(Rake::Task['gitlab:backup:db:restore']).to receive(:invoke)
expect(Rake::Task['gitlab:backup:repo:restore']).to receive(:invoke)
@@ -310,8 +310,8 @@ describe 'gitlab:app namespace rake task' do
end
it 'does not invoke repositories restore' do
- allow(Rake::Task['gitlab:shell:setup']).
- to receive(:invoke).and_return(true)
+ allow(Rake::Task['gitlab:shell:setup'])
+ .to receive(:invoke).and_return(true)
allow($stdout).to receive :write
expect(Rake::Task['gitlab:db:drop_tables']).to receive :invoke
diff --git a/spec/tasks/gitlab/gitaly_rake_spec.rb b/spec/tasks/gitlab/gitaly_rake_spec.rb
index cfa6c9ca8ce..d42d2423f15 100644
--- a/spec/tasks/gitlab/gitaly_rake_spec.rb
+++ b/spec/tasks/gitlab/gitaly_rake_spec.rb
@@ -20,8 +20,8 @@ describe 'gitlab:gitaly namespace rake task' do
context 'when an underlying Git command fail' do
it 'aborts and display a help message' do
- expect_any_instance_of(Object).
- to receive(:checkout_or_clone_version).and_raise 'Git error'
+ expect_any_instance_of(Object)
+ .to receive(:checkout_or_clone_version).and_raise 'Git error'
expect { run_rake_task('gitlab:gitaly:install', clone_path) }.to raise_error 'Git error'
end
@@ -33,8 +33,8 @@ describe 'gitlab:gitaly namespace rake task' do
end
it 'calls checkout_or_clone_version with the right arguments' do
- expect_any_instance_of(Object).
- to receive(:checkout_or_clone_version).with(version: version, repo: repo, target_dir: clone_path)
+ expect_any_instance_of(Object)
+ .to receive(:checkout_or_clone_version).with(version: version, repo: repo, target_dir: clone_path)
run_rake_task('gitlab:gitaly:install', clone_path)
end
@@ -89,6 +89,7 @@ describe 'gitlab:gitaly namespace rake task' do
}
}
allow(Gitlab.config.repositories).to receive(:storages).and_return(config)
+ allow(Rails.env).to receive(:test?).and_return(false)
expected_output = ''
Timecop.freeze do
@@ -105,8 +106,8 @@ describe 'gitlab:gitaly namespace rake task' do
TOML
end
- expect { run_rake_task('gitlab:gitaly:storage_config')}.
- to output(expected_output).to_stdout
+ expect { run_rake_task('gitlab:gitaly:storage_config')}
+ .to output(expected_output).to_stdout
parsed_output = TOML.parse(expected_output)
config.each do |name, params|
diff --git a/spec/tasks/gitlab/task_helpers_spec.rb b/spec/tasks/gitlab/task_helpers_spec.rb
index 3d9ba7cdc6f..91cc684d032 100644
--- a/spec/tasks/gitlab/task_helpers_spec.rb
+++ b/spec/tasks/gitlab/task_helpers_spec.rb
@@ -60,8 +60,8 @@ describe Gitlab::TaskHelpers do
describe '#clone_repo' do
it 'clones the repo in the target dir' do
- expect(subject).
- to receive(:run_command!).with(%W[#{Gitlab.config.git.bin_path} clone -- #{repo} #{clone_path}])
+ expect(subject)
+ .to receive(:run_command!).with(%W[#{Gitlab.config.git.bin_path} clone -- #{repo} #{clone_path}])
subject.clone_repo(repo, clone_path)
end
@@ -69,10 +69,10 @@ describe Gitlab::TaskHelpers do
describe '#checkout_version' do
it 'clones the repo in the target dir' do
- expect(subject).
- to receive(:run_command!).with(%W[#{Gitlab.config.git.bin_path} -C #{clone_path} fetch --quiet])
- expect(subject).
- to receive(:run_command!).with(%W[#{Gitlab.config.git.bin_path} -C #{clone_path} checkout --quiet #{tag}])
+ expect(subject)
+ .to receive(:run_command!).with(%W[#{Gitlab.config.git.bin_path} -C #{clone_path} fetch --quiet])
+ expect(subject)
+ .to receive(:run_command!).with(%W[#{Gitlab.config.git.bin_path} -C #{clone_path} checkout --quiet #{tag}])
subject.checkout_version(tag, clone_path)
end
@@ -80,8 +80,8 @@ describe Gitlab::TaskHelpers do
describe '#reset_to_version' do
it 'resets --hard to the given version' do
- expect(subject).
- to receive(:run_command!).with(%W[#{Gitlab.config.git.bin_path} -C #{clone_path} reset --hard #{tag}])
+ expect(subject)
+ .to receive(:run_command!).with(%W[#{Gitlab.config.git.bin_path} -C #{clone_path} reset --hard #{tag}])
subject.reset_to_version(tag, clone_path)
end
diff --git a/spec/tasks/gitlab/workhorse_rake_spec.rb b/spec/tasks/gitlab/workhorse_rake_spec.rb
index 63d1cf2bbe5..1b68f3044a4 100644
--- a/spec/tasks/gitlab/workhorse_rake_spec.rb
+++ b/spec/tasks/gitlab/workhorse_rake_spec.rb
@@ -20,8 +20,8 @@ describe 'gitlab:workhorse namespace rake task' do
context 'when an underlying Git command fail' do
it 'aborts and display a help message' do
- expect_any_instance_of(Object).
- to receive(:checkout_or_clone_version).and_raise 'Git error'
+ expect_any_instance_of(Object)
+ .to receive(:checkout_or_clone_version).and_raise 'Git error'
expect { run_rake_task('gitlab:workhorse:install', clone_path) }.to raise_error 'Git error'
end
@@ -33,8 +33,8 @@ describe 'gitlab:workhorse namespace rake task' do
end
it 'calls checkout_or_clone_version with the right arguments' do
- expect_any_instance_of(Object).
- to receive(:checkout_or_clone_version).with(version: version, repo: repo, target_dir: clone_path)
+ expect_any_instance_of(Object)
+ .to receive(:checkout_or_clone_version).with(version: version, repo: repo, target_dir: clone_path)
run_rake_task('gitlab:workhorse:install', clone_path)
end
diff --git a/spec/validators/dynamic_path_validator_spec.rb b/spec/validators/dynamic_path_validator_spec.rb
index 8dbf3eecd23..8bd5306ff98 100644
--- a/spec/validators/dynamic_path_validator_spec.rb
+++ b/spec/validators/dynamic_path_validator_spec.rb
@@ -84,5 +84,14 @@ describe DynamicPathValidator do
expect(group.errors[:path]).to include('users is a reserved name')
end
+
+ it 'updating to an invalid path is not allowed' do
+ project = create(:empty_project)
+ project.path = 'update'
+
+ validator.validate_each(project, :path, 'update')
+
+ expect(project.errors[:path]).to include('update is a reserved name')
+ end
end
end
diff --git a/spec/views/devise/shared/_signin_box.html.haml_spec.rb b/spec/views/devise/shared/_signin_box.html.haml_spec.rb
index 1397bfa5864..9adbb0476be 100644
--- a/spec/views/devise/shared/_signin_box.html.haml_spec.rb
+++ b/spec/views/devise/shared/_signin_box.html.haml_spec.rb
@@ -31,7 +31,7 @@ describe 'devise/shared/_signin_box' do
def enable_crowd
allow(view).to receive(:form_based_providers).and_return([:crowd])
allow(view).to receive(:crowd_enabled?).and_return(true)
- allow(view).to receive(:omniauth_authorize_path).with(:user, :crowd).
- and_return('/crowd')
+ allow(view).to receive(:omniauth_authorize_path).with(:user, :crowd)
+ .and_return('/crowd')
end
end
diff --git a/spec/views/profiles/show.html.haml_spec.rb b/spec/views/profiles/show.html.haml_spec.rb
new file mode 100644
index 00000000000..e89a8cb9626
--- /dev/null
+++ b/spec/views/profiles/show.html.haml_spec.rb
@@ -0,0 +1,19 @@
+require 'spec_helper'
+
+describe 'profiles/show' do
+ let(:user) { create(:user) }
+
+ before do
+ assign(:user, user)
+ allow(controller).to receive(:current_user).and_return(user)
+ end
+
+ context 'when the profile page is opened' do
+ it 'displays the correct elements' do
+ render
+
+ expect(rendered).to have_field('user_name', user.name)
+ expect(rendered).to have_field('user_id', user.id)
+ end
+ end
+end
diff --git a/spec/views/projects/notes/_more_actions_dropdown.html.haml_spec.rb b/spec/views/projects/notes/_more_actions_dropdown.html.haml_spec.rb
new file mode 100644
index 00000000000..e56c0f6be03
--- /dev/null
+++ b/spec/views/projects/notes/_more_actions_dropdown.html.haml_spec.rb
@@ -0,0 +1,41 @@
+require 'spec_helper'
+
+describe 'projects/notes/_more_actions_dropdown', :view do
+ let(:author_user) { create(:user) }
+ let(:not_author_user) { create(:user) }
+
+ let(:project) { create(:empty_project) }
+ let(:issue) { create(:issue, project: project) }
+ let!(:note) { create(:note_on_issue, author: author_user, noteable: issue, project: project) }
+
+ before do
+ assign(:project, project)
+ end
+
+ it 'shows Report as abuse button if not editable and not current users comment' do
+ render 'projects/notes/more_actions_dropdown', current_user: not_author_user, note_editable: false, note: note
+
+ expect(rendered).to have_link('Report as abuse')
+ end
+
+ it 'does not show the More actions button if not editable and current users comment' do
+ render 'projects/notes/more_actions_dropdown', current_user: author_user, note_editable: false, note: note
+
+ expect(rendered).not_to have_selector('.dropdown.more-actions')
+ end
+
+ it 'shows Report as abuse, Edit and Delete buttons if editable and not current users comment' do
+ render 'projects/notes/more_actions_dropdown', current_user: not_author_user, note_editable: true, note: note
+
+ expect(rendered).to have_link('Report as abuse')
+ expect(rendered).to have_button('Edit comment')
+ expect(rendered).to have_link('Delete comment')
+ end
+
+ it 'shows Edit and Delete buttons if editable and current users comment' do
+ render 'projects/notes/more_actions_dropdown', current_user: author_user, note_editable: true, note: note
+
+ expect(rendered).to have_button('Edit comment')
+ expect(rendered).to have_link('Delete comment')
+ end
+end
diff --git a/spec/views/shared/notes/_form.html.haml_spec.rb b/spec/views/shared/notes/_form.html.haml_spec.rb
index d7d0a5bf56a..cae6bee2776 100644
--- a/spec/views/shared/notes/_form.html.haml_spec.rb
+++ b/spec/views/shared/notes/_form.html.haml_spec.rb
@@ -20,8 +20,8 @@ describe 'shared/notes/_form' do
context "with a note on #{noteable}" do
let(:note) { build(:"note_on_#{noteable}", project: project) }
- it 'says that markdown and slash commands are supported' do
- expect(rendered).to have_content('Markdown and slash commands are supported')
+ it 'says that markdown and quick actions are supported' do
+ expect(rendered).to have_content('Markdown and quick actions are supported')
end
end
end
@@ -29,7 +29,7 @@ describe 'shared/notes/_form' do
context 'with a note on a commit' do
let(:note) { build(:note_on_commit, project: project) }
- it 'says that only markdown is supported, not slash commands' do
+ it 'says that only markdown is supported, not quick actions' do
expect(rendered).to have_content('Markdown is supported')
end
end
diff --git a/spec/workers/background_migration_worker_spec.rb b/spec/workers/background_migration_worker_spec.rb
index 0d742ae9dc7..85939429feb 100644
--- a/spec/workers/background_migration_worker_spec.rb
+++ b/spec/workers/background_migration_worker_spec.rb
@@ -3,9 +3,9 @@ require 'spec_helper'
describe BackgroundMigrationWorker do
describe '.perform' do
it 'performs a background migration' do
- expect(Gitlab::BackgroundMigration).
- to receive(:perform).
- with('Foo', [10, 20])
+ expect(Gitlab::BackgroundMigration)
+ .to receive(:perform)
+ .with('Foo', [10, 20])
described_class.new.perform('Foo', [10, 20])
end
diff --git a/spec/workers/delete_user_worker_spec.rb b/spec/workers/delete_user_worker_spec.rb
index 5912dd76262..36594515005 100644
--- a/spec/workers/delete_user_worker_spec.rb
+++ b/spec/workers/delete_user_worker_spec.rb
@@ -5,15 +5,15 @@ describe DeleteUserWorker do
let!(:current_user) { create(:user) }
it "calls the DeleteUserWorker with the params it was given" do
- expect_any_instance_of(Users::DestroyService).to receive(:execute).
- with(user, {})
+ expect_any_instance_of(Users::DestroyService).to receive(:execute)
+ .with(user, {})
described_class.new.perform(current_user.id, user.id)
end
it "uses symbolized keys" do
- expect_any_instance_of(Users::DestroyService).to receive(:execute).
- with(user, test: "test")
+ expect_any_instance_of(Users::DestroyService).to receive(:execute)
+ .with(user, test: "test")
described_class.new.perform(current_user.id, user.id, "test" => "test")
end
diff --git a/spec/workers/every_sidekiq_worker_spec.rb b/spec/workers/every_sidekiq_worker_spec.rb
index fc9adf47c1e..30908534eb3 100644
--- a/spec/workers/every_sidekiq_worker_spec.rb
+++ b/spec/workers/every_sidekiq_worker_spec.rb
@@ -5,8 +5,8 @@ describe 'Every Sidekiq worker' do
root = Rails.root.join('app', 'workers')
concerns = root.join('concerns').to_s
- workers = Dir[root.join('**', '*.rb')].
- reject { |path| path.start_with?(concerns) }
+ workers = Dir[root.join('**', '*.rb')]
+ .reject { |path| path.start_with?(concerns) }
workers.map do |path|
ns = Pathname.new(path).relative_path_from(root).to_s.gsub('.rb', '')
@@ -22,9 +22,9 @@ describe 'Every Sidekiq worker' do
end
it 'uses the cronjob queue when the worker runs as a cronjob' do
- cron_workers = Settings.cron_jobs.
- map { |job_name, options| options['job_class'].constantize }.
- to_set
+ cron_workers = Settings.cron_jobs
+ .map { |job_name, options| options['job_class'].constantize }
+ .to_set
workers.each do |worker|
next unless cron_workers.include?(worker)
diff --git a/spec/workers/expire_pipeline_cache_worker_spec.rb b/spec/workers/expire_pipeline_cache_worker_spec.rb
index 28e5b706803..e4f78999489 100644
--- a/spec/workers/expire_pipeline_cache_worker_spec.rb
+++ b/spec/workers/expire_pipeline_cache_worker_spec.rb
@@ -37,8 +37,8 @@ describe ExpirePipelineCacheWorker do
end
it 'updates the cached status for a project' do
- expect(Gitlab::Cache::Ci::ProjectPipelineStatus).to receive(:update_for_pipeline).
- with(pipeline)
+ expect(Gitlab::Cache::Ci::ProjectPipelineStatus).to receive(:update_for_pipeline)
+ .with(pipeline)
subject.perform(pipeline.id)
end
diff --git a/spec/workers/git_garbage_collect_worker_spec.rb b/spec/workers/git_garbage_collect_worker_spec.rb
index f443bb2c9b4..309b3172da1 100644
--- a/spec/workers/git_garbage_collect_worker_spec.rb
+++ b/spec/workers/git_garbage_collect_worker_spec.rb
@@ -11,8 +11,8 @@ describe GitGarbageCollectWorker do
describe "#perform" do
it "flushes ref caches when the task is 'gc'" do
expect(subject).to receive(:command).with(:gc).and_return([:the, :command])
- expect(Gitlab::Popen).to receive(:popen).
- with([:the, :command], project.repository.path_to_repo).and_return(["", 0])
+ expect(Gitlab::Popen).to receive(:popen)
+ .with([:the, :command], project.repository.path_to_repo).and_return(["", 0])
expect_any_instance_of(Repository).to receive(:after_create_branch).and_call_original
expect_any_instance_of(Repository).to receive(:branch_names).and_call_original
diff --git a/spec/workers/new_note_worker_spec.rb b/spec/workers/new_note_worker_spec.rb
index 8fdbb35afd0..575361c93d4 100644
--- a/spec/workers/new_note_worker_spec.rb
+++ b/spec/workers/new_note_worker_spec.rb
@@ -24,8 +24,8 @@ describe NewNoteWorker do
let(:unexistent_note_id) { 999 }
it 'logs NewNoteWorker process skipping' do
- expect(Rails.logger).to receive(:error).
- with("NewNoteWorker: couldn't find note with ID=999, skipping job")
+ expect(Rails.logger).to receive(:error)
+ .with("NewNoteWorker: couldn't find note with ID=999, skipping job")
described_class.new.perform(unexistent_note_id)
end
diff --git a/spec/workers/post_receive_spec.rb b/spec/workers/post_receive_spec.rb
index 3c93da63f2e..cc9bc29c6cc 100644
--- a/spec/workers/post_receive_spec.rb
+++ b/spec/workers/post_receive_spec.rb
@@ -32,7 +32,7 @@ describe PostReceive do
context "with an absolute path as the project identifier" do
it "searches the project by full path" do
- expect(Project).to receive(:find_by_full_path).with(project.full_path).and_call_original
+ expect(Project).to receive(:find_by_full_path).with(project.full_path, follow_redirects: true).and_call_original
described_class.new.perform(pwd(project), key_id, base64_changes)
end
@@ -123,9 +123,9 @@ describe PostReceive do
end
it "does not run if the author is not in the project" do
- allow_any_instance_of(Gitlab::GitPostReceive).
- to receive(:identify_using_ssh_key).
- and_return(nil)
+ allow_any_instance_of(Gitlab::GitPostReceive)
+ .to receive(:identify_using_ssh_key)
+ .and_return(nil)
expect(project).not_to receive(:execute_hooks)
diff --git a/spec/workers/process_commit_worker_spec.rb b/spec/workers/process_commit_worker_spec.rb
index 4e036285e8c..6ebc94bb544 100644
--- a/spec/workers/process_commit_worker_spec.rb
+++ b/spec/workers/process_commit_worker_spec.rb
@@ -48,11 +48,11 @@ describe ProcessCommitWorker do
describe '#process_commit_message' do
context 'when pushing to the default branch' do
it 'closes issues that should be closed per the commit message' do
- allow(commit).to receive(:safe_message).
- and_return("Closes #{issue.to_reference}")
+ allow(commit).to receive(:safe_message)
+ .and_return("Closes #{issue.to_reference}")
- expect(worker).to receive(:close_issues).
- with(project, user, user, commit, [issue])
+ expect(worker).to receive(:close_issues)
+ .with(project, user, user, commit, [issue])
worker.process_commit_message(project, commit, user, user, true)
end
@@ -60,8 +60,8 @@ describe ProcessCommitWorker do
context 'when pushing to a non-default branch' do
it 'does not close any issues' do
- allow(commit).to receive(:safe_message).
- and_return("Closes #{issue.to_reference}")
+ allow(commit).to receive(:safe_message)
+ .and_return("Closes #{issue.to_reference}")
expect(worker).not_to receive(:close_issues)
@@ -102,8 +102,8 @@ describe ProcessCommitWorker do
describe '#update_issue_metrics' do
it 'updates any existing issue metrics' do
- allow(commit).to receive(:safe_message).
- and_return("Closes #{issue.to_reference}")
+ allow(commit).to receive(:safe_message)
+ .and_return("Closes #{issue.to_reference}")
worker.update_issue_metrics(commit, user)
@@ -113,8 +113,8 @@ describe ProcessCommitWorker do
end
it "doesn't execute any queries with false conditions" do
- allow(commit).to receive(:safe_message).
- and_return("Lorem Ipsum")
+ allow(commit).to receive(:safe_message)
+ .and_return("Lorem Ipsum")
expect { worker.update_issue_metrics(commit, user) }.not_to make_queries_matching(/WHERE (?:1=0|0=1)/)
end
@@ -128,8 +128,8 @@ describe ProcessCommitWorker do
end
it 'parses date strings into Time instances' do
- commit = worker.
- build_commit(project, id: '123', authored_date: Time.now.to_s)
+ commit = worker
+ .build_commit(project, id: '123', authored_date: Time.now.to_s)
expect(commit.authored_date).to be_an_instance_of(Time)
end
diff --git a/spec/workers/project_cache_worker_spec.rb b/spec/workers/project_cache_worker_spec.rb
index a4ba5f7c943..6b1f2ff3227 100644
--- a/spec/workers/project_cache_worker_spec.rb
+++ b/spec/workers/project_cache_worker_spec.rb
@@ -7,8 +7,8 @@ describe ProjectCacheWorker do
describe '#perform' do
before do
- allow_any_instance_of(Gitlab::ExclusiveLease).to receive(:try_obtain).
- and_return(true)
+ allow_any_instance_of(Gitlab::ExclusiveLease).to receive(:try_obtain)
+ .and_return(true)
end
context 'with a non-existing project' do
@@ -39,9 +39,9 @@ describe ProjectCacheWorker do
end
it 'refreshes the method caches' do
- expect_any_instance_of(Repository).to receive(:refresh_method_caches).
- with(%i(readme)).
- and_call_original
+ expect_any_instance_of(Repository).to receive(:refresh_method_caches)
+ .with(%i(readme))
+ .and_call_original
worker.perform(project.id, %w(readme))
end
@@ -51,9 +51,9 @@ describe ProjectCacheWorker do
allow(MarkupHelper).to receive(:gitlab_markdown?).and_return(false)
allow(MarkupHelper).to receive(:plain?).and_return(true)
- expect_any_instance_of(Repository).to receive(:refresh_method_caches).
- with(%i(readme)).
- and_call_original
+ expect_any_instance_of(Repository).to receive(:refresh_method_caches)
+ .with(%i(readme))
+ .and_call_original
worker.perform(project.id, %w(readme))
end
end
@@ -63,9 +63,9 @@ describe ProjectCacheWorker do
describe '#update_statistics' do
context 'when a lease could not be obtained' do
it 'does not update the repository size' do
- allow(worker).to receive(:try_obtain_lease_for).
- with(project.id, :update_statistics).
- and_return(false)
+ allow(worker).to receive(:try_obtain_lease_for)
+ .with(project.id, :update_statistics)
+ .and_return(false)
expect(statistics).not_to receive(:refresh!)
@@ -75,9 +75,9 @@ describe ProjectCacheWorker do
context 'when a lease could be obtained' do
it 'updates the project statistics' do
- allow(worker).to receive(:try_obtain_lease_for).
- with(project.id, :update_statistics).
- and_return(true)
+ allow(worker).to receive(:try_obtain_lease_for)
+ .with(project.id, :update_statistics)
+ .and_return(true)
expect(statistics).to receive(:refresh!)
.with(only: %i(repository_size))
diff --git a/spec/workers/propagate_service_template_worker_spec.rb b/spec/workers/propagate_service_template_worker_spec.rb
index 7040d5ef81c..b8b65ead9b3 100644
--- a/spec/workers/propagate_service_template_worker_spec.rb
+++ b/spec/workers/propagate_service_template_worker_spec.rb
@@ -15,8 +15,8 @@ describe PropagateServiceTemplateWorker do
end
before do
- allow_any_instance_of(Gitlab::ExclusiveLease).to receive(:try_obtain).
- and_return(true)
+ allow_any_instance_of(Gitlab::ExclusiveLease).to receive(:try_obtain)
+ .and_return(true)
end
describe '#perform' do
diff --git a/spec/workers/repository_fork_worker_spec.rb b/spec/workers/repository_fork_worker_spec.rb
index 6ea5569b438..d9e9409840f 100644
--- a/spec/workers/repository_fork_worker_spec.rb
+++ b/spec/workers/repository_fork_worker_spec.rb
@@ -35,11 +35,11 @@ describe RepositoryForkWorker do
fork_project.namespace.full_path
).and_return(true)
- expect_any_instance_of(Repository).to receive(:expire_emptiness_caches).
- and_call_original
+ expect_any_instance_of(Repository).to receive(:expire_emptiness_caches)
+ .and_call_original
- expect_any_instance_of(Repository).to receive(:expire_exists_cache).
- and_call_original
+ expect_any_instance_of(Repository).to receive(:expire_exists_cache)
+ .and_call_original
subject.perform(project.id, '/test/path', project.full_path,
fork_project.namespace.full_path)
diff --git a/spec/workers/repository_import_worker_spec.rb b/spec/workers/repository_import_worker_spec.rb
index 9c277c501f1..6b30dabc80e 100644
--- a/spec/workers/repository_import_worker_spec.rb
+++ b/spec/workers/repository_import_worker_spec.rb
@@ -8,8 +8,8 @@ describe RepositoryImportWorker do
describe '#perform' do
context 'when the import was successful' do
it 'imports a project' do
- expect_any_instance_of(Projects::ImportService).to receive(:execute).
- and_return({ status: :ok })
+ expect_any_instance_of(Projects::ImportService).to receive(:execute)
+ .and_return({ status: :ok })
expect_any_instance_of(Repository).to receive(:expire_emptiness_caches)
expect_any_instance_of(Project).to receive(:import_finish)