summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.codeclimate.yml15
-rw-r--r--.gitlab-ci.yml15
-rw-r--r--.rubocop.yml7
-rw-r--r--app/assets/javascripts/commit/pipelines/pipelines_table.js2
-rw-r--r--app/assets/javascripts/environments/components/environment_item.vue2
-rw-r--r--app/assets/javascripts/environments/stores/environments_store.js1
-rw-r--r--app/assets/javascripts/milestone.js24
-rw-r--r--app/assets/javascripts/notes.js30
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines.vue289
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_actions.js91
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_actions.vue88
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_artifacts.js33
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_artifacts.vue51
-rw-r--r--app/assets/javascripts/pipelines/components/time_ago.js98
-rw-r--r--app/assets/javascripts/pipelines/components/time_ago.vue85
-rw-r--r--app/assets/javascripts/pipelines/index.js22
-rw-r--r--app/assets/javascripts/pipelines/pipelines.js293
-rw-r--r--app/assets/javascripts/pipelines/pipelines_bundle.js24
-rw-r--r--app/assets/javascripts/vue_shared/components/commit.js159
-rw-r--r--app/assets/javascripts/vue_shared/components/commit.vue166
-rw-r--r--app/assets/javascripts/vue_shared/components/pipelines_table.js55
-rw-r--r--app/assets/javascripts/vue_shared/components/pipelines_table.vue55
-rw-r--r--app/assets/javascripts/vue_shared/components/pipelines_table_row.vue (renamed from app/assets/javascripts/vue_shared/components/pipelines_table_row.js)154
-rw-r--r--app/assets/stylesheets/framework/selects.scss6
-rw-r--r--app/assets/stylesheets/framework/tw_bootstrap_variables.scss6
-rw-r--r--app/assets/stylesheets/pages/events.scss1
-rw-r--r--app/controllers/admin/application_settings_controller.rb2
-rw-r--r--app/helpers/application_helper.rb4
-rw-r--r--app/helpers/diff_helper.rb24
-rw-r--r--app/models/application_setting.rb14
-rw-r--r--app/models/blob_viewer/server_side.rb14
-rw-r--r--app/models/diff_viewer/added.rb8
-rw-r--r--app/models/diff_viewer/base.rb87
-rw-r--r--app/models/diff_viewer/client_side.rb10
-rw-r--r--app/models/diff_viewer/deleted.rb8
-rw-r--r--app/models/diff_viewer/image.rb12
-rw-r--r--app/models/diff_viewer/mode_changed.rb8
-rw-r--r--app/models/diff_viewer/no_preview.rb9
-rw-r--r--app/models/diff_viewer/not_diffable.rb9
-rw-r--r--app/models/diff_viewer/renamed.rb8
-rw-r--r--app/models/diff_viewer/rich.rb11
-rw-r--r--app/models/diff_viewer/server_side.rb26
-rw-r--r--app/models/diff_viewer/simple.rb11
-rw-r--r--app/models/diff_viewer/static.rb10
-rw-r--r--app/models/diff_viewer/text.rb15
-rw-r--r--app/models/environment.rb3
-rw-r--r--app/models/project_services/kubernetes_service.rb37
-rw-r--r--app/serializers/build_details_entity.rb2
-rw-r--r--app/services/slash_commands/interpret_service.rb2
-rw-r--r--app/views/admin/application_settings/_form.html.haml14
-rw-r--r--app/views/help/index.html.haml20
-rw-r--r--app/views/help/show.html.haml2
-rw-r--r--app/views/projects/diffs/_collapsed.html.haml5
-rw-r--r--app/views/projects/diffs/_content.html.haml27
-rw-r--r--app/views/projects/diffs/_render_error.html.haml6
-rw-r--r--app/views/projects/diffs/_viewer.html.haml16
-rw-r--r--app/views/projects/diffs/viewers/_added.html.haml2
-rw-r--r--app/views/projects/diffs/viewers/_deleted.html.haml2
-rw-r--r--app/views/projects/diffs/viewers/_image.html.haml1
-rw-r--r--app/views/projects/diffs/viewers/_mode_changed.html.haml3
-rw-r--r--app/views/projects/diffs/viewers/_no_preview.html.haml2
-rw-r--r--app/views/projects/diffs/viewers/_not_diffable.html.haml2
-rw-r--r--app/views/projects/diffs/viewers/_renamed.html.haml2
-rw-r--r--app/views/projects/diffs/viewers/_text.html.haml2
-rw-r--r--changelogs/unreleased/32470-pag-links.yml4
-rw-r--r--changelogs/unreleased/dm-diff-viewers.yml4
-rw-r--r--changelogs/unreleased/dm-fix-parser-cache.yml4
-rw-r--r--changelogs/unreleased/dm-target-branch-slash-command-desc.yml4
-rw-r--r--changelogs/unreleased/help-landing-page-customizations.yml4
-rw-r--r--changelogs/unreleased/zj-raise-etag-route-regex-miss.yml4
-rw-r--r--config/webpack.config.js2
-rw-r--r--db/migrate/20170602154736_add_help_page_hide_commercial_content_to_application_settings.rb9
-rw-r--r--db/migrate/20170602154813_add_help_page_support_url_to_application_settings.rb9
-rw-r--r--db/schema.rb3
-rw-r--r--doc/user/project/integrations/jira.md2
-rw-r--r--lib/api/entities.rb3
-rw-r--r--lib/api/settings.rb4
-rw-r--r--lib/banzai/reference_parser/base_parser.rb2
-rw-r--r--lib/gitlab/diff/file.rb109
-rw-r--r--lib/gitlab/etag_caching/middleware.rb2
-rw-r--r--lib/gitlab/etag_caching/router.rb4
-rw-r--r--lib/gitlab/etag_caching/store.rb2
-rw-r--r--lib/gitlab/git/diff.rb2
-rw-r--r--lib/gitlab/git/diff_collection.rb2
-rw-r--r--lib/gitlab/kubernetes.rb12
-rw-r--r--rubocop/cop/rspec/single_line_hook.rb38
-rw-r--r--rubocop/rubocop.rb1
-rw-r--r--spec/controllers/admin/identities_controller_spec.rb5
-rw-r--r--spec/controllers/admin/services_controller_spec.rb4
-rw-r--r--spec/controllers/autocomplete_controller_spec.rb4
-rw-r--r--spec/controllers/groups/group_members_controller_spec.rb56
-rw-r--r--spec/controllers/notification_settings_controller_spec.rb13
-rw-r--r--spec/controllers/profiles/personal_access_tokens_controller_spec.rb8
-rw-r--r--spec/controllers/projects/commit_controller_spec.rb8
-rw-r--r--spec/controllers/projects/compare_controller_spec.rb12
-rw-r--r--spec/controllers/projects/forks_controller_spec.rb16
-rw-r--r--spec/controllers/projects/group_links_controller_spec.rb5
-rw-r--r--spec/controllers/projects/issues_controller_spec.rb29
-rw-r--r--spec/controllers/projects/jobs_controller_spec.rb136
-rw-r--r--spec/controllers/projects/merge_requests_controller_spec.rb61
-rw-r--r--spec/controllers/projects/project_members_controller_spec.rb61
-rw-r--r--spec/controllers/projects/snippets_controller_spec.rb20
-rw-r--r--spec/controllers/projects/tags_controller_spec.rb8
-rw-r--r--spec/controllers/projects_controller_spec.rb12
-rw-r--r--spec/controllers/search_controller_spec.rb4
-rw-r--r--spec/controllers/sent_notifications_controller_spec.rb25
-rw-r--r--spec/controllers/sessions_controller_spec.rb8
-rw-r--r--spec/controllers/snippets_controller_spec.rb4
-rw-r--r--spec/controllers/users_controller_spec.rb8
-rw-r--r--spec/features/admin/admin_runners_spec.rb5
-rw-r--r--spec/features/admin/admin_settings_spec.rb5
-rw-r--r--spec/features/admin/admin_users_impersonation_tokens_spec.rb4
-rw-r--r--spec/features/admin/admin_users_spec.rb9
-rw-r--r--spec/features/dashboard/merge_requests_spec.rb4
-rw-r--r--spec/features/dashboard/project_member_activity_index_spec.rb12
-rw-r--r--spec/features/expand_collapse_diffs_spec.rb6
-rw-r--r--spec/features/groups/group_settings_spec.rb11
-rw-r--r--spec/features/groups_spec.rb8
-rw-r--r--spec/features/help_pages_spec.rb25
-rw-r--r--spec/features/issuables/default_sort_order_spec.rb8
-rw-r--r--spec/features/issues_spec.rb5
-rw-r--r--spec/features/login_spec.rb12
-rw-r--r--spec/features/merge_requests/conflicts_spec.rb8
-rw-r--r--spec/features/merge_requests/merge_immediately_with_pipeline_spec.rb4
-rw-r--r--spec/features/milestones/milestones_spec.rb10
-rw-r--r--spec/features/profiles/account_spec.rb9
-rw-r--r--spec/features/projects/blobs/blob_show_spec.rb3
-rw-r--r--spec/features/projects/diffs/diff_show_spec.rb133
-rw-r--r--spec/features/projects/jobs_spec.rb150
-rw-r--r--spec/features/projects/pipelines/pipeline_spec.rb20
-rw-r--r--spec/features/projects/pipelines/pipelines_spec.rb40
-rw-r--r--spec/features/projects/project_settings_spec.rb23
-rw-r--r--spec/features/protected_branches_spec.rb4
-rw-r--r--spec/features/protected_tags_spec.rb4
-rw-r--r--spec/features/runners_spec.rb9
-rw-r--r--spec/features/search_spec.rb4
-rw-r--r--spec/features/security/project/internal_access_spec.rb16
-rw-r--r--spec/features/security/project/public_access_spec.rb16
-rw-r--r--spec/features/signup_spec.rb8
-rw-r--r--spec/features/task_lists_spec.rb4
-rw-r--r--spec/features/todos/todos_sorting_spec.rb4
-rw-r--r--spec/features/triggers_spec.rb5
-rw-r--r--spec/features/u2f_spec.rb8
-rw-r--r--spec/features/unsubscribe_links_spec.rb4
-rw-r--r--spec/features/users_spec.rb4
-rw-r--r--spec/finders/issues_finder_spec.rb4
-rw-r--r--spec/finders/personal_access_tokens_finder_spec.rb84
-rw-r--r--spec/finders/personal_projects_finder_spec.rb4
-rw-r--r--spec/finders/todos_finder_spec.rb4
-rw-r--r--spec/helpers/application_helper_spec.rb20
-rw-r--r--spec/helpers/diff_helper_spec.rb39
-rw-r--r--spec/helpers/projects_helper_spec.rb4
-rw-r--r--spec/javascripts/notes_spec.js62
-rw-r--r--spec/javascripts/pipelines/pipelines_actions_spec.js2
-rw-r--r--spec/javascripts/pipelines/pipelines_artifacts_spec.js2
-rw-r--r--spec/javascripts/pipelines/pipelines_spec.js2
-rw-r--r--spec/javascripts/pipelines/time_ago_spec.js2
-rw-r--r--spec/javascripts/vue_shared/components/commit_spec.js2
-rw-r--r--spec/javascripts/vue_shared/components/pipelines_table_row_spec.js2
-rw-r--r--spec/javascripts/vue_shared/components/pipelines_table_spec.js2
-rw-r--r--spec/lib/banzai/filter/external_issue_reference_filter_spec.rb4
-rw-r--r--spec/lib/banzai/filter/redactor_filter_spec.rb8
-rw-r--r--spec/lib/banzai/reference_parser/base_parser_spec.rb2
-rw-r--r--spec/lib/banzai/reference_parser/commit_parser_spec.rb4
-rw-r--r--spec/lib/banzai/reference_parser/commit_range_parser_spec.rb4
-rw-r--r--spec/lib/banzai/reference_parser/external_issue_parser_spec.rb4
-rw-r--r--spec/lib/banzai/reference_parser/label_parser_spec.rb4
-rw-r--r--spec/lib/banzai/reference_parser/milestone_parser_spec.rb4
-rw-r--r--spec/lib/extracts_path_spec.rb5
-rw-r--r--spec/lib/gitlab/auth/unique_ips_limiter_spec.rb4
-rw-r--r--spec/lib/gitlab/badge/build/status_spec.rb8
-rw-r--r--spec/lib/gitlab/chat_commands/presenters/issue_search_spec.rb4
-rw-r--r--spec/lib/gitlab/checks/change_access_spec.rb8
-rw-r--r--spec/lib/gitlab/ci/config/entry/cache_spec.rb4
-rw-r--r--spec/lib/gitlab/ci/config/entry/environment_spec.rb4
-rw-r--r--spec/lib/gitlab/ci/config/entry/global_spec.rb24
-rw-r--r--spec/lib/gitlab/ci/config/entry/job_spec.rb16
-rw-r--r--spec/lib/gitlab/ci/config/entry/jobs_spec.rb8
-rw-r--r--spec/lib/gitlab/ci/config/entry/service_spec.rb4
-rw-r--r--spec/lib/gitlab/ci/config/entry/services_spec.rb4
-rw-r--r--spec/lib/gitlab/ci/status/build/cancelable_spec.rb4
-rw-r--r--spec/lib/gitlab/ci/status/build/common_spec.rb8
-rw-r--r--spec/lib/gitlab/ci/status/build/factory_spec.rb4
-rw-r--r--spec/lib/gitlab/ci/status/build/play_spec.rb4
-rw-r--r--spec/lib/gitlab/ci/status/build/retryable_spec.rb4
-rw-r--r--spec/lib/gitlab/ci/status/build/stop_spec.rb4
-rw-r--r--spec/lib/gitlab/ci/status/external/common_spec.rb4
-rw-r--r--spec/lib/gitlab/ci/status/pipeline/common_spec.rb4
-rw-r--r--spec/lib/gitlab/database_spec.rb16
-rw-r--r--spec/lib/gitlab/diff/file_spec.rb301
-rw-r--r--spec/lib/gitlab/etag_caching/middleware_spec.rb33
-rw-r--r--spec/lib/gitlab/etag_caching/router_spec.rb44
-rw-r--r--spec/lib/gitlab/gfm/reference_rewriter_spec.rb4
-rw-r--r--spec/lib/gitlab/git/repository_spec.rb40
-rw-r--r--spec/lib/gitlab/git_access_spec.rb68
-rw-r--r--spec/lib/gitlab/gitaly_client_spec.rb24
-rw-r--r--spec/lib/gitlab/highlight_spec.rb4
-rw-r--r--spec/lib/gitlab/i18n_spec.rb4
-rw-r--r--spec/lib/gitlab/kubernetes_spec.rb10
-rw-r--r--spec/lib/gitlab/ldap/adapter_spec.rb16
-rw-r--r--spec/lib/gitlab/ldap/user_spec.rb16
-rw-r--r--spec/lib/gitlab/middleware/rails_queue_duration_spec.rb8
-rw-r--r--spec/lib/gitlab/o_auth/auth_hash_spec.rb12
-rw-r--r--spec/lib/gitlab/o_auth/user_spec.rb84
-rw-r--r--spec/lib/gitlab/redis_spec.rb13
-rw-r--r--spec/lib/gitlab/saml/user_spec.rb62
-rw-r--r--spec/lib/gitlab/serializer/pagination_spec.rb4
-rw-r--r--spec/lib/gitlab/template/issue_template_spec.rb9
-rw-r--r--spec/lib/gitlab/template/merge_request_template_spec.rb9
-rw-r--r--spec/lib/json_web_token/rsa_token_spec.rb8
-rw-r--r--spec/lib/json_web_token/token_spec.rb5
-rw-r--r--spec/mailers/notify_spec.rb37
-rw-r--r--spec/migrations/rename_more_reserved_project_names_spec.rb4
-rw-r--r--spec/migrations/rename_reserved_project_names_spec.rb4
-rw-r--r--spec/models/application_setting_spec.rb4
-rw-r--r--spec/models/ci/build_spec.rb30
-rw-r--r--spec/models/ci/pipeline_spec.rb4
-rw-r--r--spec/models/commit_spec.rb12
-rw-r--r--spec/models/commit_status_spec.rb42
-rw-r--r--spec/models/concerns/access_requestable_spec.rb8
-rw-r--r--spec/models/concerns/issuable_spec.rb16
-rw-r--r--spec/models/concerns/mentionable_spec.rb4
-rw-r--r--spec/models/concerns/reactive_caching_spec.rb23
-rw-r--r--spec/models/concerns/token_authenticatable_spec.rb5
-rw-r--r--spec/models/diff_viewer/base_spec.rb150
-rw-r--r--spec/models/diff_viewer/server_side_spec.rb36
-rw-r--r--spec/models/generic_commit_status_spec.rb9
-rw-r--r--spec/models/group_spec.rb27
-rw-r--r--spec/models/issue_spec.rb18
-rw-r--r--spec/models/merge_request_diff_spec.rb8
-rw-r--r--spec/models/merge_request_spec.rb16
-rw-r--r--spec/models/note_spec.rb8
-rw-r--r--spec/models/project_services/bamboo_service_spec.rb8
-rw-r--r--spec/models/project_services/bugzilla_service_spec.rb8
-rw-r--r--spec/models/project_services/buildkite_service_spec.rb8
-rw-r--r--spec/models/project_services/campfire_service_spec.rb8
-rw-r--r--spec/models/project_services/chat_message/wiki_page_message_spec.rb40
-rw-r--r--spec/models/project_services/custom_issue_tracker_service_spec.rb8
-rw-r--r--spec/models/project_services/drone_ci_service_spec.rb8
-rw-r--r--spec/models/project_services/emails_on_push_service_spec.rb8
-rw-r--r--spec/models/project_services/external_wiki_service_spec.rb8
-rw-r--r--spec/models/project_services/flowdock_service_spec.rb8
-rw-r--r--spec/models/project_services/gemnasium_service_spec.rb8
-rw-r--r--spec/models/project_services/hipchat_service_spec.rb8
-rw-r--r--spec/models/project_services/irker_service_spec.rb8
-rw-r--r--spec/models/project_services/jira_service_spec.rb8
-rw-r--r--spec/models/project_services/kubernetes_service_spec.rb96
-rw-r--r--spec/models/project_services/microsoft_teams_service_spec.rb8
-rw-r--r--spec/models/project_services/pivotaltracker_service_spec.rb8
-rw-r--r--spec/models/project_services/prometheus_service_spec.rb8
-rw-r--r--spec/models/project_services/pushover_service_spec.rb8
-rw-r--r--spec/models/project_services/redmine_service_spec.rb8
-rw-r--r--spec/models/project_services/teamcity_service_spec.rb8
-rw-r--r--spec/models/project_spec.rb28
-rw-r--r--spec/models/project_team_spec.rb4
-rw-r--r--spec/models/project_wiki_spec.rb5
-rw-r--r--spec/models/route_spec.rb9
-rw-r--r--spec/models/user_spec.rb16
-rw-r--r--spec/policies/ci/build_policy_spec.rb12
-rw-r--r--spec/policies/project_snippet_policy_spec.rb12
-rw-r--r--spec/requests/api/award_emoji_spec.rb4
-rw-r--r--spec/requests/api/commit_statuses_spec.rb53
-rw-r--r--spec/requests/api/commits_spec.rb12
-rw-r--r--spec/requests/api/deploy_keys_spec.rb8
-rw-r--r--spec/requests/api/files_spec.rb4
-rw-r--r--spec/requests/api/helpers_spec.rb38
-rw-r--r--spec/requests/api/jobs_spec.rb114
-rw-r--r--spec/requests/api/keys_spec.rb4
-rw-r--r--spec/requests/api/labels_spec.rb12
-rw-r--r--spec/requests/api/milestones_spec.rb4
-rw-r--r--spec/requests/api/notes_spec.rb12
-rw-r--r--spec/requests/api/pipelines_spec.rb12
-rw-r--r--spec/requests/api/projects_spec.rb43
-rw-r--r--spec/requests/api/runner_spec.rb64
-rw-r--r--spec/requests/api/settings_spec.rb8
-rw-r--r--spec/requests/api/system_hooks_spec.rb4
-rw-r--r--spec/requests/api/templates_spec.rb12
-rw-r--r--spec/requests/api/users_spec.rb47
-rw-r--r--spec/requests/ci/api/builds_spec.rb12
-rw-r--r--spec/requests/ci/api/runners_spec.rb9
-rw-r--r--spec/requests/git_http_spec.rb23
-rw-r--r--spec/requests/jwt_controller_spec.rb4
-rw-r--r--spec/routing/project_routing_spec.rb8
-rw-r--r--spec/routing/routing_spec.rb4
-rw-r--r--spec/rubocop/cop/rspec/single_line_hook_spec.rb66
-rw-r--r--spec/serializers/environment_serializer_spec.rb12
-rw-r--r--spec/serializers/pipeline_details_entity_spec.rb8
-rw-r--r--spec/serializers/pipeline_entity_spec.rb8
-rw-r--r--spec/serializers/pipeline_serializer_spec.rb8
-rw-r--r--spec/services/auth/container_registry_authentication_service_spec.rb24
-rw-r--r--spec/services/ci/update_build_queue_service_spec.rb8
-rw-r--r--spec/services/create_deployment_service_spec.rb4
-rw-r--r--spec/services/groups/create_service_spec.rb8
-rw-r--r--spec/services/issues/create_service_spec.rb4
-rw-r--r--spec/services/issues/move_service_spec.rb10
-rw-r--r--spec/services/issues/update_service_spec.rb16
-rw-r--r--spec/services/members/create_service_spec.rb4
-rw-r--r--spec/services/merge_requests/build_service_spec.rb4
-rw-r--r--spec/services/merge_requests/create_service_spec.rb4
-rw-r--r--spec/services/merge_requests/merge_service_spec.rb4
-rw-r--r--spec/services/merge_requests/update_service_spec.rb12
-rw-r--r--spec/services/notes/slash_commands_service_spec.rb4
-rw-r--r--spec/services/pages_service_spec.rb12
-rw-r--r--spec/services/projects/transfer_service_spec.rb12
-rw-r--r--spec/services/slash_commands/interpret_service_spec.rb10
-rw-r--r--spec/services/spam_service_spec.rb4
-rw-r--r--spec/support/kubernetes_helpers.rb33
-rw-r--r--spec/support/milestone_tabs_examples.rb24
-rw-r--r--spec/support/reference_parser_shared_examples.rb8
-rw-r--r--spec/support/services/issuable_create_service_slash_commands_shared_examples.rb4
-rw-r--r--spec/support/services/issuable_update_service_shared_examples.rb4
-rw-r--r--spec/support/slack_mattermost_notifications_shared_examples.rb8
-rw-r--r--spec/support/unique_ip_check_shared_examples.rb8
-rw-r--r--spec/support/updating_mentions_shared_examples.rb12
-rw-r--r--spec/views/projects/diffs/_viewer.html.haml_spec.rb71
-rw-r--r--spec/workers/emails_on_push_worker_spec.rb4
-rw-r--r--spec/workers/expire_build_artifacts_worker_spec.rb8
-rw-r--r--spec/workers/git_garbage_collect_worker_spec.rb4
-rw-r--r--spec/workers/post_receive_spec.rb4
-rw-r--r--spec/workers/stuck_ci_jobs_worker_spec.rb12
320 files changed, 4686 insertions, 1863 deletions
diff --git a/.codeclimate.yml b/.codeclimate.yml
index e5636a13783..42afed54371 100644
--- a/.codeclimate.yml
+++ b/.codeclimate.yml
@@ -10,10 +10,10 @@ engines:
languages:
- ruby
- javascript
+ exclude_paths:
+ - "lib/api/v3/*"
eslint:
enabled: true
- fixme:
- enabled: true
rubocop:
enabled: true
ratings:
@@ -35,4 +35,13 @@ exclude_paths:
- node_modules/
- spec/
- vendor/
-- lib/api/v3/
+- .yarn-cache/
+- tmp/
+- builds/
+- coverage/
+- public/
+- shared/
+- webpack-report/
+- log/
+- backups/
+- coverage-javascript/
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index b442e48a3d0..c6868931657 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -456,6 +456,21 @@ karma:
paths:
- coverage-javascript/
+codeclimate:
+ before_script: []
+ image: docker:latest
+ stage: test
+ variables:
+ SETUP_DB: "false"
+ DOCKER_DRIVER: overlay
+ services:
+ - docker:dind
+ script:
+ - docker pull codeclimate/codeclimate
+ - docker run --env CODECLIMATE_CODE="$PWD" --volume "$PWD":/code --volume /var/run/docker.sock:/var/run/docker.sock --volume /tmp/cc:/tmp/cc codeclimate/codeclimate analyze -f json > codeclimate.json
+ artifacts:
+ paths: [codeclimate.json]
+
coverage:
stage: post-test
services: []
diff --git a/.rubocop.yml b/.rubocop.yml
index 66a40f2cf57..4537e710dd4 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -1064,6 +1064,13 @@ RSpec/NotToNot:
RSpec/RepeatedDescription:
Enabled: false
+# Ensure RSpec hook blocks are always multi-line.
+RSpec/SingleLineHook:
+ Enabled: true
+ Exclude:
+ - 'spec/factories/*'
+ - 'spec/requests/api/v3/*'
+
# Checks for stubbed test subjects.
RSpec/SubjectStub:
Enabled: false
diff --git a/app/assets/javascripts/commit/pipelines/pipelines_table.js b/app/assets/javascripts/commit/pipelines/pipelines_table.js
index 082fbafb740..70ba83ce5b9 100644
--- a/app/assets/javascripts/commit/pipelines/pipelines_table.js
+++ b/app/assets/javascripts/commit/pipelines/pipelines_table.js
@@ -1,6 +1,6 @@
import Vue from 'vue';
import Visibility from 'visibilityjs';
-import pipelinesTableComponent from '../../vue_shared/components/pipelines_table';
+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';
diff --git a/app/assets/javascripts/environments/components/environment_item.vue b/app/assets/javascripts/environments/components/environment_item.vue
index de2269118cd..614637b637e 100644
--- a/app/assets/javascripts/environments/components/environment_item.vue
+++ b/app/assets/javascripts/environments/components/environment_item.vue
@@ -9,7 +9,7 @@ import StopComponent from './environment_stop.vue';
import RollbackComponent from './environment_rollback.vue';
import TerminalButtonComponent from './environment_terminal_button.vue';
import MonitoringButtonComponent from './environment_monitoring.vue';
-import CommitComponent from '../../vue_shared/components/commit';
+import CommitComponent from '../../vue_shared/components/commit.vue';
import eventHub from '../event_hub';
/**
diff --git a/app/assets/javascripts/environments/stores/environments_store.js b/app/assets/javascripts/environments/stores/environments_store.js
index 8a2f6a473de..a5773dd7e4f 100644
--- a/app/assets/javascripts/environments/stores/environments_store.js
+++ b/app/assets/javascripts/environments/stores/environments_store.js
@@ -158,5 +158,4 @@ export default class EnvironmentsStore {
return environments.filter(env => env.isFolder && env.isOpen);
}
-
}
diff --git a/app/assets/javascripts/milestone.js b/app/assets/javascripts/milestone.js
index 841b24a60a3..07ede5ee913 100644
--- a/app/assets/javascripts/milestone.js
+++ b/app/assets/javascripts/milestone.js
@@ -65,14 +65,18 @@
};
Milestone.successCallback = function(data, element) {
- var img_tag;
- if (data.assignee) {
- img_tag = $('<img/>');
- img_tag.attr('src', data.assignee.avatar_url);
- img_tag.addClass('avatar s16');
- $(element).find('.assignee-icon img').replaceWith(img_tag);
- } else {
- $(element).find('.assignee-icon').empty();
+ 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);
}
};
@@ -161,9 +165,9 @@
data = (function() {
switch (newState) {
case 'ongoing':
- return opts.fieldName + '[assignee_id]=' + gon.current_user_id;
+ return `${opts.fieldName}[assignee_ids][]=${gon.current_user_id}`;
case 'unassigned':
- return opts.fieldName + '[assignee_id]=';
+ return `${opts.fieldName}[assignee_ids][]=0`;
case 'closed':
return opts.fieldName + '[state_event]=close';
}
diff --git a/app/assets/javascripts/notes.js b/app/assets/javascripts/notes.js
index b0143b12cfe..d56cf959486 100644
--- a/app/assets/javascripts/notes.js
+++ b/app/assets/javascripts/notes.js
@@ -56,6 +56,7 @@ const normalizeNewlines = function(str) {
this.toggleCommitList = this.toggleCommitList.bind(this);
this.postComment = this.postComment.bind(this);
this.clearFlashWrapper = this.clearFlash.bind(this);
+ this.onHashChange = this.onHashChange.bind(this);
this.notes_url = notes_url;
this.note_ids = note_ids;
@@ -127,7 +128,9 @@ const normalizeNewlines = function(str) {
$(document).on('ajax:success', '.js-main-target-form', this.resetMainTargetForm);
$(document).on('ajax:complete', '.js-main-target-form', this.reenableTargetFormSubmitButton);
// when a key is clicked on the notes
- return $(document).on('keydown', '.js-note-text', this.keydownNoteText);
+ $(document).on('keydown', '.js-note-text', this.keydownNoteText);
+ // When the URL fragment/hash has changed, `#note_xxx`
+ return $(window).on('hashchange', this.onHashChange);
};
Notes.prototype.cleanBinding = function() {
@@ -148,6 +151,7 @@ const normalizeNewlines = function(str) {
$(document).off('ajax:success', '.js-main-target-form');
$(document).off('ajax:success', '.js-discussion-note-form');
$(document).off('ajax:complete', '.js-main-target-form');
+ $(window).off('hashchange', this.onHashChange);
};
Notes.initCommentTypeToggle = function (form) {
@@ -298,8 +302,27 @@ const normalizeNewlines = function(str) {
Notes.prototype.setupNewNote = function($note) {
// Update datetime format on the recent note
gl.utils.localTimeAgo($note.find('.js-timeago'), false);
+
this.collapseLongCommitList();
this.taskList.init();
+
+ // This stops the note highlight, #note_xxx`, from being removed after real time update
+ // The `:target` selector does not re-evaluate after we replace element in the DOM
+ Notes.updateNoteTargetSelector($note);
+ this.$noteToCleanHighlight = $note;
+ };
+
+ Notes.prototype.onHashChange = function() {
+ if (this.$noteToCleanHighlight) {
+ Notes.updateNoteTargetSelector(this.$noteToCleanHighlight);
+ }
+
+ this.$noteToCleanHighlight = null;
+ };
+
+ Notes.updateNoteTargetSelector = function($note) {
+ const hash = gl.utils.getLocationHash();
+ $note.toggleClass('target', hash && $note.filter(`#${hash}`).length > 0);
};
/*
@@ -597,13 +620,12 @@ const normalizeNewlines = function(str) {
$noteEntityEl = $(noteEntity.html);
$noteEntityEl.addClass('fade-in-full');
this.revertNoteEditForm($targetNote);
- gl.utils.localTimeAgo($('.js-timeago', $noteEntityEl));
$noteEntityEl.renderGFM();
- $noteEntityEl.find('.js-task-list-container').taskList('enable');
// Find the note's `li` element by ID and replace it with the updated HTML
$note_li = $('.note-row-' + noteEntity.id);
$note_li.replaceWith($noteEntityEl);
+ this.setupNewNote($noteEntityEl);
if (typeof gl.diffNotesCompileComponents !== 'undefined') {
gl.diffNotesCompileComponents();
@@ -1060,7 +1082,7 @@ const normalizeNewlines = function(str) {
var targetId = $originalContentEl.data('target-id');
var targetType = $originalContentEl.data('target-type');
- new gl.GLForm($editForm.find('form'));
+ new gl.GLForm($editForm.find('form'), this.enableGFM);
$editForm.find('form')
.attr('action', postUrl)
diff --git a/app/assets/javascripts/pipelines/components/pipelines.vue b/app/assets/javascripts/pipelines/components/pipelines.vue
new file mode 100644
index 00000000000..fed42d23112
--- /dev/null
+++ b/app/assets/javascripts/pipelines/components/pipelines.vue
@@ -0,0 +1,289 @@
+<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 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: {
+ store: {
+ type: Object,
+ required: true,
+ },
+ },
+ components: {
+ tablePagination,
+ pipelinesTableComponent,
+ emptyState,
+ errorState,
+ navigationTabs,
+ navigationControls,
+ loadingIcon,
+ },
+ data() {
+ const pipelinesData = document.querySelector('#pipelines-list-vue').dataset;
+
+ return {
+ endpoint: pipelinesData.endpoint,
+ cssClass: pipelinesData.cssClass,
+ helpPagePath: pipelinesData.helpPagePath,
+ newPipelinePath: pipelinesData.newPipelinePath,
+ canCreatePipeline: pipelinesData.canCreatePipeline,
+ allPath: pipelinesData.allPath,
+ pendingPath: pipelinesData.pendingPath,
+ runningPath: pipelinesData.runningPath,
+ finishedPath: pipelinesData.finishedPath,
+ branchesPath: pipelinesData.branchesPath,
+ tagsPath: pipelinesData.tagsPath,
+ hasCi: pipelinesData.hasCi,
+ ciLintPath: pipelinesData.ciLintPath,
+ state: this.store.state,
+ apiScope: 'all',
+ pagenum: 1,
+ isLoading: false,
+ hasError: false,
+ isMakingRequest: false,
+ updateGraphDropdown: false,
+ hasMadeRequest: false,
+ };
+ },
+ computed: {
+ canCreatePipelineParsed() {
+ return gl.utils.convertPermissionToBoolean(this.canCreatePipeline);
+ },
+ scope() {
+ 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
+ * and none is returned.
+ *
+ * @return {Boolean}
+ */
+ shouldRenderEmptyState() {
+ return !this.isLoading &&
+ !this.hasError &&
+ this.hasMadeRequest &&
+ !this.state.pipelines.length &&
+ (this.scope === 'all' || this.scope === null);
+ },
+ /**
+ * When a specific scope does not have pipelines we render a message.
+ *
+ * @return {Boolean}
+ */
+ shouldRenderNoPipelinesMessage() {
+ return !this.isLoading &&
+ !this.hasError &&
+ !this.state.pipelines.length &&
+ this.scope !== 'all' &&
+ this.scope !== null;
+ },
+
+ shouldRenderTable() {
+ return !this.hasError &&
+ !this.isLoading && this.state.pipelines.length;
+ },
+ /**
+ * Pagination should only be rendered when there is more than one page.
+ *
+ * @return {Boolean}
+ */
+ shouldRenderPagination() {
+ return !this.isLoading &&
+ this.state.pipelines.length &&
+ this.state.pageInfo.total > this.state.pageInfo.perPage;
+ },
+
+ hasCiEnabled() {
+ return this.hasCi !== undefined;
+ },
+ paths() {
+ return {
+ allPath: this.allPath,
+ pendingPath: this.pendingPath,
+ finishedPath: this.finishedPath,
+ runningPath: this.runningPath,
+ branchesPath: this.branchesPath,
+ tagsPath: this.tagsPath,
+ };
+ },
+ pageParameter() {
+ return gl.utils.getParameterByName('page') || this.pagenum;
+ },
+ scopeParameter() {
+ return gl.utils.getParameterByName('scope') || this.apiScope;
+ },
+ },
+ 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');
+ },
+ methods: {
+ /**
+ * Will change the page number and update the URL.
+ *
+ * @param {Number} pageNumber desired page to go to.
+ */
+ change(pageNumber) {
+ const param = gl.utils.setParamInURL('page', pageNumber);
+
+ gl.utils.visitUrl(param);
+ 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,
+ body: resp.json(),
+ };
+
+ 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;
+ }
+ },
+ },
+ };
+</script>
+<template>
+ <div :class="cssClass">
+
+ <div
+ class="top-area scrolling-tabs-container inner-page-scroll-tabs"
+ v-if="!isLoading && !shouldRenderEmptyState">
+ <div class="fade-left">
+ <i
+ class="fa fa-angle-left"
+ aria-hidden="true">
+ </i>
+ </div>
+ <div class="fade-right">
+ <i
+ class="fa fa-angle-right"
+ aria-hidden="true">
+ </i>
+ </div>
+ <navigation-tabs
+ :scope="scope"
+ :count="state.count"
+ :paths="paths"
+ />
+
+ <navigation-controls
+ :new-pipeline-path="newPipelinePath"
+ :has-ci-enabled="hasCiEnabled"
+ :help-page-path="helpPagePath"
+ :ciLintPath="ciLintPath"
+ :can-create-pipeline="canCreatePipelineParsed "
+ />
+ </div>
+
+ <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="blank-state blank-state-no-icon"
+ v-if="shouldRenderNoPipelinesMessage">
+ <h2 class="blank-state-title js-blank-state-title">No pipelines to show.</h2>
+ </div>
+
+ <div
+ class="table-holder"
+ v-if="shouldRenderTable">
+
+ <pipelines-table-component
+ :pipelines="state.pipelines"
+ :service="service"
+ :update-graph-dropdown="updateGraphDropdown"
+ />
+ </div>
+
+ <table-pagination
+ v-if="shouldRenderPagination"
+ :change="change"
+ :pageInfo="state.pageInfo"
+ />
+ </div>
+ </div>
+</template>
diff --git a/app/assets/javascripts/pipelines/components/pipelines_actions.js b/app/assets/javascripts/pipelines/components/pipelines_actions.js
deleted file mode 100644
index b9e066c5db1..00000000000
--- a/app/assets/javascripts/pipelines/components/pipelines_actions.js
+++ /dev/null
@@ -1,91 +0,0 @@
-/* eslint-disable no-new */
-/* global Flash */
-import '~/flash';
-import playIconSvg from 'icons/_icon_play.svg';
-import eventHub from '../event_hub';
-import loadingIconComponent from '../../vue_shared/components/loading_icon.vue';
-
-export default {
- props: {
- actions: {
- type: Array,
- required: true,
- },
-
- service: {
- type: Object,
- required: true,
- },
- },
-
- components: {
- loadingIconComponent,
- },
-
- data() {
- return {
- playIconSvg,
- isLoading: false,
- };
- },
-
- methods: {
- onClickAction(endpoint) {
- this.isLoading = true;
-
- $(this.$refs.tooltip).tooltip('destroy');
-
- this.service.postAction(endpoint)
- .then(() => {
- this.isLoading = false;
- eventHub.$emit('refreshPipelines');
- })
- .catch(() => {
- this.isLoading = false;
- new Flash('An error occured while making the request.');
- });
- },
-
- isActionDisabled(action) {
- if (action.playable === undefined) {
- return false;
- }
-
- return !action.playable;
- },
- },
-
- template: `
- <div class="btn-group" v-if="actions">
- <button
- type="button"
- class="dropdown-toggle btn btn-default has-tooltip js-pipeline-dropdown-manual-actions"
- title="Manual job"
- data-toggle="dropdown"
- data-placement="top"
- aria-label="Manual job"
- ref="tooltip"
- :disabled="isLoading">
- ${playIconSvg}
- <i
- class="fa fa-caret-down"
- aria-hidden="true" />
- <loading-icon v-if="isLoading" />
- </button>
-
- <ul class="dropdown-menu dropdown-menu-align-right">
- <li v-for="action in actions">
- <button
- type="button"
- class="js-pipeline-action-link no-btn btn"
- @click="onClickAction(action.path)"
- :class="{ 'disabled': isActionDisabled(action) }"
- :disabled="isActionDisabled(action)">
- ${playIconSvg}
- <span>{{action.name}}</span>
- </button>
- </li>
- </ul>
- </div>
- `,
-};
diff --git a/app/assets/javascripts/pipelines/components/pipelines_actions.vue b/app/assets/javascripts/pipelines/components/pipelines_actions.vue
new file mode 100644
index 00000000000..da5df2a06cf
--- /dev/null
+++ b/app/assets/javascripts/pipelines/components/pipelines_actions.vue
@@ -0,0 +1,88 @@
+<script>
+ /* global Flash */
+ import '~/flash';
+ import playIconSvg from 'icons/_icon_play.svg';
+ import eventHub from '../event_hub';
+ import loadingIcon from '../../vue_shared/components/loading_icon.vue';
+
+ export default {
+ props: {
+ actions: {
+ type: Array,
+ required: true,
+ },
+ service: {
+ type: Object,
+ required: true,
+ },
+ },
+ components: {
+ loadingIcon,
+ },
+ data() {
+ return {
+ playIconSvg,
+ isLoading: false,
+ };
+ },
+ methods: {
+ onClickAction(endpoint) {
+ this.isLoading = true;
+
+ $(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.');
+ });
+ },
+ isActionDisabled(action) {
+ if (action.playable === undefined) {
+ return false;
+ }
+
+ return !action.playable;
+ },
+ },
+ };
+</script>
+<template>
+ <div class="btn-group">
+ <button
+ type="button"
+ class="dropdown-toggle btn btn-default has-tooltip js-pipeline-dropdown-manual-actions"
+ title="Manual job"
+ data-toggle="dropdown"
+ data-placement="top"
+ aria-label="Manual job"
+ ref="tooltip"
+ :disabled="isLoading">
+ <span v-html="playIconSvg"></span>
+ <i
+ class="fa fa-caret-down"
+ aria-hidden="true">
+ </i>
+ <loading-icon v-if="isLoading" />
+ </button>
+
+ <ul class="dropdown-menu dropdown-menu-align-right">
+ <li v-for="action in actions">
+ <button
+ type="button"
+ class="js-pipeline-action-link no-btn btn"
+ @click="onClickAction(action.path)"
+ :class="{ disabled: isActionDisabled(action) }"
+ :disabled="isActionDisabled(action)">
+ <span v-html="playIconSvg"></span>
+ <span>{{action.name}}</span>
+ </button>
+ </li>
+ </ul>
+ </div>
+</template>
diff --git a/app/assets/javascripts/pipelines/components/pipelines_artifacts.js b/app/assets/javascripts/pipelines/components/pipelines_artifacts.js
deleted file mode 100644
index f18e2dfadaf..00000000000
--- a/app/assets/javascripts/pipelines/components/pipelines_artifacts.js
+++ /dev/null
@@ -1,33 +0,0 @@
-export default {
- props: {
- artifacts: {
- type: Array,
- required: true,
- },
- },
-
- template: `
- <div class="btn-group" role="group">
- <button
- class="dropdown-toggle btn btn-default build-artifacts has-tooltip js-pipeline-dropdown-download"
- title="Artifacts"
- data-placement="top"
- data-toggle="dropdown"
- aria-label="Artifacts">
- <i class="fa fa-download" aria-hidden="true"></i>
- <i class="fa fa-caret-down" aria-hidden="true"></i>
- </button>
- <ul class="dropdown-menu dropdown-menu-align-right">
- <li v-for="artifact in artifacts">
- <a
- rel="nofollow"
- download
- :href="artifact.path">
- <i class="fa fa-download" aria-hidden="true"></i>
- <span>Download {{artifact.name}} artifacts</span>
- </a>
- </li>
- </ul>
- </div>
- `,
-};
diff --git a/app/assets/javascripts/pipelines/components/pipelines_artifacts.vue b/app/assets/javascripts/pipelines/components/pipelines_artifacts.vue
new file mode 100644
index 00000000000..b4520481cdc
--- /dev/null
+++ b/app/assets/javascripts/pipelines/components/pipelines_artifacts.vue
@@ -0,0 +1,51 @@
+<script>
+ import tooltipMixin from '../../vue_shared/mixins/tooltip';
+
+ export default {
+ props: {
+ artifacts: {
+ type: Array,
+ required: true,
+ },
+ },
+ mixins: [
+ tooltipMixin,
+ ],
+ };
+</script>
+<template>
+ <div
+ class="btn-group"
+ role="group">
+ <button
+ class="dropdown-toggle btn btn-default build-artifacts js-pipeline-dropdown-download"
+ title="Artifacts"
+ data-placement="top"
+ data-toggle="dropdown"
+ aria-label="Artifacts"
+ ref="tooltip">
+ <i
+ class="fa fa-download"
+ aria-hidden="true">
+ </i>
+ <i
+ class="fa fa-caret-down"
+ aria-hidden="true">
+ </i>
+ </button>
+ <ul class="dropdown-menu dropdown-menu-align-right">
+ <li v-for="artifact in artifacts">
+ <a
+ rel="nofollow"
+ download
+ :href="artifact.path">
+ <i
+ class="fa fa-download"
+ aria-hidden="true">
+ </i>
+ <span>Download {{artifact.name}} artifacts</span>
+ </a>
+ </li>
+ </ul>
+ </div>
+</template>
diff --git a/app/assets/javascripts/pipelines/components/time_ago.js b/app/assets/javascripts/pipelines/components/time_ago.js
deleted file mode 100644
index 188f74cc705..00000000000
--- a/app/assets/javascripts/pipelines/components/time_ago.js
+++ /dev/null
@@ -1,98 +0,0 @@
-import iconTimerSvg from 'icons/_icon_timer.svg';
-import '../../lib/utils/datetime_utility';
-
-export default {
- props: {
- finishedTime: {
- type: String,
- required: true,
- },
-
- duration: {
- type: Number,
- required: true,
- },
- },
-
- data() {
- return {
- iconTimerSvg,
- };
- },
-
- updated() {
- $(this.$refs.tooltip).tooltip('fixTitle');
- },
-
- computed: {
- hasDuration() {
- return this.duration > 0;
- },
-
- hasFinishedTime() {
- return this.finishedTime !== '';
- },
-
- localTimeFinished() {
- return gl.utils.formatDate(this.finishedTime);
- },
-
- durationFormated() {
- const date = new Date(this.duration * 1000);
-
- let hh = date.getUTCHours();
- let mm = date.getUTCMinutes();
- let ss = date.getSeconds();
-
- // left pad
- if (hh < 10) {
- hh = `0${hh}`;
- }
- if (mm < 10) {
- mm = `0${mm}`;
- }
- if (ss < 10) {
- ss = `0${ss}`;
- }
-
- return `${hh}:${mm}:${ss}`;
- },
-
- finishedTimeFormated() {
- const timeAgo = gl.utils.getTimeago();
-
- return timeAgo.format(this.finishedTime);
- },
- },
-
- template: `
- <td class="pipelines-time-ago">
- <p
- class="duration"
- v-if="hasDuration">
- <span
- v-html="iconTimerSvg">
- </span>
- {{durationFormated}}
- </p>
-
- <p
- class="finished-at"
- v-if="hasFinishedTime">
-
- <i
- class="fa fa-calendar"
- aria-hidden="true" />
-
- <time
- ref="tooltip"
- data-toggle="tooltip"
- data-placement="top"
- data-container="body"
- :title="localTimeFinished">
- {{finishedTimeFormated}}
- </time>
- </p>
- </td>
- `,
-};
diff --git a/app/assets/javascripts/pipelines/components/time_ago.vue b/app/assets/javascripts/pipelines/components/time_ago.vue
new file mode 100644
index 00000000000..c47658cd6e6
--- /dev/null
+++ b/app/assets/javascripts/pipelines/components/time_ago.vue
@@ -0,0 +1,85 @@
+<script>
+ import iconTimerSvg from 'icons/_icon_timer.svg';
+ import '../../lib/utils/datetime_utility';
+ import tooltipMixin from '../../vue_shared/mixins/tooltip';
+ import timeagoMixin from '../../vue_shared/mixins/timeago';
+
+ export default {
+ props: {
+ finishedTime: {
+ type: String,
+ required: true,
+ },
+ duration: {
+ type: Number,
+ required: true,
+ },
+ },
+ mixins: [
+ tooltipMixin,
+ timeagoMixin,
+ ],
+ data() {
+ return {
+ iconTimerSvg,
+ };
+ },
+ computed: {
+ hasDuration() {
+ return this.duration > 0;
+ },
+ hasFinishedTime() {
+ return this.finishedTime !== '';
+ },
+ durationFormated() {
+ const date = new Date(this.duration * 1000);
+
+ let hh = date.getUTCHours();
+ let mm = date.getUTCMinutes();
+ let ss = date.getSeconds();
+
+ // left pad
+ if (hh < 10) {
+ hh = `0${hh}`;
+ }
+ if (mm < 10) {
+ mm = `0${mm}`;
+ }
+ if (ss < 10) {
+ ss = `0${ss}`;
+ }
+
+ return `${hh}:${mm}:${ss}`;
+ },
+ },
+ };
+</script>
+<template>
+ <td class="pipelines-time-ago">
+ <p
+ class="duration"
+ v-if="hasDuration">
+ <span v-html="iconTimerSvg">
+ </span>
+ {{durationFormated}}
+ </p>
+
+ <p
+ class="finished-at"
+ v-if="hasFinishedTime">
+
+ <i
+ class="fa fa-calendar"
+ aria-hidden="true">
+ </i>
+
+ <time
+ ref="tooltip"
+ data-placement="top"
+ data-container="body"
+ :title="tooltipTitle(finishedTime)">
+ {{timeFormated(finishedTime)}}
+ </time>
+ </p>
+ </td>
+</script>
diff --git a/app/assets/javascripts/pipelines/index.js b/app/assets/javascripts/pipelines/index.js
deleted file mode 100644
index 48f9181a8d9..00000000000
--- a/app/assets/javascripts/pipelines/index.js
+++ /dev/null
@@ -1,22 +0,0 @@
-import Vue from 'vue';
-import PipelinesStore from './stores/pipelines_store';
-import PipelinesComponent from './pipelines';
-import '../vue_shared/vue_resource_interceptor';
-
-$(() => new Vue({
- el: document.querySelector('#pipelines-list-vue'),
-
- data() {
- const store = new PipelinesStore();
-
- return {
- store,
- };
- },
- components: {
- 'vue-pipelines': PipelinesComponent,
- },
- template: `
- <vue-pipelines :store="store" />
- `,
-}));
diff --git a/app/assets/javascripts/pipelines/pipelines.js b/app/assets/javascripts/pipelines/pipelines.js
deleted file mode 100644
index b530461837c..00000000000
--- a/app/assets/javascripts/pipelines/pipelines.js
+++ /dev/null
@@ -1,293 +0,0 @@
-import Visibility from 'visibilityjs';
-import PipelinesService from './services/pipelines_service';
-import eventHub from './event_hub';
-import pipelinesTableComponent from '../vue_shared/components/pipelines_table';
-import tablePagination from '../vue_shared/components/table_pagination.vue';
-import emptyState from './components/empty_state.vue';
-import errorState from './components/error_state.vue';
-import navigationTabs from './components/navigation_tabs.vue';
-import navigationControls from './components/nav_controls.vue';
-import loadingIcon from '../vue_shared/components/loading_icon.vue';
-import Poll from '../lib/utils/poll';
-
-export default {
- props: {
- store: {
- type: Object,
- required: true,
- },
- },
-
- components: {
- tablePagination,
- pipelinesTableComponent,
- emptyState,
- errorState,
- navigationTabs,
- navigationControls,
- loadingIcon,
- },
-
- data() {
- const pipelinesData = document.querySelector('#pipelines-list-vue').dataset;
-
- return {
- endpoint: pipelinesData.endpoint,
- cssClass: pipelinesData.cssClass,
- helpPagePath: pipelinesData.helpPagePath,
- newPipelinePath: pipelinesData.newPipelinePath,
- canCreatePipeline: pipelinesData.canCreatePipeline,
- allPath: pipelinesData.allPath,
- pendingPath: pipelinesData.pendingPath,
- runningPath: pipelinesData.runningPath,
- finishedPath: pipelinesData.finishedPath,
- branchesPath: pipelinesData.branchesPath,
- tagsPath: pipelinesData.tagsPath,
- hasCi: pipelinesData.hasCi,
- ciLintPath: pipelinesData.ciLintPath,
- state: this.store.state,
- apiScope: 'all',
- pagenum: 1,
- isLoading: false,
- hasError: false,
- isMakingRequest: false,
- updateGraphDropdown: false,
- hasMadeRequest: false,
- };
- },
-
- computed: {
- canCreatePipelineParsed() {
- return gl.utils.convertPermissionToBoolean(this.canCreatePipeline);
- },
-
- scope() {
- 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
- * and none is returned.
- *
- * @return {Boolean}
- */
- shouldRenderEmptyState() {
- return !this.isLoading &&
- !this.hasError &&
- this.hasMadeRequest &&
- !this.state.pipelines.length &&
- (this.scope === 'all' || this.scope === null);
- },
-
- /**
- * When a specific scope does not have pipelines we render a message.
- *
- * @return {Boolean}
- */
- shouldRenderNoPipelinesMessage() {
- return !this.isLoading &&
- !this.hasError &&
- !this.state.pipelines.length &&
- this.scope !== 'all' &&
- this.scope !== null;
- },
-
- shouldRenderTable() {
- return !this.hasError &&
- !this.isLoading && this.state.pipelines.length;
- },
-
- /**
- * Pagination should only be rendered when there is more than one page.
- *
- * @return {Boolean}
- */
- shouldRenderPagination() {
- return !this.isLoading &&
- this.state.pipelines.length &&
- this.state.pageInfo.total > this.state.pageInfo.perPage;
- },
-
- hasCiEnabled() {
- return this.hasCi !== undefined;
- },
-
- paths() {
- return {
- allPath: this.allPath,
- pendingPath: this.pendingPath,
- finishedPath: this.finishedPath,
- runningPath: this.runningPath,
- branchesPath: this.branchesPath,
- tagsPath: this.tagsPath,
- };
- },
-
- pageParameter() {
- return gl.utils.getParameterByName('page') || this.pagenum;
- },
-
- scopeParameter() {
- return gl.utils.getParameterByName('scope') || this.apiScope;
- },
- },
-
- 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');
- },
-
- methods: {
- /**
- * Will change the page number and update the URL.
- *
- * @param {Number} pageNumber desired page to go to.
- */
- change(pageNumber) {
- const param = gl.utils.setParamInURL('page', pageNumber);
-
- gl.utils.visitUrl(param);
- 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,
- body: resp.json(),
- };
-
- 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;
- }
- },
- },
-
- template: `
- <div :class="cssClass">
-
- <div
- class="top-area scrolling-tabs-container inner-page-scroll-tabs"
- v-if="!isLoading && !shouldRenderEmptyState">
- <div class="fade-left">
- <i class="fa fa-angle-left" aria-hidden="true"></i>
- </div>
- <div class="fade-right">
- <i class="fa fa-angle-right" aria-hidden="true"></i>
- </div>
- <navigation-tabs
- :scope="scope"
- :count="state.count"
- :paths="paths" />
-
- <navigation-controls
- :new-pipeline-path="newPipelinePath"
- :has-ci-enabled="hasCiEnabled"
- :help-page-path="helpPagePath"
- :ciLintPath="ciLintPath"
- :can-create-pipeline="canCreatePipelineParsed " />
- </div>
-
- <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="blank-state blank-state-no-icon"
- v-if="shouldRenderNoPipelinesMessage">
- <h2 class="blank-state-title js-blank-state-title">No pipelines to show.</h2>
- </div>
-
- <div
- class="table-holder"
- v-if="shouldRenderTable">
-
- <pipelines-table-component
- :pipelines="state.pipelines"
- :service="service"
- :update-graph-dropdown="updateGraphDropdown"
- />
- </div>
-
- <table-pagination
- v-if="shouldRenderPagination"
- :change="change"
- :pageInfo="state.pageInfo"
- />
- </div>
- </div>
- `,
-};
diff --git a/app/assets/javascripts/pipelines/pipelines_bundle.js b/app/assets/javascripts/pipelines/pipelines_bundle.js
new file mode 100644
index 00000000000..923d9bfb248
--- /dev/null
+++ b/app/assets/javascripts/pipelines/pipelines_bundle.js
@@ -0,0 +1,24 @@
+import Vue from 'vue';
+import PipelinesStore from './stores/pipelines_store';
+import pipelinesComponent from './components/pipelines.vue';
+
+document.addEventListener('DOMContentLoaded', () => new Vue({
+ el: '#pipelines-list-vue',
+ data() {
+ const store = new PipelinesStore();
+
+ return {
+ store,
+ };
+ },
+ components: {
+ pipelinesComponent,
+ },
+ render(createElement) {
+ return createElement('pipelines-component', {
+ props: {
+ store: this.store,
+ },
+ });
+ },
+}));
diff --git a/app/assets/javascripts/vue_shared/components/commit.js b/app/assets/javascripts/vue_shared/components/commit.js
deleted file mode 100644
index ff5ae28e062..00000000000
--- a/app/assets/javascripts/vue_shared/components/commit.js
+++ /dev/null
@@ -1,159 +0,0 @@
-import commitIconSvg from 'icons/_icon_commit.svg';
-import userAvatarLink from './user_avatar/user_avatar_link.vue';
-
-export default {
- props: {
- /**
- * Indicates the existance of a tag.
- * Used to render the correct icon, if true will render `fa-tag` icon,
- * if false will render `fa-code-fork` icon.
- */
- tag: {
- type: Boolean,
- required: false,
- default: false,
- },
-
- /**
- * If provided is used to render the branch name and url.
- * Should contain the following properties:
- * name
- * ref_url
- */
- commitRef: {
- type: Object,
- required: false,
- default: () => ({}),
- },
-
- /**
- * Used to link to the commit sha.
- */
- commitUrl: {
- type: String,
- required: false,
- default: '',
- },
-
- /**
- * Used to show the commit short sha that links to the commit url.
- */
- shortSha: {
- type: String,
- required: false,
- default: '',
- },
-
- /**
- * If provided shows the commit tile.
- */
- title: {
- type: String,
- required: false,
- default: '',
- },
-
- /**
- * If provided renders information about the author of the commit.
- * When provided should include:
- * `avatar_url` to render the avatar icon
- * `web_url` to link to user profile
- * `username` to render alt and title tags
- */
- author: {
- type: Object,
- required: false,
- default: () => ({}),
- },
- },
-
- computed: {
- /**
- * Used to verify if all the properties needed to render the commit
- * ref section were provided.
- *
- * TODO: Improve this! Use lodash _.has when we have it.
- *
- * @returns {Boolean}
- */
- hasCommitRef() {
- return this.commitRef && this.commitRef.name && this.commitRef.ref_url;
- },
-
- /**
- * Used to verify if all the properties needed to render the commit
- * author section were provided.
- *
- * TODO: Improve this! Use lodash _.has when we have it.
- *
- * @returns {Boolean}
- */
- hasAuthor() {
- return this.author &&
- this.author.avatar_url &&
- this.author.path &&
- this.author.username;
- },
-
- /**
- * If information about the author is provided will return a string
- * to be rendered as the alt attribute of the img tag.
- *
- * @returns {String}
- */
- userImageAltDescription() {
- return this.author &&
- this.author.username ? `${this.author.username}'s avatar` : null;
- },
- },
-
- data() {
- return { commitIconSvg };
- },
-
- components: {
- userAvatarLink,
- },
- template: `
- <div class="branch-commit">
-
- <div v-if="hasCommitRef" class="icon-container">
- <i v-if="tag" class="fa fa-tag"></i>
- <i v-if="!tag" class="fa fa-code-fork"></i>
- </div>
-
- <a v-if="hasCommitRef"
- class="ref-name"
- :href="commitRef.ref_url">
- {{commitRef.name}}
- </a>
-
- <div v-html="commitIconSvg" class="commit-icon js-commit-icon"></div>
-
- <a class="commit-sha"
- :href="commitUrl">
- {{shortSha}}
- </a>
-
- <div class="commit-title flex-truncate-parent">
- <span v-if="title" class="flex-truncate-child">
- <user-avatar-link
- v-if="hasAuthor"
- class="avatar-image-container"
- :link-href="author.path"
- :img-src="author.avatar_url"
- :img-alt="userImageAltDescription"
- :tooltip-text="author.username"
- />
- <a class="commit-row-message"
- :href="commitUrl">
- {{title}}
- </a>
- </span>
- <span v-else>
- Cant find HEAD commit for this branch
- </span>
- </div>
- </div>
- `,
-};
diff --git a/app/assets/javascripts/vue_shared/components/commit.vue b/app/assets/javascripts/vue_shared/components/commit.vue
new file mode 100644
index 00000000000..fcf48b11057
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/components/commit.vue
@@ -0,0 +1,166 @@
+<script>
+ import commitIconSvg from 'icons/_icon_commit.svg';
+ import userAvatarLink from './user_avatar/user_avatar_link.vue';
+
+ export default {
+ props: {
+ /**
+ * Indicates the existance of a tag.
+ * Used to render the correct icon, if true will render `fa-tag` icon,
+ * if false will render `fa-code-fork` icon.
+ */
+ tag: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ /**
+ * If provided is used to render the branch name and url.
+ * Should contain the following properties:
+ * name
+ * ref_url
+ */
+ commitRef: {
+ type: Object,
+ required: false,
+ default: () => ({}),
+ },
+ /**
+ * Used to link to the commit sha.
+ */
+ commitUrl: {
+ type: String,
+ required: false,
+ default: '',
+ },
+
+ /**
+ * Used to show the commit short sha that links to the commit url.
+ */
+ shortSha: {
+ type: String,
+ required: false,
+ default: '',
+ },
+ /**
+ * If provided shows the commit tile.
+ */
+ title: {
+ type: String,
+ required: false,
+ default: '',
+ },
+ /**
+ * If provided renders information about the author of the commit.
+ * When provided should include:
+ * `avatar_url` to render the avatar icon
+ * `web_url` to link to user profile
+ * `username` to render alt and title tags
+ */
+ author: {
+ type: Object,
+ required: false,
+ default: () => ({}),
+ },
+ },
+ computed: {
+ /**
+ * Used to verify if all the properties needed to render the commit
+ * ref section were provided.
+ *
+ * TODO: Improve this! Use lodash _.has when we have it.
+ *
+ * @returns {Boolean}
+ */
+ hasCommitRef() {
+ return this.commitRef && this.commitRef.name && this.commitRef.ref_url;
+ },
+ /**
+ * Used to verify if all the properties needed to render the commit
+ * author section were provided.
+ *
+ * TODO: Improve this! Use lodash _.has when we have it.
+ *
+ * @returns {Boolean}
+ */
+ hasAuthor() {
+ return this.author &&
+ this.author.avatar_url &&
+ this.author.path &&
+ this.author.username;
+ },
+ /**
+ * If information about the author is provided will return a string
+ * to be rendered as the alt attribute of the img tag.
+ *
+ * @returns {String}
+ */
+ userImageAltDescription() {
+ return this.author &&
+ this.author.username ? `${this.author.username}'s avatar` : null;
+ },
+ },
+ data() {
+ return { commitIconSvg };
+ },
+ components: {
+ userAvatarLink,
+ },
+ };
+</script>
+<template>
+ <div class="branch-commit">
+ <div v-if="hasCommitRef" class="icon-container">
+ <i
+ v-if="tag"
+ class="fa fa-tag"
+ aria-hidden="true">
+ </i>
+ <i
+ v-if="!tag"
+ class="fa fa-code-fork"
+ aria-hidden="true">
+ </i>
+ </div>
+
+ <a
+ v-if="hasCommitRef"
+ class="ref-name"
+ :href="commitRef.ref_url">
+ {{commitRef.name}}
+ </a>
+
+ <div
+ v-html="commitIconSvg"
+ class="commit-icon js-commit-icon">
+ </div>
+
+ <a
+ class="commit-sha"
+ :href="commitUrl">
+ {{shortSha}}
+ </a>
+
+ <div class="commit-title flex-truncate-parent">
+ <span
+ v-if="title"
+ class="flex-truncate-child">
+ <user-avatar-link
+ v-if="hasAuthor"
+ class="avatar-image-container"
+ :link-href="author.path"
+ :img-src="author.avatar_url"
+ :img-alt="userImageAltDescription"
+ :tooltip-text="author.username"
+ />
+ <a class="commit-row-message"
+ :href="commitUrl">
+ {{title}}
+ </a>
+ </span>
+ <span v-else>
+ Cant find HEAD commit for this branch
+ </span>
+ </div>
+ </div>
+</template>
diff --git a/app/assets/javascripts/vue_shared/components/pipelines_table.js b/app/assets/javascripts/vue_shared/components/pipelines_table.js
deleted file mode 100644
index 48a39f18112..00000000000
--- a/app/assets/javascripts/vue_shared/components/pipelines_table.js
+++ /dev/null
@@ -1,55 +0,0 @@
-import PipelinesTableRowComponent from './pipelines_table_row';
-
-/**
- * Pipelines Table Component.
- *
- * Given an array of objects, renders a table.
- */
-export default {
- props: {
- pipelines: {
- type: Array,
- required: true,
- },
-
- service: {
- type: Object,
- required: true,
- },
-
- updateGraphDropdown: {
- type: Boolean,
- required: false,
- default: false,
- },
- },
-
- components: {
- 'pipelines-table-row-component': PipelinesTableRowComponent,
- },
-
- template: `
- <table class="table ci-table">
- <thead>
- <tr>
- <th class="js-pipeline-status pipeline-status">Status</th>
- <th class="js-pipeline-info pipeline-info">Pipeline</th>
- <th class="js-pipeline-commit pipeline-commit">Commit</th>
- <th class="js-pipeline-stages pipeline-stages">Stages</th>
- <th class="js-pipeline-date pipeline-date"></th>
- <th class="js-pipeline-actions pipeline-actions"></th>
- </tr>
- </thead>
- <tbody>
- <template v-for="model in pipelines"
- v-bind:model="model">
- <tr is="pipelines-table-row-component"
- :pipeline="model"
- :service="service"
- :update-graph-dropdown="updateGraphDropdown"
- />
- </template>
- </tbody>
- </table>
- `,
-};
diff --git a/app/assets/javascripts/vue_shared/components/pipelines_table.vue b/app/assets/javascripts/vue_shared/components/pipelines_table.vue
new file mode 100644
index 00000000000..ebe8fba8a44
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/components/pipelines_table.vue
@@ -0,0 +1,55 @@
+<script>
+ import pipelinesTableRowComponent from './pipelines_table_row.vue';
+
+ /**
+ * Pipelines Table Component.
+ *
+ * Given an array of objects, renders a table.
+ */
+ export default {
+ props: {
+ pipelines: {
+ type: Array,
+ required: true,
+ },
+ service: {
+ type: Object,
+ required: true,
+ },
+ updateGraphDropdown: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ },
+ components: {
+ pipelinesTableRowComponent,
+ },
+ };
+</script>
+<template>
+ <table class="table ci-table">
+ <thead>
+ <tr>
+ <th class="js-pipeline-status pipeline-status">Status</th>
+ <th class="js-pipeline-info pipeline-info">Pipeline</th>
+ <th class="js-pipeline-commit pipeline-commit">Commit</th>
+ <th class="js-pipeline-stages pipeline-stages">Stages</th>
+ <th class="js-pipeline-date pipeline-date"></th>
+ <th class="js-pipeline-actions pipeline-actions"></th>
+ </tr>
+ </thead>
+ <tbody>
+ <template
+ v-for="model in pipelines"
+ :model="model">
+ <tr
+ is="pipelines-table-row-component"
+ :pipeline="model"
+ :service="service"
+ :update-graph-dropdown="updateGraphDropdown"
+ />
+ </template>
+ </tbody>
+ </table>
+</template>
diff --git a/app/assets/javascripts/vue_shared/components/pipelines_table_row.js b/app/assets/javascripts/vue_shared/components/pipelines_table_row.vue
index f60f8eeb43d..33b3375deff 100644
--- a/app/assets/javascripts/vue_shared/components/pipelines_table_row.js
+++ b/app/assets/javascripts/vue_shared/components/pipelines_table_row.vue
@@ -1,12 +1,13 @@
+<script>
/* eslint-disable no-param-reassign */
-import AsyncButtonComponent from '../../pipelines/components/async_button.vue';
-import PipelinesActionsComponent from '../../pipelines/components/pipelines_actions';
-import PipelinesArtifactsComponent from '../../pipelines/components/pipelines_artifacts';
+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 PipelinesStageComponent from '../../pipelines/components/stage.vue';
-import PipelinesUrlComponent from '../../pipelines/components/pipeline_url.vue';
-import PipelinesTimeagoComponent from '../../pipelines/components/time_ago';
-import CommitComponent from './commit';
+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';
/**
* Pipeline table row.
@@ -19,30 +20,26 @@ export default {
type: Object,
required: true,
},
-
service: {
type: Object,
required: true,
},
-
updateGraphDropdown: {
type: Boolean,
required: false,
default: false,
},
},
-
components: {
- 'async-button-component': AsyncButtonComponent,
- 'pipelines-actions-component': PipelinesActionsComponent,
- 'pipelines-artifacts-component': PipelinesArtifactsComponent,
- 'commit-component': CommitComponent,
- 'dropdown-stage': PipelinesStageComponent,
- 'pipeline-url': PipelinesUrlComponent,
+ asyncButtonComponent,
+ pipelinesActionsComponent,
+ pipelinesArtifactsComponent,
+ commitComponent,
+ pipelineStage,
+ pipelineUrl,
ciBadge,
- 'time-ago': PipelinesTimeagoComponent,
+ pipelinesTimeago,
},
-
computed: {
/**
* If provided, returns the commit tag.
@@ -204,69 +201,76 @@ export default {
return {};
},
},
+};
+</script>
+<template>
+ <tr class="commit">
+ <td class="commit-link">
+ <ci-badge :status="pipelineStatus" />
+ </td>
- template: `
- <tr class="commit">
- <td class="commit-link">
- <ci-badge :status="pipelineStatus"/>
- </td>
-
- <pipeline-url :pipeline="pipeline"></pipeline-url>
+ <pipeline-url :pipeline="pipeline" />
- <td>
- <commit-component
- :tag="commitTag"
- :commit-ref="commitRef"
- :commit-url="commitUrl"
- :short-sha="commitShortSha"
- :title="commitTitle"
- :author="commitAuthor"/>
- </td>
+ <td>
+ <commit-component
+ :tag="commitTag"
+ :commit-ref="commitRef"
+ :commit-url="commitUrl"
+ :short-sha="commitShortSha"
+ :title="commitTitle"
+ :author="commitAuthor"
+ />
+ </td>
- <td class="stage-cell">
- <div class="stage-container dropdown js-mini-pipeline-graph"
- v-if="pipeline.details.stages.length > 0"
- v-for="stage in pipeline.details.stages">
+ <td class="stage-cell">
+ <div class="stage-container dropdown js-mini-pipeline-graph"
+ v-if="pipeline.details.stages.length > 0"
+ v-for="stage in pipeline.details.stages">
- <dropdown-stage
- :stage="stage"
- :update-dropdown="updateGraphDropdown"/>
- </div>
- </td>
+ <pipeline-stage
+ :stage="stage"
+ :update-dropdown="updateGraphDropdown"
+ />
+ </div>
+ </td>
- <time-ago
- :duration="pipelineDuration"
- :finished-time="pipelineFinishedAt" />
+ <pipelines-timeago
+ :duration="pipelineDuration"
+ :finished-time="pipelineFinishedAt"
+ />
- <td class="pipeline-actions">
- <div class="pull-right btn-group">
- <pipelines-actions-component
- v-if="pipeline.details.manual_actions.length"
- :actions="pipeline.details.manual_actions"
- :service="service" />
+ <td class="pipeline-actions">
+ <div class="pull-right btn-group">
+ <pipelines-actions-component
+ v-if="pipeline.details.manual_actions.length"
+ :actions="pipeline.details.manual_actions"
+ :service="service"
+ />
- <pipelines-artifacts-component
- v-if="pipeline.details.artifacts.length"
- :artifacts="pipeline.details.artifacts" />
+ <pipelines-artifacts-component
+ v-if="pipeline.details.artifacts.length"
+ :artifacts="pipeline.details.artifacts"
+ />
- <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"
- icon="repeat" />
+ <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"
+ icon="repeat"
+ />
- <async-button-component
- v-if="pipeline.flags.cancelable"
- :service="service"
- :endpoint="pipeline.cancel_path"
- css-class="js-pipelines-cancel-button btn-remove"
- title="Cancel"
- icon="remove"
- confirm-action-message="Are you sure you want to cancel this pipeline?" />
- </div>
- </td>
- </tr>
- `,
-};
+ <async-button-component
+ v-if="pipeline.flags.cancelable"
+ :service="service"
+ :endpoint="pipeline.cancel_path"
+ css-class="js-pipelines-cancel-button btn-remove"
+ title="Cancel"
+ icon="remove"
+ confirm-action-message="Are you sure you want to cancel this pipeline?"
+ />
+ </div>
+ </td>
+ </tr>
+</template>
diff --git a/app/assets/stylesheets/framework/selects.scss b/app/assets/stylesheets/framework/selects.scss
index 5ae833cd5f6..1b20c35ad98 100644
--- a/app/assets/stylesheets/framework/selects.scss
+++ b/app/assets/stylesheets/framework/selects.scss
@@ -109,10 +109,12 @@
line-height: 15px;
background-color: $gray-light;
background-image: none;
+ padding: 3px 18px 3px 5px;
.select2-search-choice-close {
- top: 4px;
- left: 3px;
+ top: 5px;
+ left: initial;
+ right: 3px;
}
&.select2-search-choice-focus {
diff --git a/app/assets/stylesheets/framework/tw_bootstrap_variables.scss b/app/assets/stylesheets/framework/tw_bootstrap_variables.scss
index c9f345d24be..b666223b120 100644
--- a/app/assets/stylesheets/framework/tw_bootstrap_variables.scss
+++ b/app/assets/stylesheets/framework/tw_bootstrap_variables.scss
@@ -74,9 +74,9 @@ $pagination-hover-color: $gl-text-color;
$pagination-hover-bg: $row-hover;
$pagination-hover-border: $border-color;
-$pagination-active-color: $blue-600;
-$pagination-active-bg: $white-light;
-$pagination-active-border: $border-color;
+$pagination-active-color: $white-light;
+$pagination-active-bg: $gl-link-color;
+$pagination-active-border: $gl-link-color;
$pagination-disabled-color: #cdcdcd;
$pagination-disabled-bg: $gray-light;
diff --git a/app/assets/stylesheets/pages/events.scss b/app/assets/stylesheets/pages/events.scss
index 5b723f7c722..4c3fa1fb8d4 100644
--- a/app/assets/stylesheets/pages/events.scss
+++ b/app/assets/stylesheets/pages/events.scss
@@ -89,7 +89,6 @@
background: $gray-light;
border-radius: 0;
color: $events-pre-color;
- margin: 0 20px;
overflow: hidden;
}
diff --git a/app/controllers/admin/application_settings_controller.rb b/app/controllers/admin/application_settings_controller.rb
index 75fb19e815f..4d4b8a8425f 100644
--- a/app/controllers/admin/application_settings_controller.rb
+++ b/app/controllers/admin/application_settings_controller.rb
@@ -100,6 +100,8 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
:enabled_git_access_protocol,
:gravatar_enabled,
:help_page_text,
+ :help_page_hide_commercial_content,
+ :help_page_support_url,
:home_page_url,
:housekeeping_bitmaps_enabled,
:housekeeping_enabled,
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 71154da7ec5..2bfc7586adc 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -204,6 +204,10 @@ module ApplicationHelper
'https://' + promo_host
end
+ def support_url
+ current_application_settings.help_page_support_url.presence || promo_url + '/getting-help/'
+ end
+
def page_filter_path(options = {})
without = options.delete(:without)
add_label = options.delete(:label)
diff --git a/app/helpers/diff_helper.rb b/app/helpers/diff_helper.rb
index 2ae3a616933..06822747d11 100644
--- a/app/helpers/diff_helper.rb
+++ b/app/helpers/diff_helper.rb
@@ -124,6 +124,30 @@ module DiffHelper
!diff_file.deleted_file? && @merge_request && @merge_request.source_project
end
+ def diff_render_error_reason(viewer)
+ case viewer.render_error
+ when :too_large
+ "it is too large"
+ when :server_side_but_stored_externally
+ case viewer.diff_file.external_storage
+ when :lfs
+ 'it is stored in LFS'
+ else
+ 'it is stored externally'
+ end
+ end
+ end
+
+ def diff_render_error_options(viewer)
+ diff_file = viewer.diff_file
+ options = []
+
+ blob_url = namespace_project_blob_path(@project.namespace, @project, tree_join(diff_file.content_sha, diff_file.file_path))
+ options << link_to('view the blob', blob_url)
+
+ options
+ end
+
private
def diff_btn(title, name, selected)
diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb
index 2192f76499d..668caef0d2c 100644
--- a/app/models/application_setting.rb
+++ b/app/models/application_setting.rb
@@ -37,7 +37,12 @@ class ApplicationSetting < ActiveRecord::Base
validates :home_page_url,
allow_blank: true,
url: true,
- if: :home_page_url_column_exist
+ if: :home_page_url_column_exists?
+
+ validates :help_page_support_url,
+ allow_blank: true,
+ url: true,
+ if: :help_page_support_url_column_exists?
validates :after_sign_out_path,
allow_blank: true,
@@ -215,6 +220,7 @@ class ApplicationSetting < ActiveRecord::Base
domain_whitelist: Settings.gitlab['domain_whitelist'],
gravatar_enabled: Settings.gravatar['enabled'],
help_page_text: nil,
+ help_page_hide_commercial_content: false,
unique_ips_limit_per_user: 10,
unique_ips_limit_time_window: 3600,
unique_ips_limit_enabled: false,
@@ -263,10 +269,14 @@ class ApplicationSetting < ActiveRecord::Base
end
end
- def home_page_url_column_exist
+ def home_page_url_column_exists?
ActiveRecord::Base.connection.column_exists?(:application_settings, :home_page_url)
end
+ def help_page_support_url_column_exists?
+ ActiveRecord::Base.connection.column_exists?(:application_settings, :help_page_support_url)
+ end
+
def sidekiq_throttling_column_exists?
ActiveRecord::Base.connection.column_exists?(:application_settings, :sidekiq_throttling_enabled)
end
diff --git a/app/models/blob_viewer/server_side.rb b/app/models/blob_viewer/server_side.rb
index e6bcacf7f70..fbc1b520c01 100644
--- a/app/models/blob_viewer/server_side.rb
+++ b/app/models/blob_viewer/server_side.rb
@@ -13,14 +13,12 @@ module BlobViewer
end
def render_error
- if blob.stored_externally?
- # Files that are not stored in the repository, like LFS files and
- # build artifacts, can only be rendered using a client-side viewer,
- # since we do not want to read large amounts of data into memory on the
- # server side. Client-side viewers use JS and can fetch the file from
- # `blob_raw_url` using AJAX.
- return :server_side_but_stored_externally
- end
+ # Files that are not stored in the repository, like LFS files and
+ # build artifacts, can only be rendered using a client-side viewer,
+ # since we do not want to read large amounts of data into memory on the
+ # server side. Client-side viewers use JS and can fetch the file from
+ # `blob_raw_url` using AJAX.
+ return :server_side_but_stored_externally if blob.stored_externally?
super
end
diff --git a/app/models/diff_viewer/added.rb b/app/models/diff_viewer/added.rb
new file mode 100644
index 00000000000..1909e6ef9d8
--- /dev/null
+++ b/app/models/diff_viewer/added.rb
@@ -0,0 +1,8 @@
+module DiffViewer
+ class Added < Base
+ include Simple
+ include Static
+
+ self.partial_name = 'added'
+ end
+end
diff --git a/app/models/diff_viewer/base.rb b/app/models/diff_viewer/base.rb
new file mode 100644
index 00000000000..0cbe714288d
--- /dev/null
+++ b/app/models/diff_viewer/base.rb
@@ -0,0 +1,87 @@
+module DiffViewer
+ class Base
+ PARTIAL_PATH_PREFIX = 'projects/diffs/viewers'.freeze
+
+ class_attribute :partial_name, :type, :extensions, :file_types, :binary, :switcher_icon, :switcher_title
+
+ # These limits relate to the sum of the old and new blob sizes.
+ # Limits related to the actual size of the diff are enforced in Gitlab::Diff::File.
+ class_attribute :collapse_limit, :size_limit
+
+ delegate :partial_path, :loading_partial_path, :rich?, :simple?, :text?, :binary?, to: :class
+
+ attr_reader :diff_file
+
+ delegate :project, to: :diff_file
+
+ def initialize(diff_file)
+ @diff_file = diff_file
+ @initially_binary = diff_file.binary?
+ end
+
+ def self.partial_path
+ File.join(PARTIAL_PATH_PREFIX, partial_name)
+ end
+
+ def self.rich?
+ type == :rich
+ end
+
+ def self.simple?
+ type == :simple
+ end
+
+ def self.binary?
+ binary
+ end
+
+ def self.text?
+ !binary?
+ end
+
+ def self.can_render?(diff_file, verify_binary: true)
+ can_render_blob?(diff_file.old_blob, verify_binary: verify_binary) &&
+ can_render_blob?(diff_file.new_blob, verify_binary: verify_binary)
+ end
+
+ def self.can_render_blob?(blob, verify_binary: true)
+ return true if blob.nil?
+ return false if verify_binary && binary? != blob.binary?
+ return true if extensions&.include?(blob.extension)
+ return true if file_types&.include?(blob.file_type)
+
+ false
+ end
+
+ def collapsed?
+ return @collapsed if defined?(@collapsed)
+ return @collapsed = true if diff_file.collapsed?
+
+ @collapsed = !diff_file.expanded? && collapse_limit && diff_file.raw_size > collapse_limit
+ end
+
+ def too_large?
+ return @too_large if defined?(@too_large)
+ return @too_large = true if diff_file.too_large?
+
+ @too_large = size_limit && diff_file.raw_size > size_limit
+ end
+
+ def binary_detected_after_load?
+ !@initially_binary && diff_file.binary?
+ end
+
+ # This method is used on the server side to check whether we can attempt to
+ # render the diff_file at all. Human-readable error messages are found in the
+ # `BlobHelper#diff_render_error_reason` helper.
+ def render_error
+ if too_large?
+ :too_large
+ end
+ end
+
+ def prepare!
+ # To be overridden by subclasses
+ end
+ end
+end
diff --git a/app/models/diff_viewer/client_side.rb b/app/models/diff_viewer/client_side.rb
new file mode 100644
index 00000000000..cf41d07f8eb
--- /dev/null
+++ b/app/models/diff_viewer/client_side.rb
@@ -0,0 +1,10 @@
+module DiffViewer
+ module ClientSide
+ extend ActiveSupport::Concern
+
+ included do
+ self.collapse_limit = 1.megabyte
+ self.size_limit = 10.megabytes
+ end
+ end
+end
diff --git a/app/models/diff_viewer/deleted.rb b/app/models/diff_viewer/deleted.rb
new file mode 100644
index 00000000000..9c129bac694
--- /dev/null
+++ b/app/models/diff_viewer/deleted.rb
@@ -0,0 +1,8 @@
+module DiffViewer
+ class Deleted < Base
+ include Simple
+ include Static
+
+ self.partial_name = 'deleted'
+ end
+end
diff --git a/app/models/diff_viewer/image.rb b/app/models/diff_viewer/image.rb
new file mode 100644
index 00000000000..759d9a36ebb
--- /dev/null
+++ b/app/models/diff_viewer/image.rb
@@ -0,0 +1,12 @@
+module DiffViewer
+ class Image < Base
+ include Rich
+ include ClientSide
+
+ self.partial_name = 'image'
+ self.extensions = UploaderHelper::IMAGE_EXT
+ self.binary = true
+ self.switcher_icon = 'picture-o'
+ self.switcher_title = 'image diff'
+ end
+end
diff --git a/app/models/diff_viewer/mode_changed.rb b/app/models/diff_viewer/mode_changed.rb
new file mode 100644
index 00000000000..d487d996f8d
--- /dev/null
+++ b/app/models/diff_viewer/mode_changed.rb
@@ -0,0 +1,8 @@
+module DiffViewer
+ class ModeChanged < Base
+ include Simple
+ include Static
+
+ self.partial_name = 'mode_changed'
+ end
+end
diff --git a/app/models/diff_viewer/no_preview.rb b/app/models/diff_viewer/no_preview.rb
new file mode 100644
index 00000000000..5455fee4490
--- /dev/null
+++ b/app/models/diff_viewer/no_preview.rb
@@ -0,0 +1,9 @@
+module DiffViewer
+ class NoPreview < Base
+ include Simple
+ include Static
+
+ self.partial_name = 'no_preview'
+ self.binary = true
+ end
+end
diff --git a/app/models/diff_viewer/not_diffable.rb b/app/models/diff_viewer/not_diffable.rb
new file mode 100644
index 00000000000..4f9638626ea
--- /dev/null
+++ b/app/models/diff_viewer/not_diffable.rb
@@ -0,0 +1,9 @@
+module DiffViewer
+ class NotDiffable < Base
+ include Simple
+ include Static
+
+ self.partial_name = 'not_diffable'
+ self.binary = true
+ end
+end
diff --git a/app/models/diff_viewer/renamed.rb b/app/models/diff_viewer/renamed.rb
new file mode 100644
index 00000000000..f1fbfd8c6d5
--- /dev/null
+++ b/app/models/diff_viewer/renamed.rb
@@ -0,0 +1,8 @@
+module DiffViewer
+ class Renamed < Base
+ include Simple
+ include Static
+
+ self.partial_name = 'renamed'
+ end
+end
diff --git a/app/models/diff_viewer/rich.rb b/app/models/diff_viewer/rich.rb
new file mode 100644
index 00000000000..3b0ca6e4cff
--- /dev/null
+++ b/app/models/diff_viewer/rich.rb
@@ -0,0 +1,11 @@
+module DiffViewer
+ module Rich
+ extend ActiveSupport::Concern
+
+ included do
+ self.type = :rich
+ self.switcher_icon = 'file-text-o'
+ self.switcher_title = 'rendered diff'
+ end
+ end
+end
diff --git a/app/models/diff_viewer/server_side.rb b/app/models/diff_viewer/server_side.rb
new file mode 100644
index 00000000000..aed1a0791b1
--- /dev/null
+++ b/app/models/diff_viewer/server_side.rb
@@ -0,0 +1,26 @@
+module DiffViewer
+ module ServerSide
+ extend ActiveSupport::Concern
+
+ included do
+ self.collapse_limit = 1.megabyte
+ self.size_limit = 5.megabytes
+ end
+
+ def prepare!
+ diff_file.old_blob&.load_all_data!
+ diff_file.new_blob&.load_all_data!
+ end
+
+ def render_error
+ # Files that are not stored in the repository, like LFS files and
+ # build artifacts, can only be rendered using a client-side viewer,
+ # since we do not want to read large amounts of data into memory on the
+ # server side. Client-side viewers use JS and can fetch the file from
+ # `diff_file_blob_raw_path` and `diff_file_old_blob_raw_path` using AJAX.
+ return :server_side_but_stored_externally if diff_file.stored_externally?
+
+ super
+ end
+ end
+end
diff --git a/app/models/diff_viewer/simple.rb b/app/models/diff_viewer/simple.rb
new file mode 100644
index 00000000000..65750996ee4
--- /dev/null
+++ b/app/models/diff_viewer/simple.rb
@@ -0,0 +1,11 @@
+module DiffViewer
+ module Simple
+ extend ActiveSupport::Concern
+
+ included do
+ self.type = :simple
+ self.switcher_icon = 'code'
+ self.switcher_title = 'source diff'
+ end
+ end
+end
diff --git a/app/models/diff_viewer/static.rb b/app/models/diff_viewer/static.rb
new file mode 100644
index 00000000000..d761328b3f6
--- /dev/null
+++ b/app/models/diff_viewer/static.rb
@@ -0,0 +1,10 @@
+module DiffViewer
+ module Static
+ extend ActiveSupport::Concern
+
+ # We can always render a static viewer, even if the diff is too large.
+ def render_error
+ nil
+ end
+ end
+end
diff --git a/app/models/diff_viewer/text.rb b/app/models/diff_viewer/text.rb
new file mode 100644
index 00000000000..98f4b2aea2a
--- /dev/null
+++ b/app/models/diff_viewer/text.rb
@@ -0,0 +1,15 @@
+module DiffViewer
+ class Text < Base
+ include Simple
+ include ServerSide
+
+ self.partial_name = 'text'
+ self.binary = false
+
+ # Since the text diff viewer doesn't render the old and new blobs in full,
+ # we only need the limits related to the actual size of the diff which are
+ # already enforced in Gitlab::Diff::File.
+ self.collapse_limit = nil
+ self.size_limit = nil
+ end
+end
diff --git a/app/models/environment.rb b/app/models/environment.rb
index 6211a5c1e63..d5b974b2d31 100644
--- a/app/models/environment.rb
+++ b/app/models/environment.rb
@@ -209,7 +209,8 @@ class Environment < ActiveRecord::Base
def etag_cache_key
Gitlab::Routing.url_helpers.namespace_project_environments_path(
project.namespace,
- project)
+ project,
+ format: :json)
end
private
diff --git a/app/models/project_services/kubernetes_service.rb b/app/models/project_services/kubernetes_service.rb
index 8977a7cdafe..48e7802c557 100644
--- a/app/models/project_services/kubernetes_service.rb
+++ b/app/models/project_services/kubernetes_service.rb
@@ -116,30 +116,19 @@ class KubernetesService < DeploymentService
# short time later
def terminals(environment)
with_reactive_cache do |data|
- pods = data.fetch(:pods, nil)
- filter_pods(pods, app: environment.slug).
- flat_map { |pod| terminals_for_pod(api_url, actual_namespace, pod) }.
- each { |terminal| add_terminal_auth(terminal, terminal_auth) }
+ pods = filter_by_label(data[:pods], app: environment.slug)
+ terminals = pods.flat_map { |pod| terminals_for_pod(api_url, actual_namespace, pod) }
+ terminals.each { |terminal| add_terminal_auth(terminal, terminal_auth) }
end
end
- # Caches all pods in the namespace so other calls don't need to block on
- # network access.
+ # Caches resources in the namespace so other calls don't need to block on
+ # network access
def calculate_reactive_cache
return unless active? && project && !project.pending_delete?
- kubeclient = build_kubeclient!
-
- # Store as hashes, rather than as third-party types
- pods = begin
- kubeclient.get_pods(namespace: actual_namespace).as_json
- rescue KubeException => err
- raise err unless err.error_code == 404
- []
- end
-
# We may want to cache extra things in the future
- { pods: pods }
+ { pods: read_pods }
end
TEMPLATE_PLACEHOLDER = 'Kubernetes namespace'.freeze
@@ -166,6 +155,16 @@ class KubernetesService < DeploymentService
)
end
+ # Returns a hash of all pods in the namespace
+ def read_pods
+ kubeclient = build_kubeclient!
+
+ kubeclient.get_pods(namespace: actual_namespace).as_json
+ rescue KubeException => err
+ raise err unless err.error_code == 404
+ []
+ end
+
def kubeclient_ssl_options
opts = { verify_ssl: OpenSSL::SSL::VERIFY_PEER }
@@ -181,11 +180,11 @@ class KubernetesService < DeploymentService
{ bearer_token: token }
end
- def join_api_url(*parts)
+ def join_api_url(api_path)
url = URI.parse(api_url)
prefix = url.path.sub(%r{/+\z}, '')
- url.path = [prefix, *parts].join("/")
+ url.path = [prefix, api_path].join("/")
url.to_s
end
diff --git a/app/serializers/build_details_entity.rb b/app/serializers/build_details_entity.rb
index cb6d3dfec89..eeb5399aa8b 100644
--- a/app/serializers/build_details_entity.rb
+++ b/app/serializers/build_details_entity.rb
@@ -25,7 +25,7 @@ class BuildDetailsEntity < JobEntity
end
expose :raw_path do |build|
- raw_namespace_project_build_path(project.namespace, project, build)
+ raw_namespace_project_job_path(project.namespace, project, build)
end
private
diff --git a/app/services/slash_commands/interpret_service.rb b/app/services/slash_commands/interpret_service.rb
index b6b411d2185..83144b1e011 100644
--- a/app/services/slash_commands/interpret_service.rb
+++ b/app/services/slash_commands/interpret_service.rb
@@ -410,7 +410,7 @@ module SlashCommands
params '@user'
command :cc
- desc 'Define target branch for MR'
+ desc 'Set target branch'
explanation do |branch_name|
"Sets target branch to #{branch_name}."
end
diff --git a/app/views/admin/application_settings/_form.html.haml b/app/views/admin/application_settings/_form.html.haml
index d552704df88..0383c7ce546 100644
--- a/app/views/admin/application_settings/_form.html.haml
+++ b/app/views/admin/application_settings/_form.html.haml
@@ -180,11 +180,25 @@
.col-sm-10
= f.text_area :sign_in_text, class: 'form-control', rows: 4
.help-block Markdown enabled
+
+ %fieldset
+ %legend Help Page
.form-group
= f.label :help_page_text, class: 'control-label col-sm-2'
.col-sm-10
= f.text_area :help_page_text, class: 'form-control', rows: 4
.help-block Markdown enabled
+ .form-group
+ .col-sm-offset-2.col-sm-10
+ .checkbox
+ = f.label :help_page_hide_commercial_content do
+ = f.check_box :help_page_hide_commercial_content
+ Hide marketing-related entries from help
+ .form-group
+ = f.label :help_page_support_url, 'Support page URL', class: 'control-label col-sm-2'
+ .col-sm-10
+ = f.text_field :help_page_support_url, class: 'form-control', placeholder: 'http://company.example.com/getting-help', :'aria-describedby' => 'support_help_block'
+ %span.help-block#support_help_block Alternate support URL for help page
%fieldset
%legend Pages
diff --git a/app/views/help/index.html.haml b/app/views/help/index.html.haml
index 31d0e589c26..c25eae63eec 100644
--- a/app/views/help/index.html.haml
+++ b/app/views/help/index.html.haml
@@ -1,4 +1,9 @@
%div
+- if current_application_settings.help_page_text.present?
+ = markdown_field(current_application_settings, :help_page_text)
+ %hr
+
+- unless current_application_settings.help_page_hide_commercial_content?
%h1
GitLab
Community Edition
@@ -18,13 +23,9 @@
Used by more than 100,000 organizations, GitLab is the most popular solution to manage git repositories on-premises.
%br
Read more about GitLab at #{link_to promo_host, promo_url, target: '_blank', rel: 'noopener noreferrer'}.
- - if current_application_settings.help_page_text.present?
- %hr
- = markdown_field(current_application_settings, :help_page_text)
-
-%hr
+ %hr
-.row
+.row.prepend-top-default
.col-md-8
.documentation-index
= markdown(@help_index)
@@ -33,8 +34,9 @@
.panel-heading
Quick help
%ul.well-list
- %li= link_to 'See our website for getting help', promo_url + '/getting-help/'
+ %li= link_to 'See our website for getting help', support_url
%li= link_to 'Use the search bar on the top of this page', '#', onclick: 'Shortcuts.focusSearch(event)'
%li= link_to 'Use shortcuts', '#', onclick: 'Shortcuts.toggleHelp()'
- %li= link_to 'Get a support subscription', 'https://about.gitlab.com/pricing/'
- %li= link_to 'Compare GitLab editions', 'https://about.gitlab.com/features/#compare'
+ - unless current_application_settings.help_page_hide_commercial_content?
+ %li= link_to 'Get a support subscription', 'https://about.gitlab.com/pricing/'
+ %li= link_to 'Compare GitLab editions', 'https://about.gitlab.com/features/#compare'
diff --git a/app/views/help/show.html.haml b/app/views/help/show.html.haml
index f6ebd76af9d..c07c148a12a 100644
--- a/app/views/help/show.html.haml
+++ b/app/views/help/show.html.haml
@@ -1,3 +1,3 @@
- page_title @path.split("/").reverse.map(&:humanize)
-.documentation.wiki
+.documentation.wiki.prepend-top-default
= markdown @markdown
diff --git a/app/views/projects/diffs/_collapsed.html.haml b/app/views/projects/diffs/_collapsed.html.haml
new file mode 100644
index 00000000000..8772bd4705f
--- /dev/null
+++ b/app/views/projects/diffs/_collapsed.html.haml
@@ -0,0 +1,5 @@
+- diff_file = viewer.diff_file
+- url = url_for(params.merge(action: :diff_for_path, old_path: diff_file.old_path, new_path: diff_file.new_path, file_identifier: diff_file.file_identifier))
+.nothing-here-block.diff-collapsed{ data: { diff_for_path: url } }
+ This diff is collapsed.
+ %a.click-to-expand Click to expand it.
diff --git a/app/views/projects/diffs/_content.html.haml b/app/views/projects/diffs/_content.html.haml
index ec1c434a4b8..68f74f702ea 100644
--- a/app/views/projects/diffs/_content.html.haml
+++ b/app/views/projects/diffs/_content.html.haml
@@ -1,27 +1,2 @@
-- blob = diff_file.blob
-
.diff-content
- - if diff_file.too_large?
- .nothing-here-block This diff could not be displayed because it is too large.
- - elsif blob.truncated?
- .nothing-here-block The file could not be displayed because it is too large.
- - elsif blob.readable_text?
- - if !diff_file.diffable?
- .nothing-here-block This diff was suppressed by a .gitattributes entry.
- - elsif diff_file.collapsed?
- - url = url_for(params.merge(action: :diff_for_path, old_path: diff_file.old_path, new_path: diff_file.new_path, file_identifier: diff_file.file_identifier))
- .nothing-here-block.diff-collapsed{ data: { diff_for_path: url } }
- This diff is collapsed.
- %a.click-to-expand
- Click to expand it.
- - elsif diff_file.diff_lines.length > 0
- = render "projects/diffs/viewers/text", diff_file: diff_file
- - else
- - if diff_file.mode_changed?
- .nothing-here-block File mode changed
- - elsif diff_file.renamed_file?
- .nothing-here-block File moved
- - elsif blob.image?
- = render "projects/diffs/viewers/image", diff_file: diff_file
- - else
- .nothing-here-block No preview for this file type
+ = render 'projects/diffs/viewer', viewer: diff_file.rich_viewer || diff_file.simple_viewer
diff --git a/app/views/projects/diffs/_render_error.html.haml b/app/views/projects/diffs/_render_error.html.haml
new file mode 100644
index 00000000000..47a9ac3ee6b
--- /dev/null
+++ b/app/views/projects/diffs/_render_error.html.haml
@@ -0,0 +1,6 @@
+.nothing-here-block
+ This #{viewer.switcher_title} could not be displayed because #{diff_render_error_reason(viewer)}.
+
+ You can
+ = diff_render_error_options(viewer).to_sentence(two_words_connector: ' or ', last_word_connector: ', or ').html_safe
+ instead.
diff --git a/app/views/projects/diffs/_viewer.html.haml b/app/views/projects/diffs/_viewer.html.haml
new file mode 100644
index 00000000000..5c4d1760871
--- /dev/null
+++ b/app/views/projects/diffs/_viewer.html.haml
@@ -0,0 +1,16 @@
+- hidden = local_assigns.fetch(:hidden, false)
+
+.diff-viewer{ data: { type: viewer.type }, class: ('hidden' if hidden) }
+ - if viewer.render_error
+ = render 'projects/diffs/render_error', viewer: viewer
+ - elsif viewer.collapsed?
+ = render 'projects/diffs/collapsed', viewer: viewer
+ - else
+ - viewer.prepare!
+
+ -# In the rare case where the first kilobyte of the file looks like text,
+ -# but the file turns out to actually be binary after loading all data,
+ -# we fall back on the binary No Preview viewer.
+ - viewer = DiffViewer::NoPreview.new(viewer.diff_file) if viewer.binary_detected_after_load?
+
+ = render viewer.partial_path, viewer: viewer
diff --git a/app/views/projects/diffs/viewers/_added.html.haml b/app/views/projects/diffs/viewers/_added.html.haml
new file mode 100644
index 00000000000..8004fe16688
--- /dev/null
+++ b/app/views/projects/diffs/viewers/_added.html.haml
@@ -0,0 +1,2 @@
+.nothing-here-block
+ File added
diff --git a/app/views/projects/diffs/viewers/_deleted.html.haml b/app/views/projects/diffs/viewers/_deleted.html.haml
new file mode 100644
index 00000000000..0ac7b4ca8f6
--- /dev/null
+++ b/app/views/projects/diffs/viewers/_deleted.html.haml
@@ -0,0 +1,2 @@
+.nothing-here-block
+ File deleted
diff --git a/app/views/projects/diffs/viewers/_image.html.haml b/app/views/projects/diffs/viewers/_image.html.haml
index ea75373581e..19d08181223 100644
--- a/app/views/projects/diffs/viewers/_image.html.haml
+++ b/app/views/projects/diffs/viewers/_image.html.haml
@@ -1,3 +1,4 @@
+- diff_file = viewer.diff_file
- blob = diff_file.blob
- old_blob = diff_file.old_blob
- blob_raw_path = diff_file_blob_raw_path(diff_file)
diff --git a/app/views/projects/diffs/viewers/_mode_changed.html.haml b/app/views/projects/diffs/viewers/_mode_changed.html.haml
new file mode 100644
index 00000000000..69bc96bbdad
--- /dev/null
+++ b/app/views/projects/diffs/viewers/_mode_changed.html.haml
@@ -0,0 +1,3 @@
+- diff_file = viewer.diff_file
+.nothing-here-block
+ File mode changed from #{diff_file.a_mode} to #{diff_file.b_mode}
diff --git a/app/views/projects/diffs/viewers/_no_preview.html.haml b/app/views/projects/diffs/viewers/_no_preview.html.haml
new file mode 100644
index 00000000000..befe070af2b
--- /dev/null
+++ b/app/views/projects/diffs/viewers/_no_preview.html.haml
@@ -0,0 +1,2 @@
+.nothing-here-block
+ No preview for this file type
diff --git a/app/views/projects/diffs/viewers/_not_diffable.html.haml b/app/views/projects/diffs/viewers/_not_diffable.html.haml
new file mode 100644
index 00000000000..b2c677ec59c
--- /dev/null
+++ b/app/views/projects/diffs/viewers/_not_diffable.html.haml
@@ -0,0 +1,2 @@
+.nothing-here-block
+ This diff was suppressed by a .gitattributes entry.
diff --git a/app/views/projects/diffs/viewers/_renamed.html.haml b/app/views/projects/diffs/viewers/_renamed.html.haml
new file mode 100644
index 00000000000..ef05ee38d8d
--- /dev/null
+++ b/app/views/projects/diffs/viewers/_renamed.html.haml
@@ -0,0 +1,2 @@
+.nothing-here-block
+ File moved
diff --git a/app/views/projects/diffs/viewers/_text.html.haml b/app/views/projects/diffs/viewers/_text.html.haml
index 120d3540223..509e68598c9 100644
--- a/app/views/projects/diffs/viewers/_text.html.haml
+++ b/app/views/projects/diffs/viewers/_text.html.haml
@@ -1,5 +1,5 @@
+- diff_file = viewer.diff_file
- blob = diff_file.blob
-- blob.load_all_data!
- total_lines = blob.lines.size
- total_lines -= 1 if total_lines > 0 && blob.lines.last.blank?
- if diff_view == :parallel
diff --git a/changelogs/unreleased/32470-pag-links.yml b/changelogs/unreleased/32470-pag-links.yml
new file mode 100644
index 00000000000..d0fd284f3ee
--- /dev/null
+++ b/changelogs/unreleased/32470-pag-links.yml
@@ -0,0 +1,4 @@
+---
+title: more visual contrast in pagination widget
+merge_request:
+author:
diff --git a/changelogs/unreleased/dm-diff-viewers.yml b/changelogs/unreleased/dm-diff-viewers.yml
new file mode 100644
index 00000000000..e5b1352c8f1
--- /dev/null
+++ b/changelogs/unreleased/dm-diff-viewers.yml
@@ -0,0 +1,4 @@
+---
+title: Implement diff viewers
+merge_request:
+author:
diff --git a/changelogs/unreleased/dm-fix-parser-cache.yml b/changelogs/unreleased/dm-fix-parser-cache.yml
new file mode 100644
index 00000000000..31c163b7272
--- /dev/null
+++ b/changelogs/unreleased/dm-fix-parser-cache.yml
@@ -0,0 +1,4 @@
+---
+title: Don't return nil for missing objects from parser cache
+merge_request:
+author:
diff --git a/changelogs/unreleased/dm-target-branch-slash-command-desc.yml b/changelogs/unreleased/dm-target-branch-slash-command-desc.yml
new file mode 100644
index 00000000000..768ddf0416e
--- /dev/null
+++ b/changelogs/unreleased/dm-target-branch-slash-command-desc.yml
@@ -0,0 +1,4 @@
+---
+title: Update /target_branch slash command description to be more consistent
+merge_request:
+author:
diff --git a/changelogs/unreleased/help-landing-page-customizations.yml b/changelogs/unreleased/help-landing-page-customizations.yml
new file mode 100644
index 00000000000..58cab751ded
--- /dev/null
+++ b/changelogs/unreleased/help-landing-page-customizations.yml
@@ -0,0 +1,4 @@
+---
+title: Help landing page customizations
+merge_request: 11878
+author: Robin Bobbitt
diff --git a/changelogs/unreleased/zj-raise-etag-route-regex-miss.yml b/changelogs/unreleased/zj-raise-etag-route-regex-miss.yml
new file mode 100644
index 00000000000..57a5f4e44c0
--- /dev/null
+++ b/changelogs/unreleased/zj-raise-etag-route-regex-miss.yml
@@ -0,0 +1,4 @@
+---
+title: Fix etag route not being a match for environments
+merge_request:
+author:
diff --git a/config/webpack.config.js b/config/webpack.config.js
index 120f9d3193d..3c2455ebf35 100644
--- a/config/webpack.config.js
+++ b/config/webpack.config.js
@@ -61,7 +61,7 @@ var config = {
network: './network/network_bundle.js',
notebook_viewer: './blob/notebook_viewer.js',
pdf_viewer: './blob/pdf_viewer.js',
- pipelines: './pipelines/index.js',
+ pipelines: './pipelines/pipelines_bundle.js',
pipelines_details: './pipelines/pipeline_details_bundle.js',
profile: './profile/profile_bundle.js',
protected_branches: './protected_branches/protected_branches_bundle.js',
diff --git a/db/migrate/20170602154736_add_help_page_hide_commercial_content_to_application_settings.rb b/db/migrate/20170602154736_add_help_page_hide_commercial_content_to_application_settings.rb
new file mode 100644
index 00000000000..5e8b667b86d
--- /dev/null
+++ b/db/migrate/20170602154736_add_help_page_hide_commercial_content_to_application_settings.rb
@@ -0,0 +1,9 @@
+class AddHelpPageHideCommercialContentToApplicationSettings < ActiveRecord::Migration
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ def change
+ add_column :application_settings, :help_page_hide_commercial_content, :boolean, default: false
+ end
+end
diff --git a/db/migrate/20170602154813_add_help_page_support_url_to_application_settings.rb b/db/migrate/20170602154813_add_help_page_support_url_to_application_settings.rb
new file mode 100644
index 00000000000..138fe9b2a37
--- /dev/null
+++ b/db/migrate/20170602154813_add_help_page_support_url_to_application_settings.rb
@@ -0,0 +1,9 @@
+class AddHelpPageSupportUrlToApplicationSettings < ActiveRecord::Migration
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ def change
+ add_column :application_settings, :help_page_support_url, :string
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index b93630a410d..9d79fe162b7 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -12,6 +12,7 @@
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20170606202615) do
+
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
enable_extension "pg_trgm"
@@ -123,6 +124,8 @@ ActiveRecord::Schema.define(version: 20170606202615) do
t.boolean "clientside_sentry_enabled", default: false, null: false
t.string "clientside_sentry_dsn"
t.boolean "prometheus_metrics_enabled", default: false, null: false
+ t.boolean "help_page_hide_commercial_content", default: false
+ t.string "help_page_support_url"
end
create_table "audit_events", force: :cascade do |t|
diff --git a/doc/user/project/integrations/jira.md b/doc/user/project/integrations/jira.md
index a048260b033..e8dbf8d08d2 100644
--- a/doc/user/project/integrations/jira.md
+++ b/doc/user/project/integrations/jira.md
@@ -76,7 +76,7 @@ We have split this stage in steps so it is easier to follow.
![JIRA add user to group](img/jira_add_user_to_group.png)
----
+ ---
The JIRA configuration is over. Write down the new JIRA username and its
password as they will be needed when configuring GitLab in the next section.
diff --git a/lib/api/entities.rb b/lib/api/entities.rb
index af55c372eea..412443a2405 100644
--- a/lib/api/entities.rb
+++ b/lib/api/entities.rb
@@ -603,6 +603,9 @@ module API
expose :plantuml_url
expose :terminal_max_session_time
expose :polling_interval_multiplier
+ expose :help_page_hide_commercial_content
+ expose :help_page_text
+ expose :help_page_support_url
end
class Release < Grape::Entity
diff --git a/lib/api/settings.rb b/lib/api/settings.rb
index 25027c3b114..d598f9a62a2 100644
--- a/lib/api/settings.rb
+++ b/lib/api/settings.rb
@@ -39,7 +39,9 @@ module API
:email_author_in_body,
:enabled_git_access_protocol,
:gravatar_enabled,
+ :help_page_hide_commercial_content,
:help_page_text,
+ :help_page_support_url,
:home_page_url,
:housekeeping_enabled,
:html_emails_enabled,
@@ -101,7 +103,9 @@ module API
optional :home_page_url, type: String, desc: 'We will redirect non-logged in users to this page'
optional :after_sign_out_path, type: String, desc: 'We will redirect users to this page after they sign out'
optional :sign_in_text, type: String, desc: 'The sign in text of the GitLab application'
+ optional :help_page_hide_commercial_content, type: Boolean, desc: 'Hide marketing-related entries from help'
optional :help_page_text, type: String, desc: 'Custom text displayed on the help page'
+ optional :help_page_support_url, type: String, desc: 'Alternate support URL for help page'
optional :shared_runners_enabled, type: Boolean, desc: 'Enable shared runners for new projects'
given shared_runners_enabled: ->(val) { val } do
requires :shared_runners_text, type: String, desc: 'Shared runners text '
diff --git a/lib/banzai/reference_parser/base_parser.rb b/lib/banzai/reference_parser/base_parser.rb
index 1e2536231d8..279fca8d043 100644
--- a/lib/banzai/reference_parser/base_parser.rb
+++ b/lib/banzai/reference_parser/base_parser.rb
@@ -171,7 +171,7 @@ module Banzai
collection.where(id: to_query).each { |row| cache[row.id] = row }
end
- cache.values_at(*ids)
+ cache.values_at(*ids).compact
else
collection.where(id: ids)
end
diff --git a/lib/gitlab/diff/file.rb b/lib/gitlab/diff/file.rb
index 4212a0dbe2e..d2863a4da71 100644
--- a/lib/gitlab/diff/file.rb
+++ b/lib/gitlab/diff/file.rb
@@ -5,7 +5,20 @@ module Gitlab
delegate :new_file?, :deleted_file?, :renamed_file?,
:old_path, :new_path, :a_mode, :b_mode, :mode_changed?,
- :submodule?, :too_large?, :collapsed?, to: :diff, prefix: false
+ :submodule?, :expanded?, :too_large?, :collapsed?, :line_count, to: :diff, prefix: false
+
+ # Finding a viewer for a diff file happens based only on extension and whether the
+ # diff file blobs are binary or text, which means 1 diff file should only be matched by 1 viewer,
+ # and the order of these viewers doesn't really matter.
+ #
+ # However, when the diff file blobs are LFS pointers, we cannot know for sure whether the
+ # file being pointed to is binary or text. In this case, we match only on
+ # extension, preferring binary viewers over text ones if both exist, since the
+ # large files referred to in "Large File Storage" are much more likely to be
+ # binary than text.
+ RICH_VIEWERS = [
+ DiffViewer::Image
+ ].sort_by { |v| v.binary? ? 0 : 1 }.freeze
def initialize(diff, repository:, diff_refs: nil, fallback_diff_refs: nil)
@diff = diff
@@ -177,6 +190,100 @@ module Gitlab
def text?
!binary?
end
+
+ def external_storage_error?
+ old_blob&.external_storage_error? || new_blob&.external_storage_error?
+ end
+
+ def stored_externally?
+ old_blob&.stored_externally? || new_blob&.stored_externally?
+ end
+
+ def external_storage
+ old_blob&.external_storage || new_blob&.external_storage
+ end
+
+ def content_changed?
+ old_blob && new_blob && old_blob.id != new_blob.id
+ end
+
+ def different_type?
+ old_blob && new_blob && old_blob.binary? != new_blob.binary?
+ end
+
+ def size
+ [old_blob&.size, new_blob&.size].compact.sum
+ end
+
+ def raw_size
+ [old_blob&.raw_size, new_blob&.raw_size].compact.sum
+ end
+
+ def raw_binary?
+ old_blob&.raw_binary? || new_blob&.raw_binary?
+ end
+
+ def raw_text?
+ !raw_binary? && !different_type?
+ end
+
+ def simple_viewer
+ @simple_viewer ||= simple_viewer_class.new(self)
+ end
+
+ def rich_viewer
+ return @rich_viewer if defined?(@rich_viewer)
+
+ @rich_viewer = rich_viewer_class&.new(self)
+ end
+
+ def rendered_as_text?(ignore_errors: true)
+ simple_viewer.is_a?(DiffViewer::Text) && (ignore_errors || simple_viewer.render_error.nil?)
+ end
+
+ private
+
+ def simple_viewer_class
+ return DiffViewer::NotDiffable unless diffable?
+
+ if content_changed?
+ if raw_text?
+ DiffViewer::Text
+ else
+ DiffViewer::NoPreview
+ end
+ elsif new_file?
+ if raw_text?
+ DiffViewer::Text
+ else
+ DiffViewer::Added
+ end
+ elsif deleted_file?
+ if raw_text?
+ DiffViewer::Text
+ else
+ DiffViewer::Deleted
+ end
+ elsif renamed_file?
+ DiffViewer::Renamed
+ elsif mode_changed?
+ DiffViewer::ModeChanged
+ end
+ end
+
+ def rich_viewer_class
+ viewer_class_from(RICH_VIEWERS)
+ end
+
+ def viewer_class_from(classes)
+ return unless diffable?
+ return if different_type? || external_storage_error?
+ return unless new_file? || deleted_file? || content_changed?
+
+ verify_binary = !stored_externally?
+
+ classes.find { |viewer_class| viewer_class.can_render?(self, verify_binary: verify_binary) }
+ end
end
end
end
diff --git a/lib/gitlab/etag_caching/middleware.rb b/lib/gitlab/etag_caching/middleware.rb
index 7f884183bb1..1d6f5bb5e1c 100644
--- a/lib/gitlab/etag_caching/middleware.rb
+++ b/lib/gitlab/etag_caching/middleware.rb
@@ -7,7 +7,7 @@ module Gitlab
def call(env)
request = Rack::Request.new(env)
- route = Gitlab::EtagCaching::Router.match(request)
+ route = Gitlab::EtagCaching::Router.match(request.path_info)
return @app.call(env) unless route
track_event(:etag_caching_middleware_used, route)
diff --git a/lib/gitlab/etag_caching/router.rb b/lib/gitlab/etag_caching/router.rb
index dccc66b3918..75167a6b088 100644
--- a/lib/gitlab/etag_caching/router.rb
+++ b/lib/gitlab/etag_caching/router.rb
@@ -53,8 +53,8 @@ module Gitlab
)
].freeze
- def self.match(request)
- ROUTES.find { |route| route.regexp.match(request.path_info) }
+ def self.match(path)
+ ROUTES.find { |route| route.regexp.match(path) }
end
end
end
diff --git a/lib/gitlab/etag_caching/store.rb b/lib/gitlab/etag_caching/store.rb
index 0039fc01c8f..072fcfc65e6 100644
--- a/lib/gitlab/etag_caching/store.rb
+++ b/lib/gitlab/etag_caching/store.rb
@@ -25,6 +25,8 @@ module Gitlab
end
def redis_key(key)
+ raise 'Invalid key' if !Rails.env.production? && !Gitlab::EtagCaching::Router.match(key)
+
"#{REDIS_NAMESPACE}#{key}"
end
end
diff --git a/lib/gitlab/git/diff.rb b/lib/gitlab/git/diff.rb
index 88ad760bea3..4b689f0e94f 100644
--- a/lib/gitlab/git/diff.rb
+++ b/lib/gitlab/git/diff.rb
@@ -17,6 +17,8 @@ module Gitlab
attr_accessor :expanded
+ alias_method :expanded?, :expanded
+
# We need this accessor because of `to_hash` and `init_from_hash`
attr_accessor :too_large
diff --git a/lib/gitlab/git/diff_collection.rb b/lib/gitlab/git/diff_collection.rb
index 334e06a6eca..555894907cc 100644
--- a/lib/gitlab/git/diff_collection.rb
+++ b/lib/gitlab/git/diff_collection.rb
@@ -97,7 +97,7 @@ module Gitlab
diff = Gitlab::Git::Diff.new(raw, expanded: expanded)
- if !expanded && over_safe_limits?(i)
+ if !expanded && over_safe_limits?(i) && diff.line_count > 0
diff.collapse!
end
diff --git a/lib/gitlab/kubernetes.rb b/lib/gitlab/kubernetes.rb
index 4a6091488c8..c56c1a4322f 100644
--- a/lib/gitlab/kubernetes.rb
+++ b/lib/gitlab/kubernetes.rb
@@ -8,13 +8,13 @@ module Gitlab
)
# Filters an array of pods (as returned by the kubernetes API) by their labels
- def filter_pods(pods, labels = {})
- pods.select do |pod|
- metadata = pod.fetch("metadata", {})
- pod_labels = metadata.fetch("labels", nil)
- next unless pod_labels
+ def filter_by_label(items, labels = {})
+ items.select do |item|
+ metadata = item.fetch("metadata", {})
+ item_labels = metadata.fetch("labels", nil)
+ next unless item_labels
- labels.all? { |k, v| pod_labels[k.to_s] == v }
+ labels.all? { |k, v| item_labels[k.to_s] == v }
end
end
diff --git a/rubocop/cop/rspec/single_line_hook.rb b/rubocop/cop/rspec/single_line_hook.rb
new file mode 100644
index 00000000000..be611054323
--- /dev/null
+++ b/rubocop/cop/rspec/single_line_hook.rb
@@ -0,0 +1,38 @@
+require 'rubocop-rspec'
+
+module RuboCop
+ module Cop
+ module RSpec
+ # This cop checks for single-line hook blocks
+ #
+ # @example
+ #
+ # # bad
+ # before { do_something }
+ # after(:each) { undo_something }
+ #
+ # # good
+ # before do
+ # do_something
+ # end
+ #
+ # after(:each) do
+ # undo_something
+ # end
+ class SingleLineHook < Cop
+ MESSAGE = "Don't use single-line hook blocks.".freeze
+
+ def_node_search :rspec_hook?, <<~PATTERN
+ (send nil {:after :around :before} ...)
+ PATTERN
+
+ def on_block(node)
+ return unless rspec_hook?(node)
+ return unless node.single_line?
+
+ add_offense(node, :expression, MESSAGE)
+ end
+ end
+ end
+ end
+end
diff --git a/rubocop/rubocop.rb b/rubocop/rubocop.rb
index 6b8d127dde6..55d7708fa8c 100644
--- a/rubocop/rubocop.rb
+++ b/rubocop/rubocop.rb
@@ -15,3 +15,4 @@ require_relative 'cop/migration/remove_index'
require_relative 'cop/migration/reversible_add_column_with_default'
require_relative 'cop/migration/timestamps'
require_relative 'cop/migration/update_column_in_batches'
+require_relative 'cop/rspec/single_line_hook'
diff --git a/spec/controllers/admin/identities_controller_spec.rb b/spec/controllers/admin/identities_controller_spec.rb
index c131d22a30a..a29853bf8df 100644
--- a/spec/controllers/admin/identities_controller_spec.rb
+++ b/spec/controllers/admin/identities_controller_spec.rb
@@ -2,7 +2,10 @@ require 'spec_helper'
describe Admin::IdentitiesController do
let(:admin) { create(:admin) }
- before { sign_in(admin) }
+
+ before do
+ sign_in(admin)
+ end
describe 'UPDATE identity' do
let(:user) { create(:omniauth_user, provider: 'ldapmain', extern_uid: 'uid=myuser,ou=people,dc=example,dc=com') }
diff --git a/spec/controllers/admin/services_controller_spec.rb b/spec/controllers/admin/services_controller_spec.rb
index c94616d8508..4ca0cfc74e9 100644
--- a/spec/controllers/admin/services_controller_spec.rb
+++ b/spec/controllers/admin/services_controller_spec.rb
@@ -3,7 +3,9 @@ require 'spec_helper'
describe Admin::ServicesController do
let(:admin) { create(:admin) }
- before { sign_in(admin) }
+ before do
+ sign_in(admin)
+ end
describe 'GET #edit' do
let!(:project) { create(:empty_project) }
diff --git a/spec/controllers/autocomplete_controller_spec.rb b/spec/controllers/autocomplete_controller_spec.rb
index 4c3a5ec49ef..b40f647644d 100644
--- a/spec/controllers/autocomplete_controller_spec.rb
+++ b/spec/controllers/autocomplete_controller_spec.rb
@@ -200,7 +200,9 @@ describe AutocompleteController do
end
context 'skip_users parameter included' do
- before { sign_in(user) }
+ before do
+ sign_in(user)
+ end
it 'skips the user IDs passed' do
get(:users, skip_users: [user, user2].map(&:id))
diff --git a/spec/controllers/groups/group_members_controller_spec.rb b/spec/controllers/groups/group_members_controller_spec.rb
index ed4ad7b600e..cce53f6697c 100644
--- a/spec/controllers/groups/group_members_controller_spec.rb
+++ b/spec/controllers/groups/group_members_controller_spec.rb
@@ -16,10 +16,14 @@ describe Groups::GroupMembersController do
describe 'POST create' do
let(:group_user) { create(:user) }
- before { sign_in(user) }
+ before do
+ sign_in(user)
+ end
context 'when user does not have enough rights' do
- before { group.add_developer(user) }
+ before do
+ group.add_developer(user)
+ end
it 'returns 403' do
post :create, group_id: group,
@@ -32,7 +36,9 @@ describe Groups::GroupMembersController do
end
context 'when user has enough rights' do
- before { group.add_owner(user) }
+ before do
+ group.add_owner(user)
+ end
it 'adds user to members' do
post :create, group_id: group,
@@ -59,7 +65,9 @@ describe Groups::GroupMembersController do
describe 'DELETE destroy' do
let(:member) { create(:group_member, :developer, group: group) }
- before { sign_in(user) }
+ before do
+ sign_in(user)
+ end
context 'when member is not found' do
it 'returns 403' do
@@ -71,7 +79,9 @@ describe Groups::GroupMembersController do
context 'when member is found' do
context 'when user does not have enough rights' do
- before { group.add_developer(user) }
+ before do
+ group.add_developer(user)
+ end
it 'returns 403' do
delete :destroy, group_id: group, id: member
@@ -82,7 +92,9 @@ describe Groups::GroupMembersController do
end
context 'when user has enough rights' do
- before { group.add_owner(user) }
+ before do
+ group.add_owner(user)
+ end
it '[HTML] removes user from members' do
delete :destroy, group_id: group, id: member
@@ -103,7 +115,9 @@ describe Groups::GroupMembersController do
end
describe 'DELETE leave' do
- before { sign_in(user) }
+ before do
+ sign_in(user)
+ end
context 'when member is not found' do
it 'returns 404' do
@@ -115,7 +129,9 @@ describe Groups::GroupMembersController do
context 'when member is found' do
context 'and is not an owner' do
- before { group.add_developer(user) }
+ before do
+ group.add_developer(user)
+ end
it 'removes user from members' do
delete :leave, group_id: group
@@ -134,7 +150,9 @@ describe Groups::GroupMembersController do
end
context 'and is an owner' do
- before { group.add_owner(user) }
+ before do
+ group.add_owner(user)
+ end
it 'cannot removes himself from the group' do
delete :leave, group_id: group
@@ -144,7 +162,9 @@ describe Groups::GroupMembersController do
end
context 'and is a requester' do
- before { group.request_access(user) }
+ before do
+ group.request_access(user)
+ end
it 'removes user from members' do
delete :leave, group_id: group
@@ -159,7 +179,9 @@ describe Groups::GroupMembersController do
end
describe 'POST request_access' do
- before { sign_in(user) }
+ before do
+ sign_in(user)
+ end
it 'creates a new GroupMember that is not a team member' do
post :request_access, group_id: group
@@ -174,7 +196,9 @@ describe Groups::GroupMembersController do
describe 'POST approve_access_request' do
let(:member) { create(:group_member, :access_request, group: group) }
- before { sign_in(user) }
+ before do
+ sign_in(user)
+ end
context 'when member is not found' do
it 'returns 403' do
@@ -186,7 +210,9 @@ describe Groups::GroupMembersController do
context 'when member is found' do
context 'when user does not have enough rights' do
- before { group.add_developer(user) }
+ before do
+ group.add_developer(user)
+ end
it 'returns 403' do
post :approve_access_request, group_id: group, id: member
@@ -197,7 +223,9 @@ describe Groups::GroupMembersController do
end
context 'when user has enough rights' do
- before { group.add_owner(user) }
+ before do
+ group.add_owner(user)
+ end
it 'adds user to members' do
post :approve_access_request, group_id: group, id: member
diff --git a/spec/controllers/notification_settings_controller_spec.rb b/spec/controllers/notification_settings_controller_spec.rb
index 9e3a31e1a6b..cf136e72bac 100644
--- a/spec/controllers/notification_settings_controller_spec.rb
+++ b/spec/controllers/notification_settings_controller_spec.rb
@@ -94,7 +94,10 @@ describe NotificationSettingsController do
context 'not authorized' do
let(:private_project) { create(:empty_project, :private) }
- before { sign_in(user) }
+
+ before do
+ sign_in(user)
+ end
it 'returns 404' do
post :create,
@@ -120,7 +123,9 @@ describe NotificationSettingsController do
end
context 'when authorized' do
- before{ sign_in(user) }
+ before do
+ sign_in(user)
+ end
it 'returns success' do
put :update,
@@ -152,7 +157,9 @@ describe NotificationSettingsController do
context 'not authorized' do
let(:other_user) { create(:user) }
- before { sign_in(other_user) }
+ before do
+ sign_in(other_user)
+ end
it 'returns 404' do
put :update,
diff --git a/spec/controllers/profiles/personal_access_tokens_controller_spec.rb b/spec/controllers/profiles/personal_access_tokens_controller_spec.rb
index 98a43e278b2..ed08a4c1bf2 100644
--- a/spec/controllers/profiles/personal_access_tokens_controller_spec.rb
+++ b/spec/controllers/profiles/personal_access_tokens_controller_spec.rb
@@ -4,7 +4,9 @@ describe Profiles::PersonalAccessTokensController do
let(:user) { create(:user) }
let(:token_attributes) { attributes_for(:personal_access_token) }
- before { sign_in(user) }
+ before do
+ sign_in(user)
+ end
describe '#create' do
def created_token
@@ -38,7 +40,9 @@ describe Profiles::PersonalAccessTokensController do
let!(:inactive_personal_access_token) { create(:personal_access_token, :revoked, user: user) }
let!(:impersonation_personal_access_token) { create(:personal_access_token, :impersonation, user: user) }
- before { get :index }
+ before do
+ get :index
+ end
it "retrieves active personal access tokens" do
expect(assigns(:active_personal_access_tokens)).to include(active_personal_access_token)
diff --git a/spec/controllers/projects/commit_controller_spec.rb b/spec/controllers/projects/commit_controller_spec.rb
index 69e4706dc71..7fb08df1950 100644
--- a/spec/controllers/projects/commit_controller_spec.rb
+++ b/spec/controllers/projects/commit_controller_spec.rb
@@ -281,7 +281,9 @@ describe Projects::CommitController do
end
context 'when the path does not exist in the diff' do
- before { diff_for_path(id: commit.id, old_path: existing_path.succ, new_path: existing_path.succ) }
+ before do
+ diff_for_path(id: commit.id, old_path: existing_path.succ, new_path: existing_path.succ)
+ end
it 'returns a 404' do
expect(response).to have_http_status(404)
@@ -302,7 +304,9 @@ describe Projects::CommitController do
end
context 'when the commit does not exist' do
- before { diff_for_path(id: commit.id.succ, old_path: existing_path, new_path: existing_path) }
+ before do
+ diff_for_path(id: commit.id.succ, old_path: existing_path, new_path: existing_path)
+ end
it 'returns a 404' do
expect(response).to have_http_status(404)
diff --git a/spec/controllers/projects/compare_controller_spec.rb b/spec/controllers/projects/compare_controller_spec.rb
index 15ac4e0925a..8f4694c9854 100644
--- a/spec/controllers/projects/compare_controller_spec.rb
+++ b/spec/controllers/projects/compare_controller_spec.rb
@@ -128,7 +128,9 @@ describe Projects::CompareController do
end
context 'when the path does not exist in the diff' do
- before { diff_for_path(from: ref_from, to: ref_to, old_path: existing_path.succ, new_path: existing_path.succ) }
+ before do
+ diff_for_path(from: ref_from, to: ref_to, old_path: existing_path.succ, new_path: existing_path.succ)
+ end
it 'returns a 404' do
expect(response).to have_http_status(404)
@@ -149,7 +151,9 @@ describe Projects::CompareController do
end
context 'when the from ref does not exist' do
- before { diff_for_path(from: ref_from.succ, to: ref_to, old_path: existing_path, new_path: existing_path) }
+ before do
+ diff_for_path(from: ref_from.succ, to: ref_to, old_path: existing_path, new_path: existing_path)
+ end
it 'returns a 404' do
expect(response).to have_http_status(404)
@@ -157,7 +161,9 @@ describe Projects::CompareController do
end
context 'when the to ref does not exist' do
- before { diff_for_path(from: ref_from, to: ref_to.succ, old_path: existing_path, new_path: existing_path) }
+ before do
+ diff_for_path(from: ref_from, to: ref_to.succ, old_path: existing_path, new_path: existing_path)
+ end
it 'returns a 404' do
expect(response).to have_http_status(404)
diff --git a/spec/controllers/projects/forks_controller_spec.rb b/spec/controllers/projects/forks_controller_spec.rb
index 8282d79298f..dc8290c438e 100644
--- a/spec/controllers/projects/forks_controller_spec.rb
+++ b/spec/controllers/projects/forks_controller_spec.rb
@@ -14,7 +14,9 @@ describe Projects::ForksController do
end
context 'when fork is public' do
- before { forked_project.update_attribute(:visibility_level, Project::PUBLIC) }
+ before do
+ forked_project.update_attribute(:visibility_level, Project::PUBLIC)
+ end
it 'is visible for non logged in users' do
get_forks
@@ -35,7 +37,9 @@ describe Projects::ForksController do
end
context 'when user is logged in' do
- before { sign_in(project.creator) }
+ before do
+ sign_in(project.creator)
+ end
context 'when user is not a Project member neither a group member' do
it 'does not see the Project listed' do
@@ -46,7 +50,9 @@ describe Projects::ForksController do
end
context 'when user is a member of the Project' do
- before { forked_project.team << [project.creator, :developer] }
+ before do
+ forked_project.team << [project.creator, :developer]
+ end
it 'sees the project listed' do
get_forks
@@ -56,7 +62,9 @@ describe Projects::ForksController do
end
context 'when user is a member of the Group' do
- before { forked_project.group.add_developer(project.creator) }
+ before do
+ forked_project.group.add_developer(project.creator)
+ end
it 'sees the project listed' do
get_forks
diff --git a/spec/controllers/projects/group_links_controller_spec.rb b/spec/controllers/projects/group_links_controller_spec.rb
index ca4a8e871c0..b5435357f53 100644
--- a/spec/controllers/projects/group_links_controller_spec.rb
+++ b/spec/controllers/projects/group_links_controller_spec.rb
@@ -22,7 +22,10 @@ describe Projects::GroupLinksController do
end
context 'when user has access to group he want to link project to' do
- before { group.add_developer(user) }
+ before do
+ group.add_developer(user)
+ end
+
include_context 'link project to group'
it 'links project with selected group' do
diff --git a/spec/controllers/projects/issues_controller_spec.rb b/spec/controllers/projects/issues_controller_spec.rb
index b65e9e0dfc0..f853bfe370c 100644
--- a/spec/controllers/projects/issues_controller_spec.rb
+++ b/spec/controllers/projects/issues_controller_spec.rb
@@ -212,7 +212,9 @@ describe Projects::IssuesController do
let(:another_project) { create(:empty_project, :private) }
context 'when user has access to move issue' do
- before { another_project.team << [user, :reporter] }
+ before do
+ another_project.team << [user, :reporter]
+ end
it 'moves issue to another project' do
move_issue
@@ -250,14 +252,18 @@ describe Projects::IssuesController do
end
context 'when an issue is identified as spam' do
- before { allow_any_instance_of(AkismetService).to receive(:is_spam?).and_return(true) }
+ before do
+ allow_any_instance_of(AkismetService).to receive(:is_spam?).and_return(true)
+ end
context 'when captcha is not verified' do
def update_spam_issue
update_issue(title: 'Spam Title', description: 'Spam lives here')
end
- before { allow_any_instance_of(described_class).to receive(:verify_recaptcha).and_return(false) }
+ before do
+ allow_any_instance_of(described_class).to receive(:verify_recaptcha).and_return(false)
+ end
it 'rejects an issue recognized as a spam' do
expect(Gitlab::Recaptcha).to receive(:load_configurations!).and_return(true)
@@ -620,14 +626,18 @@ describe Projects::IssuesController do
end
context 'when an issue is identified as spam' do
- before { allow_any_instance_of(AkismetService).to receive(:is_spam?).and_return(true) }
+ before do
+ allow_any_instance_of(AkismetService).to receive(:is_spam?).and_return(true)
+ end
context 'when captcha is not verified' do
def post_spam_issue
post_new_issue(title: 'Spam Title', description: 'Spam lives here')
end
- before { allow_any_instance_of(described_class).to receive(:verify_recaptcha).and_return(false) }
+ before do
+ allow_any_instance_of(described_class).to receive(:verify_recaptcha).and_return(false)
+ end
it 'rejects an issue recognized as a spam' do
expect { post_spam_issue }.not_to change(Issue, :count)
@@ -739,7 +749,10 @@ describe Projects::IssuesController do
describe "DELETE #destroy" do
context "when the user is a developer" do
- before { sign_in(user) }
+ before do
+ sign_in(user)
+ end
+
it "rejects a developer to destroy an issue" do
delete :destroy, namespace_id: project.namespace, project_id: project, id: issue.iid
expect(response).to have_http_status(404)
@@ -751,7 +764,9 @@ describe Projects::IssuesController do
let(:namespace) { create(:namespace, owner: owner) }
let(:project) { create(:empty_project, namespace: namespace) }
- before { sign_in(owner) }
+ before do
+ sign_in(owner)
+ end
it "deletes the issue" do
delete :destroy, namespace_id: project.namespace, project_id: project, id: issue.iid
diff --git a/spec/controllers/projects/jobs_controller_spec.rb b/spec/controllers/projects/jobs_controller_spec.rb
index 4a737587899..472e5fc51a0 100644
--- a/spec/controllers/projects/jobs_controller_spec.rb
+++ b/spec/controllers/projects/jobs_controller_spec.rb
@@ -28,7 +28,7 @@ describe Projects::JobsController do
get_index(scope: 'running')
end
- it 'has only running builds' do
+ it 'has only running jobs' do
expect(response).to have_http_status(:ok)
expect(assigns(:builds).first.status).to eq('running')
end
@@ -41,7 +41,7 @@ describe Projects::JobsController do
get_index(scope: 'finished')
end
- it 'has only finished builds' do
+ it 'has only finished jobs' do
expect(response).to have_http_status(:ok)
expect(assigns(:builds).first.status).to eq('success')
end
@@ -67,7 +67,7 @@ describe Projects::JobsController do
context 'number of queries' do
before do
Ci::Build::AVAILABLE_STATUSES.each do |status|
- create_build(status, status)
+ create_job(status, status)
end
end
@@ -76,7 +76,7 @@ describe Projects::JobsController do
expect(recorded.count).to be_within(5).of(7)
end
- def create_build(name, status)
+ def create_job(name, status)
pipeline = create(:ci_pipeline, project: project)
create(:ci_build, :tags, :triggered, :artifacts,
pipeline: pipeline, name: name, status: status)
@@ -94,21 +94,21 @@ describe Projects::JobsController do
end
describe 'GET show' do
- let!(:build) { create(:ci_build, :failed, pipeline: pipeline) }
+ let!(:job) { create(:ci_build, :failed, pipeline: pipeline) }
context 'when requesting HTML' do
- context 'when build exists' do
+ context 'when job exists' do
before do
- get_show(id: build.id)
+ get_show(id: job.id)
end
- it 'has a build' do
+ it 'has a job' do
expect(response).to have_http_status(:ok)
- expect(assigns(:build).id).to eq(build.id)
+ expect(assigns(:build).id).to eq(job.id)
end
end
- context 'when build does not exist' do
+ context 'when job does not exist' do
before do
get_show(id: 1234)
end
@@ -128,12 +128,12 @@ describe Projects::JobsController do
allow_any_instance_of(Ci::Build).to receive(:merge_request).and_return(merge_request)
- get_show(id: build.id, format: :json)
+ get_show(id: job.id, format: :json)
end
it 'exposes needed information' do
expect(response).to have_http_status(:ok)
- expect(json_response['raw_path']).to match(/builds\/\d+\/raw\z/)
+ expect(json_response['raw_path']).to match(/jobs\/\d+\/raw\z/)
expect(json_response.dig('merge_request', 'path')).to match(/merge_requests\/\d+\z/)
expect(json_response['new_issue_path'])
.to include('/issues/new')
@@ -155,35 +155,35 @@ describe Projects::JobsController do
get_trace
end
- context 'when build has a trace' do
- let(:build) { create(:ci_build, :trace, pipeline: pipeline) }
+ context 'when job has a trace' do
+ let(:job) { create(:ci_build, :trace, pipeline: pipeline) }
it 'returns a trace' do
expect(response).to have_http_status(:ok)
- expect(json_response['id']).to eq build.id
- expect(json_response['status']).to eq build.status
+ expect(json_response['id']).to eq job.id
+ expect(json_response['status']).to eq job.status
expect(json_response['html']).to eq('BUILD TRACE')
end
end
- context 'when build has no traces' do
- let(:build) { create(:ci_build, pipeline: pipeline) }
+ context 'when job has no traces' do
+ let(:job) { create(:ci_build, pipeline: pipeline) }
it 'returns no traces' do
expect(response).to have_http_status(:ok)
- expect(json_response['id']).to eq build.id
- expect(json_response['status']).to eq build.status
+ expect(json_response['id']).to eq job.id
+ expect(json_response['status']).to eq job.status
expect(json_response['html']).to be_nil
end
end
- context 'when build has a trace with ANSI sequence and Unicode' do
- let(:build) { create(:ci_build, :unicode_trace, pipeline: pipeline) }
+ context 'when job has a trace with ANSI sequence and Unicode' do
+ let(:job) { create(:ci_build, :unicode_trace, pipeline: pipeline) }
it 'returns a trace with Unicode' do
expect(response).to have_http_status(:ok)
- expect(json_response['id']).to eq build.id
- expect(json_response['status']).to eq build.status
+ expect(json_response['id']).to eq job.id
+ expect(json_response['status']).to eq job.status
expect(json_response['html']).to include("ヾ(´༎ຶД༎ຶ`)ノ")
end
end
@@ -191,23 +191,23 @@ describe Projects::JobsController do
def get_trace
get :trace, namespace_id: project.namespace,
project_id: project,
- id: build.id,
+ id: job.id,
format: :json
end
end
describe 'GET status.json' do
- let(:build) { create(:ci_build, pipeline: pipeline) }
- let(:status) { build.detailed_status(double('user')) }
+ let(:job) { create(:ci_build, pipeline: pipeline) }
+ let(:status) { job.detailed_status(double('user')) }
before do
get :status, namespace_id: project.namespace,
project_id: project,
- id: build.id,
+ id: job.id,
format: :json
end
- it 'return a detailed build status in json' do
+ it 'return a detailed job status in json' do
expect(response).to have_http_status(:ok)
expect(json_response['text']).to eq status.text
expect(json_response['label']).to eq status.label
@@ -224,17 +224,17 @@ describe Projects::JobsController do
post_retry
end
- context 'when build is retryable' do
- let(:build) { create(:ci_build, :retryable, pipeline: pipeline) }
+ context 'when job is retryable' do
+ let(:job) { create(:ci_build, :retryable, pipeline: pipeline) }
- it 'redirects to the retried build page' do
+ it 'redirects to the retried job page' do
expect(response).to have_http_status(:found)
expect(response).to redirect_to(namespace_project_job_path(id: Ci::Build.last.id))
end
end
- context 'when build is not retryable' do
- let(:build) { create(:ci_build, pipeline: pipeline) }
+ context 'when job is not retryable' do
+ let(:job) { create(:ci_build, pipeline: pipeline) }
it 'renders unprocessable_entity' do
expect(response).to have_http_status(:unprocessable_entity)
@@ -244,7 +244,7 @@ describe Projects::JobsController do
def post_retry
post :retry, namespace_id: project.namespace,
project_id: project,
- id: build.id
+ id: job.id
end
end
@@ -260,21 +260,21 @@ describe Projects::JobsController do
post_play
end
- context 'when build is playable' do
- let(:build) { create(:ci_build, :playable, pipeline: pipeline) }
+ context 'when job is playable' do
+ let(:job) { create(:ci_build, :playable, pipeline: pipeline) }
- it 'redirects to the played build page' do
+ it 'redirects to the played job page' do
expect(response).to have_http_status(:found)
- expect(response).to redirect_to(namespace_project_job_path(id: build.id))
+ expect(response).to redirect_to(namespace_project_job_path(id: job.id))
end
it 'transits to pending' do
- expect(build.reload).to be_pending
+ expect(job.reload).to be_pending
end
end
- context 'when build is not playable' do
- let(:build) { create(:ci_build, pipeline: pipeline) }
+ context 'when job is not playable' do
+ let(:job) { create(:ci_build, pipeline: pipeline) }
it 'renders unprocessable_entity' do
expect(response).to have_http_status(:unprocessable_entity)
@@ -284,7 +284,7 @@ describe Projects::JobsController do
def post_play
post :play, namespace_id: project.namespace,
project_id: project,
- id: build.id
+ id: job.id
end
end
@@ -296,21 +296,21 @@ describe Projects::JobsController do
post_cancel
end
- context 'when build is cancelable' do
- let(:build) { create(:ci_build, :cancelable, pipeline: pipeline) }
+ context 'when job is cancelable' do
+ let(:job) { create(:ci_build, :cancelable, pipeline: pipeline) }
- it 'redirects to the canceled build page' do
+ it 'redirects to the canceled job page' do
expect(response).to have_http_status(:found)
- expect(response).to redirect_to(namespace_project_job_path(id: build.id))
+ expect(response).to redirect_to(namespace_project_job_path(id: job.id))
end
it 'transits to canceled' do
- expect(build.reload).to be_canceled
+ expect(job.reload).to be_canceled
end
end
- context 'when build is not cancelable' do
- let(:build) { create(:ci_build, :canceled, pipeline: pipeline) }
+ context 'when job is not cancelable' do
+ let(:job) { create(:ci_build, :canceled, pipeline: pipeline) }
it 'returns unprocessable_entity' do
expect(response).to have_http_status(:unprocessable_entity)
@@ -320,7 +320,7 @@ describe Projects::JobsController do
def post_cancel
post :cancel, namespace_id: project.namespace,
project_id: project,
- id: build.id
+ id: job.id
end
end
@@ -330,7 +330,7 @@ describe Projects::JobsController do
sign_in(user)
end
- context 'when builds are cancelable' do
+ context 'when jobs are cancelable' do
before do
create_list(:ci_build, 2, :cancelable, pipeline: pipeline)
@@ -347,7 +347,7 @@ describe Projects::JobsController do
end
end
- context 'when builds are not cancelable' do
+ context 'when jobs are not cancelable' do
before do
create_list(:ci_build, 2, :canceled, pipeline: pipeline)
@@ -374,26 +374,26 @@ describe Projects::JobsController do
post_erase
end
- context 'when build is erasable' do
- let(:build) { create(:ci_build, :erasable, :trace, pipeline: pipeline) }
+ context 'when job is erasable' do
+ let(:job) { create(:ci_build, :erasable, :trace, pipeline: pipeline) }
- it 'redirects to the erased build page' do
+ it 'redirects to the erased job page' do
expect(response).to have_http_status(:found)
- expect(response).to redirect_to(namespace_project_job_path(id: build.id))
+ expect(response).to redirect_to(namespace_project_job_path(id: job.id))
end
it 'erases artifacts' do
- expect(build.artifacts_file.exists?).to be_falsey
- expect(build.artifacts_metadata.exists?).to be_falsey
+ expect(job.artifacts_file.exists?).to be_falsey
+ expect(job.artifacts_metadata.exists?).to be_falsey
end
it 'erases trace' do
- expect(build.trace.exist?).to be_falsey
+ expect(job.trace.exist?).to be_falsey
end
end
- context 'when build is not erasable' do
- let(:build) { create(:ci_build, :erased, pipeline: pipeline) }
+ context 'when job is not erasable' do
+ let(:job) { create(:ci_build, :erased, pipeline: pipeline) }
it 'returns unprocessable_entity' do
expect(response).to have_http_status(:unprocessable_entity)
@@ -403,7 +403,7 @@ describe Projects::JobsController do
def post_erase
post :erase, namespace_id: project.namespace,
project_id: project,
- id: build.id
+ id: job.id
end
end
@@ -412,8 +412,8 @@ describe Projects::JobsController do
get_raw
end
- context 'when build has a trace file' do
- let(:build) { create(:ci_build, :trace, pipeline: pipeline) }
+ context 'when job has a trace file' do
+ let(:job) { create(:ci_build, :trace, pipeline: pipeline) }
it 'send a trace file' do
expect(response).to have_http_status(:ok)
@@ -422,8 +422,8 @@ describe Projects::JobsController do
end
end
- context 'when build does not have a trace file' do
- let(:build) { create(:ci_build, pipeline: pipeline) }
+ context 'when job does not have a trace file' do
+ let(:job) { create(:ci_build, pipeline: pipeline) }
it 'returns not_found' do
expect(response).to have_http_status(:not_found)
@@ -433,7 +433,7 @@ describe Projects::JobsController do
def get_raw
post :raw, namespace_id: project.namespace,
project_id: project,
- id: build.id
+ id: job.id
end
end
end
diff --git a/spec/controllers/projects/merge_requests_controller_spec.rb b/spec/controllers/projects/merge_requests_controller_spec.rb
index 6e1c91738db..d8a3a510f97 100644
--- a/spec/controllers/projects/merge_requests_controller_spec.rb
+++ b/spec/controllers/projects/merge_requests_controller_spec.rb
@@ -19,7 +19,10 @@ describe Projects::MergeRequestsController do
render_views
let(:fork_project) { create(:forked_project_with_submodules) }
- before { fork_project.team << [user, :master] }
+
+ before do
+ fork_project.team << [user, :master]
+ end
context 'when rendering HTML response' do
it 'renders new merge request widget template' do
@@ -328,7 +331,9 @@ describe Projects::MergeRequestsController do
end
context 'when the sha parameter does not match the source SHA' do
- before { post :merge, base_params.merge(sha: 'foo') }
+ before do
+ post :merge, base_params.merge(sha: 'foo')
+ end
it 'returns :sha_mismatch' do
expect(json_response).to eq('status' => 'sha_mismatch')
@@ -473,7 +478,9 @@ describe Projects::MergeRequestsController do
let(:namespace) { create(:namespace, owner: owner) }
let(:project) { create(:project, namespace: namespace) }
- before { sign_in owner }
+ before do
+ sign_in owner
+ end
it "deletes the merge request" do
delete :destroy, namespace_id: project.namespace, project_id: project, id: merge_request.iid
@@ -505,7 +512,9 @@ describe Projects::MergeRequestsController do
context 'with default params' do
context 'as html' do
- before { go(format: 'html') }
+ before do
+ go(format: 'html')
+ end
it 'renders the diff template' do
expect(response).to render_template('diffs')
@@ -513,7 +522,9 @@ describe Projects::MergeRequestsController do
end
context 'as json' do
- before { go(format: 'json') }
+ before do
+ go(format: 'json')
+ end
it 'renders the diffs template to a string' do
expect(response).to render_template('projects/merge_requests/show/_diffs')
@@ -544,7 +555,9 @@ describe Projects::MergeRequestsController do
context 'with ignore_whitespace_change' do
context 'as html' do
- before { go(format: 'html', w: 1) }
+ before do
+ go(format: 'html', w: 1)
+ end
it 'renders the diff template' do
expect(response).to render_template('diffs')
@@ -552,7 +565,9 @@ describe Projects::MergeRequestsController do
end
context 'as json' do
- before { go(format: 'json', w: 1) }
+ before do
+ go(format: 'json', w: 1)
+ end
it 'renders the diffs template to a string' do
expect(response).to render_template('projects/merge_requests/show/_diffs')
@@ -562,7 +577,9 @@ describe Projects::MergeRequestsController do
end
context 'with view' do
- before { go(view: 'parallel') }
+ before do
+ go(view: 'parallel')
+ end
it 'saves the preferred diff view in a cookie' do
expect(response.cookies['diff_view']).to eq('parallel')
@@ -605,7 +622,9 @@ describe Projects::MergeRequestsController do
end
context 'when the path does not exist in the diff' do
- before { diff_for_path(id: merge_request.iid, old_path: 'files/ruby/nopen.rb', new_path: 'files/ruby/nopen.rb') }
+ before do
+ diff_for_path(id: merge_request.iid, old_path: 'files/ruby/nopen.rb', new_path: 'files/ruby/nopen.rb')
+ end
it 'returns a 404' do
expect(response).to have_http_status(404)
@@ -626,7 +645,9 @@ describe Projects::MergeRequestsController do
end
context 'when the merge request does not exist' do
- before { diff_for_path(id: merge_request.iid.succ, old_path: existing_path, new_path: existing_path) }
+ before do
+ diff_for_path(id: merge_request.iid.succ, old_path: existing_path, new_path: existing_path)
+ end
it 'returns a 404' do
expect(response).to have_http_status(404)
@@ -670,7 +691,9 @@ describe Projects::MergeRequestsController do
context 'when the source branch is in a different project to the target' do
let(:other_project) { create(:project) }
- before { other_project.team << [user, :master] }
+ before do
+ other_project.team << [user, :master]
+ end
context 'when the path exists in the diff' do
it 'disables diff notes' do
@@ -690,7 +713,9 @@ describe Projects::MergeRequestsController do
end
context 'when the path does not exist in the diff' do
- before { diff_for_path(old_path: 'files/ruby/nopen.rb', new_path: 'files/ruby/nopen.rb', merge_request: { source_project: other_project, source_branch: 'feature', target_branch: 'master' }) }
+ before do
+ diff_for_path(old_path: 'files/ruby/nopen.rb', new_path: 'files/ruby/nopen.rb', merge_request: { source_project: other_project, source_branch: 'feature', target_branch: 'master' })
+ end
it 'returns a 404' do
expect(response).to have_http_status(404)
@@ -913,7 +938,9 @@ describe Projects::MergeRequestsController do
end
context 'when the file does not exist cannot be resolved in the UI' do
- before { conflict_for_path('files/ruby/regexp.rb') }
+ before do
+ conflict_for_path('files/ruby/regexp.rb')
+ end
it 'returns a 404 status code' do
expect(response).to have_http_status(:not_found)
@@ -923,7 +950,9 @@ describe Projects::MergeRequestsController do
context 'with an existing file' do
let(:path) { 'files/ruby/regex.rb' }
- before { conflict_for_path(path) }
+ before do
+ conflict_for_path(path)
+ end
it 'returns a 200 status code' do
expect(response).to have_http_status(:ok)
@@ -1195,7 +1224,9 @@ describe Projects::MergeRequestsController do
end
context 'when head_pipeline does not exist' do
- before { get_pipeline_status }
+ before do
+ get_pipeline_status
+ end
it 'return empty' do
expect(response).to have_http_status(:ok)
diff --git a/spec/controllers/projects/project_members_controller_spec.rb b/spec/controllers/projects/project_members_controller_spec.rb
index 2294d5df581..f2b59ba82ca 100644
--- a/spec/controllers/projects/project_members_controller_spec.rb
+++ b/spec/controllers/projects/project_members_controller_spec.rb
@@ -16,10 +16,14 @@ describe Projects::ProjectMembersController do
describe 'POST create' do
let(:project_user) { create(:user) }
- before { sign_in(user) }
+ before do
+ sign_in(user)
+ end
context 'when user does not have enough rights' do
- before { project.team << [user, :developer] }
+ before do
+ project.team << [user, :developer]
+ end
it 'returns 404' do
post :create, namespace_id: project.namespace,
@@ -33,7 +37,9 @@ describe Projects::ProjectMembersController do
end
context 'when user has enough rights' do
- before { project.team << [user, :master] }
+ before do
+ project.team << [user, :master]
+ end
it 'adds user to members' do
expect_any_instance_of(Members::CreateService).to receive(:execute).and_return(status: :success)
@@ -64,7 +70,9 @@ describe Projects::ProjectMembersController do
describe 'DELETE destroy' do
let(:member) { create(:project_member, :developer, project: project) }
- before { sign_in(user) }
+ before do
+ sign_in(user)
+ end
context 'when member is not found' do
it 'returns 404' do
@@ -78,7 +86,9 @@ describe Projects::ProjectMembersController do
context 'when member is found' do
context 'when user does not have enough rights' do
- before { project.team << [user, :developer] }
+ before do
+ project.team << [user, :developer]
+ end
it 'returns 404' do
delete :destroy, namespace_id: project.namespace,
@@ -91,7 +101,9 @@ describe Projects::ProjectMembersController do
end
context 'when user has enough rights' do
- before { project.team << [user, :master] }
+ before do
+ project.team << [user, :master]
+ end
it '[HTML] removes user from members' do
delete :destroy, namespace_id: project.namespace,
@@ -117,7 +129,9 @@ describe Projects::ProjectMembersController do
end
describe 'DELETE leave' do
- before { sign_in(user) }
+ before do
+ sign_in(user)
+ end
context 'when member is not found' do
it 'returns 404' do
@@ -130,7 +144,9 @@ describe Projects::ProjectMembersController do
context 'when member is found' do
context 'and is not an owner' do
- before { project.team << [user, :developer] }
+ before do
+ project.team << [user, :developer]
+ end
it 'removes user from members' do
delete :leave, namespace_id: project.namespace,
@@ -145,7 +161,9 @@ describe Projects::ProjectMembersController do
context 'and is an owner' do
let(:project) { create(:empty_project, namespace: user.namespace) }
- before { project.team << [user, :master] }
+ before do
+ project.team << [user, :master]
+ end
it 'cannot remove himself from the project' do
delete :leave, namespace_id: project.namespace,
@@ -156,7 +174,9 @@ describe Projects::ProjectMembersController do
end
context 'and is a requester' do
- before { project.request_access(user) }
+ before do
+ project.request_access(user)
+ end
it 'removes user from members' do
delete :leave, namespace_id: project.namespace,
@@ -172,7 +192,9 @@ describe Projects::ProjectMembersController do
end
describe 'POST request_access' do
- before { sign_in(user) }
+ before do
+ sign_in(user)
+ end
it 'creates a new ProjectMember that is not a team member' do
post :request_access, namespace_id: project.namespace,
@@ -190,7 +212,9 @@ describe Projects::ProjectMembersController do
describe 'POST approve' do
let(:member) { create(:project_member, :access_request, project: project) }
- before { sign_in(user) }
+ before do
+ sign_in(user)
+ end
context 'when member is not found' do
it 'returns 404' do
@@ -204,7 +228,9 @@ describe Projects::ProjectMembersController do
context 'when member is found' do
context 'when user does not have enough rights' do
- before { project.team << [user, :developer] }
+ before do
+ project.team << [user, :developer]
+ end
it 'returns 404' do
post :approve_access_request, namespace_id: project.namespace,
@@ -217,7 +243,9 @@ describe Projects::ProjectMembersController do
end
context 'when user has enough rights' do
- before { project.team << [user, :master] }
+ before do
+ project.team << [user, :master]
+ end
it 'adds user to members' do
post :approve_access_request, namespace_id: project.namespace,
@@ -252,7 +280,10 @@ describe Projects::ProjectMembersController do
end
context 'when user can access source project members' do
- before { another_project.team << [user, :guest] }
+ before do
+ another_project.team << [user, :guest]
+ end
+
include_context 'import applied'
it 'imports source project members' do
diff --git a/spec/controllers/projects/snippets_controller_spec.rb b/spec/controllers/projects/snippets_controller_spec.rb
index 8c23c46798e..2434f822c6f 100644
--- a/spec/controllers/projects/snippets_controller_spec.rb
+++ b/spec/controllers/projects/snippets_controller_spec.rb
@@ -46,7 +46,9 @@ describe Projects::SnippetsController do
end
context 'when signed in as the author' do
- before { sign_in(user) }
+ before do
+ sign_in(user)
+ end
it 'renders the snippet' do
get :index, namespace_id: project.namespace, project_id: project
@@ -57,7 +59,9 @@ describe Projects::SnippetsController do
end
context 'when signed in as a project member' do
- before { sign_in(user2) }
+ before do
+ sign_in(user2)
+ end
it 'renders the snippet' do
get :index, namespace_id: project.namespace, project_id: project
@@ -317,7 +321,9 @@ describe Projects::SnippetsController do
end
context 'when signed in as the author' do
- before { sign_in(user) }
+ before do
+ sign_in(user)
+ end
it 'renders the snippet' do
get action, namespace_id: project.namespace, project_id: project, id: project_snippet.to_param
@@ -328,7 +334,9 @@ describe Projects::SnippetsController do
end
context 'when signed in as a project member' do
- before { sign_in(user2) }
+ before do
+ sign_in(user2)
+ end
it 'renders the snippet' do
get action, namespace_id: project.namespace, project_id: project, id: project_snippet.to_param
@@ -349,7 +357,9 @@ describe Projects::SnippetsController do
end
context 'when signed in' do
- before { sign_in(user) }
+ before do
+ sign_in(user)
+ end
it 'responds with status 404' do
get action, namespace_id: project.namespace, project_id: project, id: 42
diff --git a/spec/controllers/projects/tags_controller_spec.rb b/spec/controllers/projects/tags_controller_spec.rb
index fc97bac64cd..c48f41ca12e 100644
--- a/spec/controllers/projects/tags_controller_spec.rb
+++ b/spec/controllers/projects/tags_controller_spec.rb
@@ -6,7 +6,9 @@ describe Projects::TagsController do
let!(:invalid_release) { create(:release, project: project, tag: 'does-not-exist') }
describe 'GET index' do
- before { get :index, namespace_id: project.namespace.to_param, project_id: project }
+ before do
+ get :index, namespace_id: project.namespace.to_param, project_id: project
+ end
it 'returns the tags for the page' do
expect(assigns(:tags).map(&:name)).to eq(['v1.1.0', 'v1.0.0'])
@@ -19,7 +21,9 @@ describe Projects::TagsController do
end
describe 'GET show' do
- before { get :show, namespace_id: project.namespace.to_param, project_id: project, id: id }
+ before do
+ get :show, namespace_id: project.namespace.to_param, project_id: project, id: id
+ end
context "valid tag" do
let(:id) { 'v1.0.0' }
diff --git a/spec/controllers/projects_controller_spec.rb b/spec/controllers/projects_controller_spec.rb
index 4f6fc6691be..240a81367d0 100644
--- a/spec/controllers/projects_controller_spec.rb
+++ b/spec/controllers/projects_controller_spec.rb
@@ -29,7 +29,9 @@ describe ProjectsController do
describe "GET show" do
context "user not project member" do
- before { sign_in(user) }
+ before do
+ sign_in(user)
+ end
context "user does not have access to project" do
let(:private_project) { create(:empty_project, :private) }
@@ -108,7 +110,9 @@ describe ProjectsController do
context "project with empty repo" do
let(:empty_project) { create(:project_empty_repo, :public) }
- before { sign_in(user) }
+ before do
+ sign_in(user)
+ end
User.project_views.keys.each do |project_view|
context "with #{project_view} view set" do
@@ -128,7 +132,9 @@ describe ProjectsController do
context "project with broken repo" do
let(:empty_project) { create(:project_broken_repo, :public) }
- before { sign_in(user) }
+ before do
+ sign_in(user)
+ end
User.project_views.keys.each do |project_view|
context "with #{project_view} view set" do
diff --git a/spec/controllers/search_controller_spec.rb b/spec/controllers/search_controller_spec.rb
index 3173aae664c..a3708ad0908 100644
--- a/spec/controllers/search_controller_spec.rb
+++ b/spec/controllers/search_controller_spec.rb
@@ -18,7 +18,9 @@ describe SearchController do
context 'on restricted projects' do
context 'when signed out' do
- before { sign_out(user) }
+ before do
+ sign_out(user)
+ end
it "doesn't expose comments on issues" do
project = create(:empty_project, :public, :issues_private)
diff --git a/spec/controllers/sent_notifications_controller_spec.rb b/spec/controllers/sent_notifications_controller_spec.rb
index 954fc2eaf21..0cc8a3b68eb 100644
--- a/spec/controllers/sent_notifications_controller_spec.rb
+++ b/spec/controllers/sent_notifications_controller_spec.rb
@@ -14,7 +14,9 @@ describe SentNotificationsController, type: :controller do
describe 'GET unsubscribe' do
context 'when the user is not logged in' do
context 'when the force param is passed' do
- before { get(:unsubscribe, id: sent_notification.reply_key, force: true) }
+ before do
+ get(:unsubscribe, id: sent_notification.reply_key, force: true)
+ end
it 'unsubscribes the user' do
expect(issue.subscribed?(user, project)).to be_falsey
@@ -30,7 +32,9 @@ describe SentNotificationsController, type: :controller do
end
context 'when the force param is not passed' do
- before { get(:unsubscribe, id: sent_notification.reply_key) }
+ before do
+ get(:unsubscribe, id: sent_notification.reply_key)
+ end
it 'does not unsubscribe the user' do
expect(issue.subscribed?(user, project)).to be_truthy
@@ -47,10 +51,14 @@ describe SentNotificationsController, type: :controller do
end
context 'when the user is logged in' do
- before { sign_in(user) }
+ before do
+ sign_in(user)
+ end
context 'when the ID passed does not exist' do
- before { get(:unsubscribe, id: sent_notification.reply_key.reverse) }
+ before do
+ get(:unsubscribe, id: sent_notification.reply_key.reverse)
+ end
it 'does not unsubscribe the user' do
expect(issue.subscribed?(user, project)).to be_truthy
@@ -66,7 +74,9 @@ describe SentNotificationsController, type: :controller do
end
context 'when the force param is passed' do
- before { get(:unsubscribe, id: sent_notification.reply_key, force: true) }
+ before do
+ get(:unsubscribe, id: sent_notification.reply_key, force: true)
+ end
it 'unsubscribes the user' do
expect(issue.subscribed?(user, project)).to be_falsey
@@ -89,7 +99,10 @@ describe SentNotificationsController, type: :controller do
end
end
let(:sent_notification) { create(:sent_notification, project: project, noteable: merge_request, recipient: user) }
- before { get(:unsubscribe, id: sent_notification.reply_key) }
+
+ before do
+ get(:unsubscribe, id: sent_notification.reply_key)
+ end
it 'unsubscribes the user' do
expect(merge_request.subscribed?(user, project)).to be_falsey
diff --git a/spec/controllers/sessions_controller_spec.rb b/spec/controllers/sessions_controller_spec.rb
index e87e24a33a1..03f4b0ba343 100644
--- a/spec/controllers/sessions_controller_spec.rb
+++ b/spec/controllers/sessions_controller_spec.rb
@@ -142,7 +142,9 @@ describe SessionsController do
end
context 'when OTP is invalid' do
- before { authenticate_2fa(otp_attempt: 'invalid') }
+ before do
+ authenticate_2fa(otp_attempt: 'invalid')
+ end
it 'does not authenticate' do
expect(subject.current_user).not_to eq user
@@ -169,7 +171,9 @@ describe SessionsController do
end
context 'when OTP is invalid' do
- before { authenticate_2fa(otp_attempt: 'invalid') }
+ before do
+ authenticate_2fa(otp_attempt: 'invalid')
+ end
it 'does not authenticate' do
expect(subject.current_user).not_to eq user
diff --git a/spec/controllers/snippets_controller_spec.rb b/spec/controllers/snippets_controller_spec.rb
index 9073c39f562..b1339b2a185 100644
--- a/spec/controllers/snippets_controller_spec.rb
+++ b/spec/controllers/snippets_controller_spec.rb
@@ -437,7 +437,9 @@ describe SnippetsController do
end
context 'when signed in user is the author' do
- before { get :raw, id: personal_snippet.to_param }
+ before do
+ get :raw, id: personal_snippet.to_param
+ end
it 'responds with status 200' do
expect(assigns(:snippet)).to eq(personal_snippet)
diff --git a/spec/controllers/users_controller_spec.rb b/spec/controllers/users_controller_spec.rb
index d33e2ba1e53..842d82cdbe9 100644
--- a/spec/controllers/users_controller_spec.rb
+++ b/spec/controllers/users_controller_spec.rb
@@ -43,7 +43,9 @@ describe UsersController do
end
context 'when logged in' do
- before { sign_in(user) }
+ before do
+ sign_in(user)
+ end
it 'renders show' do
get :show, username: user.username
@@ -62,7 +64,9 @@ describe UsersController do
end
context 'when logged in' do
- before { sign_in(user) }
+ before do
+ sign_in(user)
+ end
it 'renders 404' do
get :show, username: 'nonexistent'
diff --git a/spec/features/admin/admin_runners_spec.rb b/spec/features/admin/admin_runners_spec.rb
index 5dcc7d35d82..bc11b090fdb 100644
--- a/spec/features/admin/admin_runners_spec.rb
+++ b/spec/features/admin/admin_runners_spec.rb
@@ -134,7 +134,10 @@ describe "Admin Runners" do
describe 'runners registration token' do
let!(:token) { current_application_settings.runners_registration_token }
- before { visit admin_runners_path }
+
+ before do
+ visit admin_runners_path
+ end
it 'has a registration token' do
expect(page).to have_content("Registration token is #{token}")
diff --git a/spec/features/admin/admin_settings_spec.rb b/spec/features/admin/admin_settings_spec.rb
index 5099441dce2..27bc25be580 100644
--- a/spec/features/admin/admin_settings_spec.rb
+++ b/spec/features/admin/admin_settings_spec.rb
@@ -20,10 +20,15 @@ feature 'Admin updates settings', feature: true do
uncheck 'Gravatar enabled'
fill_in 'Home page URL', with: 'https://about.gitlab.com/'
fill_in 'Help page text', with: 'Example text'
+ check 'Hide marketing-related entries from help'
+ fill_in 'Support page URL', with: 'http://example.com/help'
click_button 'Save'
expect(current_application_settings.gravatar_enabled).to be_falsey
expect(current_application_settings.home_page_url).to eq "https://about.gitlab.com/"
+ expect(current_application_settings.help_page_text).to eq "Example text"
+ expect(current_application_settings.help_page_hide_commercial_content).to be_truthy
+ expect(current_application_settings.help_page_support_url).to eq "http://example.com/help"
expect(page).to have_content "Application settings saved successfully"
end
diff --git a/spec/features/admin/admin_users_impersonation_tokens_spec.rb b/spec/features/admin/admin_users_impersonation_tokens_spec.rb
index 0fb4baeb71c..849ec829f75 100644
--- a/spec/features/admin/admin_users_impersonation_tokens_spec.rb
+++ b/spec/features/admin/admin_users_impersonation_tokens_spec.rb
@@ -12,7 +12,9 @@ describe 'Admin > Users > Impersonation Tokens', feature: true, js: true do
find(".table.inactive-tokens")
end
- before { login_as(admin) }
+ before do
+ login_as(admin)
+ end
describe "token creation" do
it "allows creation of a token" do
diff --git a/spec/features/admin/admin_users_spec.rb b/spec/features/admin/admin_users_spec.rb
index 301a47169a4..f72651667ee 100644
--- a/spec/features/admin/admin_users_spec.rb
+++ b/spec/features/admin/admin_users_spec.rb
@@ -124,7 +124,10 @@ describe "Admin::Users", feature: true do
describe 'Impersonation' do
let(:another_user) { create(:user) }
- before { visit admin_user_path(another_user) }
+
+ before do
+ visit admin_user_path(another_user)
+ end
context 'before impersonating' do
it 'shows impersonate button for other users' do
@@ -149,7 +152,9 @@ describe "Admin::Users", feature: true do
end
context 'when impersonating' do
- before { click_link 'Impersonate' }
+ before do
+ click_link 'Impersonate'
+ end
it 'logs in as the user when impersonate is clicked' do
expect(page.find(:css, '.header-user .profile-link')['data-user']).to eql(another_user.username)
diff --git a/spec/features/dashboard/merge_requests_spec.rb b/spec/features/dashboard/merge_requests_spec.rb
index 9cebe52c444..bcb52f602b0 100644
--- a/spec/features/dashboard/merge_requests_spec.rb
+++ b/spec/features/dashboard/merge_requests_spec.rb
@@ -12,7 +12,9 @@ describe 'Dashboard Merge Requests' do
end
describe 'new merge request dropdown' do
- before { visit merge_requests_dashboard_path }
+ before do
+ visit merge_requests_dashboard_path
+ end
it 'shows projects only with merge requests feature enabled', js: true do
find('.new-project-item-select-button').trigger('click')
diff --git a/spec/features/dashboard/project_member_activity_index_spec.rb b/spec/features/dashboard/project_member_activity_index_spec.rb
index cdf919af9b5..0ba87d921d0 100644
--- a/spec/features/dashboard/project_member_activity_index_spec.rb
+++ b/spec/features/dashboard/project_member_activity_index_spec.rb
@@ -17,19 +17,25 @@ feature 'Project member activity', feature: true, js: true do
subject { page.find(".event-title").text }
context 'when a user joins the project' do
- before { visit_activities_and_wait_with_event(Event::JOINED) }
+ before do
+ visit_activities_and_wait_with_event(Event::JOINED)
+ end
it { is_expected.to eq("#{user.name} joined project") }
end
context 'when a user leaves the project' do
- before { visit_activities_and_wait_with_event(Event::LEFT) }
+ before do
+ visit_activities_and_wait_with_event(Event::LEFT)
+ end
it { is_expected.to eq("#{user.name} left project") }
end
context 'when a users membership expires for the project' do
- before { visit_activities_and_wait_with_event(Event::EXPIRED) }
+ before do
+ visit_activities_and_wait_with_event(Event::EXPIRED)
+ end
it "presents the correct message" do
message = "#{user.name} removed due to membership expiration from project"
diff --git a/spec/features/expand_collapse_diffs_spec.rb b/spec/features/expand_collapse_diffs_spec.rb
index c4d5077e5e1..36b0c371e6e 100644
--- a/spec/features/expand_collapse_diffs_spec.rb
+++ b/spec/features/expand_collapse_diffs_spec.rb
@@ -140,7 +140,9 @@ feature 'Expand and collapse diffs', js: true, feature: true do
end
context 'reloading the page' do
- before { refresh }
+ before do
+ refresh
+ end
it 'collapses the large diff by default' do
expect(large_diff).not_to have_selector('.code')
@@ -262,7 +264,7 @@ feature 'Expand and collapse diffs', js: true, feature: true do
# Wait for elements to appear to ensure full page reload
expect(page).to have_content('This diff was suppressed by a .gitattributes entry')
- expect(page).to have_content('This diff could not be displayed because it is too large.')
+ expect(page).to have_content('This source diff could not be displayed because it is too large.')
expect(page).to have_content('too_large_image.jpg')
find('.note-textarea')
diff --git a/spec/features/groups/group_settings_spec.rb b/spec/features/groups/group_settings_spec.rb
index cc25db4ad60..6afde1d0bed 100644
--- a/spec/features/groups/group_settings_spec.rb
+++ b/spec/features/groups/group_settings_spec.rb
@@ -52,9 +52,14 @@ feature 'Edit group settings', feature: true do
given!(:project) { create(:project, group: group, path: 'project') }
given(:old_project_full_path) { "/#{group.path}/#{project.path}" }
given(:new_project_full_path) { "/#{new_group_path}/#{project.path}" }
-
- before(:context) { TestEnv.clean_test_path }
- after(:example) { TestEnv.clean_test_path }
+
+ before(:context) do
+ TestEnv.clean_test_path
+ end
+
+ after(:example) do
+ TestEnv.clean_test_path
+ end
scenario 'the project is accessible via the new path' do
update_path(new_group_path)
diff --git a/spec/features/groups_spec.rb b/spec/features/groups_spec.rb
index 24ea7aba0cc..5737ca39b4e 100644
--- a/spec/features/groups_spec.rb
+++ b/spec/features/groups_spec.rb
@@ -12,7 +12,9 @@ feature 'Group', feature: true do
end
describe 'create a group' do
- before { visit new_group_path }
+ before do
+ visit new_group_path
+ end
describe 'with space in group path' do
it 'renders new group form with validation errors' do
@@ -138,7 +140,9 @@ feature 'Group', feature: true do
let(:path) { edit_group_path(group) }
let(:new_name) { 'new-name' }
- before { visit path }
+ before do
+ visit path
+ end
it 'saves new settings' do
fill_in 'group_name', with: new_name
diff --git a/spec/features/help_pages_spec.rb b/spec/features/help_pages_spec.rb
index 31014f5cad2..18102146b5f 100644
--- a/spec/features/help_pages_spec.rb
+++ b/spec/features/help_pages_spec.rb
@@ -37,7 +37,7 @@ describe 'Help Pages', feature: true do
context 'in a production environment with version check enabled', :js do
before do
allow(Rails.env).to receive(:production?) { true }
- allow(current_application_settings).to receive(:version_check_enabled) { true }
+ 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
@@ -53,4 +53,27 @@ describe 'Help Pages', feature: true do
expect(find('.js-version-status-badge', visible: false)).not_to be_visible
end
end
+
+ describe 'when help page is customized' do
+ before do
+ allow_any_instance_of(ApplicationSetting).to receive(:help_page_hide_commercial_content?) { true }
+ 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
+ visit help_path
+ end
+
+ it 'should display custom help page text' do
+ expect(page).to have_text "My Custom Text"
+ end
+
+ it 'should hide marketing content when enabled' do
+ expect(page).not_to have_link "Get a support subscription"
+ end
+
+ it 'should use a custom support url' do
+ expect(page).to have_link "See our website for getting help", href: "http://example.com/help"
+ end
+ end
end
diff --git a/spec/features/issuables/default_sort_order_spec.rb b/spec/features/issuables/default_sort_order_spec.rb
index bfe43bff10f..56c9b10e757 100644
--- a/spec/features/issuables/default_sort_order_spec.rb
+++ b/spec/features/issuables/default_sort_order_spec.rb
@@ -153,7 +153,9 @@ describe 'Projects > Issuables > Default sort order', feature: true do
context 'when the sort in the URL is id_desc' do
let(:issuable_type) { :issue }
- before { visit_issues(project, sort: 'id_desc') }
+ before do
+ visit_issues(project, sort: 'id_desc')
+ end
it 'shows the sort order as last created' do
expect(find('.issues-other-filters')).to have_content('Last created')
@@ -165,7 +167,9 @@ describe 'Projects > Issuables > Default sort order', feature: true do
context 'when the sort in the URL is id_asc' do
let(:issuable_type) { :issue }
- before { visit_issues(project, sort: 'id_asc') }
+ before do
+ visit_issues(project, sort: 'id_asc')
+ end
it 'shows the sort order as oldest created' do
expect(find('.issues-other-filters')).to have_content('Oldest created')
diff --git a/spec/features/issues_spec.rb b/spec/features/issues_spec.rb
index eecc565d2bd..2cff53539f3 100644
--- a/spec/features/issues_spec.rb
+++ b/spec/features/issues_spec.rb
@@ -246,7 +246,10 @@ describe 'Issues', feature: true do
context 'with a filter on labels' do
let(:label) { create(:label, project: project) }
- before { create(:label_link, label: label, target: foo) }
+
+ before do
+ create(:label_link, label: label, target: foo)
+ end
it 'sorts by least recently due date by excluding nil due dates' do
bar.update(due_date: nil)
diff --git a/spec/features/login_spec.rb b/spec/features/login_spec.rb
index c82e8c03343..4763f454810 100644
--- a/spec/features/login_spec.rb
+++ b/spec/features/login_spec.rb
@@ -202,10 +202,12 @@ feature 'Login', feature: true do
# TODO: otp_grace_period_started_at
context 'global setting' do
- before(:each) { stub_application_setting(require_two_factor_authentication: true) }
+ before do
+ stub_application_setting(require_two_factor_authentication: true)
+ end
context 'with grace period defined' do
- before(:each) do
+ before do
stub_application_setting(two_factor_grace_period: 48)
login_with(user)
end
@@ -242,7 +244,7 @@ feature 'Login', feature: true do
end
context 'without grace period defined' do
- before(:each) do
+ before do
stub_application_setting(two_factor_grace_period: 0)
login_with(user)
end
@@ -265,7 +267,7 @@ feature 'Login', feature: true do
end
context 'with grace period defined' do
- before(:each) do
+ before do
stub_application_setting(two_factor_grace_period: 48)
login_with(user)
end
@@ -306,7 +308,7 @@ feature 'Login', feature: true do
end
context 'without grace period defined' do
- before(:each) do
+ before do
stub_application_setting(two_factor_grace_period: 0)
login_with(user)
end
diff --git a/spec/features/merge_requests/conflicts_spec.rb b/spec/features/merge_requests/conflicts_spec.rb
index 27e2d5d16f3..9409c32104b 100644
--- a/spec/features/merge_requests/conflicts_spec.rb
+++ b/spec/features/merge_requests/conflicts_spec.rb
@@ -85,14 +85,18 @@ feature 'Merge request conflict resolution', js: true, feature: true do
context 'the conflicts are resolvable' do
let(:merge_request) { create_merge_request('conflict-resolvable') }
- before { visit namespace_project_merge_request_path(project.namespace, project, merge_request) }
+ before do
+ visit namespace_project_merge_request_path(project.namespace, project, merge_request)
+ end
it 'shows a link to the conflict resolution page' do
expect(page).to have_link('conflicts', href: /\/conflicts\Z/)
end
context 'in Inline view mode' do
- before { click_link('conflicts', href: /\/conflicts\Z/) }
+ before do
+ click_link('conflicts', href: /\/conflicts\Z/)
+ end
include_examples "conflicts are resolved in Interactive mode"
include_examples "conflicts are resolved in Edit inline mode"
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 c1d4d508e57..836a7b6e09a 100644
--- a/spec/features/merge_requests/merge_immediately_with_pipeline_spec.rb
+++ b/spec/features/merge_requests/merge_immediately_with_pipeline_spec.rb
@@ -18,7 +18,9 @@ feature 'Merge immediately', :feature, :js do
sha: project.repository.commit('master').id)
end
- before { project.team << [user, :master] }
+ before do
+ project.team << [user, :master]
+ end
context 'when there is active pipeline for merge request' do
background do
diff --git a/spec/features/milestones/milestones_spec.rb b/spec/features/milestones/milestones_spec.rb
index b3dfd6d0e81..c8a4d23f695 100644
--- a/spec/features/milestones/milestones_spec.rb
+++ b/spec/features/milestones/milestones_spec.rb
@@ -37,6 +37,14 @@ describe 'Milestone draggable', feature: true, js: true do
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
@@ -72,7 +80,7 @@ describe 'Milestone draggable', feature: true, js: true do
end
def create_and_drag_issue(params = {})
- create(:issue, params.merge(title: 'Foo', project: project, milestone: milestone))
+ @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')
diff --git a/spec/features/profiles/account_spec.rb b/spec/features/profiles/account_spec.rb
index 05a7587f8d4..89868c737f7 100644
--- a/spec/features/profiles/account_spec.rb
+++ b/spec/features/profiles/account_spec.rb
@@ -31,8 +31,13 @@ feature 'Profile > Account', feature: true do
given(:new_project_path) { "/#{new_username}/#{project.path}" }
given(:old_project_path) { "/#{user.username}/#{project.path}" }
- before(:context) { TestEnv.clean_test_path }
- after(:example) { TestEnv.clean_test_path }
+ before(:context) do
+ TestEnv.clean_test_path
+ end
+
+ after(:example) do
+ TestEnv.clean_test_path
+ end
scenario 'the project is accessible via the new path' do
update_username(new_username)
diff --git a/spec/features/projects/blobs/blob_show_spec.rb b/spec/features/projects/blobs/blob_show_spec.rb
index 45fdb36e506..71ffa352f80 100644
--- a/spec/features/projects/blobs/blob_show_spec.rb
+++ b/spec/features/projects/blobs/blob_show_spec.rb
@@ -17,6 +17,7 @@ feature 'File blob', :js, feature: true do
it 'displays the blob' do
aggregate_failures do
# shows highlighted Ruby code
+ expect(page).to have_css(".js-syntax-highlight")
expect(page).to have_content("require 'fileutils'")
# does not show a viewer switcher
@@ -71,6 +72,7 @@ feature 'File blob', :js, feature: true do
expect(page).to have_selector('.blob-viewer[data-type="rich"]', visible: false)
# shows highlighted Markdown code
+ expect(page).to have_css(".js-syntax-highlight")
expect(page).to have_content("[PEP-8](http://www.python.org/dev/peps/pep-0008/)")
# shows an enabled copy button
@@ -114,6 +116,7 @@ feature 'File blob', :js, feature: true do
expect(page).to have_selector('#LC1.hll')
# shows highlighted Markdown code
+ expect(page).to have_css(".js-syntax-highlight")
expect(page).to have_content("[PEP-8](http://www.python.org/dev/peps/pep-0008/)")
# shows an enabled copy button
diff --git a/spec/features/projects/diffs/diff_show_spec.rb b/spec/features/projects/diffs/diff_show_spec.rb
new file mode 100644
index 00000000000..48b7f1e0f34
--- /dev/null
+++ b/spec/features/projects/diffs/diff_show_spec.rb
@@ -0,0 +1,133 @@
+require 'spec_helper'
+
+feature 'Diff file viewer', :js, feature: true do
+ let(:project) { create(:project, :public, :repository) }
+
+ def visit_commit(sha, anchor: nil)
+ visit namespace_project_commit_path(project.namespace, project, sha, anchor: anchor)
+
+ wait_for_requests
+ end
+
+ context 'Ruby file' do
+ before do
+ visit_commit('570e7b2abdd848b95f2f578043fc23bd6f6fd24d')
+ end
+
+ it 'shows highlighted Ruby code' do
+ within('.diff-file[id="2f6fcd96b88b36ce98c38da085c795a27d92a3dd"]') do
+ expect(page).to have_css(".js-syntax-highlight")
+ expect(page).to have_content("def popen(cmd, path=nil)")
+ end
+ end
+ end
+
+ context 'Ruby file (stored in LFS)' do
+ before do
+ project.add_master(project.creator)
+
+ @commit_id = Files::CreateService.new(
+ project,
+ project.creator,
+ start_branch: 'master',
+ branch_name: 'master',
+ commit_message: "Add Ruby file in LFS",
+ file_path: 'files/lfs/ruby.rb',
+ file_content: project.repository.blob_at('master', 'files/lfs/lfs_object.iso').data
+ ).execute[:result]
+ end
+
+ context 'when LFS is enabled on the project' do
+ before do
+ allow(Gitlab.config.lfs).to receive(:enabled).and_return(true)
+ project.update_attribute(:lfs_enabled, true)
+
+ visit_commit(@commit_id)
+ end
+
+ it 'shows an error message' do
+ expect(page).to have_content('This source diff could not be displayed because it is stored in LFS. You can view the blob instead.')
+ end
+ end
+
+ context 'when LFS is disabled on the project' do
+ before do
+ visit_commit(@commit_id)
+ end
+
+ it 'displays the diff' do
+ expect(page).to have_content('size 1575078')
+ end
+ end
+ end
+
+ context 'Image file' do
+ before do
+ visit_commit('2f63565e7aac07bcdadb654e253078b727143ec4')
+ end
+
+ it 'shows a rendered image' do
+ within('.diff-file[id="e986451b8f7397b617dbb6fffcb5539328c56921"]') do
+ expect(page).to have_css('img[alt="files/images/6049019_460s.jpg"]')
+ end
+ end
+ end
+
+ context 'ISO file (stored in LFS)' do
+ context 'when LFS is enabled on the project' do
+ before do
+ allow(Gitlab.config.lfs).to receive(:enabled).and_return(true)
+ project.update_attribute(:lfs_enabled, true)
+
+ visit_commit('048721d90c449b244b7b4c53a9186b04330174ec')
+ end
+
+ it 'shows that file was added' do
+ expect(page).to have_content('File added')
+ end
+ end
+
+ context 'when LFS is disabled on the project' do
+ before do
+ visit_commit('048721d90c449b244b7b4c53a9186b04330174ec')
+ end
+
+ it 'displays the diff' do
+ expect(page).to have_content('size 1575078')
+ end
+ end
+ end
+
+ context 'ZIP file' do
+ before do
+ visit_commit('ae73cb07c9eeaf35924a10f713b364d32b2dd34f')
+ end
+
+ it 'shows that file was added' do
+ expect(page).to have_content('File added')
+ end
+ end
+
+ context 'binary file that appears to be text in the first 1024 bytes' do
+ before do
+ visit_commit('7b1cf4336b528e0f3d1d140ee50cafdbc703597c')
+ end
+
+ it 'shows the diff is collapsed' do
+ expect(page).to have_content('This diff is collapsed. Click to expand it.')
+ end
+
+ context 'expanding the diff' do
+ before do
+ # We can't use `click_link` because the "link" doesn't have an `href`.
+ find('a.click-to-expand').click
+
+ wait_for_requests
+ end
+
+ it 'shows there is no preview' do
+ expect(page).to have_content('No preview for this file type')
+ end
+ end
+ end
+end
diff --git a/spec/features/projects/jobs_spec.rb b/spec/features/projects/jobs_spec.rb
index 727ae7081b0..31c93c75d25 100644
--- a/spec/features/projects/jobs_spec.rb
+++ b/spec/features/projects/jobs_spec.rb
@@ -8,8 +8,8 @@ feature 'Jobs', :feature do
let(:namespace) { project.namespace }
let(:pipeline) { create(:ci_pipeline, project: project) }
- let(:build) { create(:ci_build, :trace, pipeline: pipeline) }
- let(:build2) { create(:ci_build) }
+ let(:job) { create(:ci_build, :trace, pipeline: pipeline) }
+ let(:job2) { create(:ci_build) }
let(:artifacts_file) do
fixture_file_upload(Rails.root + 'spec/fixtures/banana_sample.gif', 'image/gif')
@@ -21,7 +21,7 @@ feature 'Jobs', :feature do
end
describe "GET /:project/jobs" do
- let!(:build) { create(:ci_build, pipeline: pipeline) }
+ let!(:job) { create(:ci_build, pipeline: pipeline) }
context "Pending scope" do
before do
@@ -31,30 +31,30 @@ feature 'Jobs', :feature do
it "shows Pending tab jobs" do
expect(page).to have_link 'Cancel running'
expect(page).to have_selector('.nav-links li.active', text: 'Pending')
- expect(page).to have_content build.short_sha
- expect(page).to have_content build.ref
- expect(page).to have_content build.name
+ expect(page).to have_content job.short_sha
+ expect(page).to have_content job.ref
+ expect(page).to have_content job.name
end
end
context "Running scope" do
before do
- build.run!
+ job.run!
visit namespace_project_jobs_path(project.namespace, project, scope: :running)
end
it "shows Running tab jobs" do
expect(page).to have_selector('.nav-links li.active', text: 'Running')
expect(page).to have_link 'Cancel running'
- expect(page).to have_content build.short_sha
- expect(page).to have_content build.ref
- expect(page).to have_content build.name
+ expect(page).to have_content job.short_sha
+ expect(page).to have_content job.ref
+ expect(page).to have_content job.name
end
end
context "Finished scope" do
before do
- build.run!
+ job.run!
visit namespace_project_jobs_path(project.namespace, project, scope: :finished)
end
@@ -73,9 +73,9 @@ feature 'Jobs', :feature do
it "shows All tab jobs" do
expect(page).to have_selector('.nav-links li.active', text: 'All')
- expect(page).to have_content build.short_sha
- expect(page).to have_content build.ref
- expect(page).to have_content build.name
+ expect(page).to have_content job.short_sha
+ expect(page).to have_content job.ref
+ expect(page).to have_content job.name
expect(page).not_to have_link 'Cancel running'
end
end
@@ -97,7 +97,7 @@ feature 'Jobs', :feature do
describe "POST /:project/jobs/:id/cancel_all" do
before do
- build.run!
+ job.run!
visit namespace_project_jobs_path(project.namespace, project)
click_link "Cancel running"
end
@@ -105,19 +105,19 @@ feature 'Jobs', :feature do
it 'shows all necessary content' do
expect(page).to have_selector('.nav-links li.active', text: 'All')
expect(page).to have_content 'canceled'
- expect(page).to have_content build.short_sha
- expect(page).to have_content build.ref
- expect(page).to have_content build.name
+ expect(page).to have_content job.short_sha
+ expect(page).to have_content job.ref
+ expect(page).to have_content job.name
expect(page).not_to have_link 'Cancel running'
end
end
describe "GET /:project/jobs/:id" do
context "Job from project" do
- let(:build) { create(:ci_build, :success, pipeline: pipeline) }
+ let(:job) { create(:ci_build, :success, pipeline: pipeline) }
before do
- visit namespace_project_job_path(project.namespace, project, build)
+ visit namespace_project_job_path(project.namespace, project, job)
end
it 'shows status name', :js do
@@ -131,33 +131,33 @@ feature 'Jobs', :feature do
expect(page).to have_content pipeline.git_author_name
end
- it 'shows active build' do
+ it 'shows active job' do
expect(page).to have_selector('.build-job.active')
end
end
context 'when job is not running', :js do
- let(:build) { create(:ci_build, :success, pipeline: pipeline) }
+ let(:job) { create(:ci_build, :success, pipeline: pipeline) }
before do
- visit namespace_project_job_path(project.namespace, project, build)
+ visit namespace_project_job_path(project.namespace, project, job)
end
it 'shows retry button' do
expect(page).to have_link('Retry')
end
- context 'if build passed' do
+ context 'if job passed' do
it 'does not show New issue button' do
expect(page).not_to have_link('New issue')
end
end
- context 'if build failed' do
- let(:build) { create(:ci_build, :failed, pipeline: pipeline) }
+ context 'if job failed' do
+ let(:job) { create(:ci_build, :failed, pipeline: pipeline) }
before do
- visit namespace_project_job_path(namespace, project, build)
+ visit namespace_project_job_path(namespace, project, job)
end
it 'shows New issue button' do
@@ -165,9 +165,9 @@ feature 'Jobs', :feature do
end
it 'links to issues/new with the title and description filled in' do
- button_title = "Build Failed ##{build.id}"
- build_path = namespace_project_job_path(namespace, project, build)
- options = { issue: { title: button_title, description: build_path } }
+ button_title = "Build Failed ##{job.id}"
+ job_path = namespace_project_job_path(namespace, project, job)
+ options = { issue: { title: button_title, description: job_path } }
href = new_namespace_project_issue_path(namespace, project, options)
@@ -180,7 +180,7 @@ feature 'Jobs', :feature do
context "Job from other project" do
before do
- visit namespace_project_job_path(project.namespace, project, build2)
+ visit namespace_project_job_path(project.namespace, project, job2)
end
it { expect(page.status_code).to eq(404) }
@@ -188,8 +188,8 @@ feature 'Jobs', :feature do
context "Download artifacts" do
before do
- build.update_attributes(artifacts_file: artifacts_file)
- visit namespace_project_job_path(project.namespace, project, build)
+ job.update_attributes(artifacts_file: artifacts_file)
+ visit namespace_project_job_path(project.namespace, project, job)
end
it 'has button to download artifacts' do
@@ -199,10 +199,10 @@ feature 'Jobs', :feature do
context 'Artifacts expire date' do
before do
- build.update_attributes(artifacts_file: artifacts_file,
- artifacts_expire_at: expire_at)
+ job.update_attributes(artifacts_file: artifacts_file,
+ artifacts_expire_at: expire_at)
- visit namespace_project_job_path(project.namespace, project, build)
+ visit namespace_project_job_path(project.namespace, project, job)
end
context 'no expire date defined' do
@@ -248,7 +248,7 @@ feature 'Jobs', :feature do
context "when visiting old URL" do
let(:job_url) do
- namespace_project_job_path(project.namespace, project, build)
+ namespace_project_job_path(project.namespace, project, job)
end
before do
@@ -262,9 +262,9 @@ feature 'Jobs', :feature do
feature 'Raw trace' do
before do
- build.run!
+ job.run!
- visit namespace_project_job_path(project.namespace, project, build)
+ visit namespace_project_job_path(project.namespace, project, job)
end
it do
@@ -274,16 +274,16 @@ feature 'Jobs', :feature do
feature 'HTML trace', :js do
before do
- build.run!
+ job.run!
- visit namespace_project_job_path(project.namespace, project, build)
+ visit namespace_project_job_path(project.namespace, project, job)
end
context 'when job has an initial trace' do
it 'loads job trace' do
expect(page).to have_content 'BUILD TRACE'
- build.trace.write do |stream|
+ job.trace.write do |stream|
stream.append(' and more trace', 11)
end
@@ -295,12 +295,12 @@ feature 'Jobs', :feature do
feature 'Variables' do
let(:trigger_request) { create(:ci_trigger_request_with_variables) }
- let(:build) do
+ let(:job) do
create :ci_build, pipeline: pipeline, trigger_request: trigger_request
end
before do
- visit namespace_project_job_path(project.namespace, project, build)
+ visit namespace_project_job_path(project.namespace, project, job)
end
it 'shows variable key and value after click', js: true do
@@ -322,20 +322,20 @@ feature 'Jobs', :feature do
context 'job is successfull and has deployment' do
let(:deployment) { create(:deployment) }
- let(:build) { create(:ci_build, :success, environment: environment.name, deployments: [deployment], pipeline: pipeline) }
+ let(:job) { create(:ci_build, :success, environment: environment.name, deployments: [deployment], pipeline: pipeline) }
it 'shows a link for the job' do
- visit namespace_project_job_path(project.namespace, project, build)
+ visit namespace_project_job_path(project.namespace, project, job)
expect(page).to have_link environment.name
end
end
context 'job is complete and not successful' do
- let(:build) { create(:ci_build, :failed, environment: environment.name, pipeline: pipeline) }
+ let(:job) { create(:ci_build, :failed, environment: environment.name, pipeline: pipeline) }
it 'shows a link for the job' do
- visit namespace_project_job_path(project.namespace, project, build)
+ visit namespace_project_job_path(project.namespace, project, job)
expect(page).to have_link environment.name
end
@@ -343,10 +343,10 @@ feature 'Jobs', :feature do
context 'job creates a new deployment' do
let!(:deployment) { create(:deployment, environment: environment, sha: project.commit.id) }
- let(:build) { create(:ci_build, :success, environment: environment.name, pipeline: pipeline) }
+ let(:job) { create(:ci_build, :success, environment: environment.name, pipeline: pipeline) }
it 'shows a link to latest deployment' do
- visit namespace_project_job_path(project.namespace, project, build)
+ visit namespace_project_job_path(project.namespace, project, job)
expect(page).to have_link('latest deployment')
end
@@ -357,8 +357,8 @@ feature 'Jobs', :feature do
describe "POST /:project/jobs/:id/cancel", :js do
context "Job from project" do
before do
- build.run!
- visit namespace_project_job_path(project.namespace, project, build)
+ job.run!
+ visit namespace_project_job_path(project.namespace, project, job)
find('.js-cancel-job').click()
end
@@ -372,8 +372,8 @@ feature 'Jobs', :feature do
describe "POST /:project/jobs/:id/retry" do
context "Job from project", :js do
before do
- build.run!
- visit namespace_project_job_path(project.namespace, project, build)
+ job.run!
+ visit namespace_project_job_path(project.namespace, project, job)
find('.js-cancel-job').click()
find('.js-retry-button').trigger('click')
end
@@ -388,13 +388,13 @@ feature 'Jobs', :feature do
context "Job that current user is not allowed to retry" do
before do
- build.run!
- build.cancel!
+ job.run!
+ job.cancel!
project.update(visibility_level: Gitlab::VisibilityLevel::PUBLIC)
logout_direct
login_with(create(:user))
- visit namespace_project_job_path(project.namespace, project, build)
+ visit namespace_project_job_path(project.namespace, project, job)
end
it 'does not show the Retry button' do
@@ -407,15 +407,15 @@ feature 'Jobs', :feature do
describe "GET /:project/jobs/:id/download" do
before do
- build.update_attributes(artifacts_file: artifacts_file)
- visit namespace_project_job_path(project.namespace, project, build)
+ job.update_attributes(artifacts_file: artifacts_file)
+ visit namespace_project_job_path(project.namespace, project, job)
click_link 'Download'
end
context "Build from other project" do
before do
- build2.update_attributes(artifacts_file: artifacts_file)
- visit download_namespace_project_job_artifacts_path(project.namespace, project, build2)
+ job2.update_attributes(artifacts_file: artifacts_file)
+ visit download_namespace_project_job_artifacts_path(project.namespace, project, job2)
end
it { expect(page.status_code).to eq(404) }
@@ -427,23 +427,23 @@ feature 'Jobs', :feature do
context 'job from project' do
before do
Capybara.current_session.driver.headers = { 'X-Sendfile-Type' => 'X-Sendfile' }
- build.run!
- visit namespace_project_job_path(project.namespace, project, build)
+ job.run!
+ visit namespace_project_job_path(project.namespace, project, job)
find('.js-raw-link-controller').click()
end
it 'sends the right headers' do
expect(page.status_code).to eq(200)
expect(page.response_headers['Content-Type']).to eq('text/plain; charset=utf-8')
- expect(page.response_headers['X-Sendfile']).to eq(build.trace.send(:current_path))
+ expect(page.response_headers['X-Sendfile']).to eq(job.trace.send(:current_path))
end
end
context 'job from other project' do
before do
Capybara.current_session.driver.headers = { 'X-Sendfile-Type' => 'X-Sendfile' }
- build2.run!
- visit raw_namespace_project_job_path(project.namespace, project, build2)
+ job2.run!
+ visit raw_namespace_project_job_path(project.namespace, project, job2)
end
it 'sends the right headers' do
@@ -458,16 +458,16 @@ feature 'Jobs', :feature do
before do
Capybara.current_session.driver.headers = { 'X-Sendfile-Type' => 'X-Sendfile' }
- build.run!
+ job.run!
end
- context 'when build has trace in file', :js do
+ context 'when job has trace in file', :js do
before do
allow_any_instance_of(Gitlab::Ci::Trace)
.to receive(:paths)
.and_return([existing_file])
- visit namespace_project_job_path(namespace, project, build)
+ visit namespace_project_job_path(namespace, project, job)
find('.js-raw-link-controller').click
end
@@ -485,7 +485,7 @@ feature 'Jobs', :feature do
.to receive(:paths)
.and_return([])
- visit namespace_project_job_path(namespace, project, build)
+ visit namespace_project_job_path(namespace, project, job)
end
it 'sends the right headers' do
@@ -496,7 +496,7 @@ feature 'Jobs', :feature do
context "when visiting old URL" do
let(:raw_job_url) do
- raw_namespace_project_job_path(project.namespace, project, build)
+ raw_namespace_project_job_path(project.namespace, project, job)
end
before do
@@ -512,7 +512,7 @@ feature 'Jobs', :feature do
describe "GET /:project/jobs/:id/trace.json" do
context "Job from project" do
before do
- visit trace_namespace_project_job_path(project.namespace, project, build, format: :json)
+ visit trace_namespace_project_job_path(project.namespace, project, job, format: :json)
end
it { expect(page.status_code).to eq(200) }
@@ -520,7 +520,7 @@ feature 'Jobs', :feature do
context "Job from other project" do
before do
- visit trace_namespace_project_job_path(project.namespace, project, build2, format: :json)
+ visit trace_namespace_project_job_path(project.namespace, project, job2, format: :json)
end
it { expect(page.status_code).to eq(404) }
@@ -530,7 +530,7 @@ feature 'Jobs', :feature do
describe "GET /:project/jobs/:id/status" do
context "Job from project" do
before do
- visit status_namespace_project_job_path(project.namespace, project, build)
+ visit status_namespace_project_job_path(project.namespace, project, job)
end
it { expect(page.status_code).to eq(200) }
@@ -538,7 +538,7 @@ feature 'Jobs', :feature do
context "Job from other project" do
before do
- visit status_namespace_project_job_path(project.namespace, project, build2)
+ visit status_namespace_project_job_path(project.namespace, project, job2)
end
it { expect(page.status_code).to eq(404) }
diff --git a/spec/features/projects/pipelines/pipeline_spec.rb b/spec/features/projects/pipelines/pipeline_spec.rb
index 36a3ddca6ef..12c5ad45baf 100644
--- a/spec/features/projects/pipelines/pipeline_spec.rb
+++ b/spec/features/projects/pipelines/pipeline_spec.rb
@@ -47,7 +47,9 @@ describe 'Pipeline', :feature, :js do
let(:project) { create(:project) }
let(:pipeline) { create(:ci_pipeline, project: project, ref: 'master', sha: project.commit.id, user: user) }
- before { visit namespace_project_pipeline_path(project.namespace, project, pipeline) }
+ before do
+ visit namespace_project_pipeline_path(project.namespace, project, pipeline)
+ end
it 'shows the pipeline graph' do
expect(page).to have_selector('.pipeline-visualization')
@@ -164,7 +166,9 @@ describe 'Pipeline', :feature, :js do
it { expect(page).not_to have_content('retried') }
context 'when retrying' do
- before { find('.js-retry-button').trigger('click') }
+ before do
+ find('.js-retry-button').trigger('click')
+ end
it { expect(page).not_to have_content('Retry') }
end
@@ -174,7 +178,9 @@ describe 'Pipeline', :feature, :js do
it { expect(page).not_to have_selector('.ci-canceled') }
context 'when canceling' do
- before { click_on 'Cancel running' }
+ before do
+ click_on 'Cancel running'
+ end
it { expect(page).not_to have_content('Cancel running') }
end
@@ -226,7 +232,9 @@ describe 'Pipeline', :feature, :js do
it { expect(page).not_to have_content('retried') }
context 'when retrying' do
- before { find('.js-retry-button').trigger('click') }
+ before do
+ find('.js-retry-button').trigger('click')
+ end
it { expect(page).not_to have_content('Retry') }
end
@@ -236,7 +244,9 @@ describe 'Pipeline', :feature, :js do
it { expect(page).not_to have_selector('.ci-canceled') }
context 'when canceling' do
- before { click_on 'Cancel running' }
+ before do
+ click_on 'Cancel running'
+ end
it { expect(page).not_to have_content('Cancel running') }
end
diff --git a/spec/features/projects/pipelines/pipelines_spec.rb b/spec/features/projects/pipelines/pipelines_spec.rb
index 05c2bf350f1..026e2ce5b68 100644
--- a/spec/features/projects/pipelines/pipelines_spec.rb
+++ b/spec/features/projects/pipelines/pipelines_spec.rb
@@ -149,7 +149,9 @@ describe 'Pipelines', :feature, :js do
create(:ci_pipeline, :invalid, project: project)
end
- before { visit_project_pipelines }
+ before do
+ visit_project_pipelines
+ end
it 'contains badge that indicates errors' do
expect(page).to have_content 'yaml invalid'
@@ -171,7 +173,9 @@ describe 'Pipelines', :feature, :js do
commands: 'test')
end
- before { visit_project_pipelines }
+ before do
+ visit_project_pipelines
+ end
it 'has a dropdown with play button' do
expect(page).to have_selector('.dropdown-toggle.btn.btn-default .icon-play')
@@ -204,7 +208,9 @@ describe 'Pipelines', :feature, :js do
stage: 'test')
end
- before { visit_project_pipelines }
+ before do
+ visit_project_pipelines
+ end
it 'is cancelable' do
expect(page).to have_selector('.js-pipelines-cancel-button')
@@ -215,7 +221,9 @@ describe 'Pipelines', :feature, :js do
end
context 'when canceling' do
- before { find('.js-pipelines-cancel-button').trigger('click') }
+ before do
+ find('.js-pipelines-cancel-button').trigger('click')
+ end
it 'indicates that pipeline was canceled' do
expect(page).not_to have_selector('.js-pipelines-cancel-button')
@@ -255,7 +263,9 @@ describe 'Pipelines', :feature, :js do
stage: 'test')
end
- before { visit_project_pipelines }
+ before do
+ visit_project_pipelines
+ end
it 'has artifats' do
expect(page).to have_selector('.build-artifacts')
@@ -284,7 +294,9 @@ describe 'Pipelines', :feature, :js do
stage: 'test')
end
- before { visit_project_pipelines }
+ before do
+ visit_project_pipelines
+ end
it { expect(page).not_to have_selector('.build-artifacts') }
end
@@ -297,7 +309,9 @@ describe 'Pipelines', :feature, :js do
stage: 'test')
end
- before { visit_project_pipelines }
+ before do
+ visit_project_pipelines
+ end
it { expect(page).not_to have_selector('.build-artifacts') }
end
@@ -310,7 +324,9 @@ describe 'Pipelines', :feature, :js do
name: 'build')
end
- before { visit_project_pipelines }
+ before do
+ visit_project_pipelines
+ end
it 'should render a mini pipeline graph' do
expect(page).to have_selector('.js-mini-pipeline-graph')
@@ -437,7 +453,9 @@ describe 'Pipelines', :feature, :js do
end
context 'with gitlab-ci.yml' do
- before { stub_ci_pipeline_to_return_yaml_file }
+ before do
+ stub_ci_pipeline_to_return_yaml_file
+ end
it 'creates a new pipeline' do
expect { click_on 'Create pipeline' }
@@ -448,7 +466,9 @@ describe 'Pipelines', :feature, :js do
end
context 'without gitlab-ci.yml' do
- before { click_on 'Create pipeline' }
+ before do
+ click_on 'Create pipeline'
+ end
it { expect(page).to have_content('Missing .gitlab-ci.yml file') }
end
diff --git a/spec/features/projects/project_settings_spec.rb b/spec/features/projects/project_settings_spec.rb
index 11dcab4d737..2a9b32ea07e 100644
--- a/spec/features/projects/project_settings_spec.rb
+++ b/spec/features/projects/project_settings_spec.rb
@@ -58,8 +58,13 @@ describe 'Edit Project Settings', feature: true do
# Not using empty project because we need a repo to exist
let(:project) { create(:project, namespace: user.namespace, name: 'gitlabhq') }
- before(:context) { TestEnv.clean_test_path }
- after(:example) { TestEnv.clean_test_path }
+ before(:context) do
+ TestEnv.clean_test_path
+ end
+
+ after(:example) do
+ TestEnv.clean_test_path
+ end
specify 'the project is accessible via the new path' do
rename_project(project, path: 'bar')
@@ -96,9 +101,17 @@ describe 'Edit Project Settings', feature: true do
let!(:project) { create(:project, namespace: user.namespace, name: 'gitlabhq') }
let!(:group) { create(:group) }
- before(:context) { TestEnv.clean_test_path }
- before(:example) { group.add_owner(user) }
- after(:example) { TestEnv.clean_test_path }
+ before(:context) do
+ TestEnv.clean_test_path
+ end
+
+ before(:example) do
+ group.add_owner(user)
+ end
+
+ after(:example) do
+ TestEnv.clean_test_path
+ end
specify 'the project is accessible via the new path' do
transfer_project(project, group)
diff --git a/spec/features/protected_branches_spec.rb b/spec/features/protected_branches_spec.rb
index 667895bffa5..aa9164dd979 100644
--- a/spec/features/protected_branches_spec.rb
+++ b/spec/features/protected_branches_spec.rb
@@ -4,7 +4,9 @@ feature 'Protected Branches', feature: true, js: true do
let(:user) { create(:user, :admin) }
let(:project) { create(:project, :repository) }
- before { login_as(user) }
+ before do
+ login_as(user)
+ end
def set_protected_branch_name(branch_name)
find(".js-protected-branch-select").trigger('click')
diff --git a/spec/features/protected_tags_spec.rb b/spec/features/protected_tags_spec.rb
index 66236dbc7fc..63a20585776 100644
--- a/spec/features/protected_tags_spec.rb
+++ b/spec/features/protected_tags_spec.rb
@@ -4,7 +4,9 @@ feature 'Projected Tags', feature: true, js: true do
let(:user) { create(:user, :admin) }
let(:project) { create(:project, :repository) }
- before { login_as(user) }
+ before do
+ login_as(user)
+ end
def set_protected_tag_name(tag_name)
find(".js-protected-tag-select").click
diff --git a/spec/features/runners_spec.rb b/spec/features/runners_spec.rb
index 0e1cc9a0f73..e87d52f5c8f 100644
--- a/spec/features/runners_spec.rb
+++ b/spec/features/runners_spec.rb
@@ -4,7 +4,10 @@ describe "Runners" do
include GitlabRoutingHelper
let(:user) { create(:user) }
- before { login_as(user) }
+
+ before do
+ login_as(user)
+ end
describe "specific runners" do
before do
@@ -127,7 +130,9 @@ describe "Runners" do
end
context 'when runner has tags' do
- before { runner.update_attribute(:tag_list, ['tag']) }
+ before do
+ runner.update_attribute(:tag_list, ['tag'])
+ end
scenario 'user wants to prevent runner from running untagged job' do
visit runners_path(project)
diff --git a/spec/features/search_spec.rb b/spec/features/search_spec.rb
index 7834807b1f1..89d4f536b20 100644
--- a/spec/features/search_spec.rb
+++ b/spec/features/search_spec.rb
@@ -83,7 +83,9 @@ describe "Search", feature: true do
let(:project) { create(:project, :repository) }
let(:note) { create(:note_on_commit, author: user, project: project, commit_id: project.repository.commit.id, note: 'Bug here') }
- before { note.update_attributes(commit_id: 12345678) }
+ before do
+ note.update_attributes(commit_id: 12345678)
+ end
it 'finds comment' do
visit namespace_project_path(project.namespace, project)
diff --git a/spec/features/security/project/internal_access_spec.rb b/spec/features/security/project/internal_access_spec.rb
index 2a2655bbdb5..f33406a40a7 100644
--- a/spec/features/security/project/internal_access_spec.rb
+++ b/spec/features/security/project/internal_access_spec.rb
@@ -337,7 +337,9 @@ describe "Internal Project Access", feature: true do
subject { namespace_project_jobs_path(project.namespace, project) }
context "when allowed for public and internal" do
- before { project.update(public_builds: true) }
+ before do
+ project.update(public_builds: true)
+ end
it { is_expected.to be_allowed_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
@@ -351,7 +353,9 @@ describe "Internal Project Access", feature: true do
end
context "when disallowed for public and internal" do
- before { project.update(public_builds: false) }
+ before do
+ project.update(public_builds: false)
+ end
it { is_expected.to be_allowed_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
@@ -371,7 +375,9 @@ describe "Internal Project Access", feature: true do
subject { namespace_project_job_path(project.namespace, project, build.id) }
context "when allowed for public and internal" do
- before { project.update(public_builds: true) }
+ before do
+ project.update(public_builds: true)
+ end
it { is_expected.to be_allowed_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
@@ -385,7 +391,9 @@ describe "Internal Project Access", feature: true do
end
context "when disallowed for public and internal" do
- before { project.update(public_builds: false) }
+ before do
+ project.update(public_builds: false)
+ end
it { is_expected.to be_allowed_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
diff --git a/spec/features/security/project/public_access_spec.rb b/spec/features/security/project/public_access_spec.rb
index 35d5163941e..16a1331b2f3 100644
--- a/spec/features/security/project/public_access_spec.rb
+++ b/spec/features/security/project/public_access_spec.rb
@@ -157,7 +157,9 @@ describe "Public Project Access", feature: true do
subject { namespace_project_jobs_path(project.namespace, project) }
context "when allowed for public" do
- before { project.update(public_builds: true) }
+ before do
+ project.update(public_builds: true)
+ end
it { is_expected.to be_allowed_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
@@ -171,7 +173,9 @@ describe "Public Project Access", feature: true do
end
context "when disallowed for public" do
- before { project.update(public_builds: false) }
+ before do
+ project.update(public_builds: false)
+ end
it { is_expected.to be_allowed_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
@@ -191,7 +195,9 @@ describe "Public Project Access", feature: true do
subject { namespace_project_job_path(project.namespace, project, build.id) }
context "when allowed for public" do
- before { project.update(public_builds: true) }
+ before do
+ project.update(public_builds: true)
+ end
it { is_expected.to be_allowed_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
@@ -205,7 +211,9 @@ describe "Public Project Access", feature: true do
end
context "when disallowed for public" do
- before { project.update(public_builds: false) }
+ before do
+ project.update(public_builds: false)
+ end
it { is_expected.to be_allowed_for(:admin) }
it { is_expected.to be_allowed_for(:owner).of(project) }
diff --git a/spec/features/signup_spec.rb b/spec/features/signup_spec.rb
index d7b6dda4946..5d6d1e79af2 100644
--- a/spec/features/signup_spec.rb
+++ b/spec/features/signup_spec.rb
@@ -3,7 +3,9 @@ require 'spec_helper'
feature 'Signup', feature: true do
describe 'signup with no errors' do
context "when sending confirmation email" do
- before { stub_application_setting(send_user_confirmation_email: true) }
+ before do
+ stub_application_setting(send_user_confirmation_email: true)
+ end
it 'creates the user account and sends a confirmation email' do
user = build(:user)
@@ -23,7 +25,9 @@ feature 'Signup', feature: true do
end
context "when not sending confirmation email" do
- before { stub_application_setting(send_user_confirmation_email: false) }
+ before do
+ stub_application_setting(send_user_confirmation_email: false)
+ end
it 'creates the user account and goes to dashboard' do
user = build(:user)
diff --git a/spec/features/task_lists_spec.rb b/spec/features/task_lists_spec.rb
index 563e65d3cc5..51b1b8e2328 100644
--- a/spec/features/task_lists_spec.rb
+++ b/spec/features/task_lists_spec.rb
@@ -144,7 +144,9 @@ feature 'Task Lists', feature: true do
describe 'nested tasks', js: true do
let(:issue) { create(:issue, description: nested_tasks_markdown, author: user, project: project) }
- before { visit_issue(project, issue) }
+ before do
+ visit_issue(project, issue)
+ end
it 'renders' do
expect(page).to have_selector('ul.task-list', count: 2)
diff --git a/spec/features/todos/todos_sorting_spec.rb b/spec/features/todos/todos_sorting_spec.rb
index 4d5bd476301..f012d250887 100644
--- a/spec/features/todos/todos_sorting_spec.rb
+++ b/spec/features/todos/todos_sorting_spec.rb
@@ -8,7 +8,9 @@ describe "Dashboard > User sorts todos", feature: true do
let(:label_2) { create(:label, title: 'label_2', project: project, priority: 2) }
let(:label_3) { create(:label, title: 'label_3', project: project, priority: 3) }
- before { project.team << [user, :developer] }
+ before do
+ project.team << [user, :developer]
+ end
context 'sort options' do
let(:issue_1) { create(:issue, title: 'issue_1', project: project) }
diff --git a/spec/features/triggers_spec.rb b/spec/features/triggers_spec.rb
index c1ae6db00c6..2ea9992173d 100644
--- a/spec/features/triggers_spec.rb
+++ b/spec/features/triggers_spec.rb
@@ -5,7 +5,10 @@ feature 'Triggers', feature: true, js: true do
let(:user) { create(:user) }
let(:user2) { create(:user) }
let(:guest_user) { create(:user) }
- before { login_as(user) }
+
+ before do
+ login_as(user)
+ end
before do
@project = create(:empty_project)
diff --git a/spec/features/u2f_spec.rb b/spec/features/u2f_spec.rb
index 2fed8067042..dc21637967f 100644
--- a/spec/features/u2f_spec.rb
+++ b/spec/features/u2f_spec.rb
@@ -1,7 +1,9 @@
require 'spec_helper'
feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', :js do
- before { allow_any_instance_of(U2fHelper).to receive(:inject_u2f_api?).and_return(true) }
+ before do
+ allow_any_instance_of(U2fHelper).to receive(:inject_u2f_api?).and_return(true)
+ end
def manage_two_factor_authentication
click_on 'Manage two-factor authentication'
@@ -28,7 +30,9 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', :js do
end
describe 'when 2FA via OTP is disabled' do
- before { user.update_attribute(:otp_required_for_login, false) }
+ before do
+ user.update_attribute(:otp_required_for_login, false)
+ end
it 'does not allow registering a new device' do
visit profile_account_path
diff --git a/spec/features/unsubscribe_links_spec.rb b/spec/features/unsubscribe_links_spec.rb
index 8509551ce4a..0a8db15c75f 100644
--- a/spec/features/unsubscribe_links_spec.rb
+++ b/spec/features/unsubscribe_links_spec.rb
@@ -56,7 +56,9 @@ describe 'Unsubscribe links', feature: true do
end
context 'when logged in' do
- before { login_as(recipient) }
+ before do
+ login_as(recipient)
+ end
it 'unsubscribes from the issue when visiting the link from the email body' do
visit body_link
diff --git a/spec/features/users_spec.rb b/spec/features/users_spec.rb
index fbe078bd136..c241dae12cf 100644
--- a/spec/features/users_spec.rb
+++ b/spec/features/users_spec.rb
@@ -45,7 +45,9 @@ feature 'Users', feature: true, js: true do
end
describe 'redirect alias routes' do
- before { user }
+ before do
+ expect(user).to be_persisted
+ end
scenario '/u/user1 redirects to user page' do
visit '/u/user1'
diff --git a/spec/finders/issues_finder_spec.rb b/spec/finders/issues_finder_spec.rb
index 96151689359..8f2d60f2f1b 100644
--- a/spec/finders/issues_finder_spec.rb
+++ b/spec/finders/issues_finder_spec.rb
@@ -148,7 +148,9 @@ describe IssuesFinder do
let(:params) { { label_name: [label.title, label2.title].join(',') } }
let(:label2) { create(:label, project: project2) }
- before { create(:label_link, label: label2, target: issue2) }
+ before do
+ create(:label_link, label: label2, target: issue2)
+ end
it 'returns the unique issues with any of those labels' do
expect(issues).to contain_exactly(issue2)
diff --git a/spec/finders/personal_access_tokens_finder_spec.rb b/spec/finders/personal_access_tokens_finder_spec.rb
index fd92664ca24..3f22b3a253d 100644
--- a/spec/finders/personal_access_tokens_finder_spec.rb
+++ b/spec/finders/personal_access_tokens_finder_spec.rb
@@ -25,49 +25,65 @@ describe PersonalAccessTokensFinder do
end
describe 'without impersonation' do
- before { params[:impersonation] = false }
+ before do
+ params[:impersonation] = false
+ end
it { is_expected.to contain_exactly(active_personal_access_token, revoked_personal_access_token, expired_personal_access_token) }
describe 'with active state' do
- before { params[:state] = 'active' }
+ before do
+ params[:state] = 'active'
+ end
it { is_expected.to contain_exactly(active_personal_access_token) }
end
describe 'with inactive state' do
- before { params[:state] = 'inactive' }
+ before do
+ params[:state] = 'inactive'
+ end
it { is_expected.to contain_exactly(revoked_personal_access_token, expired_personal_access_token) }
end
end
describe 'with impersonation' do
- before { params[:impersonation] = true }
+ before do
+ params[:impersonation] = true
+ end
it { is_expected.to contain_exactly(active_impersonation_token, revoked_impersonation_token, expired_impersonation_token) }
describe 'with active state' do
- before { params[:state] = 'active' }
+ before do
+ params[:state] = 'active'
+ end
it { is_expected.to contain_exactly(active_impersonation_token) }
end
describe 'with inactive state' do
- before { params[:state] = 'inactive' }
+ before do
+ params[:state] = 'inactive'
+ end
it { is_expected.to contain_exactly(revoked_impersonation_token, expired_impersonation_token) }
end
end
describe 'with active state' do
- before { params[:state] = 'active' }
+ before do
+ params[:state] = 'active'
+ end
it { is_expected.to contain_exactly(active_personal_access_token, active_impersonation_token) }
end
describe 'with inactive state' do
- before { params[:state] = 'inactive' }
+ before do
+ params[:state] = 'inactive'
+ end
it do
is_expected.to contain_exactly(expired_personal_access_token, revoked_personal_access_token,
@@ -81,7 +97,9 @@ describe PersonalAccessTokensFinder do
it { is_expected.to eq(active_personal_access_token) }
describe 'with impersonation' do
- before { params[:impersonation] = true }
+ before do
+ params[:impersonation] = true
+ end
it { is_expected.to be_nil }
end
@@ -93,7 +111,9 @@ describe PersonalAccessTokensFinder do
it { is_expected.to eq(active_personal_access_token) }
describe 'with impersonation' do
- before { params[:impersonation] = true }
+ before do
+ params[:impersonation] = true
+ end
it { is_expected.to be_nil }
end
@@ -109,7 +129,9 @@ describe PersonalAccessTokensFinder do
let!(:other_user_expired_impersonation_token) { create(:personal_access_token, :expired, :impersonation, user: user2) }
let!(:other_user_revoked_impersonation_token) { create(:personal_access_token, :revoked, :impersonation, user: user2) }
- before { params[:user] = user }
+ before do
+ params[:user] = user
+ end
it do
is_expected.to contain_exactly(active_personal_access_token, active_impersonation_token,
@@ -118,49 +140,65 @@ describe PersonalAccessTokensFinder do
end
describe 'without impersonation' do
- before { params[:impersonation] = false }
+ before do
+ params[:impersonation] = false
+ end
it { is_expected.to contain_exactly(active_personal_access_token, revoked_personal_access_token, expired_personal_access_token) }
describe 'with active state' do
- before { params[:state] = 'active' }
+ before do
+ params[:state] = 'active'
+ end
it { is_expected.to contain_exactly(active_personal_access_token) }
end
describe 'with inactive state' do
- before { params[:state] = 'inactive' }
+ before do
+ params[:state] = 'inactive'
+ end
it { is_expected.to contain_exactly(revoked_personal_access_token, expired_personal_access_token) }
end
end
describe 'with impersonation' do
- before { params[:impersonation] = true }
+ before do
+ params[:impersonation] = true
+ end
it { is_expected.to contain_exactly(active_impersonation_token, revoked_impersonation_token, expired_impersonation_token) }
describe 'with active state' do
- before { params[:state] = 'active' }
+ before do
+ params[:state] = 'active'
+ end
it { is_expected.to contain_exactly(active_impersonation_token) }
end
describe 'with inactive state' do
- before { params[:state] = 'inactive' }
+ before do
+ params[:state] = 'inactive'
+ end
it { is_expected.to contain_exactly(revoked_impersonation_token, expired_impersonation_token) }
end
end
describe 'with active state' do
- before { params[:state] = 'active' }
+ before do
+ params[:state] = 'active'
+ end
it { is_expected.to contain_exactly(active_personal_access_token, active_impersonation_token) }
end
describe 'with inactive state' do
- before { params[:state] = 'inactive' }
+ before do
+ params[:state] = 'inactive'
+ end
it do
is_expected.to contain_exactly(expired_personal_access_token, revoked_personal_access_token,
@@ -174,7 +212,9 @@ describe PersonalAccessTokensFinder do
it { is_expected.to eq(active_personal_access_token) }
describe 'with impersonation' do
- before { params[:impersonation] = true }
+ before do
+ params[:impersonation] = true
+ end
it { is_expected.to be_nil }
end
@@ -186,7 +226,9 @@ describe PersonalAccessTokensFinder do
it { is_expected.to eq(active_personal_access_token) }
describe 'with impersonation' do
- before { params[:impersonation] = true }
+ before do
+ params[:impersonation] = true
+ end
it { is_expected.to be_nil }
end
diff --git a/spec/finders/personal_projects_finder_spec.rb b/spec/finders/personal_projects_finder_spec.rb
index e0e17af681a..304b0fb67fb 100644
--- a/spec/finders/personal_projects_finder_spec.rb
+++ b/spec/finders/personal_projects_finder_spec.rb
@@ -32,7 +32,9 @@ describe PersonalProjectsFinder do
end
context 'external' do
- before { current_user.update_attributes(external: true) }
+ before do
+ current_user.update_attributes(external: true)
+ end
it { is_expected.to eq([private_project, public_project]) }
end
diff --git a/spec/finders/todos_finder_spec.rb b/spec/finders/todos_finder_spec.rb
index f7e7e733cf7..8be447418b0 100644
--- a/spec/finders/todos_finder_spec.rb
+++ b/spec/finders/todos_finder_spec.rb
@@ -6,7 +6,9 @@ describe TodosFinder do
let(:project) { create(:empty_project) }
let(:finder) { described_class }
- before { project.team << [user, :developer] }
+ before do
+ project.team << [user, :developer]
+ end
describe '#sort' do
context 'by date' do
diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb
index 49df91b236f..cc7f889b927 100644
--- a/spec/helpers/application_helper_spec.rb
+++ b/spec/helpers/application_helper_spec.rb
@@ -257,4 +257,24 @@ describe ApplicationHelper do
it { expect(helper.active_when(true)).to eq('active') }
it { expect(helper.active_when(false)).to eq(nil) }
end
+
+ describe '#support_url' do
+ context 'when alternate support url is specified' do
+ let(:alternate_url) { 'http://company.example.com/getting-help' }
+
+ before do
+ allow(current_application_settings).to receive(:help_page_support_url) { alternate_url }
+ end
+
+ it 'returns the alternate support url' do
+ expect(helper.support_url).to eq(alternate_url)
+ end
+ end
+
+ context 'when alternate support url is not specified' do
+ it 'builds the support url from the promo_url' do
+ expect(helper.support_url).to eq(helper.promo_url + '/getting-help/')
+ end
+ end
+ end
end
diff --git a/spec/helpers/diff_helper_spec.rb b/spec/helpers/diff_helper_spec.rb
index a74615e07f9..0ac030d3171 100644
--- a/spec/helpers/diff_helper_spec.rb
+++ b/spec/helpers/diff_helper_spec.rb
@@ -8,7 +8,7 @@ describe DiffHelper do
let(:commit) { project.commit(sample_commit.id) }
let(:diffs) { commit.raw_diffs }
let(:diff) { diffs.first }
- let(:diff_refs) { [commit.parent, commit] }
+ let(:diff_refs) { commit.diff_refs }
let(:diff_file) { Gitlab::Diff::File.new(diff, diff_refs: diff_refs, repository: repository) }
describe 'diff_view' do
@@ -207,4 +207,41 @@ describe DiffHelper do
expect(output).not_to have_css 'td:nth-child(3)'
end
end
+
+ context 'viewer related' do
+ let(:viewer) { diff_file.simple_viewer }
+
+ before do
+ assign(:project, project)
+ end
+
+ describe '#diff_render_error_reason' do
+ context 'for error :too_large' do
+ before do
+ expect(viewer).to receive(:render_error).and_return(:too_large)
+ end
+
+ it 'returns an error message' do
+ expect(helper.diff_render_error_reason(viewer)).to eq('it is too large')
+ end
+ end
+
+ context 'for error :server_side_but_stored_externally' do
+ before do
+ expect(viewer).to receive(:render_error).and_return(:server_side_but_stored_externally)
+ expect(diff_file).to receive(:external_storage).and_return(:lfs)
+ end
+
+ it 'returns an error message' do
+ expect(helper.diff_render_error_reason(viewer)).to eq('it is stored in LFS')
+ end
+ end
+ end
+
+ describe '#diff_render_error_options' do
+ it 'includes a "view the blob" link' do
+ expect(helper.diff_render_error_options(viewer)).to include(/view the blob/)
+ end
+ end
+ end
end
diff --git a/spec/helpers/projects_helper_spec.rb b/spec/helpers/projects_helper_spec.rb
index 3ed0b0a756b..9a4086725d2 100644
--- a/spec/helpers/projects_helper_spec.rb
+++ b/spec/helpers/projects_helper_spec.rb
@@ -250,7 +250,9 @@ describe ProjectsHelper do
end
context "when project is private" do
- before { project.update_attributes(visibility_level: Gitlab::VisibilityLevel::PRIVATE) }
+ before do
+ project.update_attributes(visibility_level: Gitlab::VisibilityLevel::PRIVATE)
+ end
it "shows only allowed options" do
helper.instance_variable_set(:@project, project)
diff --git a/spec/javascripts/notes_spec.js b/spec/javascripts/notes_spec.js
index bfd8b8648a6..c6f218e4dac 100644
--- a/spec/javascripts/notes_spec.js
+++ b/spec/javascripts/notes_spec.js
@@ -126,6 +126,7 @@ import '~/notes';
const deferred = $.Deferred();
spyOn($, 'ajax').and.returnValue(deferred.promise());
spyOn(this.notes, 'revertNoteEditForm');
+ spyOn(this.notes, 'setupNewNote');
$('.js-comment-button').click();
deferred.resolve(noteEntity);
@@ -136,6 +137,46 @@ import '~/notes';
this.notes.updateNote(updatedNote, $targetNote);
expect(this.notes.revertNoteEditForm).toHaveBeenCalledWith($targetNote);
+ expect(this.notes.setupNewNote).toHaveBeenCalled();
+ });
+ });
+
+ describe('updateNoteTargetSelector', () => {
+ const hash = 'note_foo';
+ let $note;
+
+ beforeEach(() => {
+ $note = $(`<div id="${hash}"></div>`);
+ spyOn($note, 'filter').and.callThrough();
+ spyOn($note, 'toggleClass').and.callThrough();
+ });
+
+ it('sets target when hash matches', () => {
+ spyOn(gl.utils, 'getLocationHash');
+ gl.utils.getLocationHash.and.returnValue(hash);
+
+ Notes.updateNoteTargetSelector($note);
+
+ expect($note.filter).toHaveBeenCalledWith(`#${hash}`);
+ expect($note.toggleClass).toHaveBeenCalledWith('target', true);
+ });
+
+ it('unsets target when hash does not match', () => {
+ spyOn(gl.utils, 'getLocationHash');
+ gl.utils.getLocationHash.and.returnValue('note_doesnotexist');
+
+ Notes.updateNoteTargetSelector($note);
+
+ expect($note.toggleClass).toHaveBeenCalledWith('target', false);
+ });
+
+ it('unsets target when there is not a hash fragment anymore', () => {
+ spyOn(gl.utils, 'getLocationHash');
+ gl.utils.getLocationHash.and.returnValue(null);
+
+ Notes.updateNoteTargetSelector($note);
+
+ expect($note.toggleClass).toHaveBeenCalledWith('target', null);
});
});
@@ -189,9 +230,13 @@ import '~/notes';
Notes.isUpdatedNote.and.returnValue(true);
const $note = $('<div>');
$notesList.find.and.returnValue($note);
+ const $newNote = $(note.html);
+ Notes.animateUpdateNote.and.returnValue($newNote);
+
Notes.prototype.renderNote.call(notes, note, null, $notesList);
expect(Notes.animateUpdateNote).toHaveBeenCalledWith(note.html, $note);
+ expect(notes.setupNewNote).toHaveBeenCalledWith($newNote);
});
describe('while editing', () => {
@@ -378,6 +423,23 @@ import '~/notes';
});
});
+ describe('putEditFormInPlace', () => {
+ it('should call gl.GLForm with GFM parameter passed through', () => {
+ spyOn(gl, 'GLForm');
+
+ const $el = jasmine.createSpyObj('$form', ['find', 'closest']);
+ $el.find.and.returnValue($('<div>'));
+ $el.closest.and.returnValue($('<div>'));
+
+ Notes.prototype.putEditFormInPlace.call({
+ getEditFormSelector: () => '',
+ enableGFM: true
+ }, $el);
+
+ expect(gl.GLForm).toHaveBeenCalledWith(jasmine.any(Object), true);
+ });
+ });
+
describe('postComment & updateComment', () => {
const sampleComment = 'foo';
const updatedComment = 'bar';
diff --git a/spec/javascripts/pipelines/pipelines_actions_spec.js b/spec/javascripts/pipelines/pipelines_actions_spec.js
index c89dacbcd93..8a58b77f1e3 100644
--- a/spec/javascripts/pipelines/pipelines_actions_spec.js
+++ b/spec/javascripts/pipelines/pipelines_actions_spec.js
@@ -1,5 +1,5 @@
import Vue from 'vue';
-import pipelinesActionsComp from '~/pipelines/components/pipelines_actions';
+import pipelinesActionsComp from '~/pipelines/components/pipelines_actions.vue';
describe('Pipelines Actions dropdown', () => {
let component;
diff --git a/spec/javascripts/pipelines/pipelines_artifacts_spec.js b/spec/javascripts/pipelines/pipelines_artifacts_spec.js
index 9724b63d957..acb67d0ec21 100644
--- a/spec/javascripts/pipelines/pipelines_artifacts_spec.js
+++ b/spec/javascripts/pipelines/pipelines_artifacts_spec.js
@@ -1,5 +1,5 @@
import Vue from 'vue';
-import artifactsComp from '~/pipelines/components/pipelines_artifacts';
+import artifactsComp from '~/pipelines/components/pipelines_artifacts.vue';
describe('Pipelines Artifacts dropdown', () => {
let component;
diff --git a/spec/javascripts/pipelines/pipelines_spec.js b/spec/javascripts/pipelines/pipelines_spec.js
index 3a56156358b..c30abb2edb0 100644
--- a/spec/javascripts/pipelines/pipelines_spec.js
+++ b/spec/javascripts/pipelines/pipelines_spec.js
@@ -1,5 +1,5 @@
import Vue from 'vue';
-import pipelinesComp from '~/pipelines/pipelines';
+import pipelinesComp from '~/pipelines/components/pipelines.vue';
import Store from '~/pipelines/stores/pipelines_store';
describe('Pipelines', () => {
diff --git a/spec/javascripts/pipelines/time_ago_spec.js b/spec/javascripts/pipelines/time_ago_spec.js
index 24581e8c672..42b34c82f89 100644
--- a/spec/javascripts/pipelines/time_ago_spec.js
+++ b/spec/javascripts/pipelines/time_ago_spec.js
@@ -1,5 +1,5 @@
import Vue from 'vue';
-import timeAgo from '~/pipelines/components/time_ago';
+import timeAgo from '~/pipelines/components/time_ago.vue';
describe('Timeago component', () => {
let TimeAgo;
diff --git a/spec/javascripts/vue_shared/components/commit_spec.js b/spec/javascripts/vue_shared/components/commit_spec.js
index 540245fe71e..1c3188cdda2 100644
--- a/spec/javascripts/vue_shared/components/commit_spec.js
+++ b/spec/javascripts/vue_shared/components/commit_spec.js
@@ -1,5 +1,5 @@
import Vue from 'vue';
-import commitComp from '~/vue_shared/components/commit';
+import commitComp from '~/vue_shared/components/commit.vue';
describe('Commit component', () => {
let props;
diff --git a/spec/javascripts/vue_shared/components/pipelines_table_row_spec.js b/spec/javascripts/vue_shared/components/pipelines_table_row_spec.js
index 67419cfcbea..346fd0ae010 100644
--- a/spec/javascripts/vue_shared/components/pipelines_table_row_spec.js
+++ b/spec/javascripts/vue_shared/components/pipelines_table_row_spec.js
@@ -1,5 +1,5 @@
import Vue from 'vue';
-import tableRowComp from '~/vue_shared/components/pipelines_table_row';
+import tableRowComp from '~/vue_shared/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/vue_shared/components/pipelines_table_spec.js
index 6cc178b8f1d..c362cfb7a96 100644
--- a/spec/javascripts/vue_shared/components/pipelines_table_spec.js
+++ b/spec/javascripts/vue_shared/components/pipelines_table_spec.js
@@ -1,5 +1,5 @@
import Vue from 'vue';
-import pipelinesTableComp from '~/vue_shared/components/pipelines_table';
+import pipelinesTableComp from '~/vue_shared/components/pipelines_table.vue';
import '~/lib/utils/datetime_utility';
describe('Pipelines Table', () => {
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 fbf7a461fa5..76cefe112fb 100644
--- a/spec/lib/banzai/filter/external_issue_reference_filter_spec.rb
+++ b/spec/lib/banzai/filter/external_issue_reference_filter_spec.rb
@@ -82,7 +82,9 @@ describe Banzai::Filter::ExternalIssueReferenceFilter, lib: true do
context 'with RequestStore enabled' do
let(:reference_filter) { HTML::Pipeline.new([described_class]) }
- before { allow(RequestStore).to receive(:active?).and_return(true) }
+ before do
+ allow(RequestStore).to receive(:active?).and_return(true)
+ end
it 'queries the collection on the first call' do
expect_any_instance_of(Project).to receive(:default_issues_tracker?).once.and_call_original
diff --git a/spec/lib/banzai/filter/redactor_filter_spec.rb b/spec/lib/banzai/filter/redactor_filter_spec.rb
index 7c4a0f32c7b..97504aebed5 100644
--- a/spec/lib/banzai/filter/redactor_filter_spec.rb
+++ b/spec/lib/banzai/filter/redactor_filter_spec.rb
@@ -39,7 +39,9 @@ describe Banzai::Filter::RedactorFilter, lib: true do
end
context 'valid projects' do
- before { allow_any_instance_of(Banzai::ReferenceParser::BaseParser).to receive(:can_read_reference?).and_return(true) }
+ before do
+ allow_any_instance_of(Banzai::ReferenceParser::BaseParser).to receive(:can_read_reference?).and_return(true)
+ end
it 'allows permitted Project references' do
user = create(:user)
@@ -54,7 +56,9 @@ describe Banzai::Filter::RedactorFilter, lib: true do
end
context 'invalid projects' do
- before { allow_any_instance_of(Banzai::ReferenceParser::BaseParser).to receive(:can_read_reference?).and_return(false) }
+ before do
+ allow_any_instance_of(Banzai::ReferenceParser::BaseParser).to receive(:can_read_reference?).and_return(false)
+ end
it 'removes unpermitted references' do
user = create(:user)
diff --git a/spec/lib/banzai/reference_parser/base_parser_spec.rb b/spec/lib/banzai/reference_parser/base_parser_spec.rb
index f4f42bfc3ed..76fab93821a 100644
--- a/spec/lib/banzai/reference_parser/base_parser_spec.rb
+++ b/spec/lib/banzai/reference_parser/base_parser_spec.rb
@@ -114,7 +114,7 @@ describe Banzai::ReferenceParser::BaseParser, lib: true do
expect(hash).to eq({ link => user })
end
- it 'returns an empty Hash when entry does not exist in the database' 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?).
diff --git a/spec/lib/banzai/reference_parser/commit_parser_spec.rb b/spec/lib/banzai/reference_parser/commit_parser_spec.rb
index 412ffa77c36..583ce63a8ab 100644
--- a/spec/lib/banzai/reference_parser/commit_parser_spec.rb
+++ b/spec/lib/banzai/reference_parser/commit_parser_spec.rb
@@ -10,7 +10,9 @@ describe Banzai::ReferenceParser::CommitParser, lib: true do
describe '#nodes_visible_to_user' do
context 'when the link has a data-issue attribute' do
- before { link['data-commit'] = 123 }
+ before do
+ link['data-commit'] = 123
+ end
it_behaves_like "referenced feature visibility", "repository"
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 96e55b0997a..8c0f5d7df97 100644
--- a/spec/lib/banzai/reference_parser/commit_range_parser_spec.rb
+++ b/spec/lib/banzai/reference_parser/commit_range_parser_spec.rb
@@ -10,7 +10,9 @@ describe Banzai::ReferenceParser::CommitRangeParser, lib: true do
describe '#nodes_visible_to_user' do
context 'when the link has a data-issue attribute' do
- before { link['data-commit-range'] = '123..456' }
+ before do
+ link['data-commit-range'] = '123..456'
+ end
it_behaves_like "referenced feature visibility", "repository"
end
diff --git a/spec/lib/banzai/reference_parser/external_issue_parser_spec.rb b/spec/lib/banzai/reference_parser/external_issue_parser_spec.rb
index 0af36776a54..d212bbac619 100644
--- a/spec/lib/banzai/reference_parser/external_issue_parser_spec.rb
+++ b/spec/lib/banzai/reference_parser/external_issue_parser_spec.rb
@@ -10,7 +10,9 @@ describe Banzai::ReferenceParser::ExternalIssueParser, lib: true do
describe '#nodes_visible_to_user' do
context 'when the link has a data-issue attribute' do
- before { link['data-external-issue'] = 123 }
+ before do
+ link['data-external-issue'] = 123
+ end
levels = [ProjectFeature::DISABLED, ProjectFeature::PRIVATE, ProjectFeature::ENABLED]
diff --git a/spec/lib/banzai/reference_parser/label_parser_spec.rb b/spec/lib/banzai/reference_parser/label_parser_spec.rb
index 8c540d35ddd..ddd699f3c25 100644
--- a/spec/lib/banzai/reference_parser/label_parser_spec.rb
+++ b/spec/lib/banzai/reference_parser/label_parser_spec.rb
@@ -11,7 +11,9 @@ describe Banzai::ReferenceParser::LabelParser, lib: true do
describe '#nodes_visible_to_user' do
context 'when the link has a data-issue attribute' do
- before { link['data-label'] = label.id.to_s }
+ before do
+ link['data-label'] = label.id.to_s
+ end
it_behaves_like "referenced feature visibility", "issues", "merge_requests"
end
diff --git a/spec/lib/banzai/reference_parser/milestone_parser_spec.rb b/spec/lib/banzai/reference_parser/milestone_parser_spec.rb
index 2d4d589ae34..72d4f3bc18e 100644
--- a/spec/lib/banzai/reference_parser/milestone_parser_spec.rb
+++ b/spec/lib/banzai/reference_parser/milestone_parser_spec.rb
@@ -11,7 +11,9 @@ describe Banzai::ReferenceParser::MilestoneParser, lib: true do
describe '#nodes_visible_to_user' do
context 'when the link has a data-issue attribute' do
- before { link['data-milestone'] = milestone.id.to_s }
+ before do
+ link['data-milestone'] = milestone.id.to_s
+ end
it_behaves_like "referenced feature visibility", "issues", "merge_requests"
end
diff --git a/spec/lib/extracts_path_spec.rb b/spec/lib/extracts_path_spec.rb
index 33ab005667a..2b26a318583 100644
--- a/spec/lib/extracts_path_spec.rb
+++ b/spec/lib/extracts_path_spec.rb
@@ -77,7 +77,10 @@ describe ExtractsPath, lib: true do
context 'without a path' do
let(:params) { { ref: 'v1.0.0.atom' } }
- before { assign_ref_vars }
+
+ before do
+ assign_ref_vars
+ end
it 'sets the un-suffixed version as @ref' do
expect(@ref).to eq('v1.0.0')
diff --git a/spec/lib/gitlab/auth/unique_ips_limiter_spec.rb b/spec/lib/gitlab/auth/unique_ips_limiter_spec.rb
index 94dcddcc30c..fc72df575be 100644
--- a/spec/lib/gitlab/auth/unique_ips_limiter_spec.rb
+++ b/spec/lib/gitlab/auth/unique_ips_limiter_spec.rb
@@ -40,7 +40,9 @@ describe Gitlab::Auth::UniqueIpsLimiter, :redis, lib: true do
end
context 'allow 2 unique ips' do
- before { current_application_settings.update!(unique_ips_limit_per_user: 2) }
+ before do
+ current_application_settings.update!(unique_ips_limit_per_user: 2)
+ end
it 'blocks user trying to login from third ip' do
change_ip('ip1')
diff --git a/spec/lib/gitlab/badge/build/status_spec.rb b/spec/lib/gitlab/badge/build/status_spec.rb
index 3c5414701a7..6abf4ca46a9 100644
--- a/spec/lib/gitlab/badge/build/status_spec.rb
+++ b/spec/lib/gitlab/badge/build/status_spec.rb
@@ -29,7 +29,9 @@ describe Gitlab::Badge::Build::Status do
let!(:build) { create_build(project, sha, branch) }
context 'build success' do
- before { build.success! }
+ before do
+ build.success!
+ end
describe '#status' do
it 'is successful' do
@@ -39,7 +41,9 @@ describe Gitlab::Badge::Build::Status do
end
context 'build failed' do
- before { build.drop! }
+ before do
+ build.drop!
+ end
describe '#status' do
it 'failed' do
diff --git a/spec/lib/gitlab/chat_commands/presenters/issue_search_spec.rb b/spec/lib/gitlab/chat_commands/presenters/issue_search_spec.rb
index ec6d3e34a96..3799a324db4 100644
--- a/spec/lib/gitlab/chat_commands/presenters/issue_search_spec.rb
+++ b/spec/lib/gitlab/chat_commands/presenters/issue_search_spec.rb
@@ -4,7 +4,9 @@ describe Gitlab::ChatCommands::Presenters::IssueSearch do
let(:project) { create(:empty_project) }
let(:message) { subject[:text] }
- before { create_list(:issue, 2, project: project) }
+ before do
+ create_list(:issue, 2, project: project)
+ end
subject { described_class.new(project.issues).present }
diff --git a/spec/lib/gitlab/checks/change_access_spec.rb b/spec/lib/gitlab/checks/change_access_spec.rb
index c0c309d8179..643e590438a 100644
--- a/spec/lib/gitlab/checks/change_access_spec.rb
+++ b/spec/lib/gitlab/checks/change_access_spec.rb
@@ -20,7 +20,9 @@ describe Gitlab::Checks::ChangeAccess, lib: true do
).exec
end
- before { project.add_developer(user) }
+ before do
+ project.add_developer(user)
+ end
context 'without failed checks' do
it "doesn't raise an error" do
@@ -50,7 +52,9 @@ describe Gitlab::Checks::ChangeAccess, lib: true do
let!(:protected_tag) { create(:protected_tag, project: project, name: 'v*') }
context 'as master' do
- before { project.add_master(user) }
+ before do
+ project.add_master(user)
+ end
context 'deletion' do
let(:oldrev) { 'be93687618e4b132087f430a4d8fc3a609c9b77c' }
diff --git a/spec/lib/gitlab/ci/config/entry/cache_spec.rb b/spec/lib/gitlab/ci/config/entry/cache_spec.rb
index 2ed120f356a..878b1d6b862 100644
--- a/spec/lib/gitlab/ci/config/entry/cache_spec.rb
+++ b/spec/lib/gitlab/ci/config/entry/cache_spec.rb
@@ -4,7 +4,9 @@ describe Gitlab::Ci::Config::Entry::Cache do
let(:entry) { described_class.new(config) }
describe 'validations' do
- before { entry.compose! }
+ before do
+ entry.compose!
+ end
context 'when entry config value is correct' do
let(:config) do
diff --git a/spec/lib/gitlab/ci/config/entry/environment_spec.rb b/spec/lib/gitlab/ci/config/entry/environment_spec.rb
index c330e609337..3c0007f4d57 100644
--- a/spec/lib/gitlab/ci/config/entry/environment_spec.rb
+++ b/spec/lib/gitlab/ci/config/entry/environment_spec.rb
@@ -3,7 +3,9 @@ require 'spec_helper'
describe Gitlab::Ci::Config::Entry::Environment do
let(:entry) { described_class.new(config) }
- before { entry.compose! }
+ before do
+ entry.compose!
+ end
context 'when configuration is a string' do
let(:config) { 'production' }
diff --git a/spec/lib/gitlab/ci/config/entry/global_spec.rb b/spec/lib/gitlab/ci/config/entry/global_spec.rb
index e5f85c712ca..293f112b2b0 100644
--- a/spec/lib/gitlab/ci/config/entry/global_spec.rb
+++ b/spec/lib/gitlab/ci/config/entry/global_spec.rb
@@ -33,7 +33,9 @@ describe Gitlab::Ci::Config::Entry::Global do
end
describe '#compose!' do
- before { global.compose! }
+ before do
+ global.compose!
+ end
it 'creates nodes hash' do
expect(global.descendants).to be_an Array
@@ -79,7 +81,9 @@ describe Gitlab::Ci::Config::Entry::Global do
end
context 'when composed' do
- before { global.compose! }
+ before do
+ global.compose!
+ end
describe '#errors' do
it 'has no errors' do
@@ -175,7 +179,9 @@ describe Gitlab::Ci::Config::Entry::Global do
end
context 'when most of entires not defined' do
- before { global.compose! }
+ before do
+ global.compose!
+ end
let(:hash) do
{ cache: { key: 'a' }, rspec: { script: %w[ls] } }
@@ -218,7 +224,9 @@ describe Gitlab::Ci::Config::Entry::Global do
# details.
#
context 'when entires specified but not defined' do
- before { global.compose! }
+ before do
+ global.compose!
+ end
let(:hash) do
{ variables: nil, rspec: { script: 'rspec' } }
@@ -233,7 +241,9 @@ describe Gitlab::Ci::Config::Entry::Global do
end
context 'when configuration is not valid' do
- before { global.compose! }
+ before do
+ global.compose!
+ end
context 'when before script is not an array' do
let(:hash) do
@@ -297,7 +307,9 @@ describe Gitlab::Ci::Config::Entry::Global do
end
describe '#[]' do
- before { global.compose! }
+ before do
+ global.compose!
+ end
let(:hash) do
{ cache: { key: 'a' }, rspec: { script: 'ls' } }
diff --git a/spec/lib/gitlab/ci/config/entry/job_spec.rb b/spec/lib/gitlab/ci/config/entry/job_spec.rb
index 8dc94a4eb33..92cba689f47 100644
--- a/spec/lib/gitlab/ci/config/entry/job_spec.rb
+++ b/spec/lib/gitlab/ci/config/entry/job_spec.rb
@@ -18,7 +18,9 @@ describe Gitlab::Ci::Config::Entry::Job do
end
describe 'validations' do
- before { entry.compose! }
+ before do
+ entry.compose!
+ end
context 'when entry config value is correct' do
let(:config) { { script: 'rspec' } }
@@ -97,7 +99,9 @@ describe Gitlab::Ci::Config::Entry::Job do
let(:deps) { double('deps', '[]' => unspecified) }
context 'when job config overrides global config' do
- before { entry.compose!(deps) }
+ before do
+ entry.compose!(deps)
+ end
let(:config) do
{ script: 'rspec', image: 'some_image', cache: { key: 'test' } }
@@ -125,10 +129,14 @@ describe Gitlab::Ci::Config::Entry::Job do
end
context 'when composed' do
- before { entry.compose! }
+ before do
+ entry.compose!
+ end
describe '#value' do
- before { entry.compose! }
+ before do
+ entry.compose!
+ end
context 'when entry is correct' do
let(:config) do
diff --git a/spec/lib/gitlab/ci/config/entry/jobs_spec.rb b/spec/lib/gitlab/ci/config/entry/jobs_spec.rb
index 7d104372ac6..c0a2b6517e3 100644
--- a/spec/lib/gitlab/ci/config/entry/jobs_spec.rb
+++ b/spec/lib/gitlab/ci/config/entry/jobs_spec.rb
@@ -4,7 +4,9 @@ describe Gitlab::Ci::Config::Entry::Jobs do
let(:entry) { described_class.new(config) }
describe 'validations' do
- before { entry.compose! }
+ before do
+ entry.compose!
+ end
context 'when entry config value is correct' do
let(:config) { { rspec: { script: 'rspec' } } }
@@ -48,7 +50,9 @@ describe Gitlab::Ci::Config::Entry::Jobs do
end
context 'when valid job entries composed' do
- before { entry.compose! }
+ before do
+ entry.compose!
+ end
let(:config) do
{ rspec: { script: 'rspec' },
diff --git a/spec/lib/gitlab/ci/config/entry/service_spec.rb b/spec/lib/gitlab/ci/config/entry/service_spec.rb
index 2376de74554..7202fe525e4 100644
--- a/spec/lib/gitlab/ci/config/entry/service_spec.rb
+++ b/spec/lib/gitlab/ci/config/entry/service_spec.rb
@@ -3,7 +3,9 @@ require 'spec_helper'
describe Gitlab::Ci::Config::Entry::Service do
let(:entry) { described_class.new(config) }
- before { entry.compose! }
+ before do
+ entry.compose!
+ end
context 'when configuration is a string' do
let(:config) { 'postgresql:9.5' }
diff --git a/spec/lib/gitlab/ci/config/entry/services_spec.rb b/spec/lib/gitlab/ci/config/entry/services_spec.rb
index b32e52f8f26..7c4319aee63 100644
--- a/spec/lib/gitlab/ci/config/entry/services_spec.rb
+++ b/spec/lib/gitlab/ci/config/entry/services_spec.rb
@@ -3,7 +3,9 @@ require 'spec_helper'
describe Gitlab::Ci::Config::Entry::Services do
let(:entry) { described_class.new(config) }
- before { entry.compose! }
+ before do
+ entry.compose!
+ end
context 'when configuration is valid' do
let(:config) { ['postgresql:9.5', { name: 'postgresql:9.1', alias: 'postgres_old' }] }
diff --git a/spec/lib/gitlab/ci/status/build/cancelable_spec.rb b/spec/lib/gitlab/ci/status/build/cancelable_spec.rb
index 8ad9b7cdf07..114d2490490 100644
--- a/spec/lib/gitlab/ci/status/build/cancelable_spec.rb
+++ b/spec/lib/gitlab/ci/status/build/cancelable_spec.rb
@@ -47,7 +47,9 @@ describe Gitlab::Ci::Status::Build::Cancelable do
describe '#has_action?' do
context 'when user is allowed to update build' do
- before { build.project.team << [user, :developer] }
+ before do
+ build.project.team << [user, :developer]
+ end
it { is_expected.to have_action }
end
diff --git a/spec/lib/gitlab/ci/status/build/common_spec.rb b/spec/lib/gitlab/ci/status/build/common_spec.rb
index 72bd7c4eb93..03d1f46b517 100644
--- a/spec/lib/gitlab/ci/status/build/common_spec.rb
+++ b/spec/lib/gitlab/ci/status/build/common_spec.rb
@@ -17,13 +17,17 @@ describe Gitlab::Ci::Status::Build::Common do
describe '#has_details?' do
context 'when user has access to read build' do
- before { project.team << [user, :developer] }
+ before do
+ project.team << [user, :developer]
+ end
it { is_expected.to have_details }
end
context 'when user does not have access to read build' do
- before { project.update(public_builds: false) }
+ before do
+ project.update(public_builds: false)
+ end
it { is_expected.not_to have_details }
end
diff --git a/spec/lib/gitlab/ci/status/build/factory_spec.rb b/spec/lib/gitlab/ci/status/build/factory_spec.rb
index 3f30b2c38f2..c8a97016f20 100644
--- a/spec/lib/gitlab/ci/status/build/factory_spec.rb
+++ b/spec/lib/gitlab/ci/status/build/factory_spec.rb
@@ -6,7 +6,9 @@ describe Gitlab::Ci::Status::Build::Factory do
let(:status) { factory.fabricate! }
let(:factory) { described_class.new(build, user) }
- before { project.team << [user, :developer] }
+ before do
+ project.team << [user, :developer]
+ end
context 'when build is successful' do
let(:build) { create(:ci_build, :success) }
diff --git a/spec/lib/gitlab/ci/status/build/play_spec.rb b/spec/lib/gitlab/ci/status/build/play_spec.rb
index 0e15a5f3c6b..32b2e62e4e0 100644
--- a/spec/lib/gitlab/ci/status/build/play_spec.rb
+++ b/spec/lib/gitlab/ci/status/build/play_spec.rb
@@ -28,7 +28,9 @@ describe Gitlab::Ci::Status::Build::Play do
end
context 'when user can not push to the branch' do
- before { build.project.add_developer(user) }
+ before do
+ build.project.add_developer(user)
+ end
it { is_expected.not_to have_action }
end
diff --git a/spec/lib/gitlab/ci/status/build/retryable_spec.rb b/spec/lib/gitlab/ci/status/build/retryable_spec.rb
index 2db0f8d29bd..099d873fc01 100644
--- a/spec/lib/gitlab/ci/status/build/retryable_spec.rb
+++ b/spec/lib/gitlab/ci/status/build/retryable_spec.rb
@@ -47,7 +47,9 @@ describe Gitlab::Ci::Status::Build::Retryable do
describe '#has_action?' do
context 'when user is allowed to update build' do
- before { build.project.team << [user, :developer] }
+ before do
+ build.project.team << [user, :developer]
+ end
it { is_expected.to have_action }
end
diff --git a/spec/lib/gitlab/ci/status/build/stop_spec.rb b/spec/lib/gitlab/ci/status/build/stop_spec.rb
index 8d021c35a69..23902f26b1a 100644
--- a/spec/lib/gitlab/ci/status/build/stop_spec.rb
+++ b/spec/lib/gitlab/ci/status/build/stop_spec.rb
@@ -19,7 +19,9 @@ describe Gitlab::Ci::Status::Build::Stop do
describe '#has_action?' do
context 'when user is allowed to update build' do
- before { build.project.team << [user, :developer] }
+ before do
+ build.project.team << [user, :developer]
+ end
it { is_expected.to have_action }
end
diff --git a/spec/lib/gitlab/ci/status/external/common_spec.rb b/spec/lib/gitlab/ci/status/external/common_spec.rb
index e58f5d8d4df..b38fbee2486 100644
--- a/spec/lib/gitlab/ci/status/external/common_spec.rb
+++ b/spec/lib/gitlab/ci/status/external/common_spec.rb
@@ -28,7 +28,9 @@ describe Gitlab::Ci::Status::External::Common do
describe '#has_details?' do
context 'when user has access to read commit status' do
- before { project.team << [user, :developer] }
+ before do
+ project.team << [user, :developer]
+ end
it { is_expected.to have_details }
end
diff --git a/spec/lib/gitlab/ci/status/pipeline/common_spec.rb b/spec/lib/gitlab/ci/status/pipeline/common_spec.rb
index d665674bf70..f5fd31e8d03 100644
--- a/spec/lib/gitlab/ci/status/pipeline/common_spec.rb
+++ b/spec/lib/gitlab/ci/status/pipeline/common_spec.rb
@@ -17,7 +17,9 @@ describe Gitlab::Ci::Status::Pipeline::Common do
describe '#has_details?' do
context 'when user has access to read pipeline' do
- before { project.team << [user, :developer] }
+ before do
+ project.team << [user, :developer]
+ end
it { is_expected.to have_details }
end
diff --git a/spec/lib/gitlab/database_spec.rb b/spec/lib/gitlab/database_spec.rb
index 9b1d66a1b1c..26e5d73d333 100644
--- a/spec/lib/gitlab/database_spec.rb
+++ b/spec/lib/gitlab/database_spec.rb
@@ -53,14 +53,18 @@ describe Gitlab::Database, lib: true do
describe '.nulls_last_order' do
context 'when using PostgreSQL' do
- before { expect(described_class).to receive(:postgresql?).and_return(true) }
+ before do
+ expect(described_class).to receive(:postgresql?).and_return(true)
+ end
it { expect(described_class.nulls_last_order('column', 'ASC')).to eq 'column ASC NULLS LAST'}
it { expect(described_class.nulls_last_order('column', 'DESC')).to eq 'column DESC NULLS LAST'}
end
context 'when using MySQL' do
- before { expect(described_class).to receive(:postgresql?).and_return(false) }
+ before do
+ expect(described_class).to receive(:postgresql?).and_return(false)
+ end
it { expect(described_class.nulls_last_order('column', 'ASC')).to eq 'column IS NULL, column ASC'}
it { expect(described_class.nulls_last_order('column', 'DESC')).to eq 'column DESC'}
@@ -69,14 +73,18 @@ describe Gitlab::Database, lib: true do
describe '.nulls_first_order' do
context 'when using PostgreSQL' do
- before { expect(described_class).to receive(:postgresql?).and_return(true) }
+ before do
+ expect(described_class).to receive(:postgresql?).and_return(true)
+ end
it { expect(described_class.nulls_first_order('column', 'ASC')).to eq 'column ASC NULLS FIRST'}
it { expect(described_class.nulls_first_order('column', 'DESC')).to eq 'column DESC NULLS FIRST'}
end
context 'when using MySQL' do
- before { expect(described_class).to receive(:postgresql?).and_return(false) }
+ before do
+ expect(described_class).to receive(:postgresql?).and_return(false)
+ end
it { expect(described_class.nulls_first_order('column', 'ASC')).to eq 'column ASC'}
it { expect(described_class.nulls_first_order('column', 'DESC')).to eq 'column IS NULL, column DESC'}
diff --git a/spec/lib/gitlab/diff/file_spec.rb b/spec/lib/gitlab/diff/file_spec.rb
index a9953bb0d01..f289131cc3a 100644
--- a/spec/lib/gitlab/diff/file_spec.rb
+++ b/spec/lib/gitlab/diff/file_spec.rb
@@ -92,4 +92,305 @@ describe Gitlab::Diff::File, lib: true do
expect(diff_file.diffable?).to be_falsey
end
end
+
+ describe '#content_changed?' do
+ context 'when created' do
+ let(:commit) { project.commit('33f3729a45c02fc67d00adb1b8bca394b0e761d9') }
+ let(:diff_file) { commit.diffs.diff_file_with_new_path('files/images/6049019_460s.jpg') }
+
+ it 'returns false' do
+ expect(diff_file.content_changed?).to be_falsey
+ end
+ end
+
+ context 'when deleted' do
+ let(:commit) { project.commit('d59c60028b053793cecfb4022de34602e1a9218e') }
+ let(:diff_file) { commit.diffs.diff_file_with_old_path('files/js/commit.js.coffee') }
+
+ it 'returns false' do
+ expect(diff_file.content_changed?).to be_falsey
+ end
+ end
+
+ context 'when renamed' do
+ let(:commit) { project.commit('6907208d755b60ebeacb2e9dfea74c92c3449a1f') }
+ let(:diff_file) { commit.diffs.diff_file_with_new_path('files/js/commit.coffee') }
+
+ before do
+ allow(diff_file.new_blob).to receive(:id).and_return(diff_file.old_blob.id)
+ end
+
+ it 'returns false' do
+ expect(diff_file.content_changed?).to be_falsey
+ end
+ end
+
+ context 'when content changed' do
+ context 'when binary' do
+ let(:commit) { project.commit('2f63565e7aac07bcdadb654e253078b727143ec4') }
+ let(:diff_file) { commit.diffs.diff_file_with_new_path('files/images/6049019_460s.jpg') }
+
+ it 'returns true' do
+ expect(diff_file.content_changed?).to be_truthy
+ end
+ end
+
+ context 'when not binary' do
+ let(:commit) { project.commit('570e7b2abdd848b95f2f578043fc23bd6f6fd24d') }
+ let(:diff_file) { commit.diffs.diff_file_with_new_path('files/ruby/popen.rb') }
+
+ it 'returns true' do
+ expect(diff_file.content_changed?).to be_truthy
+ end
+ end
+ end
+ end
+
+ describe '#simple_viewer' do
+ context 'when the file is not diffable' do
+ before do
+ allow(diff_file).to receive(:diffable?).and_return(false)
+ end
+
+ it 'returns a Not Diffable viewer' do
+ expect(diff_file.simple_viewer).to be_a(DiffViewer::NotDiffable)
+ end
+ end
+
+ context 'when the content changed' do
+ context 'when the file represented by the diff file is binary' do
+ before do
+ allow(diff_file).to receive(:raw_binary?).and_return(true)
+ end
+
+ it 'returns a No Preview viewer' do
+ expect(diff_file.simple_viewer).to be_a(DiffViewer::NoPreview)
+ end
+ end
+
+ context 'when the diff file old and new blob types are different' do
+ before do
+ allow(diff_file).to receive(:different_type?).and_return(true)
+ end
+
+ it 'returns a No Preview viewer' do
+ expect(diff_file.simple_viewer).to be_a(DiffViewer::NoPreview)
+ end
+ end
+
+ context 'when the file represented by the diff file is text-based' do
+ it 'returns a text viewer' do
+ expect(diff_file.simple_viewer).to be_a(DiffViewer::Text)
+ end
+ end
+ end
+
+ context 'when created' do
+ let(:commit) { project.commit('913c66a37b4a45b9769037c55c2d238bd0942d2e') }
+ let(:diff_file) { commit.diffs.diff_file_with_new_path('files/ruby/popen.rb') }
+
+ before do
+ allow(diff_file).to receive(:content_changed?).and_return(nil)
+ end
+
+ context 'when the file represented by the diff file is binary' do
+ before do
+ allow(diff_file).to receive(:raw_binary?).and_return(true)
+ end
+
+ it 'returns an Added viewer' do
+ expect(diff_file.simple_viewer).to be_a(DiffViewer::Added)
+ end
+ end
+
+ context 'when the diff file old and new blob types are different' do
+ before do
+ allow(diff_file).to receive(:different_type?).and_return(true)
+ end
+
+ it 'returns an Added viewer' do
+ expect(diff_file.simple_viewer).to be_a(DiffViewer::Added)
+ end
+ end
+
+ context 'when the file represented by the diff file is text-based' do
+ it 'returns a text viewer' do
+ expect(diff_file.simple_viewer).to be_a(DiffViewer::Text)
+ end
+ end
+ end
+
+ context 'when deleted' do
+ let(:commit) { project.commit('d59c60028b053793cecfb4022de34602e1a9218e') }
+ let(:diff_file) { commit.diffs.diff_file_with_old_path('files/js/commit.js.coffee') }
+
+ before do
+ allow(diff_file).to receive(:content_changed?).and_return(nil)
+ end
+
+ context 'when the file represented by the diff file is binary' do
+ before do
+ allow(diff_file).to receive(:raw_binary?).and_return(true)
+ end
+
+ it 'returns a Deleted viewer' do
+ expect(diff_file.simple_viewer).to be_a(DiffViewer::Deleted)
+ end
+ end
+
+ context 'when the diff file old and new blob types are different' do
+ before do
+ allow(diff_file).to receive(:different_type?).and_return(true)
+ end
+
+ it 'returns a Deleted viewer' do
+ expect(diff_file.simple_viewer).to be_a(DiffViewer::Deleted)
+ end
+ end
+
+ context 'when the file represented by the diff file is text-based' do
+ it 'returns a text viewer' do
+ expect(diff_file.simple_viewer).to be_a(DiffViewer::Text)
+ end
+ end
+ end
+
+ context 'when renamed' do
+ let(:commit) { project.commit('6907208d755b60ebeacb2e9dfea74c92c3449a1f') }
+ let(:diff_file) { commit.diffs.diff_file_with_new_path('files/js/commit.coffee') }
+
+ before do
+ allow(diff_file).to receive(:content_changed?).and_return(nil)
+ end
+
+ it 'returns a Renamed viewer' do
+ expect(diff_file.simple_viewer).to be_a(DiffViewer::Renamed)
+ end
+ end
+
+ context 'when mode changed' do
+ before do
+ allow(diff_file).to receive(:content_changed?).and_return(nil)
+ allow(diff_file).to receive(:mode_changed?).and_return(true)
+ end
+
+ it 'returns a Mode Changed viewer' do
+ expect(diff_file.simple_viewer).to be_a(DiffViewer::ModeChanged)
+ end
+ end
+ end
+
+ describe '#rich_viewer' do
+ let(:commit) { project.commit('2f63565e7aac07bcdadb654e253078b727143ec4') }
+ let(:diff_file) { commit.diffs.diff_file_with_new_path('files/images/6049019_460s.jpg') }
+
+ context 'when the diff file has a matching viewer' do
+ context 'when the diff file content did not change' do
+ before do
+ allow(diff_file).to receive(:content_changed?).and_return(false)
+ end
+
+ it 'returns nil' do
+ expect(diff_file.rich_viewer).to be_nil
+ end
+ end
+
+ context 'when the diff file is not diffable' do
+ before do
+ allow(diff_file).to receive(:diffable?).and_return(false)
+ end
+
+ it 'returns nil' do
+ expect(diff_file.rich_viewer).to be_nil
+ end
+ end
+
+ context 'when the diff file old and new blob types are different' do
+ before do
+ allow(diff_file).to receive(:different_type?).and_return(true)
+ end
+
+ it 'returns nil' do
+ expect(diff_file.rich_viewer).to be_nil
+ end
+ end
+
+ context 'when the diff file has an external storage error' do
+ before do
+ allow(diff_file).to receive(:external_storage_error?).and_return(true)
+ end
+
+ it 'returns nil' do
+ expect(diff_file.rich_viewer).to be_nil
+ end
+ end
+
+ context 'when everything is right' do
+ it 'returns the viewer' do
+ expect(diff_file.rich_viewer).to be_a(DiffViewer::Image)
+ end
+ end
+ end
+
+ context 'when the diff file does not have a matching viewer' do
+ let(:commit) { project.commit('570e7b2abdd848b95f2f578043fc23bd6f6fd24d') }
+ let(:diff_file) { commit.diffs.diff_file_with_new_path('files/ruby/popen.rb') }
+
+ it 'returns nil' do
+ expect(diff_file.rich_viewer).to be_nil
+ end
+ end
+ end
+
+ describe '#rendered_as_text?' do
+ context 'when the simple viewer is text-based' do
+ let(:commit) { project.commit('570e7b2abdd848b95f2f578043fc23bd6f6fd24d') }
+ let(:diff_file) { commit.diffs.diff_file_with_new_path('files/ruby/popen.rb') }
+
+ context 'when ignoring errors' do
+ context 'when the viewer has render errors' do
+ before do
+ diff_file.diff.too_large!
+ end
+
+ it 'returns true' do
+ expect(diff_file.rendered_as_text?).to be_truthy
+ end
+ end
+
+ context "when the viewer doesn't have render errors" do
+ it 'returns true' do
+ expect(diff_file.rendered_as_text?).to be_truthy
+ end
+ end
+ end
+
+ context 'when not ignoring errors' do
+ context 'when the viewer has render errors' do
+ before do
+ diff_file.diff.too_large!
+ end
+
+ it 'returns false' do
+ expect(diff_file.rendered_as_text?(ignore_errors: false)).to be_falsey
+ end
+ end
+
+ context "when the viewer doesn't have render errors" do
+ it 'returns true' do
+ expect(diff_file.rendered_as_text?(ignore_errors: false)).to be_truthy
+ end
+ end
+ end
+ end
+
+ context 'when the simple viewer is binary' do
+ let(:commit) { project.commit('2f63565e7aac07bcdadb654e253078b727143ec4') }
+ let(:diff_file) { commit.diffs.diff_file_with_new_path('files/images/6049019_460s.jpg') }
+
+ it 'returns false' do
+ expect(diff_file.rendered_as_text?).to be_falsey
+ end
+ end
+ end
end
diff --git a/spec/lib/gitlab/etag_caching/middleware_spec.rb b/spec/lib/gitlab/etag_caching/middleware_spec.rb
index 3c6ef7c7ccb..4acf4f047f1 100644
--- a/spec/lib/gitlab/etag_caching/middleware_spec.rb
+++ b/spec/lib/gitlab/etag_caching/middleware_spec.rb
@@ -15,13 +15,13 @@ describe Gitlab::EtagCaching::Middleware do
end
it 'does not add ETag header' do
- _, headers, _ = middleware.call(build_env(path, if_none_match))
+ _, headers, _ = middleware.call(build_request(path, if_none_match))
expect(headers['ETag']).to be_nil
end
it 'passes status code from app' do
- status, _, _ = middleware.call(build_env(path, if_none_match))
+ status, _, _ = middleware.call(build_request(path, if_none_match))
expect(status).to eq app_status_code
end
@@ -39,7 +39,7 @@ describe Gitlab::EtagCaching::Middleware do
expect_any_instance_of(Gitlab::EtagCaching::Store)
.to receive(:touch).and_return('123')
- middleware.call(build_env(path, if_none_match))
+ middleware.call(build_request(path, if_none_match))
end
context 'when If-None-Match header was specified' do
@@ -51,7 +51,7 @@ describe Gitlab::EtagCaching::Middleware do
expect(Gitlab::Metrics).to receive(:add_event)
.with(:etag_caching_key_not_found, endpoint: 'issue_notes')
- middleware.call(build_env(path, if_none_match))
+ middleware.call(build_request(path, if_none_match))
end
end
end
@@ -65,7 +65,7 @@ describe Gitlab::EtagCaching::Middleware do
end
it 'returns this value as header' do
- _, headers, _ = middleware.call(build_env(path, if_none_match))
+ _, headers, _ = middleware.call(build_request(path, if_none_match))
expect(headers['ETag']).to eq 'W/"123"'
end
@@ -82,17 +82,17 @@ describe Gitlab::EtagCaching::Middleware do
it 'does not call app' do
expect(app).not_to receive(:call)
- middleware.call(build_env(path, if_none_match))
+ middleware.call(build_request(path, if_none_match))
end
it 'returns status code 304' do
- status, _, _ = middleware.call(build_env(path, if_none_match))
+ status, _, _ = middleware.call(build_request(path, if_none_match))
expect(status).to eq 304
end
it 'returns empty body' do
- _, _, body = middleware.call(build_env(path, if_none_match))
+ _, _, body = middleware.call(build_request(path, if_none_match))
expect(body).to be_empty
end
@@ -103,7 +103,7 @@ describe Gitlab::EtagCaching::Middleware do
expect(Gitlab::Metrics).to receive(:add_event)
.with(:etag_caching_cache_hit, endpoint: 'issue_notes')
- middleware.call(build_env(path, if_none_match))
+ middleware.call(build_request(path, if_none_match))
end
context 'when polling is disabled' do
@@ -113,7 +113,7 @@ describe Gitlab::EtagCaching::Middleware do
end
it 'returns status code 429' do
- status, _, _ = middleware.call(build_env(path, if_none_match))
+ status, _, _ = middleware.call(build_request(path, if_none_match))
expect(status).to eq 429
end
@@ -131,7 +131,7 @@ describe Gitlab::EtagCaching::Middleware do
it 'calls app' do
expect(app).to receive(:call).and_return([app_status_code, {}, ['body']])
- middleware.call(build_env(path, if_none_match))
+ middleware.call(build_request(path, if_none_match))
end
it 'tracks "etag_caching_resource_changed" event' do
@@ -142,7 +142,7 @@ describe Gitlab::EtagCaching::Middleware do
expect(Gitlab::Metrics).to receive(:add_event)
.with(:etag_caching_resource_changed, endpoint: 'issue_notes')
- middleware.call(build_env(path, if_none_match))
+ middleware.call(build_request(path, if_none_match))
end
end
@@ -160,7 +160,7 @@ describe Gitlab::EtagCaching::Middleware do
expect(Gitlab::Metrics).to receive(:add_event)
.with(:etag_caching_header_missing, endpoint: 'issue_notes')
- middleware.call(build_env(path, if_none_match))
+ middleware.call(build_request(path, if_none_match))
end
end
@@ -192,10 +192,7 @@ describe Gitlab::EtagCaching::Middleware do
.to receive(:get).and_return(value)
end
- def build_env(path, if_none_match)
- {
- 'PATH_INFO' => path,
- 'HTTP_IF_NONE_MATCH' => if_none_match
- }
+ def build_request(path, if_none_match)
+ { 'PATH_INFO' => path, 'HTTP_IF_NONE_MATCH' => if_none_match }
end
end
diff --git a/spec/lib/gitlab/etag_caching/router_spec.rb b/spec/lib/gitlab/etag_caching/router_spec.rb
index 2bb40827fcf..f69cb502ca6 100644
--- a/spec/lib/gitlab/etag_caching/router_spec.rb
+++ b/spec/lib/gitlab/etag_caching/router_spec.rb
@@ -2,115 +2,91 @@ require 'spec_helper'
describe Gitlab::EtagCaching::Router do
it 'matches issue notes endpoint' do
- request = build_request(
+ result = described_class.match(
'/my-group/and-subgroup/here-comes-the-project/noteable/issue/1/notes'
)
- result = described_class.match(request)
-
expect(result).to be_present
expect(result.name).to eq 'issue_notes'
end
it 'matches issue title endpoint' do
- request = build_request(
+ result = described_class.match(
'/my-group/my-project/issues/123/realtime_changes'
)
- result = described_class.match(request)
-
expect(result).to be_present
expect(result.name).to eq 'issue_title'
end
it 'matches project pipelines endpoint' do
- request = build_request(
+ result = described_class.match(
'/my-group/my-project/pipelines.json'
)
- result = described_class.match(request)
-
expect(result).to be_present
expect(result.name).to eq 'project_pipelines'
end
it 'matches commit pipelines endpoint' do
- request = build_request(
+ result = described_class.match(
'/my-group/my-project/commit/aa8260d253a53f73f6c26c734c72fdd600f6e6d4/pipelines.json'
)
- result = described_class.match(request)
-
expect(result).to be_present
expect(result.name).to eq 'commit_pipelines'
end
it 'matches new merge request pipelines endpoint' do
- request = build_request(
+ result = described_class.match(
'/my-group/my-project/merge_requests/new.json'
)
- result = described_class.match(request)
-
expect(result).to be_present
expect(result.name).to eq 'new_merge_request_pipelines'
end
it 'matches merge request pipelines endpoint' do
- request = build_request(
+ result = described_class.match(
'/my-group/my-project/merge_requests/234/pipelines.json'
)
- result = described_class.match(request)
-
expect(result).to be_present
expect(result.name).to eq 'merge_request_pipelines'
end
it 'matches build endpoint' do
- request = build_request(
+ result = described_class.match(
'/my-group/my-project/builds/234.json'
)
- result = described_class.match(request)
-
expect(result).to be_present
expect(result.name).to eq 'project_build'
end
it 'does not match blob with confusing name' do
- request = build_request(
+ result = described_class.match(
'/my-group/my-project/blob/master/pipelines.json'
)
- result = described_class.match(request)
-
expect(result).to be_blank
end
it 'matches the environments path' do
- request = build_request(
+ result = described_class.match(
'/my-group/my-project/environments.json'
)
- result = described_class.match(request)
expect(result).to be_present
-
expect(result.name).to eq 'environments'
end
it 'matches pipeline#show endpoint' do
- request = build_request(
+ result = described_class.match(
'/my-group/my-project/pipelines/2.json'
)
- result = described_class.match(request)
-
expect(result).to be_present
expect(result.name).to eq 'project_pipeline'
end
-
- def build_request(path)
- double(path_info: path)
- end
end
diff --git a/spec/lib/gitlab/gfm/reference_rewriter_spec.rb b/spec/lib/gitlab/gfm/reference_rewriter_spec.rb
index 5d416c9eec3..eaec699ad90 100644
--- a/spec/lib/gitlab/gfm/reference_rewriter_spec.rb
+++ b/spec/lib/gitlab/gfm/reference_rewriter_spec.rb
@@ -6,7 +6,9 @@ describe Gitlab::Gfm::ReferenceRewriter do
let(:new_project) { create(:empty_project, name: 'new-project') }
let(:user) { create(:user) }
- before { old_project.team << [user, :reporter] }
+ before do
+ old_project.team << [user, :reporter]
+ end
describe '#rewrite' do
subject do
diff --git a/spec/lib/gitlab/git/repository_spec.rb b/spec/lib/gitlab/git/repository_spec.rb
index e1e4aa9fde9..eee4c9eab6d 100644
--- a/spec/lib/gitlab/git/repository_spec.rb
+++ b/spec/lib/gitlab/git/repository_spec.rb
@@ -16,7 +16,9 @@ describe Gitlab::Git::Repository, seed_helper: true do
describe '#root_ref' do
context 'with gitaly disabled' do
- before { allow(Gitlab::GitalyClient).to receive(:feature_enabled?).and_return(false) }
+ before do
+ allow(Gitlab::GitalyClient).to receive(:feature_enabled?).and_return(false)
+ end
it 'calls #discover_default_branch' do
expect(repository).to receive(:discover_default_branch)
@@ -25,8 +27,13 @@ describe Gitlab::Git::Repository, seed_helper: true do
end
context 'with gitaly enabled' do
- before { stub_gitaly }
- after { Gitlab::GitalyClient.clear_stubs! }
+ before do
+ stub_gitaly
+ end
+
+ after do
+ Gitlab::GitalyClient.clear_stubs!
+ end
it 'gets the branch name from GitalyClient' do
expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:default_branch_name)
@@ -120,8 +127,13 @@ describe Gitlab::Git::Repository, seed_helper: true do
it { is_expected.not_to include("branch-from-space") }
context 'with gitaly enabled' do
- before { stub_gitaly }
- after { Gitlab::GitalyClient.clear_stubs! }
+ before do
+ stub_gitaly
+ end
+
+ after do
+ Gitlab::GitalyClient.clear_stubs!
+ end
it 'gets the branch names from GitalyClient' do
expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:branch_names)
@@ -158,8 +170,13 @@ describe Gitlab::Git::Repository, seed_helper: true do
it { is_expected.not_to include("v5.0.0") }
context 'with gitaly enabled' do
- before { stub_gitaly }
- after { Gitlab::GitalyClient.clear_stubs! }
+ before do
+ stub_gitaly
+ end
+
+ after do
+ Gitlab::GitalyClient.clear_stubs!
+ end
it 'gets the tag names from GitalyClient' do
expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:tag_names)
@@ -1280,8 +1297,13 @@ describe Gitlab::Git::Repository, seed_helper: true do
end
context 'with gitaly enabled' do
- before { stub_gitaly }
- after { Gitlab::GitalyClient.clear_stubs! }
+ before do
+ stub_gitaly
+ end
+
+ after do
+ Gitlab::GitalyClient.clear_stubs!
+ end
it 'gets the branches from GitalyClient' do
expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:local_branches).
diff --git a/spec/lib/gitlab/git_access_spec.rb b/spec/lib/gitlab/git_access_spec.rb
index 36d1d777583..3dcc20c48e8 100644
--- a/spec/lib/gitlab/git_access_spec.rb
+++ b/spec/lib/gitlab/git_access_spec.rb
@@ -60,7 +60,9 @@ describe Gitlab::GitAccess, lib: true do
let(:actor) { deploy_key }
context 'when the DeployKey has access to the project' do
- before { deploy_key.projects << project }
+ before do
+ deploy_key.projects << project
+ end
it 'allows pull access' do
expect { pull_access_check }.not_to raise_error
@@ -84,7 +86,9 @@ describe Gitlab::GitAccess, lib: true do
context 'when actor is a User' do
context 'when the User can read the project' do
- before { project.team << [user, :master] }
+ before do
+ project.team << [user, :master]
+ end
it 'allows pull access' do
expect { pull_access_check }.not_to raise_error
@@ -159,7 +163,9 @@ describe Gitlab::GitAccess, lib: true do
end
describe '#check_command_disabled!' do
- before { project.team << [user, :master] }
+ before do
+ project.team << [user, :master]
+ end
context 'over http' do
let(:protocol) { 'http' }
@@ -196,7 +202,9 @@ describe Gitlab::GitAccess, lib: true do
describe '#check_download_access!' do
describe 'master permissions' do
- before { project.team << [user, :master] }
+ before do
+ project.team << [user, :master]
+ end
context 'pull code' do
it { expect { pull_access_check }.not_to raise_error }
@@ -204,7 +212,9 @@ describe Gitlab::GitAccess, lib: true do
end
describe 'guest permissions' do
- before { project.team << [user, :guest] }
+ before do
+ project.team << [user, :guest]
+ end
context 'pull code' do
it { expect { pull_access_check }.to raise_unauthorized('You are not allowed to download code from this project.') }
@@ -253,7 +263,9 @@ describe Gitlab::GitAccess, lib: true do
context 'pull code' do
context 'when project is authorized' do
- before { key.projects << project }
+ before do
+ key.projects << project
+ end
it { expect { pull_access_check }.not_to raise_error }
end
@@ -292,7 +304,9 @@ describe Gitlab::GitAccess, lib: true do
end
describe 'reporter user' do
- before { project.team << [user, :reporter] }
+ before do
+ project.team << [user, :reporter]
+ end
context 'pull code' do
it { expect { pull_access_check }.not_to raise_error }
@@ -303,7 +317,9 @@ describe Gitlab::GitAccess, lib: true do
let(:user) { create(:admin) }
context 'when member of the project' do
- before { project.team << [user, :reporter] }
+ before do
+ project.team << [user, :reporter]
+ end
context 'pull code' do
it { expect { pull_access_check }.not_to raise_error }
@@ -328,7 +344,9 @@ describe Gitlab::GitAccess, lib: true do
end
describe '#check_push_access!' do
- before { merge_into_protected_branch }
+ before do
+ merge_into_protected_branch
+ end
let(:unprotected_branch) { 'unprotected_branch' }
let(:changes) do
@@ -457,19 +475,25 @@ describe Gitlab::GitAccess, lib: true do
[%w(feature exact), ['feat*', 'wildcard']].each do |protected_branch_name, protected_branch_type|
context do
- before { create(:protected_branch, name: protected_branch_name, project: project) }
+ before do
+ create(:protected_branch, name: protected_branch_name, project: project)
+ end
run_permission_checks(permissions_matrix)
end
context "when developers are allowed to push into the #{protected_branch_type} protected branch" do
- before { create(:protected_branch, :developers_can_push, name: protected_branch_name, project: project) }
+ before do
+ create(:protected_branch, :developers_can_push, name: protected_branch_name, project: project)
+ end
run_permission_checks(permissions_matrix.deep_merge(developer: { push_protected_branch: true, push_all: true, merge_into_protected_branch: true }))
end
context "developers are allowed to merge into the #{protected_branch_type} protected branch" do
- before { create(:protected_branch, :developers_can_merge, name: protected_branch_name, project: project) }
+ before do
+ create(:protected_branch, :developers_can_merge, name: protected_branch_name, project: project)
+ end
context "when a merge request exists for the given source/target branch" do
context "when the merge request is in progress" do
@@ -496,13 +520,17 @@ describe Gitlab::GitAccess, lib: true do
end
context "when developers are allowed to push and merge into the #{protected_branch_type} protected branch" do
- before { create(:protected_branch, :developers_can_merge, :developers_can_push, name: protected_branch_name, project: project) }
+ before do
+ create(:protected_branch, :developers_can_merge, :developers_can_push, name: protected_branch_name, project: project)
+ end
run_permission_checks(permissions_matrix.deep_merge(developer: { push_protected_branch: true, push_all: true, merge_into_protected_branch: true }))
end
context "when no one is allowed to push to the #{protected_branch_name} protected branch" do
- before { create(:protected_branch, :no_one_can_push, name: protected_branch_name, project: project) }
+ before do
+ create(:protected_branch, :no_one_can_push, name: protected_branch_name, project: project)
+ end
run_permission_checks(permissions_matrix.deep_merge(developer: { push_protected_branch: false, push_all: false, merge_into_protected_branch: false },
master: { push_protected_branch: false, push_all: false, merge_into_protected_branch: false },
@@ -515,7 +543,9 @@ describe Gitlab::GitAccess, lib: true do
let(:authentication_abilities) { build_authentication_abilities }
context 'when project is authorized' do
- before { project.team << [user, :reporter] }
+ before do
+ project.team << [user, :reporter]
+ end
it { expect { push_access_check }.to raise_unauthorized('You are not allowed to upload code for this project.') }
end
@@ -549,7 +579,9 @@ describe Gitlab::GitAccess, lib: true do
let(:can_push) { true }
context 'when project is authorized' do
- before { key.projects << project }
+ before do
+ key.projects << project
+ end
it { expect { push_access_check }.not_to raise_error }
end
@@ -579,7 +611,9 @@ describe Gitlab::GitAccess, lib: true do
let(:can_push) { false }
context 'when project is authorized' do
- before { key.projects << project }
+ before do
+ key.projects << project
+ end
it { expect { push_access_check }.to raise_unauthorized('This deploy key does not have write access to this project.') }
end
diff --git a/spec/lib/gitlab/gitaly_client_spec.rb b/spec/lib/gitlab/gitaly_client_spec.rb
index 95ecba67532..ce7b18b784a 100644
--- a/spec/lib/gitlab/gitaly_client_spec.rb
+++ b/spec/lib/gitlab/gitaly_client_spec.rb
@@ -5,7 +5,9 @@ require 'spec_helper'
describe Gitlab::GitalyClient, lib: true, skip_gitaly_mock: true do
describe '.stub' do
# Notice that this is referring to gRPC "stubs", not rspec stubs
- before { described_class.clear_stubs! }
+ before do
+ described_class.clear_stubs!
+ end
context 'when passed a UNIX socket address' do
it 'passes the address as-is to GRPC' do
@@ -41,7 +43,9 @@ describe Gitlab::GitalyClient, lib: true, skip_gitaly_mock: true do
let(:real_feature_name) { "gitaly_#{feature_name}" }
context 'when Gitaly is disabled' do
- before { allow(described_class).to receive(:enabled?).and_return(false) }
+ before do
+ allow(described_class).to receive(:enabled?).and_return(false)
+ end
it 'returns false' do
expect(described_class.feature_enabled?(feature_name)).to be(false)
@@ -66,7 +70,9 @@ describe Gitlab::GitalyClient, lib: true, skip_gitaly_mock: true do
end
context "when the feature flag is set to disable" do
- before { Feature.get(real_feature_name).disable }
+ before do
+ Feature.get(real_feature_name).disable
+ end
it 'returns false' do
expect(described_class.feature_enabled?(feature_name, status: feature_status)).to be(false)
@@ -74,7 +80,9 @@ describe Gitlab::GitalyClient, lib: true, skip_gitaly_mock: true do
end
context "when the feature flag is set to enable" do
- before { Feature.get(real_feature_name).enable }
+ before do
+ Feature.get(real_feature_name).enable
+ end
it 'returns true' do
expect(described_class.feature_enabled?(feature_name, status: feature_status)).to be(true)
@@ -82,7 +90,9 @@ describe Gitlab::GitalyClient, lib: true, skip_gitaly_mock: true do
end
context "when the feature flag is set to a percentage of time" do
- before { Feature.get(real_feature_name).enable_percentage_of_time(70) }
+ before do
+ Feature.get(real_feature_name).enable_percentage_of_time(70)
+ end
it 'bases the result on pseudo-random numbers' do
expect(Random).to receive(:rand).and_return(0.3)
@@ -104,7 +114,9 @@ describe Gitlab::GitalyClient, lib: true, skip_gitaly_mock: true do
end
context "when the feature flag is set to disable" do
- before { Feature.get(real_feature_name).disable }
+ before do
+ Feature.get(real_feature_name).disable
+ end
it 'returns false' do
expect(described_class.feature_enabled?(feature_name, status: feature_status)).to be(false)
diff --git a/spec/lib/gitlab/highlight_spec.rb b/spec/lib/gitlab/highlight_spec.rb
index c2bb9f9a166..fdc5b484ef1 100644
--- a/spec/lib/gitlab/highlight_spec.rb
+++ b/spec/lib/gitlab/highlight_spec.rb
@@ -15,7 +15,9 @@ describe Gitlab::Highlight, lib: true do
Gitlab::Highlight.new(blob.path, blob.data, repository: repository)
end
- before { project.change_head('gitattributes') }
+ before do
+ project.change_head('gitattributes')
+ end
describe 'basic language selection' do
let(:path) { 'custom-highlighting/test.gitlab-custom' }
diff --git a/spec/lib/gitlab/i18n_spec.rb b/spec/lib/gitlab/i18n_spec.rb
index a3dbeaa3753..0dba4132101 100644
--- a/spec/lib/gitlab/i18n_spec.rb
+++ b/spec/lib/gitlab/i18n_spec.rb
@@ -4,7 +4,9 @@ describe Gitlab::I18n, lib: true do
let(:user) { create(:user, preferred_language: 'es') }
describe '.locale=' do
- after { described_class.use_default_locale }
+ after do
+ described_class.use_default_locale
+ end
it 'sets the locale based on current user preferred language' do
described_class.locale = user.preferred_language
diff --git a/spec/lib/gitlab/kubernetes_spec.rb b/spec/lib/gitlab/kubernetes_spec.rb
index 91f9d06b85a..e8c599a95ee 100644
--- a/spec/lib/gitlab/kubernetes_spec.rb
+++ b/spec/lib/gitlab/kubernetes_spec.rb
@@ -1,6 +1,7 @@
require 'spec_helper'
describe Gitlab::Kubernetes do
+ include KubernetesHelpers
include described_class
describe '#container_exec_url' do
@@ -36,4 +37,13 @@ describe Gitlab::Kubernetes do
it { expect(result.query).to match(/\Acontainer=container\+1&/) }
end
end
+
+ describe '#filter_by_label' do
+ it 'returns matching labels' do
+ matching_items = [kube_pod(app: 'foo')]
+ items = matching_items + [kube_pod]
+
+ expect(filter_by_label(items, app: 'foo')).to eq(matching_items)
+ end
+ end
end
diff --git a/spec/lib/gitlab/ldap/adapter_spec.rb b/spec/lib/gitlab/ldap/adapter_spec.rb
index 563c074017a..9454878b057 100644
--- a/spec/lib/gitlab/ldap/adapter_spec.rb
+++ b/spec/lib/gitlab/ldap/adapter_spec.rb
@@ -74,13 +74,17 @@ describe Gitlab::LDAP::Adapter, lib: true do
subject { adapter.dn_matches_filter?(:dn, :filter) }
context "when the search result is non-empty" do
- before { allow(adapter).to receive(:ldap_search).and_return([:foo]) }
+ before do
+ allow(adapter).to receive(:ldap_search).and_return([:foo])
+ end
it { is_expected.to be_truthy }
end
context "when the search result is empty" do
- before { allow(adapter).to receive(:ldap_search).and_return([]) }
+ before do
+ allow(adapter).to receive(:ldap_search).and_return([])
+ end
it { is_expected.to be_falsey }
end
@@ -91,13 +95,17 @@ describe Gitlab::LDAP::Adapter, lib: true do
context "when the search is successful" do
context "and the result is non-empty" do
- before { allow(ldap).to receive(:search).and_return([:foo]) }
+ before do
+ allow(ldap).to receive(:search).and_return([:foo])
+ end
it { is_expected.to eq [:foo] }
end
context "and the result is empty" do
- before { allow(ldap).to receive(:search).and_return([]) }
+ before do
+ allow(ldap).to receive(:search).and_return([])
+ end
it { is_expected.to eq [] }
end
diff --git a/spec/lib/gitlab/ldap/user_spec.rb b/spec/lib/gitlab/ldap/user_spec.rb
index a0eda685ca3..f0a1dd22fee 100644
--- a/spec/lib/gitlab/ldap/user_spec.rb
+++ b/spec/lib/gitlab/ldap/user_spec.rb
@@ -173,7 +173,9 @@ describe Gitlab::LDAP::User, lib: true do
context 'signup' do
context 'dont block on create' do
- before { configure_block(false) }
+ before do
+ configure_block(false)
+ end
it do
ldap_user.save
@@ -183,7 +185,9 @@ describe Gitlab::LDAP::User, lib: true do
end
context 'block on create' do
- before { configure_block(true) }
+ before do
+ configure_block(true)
+ end
it do
ldap_user.save
@@ -200,7 +204,9 @@ describe Gitlab::LDAP::User, lib: true do
end
context 'dont block on create' do
- before { configure_block(false) }
+ before do
+ configure_block(false)
+ end
it do
ldap_user.save
@@ -210,7 +216,9 @@ describe Gitlab::LDAP::User, lib: true do
end
context 'block on create' do
- before { configure_block(true) }
+ before do
+ configure_block(true)
+ end
it do
ldap_user.save
diff --git a/spec/lib/gitlab/middleware/rails_queue_duration_spec.rb b/spec/lib/gitlab/middleware/rails_queue_duration_spec.rb
index 168090d5b5c..88107536c9e 100644
--- a/spec/lib/gitlab/middleware/rails_queue_duration_spec.rb
+++ b/spec/lib/gitlab/middleware/rails_queue_duration_spec.rb
@@ -6,7 +6,9 @@ describe Gitlab::Middleware::RailsQueueDuration do
let(:env) { {} }
let(:transaction) { double(:transaction) }
- before { expect(app).to receive(:call).with(env).and_return('yay') }
+ before do
+ expect(app).to receive(:call).with(env).and_return('yay')
+ end
describe '#call' do
it 'calls the app when metrics are disabled' do
@@ -15,7 +17,9 @@ describe Gitlab::Middleware::RailsQueueDuration do
end
context 'when metrics are enabled' do
- before { allow(Gitlab::Metrics).to receive(:current_transaction).and_return(transaction) }
+ before do
+ allow(Gitlab::Metrics).to receive(:current_transaction).and_return(transaction)
+ end
it 'calls the app when metrics are enabled but no timing header is found' do
expect(middleware.call(env)).to eq('yay')
diff --git a/spec/lib/gitlab/o_auth/auth_hash_spec.rb b/spec/lib/gitlab/o_auth/auth_hash_spec.rb
index 8aaeb5779d3..19ab17419fc 100644
--- a/spec/lib/gitlab/o_auth/auth_hash_spec.rb
+++ b/spec/lib/gitlab/o_auth/auth_hash_spec.rb
@@ -55,7 +55,9 @@ describe Gitlab::OAuth::AuthHash, lib: true do
end
context 'email not provided' do
- before { info_hash.delete(:email) }
+ before do
+ info_hash.delete(:email)
+ end
it 'generates a temp email' do
expect( auth_hash.email).to start_with('temp-email-for-oauth')
@@ -63,7 +65,9 @@ describe Gitlab::OAuth::AuthHash, lib: true do
end
context 'username not provided' do
- before { info_hash.delete(:nickname) }
+ before do
+ info_hash.delete(:nickname)
+ end
it 'takes the first part of the email as username' do
expect(auth_hash.username).to eql 'onur.kucuk_ABC-123'
@@ -71,7 +75,9 @@ describe Gitlab::OAuth::AuthHash, lib: true do
end
context 'name not provided' do
- before { info_hash.delete(:name) }
+ before do
+ info_hash.delete(:name)
+ end
it 'concats first and lastname as the name' do
expect(auth_hash.name).to eql name_utf8
diff --git a/spec/lib/gitlab/o_auth/user_spec.rb b/spec/lib/gitlab/o_auth/user_spec.rb
index 8943d1aa488..ea29cb9caf1 100644
--- a/spec/lib/gitlab/o_auth/user_spec.rb
+++ b/spec/lib/gitlab/o_auth/user_spec.rb
@@ -112,7 +112,9 @@ describe Gitlab::OAuth::User, lib: true do
end
context 'with new allow_single_sign_on enabled syntax' do
- before { stub_omniauth_config(allow_single_sign_on: ['twitter']) }
+ before do
+ stub_omniauth_config(allow_single_sign_on: ['twitter'])
+ end
it "creates a user from Omniauth" do
oauth_user.save
@@ -125,7 +127,9 @@ describe Gitlab::OAuth::User, lib: true do
end
context "with old allow_single_sign_on enabled syntax" do
- before { stub_omniauth_config(allow_single_sign_on: true) }
+ before do
+ stub_omniauth_config(allow_single_sign_on: true)
+ end
it "creates a user from Omniauth" do
oauth_user.save
@@ -138,14 +142,20 @@ describe Gitlab::OAuth::User, lib: true do
end
context 'with new allow_single_sign_on disabled syntax' do
- before { stub_omniauth_config(allow_single_sign_on: []) }
+ before do
+ stub_omniauth_config(allow_single_sign_on: [])
+ end
+
it 'throws an error' do
expect{ oauth_user.save }.to raise_error StandardError
end
end
context 'with old allow_single_sign_on disabled (Default)' do
- before { stub_omniauth_config(allow_single_sign_on: false) }
+ before do
+ stub_omniauth_config(allow_single_sign_on: false)
+ end
+
it 'throws an error' do
expect{ oauth_user.save }.to raise_error StandardError
end
@@ -153,21 +163,30 @@ describe Gitlab::OAuth::User, lib: true do
end
context "with auto_link_ldap_user disabled (default)" do
- before { stub_omniauth_config(auto_link_ldap_user: false) }
+ before do
+ stub_omniauth_config(auto_link_ldap_user: false)
+ end
+
include_examples "to verify compliance with allow_single_sign_on"
end
context "with auto_link_ldap_user enabled" do
- before { stub_omniauth_config(auto_link_ldap_user: true) }
+ before do
+ stub_omniauth_config(auto_link_ldap_user: true)
+ end
context "and no LDAP provider defined" do
- before { stub_ldap_config(providers: []) }
+ before do
+ stub_ldap_config(providers: [])
+ end
include_examples "to verify compliance with allow_single_sign_on"
end
context "and at least one LDAP provider is defined" do
- before { stub_ldap_config(providers: %w(ldapmain)) }
+ before do
+ stub_ldap_config(providers: %w(ldapmain))
+ end
context "and a corresponding LDAP person" do
before do
@@ -238,7 +257,9 @@ describe Gitlab::OAuth::User, lib: true do
end
context "and no corresponding LDAP person" do
- before { allow(Gitlab::LDAP::Person).to receive(:find_by_uid).and_return(nil) }
+ before do
+ allow(Gitlab::LDAP::Person).to receive(:find_by_uid).and_return(nil)
+ end
include_examples "to verify compliance with allow_single_sign_on"
end
@@ -248,11 +269,16 @@ describe Gitlab::OAuth::User, lib: true do
describe 'blocking' do
let(:provider) { 'twitter' }
- before { stub_omniauth_config(allow_single_sign_on: ['twitter']) }
+
+ before do
+ stub_omniauth_config(allow_single_sign_on: ['twitter'])
+ end
context 'signup with omniauth only' do
context 'dont block on create' do
- before { stub_omniauth_config(block_auto_created_users: false) }
+ before do
+ stub_omniauth_config(block_auto_created_users: false)
+ end
it do
oauth_user.save
@@ -262,7 +288,9 @@ describe Gitlab::OAuth::User, lib: true do
end
context 'block on create' do
- before { stub_omniauth_config(block_auto_created_users: true) }
+ before do
+ stub_omniauth_config(block_auto_created_users: true)
+ end
it do
oauth_user.save
@@ -284,7 +312,9 @@ describe Gitlab::OAuth::User, lib: true do
context "and no account for the LDAP user" do
context 'dont block on create (LDAP)' do
- before { allow_any_instance_of(Gitlab::LDAP::Config).to receive_messages(block_auto_created_users: false) }
+ before do
+ allow_any_instance_of(Gitlab::LDAP::Config).to receive_messages(block_auto_created_users: false)
+ end
it do
oauth_user.save
@@ -294,7 +324,9 @@ describe Gitlab::OAuth::User, lib: true do
end
context 'block on create (LDAP)' do
- before { allow_any_instance_of(Gitlab::LDAP::Config).to receive_messages(block_auto_created_users: true) }
+ before do
+ allow_any_instance_of(Gitlab::LDAP::Config).to receive_messages(block_auto_created_users: true)
+ end
it do
oauth_user.save
@@ -308,7 +340,9 @@ describe Gitlab::OAuth::User, lib: true do
let!(:existing_user) { create(:omniauth_user, email: 'john@example.com', extern_uid: 'uid=user1,ou=People,dc=example', provider: 'ldapmain', username: 'john') }
context 'dont block on create (LDAP)' do
- before { allow_any_instance_of(Gitlab::LDAP::Config).to receive_messages(block_auto_created_users: false) }
+ before do
+ allow_any_instance_of(Gitlab::LDAP::Config).to receive_messages(block_auto_created_users: false)
+ end
it do
oauth_user.save
@@ -318,7 +352,9 @@ describe Gitlab::OAuth::User, lib: true do
end
context 'block on create (LDAP)' do
- before { allow_any_instance_of(Gitlab::LDAP::Config).to receive_messages(block_auto_created_users: true) }
+ before do
+ allow_any_instance_of(Gitlab::LDAP::Config).to receive_messages(block_auto_created_users: true)
+ end
it do
oauth_user.save
@@ -336,7 +372,9 @@ describe Gitlab::OAuth::User, lib: true do
end
context 'dont block on create' do
- before { stub_omniauth_config(block_auto_created_users: false) }
+ before do
+ stub_omniauth_config(block_auto_created_users: false)
+ end
it do
oauth_user.save
@@ -346,7 +384,9 @@ describe Gitlab::OAuth::User, lib: true do
end
context 'block on create' do
- before { stub_omniauth_config(block_auto_created_users: true) }
+ before do
+ stub_omniauth_config(block_auto_created_users: true)
+ end
it do
oauth_user.save
@@ -356,7 +396,9 @@ describe Gitlab::OAuth::User, lib: true do
end
context 'dont block on create (LDAP)' do
- before { allow_any_instance_of(Gitlab::LDAP::Config).to receive_messages(block_auto_created_users: false) }
+ before do
+ allow_any_instance_of(Gitlab::LDAP::Config).to receive_messages(block_auto_created_users: false)
+ end
it do
oauth_user.save
@@ -366,7 +408,9 @@ describe Gitlab::OAuth::User, lib: true do
end
context 'block on create (LDAP)' do
- before { allow_any_instance_of(Gitlab::LDAP::Config).to receive_messages(block_auto_created_users: true) }
+ before do
+ allow_any_instance_of(Gitlab::LDAP::Config).to receive_messages(block_auto_created_users: true)
+ end
it do
oauth_user.save
diff --git a/spec/lib/gitlab/redis_spec.rb b/spec/lib/gitlab/redis_spec.rb
index 8b77c925705..593aa5038ad 100644
--- a/spec/lib/gitlab/redis_spec.rb
+++ b/spec/lib/gitlab/redis_spec.rb
@@ -108,11 +108,18 @@ describe Gitlab::Redis do
end
describe '.with' do
- before { clear_pool }
- after { clear_pool }
+ before do
+ clear_pool
+ end
+
+ after do
+ clear_pool
+ end
context 'when running not on sidekiq workers' do
- before { allow(Sidekiq).to receive(:server?).and_return(false) }
+ before do
+ allow(Sidekiq).to receive(:server?).and_return(false)
+ end
it 'instantiates a connection pool with size 5' do
expect(ConnectionPool).to receive(:new).with(size: 5).and_call_original
diff --git a/spec/lib/gitlab/saml/user_spec.rb b/spec/lib/gitlab/saml/user_spec.rb
index b106d156b75..a4d2367b72a 100644
--- a/spec/lib/gitlab/saml/user_spec.rb
+++ b/spec/lib/gitlab/saml/user_spec.rb
@@ -31,11 +31,17 @@ describe Gitlab::Saml::User, lib: true do
allow(Gitlab::Saml::Config).to receive_messages({ options: { name: 'saml', groups_attribute: 'groups', external_groups: groups, args: {} } })
end
- before { stub_basic_saml_config }
+ before do
+ stub_basic_saml_config
+ end
describe 'account exists on server' do
- before { stub_omniauth_config({ allow_single_sign_on: ['saml'], auto_link_saml_user: true }) }
+ before do
+ stub_omniauth_config({ allow_single_sign_on: ['saml'], auto_link_saml_user: true })
+ end
+
let!(:existing_user) { create(:user, email: 'john@mail.com', username: 'john') }
+
context 'and should bind with SAML' do
it 'adds the SAML identity to the existing user' do
saml_user.save
@@ -57,7 +63,10 @@ describe Gitlab::Saml::User, lib: true do
end
end
- before { stub_saml_group_config(%w(Interns)) }
+ before do
+ stub_saml_group_config(%w(Interns))
+ end
+
context 'are defined but the user does not belong there' do
it 'does not mark the user as external' do
saml_user.save
@@ -80,7 +89,9 @@ describe Gitlab::Saml::User, lib: true do
describe 'no account exists on server' do
shared_examples 'to verify compliance with allow_single_sign_on' do
context 'with allow_single_sign_on enabled' do
- before { stub_omniauth_config(allow_single_sign_on: ['saml']) }
+ before do
+ stub_omniauth_config(allow_single_sign_on: ['saml'])
+ end
it 'creates a user from SAML' do
saml_user.save
@@ -93,14 +104,20 @@ describe Gitlab::Saml::User, lib: true do
end
context 'with allow_single_sign_on default (["saml"])' do
- before { stub_omniauth_config(allow_single_sign_on: ['saml']) }
+ before do
+ stub_omniauth_config(allow_single_sign_on: ['saml'])
+ end
+
it 'does not throw an error' do
expect{ saml_user.save }.not_to raise_error
end
end
context 'with allow_single_sign_on disabled' do
- before { stub_omniauth_config(allow_single_sign_on: false) }
+ before do
+ stub_omniauth_config(allow_single_sign_on: false)
+ end
+
it 'throws an error' do
expect{ saml_user.save }.to raise_error StandardError
end
@@ -128,15 +145,22 @@ describe Gitlab::Saml::User, lib: true do
end
context 'with auto_link_ldap_user disabled (default)' do
- before { stub_omniauth_config({ auto_link_ldap_user: false, auto_link_saml_user: false, allow_single_sign_on: ['saml'] }) }
+ before do
+ stub_omniauth_config({ auto_link_ldap_user: false, auto_link_saml_user: false, allow_single_sign_on: ['saml'] })
+ end
+
include_examples 'to verify compliance with allow_single_sign_on'
end
context 'with auto_link_ldap_user enabled' do
- before { stub_omniauth_config({ auto_link_ldap_user: true, auto_link_saml_user: false }) }
+ before do
+ stub_omniauth_config({ auto_link_ldap_user: true, auto_link_saml_user: false })
+ end
context 'and at least one LDAP provider is defined' do
- before { stub_ldap_config(providers: %w(ldapmain)) }
+ before do
+ stub_ldap_config(providers: %w(ldapmain))
+ end
context 'and a corresponding LDAP person' do
before do
@@ -239,11 +263,15 @@ describe Gitlab::Saml::User, lib: true do
end
describe 'blocking' do
- before { stub_omniauth_config({ allow_single_sign_on: ['saml'], auto_link_saml_user: true }) }
+ before do
+ stub_omniauth_config({ allow_single_sign_on: ['saml'], auto_link_saml_user: true })
+ end
context 'signup with SAML only' do
context 'dont block on create' do
- before { stub_omniauth_config(block_auto_created_users: false) }
+ before do
+ stub_omniauth_config(block_auto_created_users: false)
+ end
it 'does not block the user' do
saml_user.save
@@ -253,7 +281,9 @@ describe Gitlab::Saml::User, lib: true do
end
context 'block on create' do
- before { stub_omniauth_config(block_auto_created_users: true) }
+ before do
+ stub_omniauth_config(block_auto_created_users: true)
+ end
it 'blocks user' do
saml_user.save
@@ -270,7 +300,9 @@ describe Gitlab::Saml::User, lib: true do
end
context 'dont block on create' do
- before { stub_omniauth_config(block_auto_created_users: false) }
+ before do
+ stub_omniauth_config(block_auto_created_users: false)
+ end
it do
saml_user.save
@@ -280,7 +312,9 @@ describe Gitlab::Saml::User, lib: true do
end
context 'block on create' do
- before { stub_omniauth_config(block_auto_created_users: true) }
+ before do
+ stub_omniauth_config(block_auto_created_users: true)
+ end
it do
saml_user.save
diff --git a/spec/lib/gitlab/serializer/pagination_spec.rb b/spec/lib/gitlab/serializer/pagination_spec.rb
index 519eb1b274f..1bc6536439e 100644
--- a/spec/lib/gitlab/serializer/pagination_spec.rb
+++ b/spec/lib/gitlab/serializer/pagination_spec.rb
@@ -22,7 +22,9 @@ describe Gitlab::Serializer::Pagination do
let(:params) { { page: 1, per_page: 2 } }
context 'when a multiple resources are present in relation' do
- before { create_list(:user, 3) }
+ before do
+ create_list(:user, 3)
+ end
it 'correctly paginates the resource' do
expect(subject.count).to be 2
diff --git a/spec/lib/gitlab/template/issue_template_spec.rb b/spec/lib/gitlab/template/issue_template_spec.rb
index 329d1d74970..bf45c8d16d6 100644
--- a/spec/lib/gitlab/template/issue_template_spec.rb
+++ b/spec/lib/gitlab/template/issue_template_spec.rb
@@ -52,7 +52,10 @@ describe Gitlab::Template::IssueTemplate do
context 'when repo is bare or empty' do
let(:empty_project) { create(:empty_project) }
- before { empty_project.add_user(user, Gitlab::Access::MASTER) }
+
+ before do
+ empty_project.add_user(user, Gitlab::Access::MASTER)
+ end
it "returns empty array" do
templates = subject.by_category('', empty_project)
@@ -77,7 +80,9 @@ describe Gitlab::Template::IssueTemplate do
context "when repo is empty" do
let(:empty_project) { create(:empty_project) }
- before { empty_project.add_user(user, Gitlab::Access::MASTER) }
+ before do
+ empty_project.add_user(user, Gitlab::Access::MASTER)
+ end
it "raises file not found" do
issue_template = subject.new('.gitlab/issue_templates/not_existent.md', empty_project)
diff --git a/spec/lib/gitlab/template/merge_request_template_spec.rb b/spec/lib/gitlab/template/merge_request_template_spec.rb
index 2b0056d9bab..8479f92c8df 100644
--- a/spec/lib/gitlab/template/merge_request_template_spec.rb
+++ b/spec/lib/gitlab/template/merge_request_template_spec.rb
@@ -52,7 +52,10 @@ describe Gitlab::Template::MergeRequestTemplate do
context 'when repo is bare or empty' do
let(:empty_project) { create(:empty_project) }
- before { empty_project.add_user(user, Gitlab::Access::MASTER) }
+
+ before do
+ empty_project.add_user(user, Gitlab::Access::MASTER)
+ end
it "returns empty array" do
templates = subject.by_category('', empty_project)
@@ -77,7 +80,9 @@ describe Gitlab::Template::MergeRequestTemplate do
context "when repo is empty" do
let(:empty_project) { create(:empty_project) }
- before { empty_project.add_user(user, Gitlab::Access::MASTER) }
+ before do
+ empty_project.add_user(user, Gitlab::Access::MASTER)
+ end
it "raises file not found" do
issue_template = subject.new('.gitlab/merge_request_templates/not_existent.md', empty_project)
diff --git a/spec/lib/json_web_token/rsa_token_spec.rb b/spec/lib/json_web_token/rsa_token_spec.rb
index 18726754517..e7022bd06f8 100644
--- a/spec/lib/json_web_token/rsa_token_spec.rb
+++ b/spec/lib/json_web_token/rsa_token_spec.rb
@@ -15,11 +15,15 @@ describe JSONWebToken::RSAToken do
let(:rsa_token) { described_class.new(nil) }
let(:rsa_encoded) { rsa_token.encoded }
- before { allow_any_instance_of(described_class).to receive(:key).and_return(rsa_key) }
+ before do
+ allow_any_instance_of(described_class).to receive(:key).and_return(rsa_key)
+ end
context 'token' do
context 'for valid key to be validated' do
- before { rsa_token['key'] = 'value' }
+ before do
+ rsa_token['key'] = 'value'
+ end
subject { JWT.decode(rsa_encoded, rsa_key) }
diff --git a/spec/lib/json_web_token/token_spec.rb b/spec/lib/json_web_token/token_spec.rb
index 3d955e4d774..d7e7560d962 100644
--- a/spec/lib/json_web_token/token_spec.rb
+++ b/spec/lib/json_web_token/token_spec.rb
@@ -3,7 +3,10 @@ describe JSONWebToken::Token do
context 'custom parameters' do
let(:value) { 'value' }
- before { token[:key] = value }
+
+ before do
+ token[:key] = value
+ end
it { expect(token[:key]).to eq(value) }
it { expect(token.payload).to include(key: value) }
diff --git a/spec/mailers/notify_spec.rb b/spec/mailers/notify_spec.rb
index ec6f6c42eac..980b24370d0 100644
--- a/spec/mailers/notify_spec.rb
+++ b/spec/mailers/notify_spec.rb
@@ -130,8 +130,13 @@ describe Notify do
end
context 'with a preferred language' do
- before { Gitlab::I18n.locale = :es }
- after { Gitlab::I18n.use_default_locale }
+ before do
+ Gitlab::I18n.locale = :es
+ end
+
+ after do
+ Gitlab::I18n.use_default_locale
+ end
it 'always generates the email using the default language' do
is_expected.to have_body_text('foo, bar, and baz')
@@ -581,7 +586,9 @@ describe Notify do
let(:project) { create(:project, :repository) }
let(:commit) { project.commit }
- before(:each) { allow(note).to receive(:noteable).and_return(commit) }
+ before do
+ allow(note).to receive(:noteable).and_return(commit)
+ end
subject { described_class.note_commit_email(recipient.id, note.id) }
@@ -603,7 +610,10 @@ describe Notify do
describe 'on a merge request' do
let(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
let(:note_on_merge_request_path) { namespace_project_merge_request_path(project.namespace, project, merge_request, anchor: "note_#{note.id}") }
- before(:each) { allow(note).to receive(:noteable).and_return(merge_request) }
+
+ before do
+ allow(note).to receive(:noteable).and_return(merge_request)
+ end
subject { described_class.note_merge_request_email(recipient.id, note.id) }
@@ -625,7 +635,10 @@ describe Notify do
describe 'on an issue' do
let(:issue) { create(:issue, project: project) }
let(:note_on_issue_path) { namespace_project_issue_path(project.namespace, project, issue, anchor: "note_#{note.id}") }
- before(:each) { allow(note).to receive(:noteable).and_return(issue) }
+
+ before do
+ allow(note).to receive(:noteable).and_return(issue)
+ end
subject { described_class.note_issue_email(recipient.id, note.id) }
@@ -687,7 +700,9 @@ describe Notify do
let(:commit) { project.commit }
let(:note) { create(:discussion_note_on_commit, commit_id: commit.id, project: project, author: note_author) }
- before(:each) { allow(note).to receive(:noteable).and_return(commit) }
+ before do
+ allow(note).to receive(:noteable).and_return(commit)
+ end
subject { described_class.note_commit_email(recipient.id, note.id) }
@@ -711,7 +726,10 @@ describe Notify do
let(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
let(:note) { create(:discussion_note_on_merge_request, noteable: merge_request, project: project, author: note_author) }
let(:note_on_merge_request_path) { namespace_project_merge_request_path(project.namespace, project, merge_request, anchor: "note_#{note.id}") }
- before(:each) { allow(note).to receive(:noteable).and_return(merge_request) }
+
+ before do
+ allow(note).to receive(:noteable).and_return(merge_request)
+ end
subject { described_class.note_merge_request_email(recipient.id, note.id) }
@@ -735,7 +753,10 @@ describe Notify do
let(:issue) { create(:issue, project: project) }
let(:note) { create(:discussion_note_on_issue, noteable: issue, project: project, author: note_author) }
let(:note_on_issue_path) { namespace_project_issue_path(project.namespace, project, issue, anchor: "note_#{note.id}") }
- before(:each) { allow(note).to receive(:noteable).and_return(issue) }
+
+ before do
+ allow(note).to receive(:noteable).and_return(issue)
+ end
subject { described_class.note_issue_email(recipient.id, note.id) }
diff --git a/spec/migrations/rename_more_reserved_project_names_spec.rb b/spec/migrations/rename_more_reserved_project_names_spec.rb
index 36e82729c23..4bd8d4ac0d1 100644
--- a/spec/migrations/rename_more_reserved_project_names_spec.rb
+++ b/spec/migrations/rename_more_reserved_project_names_spec.rb
@@ -17,7 +17,9 @@ describe RenameMoreReservedProjectNames, truncate: true do
describe '#up' do
context 'when project repository exists' do
- before { project.create_repository }
+ before do
+ project.create_repository
+ end
context 'when no exception is raised' do
it 'renames project with reserved names' do
diff --git a/spec/migrations/rename_reserved_project_names_spec.rb b/spec/migrations/rename_reserved_project_names_spec.rb
index 4fb7ed36884..05e021c2e32 100644
--- a/spec/migrations/rename_reserved_project_names_spec.rb
+++ b/spec/migrations/rename_reserved_project_names_spec.rb
@@ -17,7 +17,9 @@ describe RenameReservedProjectNames, truncate: true do
describe '#up' do
context 'when project repository exists' do
- before { project.create_repository }
+ before do
+ project.create_repository
+ end
context 'when no exception is raised' do
it 'renames project with reserved names' do
diff --git a/spec/models/application_setting_spec.rb b/spec/models/application_setting_spec.rb
index fa229542f70..166a4474abf 100644
--- a/spec/models/application_setting_spec.rb
+++ b/spec/models/application_setting_spec.rb
@@ -78,7 +78,9 @@ describe ApplicationSetting, models: true do
# Upgraded databases will have this sort of content
context 'repository_storages is a String, not an Array' do
- before { setting.__send__(:raw_write_attribute, :repository_storages, 'default') }
+ before do
+ setting.__send__(:raw_write_attribute, :repository_storages, 'default')
+ end
it { expect(setting.repository_storages_before_type_cast).to eq('default') }
it { expect(setting.repository_storages).to eq(['default']) }
diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb
index b0716e04d3d..975a8b01e9e 100644
--- a/spec/models/ci/build_spec.rb
+++ b/spec/models/ci/build_spec.rb
@@ -95,12 +95,18 @@ describe Ci::Build, :models do
it { is_expected.to be_truthy }
context 'is expired' do
- before { build.update(artifacts_expire_at: Time.now - 7.days) }
+ before do
+ build.update(artifacts_expire_at: Time.now - 7.days)
+ end
+
it { is_expected.to be_falsy }
end
context 'is not expired' do
- before { build.update(artifacts_expire_at: Time.now + 7.days) }
+ before do
+ build.update(artifacts_expire_at: Time.now + 7.days)
+ end
+
it { is_expected.to be_truthy }
end
end
@@ -110,13 +116,17 @@ describe Ci::Build, :models do
subject { build.artifacts_expired? }
context 'is expired' do
- before { build.update(artifacts_expire_at: Time.now - 7.days) }
+ before do
+ build.update(artifacts_expire_at: Time.now - 7.days)
+ end
it { is_expected.to be_truthy }
end
context 'is not expired' do
- before { build.update(artifacts_expire_at: Time.now + 7.days) }
+ before do
+ build.update(artifacts_expire_at: Time.now + 7.days)
+ end
it { is_expected.to be_falsey }
end
@@ -141,7 +151,9 @@ describe Ci::Build, :models do
context 'when artifacts_expire_at is specified' do
let(:expire_at) { Time.now + 7.days }
- before { build.artifacts_expire_at = expire_at }
+ before do
+ build.artifacts_expire_at = expire_at
+ end
it { is_expected.to be_within(5).of(expire_at - Time.now) }
end
@@ -1071,7 +1083,9 @@ describe Ci::Build, :models do
describe '#has_expiring_artifacts?' do
context 'when artifacts have expiration date set' do
- before { build.update(artifacts_expire_at: 1.day.from_now) }
+ before do
+ build.update(artifacts_expire_at: 1.day.from_now)
+ end
it 'has expiring artifacts' do
expect(build).to have_expiring_artifacts
@@ -1079,7 +1093,9 @@ describe Ci::Build, :models do
end
context 'when artifacts do not have expiration date set' do
- before { build.update(artifacts_expire_at: nil) }
+ before do
+ build.update(artifacts_expire_at: nil)
+ end
it 'does not have expiring artifacts' do
expect(build).not_to have_expiring_artifacts
diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb
index b50c7700bd3..e86cbe8498a 100644
--- a/spec/models/ci/pipeline_spec.rb
+++ b/spec/models/ci/pipeline_spec.rb
@@ -1156,7 +1156,9 @@ describe Ci::Pipeline, models: true do
end
context 'when pipeline is not stuck' do
- before { create(:ci_runner, :shared, :online) }
+ before do
+ create(:ci_runner, :shared, :online)
+ end
it 'is not stuck' do
expect(pipeline).not_to be_stuck
diff --git a/spec/models/commit_spec.rb b/spec/models/commit_spec.rb
index ba247dcc5cf..6056d78da4e 100644
--- a/spec/models/commit_spec.rb
+++ b/spec/models/commit_spec.rb
@@ -206,19 +206,25 @@ eos
it { expect(commit.reverts_commit?(another_commit, user)).to be_falsy }
context 'commit has no description' do
- before { allow(commit).to receive(:description?).and_return(false) }
+ before do
+ allow(commit).to receive(:description?).and_return(false)
+ end
it { expect(commit.reverts_commit?(another_commit, user)).to be_falsy }
end
context "another_commit's description does not revert commit" do
- before { allow(commit).to receive(:description).and_return("Foo Bar") }
+ before do
+ allow(commit).to receive(:description).and_return("Foo Bar")
+ end
it { expect(commit.reverts_commit?(another_commit, user)).to be_falsy }
end
context "another_commit's description reverts commit" do
- before { allow(commit).to receive(:description).and_return("Foo #{another_commit.revert_description} Bar") }
+ before do
+ allow(commit).to receive(:description).and_return("Foo #{another_commit.revert_description} Bar")
+ end
it { expect(commit.reverts_commit?(another_commit, user)).to be_truthy }
end
diff --git a/spec/models/commit_status_spec.rb b/spec/models/commit_status_spec.rb
index c50b8bf7b13..9262ce08987 100644
--- a/spec/models/commit_status_spec.rb
+++ b/spec/models/commit_status_spec.rb
@@ -31,7 +31,10 @@ describe CommitStatus, :models do
describe '#author' do
subject { commit_status.author }
- before { commit_status.author = User.new }
+
+ before do
+ commit_status.author = User.new
+ end
it { is_expected.to eq(commit_status.user) }
end
@@ -50,14 +53,18 @@ describe CommitStatus, :models do
subject { commit_status.started? }
context 'without started_at' do
- before { commit_status.started_at = nil }
+ before do
+ commit_status.started_at = nil
+ end
it { is_expected.to be_falsey }
end
%w[running success failed].each do |status|
context "if commit status is #{status}" do
- before { commit_status.status = status }
+ before do
+ commit_status.status = status
+ end
it { is_expected.to be_truthy }
end
@@ -65,7 +72,9 @@ describe CommitStatus, :models do
%w[pending canceled].each do |status|
context "if commit status is #{status}" do
- before { commit_status.status = status }
+ before do
+ commit_status.status = status
+ end
it { is_expected.to be_falsey }
end
@@ -77,7 +86,9 @@ describe CommitStatus, :models do
%w[pending running].each do |state|
context "if commit_status.status is #{state}" do
- before { commit_status.status = state }
+ before do
+ commit_status.status = state
+ end
it { is_expected.to be_truthy }
end
@@ -85,7 +96,9 @@ describe CommitStatus, :models do
%w[success failed canceled].each do |state|
context "if commit_status.status is #{state}" do
- before { commit_status.status = state }
+ before do
+ commit_status.status = state
+ end
it { is_expected.to be_falsey }
end
@@ -97,7 +110,9 @@ describe CommitStatus, :models do
%w[success failed canceled].each do |state|
context "if commit_status.status is #{state}" do
- before { commit_status.status = state }
+ before do
+ commit_status.status = state
+ end
it { is_expected.to be_truthy }
end
@@ -105,7 +120,9 @@ describe CommitStatus, :models do
%w[pending running].each do |state|
context "if commit_status.status is #{state}" do
- before { commit_status.status = state }
+ before do
+ commit_status.status = state
+ end
it { is_expected.to be_falsey }
end
@@ -271,7 +288,9 @@ describe CommitStatus, :models do
subject { commit_status.before_sha }
context 'when no before_sha is set for pipeline' do
- before { pipeline.before_sha = nil }
+ before do
+ pipeline.before_sha = nil
+ end
it 'returns blank sha' do
is_expected.to eq(Gitlab::Git::BLANK_SHA)
@@ -280,7 +299,10 @@ describe CommitStatus, :models do
context 'for before_sha set for pipeline' do
let(:value) { '1234' }
- before { pipeline.before_sha = value }
+
+ before do
+ pipeline.before_sha = value
+ end
it 'returns the set value' do
is_expected.to eq(value)
diff --git a/spec/models/concerns/access_requestable_spec.rb b/spec/models/concerns/access_requestable_spec.rb
index 4829ef17a20..97b7e48bb3c 100644
--- a/spec/models/concerns/access_requestable_spec.rb
+++ b/spec/models/concerns/access_requestable_spec.rb
@@ -14,7 +14,9 @@ describe AccessRequestable do
let(:group) { create(:group, :public, :access_requestable) }
let(:user) { create(:user) }
- before { group.request_access(user) }
+ before do
+ group.request_access(user)
+ end
it { expect(group.requesters.exists?(user_id: user)).to be_truthy }
end
@@ -32,7 +34,9 @@ describe AccessRequestable do
let(:project) { create(:empty_project, :public, :access_requestable) }
let(:user) { create(:user) }
- before { project.request_access(user) }
+ before do
+ project.request_access(user)
+ end
it { expect(project.requesters.exists?(user_id: user)).to be_truthy }
end
diff --git a/spec/models/concerns/issuable_spec.rb b/spec/models/concerns/issuable_spec.rb
index 27890e33b49..1a9bda64191 100644
--- a/spec/models/concerns/issuable_spec.rb
+++ b/spec/models/concerns/issuable_spec.rb
@@ -200,7 +200,9 @@ describe Issuable do
let(:project) { issue.project }
context 'user is not a participant in the issue' do
- before { allow(issue).to receive(:participants).with(user).and_return([]) }
+ before do
+ allow(issue).to receive(:participants).with(user).and_return([])
+ end
it 'returns false when no subcription exists' do
expect(issue.subscribed?(user, project)).to be_falsey
@@ -220,7 +222,9 @@ describe Issuable do
end
context 'user is a participant in the issue' do
- before { allow(issue).to receive(:participants).with(user).and_return([user]) }
+ before do
+ allow(issue).to receive(:participants).with(user).and_return([user])
+ end
it 'returns false when no subcription exists' do
expect(issue.subscribed?(user, project)).to be_truthy
@@ -252,7 +256,9 @@ describe Issuable do
end
context "issue is assigned" do
- before { issue.assignees << user }
+ before do
+ issue.assignees << user
+ end
it "returns correct hook data" do
expect(data[:assignees].first).to eq(user.hook_attrs)
@@ -276,7 +282,9 @@ describe Issuable do
context 'issue has labels' do
let(:labels) { [create(:label), create(:label)] }
- before { issue.update_attribute(:labels, labels)}
+ before do
+ issue.update_attribute(:labels, labels)
+ end
it 'includes labels in the hook data' do
expect(data[:labels]).to eq(labels.map(&:hook_attrs))
diff --git a/spec/models/concerns/mentionable_spec.rb b/spec/models/concerns/mentionable_spec.rb
index e382c7120de..e2a29e0ae70 100644
--- a/spec/models/concerns/mentionable_spec.rb
+++ b/spec/models/concerns/mentionable_spec.rb
@@ -61,7 +61,9 @@ describe Issue, "Mentionable" do
end
context 'when the current user can see the issue' do
- before { private_project.team << [user, Gitlab::Access::DEVELOPER] }
+ before do
+ private_project.team << [user, Gitlab::Access::DEVELOPER]
+ end
it 'includes the reference' do
expect(referenced_issues(user)).to contain_exactly(private_issue, public_issue)
diff --git a/spec/models/concerns/reactive_caching_spec.rb b/spec/models/concerns/reactive_caching_spec.rb
index a0765a264cf..808247ebfd5 100644
--- a/spec/models/concerns/reactive_caching_spec.rb
+++ b/spec/models/concerns/reactive_caching_spec.rb
@@ -40,7 +40,10 @@ describe ReactiveCaching, caching: true do
let(:instance) { CacheTest.new(666, &calculation) }
describe '#with_reactive_cache' do
- before { stub_reactive_cache }
+ before do
+ stub_reactive_cache
+ end
+
subject(:go!) { instance.result }
context 'when cache is empty' do
@@ -60,12 +63,17 @@ describe ReactiveCaching, caching: true do
end
context 'when the cache is full' do
- before { stub_reactive_cache(instance, 4) }
+ before do
+ stub_reactive_cache(instance, 4)
+ end
it { is_expected.to eq(2) }
context 'and expired' do
- before { invalidate_reactive_cache(instance) }
+ before do
+ invalidate_reactive_cache(instance)
+ end
+
it { is_expected.to be_nil }
end
end
@@ -84,7 +92,9 @@ describe ReactiveCaching, caching: true do
subject(:go!) { instance.exclusively_update_reactive_cache! }
context 'when the lease is free and lifetime is not exceeded' do
- before { stub_reactive_cache(instance, "preexisting") }
+ before do
+ stub_reactive_cache(instance, "preexisting")
+ end
it 'takes and releases the lease' do
expect_any_instance_of(Gitlab::ExclusiveLease).to receive(:try_obtain).and_return("000000")
@@ -106,7 +116,10 @@ describe ReactiveCaching, caching: true do
end
context 'and #calculate_reactive_cache raises an exception' do
- before { stub_reactive_cache(instance, "preexisting") }
+ before do
+ stub_reactive_cache(instance, "preexisting")
+ end
+
let(:calculation) { -> { raise "foo"} }
it 'leaves the cache untouched' do
diff --git a/spec/models/concerns/token_authenticatable_spec.rb b/spec/models/concerns/token_authenticatable_spec.rb
index 4b0bfa43abf..882afeccfc6 100644
--- a/spec/models/concerns/token_authenticatable_spec.rb
+++ b/spec/models/concerns/token_authenticatable_spec.rb
@@ -49,7 +49,10 @@ describe ApplicationSetting, 'TokenAuthenticatable' do
end
context 'token is generated' do
- before { subject.send("reset_#{token_field}!") }
+ before do
+ subject.send("reset_#{token_field}!")
+ end
+
it 'persists a new token' do
expect(subject.send(:read_attribute, token_field)).to be_a String
end
diff --git a/spec/models/diff_viewer/base_spec.rb b/spec/models/diff_viewer/base_spec.rb
new file mode 100644
index 00000000000..3755f4a56f3
--- /dev/null
+++ b/spec/models/diff_viewer/base_spec.rb
@@ -0,0 +1,150 @@
+require 'spec_helper'
+
+describe DiffViewer::Base, model: true do
+ include FakeBlobHelpers
+
+ let(:project) { create(:project, :repository) }
+ let(:commit) { project.commit('570e7b2abdd848b95f2f578043fc23bd6f6fd24d') }
+ let(:diff_file) { commit.diffs.diff_file_with_new_path('files/ruby/popen.rb') }
+
+ let(:viewer_class) do
+ Class.new(described_class) do
+ include DiffViewer::ServerSide
+
+ self.extensions = %w(jpg)
+ self.binary = true
+ self.collapse_limit = 1.megabyte
+ self.size_limit = 5.megabytes
+ end
+ end
+
+ let(:viewer) { viewer_class.new(diff_file) }
+
+ describe '.can_render?' do
+ context 'when the extension is supported' do
+ let(:commit) { project.commit('2f63565e7aac07bcdadb654e253078b727143ec4') }
+ let(:diff_file) { commit.diffs.diff_file_with_new_path('files/images/6049019_460s.jpg') }
+
+ context 'when the binaryness matches' do
+ it 'returns true' do
+ expect(viewer_class.can_render?(diff_file)).to be_truthy
+ end
+ end
+
+ context 'when the binaryness does not match' do
+ before do
+ allow(diff_file.old_blob).to receive(:binary?).and_return(false)
+ allow(diff_file.new_blob).to receive(:binary?).and_return(false)
+ end
+
+ it 'returns false' do
+ expect(viewer_class.can_render?(diff_file)).to be_falsey
+ end
+ end
+ end
+
+ context 'when the file type is supported' do
+ let(:commit) { project.commit('1a0b36b3cdad1d2ee32457c102a8c0b7056fa863') }
+ let(:diff_file) { commit.diffs.diff_file_with_new_path('LICENSE') }
+
+ before do
+ viewer_class.file_types = %i(license)
+ viewer_class.binary = false
+ end
+
+ context 'when the binaryness matches' do
+ it 'returns true' do
+ expect(viewer_class.can_render?(diff_file)).to be_truthy
+ end
+ end
+
+ context 'when the binaryness does not match' do
+ before do
+ allow(diff_file.old_blob).to receive(:binary?).and_return(true)
+ allow(diff_file.new_blob).to receive(:binary?).and_return(true)
+ end
+
+ it 'returns false' do
+ expect(viewer_class.can_render?(diff_file)).to be_falsey
+ end
+ end
+ end
+
+ context 'when the extension and file type are not supported' do
+ it 'returns false' do
+ expect(viewer_class.can_render?(diff_file)).to be_falsey
+ end
+ end
+
+ context 'when the file was renamed and only the old blob is supported' do
+ let(:commit) { project.commit('2f63565e7aac07bcdadb654e253078b727143ec4') }
+ let(:diff_file) { commit.diffs.diff_file_with_new_path('files/images/6049019_460s.jpg') }
+
+ before do
+ allow(diff_file).to receive(:renamed_file?).and_return(true)
+ allow(diff_file.new_blob).to receive(:extension).and_return('jpeg')
+ end
+
+ it 'returns false' do
+ expect(viewer_class.can_render?(diff_file)).to be_falsey
+ end
+ end
+ end
+
+ describe '#collapsed?' do
+ context 'when the combined blob size is larger than the collapse limit' do
+ before do
+ allow(diff_file.old_blob).to receive(:raw_size).and_return(512.kilobytes)
+ allow(diff_file.new_blob).to receive(:raw_size).and_return(513.kilobytes)
+ end
+
+ it 'returns true' do
+ expect(viewer.collapsed?).to be_truthy
+ end
+ end
+
+ context 'when the combined blob size is smaller than the collapse limit' do
+ it 'returns false' do
+ expect(viewer.collapsed?).to be_falsey
+ end
+ end
+ end
+
+ describe '#too_large?' do
+ context 'when the combined blob size is larger than the size limit' do
+ before do
+ allow(diff_file.old_blob).to receive(:raw_size).and_return(2.megabytes)
+ allow(diff_file.new_blob).to receive(:raw_size).and_return(4.megabytes)
+ end
+
+ it 'returns true' do
+ expect(viewer.too_large?).to be_truthy
+ end
+ end
+
+ context 'when the blob size is smaller than the size limit' do
+ it 'returns false' do
+ expect(viewer.too_large?).to be_falsey
+ end
+ end
+ end
+
+ describe '#render_error' do
+ context 'when the combined blob size is larger than the size limit' do
+ before do
+ allow(diff_file.old_blob).to receive(:raw_size).and_return(2.megabytes)
+ allow(diff_file.new_blob).to receive(:raw_size).and_return(4.megabytes)
+ end
+
+ it 'returns :too_large' do
+ expect(viewer.render_error).to eq(:too_large)
+ end
+ end
+
+ context 'when the combined blob size is smaller than the size limit' do
+ it 'returns nil' do
+ expect(viewer.render_error).to be_nil
+ end
+ end
+ end
+end
diff --git a/spec/models/diff_viewer/server_side_spec.rb b/spec/models/diff_viewer/server_side_spec.rb
new file mode 100644
index 00000000000..2d926e06936
--- /dev/null
+++ b/spec/models/diff_viewer/server_side_spec.rb
@@ -0,0 +1,36 @@
+require 'spec_helper'
+
+describe DiffViewer::ServerSide, model: true do
+ let(:project) { create(:project, :repository) }
+ let(:commit) { project.commit('570e7b2abdd848b95f2f578043fc23bd6f6fd24d') }
+ let(:diff_file) { commit.diffs.diff_file_with_new_path('files/ruby/popen.rb') }
+
+ let(:viewer_class) do
+ Class.new(DiffViewer::Base) do
+ include DiffViewer::ServerSide
+ end
+ end
+
+ subject { viewer_class.new(diff_file) }
+
+ describe '#prepare!' do
+ it 'loads all diff file data' do
+ expect(diff_file.old_blob).to receive(:load_all_data!)
+ expect(diff_file.new_blob).to receive(:load_all_data!)
+
+ subject.prepare!
+ end
+ end
+
+ describe '#render_error' do
+ context 'when the diff file is stored externally' do
+ before do
+ allow(diff_file).to receive(:stored_externally?).and_return(true)
+ end
+
+ it 'return :server_side_but_stored_externally' do
+ expect(subject.render_error).to eq(:server_side_but_stored_externally)
+ end
+ end
+ end
+end
diff --git a/spec/models/generic_commit_status_spec.rb b/spec/models/generic_commit_status_spec.rb
index f4c3e6d503f..152e97e09bf 100644
--- a/spec/models/generic_commit_status_spec.rb
+++ b/spec/models/generic_commit_status_spec.rb
@@ -19,7 +19,10 @@ describe GenericCommitStatus, models: true do
describe '#context' do
subject { generic_commit_status.context }
- before { generic_commit_status.context = 'my_context' }
+
+ before do
+ generic_commit_status.context = 'my_context'
+ end
it { is_expected.to eq(generic_commit_status.name) }
end
@@ -39,7 +42,9 @@ describe GenericCommitStatus, models: true do
end
context 'when user has ability to see datails' do
- before { project.team << [user, :developer] }
+ before do
+ project.team << [user, :developer]
+ end
it 'details path points to an external URL' do
expect(status).to have_details
diff --git a/spec/models/group_spec.rb b/spec/models/group_spec.rb
index 3d437ca0fcc..449b7c2f7d7 100644
--- a/spec/models/group_spec.rb
+++ b/spec/models/group_spec.rb
@@ -143,14 +143,20 @@ describe Group, models: true do
describe '#add_user' do
let(:user) { create(:user) }
- before { group.add_user(user, GroupMember::MASTER) }
+
+ before do
+ group.add_user(user, GroupMember::MASTER)
+ end
it { expect(group.group_members.masters.map(&:user)).to include(user) }
end
describe '#add_users' do
let(:user) { create(:user) }
- before { group.add_users([user.id], GroupMember::GUEST) }
+
+ before do
+ group.add_users([user.id], GroupMember::GUEST)
+ end
it "updates the group permission" do
expect(group.group_members.guests.map(&:user)).to include(user)
@@ -162,7 +168,10 @@ describe Group, models: true do
describe '#avatar_type' do
let(:user) { create(:user) }
- before { group.add_user(user, GroupMember::MASTER) }
+
+ before do
+ group.add_user(user, GroupMember::MASTER)
+ end
it "is true if avatar is image" do
group.update_attribute(:avatar, 'uploads/avatar.png')
@@ -182,7 +191,9 @@ describe Group, models: true do
let(:avatar_path) { "/uploads/system/group/avatar/#{group.id}/dk.png" }
context 'when avatar file is uploaded' do
- before { group.add_master(user) }
+ before do
+ group.add_master(user)
+ end
it 'shows correct avatar url' do
expect(group.avatar_url).to eq(avatar_path)
@@ -222,7 +233,9 @@ describe Group, models: true do
end
describe '#has_owner?' do
- before { @members = setup_group_members(group) }
+ before do
+ @members = setup_group_members(group)
+ end
it { expect(group.has_owner?(@members[:owner])).to be_truthy }
it { expect(group.has_owner?(@members[:master])).to be_falsey }
@@ -233,7 +246,9 @@ describe Group, models: true do
end
describe '#has_master?' do
- before { @members = setup_group_members(group) }
+ before do
+ @members = setup_group_members(group)
+ end
it { expect(group.has_master?(@members[:owner])).to be_falsey }
it { expect(group.has_master?(@members[:master])).to be_truthy }
diff --git a/spec/models/issue_spec.rb b/spec/models/issue_spec.rb
index bb4e70db2e9..12e7d646382 100644
--- a/spec/models/issue_spec.rb
+++ b/spec/models/issue_spec.rb
@@ -245,7 +245,9 @@ describe Issue, models: true do
let(:project) { create(:empty_project) }
let(:issue) { create(:issue, project: project) }
- before { project.team << [user, :reporter] }
+ before do
+ project.team << [user, :reporter]
+ end
it { is_expected.to eq true }
@@ -259,12 +261,18 @@ describe Issue, models: true do
let(:to_project) { create(:empty_project) }
context 'destination project allowed' do
- before { to_project.team << [user, :reporter] }
+ before do
+ to_project.team << [user, :reporter]
+ end
+
it { is_expected.to eq true }
end
context 'destination project not allowed' do
- before { to_project.team << [user, :guest] }
+ before do
+ to_project.team << [user, :guest]
+ end
+
it { is_expected.to eq false }
end
end
@@ -549,7 +557,9 @@ describe Issue, models: true do
end
context 'when the user is the project owner' do
- before { project.team << [user, :master] }
+ before do
+ project.team << [user, :master]
+ end
it 'returns true for a regular issue' do
issue = build(:issue, project: project)
diff --git a/spec/models/merge_request_diff_spec.rb b/spec/models/merge_request_diff_spec.rb
index ed9fde57bf7..25f7062860b 100644
--- a/spec/models/merge_request_diff_spec.rb
+++ b/spec/models/merge_request_diff_spec.rb
@@ -36,7 +36,9 @@ describe MergeRequestDiff, models: true do
end
context 'when the raw diffs are empty' do
- before { mr_diff.update_attributes(st_diffs: '') }
+ before do
+ mr_diff.update_attributes(st_diffs: '')
+ end
it 'returns an empty DiffCollection' do
expect(mr_diff.raw_diffs).to be_a(Gitlab::Git::DiffCollection)
@@ -45,7 +47,9 @@ describe MergeRequestDiff, models: true do
end
context 'when the raw diffs have invalid content' do
- before { mr_diff.update_attributes(st_diffs: ["--broken-diff"]) }
+ before do
+ mr_diff.update_attributes(st_diffs: ["--broken-diff"])
+ end
it 'returns an empty DiffCollection' do
expect(mr_diff.raw_diffs.to_a).to be_empty
diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb
index 060754fab63..cd2f11dec96 100644
--- a/spec/models/merge_request_spec.rb
+++ b/spec/models/merge_request_spec.rb
@@ -892,7 +892,9 @@ describe MergeRequest, models: true do
end
context 'when broken' do
- before { allow(subject).to receive(:broken?) { true } }
+ before do
+ allow(subject).to receive(:broken?) { true }
+ end
it 'becomes unmergeable' do
expect { subject.check_if_can_be_merged }.to change { subject.merge_status }.to('cannot_be_merged')
@@ -944,7 +946,9 @@ describe MergeRequest, models: true do
end
context 'when not open' do
- before { subject.close }
+ before do
+ subject.close
+ end
it 'returns false' do
expect(subject.mergeable_state?).to be_falsey
@@ -952,7 +956,9 @@ describe MergeRequest, models: true do
end
context 'when working in progress' do
- before { subject.title = 'WIP MR' }
+ before do
+ subject.title = 'WIP MR'
+ end
it 'returns false' do
expect(subject.mergeable_state?).to be_falsey
@@ -960,7 +966,9 @@ describe MergeRequest, models: true do
end
context 'when broken' do
- before { allow(subject).to receive(:broken?) { true } }
+ before do
+ allow(subject).to receive(:broken?) { true }
+ end
it 'returns false' do
expect(subject.mergeable_state?).to be_falsey
diff --git a/spec/models/note_spec.rb b/spec/models/note_spec.rb
index 7a01cef9b4b..d4d4fc86343 100644
--- a/spec/models/note_spec.rb
+++ b/spec/models/note_spec.rb
@@ -26,14 +26,18 @@ describe Note, models: true do
it { is_expected.to validate_presence_of(:project) }
context 'when note is on commit' do
- before { allow(subject).to receive(:for_commit?).and_return(true) }
+ before do
+ allow(subject).to receive(:for_commit?).and_return(true)
+ end
it { is_expected.to validate_presence_of(:commit_id) }
it { is_expected.not_to validate_presence_of(:noteable_id) }
end
context 'when note is not on commit' do
- before { allow(subject).to receive(:for_commit?).and_return(false) }
+ before do
+ allow(subject).to receive(:for_commit?).and_return(false)
+ end
it { is_expected.not_to validate_presence_of(:commit_id) }
it { is_expected.to validate_presence_of(:noteable_id) }
diff --git a/spec/models/project_services/bamboo_service_spec.rb b/spec/models/project_services/bamboo_service_spec.rb
index 4014d6129ee..e62fd69e567 100644
--- a/spec/models/project_services/bamboo_service_spec.rb
+++ b/spec/models/project_services/bamboo_service_spec.rb
@@ -24,7 +24,9 @@ describe BambooService, models: true, caching: true do
describe 'Validations' do
context 'when service is active' do
- before { subject.active = true }
+ before do
+ subject.active = true
+ end
it { is_expected.to validate_presence_of(:build_key) }
it { is_expected.to validate_presence_of(:bamboo_url) }
@@ -60,7 +62,9 @@ describe BambooService, models: true, caching: true do
end
context 'when service is inactive' do
- before { subject.active = false }
+ before do
+ subject.active = false
+ end
it { is_expected.not_to validate_presence_of(:build_key) }
it { is_expected.not_to validate_presence_of(:bamboo_url) }
diff --git a/spec/models/project_services/bugzilla_service_spec.rb b/spec/models/project_services/bugzilla_service_spec.rb
index 739cc72b2ff..5f17bbde390 100644
--- a/spec/models/project_services/bugzilla_service_spec.rb
+++ b/spec/models/project_services/bugzilla_service_spec.rb
@@ -8,7 +8,9 @@ describe BugzillaService, models: true do
describe 'Validations' do
context 'when service is active' do
- before { subject.active = true }
+ before do
+ subject.active = true
+ end
it { is_expected.to validate_presence_of(:project_url) }
it { is_expected.to validate_presence_of(:issues_url) }
@@ -19,7 +21,9 @@ describe BugzillaService, models: true do
end
context 'when service is inactive' do
- before { subject.active = false }
+ before do
+ subject.active = false
+ end
it { is_expected.not_to validate_presence_of(:project_url) }
it { is_expected.not_to validate_presence_of(:issues_url) }
diff --git a/spec/models/project_services/buildkite_service_spec.rb b/spec/models/project_services/buildkite_service_spec.rb
index 05b602d8106..dd529597067 100644
--- a/spec/models/project_services/buildkite_service_spec.rb
+++ b/spec/models/project_services/buildkite_service_spec.rb
@@ -23,7 +23,9 @@ describe BuildkiteService, models: true, caching: true do
describe 'Validations' do
context 'when service is active' do
- before { subject.active = true }
+ before do
+ subject.active = true
+ end
it { is_expected.to validate_presence_of(:project_url) }
it { is_expected.to validate_presence_of(:token) }
@@ -31,7 +33,9 @@ describe BuildkiteService, models: true, caching: true do
end
context 'when service is inactive' do
- before { subject.active = false }
+ before do
+ subject.active = false
+ end
it { is_expected.not_to validate_presence_of(:project_url) }
it { is_expected.not_to validate_presence_of(:token) }
diff --git a/spec/models/project_services/campfire_service_spec.rb b/spec/models/project_services/campfire_service_spec.rb
index 953e664fb66..de55627dd27 100644
--- a/spec/models/project_services/campfire_service_spec.rb
+++ b/spec/models/project_services/campfire_service_spec.rb
@@ -8,13 +8,17 @@ describe CampfireService, models: true do
describe 'Validations' do
context 'when service is active' do
- before { subject.active = true }
+ before do
+ subject.active = true
+ end
it { is_expected.to validate_presence_of(:token) }
end
context 'when service is inactive' do
- before { subject.active = false }
+ before do
+ subject.active = false
+ end
it { is_expected.not_to validate_presence_of(:token) }
end
diff --git a/spec/models/project_services/chat_message/wiki_page_message_spec.rb b/spec/models/project_services/chat_message/wiki_page_message_spec.rb
index 4ca1b8aa7b7..17355c1e6f1 100644
--- a/spec/models/project_services/chat_message/wiki_page_message_spec.rb
+++ b/spec/models/project_services/chat_message/wiki_page_message_spec.rb
@@ -23,7 +23,9 @@ describe ChatMessage::WikiPageMessage, models: true do
context 'without markdown' do
describe '#pretext' do
context 'when :action == "create"' do
- before { args[:object_attributes][:action] = 'create' }
+ before do
+ args[:object_attributes][:action] = 'create'
+ end
it 'returns a message that a new wiki page was created' do
expect(subject.pretext).to eq(
@@ -33,7 +35,9 @@ describe ChatMessage::WikiPageMessage, models: true do
end
context 'when :action == "update"' do
- before { args[:object_attributes][:action] = 'update' }
+ before do
+ args[:object_attributes][:action] = 'update'
+ end
it 'returns a message that a wiki page was updated' do
expect(subject.pretext).to eq(
@@ -47,7 +51,9 @@ describe ChatMessage::WikiPageMessage, models: true do
let(:color) { '#345' }
context 'when :action == "create"' do
- before { args[:object_attributes][:action] = 'create' }
+ before do
+ args[:object_attributes][:action] = 'create'
+ end
it 'returns the attachment for a new wiki page' do
expect(subject.attachments).to eq([
@@ -60,7 +66,9 @@ describe ChatMessage::WikiPageMessage, models: true do
end
context 'when :action == "update"' do
- before { args[:object_attributes][:action] = 'update' }
+ before do
+ args[:object_attributes][:action] = 'update'
+ end
it 'returns the attachment for an updated wiki page' do
expect(subject.attachments).to eq([
@@ -81,7 +89,9 @@ describe ChatMessage::WikiPageMessage, models: true do
describe '#pretext' do
context 'when :action == "create"' do
- before { args[:object_attributes][:action] = 'create' }
+ before do
+ args[:object_attributes][:action] = 'create'
+ end
it 'returns a message that a new wiki page was created' do
expect(subject.pretext).to eq(
@@ -90,7 +100,9 @@ describe ChatMessage::WikiPageMessage, models: true do
end
context 'when :action == "update"' do
- before { args[:object_attributes][:action] = 'update' }
+ before do
+ args[:object_attributes][:action] = 'update'
+ end
it 'returns a message that a wiki page was updated' do
expect(subject.pretext).to eq(
@@ -101,7 +113,9 @@ describe ChatMessage::WikiPageMessage, models: true do
describe '#attachments' do
context 'when :action == "create"' do
- before { args[:object_attributes][:action] = 'create' }
+ before do
+ args[:object_attributes][:action] = 'create'
+ end
it 'returns the attachment for a new wiki page' do
expect(subject.attachments).to eq('Wiki page description')
@@ -109,7 +123,9 @@ describe ChatMessage::WikiPageMessage, models: true do
end
context 'when :action == "update"' do
- before { args[:object_attributes][:action] = 'update' }
+ before do
+ args[:object_attributes][:action] = 'update'
+ end
it 'returns the attachment for an updated wiki page' do
expect(subject.attachments).to eq('Wiki page description')
@@ -119,7 +135,9 @@ describe ChatMessage::WikiPageMessage, models: true do
describe '#activity' do
context 'when :action == "create"' do
- before { args[:object_attributes][:action] = 'create' }
+ before do
+ args[:object_attributes][:action] = 'create'
+ end
it 'returns the attachment for a new wiki page' do
expect(subject.activity).to eq({
@@ -132,7 +150,9 @@ describe ChatMessage::WikiPageMessage, models: true do
end
context 'when :action == "update"' do
- before { args[:object_attributes][:action] = 'update' }
+ before do
+ args[:object_attributes][:action] = 'update'
+ end
it 'returns the attachment for an updated wiki page' do
expect(subject.activity).to eq({
diff --git a/spec/models/project_services/custom_issue_tracker_service_spec.rb b/spec/models/project_services/custom_issue_tracker_service_spec.rb
index 63320931e76..9e574762232 100644
--- a/spec/models/project_services/custom_issue_tracker_service_spec.rb
+++ b/spec/models/project_services/custom_issue_tracker_service_spec.rb
@@ -8,7 +8,9 @@ describe CustomIssueTrackerService, models: true do
describe 'Validations' do
context 'when service is active' do
- before { subject.active = true }
+ before do
+ subject.active = true
+ end
it { is_expected.to validate_presence_of(:project_url) }
it { is_expected.to validate_presence_of(:issues_url) }
@@ -19,7 +21,9 @@ describe CustomIssueTrackerService, models: true do
end
context 'when service is inactive' do
- before { subject.active = false }
+ before do
+ subject.active = false
+ end
it { is_expected.not_to validate_presence_of(:project_url) }
it { is_expected.not_to validate_presence_of(:issues_url) }
diff --git a/spec/models/project_services/drone_ci_service_spec.rb b/spec/models/project_services/drone_ci_service_spec.rb
index 044737c6026..1400175427f 100644
--- a/spec/models/project_services/drone_ci_service_spec.rb
+++ b/spec/models/project_services/drone_ci_service_spec.rb
@@ -10,7 +10,9 @@ describe DroneCiService, models: true, caching: true do
describe 'validations' do
context 'active' do
- before { subject.active = true }
+ before do
+ subject.active = true
+ end
it { is_expected.to validate_presence_of(:token) }
it { is_expected.to validate_presence_of(:drone_url) }
@@ -18,7 +20,9 @@ describe DroneCiService, models: true, caching: true do
end
context 'inactive' do
- before { subject.active = false }
+ before do
+ subject.active = false
+ end
it { is_expected.not_to validate_presence_of(:token) }
it { is_expected.not_to validate_presence_of(:drone_url) }
diff --git a/spec/models/project_services/emails_on_push_service_spec.rb b/spec/models/project_services/emails_on_push_service_spec.rb
index e6f78898c82..d9b7010e5e5 100644
--- a/spec/models/project_services/emails_on_push_service_spec.rb
+++ b/spec/models/project_services/emails_on_push_service_spec.rb
@@ -3,13 +3,17 @@ require 'spec_helper'
describe EmailsOnPushService do
describe 'Validations' do
context 'when service is active' do
- before { subject.active = true }
+ before do
+ subject.active = true
+ end
it { is_expected.to validate_presence_of(:recipients) }
end
context 'when service is inactive' do
- before { subject.active = false }
+ before do
+ subject.active = false
+ end
it { is_expected.not_to validate_presence_of(:recipients) }
end
diff --git a/spec/models/project_services/external_wiki_service_spec.rb b/spec/models/project_services/external_wiki_service_spec.rb
index bdeea1db1e3..291fc645a1c 100644
--- a/spec/models/project_services/external_wiki_service_spec.rb
+++ b/spec/models/project_services/external_wiki_service_spec.rb
@@ -9,14 +9,18 @@ describe ExternalWikiService, models: true do
describe 'Validations' do
context 'when service is active' do
- before { subject.active = true }
+ before do
+ subject.active = true
+ end
it { is_expected.to validate_presence_of(:external_wiki_url) }
it_behaves_like 'issue tracker service URL attribute', :external_wiki_url
end
context 'when service is inactive' do
- before { subject.active = false }
+ before do
+ subject.active = false
+ end
it { is_expected.not_to validate_presence_of(:external_wiki_url) }
end
diff --git a/spec/models/project_services/flowdock_service_spec.rb b/spec/models/project_services/flowdock_service_spec.rb
index a97e8c6e4ce..56ace04dd58 100644
--- a/spec/models/project_services/flowdock_service_spec.rb
+++ b/spec/models/project_services/flowdock_service_spec.rb
@@ -8,13 +8,17 @@ describe FlowdockService, models: true do
describe 'Validations' do
context 'when service is active' do
- before { subject.active = true }
+ before do
+ subject.active = true
+ end
it { is_expected.to validate_presence_of(:token) }
end
context 'when service is inactive' do
- before { subject.active = false }
+ before do
+ subject.active = false
+ end
it { is_expected.not_to validate_presence_of(:token) }
end
diff --git a/spec/models/project_services/gemnasium_service_spec.rb b/spec/models/project_services/gemnasium_service_spec.rb
index a13fbae03eb..65c9e714bd1 100644
--- a/spec/models/project_services/gemnasium_service_spec.rb
+++ b/spec/models/project_services/gemnasium_service_spec.rb
@@ -8,14 +8,18 @@ describe GemnasiumService, models: true do
describe 'Validations' do
context 'when service is active' do
- before { subject.active = true }
+ before do
+ subject.active = true
+ end
it { is_expected.to validate_presence_of(:token) }
it { is_expected.to validate_presence_of(:api_key) }
end
context 'when service is inactive' do
- before { subject.active = false }
+ before do
+ subject.active = false
+ end
it { is_expected.not_to validate_presence_of(:token) }
it { is_expected.not_to validate_presence_of(:api_key) }
diff --git a/spec/models/project_services/hipchat_service_spec.rb b/spec/models/project_services/hipchat_service_spec.rb
index 1200ae7eb22..c7c8e9651ab 100644
--- a/spec/models/project_services/hipchat_service_spec.rb
+++ b/spec/models/project_services/hipchat_service_spec.rb
@@ -8,13 +8,17 @@ describe HipchatService, models: true do
describe 'Validations' do
context 'when service is active' do
- before { subject.active = true }
+ before do
+ subject.active = true
+ end
it { is_expected.to validate_presence_of(:token) }
end
context 'when service is inactive' do
- before { subject.active = false }
+ before do
+ subject.active = false
+ end
it { is_expected.not_to validate_presence_of(:token) }
end
diff --git a/spec/models/project_services/irker_service_spec.rb b/spec/models/project_services/irker_service_spec.rb
index d5a16226d9d..a5c4938b54e 100644
--- a/spec/models/project_services/irker_service_spec.rb
+++ b/spec/models/project_services/irker_service_spec.rb
@@ -10,13 +10,17 @@ describe IrkerService, models: true do
describe 'Validations' do
context 'when service is active' do
- before { subject.active = true }
+ before do
+ subject.active = true
+ end
it { is_expected.to validate_presence_of(:recipients) }
end
context 'when service is inactive' do
- before { subject.active = false }
+ before do
+ subject.active = false
+ end
it { is_expected.not_to validate_presence_of(:recipients) }
end
diff --git a/spec/models/project_services/jira_service_spec.rb b/spec/models/project_services/jira_service_spec.rb
index 0ee050196e4..e2b8226124f 100644
--- a/spec/models/project_services/jira_service_spec.rb
+++ b/spec/models/project_services/jira_service_spec.rb
@@ -10,7 +10,9 @@ describe JiraService, models: true do
describe 'Validations' do
context 'when service is active' do
- before { subject.active = true }
+ before do
+ subject.active = true
+ end
it { is_expected.to validate_presence_of(:url) }
it { is_expected.to validate_presence_of(:project_key) }
@@ -18,7 +20,9 @@ describe JiraService, models: true do
end
context 'when service is inactive' do
- before { subject.active = false }
+ before do
+ subject.active = false
+ end
it { is_expected.not_to validate_presence_of(:url) }
end
diff --git a/spec/models/project_services/kubernetes_service_spec.rb b/spec/models/project_services/kubernetes_service_spec.rb
index 0dcf4a4b5d6..858ad595dbf 100644
--- a/spec/models/project_services/kubernetes_service_spec.rb
+++ b/spec/models/project_services/kubernetes_service_spec.rb
@@ -7,31 +7,15 @@ describe KubernetesService, models: true, caching: true do
let(:project) { build_stubbed(:kubernetes_project) }
let(:service) { project.kubernetes_service }
- # We use Kubeclient to interactive with the Kubernetes API. It will
- # GET /api/v1 for a list of resources the API supports. This must be stubbed
- # in addition to any other HTTP requests we expect it to perform.
- let(:discovery_url) { service.api_url + '/api/v1' }
- let(:discovery_response) { { body: kube_discovery_body.to_json } }
-
- let(:pods_url) { service.api_url + "/api/v1/namespaces/#{service.actual_namespace}/pods" }
- let(:pods_response) { { body: kube_pods_body(kube_pod).to_json } }
-
- def stub_kubeclient_discover
- WebMock.stub_request(:get, discovery_url).to_return(discovery_response)
- end
-
- def stub_kubeclient_pods
- stub_kubeclient_discover
- WebMock.stub_request(:get, pods_url).to_return(pods_response)
- end
-
describe "Associations" do
it { is_expected.to belong_to :project }
end
describe 'Validations' do
context 'when service is active' do
- before { subject.active = true }
+ before do
+ subject.active = true
+ end
it { is_expected.not_to validate_presence_of(:namespace) }
it { is_expected.to validate_presence_of(:api_url) }
@@ -66,7 +50,9 @@ describe KubernetesService, models: true, caching: true do
end
context 'when service is inactive' do
- before { subject.active = false }
+ before do
+ subject.active = false
+ end
it { is_expected.not_to validate_presence_of(:api_url) }
it { is_expected.not_to validate_presence_of(:token) }
@@ -87,7 +73,9 @@ describe KubernetesService, models: true, caching: true do
end
context 'as template' do
- before { subject.template = true }
+ before do
+ subject.template = true
+ end
it 'sets the namespace to the default' do
expect(kube_namespace).not_to be_nil
@@ -96,7 +84,9 @@ describe KubernetesService, models: true, caching: true do
end
context 'with associated project' do
- before { subject.project = project }
+ before do
+ subject.project = project
+ end
it 'sets the namespace to the default' do
expect(kube_namespace).not_to be_nil
@@ -111,6 +101,34 @@ describe KubernetesService, models: true, caching: true do
it "returns the default namespace" do
is_expected.to eq(service.send(:default_namespace))
end
+
+ context 'when namespace is specified' do
+ before do
+ service.namespace = 'my-namespace'
+ end
+
+ it "returns the user-namespace" do
+ is_expected.to eq('my-namespace')
+ end
+ end
+
+ context 'when service is not assigned to project' do
+ before do
+ service.project = nil
+ end
+
+ it "does not return namespace" do
+ is_expected.to be_nil
+ end
+ end
+ end
+
+ describe '#actual_namespace' do
+ subject { service.actual_namespace }
+
+ it "returns the default namespace" do
+ is_expected.to eq(service.send(:default_namespace))
+ end
context 'when namespace is specified' do
before do
@@ -134,6 +152,8 @@ describe KubernetesService, models: true, caching: true do
end
describe '#test' do
+ let(:discovery_url) { 'https://kubernetes.example.com/api/v1' }
+
before do
stub_kubeclient_discover
end
@@ -142,7 +162,8 @@ describe KubernetesService, models: true, caching: true do
let(:discovery_url) { 'https://kubernetes.example.com/prefix/api/v1' }
it 'tests with the prefix' do
- service.api_url = 'https://kubernetes.example.com/prefix/'
+ service.api_url = 'https://kubernetes.example.com/prefix'
+ stub_kubeclient_discover
expect(service.test[:success]).to be_truthy
expect(WebMock).to have_requested(:get, discovery_url).once
@@ -170,9 +191,9 @@ describe KubernetesService, models: true, caching: true do
end
context 'failure' do
- let(:discovery_response) { { status: 404 } }
-
it 'fails to read the discovery endpoint' do
+ WebMock.stub_request(:get, service.api_url + '/api/v1').to_return(status: 404)
+
expect(service.test[:success]).to be_falsy
expect(WebMock).to have_requested(:get, discovery_url).once
end
@@ -188,7 +209,9 @@ describe KubernetesService, models: true, caching: true do
end
context 'namespace is provided' do
- before { subject.namespace = 'my-project' }
+ before do
+ subject.namespace = 'my-project'
+ end
it 'sets the variables' do
expect(subject.predefined_variables).to include(
@@ -258,27 +281,36 @@ describe KubernetesService, models: true, caching: true do
end
describe '#calculate_reactive_cache' do
- before { stub_kubeclient_pods }
subject { service.calculate_reactive_cache }
context 'when service is inactive' do
- before { service.active = false }
+ before do
+ service.active = false
+ end
it { is_expected.to be_nil }
end
context 'when kubernetes responds with valid pods' do
+ before do
+ stub_kubeclient_pods
+ end
+
it { is_expected.to eq(pods: [kube_pod]) }
end
- context 'when kubernetes responds with 500' do
- let(:pods_response) { { status: 500 } }
+ context 'when kubernetes responds with 500s' do
+ before do
+ stub_kubeclient_pods(status: 500)
+ end
it { expect { subject }.to raise_error(KubeException) }
end
- context 'when kubernetes responds with 404' do
- let(:pods_response) { { status: 404 } }
+ context 'when kubernetes responds with 404s' do
+ before do
+ stub_kubeclient_pods(status: 404)
+ end
it { is_expected.to eq(pods: []) }
end
diff --git a/spec/models/project_services/microsoft_teams_service_spec.rb b/spec/models/project_services/microsoft_teams_service_spec.rb
index facc034f69c..bd50a2d1470 100644
--- a/spec/models/project_services/microsoft_teams_service_spec.rb
+++ b/spec/models/project_services/microsoft_teams_service_spec.rb
@@ -11,14 +11,18 @@ describe MicrosoftTeamsService, models: true do
describe 'Validations' do
context 'when service is active' do
- before { subject.active = true }
+ before do
+ subject.active = true
+ end
it { is_expected.to validate_presence_of(:webhook) }
it_behaves_like 'issue tracker service URL attribute', :webhook
end
context 'when service is inactive' do
- before { subject.active = false }
+ before do
+ subject.active = false
+ end
it { is_expected.not_to validate_presence_of(:webhook) }
end
diff --git a/spec/models/project_services/pivotaltracker_service_spec.rb b/spec/models/project_services/pivotaltracker_service_spec.rb
index a76e909d04d..f4c1a9c94b6 100644
--- a/spec/models/project_services/pivotaltracker_service_spec.rb
+++ b/spec/models/project_services/pivotaltracker_service_spec.rb
@@ -8,13 +8,17 @@ describe PivotaltrackerService, models: true do
describe 'Validations' do
context 'when service is active' do
- before { subject.active = true }
+ before do
+ subject.active = true
+ end
it { is_expected.to validate_presence_of(:token) }
end
context 'when service is inactive' do
- before { subject.active = false }
+ before do
+ subject.active = false
+ end
it { is_expected.not_to validate_presence_of(:token) }
end
diff --git a/spec/models/project_services/prometheus_service_spec.rb b/spec/models/project_services/prometheus_service_spec.rb
index 1f9d3c07b51..71b53732164 100644
--- a/spec/models/project_services/prometheus_service_spec.rb
+++ b/spec/models/project_services/prometheus_service_spec.rb
@@ -14,13 +14,17 @@ describe PrometheusService, models: true, caching: true do
describe 'Validations' do
context 'when service is active' do
- before { subject.active = true }
+ before do
+ subject.active = true
+ end
it { is_expected.to validate_presence_of(:api_url) }
end
context 'when service is inactive' do
- before { subject.active = false }
+ before do
+ subject.active = false
+ end
it { is_expected.not_to validate_presence_of(:api_url) }
end
diff --git a/spec/models/project_services/pushover_service_spec.rb b/spec/models/project_services/pushover_service_spec.rb
index a7e7594a7d5..9171d9604ee 100644
--- a/spec/models/project_services/pushover_service_spec.rb
+++ b/spec/models/project_services/pushover_service_spec.rb
@@ -8,7 +8,9 @@ describe PushoverService, models: true do
describe 'Validations' do
context 'when service is active' do
- before { subject.active = true }
+ before do
+ subject.active = true
+ end
it { is_expected.to validate_presence_of(:api_key) }
it { is_expected.to validate_presence_of(:user_key) }
@@ -16,7 +18,9 @@ describe PushoverService, models: true do
end
context 'when service is inactive' do
- before { subject.active = false }
+ before do
+ subject.active = false
+ end
it { is_expected.not_to validate_presence_of(:api_key) }
it { is_expected.not_to validate_presence_of(:user_key) }
diff --git a/spec/models/project_services/redmine_service_spec.rb b/spec/models/project_services/redmine_service_spec.rb
index 0a7b237a051..6631d9040b1 100644
--- a/spec/models/project_services/redmine_service_spec.rb
+++ b/spec/models/project_services/redmine_service_spec.rb
@@ -8,7 +8,9 @@ describe RedmineService, models: true do
describe 'Validations' do
context 'when service is active' do
- before { subject.active = true }
+ before do
+ subject.active = true
+ end
it { is_expected.to validate_presence_of(:project_url) }
it { is_expected.to validate_presence_of(:issues_url) }
@@ -19,7 +21,9 @@ describe RedmineService, models: true do
end
context 'when service is inactive' do
- before { subject.active = false }
+ before do
+ subject.active = false
+ end
it { is_expected.not_to validate_presence_of(:project_url) }
it { is_expected.not_to validate_presence_of(:issues_url) }
diff --git a/spec/models/project_services/teamcity_service_spec.rb b/spec/models/project_services/teamcity_service_spec.rb
index 77b18e1c7d0..7349eb4149a 100644
--- a/spec/models/project_services/teamcity_service_spec.rb
+++ b/spec/models/project_services/teamcity_service_spec.rb
@@ -24,7 +24,9 @@ describe TeamcityService, models: true, caching: true do
describe 'Validations' do
context 'when service is active' do
- before { subject.active = true }
+ before do
+ subject.active = true
+ end
it { is_expected.to validate_presence_of(:build_type) }
it { is_expected.to validate_presence_of(:teamcity_url) }
@@ -60,7 +62,9 @@ describe TeamcityService, models: true, caching: true do
end
context 'when service is inactive' do
- before { subject.active = false }
+ before do
+ subject.active = false
+ end
it { is_expected.not_to validate_presence_of(:build_type) }
it { is_expected.not_to validate_presence_of(:teamcity_url) }
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index 454eeb58ecd..63333b7af1f 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -1005,13 +1005,17 @@ describe Project, models: true do
subject { project.shared_runners_enabled }
context 'are enabled' do
- before { stub_application_setting(shared_runners_enabled: true) }
+ before do
+ stub_application_setting(shared_runners_enabled: true)
+ end
it { is_expected.to be_truthy }
end
context 'are disabled' do
- before { stub_application_setting(shared_runners_enabled: false) }
+ before do
+ stub_application_setting(shared_runners_enabled: false)
+ end
it { is_expected.to be_falsey }
end
@@ -1107,7 +1111,9 @@ describe Project, models: true do
subject { project.pages_deployed? }
context 'if public folder does exist' do
- before { allow(Dir).to receive(:exist?).with(project.public_pages_path).and_return(true) }
+ before do
+ allow(Dir).to receive(:exist?).with(project.public_pages_path).and_return(true)
+ end
it { is_expected.to be_truthy }
end
@@ -1365,7 +1371,9 @@ describe Project, models: true do
subject { project.container_registry_url }
- before { stub_container_registry_config(**registry_settings) }
+ before do
+ stub_container_registry_config(**registry_settings)
+ end
context 'for enabled registry' do
let(:registry_settings) do
@@ -1389,7 +1397,9 @@ describe Project, models: true do
let(:project) { create(:empty_project) }
context 'when container registry is enabled' do
- before { stub_container_registry_config(enabled: true) }
+ before do
+ stub_container_registry_config(enabled: true)
+ end
context 'when tags are present for multi-level registries' do
before do
@@ -1427,7 +1437,9 @@ describe Project, models: true do
end
context 'when container registry is disabled' do
- before { stub_container_registry_config(enabled: false) }
+ before do
+ stub_container_registry_config(enabled: false)
+ end
it 'should not have image tags' do
expect(project).not_to have_container_registry_tags
@@ -1945,7 +1957,9 @@ describe Project, models: true do
describe '#parent_changed?' do
let(:project) { create(:empty_project) }
- before { project.namespace_id = 7 }
+ before do
+ project.namespace_id = 7
+ end
it { expect(project.parent_changed?).to be_truthy }
end
diff --git a/spec/models/project_team_spec.rb b/spec/models/project_team_spec.rb
index 497e3cdf415..ea3cd5fe10a 100644
--- a/spec/models/project_team_spec.rb
+++ b/spec/models/project_team_spec.rb
@@ -240,7 +240,9 @@ describe ProjectTeam, models: true do
it { expect(project.team.max_member_access(requester.id)).to eq(Gitlab::Access::NO_ACCESS) }
context 'but share_with_group_lock is true' do
- before { project.namespace.update(share_with_group_lock: true) }
+ before do
+ project.namespace.update(share_with_group_lock: true)
+ end
it { expect(project.team.max_member_access(master.id)).to eq(Gitlab::Access::NO_ACCESS) }
it { expect(project.team.max_member_access(reporter.id)).to eq(Gitlab::Access::NO_ACCESS) }
diff --git a/spec/models/project_wiki_spec.rb b/spec/models/project_wiki_spec.rb
index 224067f58dd..3f5f4eea4a1 100644
--- a/spec/models/project_wiki_spec.rb
+++ b/spec/models/project_wiki_spec.rb
@@ -8,7 +8,10 @@ describe ProjectWiki, models: true do
let(:project_wiki) { ProjectWiki.new(project, user) }
subject { project_wiki }
- before { project_wiki.wiki }
+
+ before do
+ project_wiki.wiki
+ end
describe "#path_with_namespace" do
it "returns the project path with namespace with the .wiki extension" do
diff --git a/spec/models/route_spec.rb b/spec/models/route_spec.rb
index c1fe1b06c52..1754253e0f2 100644
--- a/spec/models/route_spec.rb
+++ b/spec/models/route_spec.rb
@@ -9,7 +9,10 @@ describe Route, models: true do
end
describe 'validations' do
- before { route }
+ before do
+ expect(route).to be_persisted
+ end
+
it { is_expected.to validate_presence_of(:source) }
it { is_expected.to validate_presence_of(:path) }
it { is_expected.to validate_uniqueness_of(:path) }
@@ -59,7 +62,9 @@ describe Route, models: true do
context 'path update' do
context 'when route name is set' do
- before { route.update_attributes(path: 'bar') }
+ before do
+ route.update_attributes(path: 'bar')
+ end
it 'updates children routes with new path' do
expect(described_class.exists?(path: 'bar')).to be_truthy
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index d5bd9946ab6..1a1bbd60504 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -1584,7 +1584,9 @@ describe User, models: true do
end
context 'user is member of the top group' do
- before { group.add_owner(user) }
+ before do
+ group.add_owner(user)
+ end
if Group.supports_nested_groups?
it 'returns all groups' do
@@ -1602,7 +1604,9 @@ describe User, models: true do
end
context 'user is member of the first child (internal node), branch 1', :nested_groups do
- before { nested_group_1.add_owner(user) }
+ before do
+ nested_group_1.add_owner(user)
+ end
it 'returns the groups in the hierarchy' do
is_expected.to match_array [
@@ -1613,7 +1617,9 @@ describe User, models: true do
end
context 'user is member of the first child (internal node), branch 2', :nested_groups do
- before { nested_group_2.add_owner(user) }
+ before do
+ nested_group_2.add_owner(user)
+ end
it 'returns the groups in the hierarchy' do
is_expected.to match_array [
@@ -1624,7 +1630,9 @@ describe User, models: true do
end
context 'user is member of the last child (leaf node)', :nested_groups do
- before { nested_group_1_1.add_owner(user) }
+ before do
+ nested_group_1_1.add_owner(user)
+ end
it 'returns the groups in the hierarchy' do
is_expected.to match_array [
diff --git a/spec/policies/ci/build_policy_spec.rb b/spec/policies/ci/build_policy_spec.rb
index 3f4ce222b60..48a139d4b83 100644
--- a/spec/policies/ci/build_policy_spec.rb
+++ b/spec/policies/ci/build_policy_spec.rb
@@ -10,7 +10,9 @@ describe Ci::BuildPolicy, :models do
end
shared_context 'public pipelines disabled' do
- before { project.update_attribute(:public_builds, false) }
+ before do
+ project.update_attribute(:public_builds, false)
+ end
end
describe '#rules' do
@@ -54,7 +56,9 @@ describe Ci::BuildPolicy, :models do
let(:project) { create(:empty_project, :public) }
context 'team member is a guest' do
- before { project.team << [user, :guest] }
+ before do
+ project.team << [user, :guest]
+ end
context 'when public builds are enabled' do
it 'includes ability to read build' do
@@ -72,7 +76,9 @@ describe Ci::BuildPolicy, :models do
end
context 'team member is a reporter' do
- before { project.team << [user, :reporter] }
+ before do
+ project.team << [user, :reporter]
+ end
context 'when public builds are enabled' do
it 'includes ability to read build' do
diff --git a/spec/policies/project_snippet_policy_spec.rb b/spec/policies/project_snippet_policy_spec.rb
index ddbed5f781e..d2b2528c57a 100644
--- a/spec/policies/project_snippet_policy_spec.rb
+++ b/spec/policies/project_snippet_policy_spec.rb
@@ -78,7 +78,9 @@ describe ProjectSnippetPolicy, models: true do
context 'project team member external user' do
subject { abilities(external_user, :internal) }
- before { project.team << [external_user, :developer] }
+ before do
+ project.team << [external_user, :developer]
+ end
it do
is_expected.to include(:read_project_snippet)
@@ -120,7 +122,9 @@ describe ProjectSnippetPolicy, models: true do
context 'project team member normal user' do
subject { abilities(regular_user, :private) }
- before { project.team << [regular_user, :developer] }
+ before do
+ project.team << [regular_user, :developer]
+ end
it do
is_expected.to include(:read_project_snippet)
@@ -131,7 +135,9 @@ describe ProjectSnippetPolicy, models: true do
context 'project team member external user' do
subject { abilities(external_user, :private) }
- before { project.team << [external_user, :developer] }
+ before do
+ project.team << [external_user, :developer]
+ end
it do
is_expected.to include(:read_project_snippet)
diff --git a/spec/requests/api/award_emoji_spec.rb b/spec/requests/api/award_emoji_spec.rb
index bbdef0aeb1b..6d822b5cb4f 100644
--- a/spec/requests/api/award_emoji_spec.rb
+++ b/spec/requests/api/award_emoji_spec.rb
@@ -9,7 +9,9 @@ describe API::AwardEmoji do
let!(:downvote) { create(:award_emoji, :downvote, awardable: merge_request, user: user) }
let!(:note) { create(:note, project: project, noteable: issue) }
- before { project.team << [user, :master] }
+ before do
+ project.team << [user, :master]
+ end
describe "GET /projects/:id/awardable/:awardable_id/award_emoji" do
context 'on an issue' do
diff --git a/spec/requests/api/commit_statuses_spec.rb b/spec/requests/api/commit_statuses_spec.rb
index 6b637a03b6f..b8ca73c321c 100644
--- a/spec/requests/api/commit_statuses_spec.rb
+++ b/spec/requests/api/commit_statuses_spec.rb
@@ -34,7 +34,9 @@ describe API::CommitStatuses do
let!(:status6) { create_status(master, status: 'success') }
context 'latest commit statuses' do
- before { get api(get_url, reporter) }
+ before do
+ get api(get_url, reporter)
+ end
it 'returns latest commit statuses' do
expect(response).to have_http_status(200)
@@ -48,7 +50,9 @@ describe API::CommitStatuses do
end
context 'all commit statuses' do
- before { get api(get_url, reporter), all: 1 }
+ before do
+ get api(get_url, reporter), all: 1
+ end
it 'returns all commit statuses' do
expect(response).to have_http_status(200)
@@ -61,7 +65,9 @@ describe API::CommitStatuses do
end
context 'latest commit statuses for specific ref' do
- before { get api(get_url, reporter), ref: 'develop' }
+ before do
+ get api(get_url, reporter), ref: 'develop'
+ end
it 'returns latest commit statuses for specific ref' do
expect(response).to have_http_status(200)
@@ -72,7 +78,9 @@ describe API::CommitStatuses do
end
context 'latest commit statues for specific name' do
- before { get api(get_url, reporter), name: 'coverage' }
+ before do
+ get api(get_url, reporter), name: 'coverage'
+ end
it 'return latest commit statuses for specific name' do
expect(response).to have_http_status(200)
@@ -85,7 +93,9 @@ describe API::CommitStatuses do
end
context 'ci commit does not exist' do
- before { get api(get_url, reporter) }
+ before do
+ get api(get_url, reporter)
+ end
it 'returns empty array' do
expect(response.status).to eq 200
@@ -95,7 +105,9 @@ describe API::CommitStatuses do
end
context "guest user" do
- before { get api(get_url, guest) }
+ before do
+ get api(get_url, guest)
+ end
it "does not return project commits" do
expect(response).to have_http_status(403)
@@ -103,7 +115,9 @@ describe API::CommitStatuses do
end
context "unauthorized user" do
- before { get api(get_url) }
+ before do
+ get api(get_url)
+ end
it "does not return project commits" do
expect(response).to have_http_status(401)
@@ -209,7 +223,9 @@ describe API::CommitStatuses do
end
context 'when status is invalid' do
- before { post api(post_url, developer), state: 'invalid' }
+ before do
+ post api(post_url, developer), state: 'invalid'
+ end
it 'does not create commit status' do
expect(response).to have_http_status(400)
@@ -217,7 +233,9 @@ describe API::CommitStatuses do
end
context 'when request without a state made' do
- before { post api(post_url, developer) }
+ before do
+ post api(post_url, developer)
+ end
it 'does not create commit status' do
expect(response).to have_http_status(400)
@@ -226,7 +244,10 @@ describe API::CommitStatuses do
context 'when commit SHA is invalid' do
let(:sha) { 'invalid_sha' }
- before { post api(post_url, developer), state: 'running' }
+
+ before do
+ post api(post_url, developer), state: 'running'
+ end
it 'returns not found error' do
expect(response).to have_http_status(404)
@@ -248,7 +269,9 @@ describe API::CommitStatuses do
end
context 'reporter user' do
- before { post api(post_url, reporter), state: 'running' }
+ before do
+ post api(post_url, reporter), state: 'running'
+ end
it 'does not create commit status' do
expect(response).to have_http_status(403)
@@ -256,7 +279,9 @@ describe API::CommitStatuses do
end
context 'guest user' do
- before { post api(post_url, guest), state: 'running' }
+ before do
+ post api(post_url, guest), state: 'running'
+ end
it 'does not create commit status' do
expect(response).to have_http_status(403)
@@ -264,7 +289,9 @@ describe API::CommitStatuses do
end
context 'unauthorized user' do
- before { post api(post_url) }
+ before do
+ post api(post_url)
+ end
it 'does not create commit status' do
expect(response).to have_http_status(401)
diff --git a/spec/requests/api/commits_spec.rb b/spec/requests/api/commits_spec.rb
index b0c265b6453..0dad547735d 100644
--- a/spec/requests/api/commits_spec.rb
+++ b/spec/requests/api/commits_spec.rb
@@ -9,11 +9,15 @@ describe API::Commits do
let!(:note) { create(:note_on_commit, author: user, project: project, commit_id: project.repository.commit.id, note: 'a comment on a commit') }
let!(:another_note) { create(:note_on_commit, author: user, project: project, commit_id: project.repository.commit.id, note: 'another comment on a commit') }
- before { project.team << [user, :reporter] }
+ before do
+ project.team << [user, :reporter]
+ end
describe "List repository commits" do
context "authorized user" do
- before { project.team << [user2, :reporter] }
+ before do
+ project.team << [user2, :reporter]
+ end
it "returns project commits" do
commit = project.repository.commit
@@ -514,7 +518,9 @@ describe API::Commits do
describe "Get the diff of a commit" do
context "authorized user" do
- before { project.team << [user2, :reporter] }
+ before do
+ project.team << [user2, :reporter]
+ end
it "returns the diff of the selected commit" do
get api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}/diff", user)
diff --git a/spec/requests/api/deploy_keys_spec.rb b/spec/requests/api/deploy_keys_spec.rb
index 4d9cd5f3a27..9c260f88f56 100644
--- a/spec/requests/api/deploy_keys_spec.rb
+++ b/spec/requests/api/deploy_keys_spec.rb
@@ -41,7 +41,9 @@ describe API::DeployKeys do
end
describe 'GET /projects/:id/deploy_keys' do
- before { deploy_key }
+ before do
+ deploy_key
+ end
it 'returns array of ssh keys' do
get api("/projects/#{project.id}/deploy_keys", admin)
@@ -161,7 +163,9 @@ describe API::DeployKeys do
end
describe 'DELETE /projects/:id/deploy_keys/:key_id' do
- before { deploy_key }
+ before do
+ deploy_key
+ end
it 'deletes existing key' do
expect do
diff --git a/spec/requests/api/files_spec.rb b/spec/requests/api/files_spec.rb
index d325c6eff9d..c5ec8be4f21 100644
--- a/spec/requests/api/files_spec.rb
+++ b/spec/requests/api/files_spec.rb
@@ -13,7 +13,9 @@ describe API::Files do
let(:author_email) { 'user@example.org' }
let(:author_name) { 'John Doe' }
- before { project.team << [user, :developer] }
+ before do
+ project.team << [user, :developer]
+ end
def route(file_path = nil)
"/projects/#{project.id}/repository/files/#{file_path}"
diff --git a/spec/requests/api/helpers_spec.rb b/spec/requests/api/helpers_spec.rb
index ed392acc607..191c60aba31 100644
--- a/spec/requests/api/helpers_spec.rb
+++ b/spec/requests/api/helpers_spec.rb
@@ -55,40 +55,62 @@ describe API::Helpers do
subject { current_user }
describe "Warden authentication" do
- before { doorkeeper_guard_returns false }
+ before do
+ doorkeeper_guard_returns false
+ end
context "with invalid credentials" do
context "GET request" do
- before { env['REQUEST_METHOD'] = 'GET' }
+ before do
+ env['REQUEST_METHOD'] = 'GET'
+ end
+
it { is_expected.to be_nil }
end
end
context "with valid credentials" do
- before { warden_authenticate_returns user }
+ before do
+ warden_authenticate_returns user
+ end
context "GET request" do
- before { env['REQUEST_METHOD'] = 'GET' }
+ before do
+ env['REQUEST_METHOD'] = 'GET'
+ end
+
it { is_expected.to eq(user) }
end
context "HEAD request" do
- before { env['REQUEST_METHOD'] = 'HEAD' }
+ before do
+ env['REQUEST_METHOD'] = 'HEAD'
+ end
+
it { is_expected.to eq(user) }
end
context "PUT request" do
- before { env['REQUEST_METHOD'] = 'PUT' }
+ before do
+ env['REQUEST_METHOD'] = 'PUT'
+ end
+
it { is_expected.to be_nil }
end
context "POST request" do
- before { env['REQUEST_METHOD'] = 'POST' }
+ before do
+ env['REQUEST_METHOD'] = 'POST'
+ end
+
it { is_expected.to be_nil }
end
context "DELETE request" do
- before { env['REQUEST_METHOD'] = 'DELETE' }
+ before do
+ env['REQUEST_METHOD'] = 'DELETE'
+ end
+
it { is_expected.to be_nil }
end
end
diff --git a/spec/requests/api/jobs_spec.rb b/spec/requests/api/jobs_spec.rb
index e5e5872dc1f..8d647eb1c7e 100644
--- a/spec/requests/api/jobs_spec.rb
+++ b/spec/requests/api/jobs_spec.rb
@@ -11,7 +11,7 @@ describe API::Jobs, :api do
ref: project.default_branch)
end
- let!(:build) { create(:ci_build, pipeline: pipeline) }
+ let!(:job) { create(:ci_build, pipeline: pipeline) }
let(:user) { create(:user) }
let(:api_user) { user }
@@ -42,13 +42,13 @@ describe API::Jobs, :api do
end
it 'returns pipeline data' do
- json_build = json_response.first
+ json_job = json_response.first
- expect(json_build['pipeline']).not_to be_empty
- expect(json_build['pipeline']['id']).to eq build.pipeline.id
- expect(json_build['pipeline']['ref']).to eq build.pipeline.ref
- expect(json_build['pipeline']['sha']).to eq build.pipeline.sha
- expect(json_build['pipeline']['status']).to eq build.pipeline.status
+ expect(json_job['pipeline']).not_to be_empty
+ expect(json_job['pipeline']['id']).to eq job.pipeline.id
+ expect(json_job['pipeline']['ref']).to eq job.pipeline.ref
+ expect(json_job['pipeline']['sha']).to eq job.pipeline.sha
+ expect(json_job['pipeline']['status']).to eq job.pipeline.status
end
context 'filter project with one scope element' do
@@ -79,7 +79,7 @@ describe API::Jobs, :api do
context 'unauthorized user' do
let(:api_user) { nil }
- it 'does not return project builds' do
+ it 'does not return project jobs' do
expect(response).to have_http_status(401)
end
end
@@ -105,13 +105,13 @@ describe API::Jobs, :api do
end
it 'returns pipeline data' do
- json_build = json_response.first
+ json_job = json_response.first
- expect(json_build['pipeline']).not_to be_empty
- expect(json_build['pipeline']['id']).to eq build.pipeline.id
- expect(json_build['pipeline']['ref']).to eq build.pipeline.ref
- expect(json_build['pipeline']['sha']).to eq build.pipeline.sha
- expect(json_build['pipeline']['status']).to eq build.pipeline.status
+ expect(json_job['pipeline']).not_to be_empty
+ expect(json_job['pipeline']['id']).to eq job.pipeline.id
+ expect(json_job['pipeline']['ref']).to eq job.pipeline.ref
+ expect(json_job['pipeline']['sha']).to eq job.pipeline.sha
+ expect(json_job['pipeline']['status']).to eq job.pipeline.status
end
context 'filter jobs with one scope element' do
@@ -140,7 +140,7 @@ describe API::Jobs, :api do
context 'jobs in different pipelines' do
let!(:pipeline2) { create(:ci_empty_pipeline, project: project) }
- let!(:build2) { create(:ci_build, pipeline: pipeline2) }
+ let!(:job2) { create(:ci_build, pipeline: pipeline2) }
it 'excludes jobs from other pipelines' do
json_response.each { |job| expect(job['pipeline']['id']).to eq(pipeline.id) }
@@ -159,7 +159,7 @@ describe API::Jobs, :api do
describe 'GET /projects/:id/jobs/:job_id' do
before do
- get api("/projects/#{project.id}/jobs/#{build.id}", api_user)
+ get api("/projects/#{project.id}/jobs/#{job.id}", api_user)
end
context 'authorized user' do
@@ -169,12 +169,13 @@ describe API::Jobs, :api do
end
it 'returns pipeline data' do
- json_build = json_response
- expect(json_build['pipeline']).not_to be_empty
- expect(json_build['pipeline']['id']).to eq build.pipeline.id
- expect(json_build['pipeline']['ref']).to eq build.pipeline.ref
- expect(json_build['pipeline']['sha']).to eq build.pipeline.sha
- expect(json_build['pipeline']['status']).to eq build.pipeline.status
+ json_job = json_response
+
+ expect(json_job['pipeline']).not_to be_empty
+ expect(json_job['pipeline']['id']).to eq job.pipeline.id
+ expect(json_job['pipeline']['ref']).to eq job.pipeline.ref
+ expect(json_job['pipeline']['sha']).to eq job.pipeline.sha
+ expect(json_job['pipeline']['status']).to eq job.pipeline.status
end
end
@@ -189,11 +190,11 @@ describe API::Jobs, :api do
describe 'GET /projects/:id/jobs/:job_id/artifacts' do
before do
- get api("/projects/#{project.id}/jobs/#{build.id}/artifacts", api_user)
+ get api("/projects/#{project.id}/jobs/#{job.id}/artifacts", api_user)
end
context 'job with artifacts' do
- let(:build) { create(:ci_build, :artifacts, pipeline: pipeline) }
+ let(:job) { create(:ci_build, :artifacts, pipeline: pipeline) }
context 'authorized user' do
let(:download_headers) do
@@ -204,7 +205,7 @@ describe API::Jobs, :api do
it 'returns specific job artifacts' do
expect(response).to have_http_status(200)
expect(response.headers).to include(download_headers)
- expect(response.body).to match_file(build.artifacts_file.file.file)
+ expect(response.body).to match_file(job.artifacts_file.file.file)
end
end
@@ -224,14 +225,14 @@ describe API::Jobs, :api do
describe 'GET /projects/:id/artifacts/:ref_name/download?job=name' do
let(:api_user) { reporter }
- let(:build) { create(:ci_build, :artifacts, pipeline: pipeline) }
+ let(:job) { create(:ci_build, :artifacts, pipeline: pipeline) }
before do
- build.success
+ job.success
end
- def get_for_ref(ref = pipeline.ref, job = build.name)
- get api("/projects/#{project.id}/jobs/artifacts/#{ref}/download", api_user), job: job
+ def get_for_ref(ref = pipeline.ref, job_name = job.name)
+ get api("/projects/#{project.id}/jobs/artifacts/#{ref}/download", api_user), job: job_name
end
context 'when not logged in' do
@@ -285,7 +286,7 @@ describe API::Jobs, :api do
let(:download_headers) do
{ 'Content-Transfer-Encoding' => 'binary',
'Content-Disposition' =>
- "attachment; filename=#{build.artifacts_file.filename}" }
+ "attachment; filename=#{job.artifacts_file.filename}" }
end
it { expect(response).to have_http_status(200) }
@@ -321,16 +322,16 @@ describe API::Jobs, :api do
end
describe 'GET /projects/:id/jobs/:job_id/trace' do
- let(:build) { create(:ci_build, :trace, pipeline: pipeline) }
+ let(:job) { create(:ci_build, :trace, pipeline: pipeline) }
before do
- get api("/projects/#{project.id}/jobs/#{build.id}/trace", api_user)
+ get api("/projects/#{project.id}/jobs/#{job.id}/trace", api_user)
end
context 'authorized user' do
it 'returns specific job trace' do
expect(response).to have_http_status(200)
- expect(response.body).to eq(build.trace.raw)
+ expect(response.body).to eq(job.trace.raw)
end
end
@@ -345,7 +346,7 @@ describe API::Jobs, :api do
describe 'POST /projects/:id/jobs/:job_id/cancel' do
before do
- post api("/projects/#{project.id}/jobs/#{build.id}/cancel", api_user)
+ post api("/projects/#{project.id}/jobs/#{job.id}/cancel", api_user)
end
context 'authorized user' do
@@ -375,10 +376,10 @@ describe API::Jobs, :api do
end
describe 'POST /projects/:id/jobs/:job_id/retry' do
- let(:build) { create(:ci_build, :canceled, pipeline: pipeline) }
+ let(:job) { create(:ci_build, :canceled, pipeline: pipeline) }
before do
- post api("/projects/#{project.id}/jobs/#{build.id}/retry", api_user)
+ post api("/projects/#{project.id}/jobs/#{job.id}/retry", api_user)
end
context 'authorized user' do
@@ -410,28 +411,29 @@ describe API::Jobs, :api do
describe 'POST /projects/:id/jobs/:job_id/erase' do
before do
- post api("/projects/#{project.id}/jobs/#{build.id}/erase", user)
+ post api("/projects/#{project.id}/jobs/#{job.id}/erase", user)
end
context 'job is erasable' do
- let(:build) { create(:ci_build, :trace, :artifacts, :success, project: project, pipeline: pipeline) }
+ let(:job) { create(:ci_build, :trace, :artifacts, :success, project: project, pipeline: pipeline) }
it 'erases job content' do
expect(response).to have_http_status(201)
- expect(build).not_to have_trace
- expect(build.artifacts_file.exists?).to be_falsy
- expect(build.artifacts_metadata.exists?).to be_falsy
+ expect(job).not_to have_trace
+ expect(job.artifacts_file.exists?).to be_falsy
+ expect(job.artifacts_metadata.exists?).to be_falsy
end
it 'updates job' do
- build.reload
- expect(build.erased_at).to be_truthy
- expect(build.erased_by).to eq(user)
+ job.reload
+
+ expect(job.erased_at).to be_truthy
+ expect(job.erased_by).to eq(user)
end
end
context 'job is not erasable' do
- let(:build) { create(:ci_build, :trace, project: project, pipeline: pipeline) }
+ let(:job) { create(:ci_build, :trace, project: project, pipeline: pipeline) }
it 'responds with forbidden' do
expect(response).to have_http_status(403)
@@ -439,25 +441,25 @@ describe API::Jobs, :api do
end
end
- describe 'POST /projects/:id/jobs/:build_id/artifacts/keep' do
+ describe 'POST /projects/:id/jobs/:job_id/artifacts/keep' do
before do
- post api("/projects/#{project.id}/jobs/#{build.id}/artifacts/keep", user)
+ post api("/projects/#{project.id}/jobs/#{job.id}/artifacts/keep", user)
end
context 'artifacts did not expire' do
- let(:build) do
+ let(:job) do
create(:ci_build, :trace, :artifacts, :success,
project: project, pipeline: pipeline, artifacts_expire_at: Time.now + 7.days)
end
it 'keeps artifacts' do
expect(response).to have_http_status(200)
- expect(build.reload.artifacts_expire_at).to be_nil
+ expect(job.reload.artifacts_expire_at).to be_nil
end
end
context 'no artifacts' do
- let(:build) { create(:ci_build, project: project, pipeline: pipeline) }
+ let(:job) { create(:ci_build, project: project, pipeline: pipeline) }
it 'responds with not found' do
expect(response).to have_http_status(404)
@@ -467,18 +469,18 @@ describe API::Jobs, :api do
describe 'POST /projects/:id/jobs/:job_id/play' do
before do
- post api("/projects/#{project.id}/jobs/#{build.id}/play", api_user)
+ post api("/projects/#{project.id}/jobs/#{job.id}/play", api_user)
end
context 'on an playable job' do
- let(:build) { create(:ci_build, :manual, project: project, pipeline: pipeline) }
+ let(:job) { create(:ci_build, :manual, project: project, pipeline: pipeline) }
context 'when user is authorized to trigger a manual action' do
it 'plays the job' do
expect(response).to have_http_status(200)
expect(json_response['user']['id']).to eq(user.id)
- expect(json_response['id']).to eq(build.id)
- expect(build.reload).to be_pending
+ expect(json_response['id']).to eq(job.id)
+ expect(job.reload).to be_pending
end
end
@@ -487,7 +489,7 @@ describe API::Jobs, :api do
let(:api_user) { create(:user) }
it 'does not trigger a manual action' do
- expect(build.reload).to be_manual
+ expect(job.reload).to be_manual
expect(response).to have_http_status(404)
end
end
@@ -496,7 +498,7 @@ describe API::Jobs, :api do
let(:api_user) { reporter }
it 'does not trigger a manual action' do
- expect(build.reload).to be_manual
+ expect(job.reload).to be_manual
expect(response).to have_http_status(403)
end
end
diff --git a/spec/requests/api/keys_spec.rb b/spec/requests/api/keys_spec.rb
index ab957c72984..f534332ca6c 100644
--- a/spec/requests/api/keys_spec.rb
+++ b/spec/requests/api/keys_spec.rb
@@ -4,11 +4,9 @@ describe API::Keys do
let(:user) { create(:user) }
let(:admin) { create(:admin) }
let(:key) { create(:key, user: user) }
- let(:email) { create(:email, user: user) }
+ let(:email) { create(:email, user: user) }
describe 'GET /keys/:uid' do
- before { admin }
-
context 'when unauthenticated' do
it 'returns authentication error' do
get api("/keys/#{key.id}")
diff --git a/spec/requests/api/labels_spec.rb b/spec/requests/api/labels_spec.rb
index 0c6b55c1630..f7e2f1908bb 100644
--- a/spec/requests/api/labels_spec.rb
+++ b/spec/requests/api/labels_spec.rb
@@ -339,7 +339,9 @@ describe API::Labels do
end
context "when user is already subscribed to label" do
- before { label1.subscribe(user, project) }
+ before do
+ label1.subscribe(user, project)
+ end
it "returns 304" do
post api("/projects/#{project.id}/labels/#{label1.id}/subscribe", user)
@@ -358,7 +360,9 @@ describe API::Labels do
end
describe "POST /projects/:id/labels/:label_id/unsubscribe" do
- before { label1.subscribe(user, project) }
+ before do
+ label1.subscribe(user, project)
+ end
context "when label_id is a label title" do
it "unsubscribes from the label" do
@@ -381,7 +385,9 @@ describe API::Labels do
end
context "when user is already unsubscribed from label" do
- before { label1.unsubscribe(user, project) }
+ before do
+ label1.unsubscribe(user, project)
+ end
it "returns 304" do
post api("/projects/#{project.id}/labels/#{label1.id}/unsubscribe", user)
diff --git a/spec/requests/api/milestones_spec.rb b/spec/requests/api/milestones_spec.rb
index dd74351a2b1..40934c25afc 100644
--- a/spec/requests/api/milestones_spec.rb
+++ b/spec/requests/api/milestones_spec.rb
@@ -6,7 +6,9 @@ describe API::Milestones do
let!(:closed_milestone) { create(:closed_milestone, project: project, title: 'version1', description: 'closed milestone') }
let!(:milestone) { create(:milestone, project: project, title: 'version2', description: 'open milestone') }
- before { project.team << [user, :developer] }
+ before do
+ project.team << [user, :developer]
+ end
describe 'GET /projects/:id/milestones' do
it 'returns project milestones' do
diff --git a/spec/requests/api/notes_spec.rb b/spec/requests/api/notes_spec.rb
index 6afcd237c3c..03f2b5950ee 100644
--- a/spec/requests/api/notes_spec.rb
+++ b/spec/requests/api/notes_spec.rb
@@ -28,7 +28,9 @@ describe API::Notes do
system: true
end
- before { project.team << [user, :reporter] }
+ before do
+ project.team << [user, :reporter]
+ end
describe "GET /projects/:id/noteable/:noteable_id/notes" do
context "when noteable is an Issue" do
@@ -58,7 +60,9 @@ describe API::Notes do
end
context "and issue is confidential" do
- before { ext_issue.update_attributes(confidential: true) }
+ before do
+ ext_issue.update_attributes(confidential: true)
+ end
it "returns 404" do
get api("/projects/#{ext_proj.id}/issues/#{ext_issue.iid}/notes", user)
@@ -150,7 +154,9 @@ describe API::Notes do
end
context "when issue is confidential" do
- before { issue.update_attributes(confidential: true) }
+ before do
+ issue.update_attributes(confidential: true)
+ end
it "returns 404" do
get api("/projects/#{project.id}/issues/#{issue.iid}/notes/#{issue_note.id}", private_user)
diff --git a/spec/requests/api/pipelines_spec.rb b/spec/requests/api/pipelines_spec.rb
index 9e6957e9922..258085e503f 100644
--- a/spec/requests/api/pipelines_spec.rb
+++ b/spec/requests/api/pipelines_spec.rb
@@ -10,7 +10,9 @@ describe API::Pipelines do
ref: project.default_branch, user: user)
end
- before { project.team << [user, :master] }
+ before do
+ project.team << [user, :master]
+ end
describe 'GET /projects/:id/pipelines ' do
context 'authorized user' do
@@ -285,7 +287,9 @@ describe API::Pipelines do
describe 'POST /projects/:id/pipeline ' do
context 'authorized user' do
context 'with gitlab-ci.yml' do
- before { stub_ci_pipeline_to_return_yaml_file }
+ before do
+ stub_ci_pipeline_to_return_yaml_file
+ end
it 'creates and returns a new pipeline' do
expect do
@@ -419,7 +423,9 @@ describe API::Pipelines do
context 'user without proper access rights' do
let!(:reporter) { create(:user) }
- before { project.team << [reporter, :reporter] }
+ before do
+ project.team << [reporter, :reporter]
+ end
it 'rejects the action' do
post api("/projects/#{project.id}/pipelines/#{pipeline.id}/cancel", reporter)
diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb
index 3e831373514..d92262a4c99 100644
--- a/spec/requests/api/projects_spec.rb
+++ b/spec/requests/api/projects_spec.rb
@@ -476,8 +476,9 @@ describe API::Projects do
end
describe 'POST /projects/user/:id' do
- before { project }
- before { admin }
+ before do
+ expect(project).to be_persisted
+ end
it 'creates new project without path but with name and return 201' do
expect { post api("/projects/user/#{user.id}", admin), name: 'Foo Project' }.to change {Project.count}.by(1)
@@ -581,7 +582,9 @@ describe API::Projects do
end
describe "POST /projects/:id/uploads" do
- before { project }
+ before do
+ project
+ end
it "uploads the file and returns its info" do
post api("/projects/#{project.id}/uploads", user), file: fixture_file_upload(Rails.root + "spec/fixtures/dk.png", "image/png")
@@ -729,7 +732,9 @@ describe API::Projects do
describe 'permissions' do
context 'all projects' do
- before { project.team << [user, :master] }
+ before do
+ project.team << [user, :master]
+ end
it 'contains permission information' do
get api("/projects", user)
@@ -756,7 +761,9 @@ describe API::Projects do
context 'group project' do
let(:project2) { create(:empty_project, group: create(:group)) }
- before { project2.group.add_owner(user) }
+ before do
+ project2.group.add_owner(user)
+ end
it 'sets the owner and return 200' do
get api("/projects/#{project2.id}", user)
@@ -822,7 +829,9 @@ describe API::Projects do
end
describe 'GET /projects/:id/snippets' do
- before { snippet }
+ before do
+ snippet
+ end
it 'returns an array of project snippets' do
get api("/projects/#{project.id}/snippets", user)
@@ -879,7 +888,9 @@ describe API::Projects do
end
describe 'DELETE /projects/:id/snippets/:snippet_id' do
- before { snippet }
+ before do
+ snippet
+ end
it 'deletes existing project snippet' do
expect do
@@ -1074,14 +1085,16 @@ describe API::Projects do
end
describe 'PUT /projects/:id' do
- before { project }
- before { user }
- before { user3 }
- before { user4 }
- before { project3 }
- before { project4 }
- before { project_member2 }
- before { project_member }
+ before do
+ expect(project).to be_persisted
+ expect(user).to be_persisted
+ expect(user3).to be_persisted
+ expect(user4).to be_persisted
+ expect(project3).to be_persisted
+ expect(project4).to be_persisted
+ expect(project_member2).to be_persisted
+ expect(project_member).to be_persisted
+ end
it 'returns 400 when nothing sent' do
project_param = {}
diff --git a/spec/requests/api/runner_spec.rb b/spec/requests/api/runner_spec.rb
index 5a4f0513248..d554c242916 100644
--- a/spec/requests/api/runner_spec.rb
+++ b/spec/requests/api/runner_spec.rb
@@ -190,17 +190,23 @@ describe API::Runner do
pipeline: pipeline, name: 'spinach', stage: 'test', stage_idx: 0, commands: "ls\ndate")
end
- before { project.runners << runner }
+ before do
+ project.runners << runner
+ end
describe 'POST /api/v4/jobs/request' do
let!(:last_update) {}
let!(:new_update) { }
let(:user_agent) { 'gitlab-runner 9.0.0 (9-0-stable; go1.7.4; linux/amd64)' }
- before { stub_container_registry_config(enabled: false) }
+ before do
+ stub_container_registry_config(enabled: false)
+ end
shared_examples 'no jobs available' do
- before { request_job }
+ before do
+ request_job
+ end
context 'when runner sends version in User-Agent' do
context 'for stable version' do
@@ -277,7 +283,9 @@ describe API::Runner do
end
context 'when jobs are finished' do
- before { job.success }
+ before do
+ job.success
+ end
it_behaves_like 'no jobs available'
end
@@ -508,10 +516,14 @@ describe API::Runner do
end
context 'when job has no tags' do
- before { job.update(tags: []) }
+ before do
+ job.update(tags: [])
+ end
context 'when runner is allowed to pick untagged jobs' do
- before { runner.update_column(:run_untagged, true) }
+ before do
+ runner.update_column(:run_untagged, true)
+ end
it 'picks job' do
request_job
@@ -521,7 +533,9 @@ describe API::Runner do
end
context 'when runner is not allowed to pick untagged jobs' do
- before { runner.update_column(:run_untagged, false) }
+ before do
+ runner.update_column(:run_untagged, false)
+ end
it_behaves_like 'no jobs available'
end
@@ -561,7 +575,9 @@ describe API::Runner do
end
context 'when registry is enabled' do
- before { stub_container_registry_config(enabled: true, host_port: registry_url) }
+ before do
+ stub_container_registry_config(enabled: true, host_port: registry_url)
+ end
it 'sends registry credentials key' do
request_job
@@ -572,7 +588,9 @@ describe API::Runner do
end
context 'when registry is disabled' do
- before { stub_container_registry_config(enabled: false, host_port: registry_url) }
+ before do
+ stub_container_registry_config(enabled: false, host_port: registry_url)
+ end
it 'does not send registry credentials' do
request_job
@@ -594,7 +612,9 @@ describe API::Runner do
describe 'PUT /api/v4/jobs/:id' do
let(:job) { create(:ci_build, :pending, :trace, pipeline: pipeline, runner_id: runner.id) }
- before { job.run! }
+ before do
+ job.run!
+ end
context 'when status is given' do
it 'mark job as succeeded' do
@@ -649,7 +669,9 @@ describe API::Runner do
let(:headers_with_range) { headers.merge({ 'Content-Range' => '11-20' }) }
let(:update_interval) { 10.seconds.to_i }
- before { initial_patch_the_trace }
+ before do
+ initial_patch_the_trace
+ end
context 'when request is valid' do
it 'gets correct response' do
@@ -791,7 +813,9 @@ describe API::Runner do
let(:file_upload) { fixture_file_upload(Rails.root + 'spec/fixtures/banana_sample.gif', 'image/gif') }
let(:file_upload2) { fixture_file_upload(Rails.root + 'spec/fixtures/dk.png', 'image/gif') }
- before { job.run! }
+ before do
+ job.run!
+ end
describe 'POST /api/v4/jobs/:id/artifacts/authorize' do
context 'when using token as parameter' do
@@ -897,13 +921,17 @@ describe API::Runner do
end
context 'when uses regular file post' do
- before { upload_artifacts(file_upload, headers_with_token, false) }
+ before do
+ upload_artifacts(file_upload, headers_with_token, false)
+ end
it_behaves_like 'successful artifacts upload'
end
context 'when uses accelerated file post' do
- before { upload_artifacts(file_upload, headers_with_token, true) }
+ before do
+ upload_artifacts(file_upload, headers_with_token, true)
+ end
it_behaves_like 'successful artifacts upload'
end
@@ -1057,7 +1085,9 @@ describe API::Runner do
allow(ArtifactUploader).to receive(:artifacts_upload_path).and_return(@tmpdir)
end
- after { FileUtils.remove_entry @tmpdir }
+ after do
+ FileUtils.remove_entry @tmpdir
+ end
it' "fails to post artifacts for outside of tmp path"' do
upload_artifacts(file_upload, headers_with_token)
@@ -1079,7 +1109,9 @@ describe API::Runner do
describe 'GET /api/v4/jobs/:id/artifacts' do
let(:token) { job.token }
- before { download_artifact }
+ before do
+ download_artifact
+ end
context 'when job has artifacts' do
let(:job) { create(:ci_build, :artifacts) }
diff --git a/spec/requests/api/settings_spec.rb b/spec/requests/api/settings_spec.rb
index 2398ae6219c..ede48b1c888 100644
--- a/spec/requests/api/settings_spec.rb
+++ b/spec/requests/api/settings_spec.rb
@@ -40,7 +40,10 @@ describe API::Settings, 'Settings' do
plantuml_url: 'http://plantuml.example.com',
default_snippet_visibility: 'internal',
restricted_visibility_levels: ['public'],
- default_artifacts_expire_in: '2 days'
+ default_artifacts_expire_in: '2 days',
+ help_page_text: 'custom help text',
+ help_page_hide_commercial_content: true,
+ help_page_support_url: 'http://example.com/help'
expect(response).to have_http_status(200)
expect(json_response['default_projects_limit']).to eq(3)
expect(json_response['signin_enabled']).to be_falsey
@@ -53,6 +56,9 @@ describe API::Settings, 'Settings' do
expect(json_response['default_snippet_visibility']).to eq('internal')
expect(json_response['restricted_visibility_levels']).to eq(['public'])
expect(json_response['default_artifacts_expire_in']).to eq('2 days')
+ expect(json_response['help_page_text']).to eq('custom help text')
+ expect(json_response['help_page_hide_commercial_content']).to be_truthy
+ expect(json_response['help_page_support_url']).to eq('http://example.com/help')
end
end
diff --git a/spec/requests/api/system_hooks_spec.rb b/spec/requests/api/system_hooks_spec.rb
index 2eb191d6049..f65b475fe44 100644
--- a/spec/requests/api/system_hooks_spec.rb
+++ b/spec/requests/api/system_hooks_spec.rb
@@ -5,7 +5,9 @@ describe API::SystemHooks do
let(:admin) { create(:admin) }
let!(:hook) { create(:system_hook, url: "http://example.com") }
- before { stub_request(:post, hook.url) }
+ before do
+ stub_request(:post, hook.url)
+ end
describe "GET /hooks" do
context "when no user" do
diff --git a/spec/requests/api/templates_spec.rb b/spec/requests/api/templates_spec.rb
index cb55985e3f5..f8af9295842 100644
--- a/spec/requests/api/templates_spec.rb
+++ b/spec/requests/api/templates_spec.rb
@@ -2,14 +2,18 @@ require 'spec_helper'
describe API::Templates do
context 'the Template Entity' do
- before { get api('/templates/gitignores/Ruby') }
+ before do
+ get api('/templates/gitignores/Ruby')
+ end
it { expect(json_response['name']).to eq('Ruby') }
it { expect(json_response['content']).to include('*.gem') }
end
context 'the TemplateList Entity' do
- before { get api('/templates/gitignores') }
+ before do
+ get api('/templates/gitignores')
+ end
it { expect(json_response.first['name']).not_to be_nil }
it { expect(json_response.first['content']).to be_nil }
@@ -47,7 +51,9 @@ describe API::Templates do
end
context 'the License Template Entity' do
- before { get api('/templates/licenses/mit') }
+ before do
+ get api('/templates/licenses/mit')
+ end
it 'returns a license template' do
expect(json_response['key']).to eq('mit')
diff --git a/spec/requests/api/users_spec.rb b/spec/requests/api/users_spec.rb
index ec51b96c86b..9dc4b6972a6 100644
--- a/spec/requests/api/users_spec.rb
+++ b/spec/requests/api/users_spec.rb
@@ -160,7 +160,9 @@ describe API::Users do
end
describe "POST /users" do
- before { admin }
+ before do
+ admin
+ end
it "creates user" do
expect do
@@ -349,7 +351,9 @@ describe API::Users do
describe "PUT /users/:id" do
let!(:admin_user) { create(:admin) }
- before { admin }
+ before do
+ admin
+ end
it "updates user with new bio" do
put api("/users/#{user.id}", admin), { bio: 'new test bio' }
@@ -502,7 +506,9 @@ describe API::Users do
end
describe "POST /users/:id/keys" do
- before { admin }
+ before do
+ admin
+ end
it "does not create invalid ssh key" do
post api("/users/#{user.id}/keys", admin), { title: "invalid key" }
@@ -532,7 +538,9 @@ describe API::Users do
end
describe 'GET /user/:id/keys' do
- before { admin }
+ before do
+ admin
+ end
context 'when unauthenticated' do
it 'returns authentication error' do
@@ -563,7 +571,9 @@ describe API::Users do
end
describe 'DELETE /user/:id/keys/:key_id' do
- before { admin }
+ before do
+ admin
+ end
context 'when unauthenticated' do
it 'returns authentication error' do
@@ -601,7 +611,9 @@ describe API::Users do
end
describe "POST /users/:id/emails" do
- before { admin }
+ before do
+ admin
+ end
it "does not create invalid email" do
post api("/users/#{user.id}/emails", admin), {}
@@ -625,7 +637,9 @@ describe API::Users do
end
describe 'GET /user/:id/emails' do
- before { admin }
+ before do
+ admin
+ end
context 'when unauthenticated' do
it 'returns authentication error' do
@@ -662,7 +676,9 @@ describe API::Users do
end
describe 'DELETE /user/:id/emails/:email_id' do
- before { admin }
+ before do
+ admin
+ end
context 'when unauthenticated' do
it 'returns authentication error' do
@@ -708,7 +724,10 @@ describe API::Users do
describe "DELETE /users/:id" do
let!(:namespace) { user.namespace }
let!(:issue) { create(:issue, author: user) }
- before { admin }
+
+ before do
+ admin
+ end
it "deletes user" do
Sidekiq::Testing.inline! { delete api("/users/#{user.id}", admin) }
@@ -1068,7 +1087,10 @@ describe API::Users do
end
describe 'POST /users/:id/block' do
- before { admin }
+ before do
+ admin
+ end
+
it 'blocks existing user' do
post api("/users/#{user.id}/block", admin)
expect(response).to have_http_status(201)
@@ -1096,7 +1118,10 @@ describe API::Users do
describe 'POST /users/:id/unblock' do
let(:blocked_user) { create(:user, state: 'blocked') }
- before { admin }
+
+ before do
+ admin
+ end
it 'unblocks existing user' do
post api("/users/#{user.id}/unblock", admin)
diff --git a/spec/requests/ci/api/builds_spec.rb b/spec/requests/ci/api/builds_spec.rb
index 04cc7708858..83c675792f4 100644
--- a/spec/requests/ci/api/builds_spec.rb
+++ b/spec/requests/ci/api/builds_spec.rb
@@ -241,7 +241,9 @@ describe Ci::API::Builds do
end
context 'when runner is allowed to pick untagged builds' do
- before { runner.update_column(:run_untagged, true) }
+ before do
+ runner.update_column(:run_untagged, true)
+ end
it 'picks build' do
register_builds
@@ -467,7 +469,9 @@ describe Ci::API::Builds do
let(:token) { build.token }
let(:headers_with_token) { headers.merge(Ci::API::Helpers::BUILD_TOKEN_HEADER => token) }
- before { build.run! }
+ before do
+ build.run!
+ end
describe "POST /builds/:id/artifacts/authorize" do
context "authorizes posting artifact to running build" do
@@ -523,7 +527,9 @@ describe Ci::API::Builds do
end
context 'authorization token is invalid' do
- before { post authorize_url, { token: 'invalid', filesize: 100 } }
+ before do
+ post authorize_url, { token: 'invalid', filesize: 100 }
+ end
it 'responds with forbidden' do
expect(response).to have_http_status(403)
diff --git a/spec/requests/ci/api/runners_spec.rb b/spec/requests/ci/api/runners_spec.rb
index 0b9733221d8..78b2be350cd 100644
--- a/spec/requests/ci/api/runners_spec.rb
+++ b/spec/requests/ci/api/runners_spec.rb
@@ -12,7 +12,9 @@ describe Ci::API::Runners do
describe "POST /runners/register" do
context 'when runner token is provided' do
- before { post ci_api("/runners/register"), token: registration_token }
+ before do
+ post ci_api("/runners/register"), token: registration_token
+ end
it 'creates runner with default values' do
expect(response).to have_http_status 201
@@ -69,7 +71,10 @@ describe Ci::API::Runners do
context 'when project token is provided' do
let(:project) { FactoryGirl.create(:empty_project) }
- before { post ci_api("/runners/register"), token: project.runners_token }
+
+ before do
+ post ci_api("/runners/register"), token: project.runners_token
+ end
it 'creates runner' do
expect(response).to have_http_status 201
diff --git a/spec/requests/git_http_spec.rb b/spec/requests/git_http_spec.rb
index 6a83024d0d5..dce78faefc9 100644
--- a/spec/requests/git_http_spec.rb
+++ b/spec/requests/git_http_spec.rb
@@ -627,7 +627,9 @@ describe 'Git HTTP requests', lib: true do
let(:path) { "/#{project.path_with_namespace}/info/refs" }
context "when no params are added" do
- before { get path }
+ before do
+ get path
+ end
it "redirects to the .git suffix version" do
expect(response).to redirect_to("/#{project.path_with_namespace}.git/info/refs")
@@ -636,7 +638,10 @@ describe 'Git HTTP requests', lib: true do
context "when the upload-pack service is requested" do
let(:params) { { service: 'git-upload-pack' } }
- before { get path, params }
+
+ before do
+ get path, params
+ end
it "redirects to the .git suffix version" do
expect(response).to redirect_to("/#{project.path_with_namespace}.git/info/refs?service=#{params[:service]}")
@@ -645,7 +650,10 @@ describe 'Git HTTP requests', lib: true do
context "when the receive-pack service is requested" do
let(:params) { { service: 'git-receive-pack' } }
- before { get path, params }
+
+ before do
+ get path, params
+ end
it "redirects to the .git suffix version" do
expect(response).to redirect_to("/#{project.path_with_namespace}.git/info/refs?service=#{params[:service]}")
@@ -654,7 +662,10 @@ describe 'Git HTTP requests', lib: true do
context "when the params are anything else" do
let(:params) { { service: 'git-implode-pack' } }
- before { get path, params }
+
+ before do
+ get path, params
+ end
it "redirects to the sign-in page" do
expect(response).to redirect_to(new_user_session_path)
@@ -695,7 +706,9 @@ describe 'Git HTTP requests', lib: true do
end
context "when the file does not exist" do
- before { get "/#{project.path_with_namespace}/blob/master/info/refs" }
+ before do
+ get "/#{project.path_with_namespace}/blob/master/info/refs"
+ end
it "returns not found" do
expect(response).to have_http_status(:not_found)
diff --git a/spec/requests/jwt_controller_spec.rb b/spec/requests/jwt_controller_spec.rb
index 54d7cf5f10d..5e4cf05748e 100644
--- a/spec/requests/jwt_controller_spec.rb
+++ b/spec/requests/jwt_controller_spec.rb
@@ -6,7 +6,9 @@ describe JwtController do
let(:service_name) { 'test' }
let(:parameters) { { service: service_name } }
- before { stub_const('JwtController::SERVICES', service_name => service_class) }
+ before do
+ stub_const('JwtController::SERVICES', service_name => service_class)
+ end
context 'existing service' do
subject! { get '/jwt/auth', parameters }
diff --git a/spec/routing/project_routing_spec.rb b/spec/routing/project_routing_spec.rb
index 0a6778ae2ef..95d40138fea 100644
--- a/spec/routing/project_routing_spec.rb
+++ b/spec/routing/project_routing_spec.rb
@@ -93,13 +93,17 @@ describe 'project routing' do
end
context 'name with dot' do
- before { allow(Project).to receive(:find_by_full_path).with('gitlab/gitlabhq.keys', any_args).and_return(true) }
+ before do
+ allow(Project).to receive(:find_by_full_path).with('gitlab/gitlabhq.keys', any_args).and_return(true)
+ end
it { expect(get('/gitlab/gitlabhq.keys')).to route_to('projects#show', namespace_id: 'gitlab', id: 'gitlabhq.keys') }
end
context 'with nested group' do
- before { allow(Project).to receive(:find_by_full_path).with('gitlab/subgroup/gitlabhq', any_args).and_return(true) }
+ before do
+ allow(Project).to receive(:find_by_full_path).with('gitlab/subgroup/gitlabhq', any_args).and_return(true)
+ end
it { expect(get('/gitlab/subgroup/gitlabhq')).to route_to('projects#show', namespace_id: 'gitlab/subgroup', id: 'gitlabhq') }
end
diff --git a/spec/routing/routing_spec.rb b/spec/routing/routing_spec.rb
index a62af13cf0c..a45839b16f5 100644
--- a/spec/routing/routing_spec.rb
+++ b/spec/routing/routing_spec.rb
@@ -286,7 +286,9 @@ end
describe "Groups", "routing" do
let(:name) { 'complex.group-namegit' }
- before { allow_any_instance_of(GroupUrlConstrainer).to receive(:matches?).and_return(true) }
+ before do
+ allow_any_instance_of(GroupUrlConstrainer).to receive(:matches?).and_return(true)
+ end
it "to #show" do
expect(get("/groups/#{name}")).to route_to('groups#show', id: name)
diff --git a/spec/rubocop/cop/rspec/single_line_hook_spec.rb b/spec/rubocop/cop/rspec/single_line_hook_spec.rb
new file mode 100644
index 00000000000..6cf0831d3ad
--- /dev/null
+++ b/spec/rubocop/cop/rspec/single_line_hook_spec.rb
@@ -0,0 +1,66 @@
+require 'spec_helper'
+
+require 'rubocop'
+require 'rubocop/rspec/support'
+
+require_relative '../../../../rubocop/cop/rspec/single_line_hook'
+
+describe RuboCop::Cop::RSpec::SingleLineHook do
+ include CopHelper
+
+ subject(:cop) { described_class.new }
+
+ # Override `CopHelper#inspect_source` to always appear to be in a spec file,
+ # so that our RSpec-only cop actually runs
+ def inspect_source(*args)
+ super(*args, 'foo_spec.rb')
+ end
+
+ it 'registers an offense for a single-line `before` block' do
+ inspect_source(cop, 'before { do_something }')
+
+ expect(cop.offenses.size).to eq(1)
+ expect(cop.offenses.map(&:line)).to eq([1])
+ expect(cop.highlights).to eq(['before { do_something }'])
+ end
+
+ it 'registers an offense for a single-line `after` block' do
+ inspect_source(cop, 'after(:each) { undo_something }')
+
+ expect(cop.offenses.size).to eq(1)
+ expect(cop.offenses.map(&:line)).to eq([1])
+ expect(cop.highlights).to eq(['after(:each) { undo_something }'])
+ end
+
+ it 'registers an offense for a single-line `around` block' do
+ inspect_source(cop, 'around { |ex| do_something_else }')
+
+ expect(cop.offenses.size).to eq(1)
+ expect(cop.offenses.map(&:line)).to eq([1])
+ expect(cop.highlights).to eq(['around { |ex| do_something_else }'])
+ end
+
+ it 'ignores a multi-line `before` block' do
+ inspect_source(cop, ['before do',
+ ' do_something',
+ 'end'])
+
+ expect(cop.offenses.size).to eq(0)
+ end
+
+ it 'ignores a multi-line `after` block' do
+ inspect_source(cop, ['after(:each) do',
+ ' undo_something',
+ 'end'])
+
+ expect(cop.offenses.size).to eq(0)
+ end
+
+ it 'ignores a multi-line `around` block' do
+ inspect_source(cop, ['around do |ex|',
+ ' do_something_else',
+ 'end'])
+
+ expect(cop.offenses.size).to eq(0)
+ end
+end
diff --git a/spec/serializers/environment_serializer_spec.rb b/spec/serializers/environment_serializer_spec.rb
index d2ad6c44702..4c52a00b442 100644
--- a/spec/serializers/environment_serializer_spec.rb
+++ b/spec/serializers/environment_serializer_spec.rb
@@ -62,7 +62,9 @@ describe EnvironmentSerializer do
subject { serializer.represent(resource) }
context 'when there is a single environment' do
- before { create(:environment, name: 'staging') }
+ before do
+ create(:environment, name: 'staging')
+ end
it 'represents one standalone environment' do
expect(subject.count).to eq 1
@@ -138,7 +140,9 @@ describe EnvironmentSerializer do
context 'when resource is paginatable relation' do
context 'when there is a single environment object in relation' do
- before { create(:environment) }
+ before do
+ create(:environment)
+ end
it 'serializes environments' do
expect(subject.first).to have_key :id
@@ -146,7 +150,9 @@ describe EnvironmentSerializer do
end
context 'when multiple environment objects are serialized' do
- before { create_list(:environment, 3) }
+ before do
+ create_list(:environment, 3)
+ end
it 'serializes appropriate number of objects' do
expect(subject.count).to be 2
diff --git a/spec/serializers/pipeline_details_entity_spec.rb b/spec/serializers/pipeline_details_entity_spec.rb
index 5cb9b9945b6..d28dec9592a 100644
--- a/spec/serializers/pipeline_details_entity_spec.rb
+++ b/spec/serializers/pipeline_details_entity_spec.rb
@@ -51,7 +51,9 @@ describe PipelineDetailsEntity do
end
context 'user has ability to retry pipeline' do
- before { project.team << [user, :developer] }
+ before do
+ project.team << [user, :developer]
+ end
it 'retryable flag is true' do
expect(subject[:flags][:retryable]).to eq true
@@ -77,7 +79,9 @@ describe PipelineDetailsEntity do
end
context 'user has ability to cancel pipeline' do
- before { project.add_developer(user) }
+ before do
+ project.add_developer(user)
+ end
it 'cancelable flag is true' do
expect(subject[:flags][:cancelable]).to eq true
diff --git a/spec/serializers/pipeline_entity_spec.rb b/spec/serializers/pipeline_entity_spec.rb
index a059c2cc736..46650f3a80d 100644
--- a/spec/serializers/pipeline_entity_spec.rb
+++ b/spec/serializers/pipeline_entity_spec.rb
@@ -51,7 +51,9 @@ describe PipelineEntity do
end
context 'user has ability to retry pipeline' do
- before { project.team << [user, :developer] }
+ before do
+ project.team << [user, :developer]
+ end
it 'contains retry path' do
expect(subject[:retry_path]).to be_present
@@ -77,7 +79,9 @@ describe PipelineEntity do
end
context 'user has ability to cancel pipeline' do
- before { project.add_developer(user) }
+ before do
+ project.add_developer(user)
+ end
it 'contains cancel path' do
expect(subject[:cancel_path]).to be_present
diff --git a/spec/serializers/pipeline_serializer_spec.rb b/spec/serializers/pipeline_serializer_spec.rb
index 34b19fb9fc4..44813656aff 100644
--- a/spec/serializers/pipeline_serializer_spec.rb
+++ b/spec/serializers/pipeline_serializer_spec.rb
@@ -69,7 +69,9 @@ describe PipelineSerializer do
let(:pagination) { { page: 1, per_page: 2 } }
context 'when a single pipeline object is present in relation' do
- before { create(:ci_empty_pipeline) }
+ before do
+ create(:ci_empty_pipeline)
+ end
it 'serializes pipeline relation' do
expect(subject.first).to have_key :id
@@ -77,7 +79,9 @@ describe PipelineSerializer do
end
context 'when a multiple pipeline objects are being serialized' do
- before { create_list(:ci_empty_pipeline, 3) }
+ before do
+ create_list(:ci_empty_pipeline, 3)
+ end
it 'serializes appropriate number of objects' do
expect(subject.count).to be 2
diff --git a/spec/services/auth/container_registry_authentication_service_spec.rb b/spec/services/auth/container_registry_authentication_service_spec.rb
index e273dfe1552..60cb7a9440f 100644
--- a/spec/services/auth/container_registry_authentication_service_spec.rb
+++ b/spec/services/auth/container_registry_authentication_service_spec.rb
@@ -34,7 +34,9 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
end
context 'for changed configuration' do
- before { stub_application_setting(container_registry_token_expire_delay: expire_delay) }
+ before do
+ stub_application_setting(container_registry_token_expire_delay: expire_delay)
+ end
it { expect(expires_at).to be_within(2.seconds).of(Time.now + expire_delay.minutes) }
end
@@ -117,7 +119,9 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
end
context 'allow developer to push images' do
- before { project.team << [current_user, :developer] }
+ before do
+ project.team << [current_user, :developer]
+ end
let(:current_params) do
{ scope: "repository:#{project.path_with_namespace}:push" }
@@ -128,7 +132,9 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
end
context 'allow reporter to pull images' do
- before { project.team << [current_user, :reporter] }
+ before do
+ project.team << [current_user, :reporter]
+ end
context 'when pulling from root level repository' do
let(:current_params) do
@@ -141,7 +147,9 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
end
context 'return a least of privileges' do
- before { project.team << [current_user, :reporter] }
+ before do
+ project.team << [current_user, :reporter]
+ end
let(:current_params) do
{ scope: "repository:#{project.path_with_namespace}:push,pull" }
@@ -152,7 +160,9 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
end
context 'disallow guest to pull or push images' do
- before { project.team << [current_user, :guest] }
+ before do
+ project.team << [current_user, :guest]
+ end
let(:current_params) do
{ scope: "repository:#{project.path_with_namespace}:pull,push" }
@@ -355,7 +365,9 @@ describe Auth::ContainerRegistryAuthenticationService, services: true do
context 'for project without container registry' do
let(:project) { create(:empty_project, :public, container_registry_enabled: false) }
- before { project.update(container_registry_enabled: false) }
+ before do
+ project.update(container_registry_enabled: false)
+ end
context 'disallow when pulling' do
let(:current_params) do
diff --git a/spec/services/ci/update_build_queue_service_spec.rb b/spec/services/ci/update_build_queue_service_spec.rb
index c44e6b2a48b..efefa8e8eca 100644
--- a/spec/services/ci/update_build_queue_service_spec.rb
+++ b/spec/services/ci/update_build_queue_service_spec.rb
@@ -9,7 +9,9 @@ describe Ci::UpdateBuildQueueService, :services do
let(:runner) { create(:ci_runner) }
context 'when there are runner that can pick build' do
- before { build.project.runners << runner }
+ before do
+ build.project.runners << runner
+ end
it 'ticks runner queue value' do
expect { subject.execute(build) }
@@ -36,7 +38,9 @@ describe Ci::UpdateBuildQueueService, :services do
end
context 'when there are no runners that can pick build' do
- before { build.tag_list = [:docker] }
+ before do
+ build.tag_list = [:docker]
+ end
it 'does not tick runner queue value' do
expect { subject.execute(build) }
diff --git a/spec/services/create_deployment_service_spec.rb b/spec/services/create_deployment_service_spec.rb
index 5398b5c3f7e..6cf4342ad4c 100644
--- a/spec/services/create_deployment_service_spec.rb
+++ b/spec/services/create_deployment_service_spec.rb
@@ -204,7 +204,9 @@ describe CreateDeploymentService, services: true do
let(:merge_request) { create(:merge_request, target_branch: 'master', source_branch: 'feature', source_project: project) }
context "while updating the 'first_deployed_to_production_at' time" do
- before { merge_request.mark_as_merged }
+ before do
+ merge_request.mark_as_merged
+ end
context "for merge requests merged before the current deploy" do
it "sets the time if the deploy's environment is 'production'" do
diff --git a/spec/services/groups/create_service_spec.rb b/spec/services/groups/create_service_spec.rb
index bcb62429275..fbd9026640c 100644
--- a/spec/services/groups/create_service_spec.rb
+++ b/spec/services/groups/create_service_spec.rb
@@ -14,7 +14,9 @@ describe Groups::CreateService, '#execute', services: true do
end
context "cannot create group with restricted visibility level" do
- before { allow_any_instance_of(ApplicationSetting).to receive(:restricted_visibility_levels).and_return([Gitlab::VisibilityLevel::PUBLIC]) }
+ before do
+ allow_any_instance_of(ApplicationSetting).to receive(:restricted_visibility_levels).and_return([Gitlab::VisibilityLevel::PUBLIC])
+ end
it { is_expected.not_to be_persisted }
end
@@ -25,7 +27,9 @@ describe Groups::CreateService, '#execute', services: true do
let!(:service) { described_class.new(user, group_params.merge(parent_id: group.id)) }
context 'as group owner' do
- before { group.add_owner(user) }
+ before do
+ group.add_owner(user)
+ end
it { is_expected.to be_persisted }
end
diff --git a/spec/services/issues/create_service_spec.rb b/spec/services/issues/create_service_spec.rb
index dab1a3469f7..370bd352200 100644
--- a/spec/services/issues/create_service_spec.rb
+++ b/spec/services/issues/create_service_spec.rb
@@ -155,7 +155,9 @@ describe Issues::CreateService, services: true do
context 'issue create service' do
context 'assignees' do
- before { project.team << [user, :master] }
+ before do
+ project.team << [user, :master]
+ end
it 'removes assignee when user id is invalid' do
opts = { title: 'Title', description: 'Description', assignee_ids: [-1] }
diff --git a/spec/services/issues/move_service_spec.rb b/spec/services/issues/move_service_spec.rb
index 9f8346d52bb..d1dd1466d95 100644
--- a/spec/services/issues/move_service_spec.rb
+++ b/spec/services/issues/move_service_spec.rb
@@ -251,12 +251,18 @@ describe Issues::MoveService, services: true do
end
context 'user is reporter only in new project' do
- before { new_project.team << [user, :reporter] }
+ before do
+ new_project.team << [user, :reporter]
+ end
+
it { expect { move }.to raise_error(StandardError, /permissions/) }
end
context 'user is reporter only in old project' do
- before { old_project.team << [user, :reporter] }
+ before do
+ old_project.team << [user, :reporter]
+ end
+
it { expect { move }.to raise_error(StandardError, /permissions/) }
end
diff --git a/spec/services/issues/update_service_spec.rb b/spec/services/issues/update_service_spec.rb
index a78866a2c32..c26642f5015 100644
--- a/spec/services/issues/update_service_spec.rb
+++ b/spec/services/issues/update_service_spec.rb
@@ -295,7 +295,9 @@ describe Issues::UpdateService, services: true do
end
context 'when issue has the `label` label' do
- before { issue.labels << label }
+ before do
+ issue.labels << label
+ end
it 'does not send notifications for existing labels' do
opts = { label_ids: [label.id, label2.id] }
@@ -329,7 +331,9 @@ describe Issues::UpdateService, services: true do
it { expect(issue.tasks?).to eq(true) }
context 'when tasks are marked as completed' do
- before { update_issue(description: "- [x] Task 1\n- [X] Task 2") }
+ before do
+ update_issue(description: "- [x] Task 1\n- [X] Task 2")
+ end
it 'creates system note about task status change' do
note1 = find_note('marked the task **Task 1** as completed')
@@ -417,7 +421,9 @@ describe Issues::UpdateService, services: true do
context 'when remove_label_ids and label_ids are passed' do
let(:params) { { label_ids: [], remove_label_ids: [label.id] } }
- before { issue.update_attributes(labels: [label, label3]) }
+ before do
+ issue.update_attributes(labels: [label, label3])
+ end
it 'ignores the label_ids parameter' do
expect(result.label_ids).not_to be_empty
@@ -431,7 +437,9 @@ describe Issues::UpdateService, services: true do
context 'when add_label_ids and remove_label_ids are passed' do
let(:params) { { add_label_ids: [label3.id], remove_label_ids: [label.id] } }
- before { issue.update_attributes(labels: [label]) }
+ before do
+ issue.update_attributes(labels: [label])
+ end
it 'adds the passed labels' do
expect(result.label_ids).to include(label3.id)
diff --git a/spec/services/members/create_service_spec.rb b/spec/services/members/create_service_spec.rb
index 5ce8e17976b..5a05ab3ea50 100644
--- a/spec/services/members/create_service_spec.rb
+++ b/spec/services/members/create_service_spec.rb
@@ -5,7 +5,9 @@ describe Members::CreateService, services: true do
let(:user) { create(:user) }
let(:project_user) { create(:user) }
- before { project.team << [user, :master] }
+ before do
+ project.team << [user, :master]
+ end
it 'adds user to members' do
params = { user_ids: project_user.id.to_s, access_level: Gitlab::Access::GUEST }
diff --git a/spec/services/merge_requests/build_service_spec.rb b/spec/services/merge_requests/build_service_spec.rb
index 6f9d1208b1d..01ef52396d7 100644
--- a/spec/services/merge_requests/build_service_spec.rb
+++ b/spec/services/merge_requests/build_service_spec.rb
@@ -206,7 +206,9 @@ describe MergeRequests::BuildService, services: true do
context 'branch starts with external issue IID followed by a hyphen' do
let(:source_branch) { '12345-fix-issue' }
- before { allow(project).to receive(:default_issues_tracker?).and_return(false) }
+ before do
+ allow(project).to receive(:default_issues_tracker?).and_return(false)
+ end
it 'sets the title to: Resolves External Issue $issue-iid' do
expect(merge_request.title).to eq('Resolve External Issue 12345')
diff --git a/spec/services/merge_requests/create_service_spec.rb b/spec/services/merge_requests/create_service_spec.rb
index 2963f62cc7d..13fee953e41 100644
--- a/spec/services/merge_requests/create_service_spec.rb
+++ b/spec/services/merge_requests/create_service_spec.rb
@@ -150,7 +150,9 @@ describe MergeRequests::CreateService, services: true do
context 'asssignee_id' do
let(:assignee) { create(:user) }
- before { project.team << [user, :master] }
+ before do
+ project.team << [user, :master]
+ end
it 'removes assignee_id when user id is invalid' do
opts = { title: 'Title', description: 'Description', assignee_id: -1 }
diff --git a/spec/services/merge_requests/merge_service_spec.rb b/spec/services/merge_requests/merge_service_spec.rb
index d96f819e66a..b3b188a805f 100644
--- a/spec/services/merge_requests/merge_service_spec.rb
+++ b/spec/services/merge_requests/merge_service_spec.rb
@@ -81,7 +81,9 @@ describe MergeRequests::MergeService, services: true do
end
context "when jira_issue_transition_id is not present" do
- before { allow_any_instance_of(JIRA::Resource::Issue).to receive(:resolution).and_return(nil) }
+ before do
+ allow_any_instance_of(JIRA::Resource::Issue).to receive(:resolution).and_return(nil)
+ end
it "does not close issue" do
allow(jira_tracker).to receive_messages(jira_issue_transition_id: nil)
diff --git a/spec/services/merge_requests/update_service_spec.rb b/spec/services/merge_requests/update_service_spec.rb
index 091c193aaa6..fd46020bbdb 100644
--- a/spec/services/merge_requests/update_service_spec.rb
+++ b/spec/services/merge_requests/update_service_spec.rb
@@ -356,7 +356,9 @@ describe MergeRequests::UpdateService, services: true do
end
context 'when issue has the `label` label' do
- before { merge_request.labels << label }
+ before do
+ merge_request.labels << label
+ end
it 'does not send notifications for existing labels' do
opts = { label_ids: [label.id, label2.id] }
@@ -388,12 +390,16 @@ describe MergeRequests::UpdateService, services: true do
end
context 'when MergeRequest has tasks' do
- before { update_merge_request({ description: "- [ ] Task 1\n- [ ] Task 2" }) }
+ before do
+ update_merge_request({ description: "- [ ] Task 1\n- [ ] Task 2" })
+ end
it { expect(@merge_request.tasks?).to eq(true) }
context 'when tasks are marked as completed' do
- before { update_merge_request({ description: "- [x] Task 1\n- [X] Task 2" }) }
+ before do
+ update_merge_request({ description: "- [x] Task 1\n- [X] Task 2" })
+ end
it 'creates system note about task status change' do
note1 = find_note('marked the task **Task 1** as completed')
diff --git a/spec/services/notes/slash_commands_service_spec.rb b/spec/services/notes/slash_commands_service_spec.rb
index c9954dc3603..d5ffc1908a9 100644
--- a/spec/services/notes/slash_commands_service_spec.rb
+++ b/spec/services/notes/slash_commands_service_spec.rb
@@ -6,7 +6,9 @@ describe Notes::SlashCommandsService, services: true do
let(:master) { create(:user).tap { |u| project.team << [u, :master] } }
let(:assignee) { create(:user) }
- before { project.team << [assignee, :master] }
+ before do
+ project.team << [assignee, :master]
+ end
end
shared_examples 'note on noteable that does not support slash commands' do
diff --git a/spec/services/pages_service_spec.rb b/spec/services/pages_service_spec.rb
index aa63fe3a5c1..cf38c7c75e5 100644
--- a/spec/services/pages_service_spec.rb
+++ b/spec/services/pages_service_spec.rb
@@ -10,10 +10,14 @@ describe PagesService, services: true do
end
context 'execute asynchronously for pages job' do
- before { build.name = 'pages' }
+ before do
+ build.name = 'pages'
+ end
context 'on success' do
- before { build.success }
+ before do
+ build.success
+ end
it 'executes worker' do
expect(PagesWorker).to receive(:perform_async)
@@ -23,7 +27,9 @@ describe PagesService, services: true do
%w(pending running failed canceled).each do |status|
context "on #{status}" do
- before { build.status = status }
+ before do
+ build.status = status
+ end
it 'does not execute worker' do
expect(PagesWorker).not_to receive(:perform_async)
diff --git a/spec/services/projects/transfer_service_spec.rb b/spec/services/projects/transfer_service_spec.rb
index b957517c715..5d2f4cf17fb 100644
--- a/spec/services/projects/transfer_service_spec.rb
+++ b/spec/services/projects/transfer_service_spec.rb
@@ -59,12 +59,16 @@ describe Projects::TransferService, services: true do
context 'visibility level' do
let(:internal_group) { create(:group, :internal) }
- before { internal_group.add_owner(user) }
+ before do
+ internal_group.add_owner(user)
+ end
context 'when namespace visibility level < project visibility level' do
let(:public_project) { create(:project, :public, :repository, namespace: user.namespace) }
- before { transfer_project(public_project, user, internal_group) }
+ before do
+ transfer_project(public_project, user, internal_group)
+ end
it { expect(public_project.visibility_level).to eq(internal_group.visibility_level) }
end
@@ -72,7 +76,9 @@ describe Projects::TransferService, services: true do
context 'when namespace visibility level > project visibility level' do
let(:private_project) { create(:project, :private, :repository, namespace: user.namespace) }
- before { transfer_project(private_project, user, internal_group) }
+ before do
+ transfer_project(private_project, user, internal_group)
+ end
it { expect(private_project.visibility_level).to eq(Gitlab::VisibilityLevel::PRIVATE) }
end
diff --git a/spec/services/slash_commands/interpret_service_spec.rb b/spec/services/slash_commands/interpret_service_spec.rb
index 4db491fd5f3..c12fb1a6e53 100644
--- a/spec/services/slash_commands/interpret_service_spec.rb
+++ b/spec/services/slash_commands/interpret_service_spec.rb
@@ -378,7 +378,9 @@ describe SlashCommands::InterpretService, services: true do
context 'assign command with multiple assignees' do
let(:content) { "/assign @#{developer.username} @#{developer2.username}" }
- before{ project.team << [developer2, :developer] }
+ before do
+ project.team << [developer2, :developer]
+ end
context 'Issue' do
it 'fetches assignee and populates assignee_id if content contains /assign' do
@@ -798,7 +800,11 @@ describe SlashCommands::InterpretService, services: true do
context 'if the project has multiple boards' do
let(:issuable) { issue }
- before { create(:board, project: project) }
+
+ before do
+ create(:board, project: project)
+ end
+
it_behaves_like 'empty command'
end
diff --git a/spec/services/spam_service_spec.rb b/spec/services/spam_service_spec.rb
index 74cba8c014b..5e6e43b7a90 100644
--- a/spec/services/spam_service_spec.rb
+++ b/spec/services/spam_service_spec.rb
@@ -70,7 +70,9 @@ describe SpamService, services: true do
end
context 'when not indicated as spam by akismet' do
- before { allow(AkismetService).to receive(:new).and_return(double(is_spam?: false)) }
+ before do
+ allow(AkismetService).to receive(:new).and_return(double(is_spam?: false))
+ end
it 'returns false' do
expect(check_spam(issue, request, false)).to be_falsey
diff --git a/spec/support/kubernetes_helpers.rb b/spec/support/kubernetes_helpers.rb
index 9280fad4ace..c92f78b324c 100644
--- a/spec/support/kubernetes_helpers.rb
+++ b/spec/support/kubernetes_helpers.rb
@@ -1,7 +1,26 @@
module KubernetesHelpers
include Gitlab::Kubernetes
- def kube_discovery_body
+ def kube_response(body)
+ { body: body.to_json }
+ end
+
+ def kube_pods_response
+ kube_response(kube_pods_body)
+ end
+
+ def stub_kubeclient_discover
+ WebMock.stub_request(:get, service.api_url + '/api/v1').to_return(kube_response(kube_v1_discovery_body))
+ end
+
+ def stub_kubeclient_pods(response = nil)
+ stub_kubeclient_discover
+ pods_url = service.api_url + "/api/v1/namespaces/#{service.actual_namespace}/pods"
+
+ WebMock.stub_request(:get, pods_url).to_return(response || kube_pods_response)
+ end
+
+ def kube_v1_discovery_body
{
"kind" => "APIResourceList",
"resources" => [
@@ -10,17 +29,19 @@ module KubernetesHelpers
}
end
- def kube_pods_body(*pods)
- { "kind" => "PodList",
- "items" => [kube_pod] }
+ def kube_pods_body
+ {
+ "kind" => "PodList",
+ "items" => [kube_pod]
+ }
end
# This is a partial response, it will have many more elements in reality but
# these are the ones we care about at the moment
- def kube_pod(app: "valid-pod-label")
+ def kube_pod(name: "kube-pod", app: "valid-pod-label")
{
"metadata" => {
- "name" => "kube-pod",
+ "name" => name,
"creationTimestamp" => "2016-11-25T19:55:19Z",
"labels" => { "app" => app }
},
diff --git a/spec/support/milestone_tabs_examples.rb b/spec/support/milestone_tabs_examples.rb
index 7cfc1e06975..70b499198bf 100644
--- a/spec/support/milestone_tabs_examples.rb
+++ b/spec/support/milestone_tabs_examples.rb
@@ -15,7 +15,9 @@ shared_examples 'milestone tabs' do
describe '#merge_requests' do
context 'as html' do
- before { go(:merge_requests, format: 'html') }
+ before do
+ go(:merge_requests, format: 'html')
+ end
it 'redirects to milestone#show' do
expect(response).to redirect_to(milestone_path)
@@ -23,7 +25,9 @@ shared_examples 'milestone tabs' do
end
context 'as json' do
- before { go(:merge_requests, format: 'json') }
+ before do
+ go(:merge_requests, format: 'json')
+ end
it 'renders the merge requests tab template to a string' do
expect(response).to render_template('shared/milestones/_merge_requests_tab')
@@ -34,7 +38,9 @@ shared_examples 'milestone tabs' do
describe '#participants' do
context 'as html' do
- before { go(:participants, format: 'html') }
+ before do
+ go(:participants, format: 'html')
+ end
it 'redirects to milestone#show' do
expect(response).to redirect_to(milestone_path)
@@ -42,7 +48,9 @@ shared_examples 'milestone tabs' do
end
context 'as json' do
- before { go(:participants, format: 'json') }
+ before do
+ go(:participants, format: 'json')
+ end
it 'renders the participants tab template to a string' do
expect(response).to render_template('shared/milestones/_participants_tab')
@@ -53,7 +61,9 @@ shared_examples 'milestone tabs' do
describe '#labels' do
context 'as html' do
- before { go(:labels, format: 'html') }
+ before do
+ go(:labels, format: 'html')
+ end
it 'redirects to milestone#show' do
expect(response).to redirect_to(milestone_path)
@@ -61,7 +71,9 @@ shared_examples 'milestone tabs' do
end
context 'as json' do
- before { go(:labels, format: 'json') }
+ before do
+ go(:labels, format: 'json')
+ end
it 'renders the labels tab template to a string' do
expect(response).to render_template('shared/milestones/_labels_tab')
diff --git a/spec/support/reference_parser_shared_examples.rb b/spec/support/reference_parser_shared_examples.rb
index 8eb74635a60..bd83cb88058 100644
--- a/spec/support/reference_parser_shared_examples.rb
+++ b/spec/support/reference_parser_shared_examples.rb
@@ -3,7 +3,9 @@ RSpec.shared_examples "referenced feature visibility" do |*related_features|
related_features.map { |feature| (feature + "_access_level").to_sym }
end
- before { link['data-project'] = project.id.to_s }
+ before do
+ link['data-project'] = project.id.to_s
+ end
context "when feature is disabled" do
it "does not create reference" do
@@ -13,7 +15,9 @@ RSpec.shared_examples "referenced feature visibility" do |*related_features|
end
context "when feature is enabled only for team members" do
- before { set_features_fields_to(ProjectFeature::PRIVATE) }
+ before do
+ set_features_fields_to(ProjectFeature::PRIVATE)
+ end
it "does not create reference for non member" do
non_member = create(:user)
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 1dd3663b944..5e6f9f323a1 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
@@ -11,7 +11,9 @@ shared_examples 'new issuable record that supports slash commands' do
let(:params) { base_params.merge(defined?(default_params) ? default_params : {}).merge(example_params) }
let(:issuable) { described_class.new(project, user, params).execute }
- before { project.team << [assignee, :master] }
+ before do
+ project.team << [assignee, :master]
+ end
context 'with labels in command only' do
let(:example_params) do
diff --git a/spec/support/services/issuable_update_service_shared_examples.rb b/spec/support/services/issuable_update_service_shared_examples.rb
index 8947f20562f..ffbce6c42bf 100644
--- a/spec/support/services/issuable_update_service_shared_examples.rb
+++ b/spec/support/services/issuable_update_service_shared_examples.rb
@@ -4,7 +4,9 @@ shared_examples 'issuable update service' do
end
context 'changing state' do
- before { expect(project).to receive(:execute_hooks).once }
+ before do
+ expect(project).to receive(:execute_hooks).once
+ end
context 'to reopened' do
it 'executes hooks only once' do
diff --git a/spec/support/slack_mattermost_notifications_shared_examples.rb b/spec/support/slack_mattermost_notifications_shared_examples.rb
index 7e35ebb6c97..a7deb038703 100644
--- a/spec/support/slack_mattermost_notifications_shared_examples.rb
+++ b/spec/support/slack_mattermost_notifications_shared_examples.rb
@@ -11,14 +11,18 @@ RSpec.shared_examples 'slack or mattermost notifications' do
describe 'Validations' do
context 'when service is active' do
- before { subject.active = true }
+ before do
+ subject.active = true
+ end
it { is_expected.to validate_presence_of(:webhook) }
it_behaves_like 'issue tracker service URL attribute', :webhook
end
context 'when service is inactive' do
- before { subject.active = false }
+ before do
+ subject.active = false
+ end
it { is_expected.not_to validate_presence_of(:webhook) }
end
diff --git a/spec/support/unique_ip_check_shared_examples.rb b/spec/support/unique_ip_check_shared_examples.rb
index 7cf5a65eeed..1986d202c4a 100644
--- a/spec/support/unique_ip_check_shared_examples.rb
+++ b/spec/support/unique_ip_check_shared_examples.rb
@@ -31,7 +31,9 @@ end
shared_examples 'user login operation with unique ip limit' do
include_context 'unique ips sign in limit' do
- before { current_application_settings.update!(unique_ips_limit_per_user: 1) }
+ before do
+ current_application_settings.update!(unique_ips_limit_per_user: 1)
+ end
it 'allows user authenticating from the same ip' do
expect { operation_from_ip('ip') }.not_to raise_error
@@ -47,7 +49,9 @@ end
shared_examples 'user login request with unique ip limit' do |success_status = 200|
include_context 'unique ips sign in limit' do
- before { current_application_settings.update!(unique_ips_limit_per_user: 1) }
+ before do
+ current_application_settings.update!(unique_ips_limit_per_user: 1)
+ end
it 'allows user authenticating from the same ip' do
expect(request_from_ip('ip')).to have_http_status(success_status)
diff --git a/spec/support/updating_mentions_shared_examples.rb b/spec/support/updating_mentions_shared_examples.rb
index e0c59a5c280..eeec3e1d79b 100644
--- a/spec/support/updating_mentions_shared_examples.rb
+++ b/spec/support/updating_mentions_shared_examples.rb
@@ -2,7 +2,9 @@ RSpec.shared_examples 'updating mentions' do |service_class|
let(:mentioned_user) { create(:user) }
let(:service_class) { service_class }
- before { project.team << [mentioned_user, :developer] }
+ before do
+ project.team << [mentioned_user, :developer]
+ end
def update_mentionable(opts)
reset_delivered_emails!
@@ -15,7 +17,9 @@ RSpec.shared_examples 'updating mentions' do |service_class|
end
context 'in title' do
- before { update_mentionable(title: mentioned_user.to_reference) }
+ before do
+ update_mentionable(title: mentioned_user.to_reference)
+ end
it 'emails only the newly-mentioned user' do
should_only_email(mentioned_user)
@@ -23,7 +27,9 @@ RSpec.shared_examples 'updating mentions' do |service_class|
end
context 'in description' do
- before { update_mentionable(description: mentioned_user.to_reference) }
+ before do
+ update_mentionable(description: mentioned_user.to_reference)
+ end
it 'emails only the newly-mentioned user' do
should_only_email(mentioned_user)
diff --git a/spec/views/projects/diffs/_viewer.html.haml_spec.rb b/spec/views/projects/diffs/_viewer.html.haml_spec.rb
new file mode 100644
index 00000000000..32469202508
--- /dev/null
+++ b/spec/views/projects/diffs/_viewer.html.haml_spec.rb
@@ -0,0 +1,71 @@
+require 'spec_helper'
+
+describe 'projects/diffs/_viewer.html.haml', :view do
+ include FakeBlobHelpers
+
+ let(:project) { create(:project, :repository) }
+ let(:commit) { project.commit('570e7b2abdd848b95f2f578043fc23bd6f6fd24d') }
+ let(:diff_file) { commit.diffs.diff_file_with_new_path('files/ruby/popen.rb') }
+
+ let(:viewer_class) do
+ Class.new(DiffViewer::Base) do
+ include DiffViewer::Rich
+
+ self.partial_name = 'text'
+ end
+ end
+
+ let(:viewer) { viewer_class.new(diff_file) }
+
+ before do
+ assign(:project, project)
+
+ controller.params[:controller] = 'projects/commit'
+ controller.params[:action] = 'show'
+ controller.params[:namespace_id] = project.namespace.to_param
+ controller.params[:project_id] = project.to_param
+ controller.params[:id] = commit.id
+ end
+
+ def render_view
+ render partial: 'projects/diffs/viewer', locals: { viewer: viewer }
+ end
+
+ context 'when there is a render error' do
+ before do
+ allow(viewer).to receive(:render_error).and_return(:too_large)
+ end
+
+ it 'renders the error' do
+ render_view
+
+ expect(view).to render_template('projects/diffs/_render_error')
+ end
+ end
+
+ context 'when the viewer is collapsed' do
+ before do
+ allow(diff_file).to receive(:collapsed?).and_return(true)
+ end
+
+ it 'renders the collapsed view' do
+ render_view
+
+ expect(view).to render_template('projects/diffs/_collapsed')
+ end
+ end
+
+ context 'when there is no render error' do
+ it 'prepares the viewer' do
+ expect(viewer).to receive(:prepare!)
+
+ render_view
+ end
+
+ it 'renders the viewer' do
+ render_view
+
+ expect(view).to render_template('projects/diffs/viewers/_text')
+ end
+ end
+end
diff --git a/spec/workers/emails_on_push_worker_spec.rb b/spec/workers/emails_on_push_worker_spec.rb
index a0ed85cc0b3..5b6b38e0f76 100644
--- a/spec/workers/emails_on_push_worker_spec.rb
+++ b/spec/workers/emails_on_push_worker_spec.rb
@@ -71,7 +71,9 @@ describe EmailsOnPushWorker do
end
context "when there are no errors in sending" do
- before { perform }
+ before do
+ perform
+ end
it "sends a mail with the correct subject" do
expect(email.subject).to include('adds bar folder and branch-test text file')
diff --git a/spec/workers/expire_build_artifacts_worker_spec.rb b/spec/workers/expire_build_artifacts_worker_spec.rb
index 73cbadc13d9..b47b4a02a68 100644
--- a/spec/workers/expire_build_artifacts_worker_spec.rb
+++ b/spec/workers/expire_build_artifacts_worker_spec.rb
@@ -5,10 +5,14 @@ describe ExpireBuildArtifactsWorker do
let(:worker) { described_class.new }
- before { Sidekiq::Worker.clear_all }
+ before do
+ Sidekiq::Worker.clear_all
+ end
describe '#perform' do
- before { build }
+ before do
+ build
+ end
subject! do
Sidekiq::Testing.fake! { worker.perform }
diff --git a/spec/workers/git_garbage_collect_worker_spec.rb b/spec/workers/git_garbage_collect_worker_spec.rb
index 8c5303b61cc..f443bb2c9b4 100644
--- a/spec/workers/git_garbage_collect_worker_spec.rb
+++ b/spec/workers/git_garbage_collect_worker_spec.rb
@@ -23,7 +23,9 @@ describe GitGarbageCollectWorker do
end
shared_examples 'gc tasks' do
- before { allow(subject).to receive(:bitmaps_enabled?).and_return(bitmaps_enabled) }
+ before do
+ allow(subject).to receive(:bitmaps_enabled?).and_return(bitmaps_enabled)
+ end
it 'incremental repack adds a new packfile' do
create_objects(project)
diff --git a/spec/workers/post_receive_spec.rb b/spec/workers/post_receive_spec.rb
index 44163c735ba..3c93da63f2e 100644
--- a/spec/workers/post_receive_spec.rb
+++ b/spec/workers/post_receive_spec.rb
@@ -89,7 +89,9 @@ describe PostReceive do
end
context "does not create a Ci::Pipeline" do
- before { stub_ci_pipeline_yaml_file(nil) }
+ before do
+ stub_ci_pipeline_yaml_file(nil)
+ end
it { expect{ subject }.not_to change{ Ci::Pipeline.count } }
end
diff --git a/spec/workers/stuck_ci_jobs_worker_spec.rb b/spec/workers/stuck_ci_jobs_worker_spec.rb
index 8434b0c8e5b..549635f7f33 100644
--- a/spec/workers/stuck_ci_jobs_worker_spec.rb
+++ b/spec/workers/stuck_ci_jobs_worker_spec.rb
@@ -34,7 +34,9 @@ describe StuckCiJobsWorker do
let(:status) { 'pending' }
context 'when job is not stuck' do
- before { allow_any_instance_of(Ci::Build).to receive(:stuck?).and_return(false) }
+ before do
+ allow_any_instance_of(Ci::Build).to receive(:stuck?).and_return(false)
+ end
context 'when job was not updated for more than 1 day ago' do
let(:updated_at) { 2.days.ago }
@@ -53,7 +55,9 @@ describe StuckCiJobsWorker do
end
context 'when job is stuck' do
- before { allow_any_instance_of(Ci::Build).to receive(:stuck?).and_return(true) }
+ before do
+ allow_any_instance_of(Ci::Build).to receive(:stuck?).and_return(true)
+ end
context 'when job was not updated for more than 1 hour ago' do
let(:updated_at) { 2.hours.ago }
@@ -93,7 +97,9 @@ describe StuckCiJobsWorker do
let(:status) { 'running' }
let(:updated_at) { 2.days.ago }
- before { job.project.update(pending_delete: true) }
+ before do
+ job.project.update(pending_delete: true)
+ end
it 'does not drop job' do
expect_any_instance_of(Ci::Build).not_to receive(:drop)