summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorGrzegorz Bizon <grzesiek.bizon@gmail.com>2017-08-16 13:18:03 +0200
committerGrzegorz Bizon <grzesiek.bizon@gmail.com>2017-08-16 13:18:03 +0200
commit32d0983a4ea3ce61b78e4d11d61892989ac4cb35 (patch)
tree3fe78e7302579c38046a7fbfd79ee1d78d8aecd3 /spec
parent13a15e7009e292919109ea911640a627dbd0e327 (diff)
parent04f7f394d3825e3290f523dce28d42b7c87fc9bb (diff)
downloadgitlab-ce-32d0983a4ea3ce61b78e4d11d61892989ac4cb35.tar.gz
Merge branch 'master' into backstage/gb/migrate-stages-statuses
* master: (1000 commits) Fix username autocomplete group name with no avatar alignment Fix 'Projected tags' typo in protected_tags_spec.rb Many Repo Fixes Repo Editor Fixes Docs: New index for permissions link article from CI index link tech articles from the landing page new articles come first fix relative link fix date format Fixed changed files dropdown not being shown Update publication date Remove deprecated field from workhorse API responses Fix API responses when dealing with txt files Make sure MySQL would not use CURRENT_TIMESTAMP Add two more project templates Allow usage of any_projects? with an Array Copyedit Artifactory and GitLab article Rename Artifactory and GitLab article file Display GPG status loading spinner only when Ajax request is made ...
Diffstat (limited to 'spec')
-rw-r--r--spec/bin/changelog_spec.rb98
-rw-r--r--spec/config/mail_room_spec.rb4
-rw-r--r--spec/controllers/admin/groups_controller_spec.rb2
-rw-r--r--spec/controllers/admin/health_check_controller_spec.rb25
-rw-r--r--spec/controllers/admin/projects_controller_spec.rb14
-rw-r--r--spec/controllers/admin/services_controller_spec.rb4
-rw-r--r--spec/controllers/admin/users_controller_spec.rb4
-rw-r--r--spec/controllers/application_controller_spec.rb24
-rw-r--r--spec/controllers/autocomplete_controller_spec.rb135
-rw-r--r--spec/controllers/dashboard/labels_controller_spec.rb4
-rw-r--r--spec/controllers/dashboard/milestones_controller_spec.rb2
-rw-r--r--spec/controllers/dashboard/todos_controller_spec.rb6
-rw-r--r--spec/controllers/explore/projects_controller_spec.rb4
-rw-r--r--spec/controllers/groups/milestones_controller_spec.rb4
-rw-r--r--spec/controllers/groups_controller_spec.rb2
-rw-r--r--spec/controllers/import/bitbucket_controller_spec.rb4
-rw-r--r--spec/controllers/import/fogbugz_controller_spec.rb4
-rw-r--r--spec/controllers/import/gitlab_controller_spec.rb4
-rw-r--r--spec/controllers/import/google_code_controller_spec.rb4
-rw-r--r--spec/controllers/invites_controller_spec.rb2
-rw-r--r--spec/controllers/notification_settings_controller_spec.rb4
-rw-r--r--spec/controllers/projects/avatars_controller_spec.rb2
-rw-r--r--spec/controllers/projects/blob_controller_spec.rb24
-rw-r--r--spec/controllers/projects/boards/issues_controller_spec.rb2
-rw-r--r--spec/controllers/projects/boards/lists_controller_spec.rb2
-rw-r--r--spec/controllers/projects/boards_controller_spec.rb2
-rw-r--r--spec/controllers/projects/branches_controller_spec.rb8
-rw-r--r--spec/controllers/projects/deploy_keys_controller_spec.rb4
-rw-r--r--spec/controllers/projects/deployments_controller_spec.rb2
-rw-r--r--spec/controllers/projects/environments_controller_spec.rb2
-rw-r--r--spec/controllers/projects/graphs_controller_spec.rb33
-rw-r--r--spec/controllers/projects/group_links_controller_spec.rb2
-rw-r--r--spec/controllers/projects/hooks_controller_spec.rb2
-rw-r--r--spec/controllers/projects/imports_controller_spec.rb2
-rw-r--r--spec/controllers/projects/issues_controller_spec.rb18
-rw-r--r--spec/controllers/projects/jobs_controller_spec.rb2
-rw-r--r--spec/controllers/projects/labels_controller_spec.rb4
-rw-r--r--spec/controllers/projects/mattermosts_controller_spec.rb2
-rw-r--r--spec/controllers/projects/merge_requests/conflicts_controller_spec.rb2
-rw-r--r--spec/controllers/projects/merge_requests/creations_controller_spec.rb4
-rw-r--r--spec/controllers/projects/merge_requests/diffs_controller_spec.rb6
-rw-r--r--spec/controllers/projects/merge_requests_controller_spec.rb14
-rw-r--r--spec/controllers/projects/milestones_controller_spec.rb2
-rw-r--r--spec/controllers/projects/notes_controller_spec.rb6
-rw-r--r--spec/controllers/projects/pages_controller_spec.rb2
-rw-r--r--spec/controllers/projects/pages_domains_controller_spec.rb2
-rw-r--r--spec/controllers/projects/pipeline_schedules_controller_spec.rb2
-rw-r--r--spec/controllers/projects/pipelines_controller_spec.rb4
-rw-r--r--spec/controllers/projects/project_members_controller_spec.rb6
-rw-r--r--spec/controllers/projects/prometheus_controller_spec.rb2
-rw-r--r--spec/controllers/projects/registry/repositories_controller_spec.rb2
-rw-r--r--spec/controllers/projects/registry/tags_controller_spec.rb2
-rw-r--r--spec/controllers/projects/repositories_controller_spec.rb2
-rw-r--r--spec/controllers/projects/runners_controller_spec.rb2
-rw-r--r--spec/controllers/projects/services_controller_spec.rb2
-rw-r--r--spec/controllers/projects/settings/ci_cd_controller_spec.rb2
-rw-r--r--spec/controllers/projects/settings/integrations_controller_spec.rb2
-rw-r--r--spec/controllers/projects/todos_controller_spec.rb6
-rw-r--r--spec/controllers/projects/tree_controller_spec.rb6
-rw-r--r--spec/controllers/projects/uploads_controller_spec.rb2
-rw-r--r--spec/controllers/projects/variables_controller_spec.rb2
-rw-r--r--spec/controllers/projects_controller_spec.rb146
-rw-r--r--spec/controllers/registrations_controller_spec.rb4
-rw-r--r--spec/controllers/search_controller_spec.rb8
-rw-r--r--spec/controllers/sent_notifications_controller_spec.rb2
-rw-r--r--spec/controllers/snippets/notes_controller_spec.rb6
-rw-r--r--spec/controllers/snippets_controller_spec.rb8
-rw-r--r--spec/controllers/uploads_controller_spec.rb8
-rw-r--r--spec/controllers/users_controller_spec.rb14
-rw-r--r--spec/factories/boards.rb2
-rw-r--r--spec/factories/ci/pipeline_schedule.rb2
-rw-r--r--spec/factories/ci/pipelines.rb2
-rw-r--r--spec/factories/ci/runner_projects.rb2
-rw-r--r--spec/factories/ci/variables.rb2
-rw-r--r--spec/factories/commits.rb2
-rw-r--r--spec/factories/conversational_development_index_metrics.rb10
-rw-r--r--spec/factories/deploy_keys_projects.rb2
-rw-r--r--spec/factories/deployments.rb4
-rw-r--r--spec/factories/environments.rb4
-rw-r--r--spec/factories/events.rb18
-rw-r--r--spec/factories/file_uploaders.rb2
-rw-r--r--spec/factories/forked_project_links.rb6
-rw-r--r--spec/factories/issues.rb2
-rw-r--r--spec/factories/label_priorities.rb2
-rw-r--r--spec/factories/labels.rb2
-rw-r--r--spec/factories/merge_requests.rb11
-rw-r--r--spec/factories/milestones.rb4
-rw-r--r--spec/factories/notes.rb2
-rw-r--r--spec/factories/notification_settings.rb3
-rw-r--r--spec/factories/project_group_links.rb2
-rw-r--r--spec/factories/project_hooks.rb2
-rw-r--r--spec/factories/project_members.rb2
-rw-r--r--spec/factories/project_wikis.rb2
-rw-r--r--spec/factories/projects.rb176
-rw-r--r--spec/factories/protected_branches.rb6
-rw-r--r--spec/factories/releases.rb2
-rw-r--r--spec/factories/sent_notifications.rb2
-rw-r--r--spec/factories/services.rb12
-rw-r--r--spec/factories/snippets.rb2
-rw-r--r--spec/factories/subscriptions.rb2
-rw-r--r--spec/factories/todos.rb4
-rw-r--r--spec/factories/users.rb6
-rw-r--r--spec/features/admin/admin_disables_git_access_protocol_spec.rb2
-rw-r--r--spec/features/admin/admin_groups_spec.rb2
-rw-r--r--spec/features/admin/admin_health_check_spec.rb24
-rw-r--r--spec/features/admin/admin_hook_logs_spec.rb2
-rw-r--r--spec/features/admin/admin_hooks_spec.rb2
-rw-r--r--spec/features/admin/admin_projects_spec.rb4
-rw-r--r--spec/features/admin/admin_runners_spec.rb4
-rw-r--r--spec/features/admin/admin_settings_spec.rb10
-rw-r--r--spec/features/admin/admin_users_impersonation_tokens_spec.rb4
-rw-r--r--spec/features/admin/admin_users_spec.rb2
-rw-r--r--spec/features/admin/admin_uses_repository_checks_spec.rb4
-rw-r--r--spec/features/atom/dashboard_issues_spec.rb4
-rw-r--r--spec/features/atom/dashboard_spec.rb2
-rw-r--r--spec/features/atom/issues_spec.rb2
-rw-r--r--spec/features/boards/add_issues_modal_spec.rb2
-rw-r--r--spec/features/boards/boards_spec.rb6
-rw-r--r--spec/features/boards/issue_ordering_spec.rb2
-rw-r--r--spec/features/boards/keyboard_shortcut_spec.rb2
-rw-r--r--spec/features/boards/modal_filter_spec.rb2
-rw-r--r--spec/features/boards/new_issue_spec.rb2
-rw-r--r--spec/features/boards/sidebar_spec.rb20
-rw-r--r--spec/features/boards/sub_group_project_spec.rb2
-rw-r--r--spec/features/calendar_spec.rb18
-rw-r--r--spec/features/commits_spec.rb4
-rw-r--r--spec/features/container_registry_spec.rb2
-rw-r--r--spec/features/cycle_analytics_spec.rb38
-rw-r--r--spec/features/dashboard/activity_spec.rb30
-rw-r--r--spec/features/dashboard/archived_projects_spec.rb2
-rw-r--r--spec/features/dashboard/datetime_on_tooltips_spec.rb2
-rw-r--r--spec/features/dashboard/issuables_counter_spec.rb2
-rw-r--r--spec/features/dashboard/issues_filter_spec.rb2
-rw-r--r--spec/features/dashboard/issues_spec.rb21
-rw-r--r--spec/features/dashboard/label_filter_spec.rb4
-rw-r--r--spec/features/dashboard/merge_requests_spec.rb6
-rw-r--r--spec/features/dashboard/milestone_filter_spec.rb2
-rw-r--r--spec/features/dashboard/milestone_tabs_spec.rb2
-rw-r--r--spec/features/dashboard/milestones_spec.rb2
-rw-r--r--spec/features/dashboard/project_member_activity_index_spec.rb2
-rw-r--r--spec/features/dashboard/projects_spec.rb2
-rw-r--r--spec/features/dashboard/snippets_spec.rb2
-rw-r--r--spec/features/dashboard/todos/target_state_spec.rb2
-rw-r--r--spec/features/dashboard/todos/todos_filtering_spec.rb4
-rw-r--r--spec/features/dashboard/todos/todos_sorting_spec.rb2
-rw-r--r--spec/features/dashboard/todos/todos_spec.rb4
-rw-r--r--spec/features/dashboard/user_filters_projects_spec.rb4
-rw-r--r--spec/features/discussion_comments/commit_spec.rb2
-rw-r--r--spec/features/discussion_comments/issue_spec.rb2
-rw-r--r--spec/features/discussion_comments/merge_request_spec.rb2
-rw-r--r--spec/features/discussion_comments/snippets_spec.rb2
-rw-r--r--spec/features/explore/groups_list_spec.rb2
-rw-r--r--spec/features/explore/new_menu_spec.rb2
-rw-r--r--spec/features/gitlab_flavored_markdown_spec.rb2
-rw-r--r--spec/features/global_search_spec.rb2
-rw-r--r--spec/features/groups/empty_states_spec.rb6
-rw-r--r--spec/features/groups/group_settings_spec.rb4
-rw-r--r--spec/features/groups/issues_spec.rb10
-rw-r--r--spec/features/groups/members/request_access_spec.rb2
-rw-r--r--spec/features/groups/milestone_spec.rb10
-rw-r--r--spec/features/issuables/close_reopen_report_toggle_spec.rb4
-rw-r--r--spec/features/issuables/default_sort_order_spec.rb2
-rw-r--r--spec/features/issuables/issuable_list_spec.rb2
-rw-r--r--spec/features/issuables/markdown_references_spec.rb4
-rw-r--r--spec/features/issues/award_emoji_spec.rb2
-rw-r--r--spec/features/issues/award_spec.rb2
-rw-r--r--spec/features/issues/bulk_assignment_labels_spec.rb6
-rw-r--r--spec/features/issues/create_branch_merge_request_spec.rb14
-rw-r--r--spec/features/issues/filtered_search/dropdown_assignee_spec.rb2
-rw-r--r--spec/features/issues/filtered_search/dropdown_author_spec.rb2
-rw-r--r--spec/features/issues/filtered_search/dropdown_hint_spec.rb2
-rw-r--r--spec/features/issues/filtered_search/dropdown_label_spec.rb2
-rw-r--r--spec/features/issues/filtered_search/dropdown_milestone_spec.rb2
-rw-r--r--spec/features/issues/filtered_search/filter_issues_spec.rb2
-rw-r--r--spec/features/issues/filtered_search/recent_searches_spec.rb4
-rw-r--r--spec/features/issues/filtered_search/search_bar_spec.rb2
-rw-r--r--spec/features/issues/filtered_search/visual_tokens_spec.rb2
-rw-r--r--spec/features/issues/form_spec.rb4
-rw-r--r--spec/features/issues/gfm_autocomplete_spec.rb2
-rw-r--r--spec/features/issues/group_label_sidebar_spec.rb2
-rw-r--r--spec/features/issues/issue_detail_spec.rb2
-rw-r--r--spec/features/issues/issue_sidebar_spec.rb10
-rw-r--r--spec/features/issues/markdown_toolbar_spec.rb2
-rw-r--r--spec/features/issues/move_spec.rb8
-rw-r--r--spec/features/issues/note_polling_spec.rb4
-rw-r--r--spec/features/issues/notes_on_issues_spec.rb6
-rw-r--r--spec/features/issues/spam_issues_spec.rb2
-rw-r--r--spec/features/issues/todo_spec.rb2
-rw-r--r--spec/features/issues/update_issues_spec.rb14
-rw-r--r--spec/features/issues/user_uses_slash_commands_spec.rb2
-rw-r--r--spec/features/issues_spec.rb29
-rw-r--r--spec/features/merge_requests/closes_issues_spec.rb22
-rw-r--r--spec/features/merge_requests/create_new_mr_spec.rb8
-rw-r--r--spec/features/merge_requests/diff_notes_avatars_spec.rb2
-rw-r--r--spec/features/merge_requests/diffs_spec.rb2
-rw-r--r--spec/features/merge_requests/discussion_spec.rb4
-rw-r--r--spec/features/merge_requests/filter_by_labels_spec.rb10
-rw-r--r--spec/features/merge_requests/filter_merge_requests_spec.rb12
-rw-r--r--spec/features/merge_requests/form_spec.rb2
-rw-r--r--spec/features/merge_requests/merge_when_pipeline_succeeds_spec.rb10
-rw-r--r--spec/features/merge_requests/only_allow_merge_if_build_succeeds_spec.rb8
-rw-r--r--spec/features/merge_requests/pipelines_spec.rb97
-rw-r--r--spec/features/merge_requests/reset_filters_spec.rb6
-rw-r--r--spec/features/merge_requests/update_merge_requests_spec.rb6
-rw-r--r--spec/features/merge_requests/user_lists_merge_requests_spec.rb16
-rw-r--r--spec/features/merge_requests/user_posts_diff_notes_spec.rb4
-rw-r--r--spec/features/merge_requests/user_posts_notes_spec.rb3
-rw-r--r--spec/features/merge_requests/user_uses_slash_commands_spec.rb10
-rw-r--r--spec/features/merge_requests/widget_spec.rb13
-rw-r--r--spec/features/milestone_spec.rb2
-rw-r--r--spec/features/milestones/show_spec.rb2
-rw-r--r--spec/features/participants_autocomplete_spec.rb2
-rw-r--r--spec/features/password_reset_spec.rb4
-rw-r--r--spec/features/profiles/account_spec.rb4
-rw-r--r--spec/features/profiles/preferences_spec.rb28
-rw-r--r--spec/features/profiles/user_visits_notifications_tab_spec.rb2
-rw-r--r--spec/features/projects/activity/rss_spec.rb2
-rw-r--r--spec/features/projects/artifacts/browse_spec.rb2
-rw-r--r--spec/features/projects/artifacts/download_spec.rb2
-rw-r--r--spec/features/projects/artifacts/file_spec.rb2
-rw-r--r--spec/features/projects/artifacts/raw_spec.rb2
-rw-r--r--spec/features/projects/badges/coverage_spec.rb2
-rw-r--r--spec/features/projects/blobs/edit_spec.rb2
-rw-r--r--spec/features/projects/developer_views_empty_project_instructions_spec.rb2
-rw-r--r--spec/features/projects/edit_spec.rb6
-rw-r--r--spec/features/projects/environments/environment_spec.rb2
-rw-r--r--spec/features/projects/environments/environments_spec.rb2
-rw-r--r--spec/features/projects/features_visibility_spec.rb34
-rw-r--r--spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb2
-rw-r--r--spec/features/projects/gfm_autocomplete_load_spec.rb2
-rw-r--r--spec/features/projects/group_links_spec.rb4
-rw-r--r--spec/features/projects/guest_navigation_menu_spec.rb2
-rw-r--r--spec/features/projects/import_export/import_file_spec.rb18
-rw-r--r--spec/features/projects/import_export/namespace_export_file_spec.rb2
-rw-r--r--spec/features/projects/issuable_counts_caching_spec.rb2
-rw-r--r--spec/features/projects/issues/list_spec.rb2
-rw-r--r--spec/features/projects/issues/rss_spec.rb2
-rw-r--r--spec/features/projects/labels/issues_sorted_by_priority_spec.rb2
-rw-r--r--spec/features/projects/labels/subscription_spec.rb2
-rw-r--r--spec/features/projects/labels/update_prioritization_spec.rb2
-rw-r--r--spec/features/projects/members/anonymous_user_sees_members_spec.rb2
-rw-r--r--spec/features/projects/members/group_links_spec.rb2
-rw-r--r--spec/features/projects/members/group_member_cannot_leave_group_project_spec.rb2
-rw-r--r--spec/features/projects/members/group_member_cannot_request_access_to_his_group_project_spec.rb2
-rw-r--r--spec/features/projects/members/group_members_spec.rb2
-rw-r--r--spec/features/projects/members/group_requester_cannot_request_access_to_project_spec.rb2
-rw-r--r--spec/features/projects/members/list_spec.rb2
-rw-r--r--spec/features/projects/members/master_adds_member_with_expiration_date_spec.rb2
-rw-r--r--spec/features/projects/members/master_manages_access_requests_spec.rb2
-rw-r--r--spec/features/projects/members/member_cannot_request_access_to_his_project_spec.rb2
-rw-r--r--spec/features/projects/members/owner_cannot_leave_project_spec.rb2
-rw-r--r--spec/features/projects/members/owner_cannot_request_access_to_his_project_spec.rb2
-rw-r--r--spec/features/projects/members/sorting_spec.rb2
-rw-r--r--spec/features/projects/milestones/milestone_spec.rb2
-rw-r--r--spec/features/projects/milestones/milestones_sorting_spec.rb2
-rw-r--r--spec/features/projects/milestones/new_spec.rb2
-rw-r--r--spec/features/projects/pages_spec.rb2
-rw-r--r--spec/features/projects/pipeline_schedules_spec.rb19
-rw-r--r--spec/features/projects/pipelines/pipeline_spec.rb2
-rw-r--r--spec/features/projects/pipelines/pipelines_spec.rb2
-rw-r--r--spec/features/projects/project_settings_spec.rb20
-rw-r--r--spec/features/projects/services/jira_service_spec.rb2
-rw-r--r--spec/features/projects/services/mattermost_slash_command_spec.rb2
-rw-r--r--spec/features/projects/services/slack_service_spec.rb2
-rw-r--r--spec/features/projects/services/slack_slash_command_spec.rb2
-rw-r--r--spec/features/projects/settings/integration_settings_spec.rb2
-rw-r--r--spec/features/projects/settings/merge_requests_settings_spec.rb15
-rw-r--r--spec/features/projects/settings/pipelines_settings_spec.rb2
-rw-r--r--spec/features/projects/settings/visibility_settings_spec.rb2
-rw-r--r--spec/features/projects/shortcuts_spec.rb2
-rw-r--r--spec/features/projects/snippets/create_snippet_spec.rb2
-rw-r--r--spec/features/projects/snippets_spec.rb2
-rw-r--r--spec/features/projects/sub_group_issuables_spec.rb2
-rw-r--r--spec/features/projects/tags/download_buttons_spec.rb2
-rw-r--r--spec/features/projects/user_edits_files_spec.rb26
-rw-r--r--spec/features/projects/wiki/markdown_preview_spec.rb50
-rw-r--r--spec/features/projects/wiki/shortcuts_spec.rb2
-rw-r--r--spec/features/projects/wiki/user_creates_wiki_page_spec.rb4
-rw-r--r--spec/features/projects/wiki/user_git_access_wiki_page_spec.rb4
-rw-r--r--spec/features/projects/wiki/user_updates_wiki_page_spec.rb6
-rw-r--r--spec/features/projects/wiki/user_views_project_wiki_page_spec.rb2
-rw-r--r--spec/features/projects/wiki/user_views_wiki_in_project_page_spec.rb2
-rw-r--r--spec/features/projects_spec.rb46
-rw-r--r--spec/features/protected_tags_spec.rb2
-rw-r--r--spec/features/reportable_note/commit_spec.rb2
-rw-r--r--spec/features/reportable_note/issue_spec.rb2
-rw-r--r--spec/features/reportable_note/merge_request_spec.rb2
-rw-r--r--spec/features/reportable_note/snippets_spec.rb2
-rw-r--r--spec/features/runners_spec.rb14
-rw-r--r--spec/features/search_spec.rb4
-rw-r--r--spec/features/security/group/internal_access_spec.rb2
-rw-r--r--spec/features/security/group/private_access_spec.rb2
-rw-r--r--spec/features/security/group/public_access_spec.rb2
-rw-r--r--spec/features/security/project/snippet/internal_access_spec.rb2
-rw-r--r--spec/features/security/project/snippet/private_access_spec.rb2
-rw-r--r--spec/features/security/project/snippet/public_access_spec.rb2
-rw-r--r--spec/features/snippets/notes_on_personal_snippets_spec.rb6
-rw-r--r--spec/features/snippets/user_creates_snippet_spec.rb6
-rw-r--r--spec/features/snippets/user_edits_snippet_spec.rb2
-rw-r--r--spec/features/snippets_spec.rb2
-rw-r--r--spec/features/tags/master_creates_tag_spec.rb2
-rw-r--r--spec/features/tags/master_deletes_tag_spec.rb2
-rw-r--r--spec/features/tags/master_updates_tag_spec.rb2
-rw-r--r--spec/features/tags/master_views_tags_spec.rb2
-rw-r--r--spec/features/task_lists_spec.rb6
-rw-r--r--spec/features/triggers_spec.rb6
-rw-r--r--spec/features/unsubscribe_links_spec.rb2
-rw-r--r--spec/features/uploads/user_uploads_file_to_note_spec.rb2
-rw-r--r--spec/features/user_callout_spec.rb2
-rw-r--r--spec/features/users/projects_spec.rb4
-rw-r--r--spec/features/users_spec.rb4
-rw-r--r--spec/features/variables_spec.rb2
-rw-r--r--spec/finders/access_requests_finder_spec.rb2
-rw-r--r--spec/finders/admin/projects_finder_spec.rb20
-rw-r--r--spec/finders/contributed_projects_finder_spec.rb8
-rw-r--r--spec/finders/environments_finder_spec.rb2
-rw-r--r--spec/finders/events_finder_spec.rb4
-rw-r--r--spec/finders/group_projects_finder_spec.rb10
-rw-r--r--spec/finders/groups_finder_spec.rb4
-rw-r--r--spec/finders/issues_finder_spec.rb22
-rw-r--r--spec/finders/joined_groups_finder_spec.rb2
-rw-r--r--spec/finders/labels_finder_spec.rb12
-rw-r--r--spec/finders/merge_requests_finder_spec.rb8
-rw-r--r--spec/finders/milestones_finder_spec.rb4
-rw-r--r--spec/finders/move_to_project_finder_spec.rb20
-rw-r--r--spec/finders/notes_finder_spec.rb6
-rw-r--r--spec/finders/personal_projects_finder_spec.rb6
-rw-r--r--spec/finders/pipeline_schedules_finder_spec.rb2
-rw-r--r--spec/finders/projects_finder_spec.rb14
-rw-r--r--spec/finders/snippets_finder_spec.rb4
-rw-r--r--spec/finders/todos_finder_spec.rb2
-rw-r--r--spec/fixtures/api/schemas/entities/merge_request.json4
-rw-r--r--spec/fixtures/api/schemas/public_api/v4/comment.json21
-rw-r--r--spec/fixtures/api/schemas/public_api/v4/commit/detail.json16
-rw-r--r--spec/fixtures/api/schemas/public_api/v4/commit_note.json19
-rw-r--r--spec/fixtures/api/schemas/public_api/v4/commit_notes.json4
-rw-r--r--spec/fixtures/api/schemas/public_api/v4/commit_stats.json14
-rw-r--r--spec/fixtures/api/schemas/public_api/v4/commits.json4
-rw-r--r--spec/fixtures/api/schemas/public_api/v4/release.json12
-rw-r--r--spec/fixtures/api/schemas/public_api/v4/tag.json21
-rw-r--r--spec/fixtures/api/schemas/public_api/v4/tags.json4
-rw-r--r--spec/fixtures/api/schemas/public_api/v4/user/basic.json15
-rw-r--r--spec/fixtures/encoding/Japanese.md42
-rw-r--r--spec/fixtures/markdown.md.erb5
-rw-r--r--spec/helpers/application_helper_spec.rb4
-rw-r--r--spec/helpers/blob_helper_spec.rb2
-rw-r--r--spec/helpers/button_helper_spec.rb2
-rw-r--r--spec/helpers/ci_status_helper_spec.rb2
-rw-r--r--spec/helpers/commits_helper_spec.rb2
-rw-r--r--spec/helpers/defer_script_tag_helper_spec.rb13
-rw-r--r--spec/helpers/diff_helper_spec.rb2
-rw-r--r--spec/helpers/events_helper_spec.rb4
-rw-r--r--spec/helpers/gitlab_routing_helper_spec.rb13
-rw-r--r--spec/helpers/groups_helper_spec.rb4
-rw-r--r--spec/helpers/hooks_helper_spec.rb2
-rw-r--r--spec/helpers/issues_helper_spec.rb2
-rw-r--r--spec/helpers/labels_helper_spec.rb8
-rw-r--r--spec/helpers/markup_helper_spec.rb4
-rw-r--r--spec/helpers/members_helper_spec.rb6
-rw-r--r--spec/helpers/merge_requests_helper_spec.rb10
-rw-r--r--spec/helpers/milestones_helper_spec.rb6
-rw-r--r--spec/helpers/milestones_routing_helper_spec.rb46
-rw-r--r--spec/helpers/notes_helper_spec.rb20
-rw-r--r--spec/helpers/pagination_helper_spec.rb23
-rw-r--r--spec/helpers/projects_helper_spec.rb70
-rw-r--r--spec/helpers/search_helper_spec.rb36
-rw-r--r--spec/helpers/storage_health_helper_spec.rb20
-rw-r--r--spec/helpers/submodule_helper_spec.rb6
-rw-r--r--spec/helpers/todos_helper_spec.rb2
-rw-r--r--spec/helpers/visibility_level_helper_spec.rb8
-rw-r--r--spec/initializers/6_validations_spec.rb21
-rw-r--r--spec/initializers/settings_spec.rb11
-rw-r--r--spec/javascripts/abuse_reports_spec.js6
-rw-r--r--spec/javascripts/ajax_loading_spinner_spec.js1
-rw-r--r--spec/javascripts/blob/blob_file_dropzone_spec.js42
-rw-r--r--spec/javascripts/blob/viewer/index_spec.js4
-rw-r--r--spec/javascripts/boards/issue_card_spec.js28
-rw-r--r--spec/javascripts/breakpoints_spec.js15
-rw-r--r--spec/javascripts/build_spec.js1
-rw-r--r--spec/javascripts/droplab/plugins/ajax_spec.js36
-rw-r--r--spec/javascripts/extensions/array_spec.js22
-rw-r--r--spec/javascripts/filtered_search/dropdown_utils_spec.js97
-rw-r--r--spec/javascripts/filtered_search/filtered_search_dropdown_manager_spec.js1
-rw-r--r--spec/javascripts/filtered_search/filtered_search_token_keys_spec.js1
-rw-r--r--spec/javascripts/filtered_search/filtered_search_tokenizer_spec.js1
-rw-r--r--spec/javascripts/filtered_search/filtered_search_visual_tokens_spec.js63
-rw-r--r--spec/javascripts/fixtures/abuse_reports.rb2
-rw-r--r--spec/javascripts/fixtures/balsamiq.rb2
-rw-r--r--spec/javascripts/fixtures/blob.rb2
-rw-r--r--spec/javascripts/fixtures/boards.rb2
-rw-r--r--spec/javascripts/fixtures/branches.rb2
-rw-r--r--spec/javascripts/fixtures/dashboard.rb2
-rw-r--r--spec/javascripts/fixtures/deploy_keys.rb4
-rw-r--r--spec/javascripts/fixtures/environments.rb2
-rw-r--r--spec/javascripts/fixtures/issues.rb2
-rw-r--r--spec/javascripts/fixtures/jobs.rb2
-rw-r--r--spec/javascripts/fixtures/labels.rb4
-rw-r--r--spec/javascripts/fixtures/merge_requests.rb4
-rw-r--r--spec/javascripts/fixtures/merge_requests_diffs.rb4
-rw-r--r--spec/javascripts/fixtures/pdf.rb2
-rw-r--r--spec/javascripts/fixtures/pipelines.rb2
-rw-r--r--spec/javascripts/fixtures/project_select_combo_button.html.haml6
-rw-r--r--spec/javascripts/fixtures/projects.rb2
-rw-r--r--spec/javascripts/fixtures/prometheus_service.rb2
-rw-r--r--spec/javascripts/fixtures/raw.rb2
-rw-r--r--spec/javascripts/fixtures/services.rb2
-rw-r--r--spec/javascripts/fixtures/snippet.rb27
-rw-r--r--spec/javascripts/fixtures/todos.rb4
-rw-r--r--spec/javascripts/fly_out_nav_spec.js329
-rw-r--r--spec/javascripts/gpg_badges_spec.js48
-rw-r--r--spec/javascripts/groups/group_identicon_spec.js60
-rw-r--r--spec/javascripts/groups/groups_spec.js13
-rw-r--r--spec/javascripts/groups/mock_data.js4
-rw-r--r--spec/javascripts/labels_issue_sidebar_spec.js1
-rw-r--r--spec/javascripts/lib/utils/ajax_cache_spec.js9
-rw-r--r--spec/javascripts/lib/utils/sticky_spec.js52
-rw-r--r--spec/javascripts/pdf/index_spec.js4
-rw-r--r--spec/javascripts/pdf/page_spec.js4
-rw-r--r--spec/javascripts/pipeline_schedules/pipeline_schedule_callout_spec.js2
-rw-r--r--spec/javascripts/project_select_combo_button_spec.js105
-rw-r--r--spec/javascripts/projects/project_import_gitlab_project_spec.js25
-rw-r--r--spec/javascripts/projects/project_new_spec.js127
-rw-r--r--spec/javascripts/repo/components/repo_commit_section_spec.js160
-rw-r--r--spec/javascripts/repo/components/repo_edit_button_spec.js51
-rw-r--r--spec/javascripts/repo/components/repo_editor_spec.js49
-rw-r--r--spec/javascripts/repo/components/repo_file_buttons_spec.js75
-rw-r--r--spec/javascripts/repo/components/repo_file_options_spec.js33
-rw-r--r--spec/javascripts/repo/components/repo_file_spec.js136
-rw-r--r--spec/javascripts/repo/components/repo_loading_file_spec.js79
-rw-r--r--spec/javascripts/repo/components/repo_prev_directory_spec.js43
-rw-r--r--spec/javascripts/repo/components/repo_preview_spec.js23
-rw-r--r--spec/javascripts/repo/components/repo_sidebar_spec.js111
-rw-r--r--spec/javascripts/repo/components/repo_tab_spec.js70
-rw-r--r--spec/javascripts/repo/components/repo_tabs_spec.js45
-rw-r--r--spec/javascripts/repo/monaco_loader_spec.js17
-rw-r--r--spec/javascripts/repo/services/repo_service_spec.js121
-rw-r--r--spec/javascripts/sidebar/confidential_edit_buttons_spec.js39
-rw-r--r--spec/javascripts/sidebar/confidential_edit_form_buttons_spec.js39
-rw-r--r--spec/javascripts/sidebar/confidential_issue_sidebar_spec.js65
-rw-r--r--spec/javascripts/vue_mr_widget/components/mr_widget_deployment_spec.js10
-rw-r--r--spec/javascripts/vue_mr_widget/components/mr_widget_memory_usage_spec.js6
-rw-r--r--spec/javascripts/vue_mr_widget/components/mr_widget_pipeline_spec.js4
-rw-r--r--spec/javascripts/vue_mr_widget/components/mr_widget_related_links_spec.js73
-rw-r--r--spec/javascripts/vue_mr_widget/components/states/mr_widget_archived_spec.js2
-rw-r--r--spec/javascripts/vue_mr_widget/components/states/mr_widget_auto_merge_failed_spec.js4
-rw-r--r--spec/javascripts/vue_mr_widget/components/states/mr_widget_checking_spec.js2
-rw-r--r--spec/javascripts/vue_mr_widget/components/states/mr_widget_conflicts_spec.js13
-rw-r--r--spec/javascripts/vue_mr_widget/components/states/mr_widget_failed_to_merge_spec.js4
-rw-r--r--spec/javascripts/vue_mr_widget/components/states/mr_widget_locked_spec.js10
-rw-r--r--spec/javascripts/vue_mr_widget/components/states/mr_widget_merge_when_pipeline_succeeds_spec.js8
-rw-r--r--spec/javascripts/vue_mr_widget/components/states/mr_widget_merged_spec.js16
-rw-r--r--spec/javascripts/vue_mr_widget/components/states/mr_widget_missing_branch_spec.js2
-rw-r--r--spec/javascripts/vue_mr_widget/components/states/mr_widget_not_allowed_spec.js2
-rw-r--r--spec/javascripts/vue_mr_widget/components/states/mr_widget_pipeline_blocked_spec.js2
-rw-r--r--spec/javascripts/vue_mr_widget/components/states/mr_widget_pipeline_failed_spec.js2
-rw-r--r--spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js2
-rw-r--r--spec/javascripts/vue_mr_widget/components/states/mr_widget_sha_mismatch_spec.js2
-rw-r--r--spec/javascripts/vue_mr_widget/components/states/mr_widget_wip_spec.js2
-rw-r--r--spec/javascripts/vue_mr_widget/mock_data.js2
-rw-r--r--spec/javascripts/vue_mr_widget/mr_widget_options_spec.js2
-rw-r--r--spec/lib/api/helpers/pagination_spec.rb2
-rw-r--r--spec/lib/banzai/filter/abstract_reference_filter_spec.rb16
-rw-r--r--spec/lib/banzai/filter/commit_range_reference_filter_spec.rb10
-rw-r--r--spec/lib/banzai/filter/commit_reference_filter_spec.rb14
-rw-r--r--spec/lib/banzai/filter/gollum_tags_filter_spec.rb2
-rw-r--r--spec/lib/banzai/filter/issuable_state_filter_spec.rb4
-rw-r--r--spec/lib/banzai/filter/issue_reference_filter_spec.rb30
-rw-r--r--spec/lib/banzai/filter/label_reference_filter_spec.rb36
-rw-r--r--spec/lib/banzai/filter/merge_request_reference_filter_spec.rb18
-rw-r--r--spec/lib/banzai/filter/milestone_reference_filter_spec.rb210
-rw-r--r--spec/lib/banzai/filter/redactor_filter_spec.rb20
-rw-r--r--spec/lib/banzai/filter/reference_filter_spec.rb2
-rw-r--r--spec/lib/banzai/filter/relative_link_filter_spec.rb4
-rw-r--r--spec/lib/banzai/filter/snippet_reference_filter_spec.rb18
-rw-r--r--spec/lib/banzai/filter/upload_link_filter_spec.rb12
-rw-r--r--spec/lib/banzai/filter/user_reference_filter_spec.rb2
-rw-r--r--spec/lib/banzai/filter/wiki_link_filter_spec.rb2
-rw-r--r--spec/lib/banzai/issuable_extractor_spec.rb2
-rw-r--r--spec/lib/banzai/object_renderer_spec.rb4
-rw-r--r--spec/lib/banzai/pipeline/full_pipeline_spec.rb2
-rw-r--r--spec/lib/banzai/pipeline/gfm_pipeline_spec.rb4
-rw-r--r--spec/lib/banzai/pipeline/wiki_pipeline_spec.rb2
-rw-r--r--spec/lib/banzai/redactor_spec.rb2
-rw-r--r--spec/lib/banzai/reference_parser/base_parser_spec.rb2
-rw-r--r--spec/lib/banzai/reference_parser/commit_parser_spec.rb2
-rw-r--r--spec/lib/banzai/reference_parser/commit_range_parser_spec.rb2
-rw-r--r--spec/lib/banzai/reference_parser/external_issue_parser_spec.rb2
-rw-r--r--spec/lib/banzai/reference_parser/issue_parser_spec.rb2
-rw-r--r--spec/lib/banzai/reference_parser/label_parser_spec.rb2
-rw-r--r--spec/lib/banzai/reference_parser/milestone_parser_spec.rb2
-rw-r--r--spec/lib/banzai/reference_parser/snippet_parser_spec.rb2
-rw-r--r--spec/lib/banzai/reference_parser/user_parser_spec.rb12
-rw-r--r--spec/lib/bitbucket/paginator_spec.rb2
-rw-r--r--spec/lib/ci/charts_spec.rb2
-rw-r--r--spec/lib/ci/gitlab_ci_yaml_processor_spec.rb4
-rw-r--r--spec/lib/constraints/project_url_constrainer_spec.rb2
-rw-r--r--spec/lib/container_registry/blob_spec.rb2
-rw-r--r--spec/lib/container_registry/path_spec.rb12
-rw-r--r--spec/lib/container_registry/tag_spec.rb2
-rw-r--r--spec/lib/event_filter_spec.rb4
-rw-r--r--spec/lib/extracts_path_spec.rb6
-rw-r--r--spec/lib/gitlab/allowable_spec.rb4
-rw-r--r--spec/lib/gitlab/auth_spec.rb5
-rw-r--r--spec/lib/gitlab/background_migration/deserialize_merge_request_diffs_and_commits_spec.rb199
-rw-r--r--spec/lib/gitlab/background_migration/migrate_events_to_push_event_payloads_spec.rb423
-rw-r--r--spec/lib/gitlab/background_migration/migrate_system_uploads_to_new_folder_spec.rb2
-rw-r--r--spec/lib/gitlab/background_migration/move_personal_snippet_files_spec.rb72
-rw-r--r--spec/lib/gitlab/backup/repository_spec.rb56
-rw-r--r--spec/lib/gitlab/badge/coverage/metadata_spec.rb2
-rw-r--r--spec/lib/gitlab/badge/coverage/report_spec.rb2
-rw-r--r--spec/lib/gitlab/badge/pipeline/metadata_spec.rb2
-rw-r--r--spec/lib/gitlab/bitbucket_import/importer_spec.rb4
-rw-r--r--spec/lib/gitlab/bitbucket_import/project_creator_spec.rb2
-rw-r--r--spec/lib/gitlab/cache/ci/project_pipeline_status_spec.rb22
-rw-r--r--spec/lib/gitlab/checks/force_push_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/status/pipeline/common_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/status/stage/common_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/status/stage/factory_spec.rb2
-rw-r--r--spec/lib/gitlab/closing_issue_extractor_spec.rb4
-rw-r--r--spec/lib/gitlab/contributions_calendar_spec.rb44
-rw-r--r--spec/lib/gitlab/cycle_analytics/base_event_fetcher_spec.rb2
-rw-r--r--spec/lib/gitlab/cycle_analytics/events_spec.rb2
-rw-r--r--spec/lib/gitlab/cycle_analytics/permissions_spec.rb2
-rw-r--r--spec/lib/gitlab/cycle_analytics/shared_event_spec.rb2
-rw-r--r--spec/lib/gitlab/cycle_analytics/stage_summary_spec.rb2
-rw-r--r--spec/lib/gitlab/daemon_spec.rb103
-rw-r--r--spec/lib/gitlab/data_builder/note_spec.rb2
-rw-r--r--spec/lib/gitlab/database/migration_helpers_spec.rb2
-rw-r--r--spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_base_spec.rb12
-rw-r--r--spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_namespaces_spec.rb14
-rw-r--r--spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_projects_spec.rb12
-rw-r--r--spec/lib/gitlab/database_spec.rb22
-rw-r--r--spec/lib/gitlab/diff/file_spec.rb8
-rw-r--r--spec/lib/gitlab/diff/parser_spec.rb2
-rw-r--r--spec/lib/gitlab/email/handler/create_note_handler_spec.rb9
-rw-r--r--spec/lib/gitlab/email/handler/unsubscribe_handler_spec.rb2
-rw-r--r--spec/lib/gitlab/email/message/repository_push_spec.rb2
-rw-r--r--spec/lib/gitlab/email/receiver_spec.rb16
-rw-r--r--spec/lib/gitlab/encoding_helper_spec.rb47
-rw-r--r--spec/lib/gitlab/gfm/reference_rewriter_spec.rb4
-rw-r--r--spec/lib/gitlab/gfm/uploads_rewriter_spec.rb8
-rw-r--r--spec/lib/gitlab/git/blame_spec.rb102
-rw-r--r--spec/lib/gitlab/git/blob_spec.rb81
-rw-r--r--spec/lib/gitlab/git/commit_spec.rb63
-rw-r--r--spec/lib/gitlab/git/diff_collection_spec.rb6
-rw-r--r--spec/lib/gitlab/git/repository_spec.rb161
-rw-r--r--spec/lib/gitlab/git/storage/circuit_breaker_spec.rb290
-rw-r--r--spec/lib/gitlab/git/storage/forked_storage_check_spec.rb58
-rw-r--r--spec/lib/gitlab/git/storage/health_spec.rb87
-rw-r--r--spec/lib/gitlab/gitaly_client/commit_service_spec.rb30
-rw-r--r--spec/lib/gitlab/gitaly_client/notification_service_spec.rb4
-rw-r--r--spec/lib/gitlab/gitaly_client/ref_service_spec.rb4
-rw-r--r--spec/lib/gitlab/gitaly_client/repository_service_spec.rb19
-rw-r--r--spec/lib/gitlab/github_import/comment_formatter_spec.rb2
-rw-r--r--spec/lib/gitlab/github_import/importer_spec.rb2
-rw-r--r--spec/lib/gitlab/github_import/issue_formatter_spec.rb2
-rw-r--r--spec/lib/gitlab/github_import/label_formatter_spec.rb2
-rw-r--r--spec/lib/gitlab/github_import/milestone_formatter_spec.rb2
-rw-r--r--spec/lib/gitlab/github_import/release_formatter_spec.rb2
-rw-r--r--spec/lib/gitlab/github_import/wiki_formatter_spec.rb4
-rw-r--r--spec/lib/gitlab/gitlab_import/importer_spec.rb2
-rw-r--r--spec/lib/gitlab/gitlab_import/project_creator_spec.rb2
-rw-r--r--spec/lib/gitlab/gl_repository_spec.rb2
-rw-r--r--spec/lib/gitlab/google_code_import/importer_spec.rb2
-rw-r--r--spec/lib/gitlab/google_code_import/project_creator_spec.rb2
-rw-r--r--spec/lib/gitlab/gpg_spec.rb52
-rw-r--r--spec/lib/gitlab/graphs/commits_spec.rb2
-rw-r--r--spec/lib/gitlab/health_checks/fs_shards_check_spec.rb21
-rw-r--r--spec/lib/gitlab/identifier_spec.rb2
-rw-r--r--spec/lib/gitlab/import_export/all_models.yml3
-rw-r--r--spec/lib/gitlab/import_export/attribute_cleaner_spec.rb2
-rw-r--r--spec/lib/gitlab/import_export/avatar_restorer_spec.rb2
-rw-r--r--spec/lib/gitlab/import_export/avatar_saver_spec.rb4
-rw-r--r--spec/lib/gitlab/import_export/file_importer_spec.rb5
-rw-r--r--spec/lib/gitlab/import_export/fork_spec.rb8
-rw-r--r--spec/lib/gitlab/import_export/import_export_spec.rb2
-rw-r--r--spec/lib/gitlab/import_export/members_mapper_spec.rb6
-rw-r--r--spec/lib/gitlab/import_export/merge_request_parser_spec.rb4
-rw-r--r--spec/lib/gitlab/import_export/project.json9
-rw-r--r--spec/lib/gitlab/import_export/project_tree_restorer_spec.rb6
-rw-r--r--spec/lib/gitlab/import_export/project_tree_saver_spec.rb2
-rw-r--r--spec/lib/gitlab/import_export/relation_factory_spec.rb2
-rw-r--r--spec/lib/gitlab/import_export/repo_restorer_spec.rb6
-rw-r--r--spec/lib/gitlab/import_export/repo_saver_spec.rb4
-rw-r--r--spec/lib/gitlab/import_export/safe_model_attributes.yml9
-rw-r--r--spec/lib/gitlab/import_export/wiki_repo_saver_spec.rb4
-rw-r--r--spec/lib/gitlab/import_sources_spec.rb2
-rw-r--r--spec/lib/gitlab/issuable_sorter_spec.rb42
-rw-r--r--spec/lib/gitlab/key_fingerprint_spec.rb84
-rw-r--r--spec/lib/gitlab/ldap/config_spec.rb4
-rw-r--r--spec/lib/gitlab/ldap/user_spec.rb10
-rw-r--r--spec/lib/gitlab/metrics/influx_sampler_spec.rb2
-rw-r--r--spec/lib/gitlab/metrics/requests_rack_middleware_spec.rb18
-rw-r--r--spec/lib/gitlab/metrics/sidekiq_metrics_exporter_spec.rb101
-rw-r--r--spec/lib/gitlab/o_auth/user_spec.rb34
-rw-r--r--spec/lib/gitlab/project_authorizations_spec.rb8
-rw-r--r--spec/lib/gitlab/project_search_results_spec.rb10
-rw-r--r--spec/lib/gitlab/project_template_spec.rb65
-rw-r--r--spec/lib/gitlab/prometheus/queries/additional_metrics_deployment_query_spec.rb11
-rw-r--r--spec/lib/gitlab/prometheus/queries/additional_metrics_environment_query_spec.rb10
-rw-r--r--spec/lib/gitlab/quick_actions/dsl_spec.rb16
-rw-r--r--spec/lib/gitlab/quick_actions/extractor_spec.rb37
-rw-r--r--spec/lib/gitlab/quick_actions/substitution_definition_spec.rb42
-rw-r--r--spec/lib/gitlab/reference_extractor_spec.rb4
-rw-r--r--spec/lib/gitlab/repo_path_spec.rb4
-rw-r--r--spec/lib/gitlab/request_context_spec.rb2
-rw-r--r--spec/lib/gitlab/saml/user_spec.rb4
-rw-r--r--spec/lib/gitlab/search_results_spec.rb14
-rw-r--r--spec/lib/gitlab/shell_spec.rb90
-rw-r--r--spec/lib/gitlab/slash_commands/command_spec.rb6
-rw-r--r--spec/lib/gitlab/slash_commands/deploy_spec.rb58
-rw-r--r--spec/lib/gitlab/slash_commands/issue_new_spec.rb2
-rw-r--r--spec/lib/gitlab/slash_commands/issue_search_spec.rb2
-rw-r--r--spec/lib/gitlab/slash_commands/issue_show_spec.rb2
-rw-r--r--spec/lib/gitlab/slash_commands/presenters/deploy_spec.rb20
-rw-r--r--spec/lib/gitlab/slash_commands/presenters/issue_new_spec.rb2
-rw-r--r--spec/lib/gitlab/slash_commands/presenters/issue_search_spec.rb2
-rw-r--r--spec/lib/gitlab/slash_commands/presenters/issue_show_spec.rb2
-rw-r--r--spec/lib/gitlab/sql/union_spec.rb2
-rw-r--r--spec/lib/gitlab/template/issue_template_spec.rb48
-rw-r--r--spec/lib/gitlab/template/merge_request_template_spec.rb48
-rw-r--r--spec/lib/gitlab/uploads_transfer_spec.rb2
-rw-r--r--spec/lib/gitlab/url_blocker_spec.rb34
-rw-r--r--spec/lib/gitlab/url_builder_spec.rb20
-rw-r--r--spec/lib/gitlab/user_access_spec.rb2
-rw-r--r--spec/lib/gitlab/version_info_spec.rb4
-rw-r--r--spec/lib/gitlab/view/presenter/base_spec.rb8
-rw-r--r--spec/lib/gitlab/workhorse_spec.rb5
-rw-r--r--spec/lib/json_web_token/rsa_token_spec.rb4
-rw-r--r--spec/lib/mattermost/session_spec.rb7
-rw-r--r--spec/lib/repository_cache_spec.rb2
-rw-r--r--spec/lib/rspec_flaky/example_spec.rb89
-rw-r--r--spec/lib/rspec_flaky/flaky_example_spec.rb104
-rw-r--r--spec/lib/rspec_flaky/listener_spec.rb178
-rw-r--r--spec/lib/system_check/simple_executor_spec.rb2
-rw-r--r--spec/mailers/notify_spec.rb24
-rw-r--r--spec/migrations/add_head_pipeline_for_each_merge_request_spec.rb2
-rw-r--r--spec/migrations/calculate_conv_dev_index_percentages_spec.rb41
-rw-r--r--spec/migrations/clean_upload_symlinks_spec.rb2
-rw-r--r--spec/migrations/cleanup_namespaceless_pending_delete_projects_spec.rb12
-rw-r--r--spec/migrations/fix_wrongly_renamed_routes_spec.rb4
-rw-r--r--spec/migrations/migrate_old_artifacts_spec.rb6
-rw-r--r--spec/migrations/migrate_process_commit_worker_jobs_spec.rb4
-rw-r--r--spec/migrations/move_personal_snippets_files_spec.rb10
-rw-r--r--spec/migrations/move_system_upload_folder_spec.rb18
-rw-r--r--spec/migrations/move_uploads_to_system_dir_spec.rb2
-rw-r--r--spec/migrations/rename_more_reserved_project_names_spec.rb2
-rw-r--r--spec/migrations/rename_reserved_project_names_spec.rb2
-rw-r--r--spec/migrations/rename_system_namespaces_spec.rb254
-rw-r--r--spec/migrations/schedule_merge_request_diff_migrations_spec.rb59
-rw-r--r--spec/migrations/turn_nested_groups_into_regular_groups_for_mysql_spec.rb2
-rw-r--r--spec/migrations/update_upload_paths_to_system_spec.rb18
-rw-r--r--spec/models/ability_spec.rb10
-rw-r--r--spec/models/appearance_spec.rb35
-rw-r--r--spec/models/blob_spec.rb2
-rw-r--r--spec/models/blob_viewer/base_spec.rb2
-rw-r--r--spec/models/blob_viewer/composer_json_spec.rb2
-rw-r--r--spec/models/blob_viewer/gemspec_spec.rb2
-rw-r--r--spec/models/blob_viewer/gitlab_ci_yml_spec.rb2
-rw-r--r--spec/models/blob_viewer/package_json_spec.rb2
-rw-r--r--spec/models/blob_viewer/podspec_json_spec.rb2
-rw-r--r--spec/models/blob_viewer/podspec_spec.rb2
-rw-r--r--spec/models/blob_viewer/route_map_spec.rb2
-rw-r--r--spec/models/blob_viewer/server_side_spec.rb4
-rw-r--r--spec/models/broadcast_message_spec.rb20
-rw-r--r--spec/models/ci/pipeline_spec.rb14
-rw-r--r--spec/models/ci/runner_spec.rb12
-rw-r--r--spec/models/ci/trigger_spec.rb2
-rw-r--r--spec/models/commit_range_spec.rb4
-rw-r--r--spec/models/commit_spec.rb8
-rw-r--r--spec/models/commit_status_spec.rb2
-rw-r--r--spec/models/concerns/access_requestable_spec.rb4
-rw-r--r--spec/models/concerns/issuable_spec.rb14
-rw-r--r--spec/models/concerns/mentionable_spec.rb10
-rw-r--r--spec/models/concerns/milestoneish_spec.rb2
-rw-r--r--spec/models/concerns/project_features_compatibility_spec.rb2
-rw-r--r--spec/models/concerns/reactive_caching_spec.rb2
-rw-r--r--spec/models/concerns/relative_positioning_spec.rb2
-rw-r--r--spec/models/concerns/resolvable_note_spec.rb2
-rw-r--r--spec/models/concerns/routable_spec.rb4
-rw-r--r--spec/models/concerns/subscribable_spec.rb2
-rw-r--r--spec/models/container_repository_spec.rb4
-rw-r--r--spec/models/conversational_development_index/metric_spec.rb11
-rw-r--r--spec/models/deploy_key_spec.rb4
-rw-r--r--spec/models/deploy_keys_project_spec.rb4
-rw-r--r--spec/models/deployment_spec.rb2
-rw-r--r--spec/models/diff_discussion_spec.rb2
-rw-r--r--spec/models/environment_spec.rb4
-rw-r--r--spec/models/event_collection_spec.rb51
-rw-r--r--spec/models/event_spec.rb46
-rw-r--r--spec/models/forked_project_link_spec.rb2
-rw-r--r--spec/models/generic_commit_status_spec.rb2
-rw-r--r--spec/models/global_milestone_spec.rb6
-rw-r--r--spec/models/gpg_key_spec.rb4
-rw-r--r--spec/models/gpg_signature_spec.rb2
-rw-r--r--spec/models/group_label_spec.rb4
-rw-r--r--spec/models/group_milestone_spec.rb2
-rw-r--r--spec/models/group_spec.rb2
-rw-r--r--spec/models/guest_spec.rb6
-rw-r--r--spec/models/hooks/system_hook_spec.rb2
-rw-r--r--spec/models/issue/metrics_spec.rb2
-rw-r--r--spec/models/issue_collection_spec.rb2
-rw-r--r--spec/models/issue_spec.rb60
-rw-r--r--spec/models/key_spec.rb20
-rw-r--r--spec/models/lfs_objects_project_spec.rb2
-rw-r--r--spec/models/member_spec.rb4
-rw-r--r--spec/models/members/project_member_spec.rb14
-rw-r--r--spec/models/merge_request_spec.rb64
-rw-r--r--spec/models/milestone_spec.rb50
-rw-r--r--spec/models/namespace_spec.rb36
-rw-r--r--spec/models/note_spec.rb12
-rw-r--r--spec/models/notification_setting_spec.rb12
-rw-r--r--spec/models/project_authorization_spec.rb4
-rw-r--r--spec/models/project_feature_spec.rb4
-rw-r--r--spec/models/project_group_link_spec.rb2
-rw-r--r--spec/models/project_label_spec.rb12
-rw-r--r--spec/models/project_services/asana_service_spec.rb2
-rw-r--r--spec/models/project_services/bamboo_service_spec.rb2
-rw-r--r--spec/models/project_services/buildkite_service_spec.rb2
-rw-r--r--spec/models/project_services/chat_notification_service_spec.rb4
-rw-r--r--spec/models/project_services/drone_ci_service_spec.rb2
-rw-r--r--spec/models/project_services/external_wiki_service_spec.rb2
-rw-r--r--spec/models/project_services/gitlab_issue_tracker_service_spec.rb18
-rw-r--r--spec/models/project_services/hipchat_service_spec.rb2
-rw-r--r--spec/models/project_services/jira_service_spec.rb25
-rw-r--r--spec/models/project_services/mattermost_slash_commands_service_spec.rb2
-rw-r--r--spec/models/project_services/pipelines_email_service_spec.rb8
-rw-r--r--spec/models/project_services/slack_slash_commands_service_spec.rb2
-rw-r--r--spec/models/project_services/teamcity_service_spec.rb2
-rw-r--r--spec/models/project_spec.rb317
-rw-r--r--spec/models/project_statistics_spec.rb2
-rw-r--r--spec/models/project_team_spec.rb28
-rw-r--r--spec/models/project_wiki_spec.rb36
-rw-r--r--spec/models/protected_branch_spec.rb2
-rw-r--r--spec/models/push_event_payload_spec.rb16
-rw-r--r--spec/models/push_event_spec.rb202
-rw-r--r--spec/models/redirect_route_spec.rb12
-rw-r--r--spec/models/repository_spec.rb175
-rw-r--r--spec/models/route_spec.rb74
-rw-r--r--spec/models/sent_notification_spec.rb4
-rw-r--r--spec/models/service_spec.rb16
-rw-r--r--spec/models/snippet_spec.rb10
-rw-r--r--spec/models/trending_project_spec.rb10
-rw-r--r--spec/models/user_spec.rb132
-rw-r--r--spec/models/wiki_page_spec.rb37
-rw-r--r--spec/policies/ci/build_policy_spec.rb8
-rw-r--r--spec/policies/ci/pipeline_policy_spec.rb2
-rw-r--r--spec/policies/ci/trigger_policy_spec.rb2
-rw-r--r--spec/policies/environment_policy_spec.rb8
-rw-r--r--spec/policies/issue_policy_spec.rb4
-rw-r--r--spec/policies/project_policy_spec.rb8
-rw-r--r--spec/policies/project_snippet_policy_spec.rb2
-rw-r--r--spec/presenters/ci/build_presenter_spec.rb6
-rw-r--r--spec/presenters/ci/pipeline_presenter_spec.rb2
-rw-r--r--spec/presenters/ci/variable_presenter_spec.rb2
-rw-r--r--spec/presenters/conversational_development_index/metric_presenter_spec.rb6
-rw-r--r--spec/presenters/merge_request_presenter_spec.rb6
-rw-r--r--spec/presenters/projects/settings/deploy_keys_presenter_spec.rb2
-rw-r--r--spec/requests/api/access_requests_spec.rb2
-rw-r--r--spec/requests/api/award_emoji_spec.rb2
-rw-r--r--spec/requests/api/boards_spec.rb4
-rw-r--r--spec/requests/api/circuit_breakers_spec.rb57
-rw-r--r--spec/requests/api/commit_statuses_spec.rb4
-rw-r--r--spec/requests/api/commits_spec.rb634
-rw-r--r--spec/requests/api/deploy_keys_spec.rb8
-rw-r--r--spec/requests/api/environments_spec.rb11
-rw-r--r--spec/requests/api/events_spec.rb64
-rw-r--r--spec/requests/api/files_spec.rb14
-rw-r--r--spec/requests/api/group_milestones_spec.rb2
-rw-r--r--spec/requests/api/group_variables_spec.rb221
-rw-r--r--spec/requests/api/groups_spec.rb14
-rw-r--r--spec/requests/api/helpers_spec.rb4
-rw-r--r--spec/requests/api/internal_spec.rb15
-rw-r--r--spec/requests/api/issues_spec.rb18
-rw-r--r--spec/requests/api/labels_spec.rb2
-rw-r--r--spec/requests/api/members_spec.rb2
-rw-r--r--spec/requests/api/merge_requests_spec.rb238
-rw-r--r--spec/requests/api/notes_spec.rb10
-rw-r--r--spec/requests/api/notification_settings_spec.rb6
-rw-r--r--spec/requests/api/pipeline_schedules_spec.rb4
-rw-r--r--spec/requests/api/project_hooks_spec.rb4
-rw-r--r--spec/requests/api/project_milestones_spec.rb2
-rw-r--r--spec/requests/api/project_snippets_spec.rb2
-rw-r--r--spec/requests/api/projects_spec.rb64
-rw-r--r--spec/requests/api/protected_branches_spec.rb232
-rw-r--r--spec/requests/api/runner_spec.rb8
-rw-r--r--spec/requests/api/runners_spec.rb34
-rw-r--r--spec/requests/api/services_spec.rb4
-rw-r--r--spec/requests/api/settings_spec.rb5
-rw-r--r--spec/requests/api/snippets_spec.rb4
-rw-r--r--spec/requests/api/tags_spec.rb471
-rw-r--r--spec/requests/api/todos_spec.rb4
-rw-r--r--spec/requests/api/triggers_spec.rb6
-rw-r--r--spec/requests/api/users_spec.rb50
-rw-r--r--spec/requests/api/v3/award_emoji_spec.rb2
-rw-r--r--spec/requests/api/v3/boards_spec.rb4
-rw-r--r--spec/requests/api/v3/deploy_keys_spec.rb10
-rw-r--r--spec/requests/api/v3/environments_spec.rb2
-rw-r--r--spec/requests/api/v3/files_spec.rb2
-rw-r--r--spec/requests/api/v3/groups_spec.rb14
-rw-r--r--spec/requests/api/v3/issues_spec.rb18
-rw-r--r--spec/requests/api/v3/labels_spec.rb2
-rw-r--r--spec/requests/api/v3/members_spec.rb2
-rw-r--r--spec/requests/api/v3/merge_requests_spec.rb40
-rw-r--r--spec/requests/api/v3/milestones_spec.rb4
-rw-r--r--spec/requests/api/v3/notes_spec.rb10
-rw-r--r--spec/requests/api/v3/project_snippets_spec.rb4
-rw-r--r--spec/requests/api/v3/projects_spec.rb68
-rw-r--r--spec/requests/api/v3/runners_spec.rb16
-rw-r--r--spec/requests/api/v3/services_spec.rb2
-rw-r--r--spec/requests/api/v3/snippets_spec.rb4
-rw-r--r--spec/requests/api/v3/todos_spec.rb4
-rw-r--r--spec/requests/api/v3/triggers_spec.rb4
-rw-r--r--spec/requests/api/v3/users_spec.rb29
-rw-r--r--spec/requests/api/variables_spec.rb10
-rw-r--r--spec/requests/ci/api/builds_spec.rb6
-rw-r--r--spec/requests/ci/api/runners_spec.rb2
-rw-r--r--spec/requests/ci/api/triggers_spec.rb2
-rw-r--r--spec/requests/git_http_spec.rb46
-rw-r--r--spec/requests/lfs_http_spec.rb34
-rw-r--r--spec/requests/request_profiler_spec.rb2
-rw-r--r--spec/routing/environments_spec.rb2
-rw-r--r--spec/routing/project_routing_spec.rb10
-rw-r--r--spec/rubocop/cop/migration/safer_boolean_column_spec.rb85
-rw-r--r--spec/serializers/analytics_build_entity_spec.rb14
-rw-r--r--spec/serializers/analytics_issue_entity_spec.rb2
-rw-r--r--spec/serializers/analytics_issue_serializer_spec.rb2
-rw-r--r--spec/serializers/analytics_merge_request_serializer_spec.rb2
-rw-r--r--spec/serializers/analytics_summary_serializer_spec.rb2
-rw-r--r--spec/serializers/build_details_entity_spec.rb2
-rw-r--r--spec/serializers/deploy_key_entity_spec.rb6
-rw-r--r--spec/serializers/environment_serializer_spec.rb4
-rw-r--r--spec/serializers/merge_request_entity_spec.rb4
-rw-r--r--spec/serializers/pipeline_details_entity_spec.rb4
-rw-r--r--spec/serializers/pipeline_entity_spec.rb4
-rw-r--r--spec/serializers/pipeline_serializer_spec.rb4
-rw-r--r--spec/serializers/runner_entity_spec.rb2
-rw-r--r--spec/services/auth/container_registry_authentication_service_spec.rb200
-rw-r--r--spec/services/boards/create_service_spec.rb2
-rw-r--r--spec/services/boards/issues/create_service_spec.rb2
-rw-r--r--spec/services/boards/issues/list_service_spec.rb2
-rw-r--r--spec/services/boards/issues/move_service_spec.rb2
-rw-r--r--spec/services/boards/list_service_spec.rb2
-rw-r--r--spec/services/boards/lists/create_service_spec.rb2
-rw-r--r--spec/services/boards/lists/destroy_service_spec.rb2
-rw-r--r--spec/services/boards/lists/generate_service_spec.rb2
-rw-r--r--spec/services/boards/lists/list_service_spec.rb2
-rw-r--r--spec/services/boards/lists/move_service_spec.rb2
-rw-r--r--spec/services/ci/create_pipeline_service_spec.rb4
-rw-r--r--spec/services/ci/pipeline_trigger_service_spec.rb4
-rw-r--r--spec/services/ci/play_build_service_spec.rb6
-rw-r--r--spec/services/ci/process_pipeline_service_spec.rb2
-rw-r--r--spec/services/ci/register_job_service_spec.rb6
-rw-r--r--spec/services/ci/retry_build_service_spec.rb2
-rw-r--r--spec/services/ci/retry_pipeline_service_spec.rb2
-rw-r--r--spec/services/create_deployment_service_spec.rb4
-rw-r--r--spec/services/delete_merged_branches_service_spec.rb8
-rw-r--r--spec/services/event_create_service_spec.rb48
-rw-r--r--spec/services/git_push_service_spec.rb11
-rw-r--r--spec/services/git_tag_push_service_spec.rb2
-rw-r--r--spec/services/groups/destroy_service_spec.rb2
-rw-r--r--spec/services/groups/update_service_spec.rb6
-rw-r--r--spec/services/issuable/bulk_update_service_spec.rb4
-rw-r--r--spec/services/issues/create_service_spec.rb8
-rw-r--r--spec/services/issues/duplicate_service_spec.rb4
-rw-r--r--spec/services/issues/move_service_spec.rb4
-rw-r--r--spec/services/issues/reopen_service_spec.rb2
-rw-r--r--spec/services/issues/resolve_discussions_spec.rb2
-rw-r--r--spec/services/issues/update_service_spec.rb8
-rw-r--r--spec/services/labels/create_service_spec.rb2
-rw-r--r--spec/services/labels/find_or_create_service_spec.rb2
-rw-r--r--spec/services/labels/promote_service_spec.rb10
-rw-r--r--spec/services/labels/transfer_service_spec.rb4
-rw-r--r--spec/services/labels/update_service_spec.rb2
-rw-r--r--spec/services/members/approve_access_request_service_spec.rb2
-rw-r--r--spec/services/members/authorized_destroy_service_spec.rb4
-rw-r--r--spec/services/members/create_service_spec.rb2
-rw-r--r--spec/services/members/destroy_service_spec.rb2
-rw-r--r--spec/services/members/request_access_service_spec.rb6
-rw-r--r--spec/services/merge_requests/build_service_spec.rb4
-rw-r--r--spec/services/merge_requests/get_urls_service_spec.rb8
-rw-r--r--spec/services/merge_requests/update_service_spec.rb6
-rw-r--r--spec/services/milestones/close_service_spec.rb2
-rw-r--r--spec/services/milestones/create_service_spec.rb2
-rw-r--r--spec/services/note_summary_spec.rb2
-rw-r--r--spec/services/notes/create_service_spec.rb2
-rw-r--r--spec/services/notes/destroy_service_spec.rb2
-rw-r--r--spec/services/notes/post_process_service_spec.rb2
-rw-r--r--spec/services/notes/quick_actions_service_spec.rb4
-rw-r--r--spec/services/notes/update_service_spec.rb2
-rw-r--r--spec/services/notification_recipient_service_spec.rb34
-rw-r--r--spec/services/notification_service_spec.rb193
-rw-r--r--spec/services/preview_markdown_service_spec.rb2
-rw-r--r--spec/services/projects/autocomplete_service_spec.rb29
-rw-r--r--spec/services/projects/create_from_template_service_spec.rb26
-rw-r--r--spec/services/projects/destroy_service_spec.rb4
-rw-r--r--spec/services/projects/download_service_spec.rb2
-rw-r--r--spec/services/projects/enable_deploy_key_service_spec.rb2
-rw-r--r--spec/services/projects/fork_service_spec.rb8
-rw-r--r--spec/services/projects/forks_count_service_spec.rb40
-rw-r--r--spec/services/projects/housekeeping_service_spec.rb2
-rw-r--r--spec/services/projects/import_service_spec.rb42
-rw-r--r--spec/services/projects/participants_service_spec.rb2
-rw-r--r--spec/services/projects/propagate_service_template_spec.rb4
-rw-r--r--spec/services/projects/transfer_service_spec.rb24
-rw-r--r--spec/services/projects/unlink_fork_service_spec.rb10
-rw-r--r--spec/services/projects/update_pages_configuration_service_spec.rb2
-rw-r--r--spec/services/projects/update_service_spec.rb11
-rw-r--r--spec/services/protected_branches/create_service_spec.rb2
-rw-r--r--spec/services/protected_branches/update_service_spec.rb2
-rw-r--r--spec/services/protected_tags/create_service_spec.rb2
-rw-r--r--spec/services/protected_tags/update_service_spec.rb2
-rw-r--r--spec/services/push_event_payload_service_spec.rb218
-rw-r--r--spec/services/quick_actions/interpret_service_spec.rb68
-rw-r--r--spec/services/search/global_service_spec.rb8
-rw-r--r--spec/services/search/group_service_spec.rb12
-rw-r--r--spec/services/search/snippet_service_spec.rb2
-rw-r--r--spec/services/search_service_spec.rb10
-rw-r--r--spec/services/spam_service_spec.rb2
-rw-r--r--spec/services/submit_usage_ping_service_spec.rb7
-rw-r--r--spec/services/system_hooks_service_spec.rb2
-rw-r--r--spec/services/system_note_service_spec.rb69
-rw-r--r--spec/services/todo_service_spec.rb41
-rw-r--r--spec/services/upload_service_spec.rb2
-rw-r--r--spec/services/users/destroy_service_spec.rb4
-rw-r--r--spec/services/users/migrate_to_ghost_user_service_spec.rb2
-rw-r--r--spec/services/users/refresh_authorized_projects_service_spec.rb14
-rw-r--r--spec/services/web_hook_service_spec.rb21
-rw-r--r--spec/services/wiki_pages/create_service_spec.rb2
-rw-r--r--spec/services/wiki_pages/destroy_service_spec.rb2
-rw-r--r--spec/services/wiki_pages/update_service_spec.rb6
-rw-r--r--spec/simplecov_env.rb25
-rw-r--r--spec/spec_helper.rb20
-rw-r--r--spec/support/api/milestones_shared_examples.rb4
-rw-r--r--spec/support/api/schema_matcher.rb18
-rw-r--r--spec/support/chat_slash_commands_shared_examples.rb2
-rw-r--r--spec/support/controllers/githubish_import_controller_shared_examples.rb4
-rw-r--r--spec/support/cycle_analytics_helpers.rb4
-rw-r--r--spec/support/features/issuable_slash_commands_shared_examples.rb20
-rw-r--r--spec/support/features/reportable_note_shared_examples.rb7
-rw-r--r--spec/support/gitlab-git-test.git/objects/3e/20715310a699808282e772720b9c04a0696bccbin0 -> 566 bytes
-rw-r--r--spec/support/gitlab-git-test.git/objects/95/96bc54a6f0c0c98248fe97077eb5ccf48a98d02
-rw-r--r--spec/support/gitlab-git-test.git/packed-refs1
-rw-r--r--spec/support/gpg_helpers.rb2
-rw-r--r--spec/support/import_export/export_file_helper.rb2
-rw-r--r--spec/support/issuable_shared_examples.rb6
-rw-r--r--spec/support/issuables_list_metadata_shared_examples.rb17
-rw-r--r--spec/support/login_helpers.rb2
-rw-r--r--spec/support/markdown_feature.rb6
-rw-r--r--spec/support/matchers/markdown_matchers.rb2
-rw-r--r--spec/support/matchers/query_matcher.rb2
-rw-r--r--spec/support/migrations_helpers.rb10
-rw-r--r--spec/support/notify_shared_examples.rb5
-rw-r--r--spec/support/project_features_apply_to_issuables_shared_examples.rb2
-rw-r--r--spec/support/project_hook_data_shared_example.rb4
-rw-r--r--spec/support/prometheus/additional_metrics_shared_examples.rb51
-rw-r--r--spec/support/rake_helpers.rb10
-rw-r--r--spec/support/redis/redis_shared_examples.rb4
-rw-r--r--spec/support/seed_repo.rb1
-rw-r--r--spec/support/services/migrate_to_ghost_user_service_shared_examples.rb9
-rw-r--r--spec/support/stored_repositories.rb12
-rw-r--r--spec/support/stub_configuration.rb11
-rw-r--r--spec/support/test_env.rb51
-rw-r--r--spec/support/unique_ip_check_shared_examples.rb2
-rw-r--r--spec/support/updating_mentions_shared_examples.rb2
-rw-r--r--spec/tasks/config_lint_spec.rb8
-rw-r--r--spec/tasks/gitlab/backup_rake_spec.rb10
-rw-r--r--spec/tasks/gitlab/gitaly_rake_spec.rb41
-rw-r--r--spec/tasks/gitlab/shell_rake_spec.rb3
-rw-r--r--spec/tasks/gitlab/workhorse_rake_spec.rb16
-rw-r--r--spec/uploaders/file_mover_spec.rb14
-rw-r--r--spec/uploaders/file_uploader_spec.rb4
-rw-r--r--spec/uploaders/personal_file_uploader_spec.rb6
-rw-r--r--spec/validators/dynamic_path_validator_spec.rb2
-rw-r--r--spec/views/admin/dashboard/index.html.haml_spec.rb2
-rw-r--r--spec/views/ci/status/_badge.html.haml_spec.rb2
-rw-r--r--spec/views/layouts/nav/_project.html.haml_spec.rb2
-rw-r--r--spec/views/notify/pipeline_failed_email.html.haml_spec.rb2
-rw-r--r--spec/views/notify/pipeline_success_email.html.haml_spec.rb2
-rw-r--r--spec/views/projects/_home_panel.html.haml_spec.rb2
-rw-r--r--spec/views/projects/blob/_viewer.html.haml_spec.rb2
-rw-r--r--spec/views/projects/commits/_commit.html.haml_spec.rb22
-rw-r--r--spec/views/projects/edit.html.haml_spec.rb16
-rw-r--r--spec/views/projects/notes/_more_actions_dropdown.html.haml_spec.rb8
-rw-r--r--spec/views/projects/registry/repositories/index.html.haml_spec.rb2
-rw-r--r--spec/views/projects/tags/index.html.haml_spec.rb2
-rw-r--r--spec/views/shared/projects/_project.html.haml_spec.rb2
-rw-r--r--spec/workers/authorized_projects_worker_spec.rb2
-rw-r--r--spec/workers/email_receiver_worker_spec.rb26
-rw-r--r--spec/workers/emails_on_push_worker_spec.rb6
-rw-r--r--spec/workers/expire_pipeline_cache_worker_spec.rb2
-rw-r--r--spec/workers/git_garbage_collect_worker_spec.rb52
-rw-r--r--spec/workers/group_destroy_worker_spec.rb2
-rw-r--r--spec/workers/merge_worker_spec.rb11
-rw-r--r--spec/workers/namespaceless_project_destroy_worker_spec.rb8
-rw-r--r--spec/workers/new_issue_worker_spec.rb54
-rw-r--r--spec/workers/new_merge_request_worker_spec.rb56
-rw-r--r--spec/workers/pipeline_notification_worker_spec.rb4
-rw-r--r--spec/workers/pipeline_schedule_worker_spec.rb2
-rw-r--r--spec/workers/post_receive_spec.rb4
-rw-r--r--spec/workers/process_commit_worker_spec.rb2
-rw-r--r--spec/workers/prune_old_events_worker_spec.rb8
-rw-r--r--spec/workers/remove_unreferenced_lfs_objects_worker_spec.rb4
-rw-r--r--spec/workers/repository_check/batch_worker_spec.rb10
-rw-r--r--spec/workers/repository_check/clear_worker_spec.rb2
-rw-r--r--spec/workers/repository_import_worker_spec.rb2
-rw-r--r--spec/workers/stuck_import_jobs_worker_spec.rb4
-rw-r--r--spec/workers/stuck_merge_jobs_worker_spec.rb50
1008 files changed, 12466 insertions, 4113 deletions
diff --git a/spec/bin/changelog_spec.rb b/spec/bin/changelog_spec.rb
index 91aff0db7cc..6d8b9865dcb 100644
--- a/spec/bin/changelog_spec.rb
+++ b/spec/bin/changelog_spec.rb
@@ -4,56 +4,90 @@ load File.expand_path('../../bin/changelog', __dir__)
describe 'bin/changelog' do
describe ChangelogOptionParser do
- it 'parses --ammend' do
- options = described_class.parse(%w[foo bar --amend])
+ describe '.parse' do
+ it 'parses --amend' do
+ options = described_class.parse(%w[foo bar --amend])
- expect(options.amend).to eq true
- end
+ expect(options.amend).to eq true
+ end
- it 'parses --force and -f' do
- %w[--force -f].each do |flag|
- options = described_class.parse(%W[foo #{flag} bar])
+ it 'parses --force and -f' do
+ %w[--force -f].each do |flag|
+ options = described_class.parse(%W[foo #{flag} bar])
- expect(options.force).to eq true
+ expect(options.force).to eq true
+ end
end
- end
- it 'parses --merge-request and -m' do
- %w[--merge-request -m].each do |flag|
- options = described_class.parse(%W[foo #{flag} 1234 bar])
+ it 'parses --merge-request and -m' do
+ %w[--merge-request -m].each do |flag|
+ options = described_class.parse(%W[foo #{flag} 1234 bar])
- expect(options.merge_request).to eq 1234
+ expect(options.merge_request).to eq 1234
+ end
end
- end
- it 'parses --dry-run and -n' do
- %w[--dry-run -n].each do |flag|
- options = described_class.parse(%W[foo #{flag} bar])
+ it 'parses --dry-run and -n' do
+ %w[--dry-run -n].each do |flag|
+ options = described_class.parse(%W[foo #{flag} bar])
- expect(options.dry_run).to eq true
+ expect(options.dry_run).to eq true
+ end
end
- end
- it 'parses --git-username and -u' do
- allow(described_class).to receive(:git_user_name).and_return('Jane Doe')
+ it 'parses --git-username and -u' do
+ allow(described_class).to receive(:git_user_name).and_return('Jane Doe')
- %w[--git-username -u].each do |flag|
- options = described_class.parse(%W[foo #{flag} bar])
+ %w[--git-username -u].each do |flag|
+ options = described_class.parse(%W[foo #{flag} bar])
- expect(options.author).to eq 'Jane Doe'
+ expect(options.author).to eq 'Jane Doe'
+ end
+ end
+
+ it 'parses --type and -t' do
+ %w[--type -t].each do |flag|
+ options = described_class.parse(%W[foo #{flag} security])
+
+ expect(options.type).to eq 'security'
+ end
end
- end
- it 'parses -h' do
- expect do
- expect { described_class.parse(%w[foo -h bar]) }.to output.to_stdout
- end.to raise_error(SystemExit)
+ it 'parses -h' do
+ expect do
+ expect { described_class.parse(%w[foo -h bar]) }.to output.to_stdout
+ end.to raise_error(SystemExit)
+ end
+
+ it 'assigns title' do
+ options = described_class.parse(%W[foo -m 1 bar\n -u baz\r\n --amend])
+
+ expect(options.title).to eq 'foo bar baz'
+ end
end
- it 'assigns title' do
- options = described_class.parse(%W[foo -m 1 bar\n -u baz\r\n --amend])
+ describe '.read_type' do
+ let(:type) { '1' }
- expect(options.title).to eq 'foo bar baz'
+ it 'reads type from $stdin' do
+ expect($stdin).to receive(:getc).and_return(type)
+ expect do
+ expect(described_class.read_type).to eq('added')
+ end.to output.to_stdout
+ end
+
+ context 'invalid type given' do
+ let(:type) { '99' }
+
+ it 'shows error message and exits the program' do
+ allow($stdin).to receive(:getc).and_return(type)
+ expect do
+ expect do
+ expect { described_class.read_type }.to raise_error(SystemExit)
+ end.to output("Invalid category index, please select an index between 1 and 7\n").to_stderr
+ end.to output.to_stdout
+ end
+ end
end
end
end
diff --git a/spec/config/mail_room_spec.rb b/spec/config/mail_room_spec.rb
index a31e44fa928..74634dac713 100644
--- a/spec/config/mail_room_spec.rb
+++ b/spec/config/mail_room_spec.rb
@@ -20,12 +20,12 @@ describe 'mail_room.yml' do
YAML.load(output)
end
- before(:each) do
+ before do
stub_env('GITLAB_REDIS_QUEUES_CONFIG_FILE', absolute_path(queues_config_path))
clear_queues_raw_config
end
- after(:each) do
+ after do
clear_queues_raw_config
end
diff --git a/spec/controllers/admin/groups_controller_spec.rb b/spec/controllers/admin/groups_controller_spec.rb
index ddf38967dd7..0dad95e418f 100644
--- a/spec/controllers/admin/groups_controller_spec.rb
+++ b/spec/controllers/admin/groups_controller_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe Admin::GroupsController do
let(:group) { create(:group) }
- let(:project) { create(:empty_project, namespace: group) }
+ let(:project) { create(:project, namespace: group) }
let(:admin) { create(:admin) }
before do
diff --git a/spec/controllers/admin/health_check_controller_spec.rb b/spec/controllers/admin/health_check_controller_spec.rb
new file mode 100644
index 00000000000..0b8e0c8a065
--- /dev/null
+++ b/spec/controllers/admin/health_check_controller_spec.rb
@@ -0,0 +1,25 @@
+require 'spec_helper'
+
+describe Admin::HealthCheckController, broken_storage: true do
+ let(:admin) { create(:admin) }
+
+ before do
+ sign_in(admin)
+ end
+
+ describe 'GET show' do
+ it 'loads the git storage health information' do
+ get :show
+
+ expect(assigns[:failing_storage_statuses]).not_to be_nil
+ end
+ end
+
+ describe 'POST reset_storage_health' do
+ it 'resets all storage health information' do
+ expect(Gitlab::Git::Storage::CircuitBreaker).to receive(:reset_all!)
+
+ post :reset_storage_health
+ end
+ end
+end
diff --git a/spec/controllers/admin/projects_controller_spec.rb b/spec/controllers/admin/projects_controller_spec.rb
index 2c35d394b74..373260b3978 100644
--- a/spec/controllers/admin/projects_controller_spec.rb
+++ b/spec/controllers/admin/projects_controller_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Admin::ProjectsController do
- let!(:project) { create(:empty_project, :public) }
+ let!(:project) { create(:project, :public) }
before do
sign_in(create(:admin))
@@ -12,12 +12,24 @@ describe Admin::ProjectsController do
it 'retrieves the project for the given visibility level' do
get :index, visibility_level: [Gitlab::VisibilityLevel::PUBLIC]
+
expect(response.body).to match(project.name)
end
it 'does not retrieve the project' do
get :index, visibility_level: [Gitlab::VisibilityLevel::INTERNAL]
+
expect(response.body).not_to match(project.name)
end
+
+ it 'does not respond with projects pending deletion' do
+ pending_delete_project = create(:project, pending_delete: true)
+
+ get :index
+
+ expect(response).to have_http_status(200)
+ expect(response.body).not_to match(pending_delete_project.name)
+ expect(response.body).to match(project.name)
+ end
end
end
diff --git a/spec/controllers/admin/services_controller_spec.rb b/spec/controllers/admin/services_controller_spec.rb
index 4ca0cfc74e9..249bd948847 100644
--- a/spec/controllers/admin/services_controller_spec.rb
+++ b/spec/controllers/admin/services_controller_spec.rb
@@ -8,7 +8,7 @@ describe Admin::ServicesController do
end
describe 'GET #edit' do
- let!(:project) { create(:empty_project) }
+ let!(:project) { create(:project) }
Service.available_services_names.each do |service_name|
context "#{service_name}" do
@@ -27,7 +27,7 @@ describe Admin::ServicesController do
end
describe "#update" do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let!(:service) do
RedmineService.create(
project: project,
diff --git a/spec/controllers/admin/users_controller_spec.rb b/spec/controllers/admin/users_controller_spec.rb
index 69928a906c6..3d21b695af4 100644
--- a/spec/controllers/admin/users_controller_spec.rb
+++ b/spec/controllers/admin/users_controller_spec.rb
@@ -9,7 +9,7 @@ describe Admin::UsersController do
end
describe 'DELETE #user with projects' do
- let(:project) { create(:empty_project, namespace: user.namespace) }
+ let(:project) { create(:project, namespace: user.namespace) }
let!(:issue) { create(:issue, author: user) }
before do
@@ -127,7 +127,7 @@ describe Admin::UsersController do
describe 'POST create' do
it 'creates the user' do
- expect{ post :create, user: attributes_for(:user) }.to change{ User.count }.by(1)
+ expect { post :create, user: attributes_for(:user) }.to change { User.count }.by(1)
end
it 'shows only one error message for an invalid email' do
diff --git a/spec/controllers/application_controller_spec.rb b/spec/controllers/application_controller_spec.rb
index 1641bddea11..331903a5543 100644
--- a/spec/controllers/application_controller_spec.rb
+++ b/spec/controllers/application_controller_spec.rb
@@ -108,6 +108,30 @@ describe ApplicationController do
end
end
+ describe 'rescue from Gitlab::Git::Storage::Inaccessible' do
+ controller(described_class) do
+ def index
+ raise Gitlab::Git::Storage::Inaccessible.new('broken', 100)
+ end
+ end
+
+ it 'renders a 503 when storage is not available' do
+ sign_in(create(:user))
+
+ get :index
+
+ expect(response.status).to eq(503)
+ end
+
+ it 'renders includes a Retry-After header' do
+ sign_in(create(:user))
+
+ get :index
+
+ expect(response.headers['Retry-After']).to eq(100)
+ end
+ end
+
describe 'response format' do
controller(described_class) do
def index
diff --git a/spec/controllers/autocomplete_controller_spec.rb b/spec/controllers/autocomplete_controller_spec.rb
index 58486f33229..2fbab1e4040 100644
--- a/spec/controllers/autocomplete_controller_spec.rb
+++ b/spec/controllers/autocomplete_controller_spec.rb
@@ -1,8 +1,8 @@
require 'spec_helper'
describe AutocompleteController do
- let!(:project) { create(:empty_project) }
- let!(:user) { create(:user) }
+ let(:project) { create(:project) }
+ let(:user) { project.owner }
context 'GET users' do
let!(:user2) { create(:user) }
@@ -11,7 +11,6 @@ describe AutocompleteController do
context 'project members' do
before do
sign_in(user)
- project.add_master(user)
end
describe 'GET #users with project ID' do
@@ -19,11 +18,11 @@ describe AutocompleteController do
get(:users, project_id: project.id)
end
- let(:body) { JSON.parse(response.body) }
-
- it { expect(body).to be_kind_of(Array) }
- it { expect(body.size).to eq 2 }
- it { expect(body.map { |u| u["username"] }).to include(user.username) }
+ it 'returns the project members' do
+ expect(json_response).to be_kind_of(Array)
+ expect(json_response.size).to eq(1)
+ expect(json_response.map { |u| u["username"] }).to include(user.username)
+ end
end
describe 'GET #users with unknown project' do
@@ -39,20 +38,20 @@ describe AutocompleteController do
let(:group) { create(:group) }
before do
- sign_in(user)
group.add_owner(user)
+ sign_in(user)
end
- let(:body) { JSON.parse(response.body) }
-
describe 'GET #users with group ID' do
before do
get(:users, group_id: group.id)
end
- it { expect(body).to be_kind_of(Array) }
- it { expect(body.size).to eq 1 }
- it { expect(body.first["username"]).to eq user.username }
+ it 'returns the group members' do
+ expect(json_response).to be_kind_of(Array)
+ expect(json_response.size).to eq(1)
+ expect(json_response.first["username"]).to eq user.username
+ end
end
describe 'GET #users with unknown group ID' do
@@ -65,23 +64,22 @@ describe AutocompleteController do
end
context 'non-member login for public project' do
- let!(:project) { create(:project, :public) }
+ let(:project) { create(:project, :public) }
before do
sign_in(non_member)
- project.add_master(user)
end
- let(:body) { JSON.parse(response.body) }
-
describe 'GET #users with project ID' do
before do
get(:users, project_id: project.id, current_user: true)
end
- it { expect(body).to be_kind_of(Array) }
- it { expect(body.size).to eq 3 }
- it { expect(body.map { |u| u['username'] }).to include(user.username, non_member.username) }
+ it 'returns the project members and non-members' do
+ expect(json_response).to be_kind_of(Array)
+ expect(json_response.size).to eq(2)
+ expect(json_response.map { |u| u['username'] }).to include(user.username, non_member.username)
+ end
end
end
@@ -91,10 +89,8 @@ describe AutocompleteController do
get(:users)
end
- let(:body) { JSON.parse(response.body) }
-
- it { expect(body).to be_kind_of(Array) }
- it { expect(body.size).to eq User.count }
+ it { expect(json_response).to be_kind_of(Array) }
+ it { expect(json_response.size).to eq User.count }
end
context 'user order' do
@@ -106,7 +102,7 @@ describe AutocompleteController do
sign_in(user)
get(:users, search: 'user')
- response_usernames = JSON.parse(response.body).map { |user| user['username'] }
+ response_usernames = json_response.map { |user| user['username'] }
expect(response_usernames.take(3)).to match_array([user.username, reported_user.username, user1.username])
end
@@ -120,15 +116,12 @@ describe AutocompleteController do
get(:users, per_page: per_page)
end
- let(:body) { JSON.parse(response.body) }
-
- it { expect(body).to be_kind_of(Array) }
- it { expect(body.size).to eq per_page }
+ it { expect(json_response).to be_kind_of(Array) }
+ it { expect(json_response.size).to eq(per_page) }
end
context 'unauthenticated user' do
let(:public_project) { create(:project, :public) }
- let(:body) { JSON.parse(response.body) }
describe 'GET #users with public project' do
before do
@@ -136,8 +129,8 @@ describe AutocompleteController do
get(:users, project_id: public_project.id)
end
- it { expect(body).to be_kind_of(Array) }
- it { expect(body.size).to eq 2 }
+ it { expect(json_response).to be_kind_of(Array) }
+ it { expect(json_response.size).to eq 2 }
end
describe 'GET #users with project' do
@@ -170,8 +163,8 @@ describe AutocompleteController do
get(:users)
end
- it { expect(body).to be_kind_of(Array) }
- it { expect(body.size).to eq 0 }
+ it { expect(json_response).to be_kind_of(Array) }
+ it { expect(json_response).to be_empty }
end
describe 'GET #users with todo filter' do
@@ -179,14 +172,12 @@ describe AutocompleteController do
get :users, todo_filter: true
expect(response.status).to eq 200
- expect(body).to be_kind_of(Array)
+ expect(json_response).to be_kind_of(Array)
end
end
end
context 'author of issuable included' do
- let(:body) { JSON.parse(response.body) }
-
context 'authenticated' do
before do
sign_in(user)
@@ -195,13 +186,13 @@ describe AutocompleteController do
it 'includes the author' do
get(:users, author_id: non_member.id)
- expect(body.first["username"]).to eq non_member.username
+ expect(json_response.first["username"]).to eq non_member.username
end
it 'rejects non existent user ids' do
get(:users, author_id: 99999)
- expect(body.collect { |u| u['id'] }).not_to include(99999)
+ expect(json_response.collect { |u| u['id'] }).not_to include(99999)
end
end
@@ -209,7 +200,7 @@ describe AutocompleteController do
it 'returns empty result' do
get(:users, author_id: non_member.id)
- expect(body).to be_empty
+ expect(json_response).to be_empty
end
end
end
@@ -222,10 +213,9 @@ describe AutocompleteController do
it 'skips the user IDs passed' do
get(:users, skip_users: [user, user2].map(&:id))
- other_user_ids = [non_member, project.owner, project.creator].map(&:id)
- response_user_ids = JSON.parse(response.body).map { |user| user['id'] }
+ response_user_ids = json_response.map { |user| user['id'] }
- expect(response_user_ids).to contain_exactly(*other_user_ids)
+ expect(response_user_ids).to contain_exactly(non_member.id)
end
end
end
@@ -249,17 +239,15 @@ describe AutocompleteController do
get(:projects, project_id: project.id)
end
- let(:body) { JSON.parse(response.body) }
-
- it do
- expect(body).to be_kind_of(Array)
- expect(body.size).to eq 2
+ it 'returns projects' do
+ expect(json_response).to be_kind_of(Array)
+ expect(json_response.size).to eq(2)
- expect(body.first['id']).to eq 0
- expect(body.first['name_with_namespace']).to eq 'No project'
+ expect(json_response.first['id']).to eq(0)
+ expect(json_response.first['name_with_namespace']).to eq 'No project'
- expect(body.last['id']).to eq authorized_project.id
- expect(body.last['name_with_namespace']).to eq authorized_project.name_with_namespace
+ expect(json_response.last['id']).to eq authorized_project.id
+ expect(json_response.last['name_with_namespace']).to eq authorized_project.name_with_namespace
end
end
end
@@ -275,14 +263,12 @@ describe AutocompleteController do
get(:projects, project_id: project.id, search: 'rugged')
end
- let(:body) { JSON.parse(response.body) }
+ it 'returns projects' do
+ expect(json_response).to be_kind_of(Array)
+ expect(json_response.size).to eq(2)
- it do
- expect(body).to be_kind_of(Array)
- expect(body.size).to eq 2
-
- expect(body.last['id']).to eq authorized_search_project.id
- expect(body.last['name_with_namespace']).to eq authorized_search_project.name_with_namespace
+ expect(json_response.last['id']).to eq authorized_search_project.id
+ expect(json_response.last['name_with_namespace']).to eq authorized_search_project.name_with_namespace
end
end
end
@@ -304,11 +290,9 @@ describe AutocompleteController do
get(:projects, project_id: project.id)
end
- let(:body) { JSON.parse(response.body) }
-
- it do
- expect(body).to be_kind_of(Array)
- expect(body.size).to eq 3 # Of a total of 4
+ it 'returns projects' do
+ expect(json_response).to be_kind_of(Array)
+ expect(json_response.size).to eq 3 # Of a total of 4
end
end
end
@@ -328,17 +312,15 @@ describe AutocompleteController do
get(:projects, project_id: project.id, offset_id: authorized_project.id)
end
- let(:body) { JSON.parse(response.body) }
-
- it do
- expect(body.detect { |item| item['id'] == 0 }).to be_nil # 'No project' is not there
- expect(body.detect { |item| item['id'] == authorized_project.id }).to be_nil # Offset project is not there either
+ it 'returns "No project"' do
+ expect(json_response.detect { |item| item['id'] == 0 }).to be_nil # 'No project' is not there
+ expect(json_response.detect { |item| item['id'] == authorized_project.id }).to be_nil # Offset project is not there either
end
end
end
context 'authorized projects without admin_issue ability' do
- before(:each) do
+ before do
authorized_project.add_guest(user)
expect(user.can?(:admin_issue, authorized_project)).to eq(false)
@@ -349,13 +331,10 @@ describe AutocompleteController do
get(:projects, project_id: project.id)
end
- let(:body) { JSON.parse(response.body) }
-
- it do
- expect(body).to be_kind_of(Array)
- expect(body.size).to eq 1 # 'No project'
-
- expect(body.first['id']).to eq 0
+ it 'returns a single "No project"' do
+ expect(json_response).to be_kind_of(Array)
+ expect(json_response.size).to eq(1) # 'No project'
+ expect(json_response.first['id']).to eq 0
end
end
end
diff --git a/spec/controllers/dashboard/labels_controller_spec.rb b/spec/controllers/dashboard/labels_controller_spec.rb
index 2b63933008f..a3bfb2f3a87 100644
--- a/spec/controllers/dashboard/labels_controller_spec.rb
+++ b/spec/controllers/dashboard/labels_controller_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Dashboard::LabelsController do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:user) { create(:user) }
let!(:label) { create(:label, project: project) }
@@ -11,7 +11,7 @@ describe Dashboard::LabelsController do
end
describe "#index" do
- let!(:unrelated_label) { create(:label, project: create(:empty_project, :public)) }
+ let!(:unrelated_label) { create(:label, project: create(:project, :public)) }
it 'returns global labels for projects the user has a relationship with' do
get :index, format: :json
diff --git a/spec/controllers/dashboard/milestones_controller_spec.rb b/spec/controllers/dashboard/milestones_controller_spec.rb
index 424f39fd3b8..2dcb67d50f4 100644
--- a/spec/controllers/dashboard/milestones_controller_spec.rb
+++ b/spec/controllers/dashboard/milestones_controller_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Dashboard::MilestonesController do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:user) { create(:user) }
let(:project_milestone) { create(:milestone, project: project) }
let(:milestone) do
diff --git a/spec/controllers/dashboard/todos_controller_spec.rb b/spec/controllers/dashboard/todos_controller_spec.rb
index 4a48621abe1..c8c6b9f41bf 100644
--- a/spec/controllers/dashboard/todos_controller_spec.rb
+++ b/spec/controllers/dashboard/todos_controller_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe Dashboard::TodosController do
let(:user) { create(:user) }
let(:author) { create(:user) }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:todo_service) { TodoService.new }
before do
@@ -14,7 +14,7 @@ describe Dashboard::TodosController do
describe 'GET #index' do
context 'project authorization' do
it 'renders 404 when user does not have read access on given project' do
- unauthorized_project = create(:empty_project, :private)
+ unauthorized_project = create(:project, :private)
get :index, project_id: unauthorized_project.id
@@ -34,7 +34,7 @@ describe Dashboard::TodosController do
end
it 'renders 200 when user has access on given project' do
- authorized_project = create(:empty_project, :public)
+ authorized_project = create(:project, :public)
get :index, project_id: authorized_project.id
diff --git a/spec/controllers/explore/projects_controller_spec.rb b/spec/controllers/explore/projects_controller_spec.rb
index 9dceeca168d..2845f258f6f 100644
--- a/spec/controllers/explore/projects_controller_spec.rb
+++ b/spec/controllers/explore/projects_controller_spec.rb
@@ -3,8 +3,8 @@ require 'spec_helper'
describe Explore::ProjectsController do
describe 'GET #trending' do
context 'sorting by update date' do
- let(:project1) { create(:empty_project, :public, updated_at: 3.days.ago) }
- let(:project2) { create(:empty_project, :public, updated_at: 1.day.ago) }
+ let(:project1) { create(:project, :public, updated_at: 3.days.ago) }
+ let(:project2) { create(:project, :public, updated_at: 1.day.ago) }
before do
create(:trending_project, project: project1)
diff --git a/spec/controllers/groups/milestones_controller_spec.rb b/spec/controllers/groups/milestones_controller_spec.rb
index aad67dd0164..fbbc67f3ae0 100644
--- a/spec/controllers/groups/milestones_controller_spec.rb
+++ b/spec/controllers/groups/milestones_controller_spec.rb
@@ -2,8 +2,8 @@ require 'spec_helper'
describe Groups::MilestonesController do
let(:group) { create(:group) }
- let!(:project) { create(:empty_project, group: group) }
- let!(:project2) { create(:empty_project, group: group) }
+ let!(:project) { create(:project, group: group) }
+ let!(:project2) { create(:project, group: group) }
let(:user) { create(:user) }
let(:title) { 'è‚¯å®šä¸æ˜¯ä¸­æ–‡çš„问题' }
let(:milestone) do
diff --git a/spec/controllers/groups_controller_spec.rb b/spec/controllers/groups_controller_spec.rb
index c4092303a67..c2ada8c8df7 100644
--- a/spec/controllers/groups_controller_spec.rb
+++ b/spec/controllers/groups_controller_spec.rb
@@ -3,7 +3,7 @@ require 'rails_helper'
describe GroupsController do
let(:user) { create(:user) }
let(:group) { create(:group, :public) }
- let(:project) { create(:empty_project, namespace: group) }
+ let(:project) { create(:project, namespace: group) }
let!(:group_member) { create(:group_member, group: group, user: user) }
describe 'GET #index' do
diff --git a/spec/controllers/import/bitbucket_controller_spec.rb b/spec/controllers/import/bitbucket_controller_spec.rb
index 8ef10dabd4c..e8707760a5a 100644
--- a/spec/controllers/import/bitbucket_controller_spec.rb
+++ b/spec/controllers/import/bitbucket_controller_spec.rb
@@ -52,7 +52,7 @@ describe Import::BitbucketController do
end
it "assigns variables" do
- @project = create(:empty_project, import_type: 'bitbucket', creator_id: user.id)
+ @project = create(:project, import_type: 'bitbucket', creator_id: user.id)
allow_any_instance_of(Bitbucket::Client).to receive(:repos).and_return([@repo])
get :status
@@ -63,7 +63,7 @@ describe Import::BitbucketController do
end
it "does not show already added project" do
- @project = create(:empty_project, import_type: 'bitbucket', creator_id: user.id, import_source: 'asd/vim')
+ @project = create(:project, import_type: 'bitbucket', creator_id: user.id, import_source: 'asd/vim')
allow_any_instance_of(Bitbucket::Client).to receive(:repos).and_return([@repo])
get :status
diff --git a/spec/controllers/import/fogbugz_controller_spec.rb b/spec/controllers/import/fogbugz_controller_spec.rb
index fffbc805335..5f0f6dea821 100644
--- a/spec/controllers/import/fogbugz_controller_spec.rb
+++ b/spec/controllers/import/fogbugz_controller_spec.rb
@@ -16,7 +16,7 @@ describe Import::FogbugzController do
end
it 'assigns variables' do
- @project = create(:empty_project, import_type: 'fogbugz', creator_id: user.id)
+ @project = create(:project, import_type: 'fogbugz', creator_id: user.id)
stub_client(repos: [@repo])
get :status
@@ -26,7 +26,7 @@ describe Import::FogbugzController do
end
it 'does not show already added project' do
- @project = create(:empty_project, import_type: 'fogbugz', creator_id: user.id, import_source: 'vim')
+ @project = create(:project, import_type: 'fogbugz', creator_id: user.id, import_source: 'vim')
stub_client(repos: [@repo])
get :status
diff --git a/spec/controllers/import/gitlab_controller_spec.rb b/spec/controllers/import/gitlab_controller_spec.rb
index 997107dadea..faf1e6f63ea 100644
--- a/spec/controllers/import/gitlab_controller_spec.rb
+++ b/spec/controllers/import/gitlab_controller_spec.rb
@@ -36,7 +36,7 @@ describe Import::GitlabController do
end
it "assigns variables" do
- @project = create(:empty_project, import_type: 'gitlab', creator_id: user.id)
+ @project = create(:project, import_type: 'gitlab', creator_id: user.id)
stub_client(projects: [@repo])
get :status
@@ -46,7 +46,7 @@ describe Import::GitlabController do
end
it "does not show already added project" do
- @project = create(:empty_project, import_type: 'gitlab', creator_id: user.id, import_source: 'asd/vim')
+ @project = create(:project, import_type: 'gitlab', creator_id: user.id, import_source: 'asd/vim')
stub_client(projects: [@repo])
get :status
diff --git a/spec/controllers/import/google_code_controller_spec.rb b/spec/controllers/import/google_code_controller_spec.rb
index c96fb90f70e..4241db6e771 100644
--- a/spec/controllers/import/google_code_controller_spec.rb
+++ b/spec/controllers/import/google_code_controller_spec.rb
@@ -27,7 +27,7 @@ describe Import::GoogleCodeController do
end
it "assigns variables" do
- @project = create(:empty_project, import_type: 'google_code', creator_id: user.id)
+ @project = create(:project, import_type: 'google_code', creator_id: user.id)
stub_client(repos: [@repo], incompatible_repos: [])
get :status
@@ -38,7 +38,7 @@ describe Import::GoogleCodeController do
end
it "does not show already added project" do
- @project = create(:empty_project, import_type: 'google_code', creator_id: user.id, import_source: 'vim')
+ @project = create(:project, import_type: 'google_code', creator_id: user.id, import_source: 'vim')
stub_client(repos: [@repo], incompatible_repos: [])
get :status
diff --git a/spec/controllers/invites_controller_spec.rb b/spec/controllers/invites_controller_spec.rb
index e478a253b3f..e00403118a0 100644
--- a/spec/controllers/invites_controller_spec.rb
+++ b/spec/controllers/invites_controller_spec.rb
@@ -24,7 +24,7 @@ describe InvitesController do
describe 'GET #decline' do
it 'declines user' do
get :decline, id: token
- expect{member.reload}.to raise_error ActiveRecord::RecordNotFound
+ expect {member.reload}.to raise_error ActiveRecord::RecordNotFound
expect(response).to have_http_status(302)
expect(flash[:notice]).to include 'You have declined the invitation to join'
diff --git a/spec/controllers/notification_settings_controller_spec.rb b/spec/controllers/notification_settings_controller_spec.rb
index 6b690407ce3..bef815ee1f7 100644
--- a/spec/controllers/notification_settings_controller_spec.rb
+++ b/spec/controllers/notification_settings_controller_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe NotificationSettingsController do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:group) { create(:group, :internal) }
let(:user) { create(:user) }
@@ -99,7 +99,7 @@ describe NotificationSettingsController do
end
context 'not authorized' do
- let(:private_project) { create(:empty_project, :private) }
+ let(:private_project) { create(:project, :private) }
before do
sign_in(user)
diff --git a/spec/controllers/projects/avatars_controller_spec.rb b/spec/controllers/projects/avatars_controller_spec.rb
index 8b71d6518bb..f5ea097af8b 100644
--- a/spec/controllers/projects/avatars_controller_spec.rb
+++ b/spec/controllers/projects/avatars_controller_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Projects::AvatarsController do
- let(:project) { create(:empty_project, avatar: fixture_file_upload(Rails.root + "spec/fixtures/dk.png", "image/png")) }
+ let(:project) { create(:project, avatar: fixture_file_upload(Rails.root + "spec/fixtures/dk.png", "image/png")) }
let(:user) { create(:user) }
before do
diff --git a/spec/controllers/projects/blob_controller_spec.rb b/spec/controllers/projects/blob_controller_spec.rb
index 02bbc48dc59..64b9af7b845 100644
--- a/spec/controllers/projects/blob_controller_spec.rb
+++ b/spec/controllers/projects/blob_controller_spec.rb
@@ -35,6 +35,26 @@ describe Projects::BlobController do
end
end
+ context 'with file path and JSON format' do
+ context "valid branch, valid file" do
+ let(:id) { 'master/README.md' }
+
+ before do
+ get(:show,
+ namespace_id: project.namespace,
+ project_id: project,
+ id: id,
+ format: :json)
+ end
+
+ it do
+ expect(response).to be_ok
+ expect(json_response).to have_key 'html'
+ expect(json_response).to have_key 'raw_path'
+ end
+ end
+ end
+
context 'with tree path' do
before do
get(:show,
@@ -48,7 +68,7 @@ describe Projects::BlobController do
let(:id) { 'markdown/doc' }
it 'redirects' do
expect(subject)
- .to redirect_to("/#{project.path_with_namespace}/tree/markdown/doc")
+ .to redirect_to("/#{project.full_path}/tree/markdown/doc")
end
end
end
@@ -193,7 +213,7 @@ describe Projects::BlobController do
context "when user doesn't have access" do
before do
- other_project = create(:empty_project)
+ other_project = create(:project, :repository)
merge_request.update!(source_project: other_project, target_project: other_project)
end
diff --git a/spec/controllers/projects/boards/issues_controller_spec.rb b/spec/controllers/projects/boards/issues_controller_spec.rb
index dc3b72c6de4..3f6c1092163 100644
--- a/spec/controllers/projects/boards/issues_controller_spec.rb
+++ b/spec/controllers/projects/boards/issues_controller_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Projects::Boards::IssuesController do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:board) { create(:board, project: project) }
let(:user) { create(:user) }
let(:guest) { create(:user) }
diff --git a/spec/controllers/projects/boards/lists_controller_spec.rb b/spec/controllers/projects/boards/lists_controller_spec.rb
index 0f2664262e8..65beec16307 100644
--- a/spec/controllers/projects/boards/lists_controller_spec.rb
+++ b/spec/controllers/projects/boards/lists_controller_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Projects::Boards::ListsController do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:board) { create(:board, project: project) }
let(:user) { create(:user) }
let(:guest) { create(:user) }
diff --git a/spec/controllers/projects/boards_controller_spec.rb b/spec/controllers/projects/boards_controller_spec.rb
index aed3a45c413..9e2e9a39481 100644
--- a/spec/controllers/projects/boards_controller_spec.rb
+++ b/spec/controllers/projects/boards_controller_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Projects::BoardsController do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:user) { create(:user) }
before do
diff --git a/spec/controllers/projects/branches_controller_spec.rb b/spec/controllers/projects/branches_controller_spec.rb
index 9cd4e9dbf84..745d051a5c1 100644
--- a/spec/controllers/projects/branches_controller_spec.rb
+++ b/spec/controllers/projects/branches_controller_spec.rb
@@ -33,7 +33,7 @@ describe Projects::BranchesController do
let(:ref) { "master" }
it 'redirects' do
expect(subject)
- .to redirect_to("/#{project.path_with_namespace}/tree/merge_branch")
+ .to redirect_to("/#{project.full_path}/tree/merge_branch")
end
end
@@ -42,7 +42,7 @@ describe Projects::BranchesController do
let(:ref) { "master" }
it 'redirects' do
expect(subject)
- .to redirect_to("/#{project.path_with_namespace}/tree/alert('merge');")
+ .to redirect_to("/#{project.full_path}/tree/alert('merge');")
end
end
@@ -82,7 +82,7 @@ describe Projects::BranchesController do
issue_iid: issue.iid
expect(subject)
- .to redirect_to("/#{project.path_with_namespace}/tree/1-feature-branch")
+ .to redirect_to("/#{project.full_path}/tree/1-feature-branch")
end
it 'posts a system note' do
@@ -96,7 +96,7 @@ describe Projects::BranchesController do
end
context 'repository-less project' do
- let(:project) { create :empty_project }
+ let(:project) { create :project }
it 'redirects to newly created branch' do
result = { status: :success, branch: double(name: branch) }
diff --git a/spec/controllers/projects/deploy_keys_controller_spec.rb b/spec/controllers/projects/deploy_keys_controller_spec.rb
index efe1a78415b..c3208357694 100644
--- a/spec/controllers/projects/deploy_keys_controller_spec.rb
+++ b/spec/controllers/projects/deploy_keys_controller_spec.rb
@@ -24,8 +24,8 @@ describe Projects::DeployKeysController do
end
context 'when json requested' do
- let(:project2) { create(:empty_project, :internal)}
- let(:project_private) { create(:empty_project, :private)}
+ let(:project2) { create(:project, :internal)}
+ let(:project_private) { create(:project, :private)}
let(:deploy_key_internal) do
create(:deploy_key, key: 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQCdMHEHyhRjbhEZVddFn6lTWdgEy5Q6Bz4nwGB76xWZI5YT/1WJOMEW+sL5zYd31kk7sd3FJ5L9ft8zWMWrr/iWXQikC2cqZK24H1xy+ZUmrRuJD4qGAaIVoyyzBL+avL+lF8J5lg6YSw8gwJY/lX64/vnJHUlWw2n5BF8IFOWhiw== dummy@gitlab.com')
diff --git a/spec/controllers/projects/deployments_controller_spec.rb b/spec/controllers/projects/deployments_controller_spec.rb
index 0dbfcf97f6f..3daff1eeea3 100644
--- a/spec/controllers/projects/deployments_controller_spec.rb
+++ b/spec/controllers/projects/deployments_controller_spec.rb
@@ -4,7 +4,7 @@ describe Projects::DeploymentsController do
include ApiHelpers
let(:user) { create(:user) }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:environment) { create(:environment, name: 'production', project: project) }
before do
diff --git a/spec/controllers/projects/environments_controller_spec.rb b/spec/controllers/projects/environments_controller_spec.rb
index f88f50c3cc6..5a95f4f6199 100644
--- a/spec/controllers/projects/environments_controller_spec.rb
+++ b/spec/controllers/projects/environments_controller_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe Projects::EnvironmentsController do
set(:user) { create(:user) }
- set(:project) { create(:empty_project) }
+ set(:project) { create(:project) }
set(:environment) do
create(:environment, name: 'production', project: project)
diff --git a/spec/controllers/projects/graphs_controller_spec.rb b/spec/controllers/projects/graphs_controller_spec.rb
index e0de62e4454..5af03ae118c 100644
--- a/spec/controllers/projects/graphs_controller_spec.rb
+++ b/spec/controllers/projects/graphs_controller_spec.rb
@@ -24,37 +24,4 @@ describe Projects::GraphsController do
expect(response).to redirect_to action: :charts
end
end
-
- describe 'GET charts' do
- let(:linguist_repository) do
- double(languages: {
- 'Ruby' => 1000,
- 'CoffeeScript' => 350,
- 'NSIS' => 15
- })
- end
-
- let(:expected_values) do
- nsis_color = "##{Digest::SHA256.hexdigest('NSIS')[0...6]}"
- [
- # colors from Linguist:
- { label: "Ruby", color: "#701516", highlight: "#701516" },
- { label: "CoffeeScript", color: "#244776", highlight: "#244776" },
- # colors from SHA256 fallback:
- { label: "NSIS", color: nsis_color, highlight: nsis_color }
- ]
- end
-
- before do
- allow(Linguist::Repository).to receive(:new).and_return(linguist_repository)
- end
-
- it 'sets the correct colour according to language' do
- get(:charts, namespace_id: project.namespace, project_id: project, id: 'master')
-
- expected_values.each do |val|
- expect(assigns(:languages)).to include(a_hash_including(val))
- end
- end
- end
end
diff --git a/spec/controllers/projects/group_links_controller_spec.rb b/spec/controllers/projects/group_links_controller_spec.rb
index 019a50882ab..f8c792cd0f0 100644
--- a/spec/controllers/projects/group_links_controller_spec.rb
+++ b/spec/controllers/projects/group_links_controller_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe Projects::GroupLinksController do
let(:group) { create(:group, :private) }
let(:group2) { create(:group, :private) }
- let(:project) { create(:empty_project, :private, group: group2) }
+ let(:project) { create(:project, :private, group: group2) }
let(:user) { create(:user) }
before do
diff --git a/spec/controllers/projects/hooks_controller_spec.rb b/spec/controllers/projects/hooks_controller_spec.rb
index b93ab220f4d..07174660f46 100644
--- a/spec/controllers/projects/hooks_controller_spec.rb
+++ b/spec/controllers/projects/hooks_controller_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Projects::HooksController do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:user) { create(:user) }
before do
diff --git a/spec/controllers/projects/imports_controller_spec.rb b/spec/controllers/projects/imports_controller_spec.rb
index 9be61342616..2a5ec6d584b 100644
--- a/spec/controllers/projects/imports_controller_spec.rb
+++ b/spec/controllers/projects/imports_controller_spec.rb
@@ -5,7 +5,7 @@ describe Projects::ImportsController do
describe 'GET #show' do
context 'when repository does not exists' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
before do
sign_in(user)
diff --git a/spec/controllers/projects/issues_controller_spec.rb b/spec/controllers/projects/issues_controller_spec.rb
index 2c57f3bcf8d..b571b11dcac 100644
--- a/spec/controllers/projects/issues_controller_spec.rb
+++ b/spec/controllers/projects/issues_controller_spec.rb
@@ -1,7 +1,7 @@
require('spec_helper')
describe Projects::IssuesController do
- let(:project) { create(:project_empty_repo) }
+ let(:project) { create(:project) }
let(:user) { create(:user) }
let(:issue) { create(:issue, project: project) }
@@ -234,7 +234,7 @@ describe Projects::IssuesController do
end
context 'when moving issue to another private project' do
- let(:another_project) { create(:empty_project, :private) }
+ let(:another_project) { create(:project, :private) }
context 'when user has access to move issue' do
before do
@@ -292,13 +292,13 @@ describe Projects::IssuesController do
it 'rejects an issue recognized as a spam' do
expect(Gitlab::Recaptcha).to receive(:load_configurations!).and_return(true)
- expect { update_spam_issue }.not_to change{ issue.reload.title }
+ expect { update_spam_issue }.not_to change { issue.reload.title }
end
it 'rejects an issue recognized as a spam when recaptcha disabled' do
stub_application_setting(recaptcha_enabled: false)
- expect { update_spam_issue }.not_to change{ issue.reload.title }
+ expect { update_spam_issue }.not_to change { issue.reload.title }
end
it 'creates a spam log' do
@@ -358,7 +358,7 @@ describe Projects::IssuesController do
end
it 'accepts an issue after recaptcha is verified' do
- expect{ update_verified_issue }.to change{ issue.reload.title }.to(spammy_title)
+ expect { update_verified_issue }.to change { issue.reload.title }.to(spammy_title)
end
it 'marks spam log as recaptcha_verified' do
@@ -594,7 +594,7 @@ describe Projects::IssuesController do
describe 'POST #create' do
def post_new_issue(issue_attrs = {}, additional_params = {})
sign_in(user)
- project = create(:empty_project, :public)
+ project = create(:project, :public)
project.team << [user, :developer]
post :create, {
@@ -817,7 +817,7 @@ describe Projects::IssuesController do
context "when the user is owner" do
let(:owner) { create(:user) }
let(:namespace) { create(:namespace, owner: owner) }
- let(:project) { create(:empty_project, namespace: namespace) }
+ let(:project) { create(:project, namespace: namespace) }
before do
sign_in(owner)
@@ -841,7 +841,7 @@ describe Projects::IssuesController do
describe 'POST #toggle_award_emoji' do
before do
sign_in(user)
- project.team << [user, :developer]
+ project.add_developer(user)
end
it "toggles the award emoji" do
@@ -855,6 +855,8 @@ describe Projects::IssuesController do
end
describe 'POST create_merge_request' do
+ let(:project) { create(:project, :repository) }
+
before do
project.add_developer(user)
sign_in(user)
diff --git a/spec/controllers/projects/jobs_controller_spec.rb b/spec/controllers/projects/jobs_controller_spec.rb
index 5a295ae47a6..fdd7e6f173f 100644
--- a/spec/controllers/projects/jobs_controller_spec.rb
+++ b/spec/controllers/projects/jobs_controller_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe Projects::JobsController do
include ApiHelpers
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:pipeline) { create(:ci_pipeline, project: project) }
let(:user) { create(:user) }
diff --git a/spec/controllers/projects/labels_controller_spec.rb b/spec/controllers/projects/labels_controller_spec.rb
index f19ad4c2c81..f4e2dca883d 100644
--- a/spec/controllers/projects/labels_controller_spec.rb
+++ b/spec/controllers/projects/labels_controller_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe Projects::LabelsController do
let(:group) { create(:group) }
- let(:project) { create(:empty_project, namespace: group) }
+ let(:project) { create(:project, namespace: group) }
let(:user) { create(:user) }
before do
@@ -73,7 +73,7 @@ describe Projects::LabelsController do
describe 'POST #generate' do
context 'personal project' do
- let(:personal_project) { create(:empty_project, namespace: user.namespace) }
+ let(:personal_project) { create(:project, namespace: user.namespace) }
it 'creates labels' do
post :generate, namespace_id: personal_project.namespace.to_param, project_id: personal_project
diff --git a/spec/controllers/projects/mattermosts_controller_spec.rb b/spec/controllers/projects/mattermosts_controller_spec.rb
index 12e413db902..4eea7041d29 100644
--- a/spec/controllers/projects/mattermosts_controller_spec.rb
+++ b/spec/controllers/projects/mattermosts_controller_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Projects::MattermostsController do
- let!(:project) { create(:empty_project) }
+ let!(:project) { create(:project) }
let!(:user) { create(:user) }
before do
diff --git a/spec/controllers/projects/merge_requests/conflicts_controller_spec.rb b/spec/controllers/projects/merge_requests/conflicts_controller_spec.rb
index 9278ac8edd8..393d38c6e6b 100644
--- a/spec/controllers/projects/merge_requests/conflicts_controller_spec.rb
+++ b/spec/controllers/projects/merge_requests/conflicts_controller_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Projects::MergeRequests::ConflictsController do
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:user) { project.owner }
let(:merge_request) { create(:merge_request_with_diffs, target_project: project, source_project: project) }
let(:merge_request_with_conflicts) do
diff --git a/spec/controllers/projects/merge_requests/creations_controller_spec.rb b/spec/controllers/projects/merge_requests/creations_controller_spec.rb
index f9d8f0f5fcf..fc4cec53374 100644
--- a/spec/controllers/projects/merge_requests/creations_controller_spec.rb
+++ b/spec/controllers/projects/merge_requests/creations_controller_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Projects::MergeRequests::CreationsController do
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:user) { project.owner }
let(:fork_project) { create(:forked_project_with_submodules) }
@@ -83,7 +83,7 @@ describe Projects::MergeRequests::CreationsController do
end
context 'when the source branch is in a different project to the target' do
- let(:other_project) { create(:project) }
+ let(:other_project) { create(:project, :repository) }
before do
other_project.team << [user, :master]
diff --git a/spec/controllers/projects/merge_requests/diffs_controller_spec.rb b/spec/controllers/projects/merge_requests/diffs_controller_spec.rb
index 53fe2bdb189..fad2c8f3ab7 100644
--- a/spec/controllers/projects/merge_requests/diffs_controller_spec.rb
+++ b/spec/controllers/projects/merge_requests/diffs_controller_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Projects::MergeRequests::DiffsController do
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:user) { project.owner }
let(:merge_request) { create(:merge_request_with_diffs, target_project: project, source_project: project) }
@@ -36,7 +36,7 @@ describe Projects::MergeRequests::DiffsController do
context 'with forked projects with submodules' do
render_views
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:fork_project) { create(:forked_project_with_submodules) }
let(:merge_request) { create(:merge_request_with_diffs, source_project: fork_project, source_branch: 'add-submodule-version-bump', target_branch: 'master', target_project: project) }
@@ -145,7 +145,7 @@ describe Projects::MergeRequests::DiffsController do
end
context 'when the merge request belongs to a different project' do
- let(:other_project) { create(:empty_project) }
+ let(:other_project) { create(:project) }
before do
other_project.team << [user, :master]
diff --git a/spec/controllers/projects/merge_requests_controller_spec.rb b/spec/controllers/projects/merge_requests_controller_spec.rb
index 2fce4b7a85f..bb67db268fa 100644
--- a/spec/controllers/projects/merge_requests_controller_spec.rb
+++ b/spec/controllers/projects/merge_requests_controller_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Projects::MergeRequestsController do
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:user) { project.owner }
let(:merge_request) { create(:merge_request_with_diffs, target_project: project, source_project: project) }
let(:merge_request_with_conflicts) do
@@ -106,7 +106,7 @@ describe Projects::MergeRequestsController do
end
describe 'GET index' do
- let!(:merge_request) { create(:merge_request_with_diffs, target_project: project, source_project: project) }
+ let(:merge_request) { create(:merge_request_with_diffs, target_project: project, source_project: project) }
def get_merge_requests(page = nil)
get :index,
@@ -150,6 +150,8 @@ describe Projects::MergeRequestsController do
context 'when filtering by opened state' do
context 'with opened merge requests' do
it 'lists those merge requests' do
+ expect(merge_request).to be_persisted
+
get_merge_requests
expect(assigns(:merge_requests)).to include(merge_request)
@@ -191,7 +193,7 @@ describe Projects::MergeRequestsController do
end
context 'there is no source project' do
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:fork_project) { create(:forked_project_with_submodules) }
let(:merge_request) { create(:merge_request, source_project: fork_project, source_branch: 'add-submodule-version-bump', target_branch: 'master', target_project: project) }
@@ -429,7 +431,7 @@ describe Projects::MergeRequestsController do
context "when the user is owner" do
let(:owner) { create(:user) }
let(:namespace) { create(:namespace, owner: owner) }
- let(:project) { create(:project, namespace: namespace) }
+ let(:project) { create(:project, :repository, namespace: namespace) }
before do
sign_in owner
@@ -587,7 +589,7 @@ describe Projects::MergeRequestsController do
describe 'GET ci_environments_status' do
context 'the environment is from a forked project' do
- let!(:forked) { create(:project) }
+ let!(:forked) { create(:project, :repository) }
let!(:environment) { create(:environment, project: forked) }
let!(:deployment) { create(:deployment, environment: environment, sha: forked.commit.id, ref: 'master') }
let(:admin) { create(:admin) }
@@ -609,7 +611,7 @@ describe Projects::MergeRequestsController do
end
it 'links to the environment on that project' do
- expect(json_response.first['url']).to match /#{forked.path_with_namespace}/
+ expect(json_response.first['url']).to match /#{forked.full_path}/
end
end
end
diff --git a/spec/controllers/projects/milestones_controller_spec.rb b/spec/controllers/projects/milestones_controller_spec.rb
index bb5a340cd96..62f1fb1f697 100644
--- a/spec/controllers/projects/milestones_controller_spec.rb
+++ b/spec/controllers/projects/milestones_controller_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Projects::MilestonesController do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:user) { create(:user) }
let(:milestone) { create(:milestone, project: project) }
let(:issue) { create(:issue, project: project, milestone: milestone) }
diff --git a/spec/controllers/projects/notes_controller_spec.rb b/spec/controllers/projects/notes_controller_spec.rb
index 3b88d5b0d7d..f280c55059c 100644
--- a/spec/controllers/projects/notes_controller_spec.rb
+++ b/spec/controllers/projects/notes_controller_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe Projects::NotesController do
let(:user) { create(:user) }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:issue) { create(:issue, project: project) }
let(:note) { create(:note, noteable: issue, project: project) }
@@ -167,10 +167,10 @@ describe Projects::NotesController do
end
context 'when creating a commit comment from an MR fork' do
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:fork_project) do
- create(:project).tap do |fork|
+ create(:project, :repository).tap do |fork|
create(:forked_project_link, forked_to_project: fork, forked_from_project: project)
end
end
diff --git a/spec/controllers/projects/pages_controller_spec.rb b/spec/controllers/projects/pages_controller_spec.rb
index df35d8e86b9..4d0111302f3 100644
--- a/spec/controllers/projects/pages_controller_spec.rb
+++ b/spec/controllers/projects/pages_controller_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe Projects::PagesController do
let(:user) { create(:user) }
- let(:project) { create(:empty_project, :public, :access_requestable) }
+ let(:project) { create(:project, :public, :access_requestable) }
let(:request_params) do
{
diff --git a/spec/controllers/projects/pages_domains_controller_spec.rb b/spec/controllers/projects/pages_domains_controller_spec.rb
index 920189be381..ad4d7da3bdd 100644
--- a/spec/controllers/projects/pages_domains_controller_spec.rb
+++ b/spec/controllers/projects/pages_domains_controller_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe Projects::PagesDomainsController do
let(:user) { create(:user) }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let!(:pages_domain) { create(:pages_domain, project: project) }
let(:request_params) do
diff --git a/spec/controllers/projects/pipeline_schedules_controller_spec.rb b/spec/controllers/projects/pipeline_schedules_controller_spec.rb
index 41bf5580993..4ac0559c679 100644
--- a/spec/controllers/projects/pipeline_schedules_controller_spec.rb
+++ b/spec/controllers/projects/pipeline_schedules_controller_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe Projects::PipelineSchedulesController do
include AccessMatchersForController
- set(:project) { create(:empty_project, :public) }
+ set(:project) { create(:project, :public) }
let!(:pipeline_schedule) { create(:ci_pipeline_schedule, project: project) }
describe 'GET #index' do
diff --git a/spec/controllers/projects/pipelines_controller_spec.rb b/spec/controllers/projects/pipelines_controller_spec.rb
index c8de275ca3e..f9d77c7ad03 100644
--- a/spec/controllers/projects/pipelines_controller_spec.rb
+++ b/spec/controllers/projects/pipelines_controller_spec.rb
@@ -4,7 +4,7 @@ describe Projects::PipelinesController do
include ApiHelpers
let(:user) { create(:user) }
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:feature) { ProjectFeature::DISABLED }
before do
@@ -61,7 +61,7 @@ describe Projects::PipelinesController do
create_build('post deploy', 3, 'pages 0')
end
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:pipeline) do
create(:ci_empty_pipeline, project: project, user: user, sha: project.commit.id)
end
diff --git a/spec/controllers/projects/project_members_controller_spec.rb b/spec/controllers/projects/project_members_controller_spec.rb
index 8671d7a78dd..3cb1bec5ea2 100644
--- a/spec/controllers/projects/project_members_controller_spec.rb
+++ b/spec/controllers/projects/project_members_controller_spec.rb
@@ -2,7 +2,7 @@ require('spec_helper')
describe Projects::ProjectMembersController do
let(:user) { create(:user) }
- let(:project) { create(:empty_project, :public, :access_requestable) }
+ let(:project) { create(:project, :public, :access_requestable) }
describe 'GET index' do
it 'should have the project_members address with a 200 status code' do
@@ -158,7 +158,7 @@ describe Projects::ProjectMembersController do
end
context 'and is an owner' do
- let(:project) { create(:empty_project, namespace: user.namespace) }
+ let(:project) { create(:project, namespace: user.namespace) }
before do
project.team << [user, :master]
@@ -261,7 +261,7 @@ describe Projects::ProjectMembersController do
end
describe 'POST apply_import' do
- let(:another_project) { create(:empty_project, :private) }
+ let(:another_project) { create(:project, :private) }
let(:member) { create(:user) }
before do
diff --git a/spec/controllers/projects/prometheus_controller_spec.rb b/spec/controllers/projects/prometheus_controller_spec.rb
index eddf7275975..8407a53272a 100644
--- a/spec/controllers/projects/prometheus_controller_spec.rb
+++ b/spec/controllers/projects/prometheus_controller_spec.rb
@@ -2,7 +2,7 @@ require('spec_helper')
describe Projects::PrometheusController do
let(:user) { create(:user) }
- let!(:project) { create(:empty_project) }
+ let!(:project) { create(:project) }
let(:prometheus_service) { double('prometheus_service') }
diff --git a/spec/controllers/projects/registry/repositories_controller_spec.rb b/spec/controllers/projects/registry/repositories_controller_spec.rb
index 464302824a8..2805968dcd9 100644
--- a/spec/controllers/projects/registry/repositories_controller_spec.rb
+++ b/spec/controllers/projects/registry/repositories_controller_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe Projects::Registry::RepositoriesController do
let(:user) { create(:user) }
- let(:project) { create(:empty_project, :private) }
+ let(:project) { create(:project, :private) }
before do
sign_in(user)
diff --git a/spec/controllers/projects/registry/tags_controller_spec.rb b/spec/controllers/projects/registry/tags_controller_spec.rb
index a823516830e..f4af3587d23 100644
--- a/spec/controllers/projects/registry/tags_controller_spec.rb
+++ b/spec/controllers/projects/registry/tags_controller_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe Projects::Registry::TagsController do
let(:user) { create(:user) }
- let(:project) { create(:empty_project, :private) }
+ let(:project) { create(:project, :private) }
before do
sign_in(user)
diff --git a/spec/controllers/projects/repositories_controller_spec.rb b/spec/controllers/projects/repositories_controller_spec.rb
index 9c55d159fa0..f712d1e0d63 100644
--- a/spec/controllers/projects/repositories_controller_spec.rb
+++ b/spec/controllers/projects/repositories_controller_spec.rb
@@ -6,7 +6,7 @@ describe Projects::RepositoriesController do
describe "GET archive" do
context 'as a guest' do
it 'responds with redirect in correct format' do
- get :archive, namespace_id: project.namespace, project_id: project, format: "zip"
+ get :archive, namespace_id: project.namespace, project_id: project, format: "zip", ref: 'master'
expect(response.header["Content-Type"]).to start_with('text/html')
expect(response).to be_redirect
diff --git a/spec/controllers/projects/runners_controller_spec.rb b/spec/controllers/projects/runners_controller_spec.rb
index 0fa249e4405..2b6f988fd9c 100644
--- a/spec/controllers/projects/runners_controller_spec.rb
+++ b/spec/controllers/projects/runners_controller_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe Projects::RunnersController do
let(:user) { create(:user) }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:runner) { create(:ci_runner) }
let(:params) do
diff --git a/spec/controllers/projects/services_controller_spec.rb b/spec/controllers/projects/services_controller_spec.rb
index 5a9d8a75f3e..4e9b0c09ff2 100644
--- a/spec/controllers/projects/services_controller_spec.rb
+++ b/spec/controllers/projects/services_controller_spec.rb
@@ -28,7 +28,7 @@ describe Projects::ServicesController do
context 'success' do
context 'with empty project' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
context 'with chat notification service' do
let(:service) { project.create_microsoft_teams_service(webhook: 'http://webhook.com') }
diff --git a/spec/controllers/projects/settings/ci_cd_controller_spec.rb b/spec/controllers/projects/settings/ci_cd_controller_spec.rb
index e9a91cff1b3..a8f4b79b64c 100644
--- a/spec/controllers/projects/settings/ci_cd_controller_spec.rb
+++ b/spec/controllers/projects/settings/ci_cd_controller_spec.rb
@@ -1,7 +1,7 @@
require('spec_helper')
describe Projects::Settings::CiCdController do
- let(:project) { create(:empty_project, :public, :access_requestable) }
+ let(:project) { create(:project, :public, :access_requestable) }
let(:user) { create(:user) }
before do
diff --git a/spec/controllers/projects/settings/integrations_controller_spec.rb b/spec/controllers/projects/settings/integrations_controller_spec.rb
index 65f7bb34f4a..e0f9a5b24a6 100644
--- a/spec/controllers/projects/settings/integrations_controller_spec.rb
+++ b/spec/controllers/projects/settings/integrations_controller_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Projects::Settings::IntegrationsController do
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:user) { create(:user) }
before do
diff --git a/spec/controllers/projects/todos_controller_spec.rb b/spec/controllers/projects/todos_controller_spec.rb
index c5a4153d991..41d211ed1bb 100644
--- a/spec/controllers/projects/todos_controller_spec.rb
+++ b/spec/controllers/projects/todos_controller_spec.rb
@@ -2,7 +2,7 @@ require('spec_helper')
describe Projects::TodosController do
let(:user) { create(:user) }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:issue) { create(:issue, project: project) }
let(:merge_request) { create(:merge_request, source_project: project) }
@@ -67,7 +67,7 @@ describe Projects::TodosController do
end
it "doesn't create todo" do
- expect{ go }.not_to change { user.todos.count }
+ expect { go }.not_to change { user.todos.count }
expect(response).to have_http_status(404)
end
end
@@ -135,7 +135,7 @@ describe Projects::TodosController do
end
it "doesn't create todo" do
- expect{ go }.not_to change { user.todos.count }
+ expect { go }.not_to change { user.todos.count }
expect(response).to have_http_status(404)
end
end
diff --git a/spec/controllers/projects/tree_controller_spec.rb b/spec/controllers/projects/tree_controller_spec.rb
index 16cd2e076e5..775f3998f5d 100644
--- a/spec/controllers/projects/tree_controller_spec.rb
+++ b/spec/controllers/projects/tree_controller_spec.rb
@@ -81,7 +81,7 @@ describe Projects::TreeController do
context 'redirect to blob' do
let(:id) { 'master/README.md' }
it 'redirects' do
- redirect_url = "/#{project.path_with_namespace}/blob/master/README.md"
+ redirect_url = "/#{project.full_path}/blob/master/README.md"
expect(subject)
.to redirect_to(redirect_url)
end
@@ -107,7 +107,7 @@ describe Projects::TreeController do
it 'redirects to the new directory' do
expect(subject)
- .to redirect_to("/#{project.path_with_namespace}/tree/#{branch_name}/#{path}")
+ .to redirect_to("/#{project.full_path}/tree/#{branch_name}/#{path}")
expect(flash[:notice]).to eq('The directory has been successfully created.')
end
end
@@ -118,7 +118,7 @@ describe Projects::TreeController do
it 'does not allow overwriting of existing files' do
expect(subject)
- .to redirect_to("/#{project.path_with_namespace}/tree/master")
+ .to redirect_to("/#{project.full_path}/tree/master")
expect(flash[:alert]).to eq('A file with this name already exists')
end
end
diff --git a/spec/controllers/projects/uploads_controller_spec.rb b/spec/controllers/projects/uploads_controller_spec.rb
index cd6961a7bd5..488bcf31371 100644
--- a/spec/controllers/projects/uploads_controller_spec.rb
+++ b/spec/controllers/projects/uploads_controller_spec.rb
@@ -1,7 +1,7 @@
require('spec_helper')
describe Projects::UploadsController do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:user) { create(:user) }
let(:jpg) { fixture_file_upload(Rails.root + 'spec/fixtures/rails_sample.jpg', 'image/jpg') }
let(:txt) { fixture_file_upload(Rails.root + 'spec/fixtures/doc_sample.txt', 'text/plain') }
diff --git a/spec/controllers/projects/variables_controller_spec.rb b/spec/controllers/projects/variables_controller_spec.rb
index da06fcb7cfb..6957fb43c19 100644
--- a/spec/controllers/projects/variables_controller_spec.rb
+++ b/spec/controllers/projects/variables_controller_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Projects::VariablesController do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:user) { create(:user) }
before do
diff --git a/spec/controllers/projects_controller_spec.rb b/spec/controllers/projects_controller_spec.rb
index 192cca45d99..c0e48046937 100644
--- a/spec/controllers/projects_controller_spec.rb
+++ b/spec/controllers/projects_controller_spec.rb
@@ -1,8 +1,8 @@
require('spec_helper')
describe ProjectsController do
- let(:project) { create(:empty_project) }
- let(:public_project) { create(:empty_project, :public) }
+ let(:project) { create(:project) }
+ let(:public_project) { create(:project, :public) }
let(:user) { create(:user) }
let(:jpg) { fixture_file_upload(Rails.root + 'spec/fixtures/rails_sample.jpg', 'image/jpg') }
let(:txt) { fixture_file_upload(Rails.root + 'spec/fixtures/doc_sample.txt', 'text/plain') }
@@ -34,7 +34,7 @@ describe ProjectsController do
end
context "user does not have access to project" do
- let(:private_project) { create(:empty_project, :private) }
+ let(:private_project) { create(:project, :private) }
it "does not initialize notification setting" do
get :show, namespace_id: private_project.namespace, id: private_project
@@ -107,6 +107,20 @@ describe ProjectsController do
end
end
+ context 'when the storage is not available', broken_storage: true do
+ let(:project) { create(:project, :broken_storage) }
+ before do
+ project.add_developer(user)
+ sign_in(user)
+ end
+
+ it 'renders a 503' do
+ get :show, namespace_id: project.namespace, id: project
+
+ expect(response).to have_http_status(503)
+ end
+ end
+
context "project with empty repo" do
let(:empty_project) { create(:project_empty_repo, :public) }
@@ -176,7 +190,7 @@ describe ProjectsController do
end
context "when the url contains .atom" do
- let(:public_project_with_dot_atom) { build(:empty_project, :public, name: 'my.atom', path: 'my.atom') }
+ let(:public_project_with_dot_atom) { build(:project, :public, name: 'my.atom', path: 'my.atom') }
it 'expects an error creating the project' do
expect(public_project_with_dot_atom).not_to be_valid
@@ -185,7 +199,7 @@ describe ProjectsController do
context 'when the project is pending deletions' do
it 'renders a 404 error' do
- project = create(:empty_project, pending_delete: true)
+ project = create(:project, pending_delete: true)
sign_in(user)
get :show, namespace_id: project.namespace, id: project
@@ -254,7 +268,7 @@ describe ProjectsController do
describe '#transfer' do
render_views
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:admin) { create(:admin) }
let(:new_namespace) { create(:namespace) }
@@ -311,8 +325,8 @@ describe ProjectsController do
end
context "when the project is forked" do
- let(:project) { create(:project) }
- let(:fork_project) { create(:project, forked_from_project: project) }
+ let(:project) { create(:project, :repository) }
+ let(:fork_project) { create(:project, :repository, forked_from_project: project) }
let(:merge_request) do
create(:merge_request,
source_project: fork_project,
@@ -390,7 +404,7 @@ describe ProjectsController do
end
context 'with forked project' do
- let(:project_fork) { create(:project, namespace: user.namespace) }
+ let(:project_fork) { create(:project, :repository, namespace: user.namespace) }
before do
create(:forked_project_link, forked_to_project: project_fork)
@@ -430,7 +444,7 @@ describe ProjectsController do
end
describe "GET refs" do
- let(:public_project) { create(:project, :public) }
+ let(:public_project) { create(:project, :public, :repository) }
it "gets a list of branches and tags" do
get :refs, namespace_id: public_project.namespace, id: public_project
@@ -564,6 +578,118 @@ describe ProjectsController do
end
end
+ describe '#export' do
+ before do
+ sign_in(user)
+
+ project.add_master(user)
+ end
+
+ context 'when project export is enabled' do
+ it 'returns 302' do
+ get :export, namespace_id: project.namespace, id: project
+
+ expect(response).to have_http_status(302)
+ end
+ end
+
+ context 'when project export is disabled' do
+ before do
+ stub_application_setting(project_export_enabled?: false)
+ end
+
+ it 'returns 404' do
+ get :export, namespace_id: project.namespace, id: project
+
+ expect(response).to have_http_status(404)
+ end
+ end
+ end
+
+ describe '#download_export' do
+ before do
+ sign_in(user)
+
+ project.add_master(user)
+ end
+
+ context 'when project export is enabled' do
+ it 'returns 302' do
+ get :download_export, namespace_id: project.namespace, id: project
+
+ expect(response).to have_http_status(302)
+ end
+ end
+
+ context 'when project export is disabled' do
+ before do
+ stub_application_setting(project_export_enabled?: false)
+ end
+
+ it 'returns 404' do
+ get :download_export, namespace_id: project.namespace, id: project
+
+ expect(response).to have_http_status(404)
+ end
+ end
+ end
+
+ describe '#remove_export' do
+ before do
+ sign_in(user)
+
+ project.add_master(user)
+ end
+
+ context 'when project export is enabled' do
+ it 'returns 302' do
+ post :remove_export, namespace_id: project.namespace, id: project
+
+ expect(response).to have_http_status(302)
+ end
+ end
+
+ context 'when project export is disabled' do
+ before do
+ stub_application_setting(project_export_enabled?: false)
+ end
+
+ it 'returns 404' do
+ post :remove_export, namespace_id: project.namespace, id: project
+
+ expect(response).to have_http_status(404)
+ end
+ end
+ end
+
+ describe '#generate_new_export' do
+ before do
+ sign_in(user)
+
+ project.add_master(user)
+ end
+
+ context 'when project export is enabled' do
+ it 'returns 302' do
+ post :generate_new_export, namespace_id: project.namespace, id: project
+
+ expect(response).to have_http_status(302)
+ end
+ end
+
+ context 'when project export is disabled' do
+ before do
+ stub_application_setting(project_export_enabled?: false)
+ end
+
+ it 'returns 404' do
+ post :generate_new_export, namespace_id: project.namespace, id: project
+
+ expect(response).to have_http_status(404)
+ end
+ end
+ end
+
def project_moved_message(redirect_route, project)
"Project '#{redirect_route.path}' was moved to '#{project.full_path}'. Please update any links and bookmarks that may still have the old path."
end
diff --git a/spec/controllers/registrations_controller_spec.rb b/spec/controllers/registrations_controller_spec.rb
index 634563fc290..5a4ab39ab86 100644
--- a/spec/controllers/registrations_controller_spec.rb
+++ b/spec/controllers/registrations_controller_spec.rb
@@ -5,7 +5,7 @@ describe RegistrationsController do
let(:user_params) { { user: { name: 'new_user', username: 'new_username', email: 'new@user.com', password: 'Any_password' } } }
context 'email confirmation' do
- around(:each) do |example|
+ around do |example|
perform_enqueued_jobs do
example.run
end
@@ -15,7 +15,7 @@ describe RegistrationsController do
it 'signs the user in' do
allow_any_instance_of(ApplicationSetting).to receive(:send_user_confirmation_email).and_return(false)
- expect { post(:create, user_params) }.not_to change{ ActionMailer::Base.deliveries.size }
+ expect { post(:create, user_params) }.not_to change { ActionMailer::Base.deliveries.size }
expect(subject.current_user).not_to be_nil
end
end
diff --git a/spec/controllers/search_controller_spec.rb b/spec/controllers/search_controller_spec.rb
index a3708ad0908..37f961d0c94 100644
--- a/spec/controllers/search_controller_spec.rb
+++ b/spec/controllers/search_controller_spec.rb
@@ -8,7 +8,7 @@ describe SearchController do
end
it 'finds issue comments' do
- project = create(:empty_project, :public)
+ project = create(:project, :public)
note = create(:note_on_issue, project: project)
get :show, project_id: project.id, scope: 'notes', search: note.note
@@ -23,7 +23,7 @@ describe SearchController do
end
it "doesn't expose comments on issues" do
- project = create(:empty_project, :public, :issues_private)
+ project = create(:project, :public, :issues_private)
note = create(:note_on_issue, project: project)
get :show, project_id: project.id, scope: 'notes', search: note.note
@@ -33,7 +33,7 @@ describe SearchController do
end
it "doesn't expose comments on merge_requests" do
- project = create(:empty_project, :public, :merge_requests_private)
+ project = create(:project, :public, :merge_requests_private)
note = create(:note_on_merge_request, project: project)
get :show, project_id: project.id, scope: 'notes', search: note.note
@@ -42,7 +42,7 @@ describe SearchController do
end
it "doesn't expose comments on snippets" do
- project = create(:empty_project, :public, :snippets_private)
+ project = create(:project, :public, :snippets_private)
note = create(:note_on_project_snippet, project: project)
get :show, project_id: project.id, scope: 'notes', search: note.note
diff --git a/spec/controllers/sent_notifications_controller_spec.rb b/spec/controllers/sent_notifications_controller_spec.rb
index 5d2734b8827..31593ce7311 100644
--- a/spec/controllers/sent_notifications_controller_spec.rb
+++ b/spec/controllers/sent_notifications_controller_spec.rb
@@ -2,7 +2,7 @@ require 'rails_helper'
describe SentNotificationsController do
let(:user) { create(:user) }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:sent_notification) { create(:sent_notification, project: project, noteable: issue, recipient: user) }
let(:issue) do
diff --git a/spec/controllers/snippets/notes_controller_spec.rb b/spec/controllers/snippets/notes_controller_spec.rb
index 1c494b8c7ab..225753333ee 100644
--- a/spec/controllers/snippets/notes_controller_spec.rb
+++ b/spec/controllers/snippets/notes_controller_spec.rb
@@ -138,7 +138,7 @@ describe Snippets::NotesController do
end
it "deletes the note" do
- expect{ delete :destroy, request_params }.to change{ Note.count }.from(1).to(0)
+ expect { delete :destroy, request_params }.to change { Note.count }.from(1).to(0)
end
context 'system note' do
@@ -147,7 +147,7 @@ describe Snippets::NotesController do
end
it "does not delete the note" do
- expect{ delete :destroy, request_params }.not_to change{ Note.count }
+ expect { delete :destroy, request_params }.not_to change { Note.count }
end
end
end
@@ -166,7 +166,7 @@ describe Snippets::NotesController do
end
it "does not update the note" do
- expect{ delete :destroy, request_params }.not_to change{ Note.count }
+ expect { delete :destroy, request_params }.not_to change { Note.count }
end
end
end
diff --git a/spec/controllers/snippets_controller_spec.rb b/spec/controllers/snippets_controller_spec.rb
index 475ceda11fe..7c5d059760f 100644
--- a/spec/controllers/snippets_controller_spec.rb
+++ b/spec/controllers/snippets_controller_spec.rb
@@ -186,8 +186,8 @@ describe SnippetsController do
end
context 'when the snippet description contains a file' do
- let(:picture_file) { '/system/temp/secret56/picture.jpg' }
- let(:text_file) { '/system/temp/secret78/text.txt' }
+ let(:picture_file) { '/-/system/temp/secret56/picture.jpg' }
+ let(:text_file) { '/-/system/temp/secret78/text.txt' }
let(:description) do
"Description with picture: ![picture](/uploads#{picture_file}) and "\
"text: [text.txt](/uploads#{text_file})"
@@ -208,8 +208,8 @@ describe SnippetsController do
snippet = subject
expected_description = "Description with picture: "\
- "![picture](/uploads/system/personal_snippet/#{snippet.id}/secret56/picture.jpg) and "\
- "text: [text.txt](/uploads/system/personal_snippet/#{snippet.id}/secret78/text.txt)"
+ "![picture](/uploads/-/system/personal_snippet/#{snippet.id}/secret56/picture.jpg) and "\
+ "text: [text.txt](/uploads/-/system/personal_snippet/#{snippet.id}/secret78/text.txt)"
expect(snippet.description).to eq(expected_description)
end
diff --git a/spec/controllers/uploads_controller_spec.rb b/spec/controllers/uploads_controller_spec.rb
index 96f719e2b82..b29f3d861be 100644
--- a/spec/controllers/uploads_controller_spec.rb
+++ b/spec/controllers/uploads_controller_spec.rb
@@ -102,7 +102,7 @@ describe UploadsController do
subject
expect(response.body).to match '\"alt\":\"rails_sample\"'
- expect(response.body).to match "\"url\":\"/uploads/system/temp"
+ expect(response.body).to match "\"url\":\"/uploads/-/system/temp"
end
it 'does not create an Upload record' do
@@ -119,7 +119,7 @@ describe UploadsController do
subject
expect(response.body).to match '\"alt\":\"doc_sample.txt\"'
- expect(response.body).to match "\"url\":\"/uploads/system/temp"
+ expect(response.body).to match "\"url\":\"/uploads/-/system/temp"
end
it 'does not create an Upload record' do
@@ -131,7 +131,7 @@ describe UploadsController do
describe "GET show" do
context 'Content-Disposition security measures' do
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
context 'for PNG files' do
it 'returns Content-Disposition: inline' do
@@ -203,7 +203,7 @@ describe UploadsController do
end
context "when viewing a project avatar" do
- let!(:project) { create(:empty_project, avatar: fixture_file_upload(Rails.root + "spec/fixtures/dk.png", "image/png")) }
+ let!(:project) { create(:project, avatar: fixture_file_upload(Rails.root + "spec/fixtures/dk.png", "image/png")) }
context "when the project is public" do
before do
diff --git a/spec/controllers/users_controller_spec.rb b/spec/controllers/users_controller_spec.rb
index 7aeb6efd86d..2cecd2646fc 100644
--- a/spec/controllers/users_controller_spec.rb
+++ b/spec/controllers/users_controller_spec.rb
@@ -86,14 +86,20 @@ describe UsersController do
end
context 'forked project' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:forked_project) { Projects::ForkService.new(project, user).execute }
before do
sign_in(user)
project.team << [user, :developer]
- EventCreateService.new.push(project, user, [])
- EventCreateService.new.push(forked_project, user, [])
+
+ push_data = Gitlab::DataBuilder::Push.build_sample(project, user)
+
+ fork_push_data = Gitlab::DataBuilder::Push
+ .build_sample(forked_project, user)
+
+ EventCreateService.new.push(project, user, push_data)
+ EventCreateService.new.push(forked_project, user, fork_push_data)
end
it 'includes forked projects' do
@@ -104,7 +110,7 @@ describe UsersController do
end
describe 'GET #calendar_activities' do
- let!(:project) { create(:empty_project) }
+ let!(:project) { create(:project) }
let(:user) { create(:user) }
before do
diff --git a/spec/factories/boards.rb b/spec/factories/boards.rb
index 4df9aef2846..1ec042a6ab4 100644
--- a/spec/factories/boards.rb
+++ b/spec/factories/boards.rb
@@ -1,6 +1,6 @@
FactoryGirl.define do
factory :board do
- project factory: :empty_project
+ project
after(:create) do |board|
board.lists.create(list_type: :closed)
diff --git a/spec/factories/ci/pipeline_schedule.rb b/spec/factories/ci/pipeline_schedule.rb
index a716da46ac6..564fef6833b 100644
--- a/spec/factories/ci/pipeline_schedule.rb
+++ b/spec/factories/ci/pipeline_schedule.rb
@@ -5,7 +5,7 @@ FactoryGirl.define do
ref 'master'
active true
description "pipeline schedule"
- project factory: :empty_project
+ project
trait :nightly do
cron '0 1 * * *'
diff --git a/spec/factories/ci/pipelines.rb b/spec/factories/ci/pipelines.rb
index 35803f0c37f..e83a0e599a8 100644
--- a/spec/factories/ci/pipelines.rb
+++ b/spec/factories/ci/pipelines.rb
@@ -5,7 +5,7 @@ FactoryGirl.define do
sha '97de212e80737a608d939f648d959671fb0a0142'
status 'pending'
- project factory: :empty_project
+ project
factory :ci_pipeline_without_jobs do
after(:build) do |pipeline|
diff --git a/spec/factories/ci/runner_projects.rb b/spec/factories/ci/runner_projects.rb
index 33a17cf7ed5..fa76d0ecd8c 100644
--- a/spec/factories/ci/runner_projects.rb
+++ b/spec/factories/ci/runner_projects.rb
@@ -1,6 +1,6 @@
FactoryGirl.define do
factory :ci_runner_project, class: Ci::RunnerProject do
runner factory: :ci_runner
- project factory: :empty_project
+ project
end
end
diff --git a/spec/factories/ci/variables.rb b/spec/factories/ci/variables.rb
index f83366136fd..d8fd513ffcf 100644
--- a/spec/factories/ci/variables.rb
+++ b/spec/factories/ci/variables.rb
@@ -7,6 +7,6 @@ FactoryGirl.define do
protected true
end
- project factory: :empty_project
+ project
end
end
diff --git a/spec/factories/commits.rb b/spec/factories/commits.rb
index 89e260cf65b..f4f12a095fc 100644
--- a/spec/factories/commits.rb
+++ b/spec/factories/commits.rb
@@ -3,7 +3,7 @@ require_relative '../support/repo_helpers'
FactoryGirl.define do
factory :commit do
git_commit RepoHelpers.sample_commit
- project factory: :empty_project
+ project
initialize_with do
new(git_commit, project)
diff --git a/spec/factories/conversational_development_index_metrics.rb b/spec/factories/conversational_development_index_metrics.rb
index a5412629195..3806c43ba15 100644
--- a/spec/factories/conversational_development_index_metrics.rb
+++ b/spec/factories/conversational_development_index_metrics.rb
@@ -2,32 +2,42 @@ FactoryGirl.define do
factory :conversational_development_index_metric, class: ConversationalDevelopmentIndex::Metric do
leader_issues 9.256
instance_issues 1.234
+ percentage_issues 13.331
leader_notes 30.33333
instance_notes 28.123
+ percentage_notes 92.713
leader_milestones 16.2456
instance_milestones 1.234
+ percentage_milestones 7.595
leader_boards 5.2123
instance_boards 3.254
+ percentage_boards 62.429
leader_merge_requests 1.2
instance_merge_requests 0.6
+ percentage_merge_requests 50.0
leader_ci_pipelines 12.1234
instance_ci_pipelines 2.344
+ percentage_ci_pipelines 19.334
leader_environments 3.3333
instance_environments 2.2222
+ percentage_environments 66.672
leader_deployments 1.200
instance_deployments 0.771
+ percentage_deployments 64.25
leader_projects_prometheus_active 0.111
instance_projects_prometheus_active 0.109
+ percentage_projects_prometheus_active 98.198
leader_service_desk_issues 15.891
instance_service_desk_issues 13.345
+ percentage_service_desk_issues 83.978
end
end
diff --git a/spec/factories/deploy_keys_projects.rb b/spec/factories/deploy_keys_projects.rb
index 75f8982ecd9..27cece487bd 100644
--- a/spec/factories/deploy_keys_projects.rb
+++ b/spec/factories/deploy_keys_projects.rb
@@ -1,6 +1,6 @@
FactoryGirl.define do
factory :deploy_keys_project do
deploy_key
- project factory: :empty_project
+ project
end
end
diff --git a/spec/factories/deployments.rb b/spec/factories/deployments.rb
index 29ad1af9fd9..e5abfd67d60 100644
--- a/spec/factories/deployments.rb
+++ b/spec/factories/deployments.rb
@@ -10,6 +10,10 @@ FactoryGirl.define do
after(:build) do |deployment, evaluator|
deployment.project ||= deployment.environment.project
+
+ unless deployment.project.repository_exists?
+ allow(deployment.project.repository).to receive(:fetch_ref)
+ end
end
end
end
diff --git a/spec/factories/environments.rb b/spec/factories/environments.rb
index d8d699fb3aa..9034476d094 100644
--- a/spec/factories/environments.rb
+++ b/spec/factories/environments.rb
@@ -2,12 +2,10 @@ FactoryGirl.define do
factory :environment, class: Environment do
sequence(:name) { |n| "environment#{n}" }
- project factory: :empty_project
+ association :project, :repository
sequence(:external_url) { |n| "https://env#{n}.example.gitlab.com" }
trait :with_review_app do |environment|
- project
-
transient do
ref 'master'
end
diff --git a/spec/factories/events.rb b/spec/factories/events.rb
index 55727d6b62c..ad9f7e2caef 100644
--- a/spec/factories/events.rb
+++ b/spec/factories/events.rb
@@ -1,7 +1,8 @@
FactoryGirl.define do
factory :event do
- project factory: :empty_project
+ project
author factory: :user
+ action Event::JOINED
trait(:created) { action Event::CREATED }
trait(:updated) { action Event::UPDATED }
@@ -20,4 +21,19 @@ FactoryGirl.define do
target factory: :closed_issue
end
end
+
+ factory :push_event, class: PushEvent do
+ project factory: :project_empty_repo
+ author factory: :user
+ action Event::PUSHED
+ end
+
+ factory :push_event_payload do
+ event
+ commit_count 1
+ action :pushed
+ ref_type :branch
+ ref 'master'
+ commit_to '3cdce97ed87c91368561584e7358f4d46e3e173c'
+ end
end
diff --git a/spec/factories/file_uploaders.rb b/spec/factories/file_uploaders.rb
index d397dd705a5..622571390d2 100644
--- a/spec/factories/file_uploaders.rb
+++ b/spec/factories/file_uploaders.rb
@@ -2,7 +2,7 @@ FactoryGirl.define do
factory :file_uploader do
skip_create
- project factory: :empty_project
+ project
secret nil
transient do
diff --git a/spec/factories/forked_project_links.rb b/spec/factories/forked_project_links.rb
index 66b0f248959..9b34651a4ae 100644
--- a/spec/factories/forked_project_links.rb
+++ b/spec/factories/forked_project_links.rb
@@ -1,7 +1,7 @@
FactoryGirl.define do
factory :forked_project_link do
- association :forked_to_project, factory: :project
- association :forked_from_project, factory: :project
+ association :forked_to_project, factory: [:project, :repository]
+ association :forked_from_project, factory: [:project, :repository]
after(:create) do |link|
link.forked_from_project.reload
@@ -9,7 +9,7 @@ FactoryGirl.define do
end
trait :forked_to_empty_project do
- association :forked_to_project, factory: :empty_project
+ association :forked_to_project, factory: [:project, :repository]
end
end
end
diff --git a/spec/factories/issues.rb b/spec/factories/issues.rb
index a16695cb7c1..7c3b80198f9 100644
--- a/spec/factories/issues.rb
+++ b/spec/factories/issues.rb
@@ -2,7 +2,7 @@ FactoryGirl.define do
factory :issue do
title { generate(:title) }
author
- project factory: :empty_project
+ project
trait :confidential do
confidential true
diff --git a/spec/factories/label_priorities.rb b/spec/factories/label_priorities.rb
index f25939d2d3e..7430466fc57 100644
--- a/spec/factories/label_priorities.rb
+++ b/spec/factories/label_priorities.rb
@@ -1,6 +1,6 @@
FactoryGirl.define do
factory :label_priority do
- project factory: :empty_project
+ project
label
sequence(:priority)
end
diff --git a/spec/factories/labels.rb b/spec/factories/labels.rb
index 22c2a1f15e2..416317d677b 100644
--- a/spec/factories/labels.rb
+++ b/spec/factories/labels.rb
@@ -5,7 +5,7 @@ FactoryGirl.define do
end
factory :label, traits: [:base_label], class: ProjectLabel do
- project factory: :empty_project
+ project
transient do
priority nil
diff --git a/spec/factories/merge_requests.rb b/spec/factories/merge_requests.rb
index 1bc530d06db..cbec716d6ea 100644
--- a/spec/factories/merge_requests.rb
+++ b/spec/factories/merge_requests.rb
@@ -68,6 +68,17 @@ FactoryGirl.define do
merge_user author
end
+ after(:build) do |merge_request|
+ target_project = merge_request.target_project
+ source_project = merge_request.source_project
+
+ # Fake `write_ref` if we don't have repository
+ # We have too many existing tests replying on this behaviour
+ unless [target_project, source_project].all?(&:repository_exists?)
+ allow(merge_request).to receive(:write_ref)
+ end
+ end
+
factory :merged_merge_request, traits: [:merged]
factory :closed_merge_request, traits: [:closed]
factory :reopened_merge_request, traits: [:opened]
diff --git a/spec/factories/milestones.rb b/spec/factories/milestones.rb
index 113665ff11b..2f75bf12cd7 100644
--- a/spec/factories/milestones.rb
+++ b/spec/factories/milestones.rb
@@ -17,7 +17,7 @@ FactoryGirl.define do
state "closed"
end
- after(:build) do |milestone, evaluator|
+ after(:build, :stub) do |milestone, evaluator|
if evaluator.group
milestone.group = evaluator.group
elsif evaluator.group_id
@@ -27,7 +27,7 @@ FactoryGirl.define do
elsif evaluator.project_id
milestone.project_id = evaluator.project_id
else
- milestone.project = create(:empty_project)
+ milestone.project = create(:project)
end
end
diff --git a/spec/factories/notes.rb b/spec/factories/notes.rb
index 046974dcd6e..f0d05504b7e 100644
--- a/spec/factories/notes.rb
+++ b/spec/factories/notes.rb
@@ -4,7 +4,7 @@ include ActionDispatch::TestProcess
FactoryGirl.define do
factory :note do
- project factory: :empty_project
+ project
note { generate(:title) }
author
on_issue
diff --git a/spec/factories/notification_settings.rb b/spec/factories/notification_settings.rb
index b5e96d18b8f..e9171528d86 100644
--- a/spec/factories/notification_settings.rb
+++ b/spec/factories/notification_settings.rb
@@ -1,8 +1,7 @@
FactoryGirl.define do
factory :notification_setting do
- source factory: :empty_project
+ source factory: :project
user
level 3
- events []
end
end
diff --git a/spec/factories/project_group_links.rb b/spec/factories/project_group_links.rb
index 50341d943f5..e73cc05f9d7 100644
--- a/spec/factories/project_group_links.rb
+++ b/spec/factories/project_group_links.rb
@@ -1,6 +1,6 @@
FactoryGirl.define do
factory :project_group_link do
- project factory: :empty_project
+ project
group
end
end
diff --git a/spec/factories/project_hooks.rb b/spec/factories/project_hooks.rb
index d754e980931..accae636a3a 100644
--- a/spec/factories/project_hooks.rb
+++ b/spec/factories/project_hooks.rb
@@ -2,7 +2,7 @@ FactoryGirl.define do
factory :project_hook do
url { generate(:url) }
enable_ssl_verification false
- project factory: :empty_project
+ project
trait :token do
token { SecureRandom.hex(10) }
diff --git a/spec/factories/project_members.rb b/spec/factories/project_members.rb
index fe4518caadf..9cf3a1e8e8a 100644
--- a/spec/factories/project_members.rb
+++ b/spec/factories/project_members.rb
@@ -1,7 +1,7 @@
FactoryGirl.define do
factory :project_member do
user
- project factory: :empty_project
+ project
master
trait(:guest) { access_level ProjectMember::GUEST }
diff --git a/spec/factories/project_wikis.rb b/spec/factories/project_wikis.rb
index ae222d5e69a..38fcab7466d 100644
--- a/spec/factories/project_wikis.rb
+++ b/spec/factories/project_wikis.rb
@@ -2,7 +2,7 @@ FactoryGirl.define do
factory :project_wiki do
skip_create
- project factory: :empty_project
+ project
user factory: :user
initialize_with { new(project, user) }
end
diff --git a/spec/factories/projects.rb b/spec/factories/projects.rb
index 485ed48d2de..4a2034b31b3 100644
--- a/spec/factories/projects.rb
+++ b/spec/factories/projects.rb
@@ -5,15 +5,50 @@ FactoryGirl.define do
#
# Project does not have bare repository.
# Use this factory if you don't need repository in tests
- factory :empty_project, class: 'Project' do
+ factory :project, class: 'Project' do
sequence(:name) { |n| "project#{n}" }
path { name.downcase.gsub(/\s/, '_') }
- namespace
- creator
-
# Behaves differently to nil due to cache_has_external_issue_tracker
has_external_issue_tracker false
+ # Associations
+ namespace
+ creator { group ? create(:user) : namespace&.owner }
+
+ # Nest Project Feature attributes
+ transient do
+ wiki_access_level ProjectFeature::ENABLED
+ builds_access_level ProjectFeature::ENABLED
+ snippets_access_level ProjectFeature::ENABLED
+ issues_access_level ProjectFeature::ENABLED
+ merge_requests_access_level ProjectFeature::ENABLED
+ repository_access_level ProjectFeature::ENABLED
+ end
+
+ after(:create) do |project, evaluator|
+ # Builds and MRs can't have higher visibility level than repository access level.
+ builds_access_level = [evaluator.builds_access_level, evaluator.repository_access_level].min
+ merge_requests_access_level = [evaluator.merge_requests_access_level, evaluator.repository_access_level].min
+
+ project.project_feature.update_columns(
+ wiki_access_level: evaluator.wiki_access_level,
+ builds_access_level: builds_access_level,
+ snippets_access_level: evaluator.snippets_access_level,
+ issues_access_level: evaluator.issues_access_level,
+ merge_requests_access_level: merge_requests_access_level,
+ repository_access_level: evaluator.repository_access_level)
+
+ # Normally the class Projects::CreateService is used for creating
+ # projects, and this class takes care of making sure the owner and current
+ # user have access to the project. Our specs don't use said service class,
+ # thus we must manually refresh things here.
+ unless project.group || project.pending_delete
+ project.add_master(project.owner)
+ end
+
+ project.group&.refresh_members_authorized_projects
+ end
+
trait :public do
visibility_level Gitlab::VisibilityLevel::PUBLIC
end
@@ -54,8 +89,46 @@ FactoryGirl.define do
avatar { File.open(Rails.root.join('spec/fixtures/dk.png')) }
end
+ trait :broken_storage do
+ after(:create) do |project|
+ project.update_column(:repository_storage, 'broken')
+ end
+ end
+
+ # Test repository - https://gitlab.com/gitlab-org/gitlab-test
trait :repository do
- # no-op... for now!
+ path { 'gitlabhq' }
+
+ test_repo
+
+ transient do
+ create_templates nil
+ end
+
+ after :create do |project, evaluator|
+ if evaluator.create_templates
+ templates_path = "#{evaluator.create_templates}_templates"
+
+ project.repository.create_file(
+ project.creator,
+ ".gitlab/#{templates_path}/bug.md",
+ 'something valid',
+ message: 'test 3',
+ branch_name: 'master')
+ project.repository.create_file(
+ project.creator,
+ ".gitlab/#{templates_path}/template_test.md",
+ 'template_test',
+ message: 'test 1',
+ branch_name: 'master')
+ project.repository.create_file(
+ project.creator,
+ ".gitlab/#{templates_path}/feature_proposal.md",
+ 'feature_proposal',
+ message: 'test 2',
+ branch_name: 'master')
+ end
+ end
end
trait :empty_repo do
@@ -64,7 +137,7 @@ FactoryGirl.define do
# We delete hooks so that gitlab-shell will not try to authenticate with
# an API that isn't running
- FileUtils.rm_r(File.join(project.repository_storage_path, "#{project.path_with_namespace}.git", 'hooks'))
+ FileUtils.rm_r(File.join(project.repository_storage_path, "#{project.disk_path}.git", 'hooks'))
end
end
@@ -72,7 +145,7 @@ FactoryGirl.define do
after(:create) do |project|
raise "Failed to create repository!" unless project.create_repository
- FileUtils.rm_r(File.join(project.repository_storage_path, "#{project.path_with_namespace}.git", 'refs'))
+ FileUtils.rm_r(File.join(project.repository_storage_path, "#{project.disk_path}.git", 'refs'))
end
end
@@ -102,103 +175,24 @@ FactoryGirl.define do
trait(:repository_enabled) { repository_access_level ProjectFeature::ENABLED }
trait(:repository_disabled) { repository_access_level ProjectFeature::DISABLED }
trait(:repository_private) { repository_access_level ProjectFeature::PRIVATE }
-
- # Nest Project Feature attributes
- transient do
- wiki_access_level ProjectFeature::ENABLED
- builds_access_level ProjectFeature::ENABLED
- snippets_access_level ProjectFeature::ENABLED
- issues_access_level ProjectFeature::ENABLED
- merge_requests_access_level ProjectFeature::ENABLED
- repository_access_level ProjectFeature::ENABLED
- end
-
- after(:create) do |project, evaluator|
- # Builds and MRs can't have higher visibility level than repository access level.
- builds_access_level = [evaluator.builds_access_level, evaluator.repository_access_level].min
- merge_requests_access_level = [evaluator.merge_requests_access_level, evaluator.repository_access_level].min
-
- project.project_feature
- .update_attributes!(
- wiki_access_level: evaluator.wiki_access_level,
- builds_access_level: builds_access_level,
- snippets_access_level: evaluator.snippets_access_level,
- issues_access_level: evaluator.issues_access_level,
- merge_requests_access_level: merge_requests_access_level,
- repository_access_level: evaluator.repository_access_level
- )
-
- # Normally the class Projects::CreateService is used for creating
- # projects, and this class takes care of making sure the owner and current
- # user have access to the project. Our specs don't use said service class,
- # thus we must manually refresh things here.
- owner = project.owner
-
- if owner && owner.is_a?(User) && !project.pending_delete
- project.members.create!(user: owner, access_level: Gitlab::Access::MASTER)
- end
-
- project.group&.refresh_members_authorized_projects
- end
end
# Project with empty repository
#
# This is a case when you just created a project
# but not pushed any code there yet
- factory :project_empty_repo, parent: :empty_project do
+ factory :project_empty_repo, parent: :project do
empty_repo
end
# Project with broken repository
#
# Project with an invalid repository state
- factory :project_broken_repo, parent: :empty_project do
+ factory :project_broken_repo, parent: :project do
broken_repo
end
- # Project with test repository
- #
- # Test repository source can be found at
- # https://gitlab.com/gitlab-org/gitlab-test
- factory :project, parent: :empty_project do
- path { 'gitlabhq' }
-
- test_repo
-
- transient do
- create_template nil
- end
-
- after :create do |project, evaluator|
- if evaluator.create_template
- args = evaluator.create_template
-
- project.add_user(args[:user], args[:access])
-
- project.repository.create_file(
- args[:user],
- ".gitlab/#{args[:path]}/bug.md",
- 'something valid',
- message: 'test 3',
- branch_name: 'master')
- project.repository.create_file(
- args[:user],
- ".gitlab/#{args[:path]}/template_test.md",
- 'template_test',
- message: 'test 1',
- branch_name: 'master')
- project.repository.create_file(
- args[:user],
- ".gitlab/#{args[:path]}/feature_proposal.md",
- 'feature_proposal',
- message: 'test 2',
- branch_name: 'master')
- end
- end
- end
-
- factory :forked_project_with_submodules, parent: :empty_project do
+ factory :forked_project_with_submodules, parent: :project do
path { 'forked-gitlabhq' }
after :create do |project|
@@ -228,11 +222,11 @@ FactoryGirl.define do
jira_service
end
- factory :kubernetes_project, parent: :empty_project do
+ factory :kubernetes_project, parent: :project do
kubernetes_service
end
- factory :prometheus_project, parent: :empty_project do
+ factory :prometheus_project, parent: :project do
after :create do |project|
project.create_prometheus_service(
active: true,
diff --git a/spec/factories/protected_branches.rb b/spec/factories/protected_branches.rb
index 3dbace4b38a..fe0cbfc4444 100644
--- a/spec/factories/protected_branches.rb
+++ b/spec/factories/protected_branches.rb
@@ -57,5 +57,11 @@ FactoryGirl.define do
protected_branch.merge_access_levels.new(access_level: Gitlab::Access::MASTER)
end
end
+
+ trait :no_one_can_merge do
+ after(:create) do |protected_branch|
+ protected_branch.merge_access_levels.first.update!(access_level: Gitlab::Access::NO_ACCESS)
+ end
+ end
end
end
diff --git a/spec/factories/releases.rb b/spec/factories/releases.rb
index 6a6d6fa171f..74497dc82c0 100644
--- a/spec/factories/releases.rb
+++ b/spec/factories/releases.rb
@@ -2,6 +2,6 @@ FactoryGirl.define do
factory :release do
tag "v1.1.0"
description "Awesome release"
- project factory: :empty_project
+ project
end
end
diff --git a/spec/factories/sent_notifications.rb b/spec/factories/sent_notifications.rb
index 99253be5a22..c2febf5b438 100644
--- a/spec/factories/sent_notifications.rb
+++ b/spec/factories/sent_notifications.rb
@@ -1,6 +1,6 @@
FactoryGirl.define do
factory :sent_notification do
- project factory: :empty_project
+ project
recipient factory: :user
noteable { create(:issue, project: project) }
reply_key { SentNotification.reply_key }
diff --git a/spec/factories/services.rb b/spec/factories/services.rb
index 30bc25cf88a..c2674ce2d11 100644
--- a/spec/factories/services.rb
+++ b/spec/factories/services.rb
@@ -1,11 +1,11 @@
FactoryGirl.define do
factory :service do
- project factory: :empty_project
+ project
type 'Service'
end
factory :custom_issue_tracker_service, class: CustomIssueTrackerService do
- project factory: :empty_project
+ project
type 'CustomIssueTrackerService'
category 'issue_tracker'
active true
@@ -17,7 +17,7 @@ FactoryGirl.define do
end
factory :kubernetes_service do
- project factory: :empty_project
+ project
active true
properties({
api_url: 'https://kubernetes.example.com',
@@ -26,7 +26,7 @@ FactoryGirl.define do
end
factory :prometheus_service do
- project factory: :empty_project
+ project
active true
properties({
api_url: 'https://prometheus.example.com/'
@@ -34,7 +34,7 @@ FactoryGirl.define do
end
factory :jira_service do
- project factory: :empty_project
+ project
active true
properties(
url: 'https://jira.example.com',
@@ -43,7 +43,7 @@ FactoryGirl.define do
end
factory :hipchat_service do
- project factory: :empty_project
+ project
type 'HipchatService'
token 'test_token'
end
diff --git a/spec/factories/snippets.rb b/spec/factories/snippets.rb
index f6ce99d50f9..075bccd7f94 100644
--- a/spec/factories/snippets.rb
+++ b/spec/factories/snippets.rb
@@ -20,7 +20,7 @@ FactoryGirl.define do
end
factory :project_snippet, parent: :snippet, class: :ProjectSnippet do
- project factory: :empty_project
+ project
end
factory :personal_snippet, parent: :snippet, class: :PersonalSnippet do
diff --git a/spec/factories/subscriptions.rb b/spec/factories/subscriptions.rb
index b11b0a0a17b..1ae7fc9f384 100644
--- a/spec/factories/subscriptions.rb
+++ b/spec/factories/subscriptions.rb
@@ -1,7 +1,7 @@
FactoryGirl.define do
factory :subscription do
user
- project factory: :empty_project
+ project
subscribable factory: :issue
end
end
diff --git a/spec/factories/todos.rb b/spec/factories/todos.rb
index c1ac3bb84ad..4975befbfe3 100644
--- a/spec/factories/todos.rb
+++ b/spec/factories/todos.rb
@@ -1,6 +1,6 @@
FactoryGirl.define do
factory :todo do
- project factory: :empty_project
+ project
author
user
target factory: :issue
@@ -45,7 +45,7 @@ FactoryGirl.define do
end
factory :on_commit_todo, class: Todo do
- project factory: :empty_project
+ project
author
user
action { Todo::ASSIGNED }
diff --git a/spec/factories/users.rb b/spec/factories/users.rb
index e60fe713bc3..4000cd085b7 100644
--- a/spec/factories/users.rb
+++ b/spec/factories/users.rb
@@ -1,5 +1,5 @@
FactoryGirl.define do
- factory :user, aliases: [:author, :assignee, :recipient, :owner, :creator, :resource_owner] do
+ factory :user, aliases: [:author, :assignee, :recipient, :owner, :resource_owner] do
email { generate(:email) }
name { generate(:name) }
username { generate(:username) }
@@ -8,6 +8,10 @@ FactoryGirl.define do
confirmation_token { nil }
can_create_group true
+ after(:stub) do |user|
+ user.notification_email = user.email
+ end
+
before(:create) do |user|
user.ensure_rss_token
end
diff --git a/spec/features/admin/admin_disables_git_access_protocol_spec.rb b/spec/features/admin/admin_disables_git_access_protocol_spec.rb
index 931f4ec3d24..9ea3cfa72c6 100644
--- a/spec/features/admin/admin_disables_git_access_protocol_spec.rb
+++ b/spec/features/admin/admin_disables_git_access_protocol_spec.rb
@@ -3,7 +3,7 @@ require 'rails_helper'
feature 'Admin disables Git access protocol' do
include StubENV
- let(:project) { create(:empty_project, :empty_repo) }
+ let(:project) { create(:project, :empty_repo) }
let(:admin) { create(:admin) }
background do
diff --git a/spec/features/admin/admin_groups_spec.rb b/spec/features/admin/admin_groups_spec.rb
index 2e1bfcdcec3..3768727d8ae 100644
--- a/spec/features/admin/admin_groups_spec.rb
+++ b/spec/features/admin/admin_groups_spec.rb
@@ -165,7 +165,7 @@ feature 'Admin Groups' do
describe 'shared projects' do
it 'renders shared project' do
- empty_project = create(:empty_project)
+ empty_project = create(:project)
empty_project.project_group_links.create!(
group_access: Gitlab::Access::MASTER,
group: group
diff --git a/spec/features/admin/admin_health_check_spec.rb b/spec/features/admin/admin_health_check_spec.rb
index 106e7370a98..37fd3e171eb 100644
--- a/spec/features/admin/admin_health_check_spec.rb
+++ b/spec/features/admin/admin_health_check_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-feature "Admin Health Check" do
+feature "Admin Health Check", feature: true, broken_storage: true do
include StubENV
before do
@@ -55,4 +55,26 @@ feature "Admin Health Check" do
expect(page).to have_content('The server is on fire')
end
end
+
+ context 'with repository storage failures' do
+ before do
+ # Track a failure
+ Gitlab::Git::Storage::CircuitBreaker.for_storage('broken').perform { nil } rescue nil
+ visit admin_health_check_path
+ end
+
+ it 'shows storage failure information' do
+ hostname = Gitlab::Environment.hostname
+
+ expect(page).to have_content('broken: failed storage access attempt on host:')
+ expect(page).to have_content("#{hostname}: 1 of 10 failures.")
+ end
+
+ it 'allows resetting storage failures' do
+ click_button 'Reset git storage health information'
+
+ expect(page).to have_content('Git storage health information has been reset')
+ expect(page).not_to have_content('failed storage access attempt')
+ end
+ end
end
diff --git a/spec/features/admin/admin_hook_logs_spec.rb b/spec/features/admin/admin_hook_logs_spec.rb
index 7910d5fb72b..710822ac042 100644
--- a/spec/features/admin/admin_hook_logs_spec.rb
+++ b/spec/features/admin/admin_hook_logs_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
feature 'Admin::HookLogs' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:system_hook) { create(:system_hook) }
let(:hook_log) { create(:web_hook_log, web_hook: system_hook, internal_error_message: 'some error') }
diff --git a/spec/features/admin/admin_hooks_spec.rb b/spec/features/admin/admin_hooks_spec.rb
index 141109fd464..30fcb334b60 100644
--- a/spec/features/admin/admin_hooks_spec.rb
+++ b/spec/features/admin/admin_hooks_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe 'Admin::Hooks' do
before do
- @project = create(:empty_project)
+ @project = create(:project)
sign_in(create(:admin))
@system_hook = create(:system_hook)
diff --git a/spec/features/admin/admin_projects_spec.rb b/spec/features/admin/admin_projects_spec.rb
index 4f69eafcb9d..77710f80036 100644
--- a/spec/features/admin/admin_projects_spec.rb
+++ b/spec/features/admin/admin_projects_spec.rb
@@ -4,7 +4,7 @@ describe "Admin::Projects" do
include Select2Helper
let(:user) { create :user }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:current_user) { create(:admin) }
before do
@@ -12,7 +12,7 @@ describe "Admin::Projects" do
end
describe "GET /admin/projects" do
- let!(:archived_project) { create :empty_project, :public, :archived }
+ let!(:archived_project) { create :project, :public, :archived }
before do
expect(project).to be_persisted
diff --git a/spec/features/admin/admin_runners_spec.rb b/spec/features/admin/admin_runners_spec.rb
index 46bab3763cc..e3bb16af38a 100644
--- a/spec/features/admin/admin_runners_spec.rb
+++ b/spec/features/admin/admin_runners_spec.rb
@@ -65,8 +65,8 @@ describe "Admin Runners" do
let(:runner) { FactoryGirl.create :ci_runner }
before do
- @project1 = FactoryGirl.create(:empty_project)
- @project2 = FactoryGirl.create(:empty_project)
+ @project1 = FactoryGirl.create(:project)
+ @project2 = FactoryGirl.create(:project)
visit admin_runner_path(runner)
end
diff --git a/spec/features/admin/admin_settings_spec.rb b/spec/features/admin/admin_settings_spec.rb
index c1eced417cf..5db42175c15 100644
--- a/spec/features/admin/admin_settings_spec.rb
+++ b/spec/features/admin/admin_settings_spec.rb
@@ -35,6 +35,7 @@ feature 'Admin updates settings' do
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'
+ uncheck 'Project export enabled'
click_button 'Save'
expect(current_application_settings.gravatar_enabled).to be_falsey
@@ -42,6 +43,7 @@ feature 'Admin updates settings' do
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(current_application_settings.project_export_enabled).to be_falsey
expect(page).to have_content "Application settings saved successfully"
end
@@ -69,6 +71,14 @@ feature 'Admin updates settings' do
expect(find('#service_push_channel').value).to eq '#test_channel'
end
+ context 'sign-in restrictions', :js do
+ it 'de-activates oauth sign-in source' do
+ find('.btn', text: 'GitLab.com').click
+
+ expect(find('.btn', text: 'GitLab.com')).not_to have_css('.active')
+ end
+ end
+
def check_all_events
page.check('Active')
page.check('Push')
diff --git a/spec/features/admin/admin_users_impersonation_tokens_spec.rb b/spec/features/admin/admin_users_impersonation_tokens_spec.rb
index 97ffc54415c..034682dae27 100644
--- a/spec/features/admin/admin_users_impersonation_tokens_spec.rb
+++ b/spec/features/admin/admin_users_impersonation_tokens_spec.rb
@@ -32,11 +32,13 @@ describe 'Admin > Users > Impersonation Tokens', js: true do
check "api"
check "read_user"
- expect { click_on "Create impersonation token" }.to change { PersonalAccessTokensFinder.new(impersonation: true).execute.count }
+ click_on "Create impersonation token"
+
expect(active_impersonation_tokens).to have_text(name)
expect(active_impersonation_tokens).to have_text('In')
expect(active_impersonation_tokens).to have_text('api')
expect(active_impersonation_tokens).to have_text('read_user')
+ expect(PersonalAccessTokensFinder.new(impersonation: true).execute.count).to equal(1)
end
end
diff --git a/spec/features/admin/admin_users_spec.rb b/spec/features/admin/admin_users_spec.rb
index 0dde8bb696c..e2e2b13cf8a 100644
--- a/spec/features/admin/admin_users_spec.rb
+++ b/spec/features/admin/admin_users_spec.rb
@@ -257,7 +257,7 @@ describe "Admin::Users" do
describe "GET /admin/users/:id/projects" do
let(:group) { create(:group) }
- let!(:project) { create(:empty_project, group: group) }
+ let!(:project) { create(:project, group: group) }
before do
group.add_developer(user)
diff --git a/spec/features/admin/admin_uses_repository_checks_spec.rb b/spec/features/admin/admin_uses_repository_checks_spec.rb
index 5b3ee6ee822..c2b7543a690 100644
--- a/spec/features/admin/admin_uses_repository_checks_spec.rb
+++ b/spec/features/admin/admin_uses_repository_checks_spec.rb
@@ -9,7 +9,7 @@ feature 'Admin uses repository checks' do
end
scenario 'to trigger a single check' do
- project = create(:empty_project)
+ project = create(:project)
visit_admin_project_page(project)
page.within('.repository-check') do
@@ -20,7 +20,7 @@ feature 'Admin uses repository checks' do
end
scenario 'to see a single failed repository check' do
- project = create(:empty_project)
+ project = create(:project)
project.update_columns(
last_repository_check_failed: true,
last_repository_check_at: Time.now
diff --git a/spec/features/atom/dashboard_issues_spec.rb b/spec/features/atom/dashboard_issues_spec.rb
index d70da7f09e9..5aae2dbaf91 100644
--- a/spec/features/atom/dashboard_issues_spec.rb
+++ b/spec/features/atom/dashboard_issues_spec.rb
@@ -4,8 +4,8 @@ describe "Dashboard Issues Feed" do
describe "GET /issues" do
let!(:user) { create(:user, email: 'private1@example.com', public_email: 'public1@example.com') }
let!(:assignee) { create(:user, email: 'private2@example.com', public_email: 'public2@example.com') }
- let!(:project1) { create(:empty_project) }
- let!(:project2) { create(:empty_project) }
+ let!(:project1) { create(:project) }
+ let!(:project2) { create(:project) }
before do
project1.team << [user, :master]
diff --git a/spec/features/atom/dashboard_spec.rb b/spec/features/atom/dashboard_spec.rb
index a7c12853981..321c8a2a670 100644
--- a/spec/features/atom/dashboard_spec.rb
+++ b/spec/features/atom/dashboard_spec.rb
@@ -19,7 +19,7 @@ describe "Dashboard Feed" do
end
context 'feed content' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:issue) { create(:issue, project: project, author: user, description: '') }
let(:note) { create(:note, noteable: issue, author: user, note: 'Bug confirmed', project: project) }
diff --git a/spec/features/atom/issues_spec.rb b/spec/features/atom/issues_spec.rb
index 59e20d7e24d..3eeb4d35131 100644
--- a/spec/features/atom/issues_spec.rb
+++ b/spec/features/atom/issues_spec.rb
@@ -5,7 +5,7 @@ describe 'Issues Feed' do
let!(:user) { create(:user, email: 'private1@example.com', public_email: 'public1@example.com') }
let!(:assignee) { create(:user, email: 'private2@example.com', public_email: 'public2@example.com') }
let!(:group) { create(:group) }
- let!(:project) { create(:empty_project) }
+ let!(:project) { create(:project) }
let!(:issue) { create(:issue, author: user, assignees: [assignee], project: project) }
before do
diff --git a/spec/features/boards/add_issues_modal_spec.rb b/spec/features/boards/add_issues_modal_spec.rb
index c87469696da..a6ad5981f8f 100644
--- a/spec/features/boards/add_issues_modal_spec.rb
+++ b/spec/features/boards/add_issues_modal_spec.rb
@@ -1,7 +1,7 @@
require 'rails_helper'
describe 'Issue Boards add issue modal', :js do
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:board) { create(:board, project: project) }
let(:user) { create(:user) }
let!(:planning) { create(:label, project: project, name: 'Planning') }
diff --git a/spec/features/boards/boards_spec.rb b/spec/features/boards/boards_spec.rb
index c3711c9b2c5..ce458431c55 100644
--- a/spec/features/boards/boards_spec.rb
+++ b/spec/features/boards/boards_spec.rb
@@ -4,7 +4,7 @@ describe 'Issue Boards', js: true do
include DragTo
let(:group) { create(:group, :nested) }
- let(:project) { create(:empty_project, :public, namespace: group) }
+ let(:project) { create(:project, :public, namespace: group) }
let(:board) { create(:board, project: project) }
let(:user) { create(:user) }
let!(:user2) { create(:user) }
@@ -233,7 +233,7 @@ describe 'Issue Boards', js: true do
wait_for_board_cards(4, 1)
expect(find('.board:nth-child(3)')).to have_content(issue6.title)
- expect(find('.board:nth-child(3)').all('.card').last).not_to have_content(development.title)
+ expect(find('.board:nth-child(3)').all('.card').last).to have_content(development.title)
end
it 'issue moves between lists' do
@@ -244,7 +244,7 @@ describe 'Issue Boards', js: true do
wait_for_board_cards(4, 1)
expect(find('.board:nth-child(2)')).to have_content(issue7.title)
- expect(find('.board:nth-child(2)').all('.card').first).not_to have_content(planning.title)
+ expect(find('.board:nth-child(2)').all('.card').first).to have_content(planning.title)
end
it 'issue moves from closed' do
diff --git a/spec/features/boards/issue_ordering_spec.rb b/spec/features/boards/issue_ordering_spec.rb
index f4be56a4463..4cbb48e2e6e 100644
--- a/spec/features/boards/issue_ordering_spec.rb
+++ b/spec/features/boards/issue_ordering_spec.rb
@@ -3,7 +3,7 @@ require 'rails_helper'
describe 'Issue Boards', :js do
include DragTo
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:board) { create(:board, project: project) }
let(:user) { create(:user) }
let(:label) { create(:label, project: project) }
diff --git a/spec/features/boards/keyboard_shortcut_spec.rb b/spec/features/boards/keyboard_shortcut_spec.rb
index 415eda0e058..61b53aa5d1e 100644
--- a/spec/features/boards/keyboard_shortcut_spec.rb
+++ b/spec/features/boards/keyboard_shortcut_spec.rb
@@ -1,7 +1,7 @@
require 'rails_helper'
describe 'Issue Boards shortcut', js: true do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
before do
create(:board, project: project)
diff --git a/spec/features/boards/modal_filter_spec.rb b/spec/features/boards/modal_filter_spec.rb
index 1c8b9c46569..422d96175f7 100644
--- a/spec/features/boards/modal_filter_spec.rb
+++ b/spec/features/boards/modal_filter_spec.rb
@@ -1,7 +1,7 @@
require 'rails_helper'
describe 'Issue Boards add issue modal filtering', :js do
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:board) { create(:board, project: project) }
let(:planning) { create(:label, project: project, name: 'Planning') }
let!(:list1) { create(:list, board: board, label: planning, position: 0) }
diff --git a/spec/features/boards/new_issue_spec.rb b/spec/features/boards/new_issue_spec.rb
index 1dbe3dbda11..f67372337ec 100644
--- a/spec/features/boards/new_issue_spec.rb
+++ b/spec/features/boards/new_issue_spec.rb
@@ -1,7 +1,7 @@
require 'rails_helper'
describe 'Issue Boards new issue', js: true do
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:board) { create(:board, project: project) }
let!(:list) { create(:list, board: board, position: 0) }
let(:user) { create(:user) }
diff --git a/spec/features/boards/sidebar_spec.rb b/spec/features/boards/sidebar_spec.rb
index 3f58fe1c32c..c3bf50ef9d1 100644
--- a/spec/features/boards/sidebar_spec.rb
+++ b/spec/features/boards/sidebar_spec.rb
@@ -3,7 +3,7 @@ require 'rails_helper'
describe 'Issue Boards', js: true do
let(:user) { create(:user) }
let(:user2) { create(:user) }
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let!(:milestone) { create(:milestone, project: project) }
let!(:development) { create(:label, project: project, name: 'Development') }
let!(:bug) { create(:label, project: project, name: 'Bug') }
@@ -15,10 +15,12 @@ describe 'Issue Boards', js: true do
let!(:list) { create(:list, board: board, label: development, position: 0) }
let(:card) { find('.board:nth-child(2)').first('.card') }
- before do
- Timecop.freeze
+ around do |example|
+ Timecop.freeze { example.run }
+ end
- project.team << [user, :master]
+ before do
+ project.add_master(user)
sign_in(user)
@@ -26,10 +28,6 @@ describe 'Issue Boards', js: true do
wait_for_requests
end
- after do
- Timecop.return
- end
-
it 'shows sidebar when clicking issue' do
click_card(card)
@@ -257,7 +255,7 @@ describe 'Issue Boards', js: true do
end
end
- expect(card).to have_selector('.label', count: 2)
+ expect(card).to have_selector('.label', count: 3)
expect(card).to have_content(bug.title)
end
@@ -283,7 +281,7 @@ describe 'Issue Boards', js: true do
end
end
- expect(card).to have_selector('.label', count: 3)
+ expect(card).to have_selector('.label', count: 4)
expect(card).to have_content(bug.title)
expect(card).to have_content(regression.title)
end
@@ -308,7 +306,7 @@ describe 'Issue Boards', js: true do
end
end
- expect(card).not_to have_selector('.label')
+ expect(card).to have_selector('.label', count: 1)
expect(card).not_to have_content(stretch.title)
end
end
diff --git a/spec/features/boards/sub_group_project_spec.rb b/spec/features/boards/sub_group_project_spec.rb
index f54f2234203..11a54079f4f 100644
--- a/spec/features/boards/sub_group_project_spec.rb
+++ b/spec/features/boards/sub_group_project_spec.rb
@@ -3,7 +3,7 @@ require 'rails_helper'
describe 'Sub-group project issue boards', :js do
let(:group) { create(:group) }
let(:nested_group_1) { create(:group, parent: group) }
- let(:project) { create(:empty_project, group: nested_group_1) }
+ let(:project) { create(:project, group: nested_group_1) }
let(:board) { create(:board, project: project) }
let(:label) { create(:label, project: project) }
let(:user) { create(:user) }
diff --git a/spec/features/calendar_spec.rb b/spec/features/calendar_spec.rb
index 1e7fd7b62bd..9a597a2d690 100644
--- a/spec/features/calendar_spec.rb
+++ b/spec/features/calendar_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
feature 'Contributions Calendar', :js do
let(:user) { create(:user) }
- let(:contributed_project) { create(:empty_project, :public) }
+ let(:contributed_project) { create(:project, :public) }
let(:issue_note) { create(:note, project: contributed_project) }
# Ex/ Sunday Jan 1, 2016
@@ -42,14 +42,14 @@ feature 'Contributions Calendar', :js do
end
def push_code_contribution
- push_params = {
- project: contributed_project,
- action: Event::PUSHED,
- author_id: user.id,
- data: { commit_count: 3 }
- }
-
- Event.create(push_params)
+ event = create(:push_event, project: contributed_project, author: user)
+
+ create(:push_event_payload,
+ event: event,
+ commit_from: '11f9ac0a48b62cef25eedede4c1819964f08d5ce',
+ commit_to: '1cf19a015df3523caf0a1f9d40c98a267d6a2fc2',
+ commit_count: 3,
+ ref: 'master')
end
def note_comment_contribution
diff --git a/spec/features/commits_spec.rb b/spec/features/commits_spec.rb
index 15ec6f20763..0c9fcc60d30 100644
--- a/spec/features/commits_spec.rb
+++ b/spec/features/commits_spec.rb
@@ -282,7 +282,7 @@ describe 'Commits' do
end
# verified and the gpg user has a gitlab profile
- click_on 'Verified'
+ click_on 'Verified', match: :first
within '.popover' do
expect(page).to have_content 'This commit was signed with a verified signature.'
expect(page).to have_content 'Nannie Bernhard'
@@ -295,7 +295,7 @@ describe 'Commits' do
visit project_commits_path(project, :'signed-commits')
- click_on 'Verified'
+ click_on 'Verified', match: :first
within '.popover' do
expect(page).to have_content 'This commit was signed with a verified signature.'
expect(page).to have_content 'Nannie Bernhard'
diff --git a/spec/features/container_registry_spec.rb b/spec/features/container_registry_spec.rb
index 8f59ce3d2e7..ae39ba4da6b 100644
--- a/spec/features/container_registry_spec.rb
+++ b/spec/features/container_registry_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe "Container Registry" do
let(:user) { create(:user) }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:container_repository) do
create(:container_repository, name: 'my/image')
diff --git a/spec/features/cycle_analytics_spec.rb b/spec/features/cycle_analytics_spec.rb
index 5c60cca10b9..bfe9dac3bd4 100644
--- a/spec/features/cycle_analytics_spec.rb
+++ b/spec/features/cycle_analytics_spec.rb
@@ -24,6 +24,12 @@ feature 'Cycle Analytics', js: true do
expect(page).to have_content('Introducing Cycle Analytics')
end
+ it 'shows pipeline summary' do
+ expect(new_issues_counter).to have_content('-')
+ expect(commits_counter).to have_content('-')
+ expect(deploys_counter).to have_content('-')
+ end
+
it 'shows active stage with empty message' do
expect(page).to have_selector('.stage-nav-item.active', text: 'Issue')
expect(page).to have_content("We don't have enough data to show this stage.")
@@ -42,6 +48,12 @@ feature 'Cycle Analytics', js: true do
visit project_cycle_analytics_path(project)
end
+ it 'shows pipeline summary' do
+ expect(new_issues_counter).to have_content('1')
+ expect(commits_counter).to have_content('2')
+ expect(deploys_counter).to have_content('1')
+ end
+
it 'shows data on each stage' do
expect_issue_to_be_present
@@ -63,6 +75,20 @@ feature 'Cycle Analytics', js: true do
click_stage('Production')
expect_issue_to_be_present
end
+
+ context "when I change the time period observed" do
+ before do
+ _two_weeks_old_issue = create(:issue, project: project, created_at: 2.weeks.ago)
+
+ click_button('Last 30 days')
+ click_link('Last 7 days')
+ wait_for_requests
+ end
+
+ it 'shows only relevant data' do
+ expect(new_issues_counter).to have_content('1')
+ end
+ end
end
context "when my preferred language is Spanish" do
@@ -109,6 +135,18 @@ feature 'Cycle Analytics', js: true do
end
end
+ def new_issues_counter
+ find(:xpath, "//p[contains(text(),'New Issue')]/preceding-sibling::h3")
+ end
+
+ def commits_counter
+ find(:xpath, "//p[contains(text(),'Commits')]/preceding-sibling::h3")
+ end
+
+ def deploys_counter
+ find(:xpath, "//p[contains(text(),'Deploy')]/preceding-sibling::h3")
+ end
+
def expect_issue_to_be_present
expect(find('.stage-events')).to have_content(issue.title)
expect(find('.stage-events')).to have_content(issue.author.name)
diff --git a/spec/features/dashboard/activity_spec.rb b/spec/features/dashboard/activity_spec.rb
index a96270c9147..582868bac1e 100644
--- a/spec/features/dashboard/activity_spec.rb
+++ b/spec/features/dashboard/activity_spec.rb
@@ -17,33 +17,25 @@ feature 'Dashboard > Activity' do
end
context 'event filters', :js do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:merge_request) do
create(:merge_request, author: user, source_project: project, target_project: project)
end
- let(:push_event_data) do
- {
- before: Gitlab::Git::BLANK_SHA,
- after: '0220c11b9a3e6c69dc8fd35321254ca9a7b98f7e',
- ref: 'refs/heads/new_design',
- user_id: user.id,
- user_name: user.name,
- repository: {
- name: project.name,
- url: 'localhost/rubinius',
- description: '',
- homepage: 'localhost/rubinius',
- private: true
- }
- }
- end
-
let(:note) { create(:note, project: project, noteable: merge_request) }
let!(:push_event) do
- create(:event, :pushed, data: push_event_data, project: project, author: user)
+ event = create(:push_event, project: project, author: user)
+
+ create(:push_event_payload,
+ event: event,
+ action: :created,
+ commit_to: '0220c11b9a3e6c69dc8fd35321254ca9a7b98f7e',
+ ref: 'new_design',
+ commit_count: 1)
+
+ event
end
let!(:merged_event) do
diff --git a/spec/features/dashboard/archived_projects_spec.rb b/spec/features/dashboard/archived_projects_spec.rb
index ceac6a0a27c..814ec0e59c7 100644
--- a/spec/features/dashboard/archived_projects_spec.rb
+++ b/spec/features/dashboard/archived_projects_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
RSpec.describe 'Dashboard Archived Project' do
let(:user) { create :user }
let(:project) { create :project}
- let(:archived_project) { create(:empty_project, :archived) }
+ let(:archived_project) { create(:project, :archived) }
before do
project.team << [user, :master]
diff --git a/spec/features/dashboard/datetime_on_tooltips_spec.rb b/spec/features/dashboard/datetime_on_tooltips_spec.rb
index 05dcdd93f37..b6dce1b8ec4 100644
--- a/spec/features/dashboard/datetime_on_tooltips_spec.rb
+++ b/spec/features/dashboard/datetime_on_tooltips_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
feature 'Tooltips on .timeago dates', js: true do
let(:user) { create(:user) }
- let(:project) { create(:empty_project, name: 'test', namespace: user.namespace) }
+ let(:project) { create(:project, name: 'test', namespace: user.namespace) }
let(:created_date) { Date.yesterday.to_time }
let(:expected_format) { created_date.in_time_zone.strftime('%b %-d, %Y %l:%M%P') }
diff --git a/spec/features/dashboard/issuables_counter_spec.rb b/spec/features/dashboard/issuables_counter_spec.rb
index ae68b0f65d5..b431f72fcc9 100644
--- a/spec/features/dashboard/issuables_counter_spec.rb
+++ b/spec/features/dashboard/issuables_counter_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe 'Navigation bar counter', :use_clean_rails_memory_store_caching do
let(:user) { create(:user) }
- let(:project) { create(:empty_project, namespace: user.namespace) }
+ let(:project) { create(:project, namespace: user.namespace) }
let(:issue) { create(:issue, project: project) }
let(:merge_request) { create(:merge_request, source_project: project) }
diff --git a/spec/features/dashboard/issues_filter_spec.rb b/spec/features/dashboard/issues_filter_spec.rb
index 0ce642f32f2..facb67ae787 100644
--- a/spec/features/dashboard/issues_filter_spec.rb
+++ b/spec/features/dashboard/issues_filter_spec.rb
@@ -4,7 +4,7 @@ feature 'Dashboard Issues filtering', :js do
include SortingHelper
let(:user) { create(:user) }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:milestone) { create(:milestone, project: project) }
let!(:issue) { create(:issue, project: project, author: user, assignees: [user]) }
diff --git a/spec/features/dashboard/issues_spec.rb b/spec/features/dashboard/issues_spec.rb
index 82adde6258f..795335aa106 100644
--- a/spec/features/dashboard/issues_spec.rb
+++ b/spec/features/dashboard/issues_spec.rb
@@ -3,9 +3,9 @@ require 'spec_helper'
RSpec.describe 'Dashboard Issues' do
let(:current_user) { create :user }
let(:user) { current_user } # Shared examples depend on this being available
- let!(:public_project) { create(:empty_project, :public) }
- let(:project) { create(:empty_project) }
- let(:project_with_issues_disabled) { create(:empty_project, :issues_disabled) }
+ let!(:public_project) { create(:project, :public) }
+ let(:project) { create(:project) }
+ let(:project_with_issues_disabled) { create(:project, :issues_disabled) }
let!(:authored_issue) { create :issue, author: current_user, project: project }
let!(:authored_issue_on_public_project) { create :issue, author: current_user, project: public_project }
let!(:assigned_issue) { create :issue, assignees: [current_user], project: project }
@@ -79,12 +79,21 @@ RSpec.describe 'Dashboard Issues' do
end
end
- it 'shows the new issue page', :js do
+ it 'shows the new issue page', js: true do
find('.new-project-item-select-button').trigger('click')
+
wait_for_requests
- find('.select2-results li').click
- expect(page).to have_current_path("/#{project.path_with_namespace}/issues/new")
+ project_path = "/#{project.path_with_namespace}"
+ project_json = { name: project.name_with_namespace, url: project_path }.to_json
+
+ # similate selection, and prevent overlap by dropdown menu
+ execute_script("$('.project-item-select').val('#{project_json}').trigger('change');")
+ execute_script("$('#select2-drop-mask').remove();")
+
+ find('.new-project-item-link').trigger('click')
+
+ expect(page).to have_current_path("#{project_path}/issues/new")
page.within('#content-body') do
expect(page).to have_selector('.issue-form')
diff --git a/spec/features/dashboard/label_filter_spec.rb b/spec/features/dashboard/label_filter_spec.rb
index 8e19fb93665..b1a207682c3 100644
--- a/spec/features/dashboard/label_filter_spec.rb
+++ b/spec/features/dashboard/label_filter_spec.rb
@@ -2,8 +2,8 @@ require 'spec_helper'
describe 'Dashboard > label filter', js: true do
let(:user) { create(:user) }
- let(:project) { create(:empty_project, name: 'test', namespace: user.namespace) }
- let(:project2) { create(:empty_project, name: 'test2', path: 'test2', namespace: user.namespace) }
+ let(:project) { create(:project, name: 'test', namespace: user.namespace) }
+ let(:project2) { create(:project, name: 'test2', path: 'test2', namespace: user.namespace) }
let(:label) { create(:label, title: 'bug', color: '#ff0000') }
let(:label2) { create(:label, title: 'bug') }
diff --git a/spec/features/dashboard/merge_requests_spec.rb b/spec/features/dashboard/merge_requests_spec.rb
index 42d6fadc0c1..b4992dd54a1 100644
--- a/spec/features/dashboard/merge_requests_spec.rb
+++ b/spec/features/dashboard/merge_requests_spec.rb
@@ -5,9 +5,9 @@ feature 'Dashboard Merge Requests' do
include SortingHelper
let(:current_user) { create :user }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
- let(:public_project) { create(:empty_project, :public, :repository) }
+ let(:public_project) { create(:project, :public, :repository) }
let(:forked_project) { Projects::ForkService.new(public_project, current_user).execute }
before do
@@ -16,7 +16,7 @@ feature 'Dashboard Merge Requests' do
end
context 'new merge request dropdown' do
- let(:project_with_disabled_merge_requests) { create(:empty_project, :merge_requests_disabled) }
+ let(:project_with_disabled_merge_requests) { create(:project, :merge_requests_disabled) }
before do
project_with_disabled_merge_requests.add_master(current_user)
diff --git a/spec/features/dashboard/milestone_filter_spec.rb b/spec/features/dashboard/milestone_filter_spec.rb
index 5ebef1eb097..c965b565ca3 100644
--- a/spec/features/dashboard/milestone_filter_spec.rb
+++ b/spec/features/dashboard/milestone_filter_spec.rb
@@ -4,7 +4,7 @@ feature 'Dashboard > milestone filter', :js do
include FilterItemSelectHelper
let(:user) { create(:user) }
- let(:project) { create(:empty_project, name: 'test', namespace: user.namespace) }
+ let(:project) { create(:project, name: 'test', namespace: user.namespace) }
let(:milestone) { create(:milestone, title: 'v1.0', project: project) }
let(:milestone2) { create(:milestone, title: 'v2.0', project: project) }
let!(:issue) { create :issue, author: user, project: project, milestone: milestone }
diff --git a/spec/features/dashboard/milestone_tabs_spec.rb b/spec/features/dashboard/milestone_tabs_spec.rb
index cf32d705365..6fcde35f541 100644
--- a/spec/features/dashboard/milestone_tabs_spec.rb
+++ b/spec/features/dashboard/milestone_tabs_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe 'Dashboard milestone tabs', :js do
let(:user) { create(:user) }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let!(:label) { create(:label, project: project) }
let(:project_milestone) { create(:milestone, project: project) }
let(:milestone) do
diff --git a/spec/features/dashboard/milestones_spec.rb b/spec/features/dashboard/milestones_spec.rb
index 488f7397c69..41d37376cfb 100644
--- a/spec/features/dashboard/milestones_spec.rb
+++ b/spec/features/dashboard/milestones_spec.rb
@@ -13,7 +13,7 @@ feature 'Dashboard > Milestones' do
describe 'as logged-in user' do
let(:user) { create(:user) }
- let(:project) { create(:empty_project, namespace: user.namespace) }
+ let(:project) { create(:project, namespace: user.namespace) }
let!(:milestone) { create(:milestone, project: project) }
before do
project.team << [user, :master]
diff --git a/spec/features/dashboard/project_member_activity_index_spec.rb b/spec/features/dashboard/project_member_activity_index_spec.rb
index f3b538e490e..4a004107408 100644
--- a/spec/features/dashboard/project_member_activity_index_spec.rb
+++ b/spec/features/dashboard/project_member_activity_index_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
feature 'Project member activity', js: true do
let(:user) { create(:user) }
- let(:project) { create(:empty_project, :public, name: 'x', namespace: user.namespace) }
+ let(:project) { create(:project, :public, name: 'x', namespace: user.namespace) }
before do
project.team << [user, :master]
diff --git a/spec/features/dashboard/projects_spec.rb b/spec/features/dashboard/projects_spec.rb
index abb9e5eef96..06a43909053 100644
--- a/spec/features/dashboard/projects_spec.rb
+++ b/spec/features/dashboard/projects_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
feature 'Dashboard Projects' do
let(:user) { create(:user) }
- let(:project) { create(:project, name: 'awesome stuff') }
+ let(:project) { create(:project, :repository, name: 'awesome stuff') }
let(:project2) { create(:project, :public, name: 'Community project') }
before do
diff --git a/spec/features/dashboard/snippets_spec.rb b/spec/features/dashboard/snippets_spec.rb
index c29bcc7c9e9..fb4263d74c4 100644
--- a/spec/features/dashboard/snippets_spec.rb
+++ b/spec/features/dashboard/snippets_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe 'Dashboard snippets' do
context 'when the project has snippets' do
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let!(:snippets) { create_list(:project_snippet, 2, :public, author: project.owner, project: project) }
before do
allow(Snippet).to receive(:default_per_page).and_return(1)
diff --git a/spec/features/dashboard/todos/target_state_spec.rb b/spec/features/dashboard/todos/target_state_spec.rb
index 93da36c08fc..030a86d1c01 100644
--- a/spec/features/dashboard/todos/target_state_spec.rb
+++ b/spec/features/dashboard/todos/target_state_spec.rb
@@ -3,7 +3,7 @@ require 'rails_helper'
feature 'Dashboard > Todo target states' do
let(:user) { create(:user) }
let(:author) { create(:user) }
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
before do
sign_in(user)
diff --git a/spec/features/dashboard/todos/todos_filtering_spec.rb b/spec/features/dashboard/todos/todos_filtering_spec.rb
index 0a363259fe7..54d477f7274 100644
--- a/spec/features/dashboard/todos/todos_filtering_spec.rb
+++ b/spec/features/dashboard/todos/todos_filtering_spec.rb
@@ -4,8 +4,8 @@ feature 'Dashboard > User filters todos', js: true do
let(:user_1) { create(:user, username: 'user_1', name: 'user_1') }
let(:user_2) { create(:user, username: 'user_2', name: 'user_2') }
- let(:project_1) { create(:empty_project, name: 'project_1') }
- let(:project_2) { create(:empty_project, name: 'project_2') }
+ let(:project_1) { create(:project, name: 'project_1') }
+ let(:project_2) { create(:project, name: 'project_2') }
let(:issue) { create(:issue, title: 'issue', project: project_1) }
diff --git a/spec/features/dashboard/todos/todos_sorting_spec.rb b/spec/features/dashboard/todos/todos_sorting_spec.rb
index d49a78b290f..b7d39a872b0 100644
--- a/spec/features/dashboard/todos/todos_sorting_spec.rb
+++ b/spec/features/dashboard/todos/todos_sorting_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
feature 'Dashboard > User sorts todos' do
let(:user) { create(:user) }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:label_1) { create(:label, title: 'label_1', project: project, priority: 1) }
let(:label_2) { create(:label, title: 'label_2', project: project, priority: 2) }
diff --git a/spec/features/dashboard/todos/todos_spec.rb b/spec/features/dashboard/todos/todos_spec.rb
index c2a61cf5aff..30bab7eeaa7 100644
--- a/spec/features/dashboard/todos/todos_spec.rb
+++ b/spec/features/dashboard/todos/todos_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
feature 'Dashboard Todos' do
let(:user) { create(:user) }
let(:author) { create(:user) }
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:issue) { create(:issue, due_date: Date.today) }
context 'User does not have todos' do
@@ -212,7 +212,7 @@ feature 'Dashboard Todos' do
note1 = create(:note_on_issue, note: "Hello #{label1.to_reference(format: :name)}", noteable_id: issue.id, noteable_type: 'Issue', project: issue.project)
create(:todo, :mentioned, project: project, target: issue, user: user, note_id: note1.id)
- project2 = create(:empty_project, :public)
+ project2 = create(:project, :public)
label2 = create(:label, project: project2)
issue2 = create(:issue, project: project2)
note2 = create(:note_on_issue, note: "Test #{label2.to_reference(format: :name)}", noteable_id: issue2.id, noteable_type: 'Issue', project: project2)
diff --git a/spec/features/dashboard/user_filters_projects_spec.rb b/spec/features/dashboard/user_filters_projects_spec.rb
index a88fe207e0e..c352b6ded14 100644
--- a/spec/features/dashboard/user_filters_projects_spec.rb
+++ b/spec/features/dashboard/user_filters_projects_spec.rb
@@ -2,9 +2,9 @@ require 'spec_helper'
describe 'Dashboard > User filters projects' do
let(:user) { create(:user) }
- let(:project) { create(:empty_project, name: 'Victorialand', namespace: user.namespace) }
+ let(:project) { create(:project, name: 'Victorialand', namespace: user.namespace) }
let(:user2) { create(:user) }
- let(:project2) { create(:empty_project, name: 'Treasure', namespace: user2.namespace) }
+ let(:project2) { create(:project, name: 'Treasure', namespace: user2.namespace) }
before do
project.team << [user, :master]
diff --git a/spec/features/discussion_comments/commit_spec.rb b/spec/features/discussion_comments/commit_spec.rb
index fa83ad5d17c..0375d0bf8ff 100644
--- a/spec/features/discussion_comments/commit_spec.rb
+++ b/spec/features/discussion_comments/commit_spec.rb
@@ -4,7 +4,7 @@ describe 'Discussion Comments Merge Request', :js do
include RepoHelpers
let(:user) { create(:user) }
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:merge_request) { create(:merge_request, source_project: project) }
before do
diff --git a/spec/features/discussion_comments/issue_spec.rb b/spec/features/discussion_comments/issue_spec.rb
index f52ba9c4d09..9812eaf3420 100644
--- a/spec/features/discussion_comments/issue_spec.rb
+++ b/spec/features/discussion_comments/issue_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe 'Discussion Comments Issue', :js do
let(:user) { create(:user) }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:issue) { create(:issue, project: project) }
before do
diff --git a/spec/features/discussion_comments/merge_request_spec.rb b/spec/features/discussion_comments/merge_request_spec.rb
index 042f39f47e0..b0019c32189 100644
--- a/spec/features/discussion_comments/merge_request_spec.rb
+++ b/spec/features/discussion_comments/merge_request_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe 'Discussion Comments Merge Request', :js do
let(:user) { create(:user) }
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:merge_request) { create(:merge_request, source_project: project) }
before do
diff --git a/spec/features/discussion_comments/snippets_spec.rb b/spec/features/discussion_comments/snippets_spec.rb
index 50ba13499d9..1e6389d9a13 100644
--- a/spec/features/discussion_comments/snippets_spec.rb
+++ b/spec/features/discussion_comments/snippets_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe 'Discussion Comments Issue', :js do
let(:user) { create(:user) }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:snippet) { create(:project_snippet, :private, project: project, author: user) }
before do
diff --git a/spec/features/explore/groups_list_spec.rb b/spec/features/explore/groups_list_spec.rb
index 84f41eca999..b5325301968 100644
--- a/spec/features/explore/groups_list_spec.rb
+++ b/spec/features/explore/groups_list_spec.rb
@@ -5,7 +5,7 @@ describe 'Explore Groups page', :js do
let!(:group) { create(:group) }
let!(:public_group) { create(:group, :public) }
let!(:private_group) { create(:group, :private) }
- let!(:empty_project) { create(:empty_project, group: public_group) }
+ let!(:empty_project) { create(:project, group: public_group) }
before do
group.add_owner(user)
diff --git a/spec/features/explore/new_menu_spec.rb b/spec/features/explore/new_menu_spec.rb
index b1ccf80c28e..2cd06258e22 100644
--- a/spec/features/explore/new_menu_spec.rb
+++ b/spec/features/explore/new_menu_spec.rb
@@ -4,7 +4,7 @@ feature 'Top Plus Menu', :js do
let(:user) { create(:user) }
let(:group) { create(:group) }
let(:project) { create(:project, :repository, creator: user, namespace: user.namespace) }
- let(:public_project) { create(:empty_project, :public) }
+ let(:public_project) { create(:project, :public) }
before do
group.add_owner(user)
diff --git a/spec/features/gitlab_flavored_markdown_spec.rb b/spec/features/gitlab_flavored_markdown_spec.rb
index 300296a2b94..53b3bb3b65f 100644
--- a/spec/features/gitlab_flavored_markdown_spec.rb
+++ b/spec/features/gitlab_flavored_markdown_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe "GitLab Flavored Markdown" do
let(:user) { create(:user) }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:issue) { create(:issue, project: project) }
let(:fred) do
create(:user, name: 'fred') do |user|
diff --git a/spec/features/global_search_spec.rb b/spec/features/global_search_spec.rb
index 627a930c997..f04e13adba7 100644
--- a/spec/features/global_search_spec.rb
+++ b/spec/features/global_search_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
feature 'Global search' do
let(:user) { create(:user) }
- let(:project) { create(:empty_project, namespace: user.namespace) }
+ let(:project) { create(:project, namespace: user.namespace) }
before do
project.team << [user, :master]
diff --git a/spec/features/groups/empty_states_spec.rb b/spec/features/groups/empty_states_spec.rb
index e2c7907528b..243e8536168 100644
--- a/spec/features/groups/empty_states_spec.rb
+++ b/spec/features/groups/empty_states_spec.rb
@@ -9,7 +9,7 @@ feature 'Groups Merge Requests Empty States' do
end
context 'group has a project' do
- let(:project) { create(:empty_project, namespace: group) }
+ let(:project) { create(:project, namespace: group) }
before do
project.add_master(user)
@@ -38,7 +38,7 @@ feature 'Groups Merge Requests Empty States' do
it 'should show a new merge request button' do
within '.empty-state' do
- expect(page).to have_content('New merge request')
+ expect(page).to have_content('create merge request')
end
end
@@ -63,7 +63,7 @@ feature 'Groups Merge Requests Empty States' do
it 'should not show a new merge request button' do
within '.empty-state' do
- expect(page).not_to have_link('New merge request')
+ expect(page).not_to have_link('create merge request')
end
end
end
diff --git a/spec/features/groups/group_settings_spec.rb b/spec/features/groups/group_settings_spec.rb
index 121df1ec635..d0316cfb18d 100644
--- a/spec/features/groups/group_settings_spec.rb
+++ b/spec/features/groups/group_settings_spec.rb
@@ -49,7 +49,7 @@ feature 'Edit group settings' do
end
context 'with a project' do
- given!(:project) { create(:empty_project, group: group) }
+ given!(:project) { create(:project, group: group) }
given(:old_project_full_path) { "/#{group.path}/#{project.path}" }
given(:new_project_full_path) { "/#{new_group_path}/#{project.path}" }
@@ -57,7 +57,7 @@ feature 'Edit group settings' do
TestEnv.clean_test_path
end
- after(:example) do
+ after do
TestEnv.clean_test_path
end
diff --git a/spec/features/groups/issues_spec.rb b/spec/features/groups/issues_spec.rb
index 449a99a2c7b..cdf7aceb13c 100644
--- a/spec/features/groups/issues_spec.rb
+++ b/spec/features/groups/issues_spec.rb
@@ -1,6 +1,8 @@
require 'spec_helper'
feature 'Group issues page' do
+ include FilteredSearchHelpers
+
let(:path) { issues_group_path(group) }
let(:issuable) { create(:issue, project: project, title: "this is my created issuable")}
@@ -31,12 +33,10 @@ feature 'Group issues page' do
let(:path) { issues_group_path(group) }
it 'filters by only group users' do
- click_button('Assignee')
-
- wait_for_requests
+ filtered_search.set('assignee:')
- expect(find('.dropdown-menu-assignee')).to have_link(user.name)
- expect(find('.dropdown-menu-assignee')).not_to have_link(user2.name)
+ expect(find('#js-dropdown-assignee .filter-dropdown')).to have_content(user.name)
+ expect(find('#js-dropdown-assignee .filter-dropdown')).not_to have_content(user2.name)
end
end
end
diff --git a/spec/features/groups/members/request_access_spec.rb b/spec/features/groups/members/request_access_spec.rb
index 6141981023c..1f3c7fd3859 100644
--- a/spec/features/groups/members/request_access_spec.rb
+++ b/spec/features/groups/members/request_access_spec.rb
@@ -4,7 +4,7 @@ feature 'Groups > Members > Request access' do
let(:user) { create(:user) }
let(:owner) { create(:user) }
let(:group) { create(:group, :public, :access_requestable) }
- let!(:project) { create(:empty_project, :private, namespace: group) }
+ let!(:project) { create(:project, :private, namespace: group) }
background do
group.add_owner(owner)
diff --git a/spec/features/groups/milestone_spec.rb b/spec/features/groups/milestone_spec.rb
index 574bbe0e0e1..32b3e13c624 100644
--- a/spec/features/groups/milestone_spec.rb
+++ b/spec/features/groups/milestone_spec.rb
@@ -5,14 +5,12 @@ feature 'Group milestones', :js do
let!(:project) { create(:project_empty_repo, group: group) }
let(:user) { create(:group_member, :master, user: create(:user), group: group ).user }
- before do
- Timecop.freeze
-
- sign_in(user)
+ around do |example|
+ Timecop.freeze { example.run }
end
- after do
- Timecop.return
+ before do
+ sign_in(user)
end
context 'create a milestone' do
diff --git a/spec/features/issuables/close_reopen_report_toggle_spec.rb b/spec/features/issuables/close_reopen_report_toggle_spec.rb
index 0e43eed8699..3df77a104e8 100644
--- a/spec/features/issuables/close_reopen_report_toggle_spec.rb
+++ b/spec/features/issuables/close_reopen_report_toggle_spec.rb
@@ -42,7 +42,7 @@ describe 'Issuables Close/Reopen/Report toggle' do
end
context 'on an issue' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:issuable) { create(:issue, project: project) }
before do
@@ -59,7 +59,7 @@ describe 'Issuables Close/Reopen/Report toggle' do
end
context 'when user doesnt have permission to update' do
- let(:cant_project) { create(:empty_project) }
+ let(:cant_project) { create(:project) }
let(:cant_issuable) { create(:issue, project: cant_project) }
before do
diff --git a/spec/features/issuables/default_sort_order_spec.rb b/spec/features/issuables/default_sort_order_spec.rb
index 7c20c96528e..b72b690110f 100644
--- a/spec/features/issuables/default_sort_order_spec.rb
+++ b/spec/features/issuables/default_sort_order_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe 'Projects > Issuables > Default sort order' do
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:first_created_issuable) { issuables.order_created_asc.first }
let(:last_created_issuable) { issuables.order_created_desc.first }
diff --git a/spec/features/issuables/issuable_list_spec.rb b/spec/features/issuables/issuable_list_spec.rb
index 557de721222..2f45ef856a5 100644
--- a/spec/features/issuables/issuable_list_spec.rb
+++ b/spec/features/issuables/issuable_list_spec.rb
@@ -1,7 +1,7 @@
require 'rails_helper'
describe 'issuable list' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:user) { create(:user) }
issuable_types = [:issue, :merge_request]
diff --git a/spec/features/issuables/markdown_references_spec.rb b/spec/features/issuables/markdown_references_spec.rb
index 169381d703a..dd4e10a9886 100644
--- a/spec/features/issuables/markdown_references_spec.rb
+++ b/spec/features/issuables/markdown_references_spec.rb
@@ -2,10 +2,10 @@ require 'rails_helper'
describe 'Markdown References', :js do
let(:user) { create(:user) }
- let(:actual_project) { create(:project, :public) }
+ let(:actual_project) { create(:project, :public, :repository) }
let(:merge_request) { create(:merge_request, target_project: actual_project, source_project: actual_project)}
let(:issue_actual_project) { create(:issue, project: actual_project) }
- let!(:other_project) { create(:empty_project, :public) }
+ let!(:other_project) { create(:project, :public) }
let!(:issue_other_project) { create(:issue, project: other_project) }
let(:issues) { [issue_actual_project, issue_other_project] }
diff --git a/spec/features/issues/award_emoji_spec.rb b/spec/features/issues/award_emoji_spec.rb
index 6cb0bf6fdfd..134e618feac 100644
--- a/spec/features/issues/award_emoji_spec.rb
+++ b/spec/features/issues/award_emoji_spec.rb
@@ -1,7 +1,7 @@
require 'rails_helper'
describe 'Awards Emoji' do
- let!(:project) { create(:empty_project, :public) }
+ let!(:project) { create(:project, :public) }
let!(:user) { create(:user) }
let(:issue) do
create(:issue,
diff --git a/spec/features/issues/award_spec.rb b/spec/features/issues/award_spec.rb
index 740281c1050..e95eb19f7d1 100644
--- a/spec/features/issues/award_spec.rb
+++ b/spec/features/issues/award_spec.rb
@@ -2,7 +2,7 @@ require 'rails_helper'
feature 'Issue awards', js: true do
let(:user) { create(:user) }
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:issue) { create(:issue, project: project) }
describe 'logged in' do
diff --git a/spec/features/issues/bulk_assignment_labels_spec.rb b/spec/features/issues/bulk_assignment_labels_spec.rb
index 5acf8fdae84..b2229b44f99 100644
--- a/spec/features/issues/bulk_assignment_labels_spec.rb
+++ b/spec/features/issues/bulk_assignment_labels_spec.rb
@@ -2,7 +2,7 @@ require 'rails_helper'
feature 'Issues > Labels bulk assignment' do
let(:user) { create(:user) }
- let!(:project) { create(:empty_project) }
+ let!(:project) { create(:project) }
let!(:issue1) { create(:issue, project: project, title: "Issue 1") }
let!(:issue2) { create(:issue, project: project, title: "Issue 2") }
let!(:bug) { create(:label, project: project, title: 'bug') }
@@ -353,7 +353,7 @@ feature 'Issues > Labels bulk assignment' do
context 'cannot bulk assign labels' do
it do
- expect(page).not_to have_button 'Edit Issues'
+ expect(page).not_to have_button 'Edit issues'
expect(page).not_to have_css '.check-all-issues'
expect(page).not_to have_css '.issue-check'
end
@@ -411,7 +411,7 @@ feature 'Issues > Labels bulk assignment' do
def enable_bulk_update
visit project_issues_path(project)
- click_button 'Edit Issues'
+ click_button 'Edit issues'
end
def disable_bulk_update
diff --git a/spec/features/issues/create_branch_merge_request_spec.rb b/spec/features/issues/create_branch_merge_request_spec.rb
index f59f687cf51..546dc7e8a49 100644
--- a/spec/features/issues/create_branch_merge_request_spec.rb
+++ b/spec/features/issues/create_branch_merge_request_spec.rb
@@ -1,6 +1,6 @@
require 'rails_helper'
-feature 'Create Branch/Merge Request Dropdown on issue page', js: true do
+feature 'Create Branch/Merge Request Dropdown on issue page', :feature, :js do
let(:user) { create(:user) }
let!(:project) { create(:project, :repository) }
let(:issue) { create(:issue, project: project, title: 'Cherry-Coloured Funk') }
@@ -14,10 +14,14 @@ feature 'Create Branch/Merge Request Dropdown on issue page', js: true do
it 'allows creating a merge request from the issue page' do
visit project_issue_path(project, issue)
- select_dropdown_option('create-mr')
-
- expect(page).to have_content('WIP: Resolve "Cherry-Coloured Funk"')
- expect(current_path).to eq(project_merge_request_path(project, MergeRequest.first))
+ perform_enqueued_jobs do
+ select_dropdown_option('create-mr')
+
+ expect(page).to have_content('WIP: Resolve "Cherry-Coloured Funk"')
+ expect(current_path).to eq(project_merge_request_path(project, MergeRequest.first))
+
+ wait_for_requests
+ end
visit project_issue_path(project, issue)
diff --git a/spec/features/issues/filtered_search/dropdown_assignee_spec.rb b/spec/features/issues/filtered_search/dropdown_assignee_spec.rb
index a403d885de0..a69bd8a09b7 100644
--- a/spec/features/issues/filtered_search/dropdown_assignee_spec.rb
+++ b/spec/features/issues/filtered_search/dropdown_assignee_spec.rb
@@ -3,7 +3,7 @@ require 'rails_helper'
describe 'Dropdown assignee', :js do
include FilteredSearchHelpers
- let!(:project) { create(:empty_project) }
+ let!(:project) { create(:project) }
let!(:user) { create(:user, name: 'administrator', username: 'root') }
let!(:user_john) { create(:user, name: 'John', username: 'th0mas') }
let!(:user_jacob) { create(:user, name: 'Jacob', username: 'otter32') }
diff --git a/spec/features/issues/filtered_search/dropdown_author_spec.rb b/spec/features/issues/filtered_search/dropdown_author_spec.rb
index b7d9bbd7e1d..4bbf18e1dbe 100644
--- a/spec/features/issues/filtered_search/dropdown_author_spec.rb
+++ b/spec/features/issues/filtered_search/dropdown_author_spec.rb
@@ -3,7 +3,7 @@ require 'rails_helper'
describe 'Dropdown author', js: true do
include FilteredSearchHelpers
- let!(:project) { create(:empty_project) }
+ let!(:project) { create(:project) }
let!(:user) { create(:user, name: 'administrator', username: 'root') }
let!(:user_john) { create(:user, name: 'John', username: 'th0mas') }
let!(:user_jacob) { create(:user, name: 'Jacob', username: 'otter32') }
diff --git a/spec/features/issues/filtered_search/dropdown_hint_spec.rb b/spec/features/issues/filtered_search/dropdown_hint_spec.rb
index 292fd683271..04d6dea4b8c 100644
--- a/spec/features/issues/filtered_search/dropdown_hint_spec.rb
+++ b/spec/features/issues/filtered_search/dropdown_hint_spec.rb
@@ -3,7 +3,7 @@ require 'rails_helper'
describe 'Dropdown hint', :js do
include FilteredSearchHelpers
- let!(:project) { create(:empty_project) }
+ let!(:project) { create(:project) }
let!(:user) { create(:user) }
let(:filtered_search) { find('.filtered-search') }
let(:js_dropdown_hint) { '#js-dropdown-hint' }
diff --git a/spec/features/issues/filtered_search/dropdown_label_spec.rb b/spec/features/issues/filtered_search/dropdown_label_spec.rb
index e8f005d7752..67eb0ef0119 100644
--- a/spec/features/issues/filtered_search/dropdown_label_spec.rb
+++ b/spec/features/issues/filtered_search/dropdown_label_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe 'Dropdown label', js: true do
include FilteredSearchHelpers
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:user) { create(:user) }
let(:filtered_search) { find('.filtered-search') }
let(:js_dropdown_label) { '#js-dropdown-label' }
diff --git a/spec/features/issues/filtered_search/dropdown_milestone_spec.rb b/spec/features/issues/filtered_search/dropdown_milestone_spec.rb
index ace73f4b1a6..456eb05f241 100644
--- a/spec/features/issues/filtered_search/dropdown_milestone_spec.rb
+++ b/spec/features/issues/filtered_search/dropdown_milestone_spec.rb
@@ -3,7 +3,7 @@ require 'rails_helper'
describe 'Dropdown milestone', :js do
include FilteredSearchHelpers
- let!(:project) { create(:empty_project) }
+ let!(:project) { create(:project) }
let!(:user) { create(:user) }
let!(:milestone) { create(:milestone, title: 'v1.0', project: project) }
let!(:uppercase_milestone) { create(:milestone, title: 'CAP_MILESTONE', project: project) }
diff --git a/spec/features/issues/filtered_search/filter_issues_spec.rb b/spec/features/issues/filtered_search/filter_issues_spec.rb
index 265bcb3a8e5..cd2cbf4bfe7 100644
--- a/spec/features/issues/filtered_search/filter_issues_spec.rb
+++ b/spec/features/issues/filtered_search/filter_issues_spec.rb
@@ -5,7 +5,7 @@ describe 'Filter issues', js: true do
include FilteredSearchHelpers
let!(:group) { create(:group) }
- let!(:project) { create(:empty_project, group: group) }
+ let!(:project) { create(:project, group: group) }
let!(:user) { create(:user, username: 'joe', name: 'Joe') }
let!(:user2) { create(:user, username: 'jane') }
let!(:label) { create(:label, project: project) }
diff --git a/spec/features/issues/filtered_search/recent_searches_spec.rb b/spec/features/issues/filtered_search/recent_searches_spec.rb
index 5842bb22beb..5eeecaeda47 100644
--- a/spec/features/issues/filtered_search/recent_searches_spec.rb
+++ b/spec/features/issues/filtered_search/recent_searches_spec.rb
@@ -3,8 +3,8 @@ require 'spec_helper'
describe 'Recent searches', js: true do
include FilteredSearchHelpers
- let(:project_1) { create(:empty_project, :public) }
- let(:project_2) { create(:empty_project, :public) }
+ let(:project_1) { create(:project, :public) }
+ let(:project_2) { create(:project, :public) }
let(:project_1_local_storage_key) { "#{project_1.full_path}-issue-recent-searches" }
before do
diff --git a/spec/features/issues/filtered_search/search_bar_spec.rb b/spec/features/issues/filtered_search/search_bar_spec.rb
index 115875d72ce..aa9d0d842de 100644
--- a/spec/features/issues/filtered_search/search_bar_spec.rb
+++ b/spec/features/issues/filtered_search/search_bar_spec.rb
@@ -3,7 +3,7 @@ require 'rails_helper'
describe 'Search bar', js: true do
include FilteredSearchHelpers
- let!(:project) { create(:empty_project) }
+ let!(:project) { create(:project) }
let!(:user) { create(:user) }
let(:filtered_search) { find('.filtered-search') }
diff --git a/spec/features/issues/filtered_search/visual_tokens_spec.rb b/spec/features/issues/filtered_search/visual_tokens_spec.rb
index d00d0a9c81b..52efe944b69 100644
--- a/spec/features/issues/filtered_search/visual_tokens_spec.rb
+++ b/spec/features/issues/filtered_search/visual_tokens_spec.rb
@@ -4,7 +4,7 @@ describe 'Visual tokens', js: true do
include FilteredSearchHelpers
include WaitForRequests
- let!(:project) { create(:empty_project) }
+ let!(:project) { create(:project) }
let!(:user) { create(:user, name: 'administrator', username: 'root') }
let!(:user_rock) { create(:user, name: 'The Rock', username: 'rock') }
let!(:milestone_nine) { create(:milestone, title: '9.0', project: project) }
diff --git a/spec/features/issues/form_spec.rb b/spec/features/issues/form_spec.rb
index 0ba02ba42ba..4297bfff3d9 100644
--- a/spec/features/issues/form_spec.rb
+++ b/spec/features/issues/form_spec.rb
@@ -4,7 +4,7 @@ describe 'New/edit issue', :js do
include ActionView::Helpers::JavaScriptHelper
include FormHelper
- let!(:project) { create(:empty_project) }
+ let!(:project) { create(:project) }
let!(:user) { create(:user)}
let!(:user2) { create(:user)}
let!(:milestone) { create(:milestone, project: project) }
@@ -276,7 +276,7 @@ describe 'New/edit issue', :js do
describe 'sub-group project' do
let(:group) { create(:group) }
let(:nested_group_1) { create(:group, parent: group) }
- let(:sub_group_project) { create(:empty_project, group: nested_group_1) }
+ let(:sub_group_project) { create(:project, group: nested_group_1) }
before do
sub_group_project.add_master(user)
diff --git a/spec/features/issues/gfm_autocomplete_spec.rb b/spec/features/issues/gfm_autocomplete_spec.rb
index 1b36f16e8b6..b84635c5134 100644
--- a/spec/features/issues/gfm_autocomplete_spec.rb
+++ b/spec/features/issues/gfm_autocomplete_spec.rb
@@ -2,7 +2,7 @@ require 'rails_helper'
feature 'GFM autocomplete', js: true do
let(:user) { create(:user, name: '💃speciąl someone💃', username: 'someone.special') }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:label) { create(:label, project: project, title: 'special+') }
let(:issue) { create(:issue, project: project) }
diff --git a/spec/features/issues/group_label_sidebar_spec.rb b/spec/features/issues/group_label_sidebar_spec.rb
index a8ac1d605cb..9c10f78f67a 100644
--- a/spec/features/issues/group_label_sidebar_spec.rb
+++ b/spec/features/issues/group_label_sidebar_spec.rb
@@ -3,7 +3,7 @@ require 'rails_helper'
describe 'Group label on issue' do
it 'renders link to the project issues page' do
group = create(:group)
- project = create(:empty_project, :public, namespace: group)
+ project = create(:project, :public, namespace: group)
feature = create(:group_label, group: group, title: 'feature')
issue = create(:labeled_issue, project: project, labels: [feature])
label_link = project_issues_path(project, label_name: [feature.name])
diff --git a/spec/features/issues/issue_detail_spec.rb b/spec/features/issues/issue_detail_spec.rb
index a7a7e02b59c..28b636f9359 100644
--- a/spec/features/issues/issue_detail_spec.rb
+++ b/spec/features/issues/issue_detail_spec.rb
@@ -2,7 +2,7 @@ require 'rails_helper'
feature 'Issue Detail', :js do
let(:user) { create(:user) }
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:issue) { create(:issue, project: project, author: user) }
context 'when user displays the issue' do
diff --git a/spec/features/issues/issue_sidebar_spec.rb b/spec/features/issues/issue_sidebar_spec.rb
index 28f93cfd971..af11b474842 100644
--- a/spec/features/issues/issue_sidebar_spec.rb
+++ b/spec/features/issues/issue_sidebar_spec.rb
@@ -4,7 +4,7 @@ feature 'Issue Sidebar' do
include MobileHelpers
let(:group) { create(:group, :nested) }
- let(:project) { create(:empty_project, :public, namespace: group) }
+ let(:project) { create(:project, :public, namespace: group) }
let(:issue) { create(:issue, project: project) }
let!(:user) { create(:user)}
let!(:label) { create(:label, project: project, title: 'bug') }
@@ -130,8 +130,8 @@ feature 'Issue Sidebar' do
it 'adds new label' do
page.within('.block.labels') do
fill_in 'new_label_name', with: 'wontfix'
- page.find(".suggest-colors a", match: :first).click
- click_button 'Create'
+ page.find('.suggest-colors a', match: :first).trigger('click')
+ page.find('button', text: 'Create').trigger('click')
page.within('.dropdown-page-one') do
expect(page).to have_content 'wontfix'
@@ -142,8 +142,8 @@ feature 'Issue Sidebar' do
it 'shows error message if label title is taken' do
page.within('.block.labels') do
fill_in 'new_label_name', with: label.title
- page.find('.suggest-colors a', match: :first).click
- click_button 'Create'
+ page.find('.suggest-colors a', match: :first).trigger('click')
+ page.find('button', text: 'Create').trigger('click')
page.within('.dropdown-page-two') do
expect(page).to have_content 'Title has already been taken'
diff --git a/spec/features/issues/markdown_toolbar_spec.rb b/spec/features/issues/markdown_toolbar_spec.rb
index 0f869970460..8c23fcd483b 100644
--- a/spec/features/issues/markdown_toolbar_spec.rb
+++ b/spec/features/issues/markdown_toolbar_spec.rb
@@ -1,7 +1,7 @@
require 'rails_helper'
feature 'Issue markdown toolbar', js: true do
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:issue) { create(:issue, project: project) }
let(:user) { create(:user) }
diff --git a/spec/features/issues/move_spec.rb b/spec/features/issues/move_spec.rb
index 2ab7d1a71b7..494c309c9ea 100644
--- a/spec/features/issues/move_spec.rb
+++ b/spec/features/issues/move_spec.rb
@@ -25,8 +25,8 @@ feature 'issue move to another project' do
context 'user has permission to move issue' do
let!(:mr) { create(:merge_request, source_project: old_project) }
- let(:new_project) { create(:empty_project) }
- let(:new_project_search) { create(:empty_project) }
+ let(:new_project) { create(:project) }
+ let(:new_project_search) { create(:project) }
let(:text) { "Text with #{mr.to_reference}" }
let(:cross_reference) { old_project.to_reference(new_project) }
@@ -63,8 +63,8 @@ feature 'issue move to another project' do
end
context 'user does not have permission to move the issue to a project', js: true do
- let!(:private_project) { create(:empty_project, :private) }
- let(:another_project) { create(:empty_project) }
+ let!(:private_project) { create(:project, :private) }
+ let(:another_project) { create(:project) }
background { another_project.team << [user, :guest] }
scenario 'browsing projects in projects select' do
diff --git a/spec/features/issues/note_polling_spec.rb b/spec/features/issues/note_polling_spec.rb
index b524260750e..62dbc3efb01 100644
--- a/spec/features/issues/note_polling_spec.rb
+++ b/spec/features/issues/note_polling_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
feature 'Issue notes polling', :js do
include NoteInteractionHelpers
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:issue) { create(:issue, project: project) }
describe 'creates' do
@@ -133,8 +133,6 @@ feature 'Issue notes polling', :js do
def click_edit_action(note)
note_element = find("#note_#{note.id}")
- open_more_actions_dropdown(note)
-
note_element.find('.js-note-edit').click
end
end
diff --git a/spec/features/issues/notes_on_issues_spec.rb b/spec/features/issues/notes_on_issues_spec.rb
index 29c9b99030a..05c93a19253 100644
--- a/spec/features/issues/notes_on_issues_spec.rb
+++ b/spec/features/issues/notes_on_issues_spec.rb
@@ -35,21 +35,21 @@ describe 'Create notes on issues', :js do
context 'mentioning issue on a private project' do
it_behaves_like 'notes with reference' do
- let(:project) { create(:empty_project, :private) }
+ let(:project) { create(:project, :private) }
let(:mention) { create(:issue, project: project) }
end
end
context 'mentioning issue on an internal project' do
it_behaves_like 'notes with reference' do
- let(:project) { create(:empty_project, :internal) }
+ let(:project) { create(:project, :internal) }
let(:mention) { create(:issue, project: project) }
end
end
context 'mentioning issue on a public project' do
it_behaves_like 'notes with reference' do
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:mention) { create(:issue, project: project) }
end
end
diff --git a/spec/features/issues/spam_issues_spec.rb b/spec/features/issues/spam_issues_spec.rb
index 7a05e8b2ccc..332ce78b138 100644
--- a/spec/features/issues/spam_issues_spec.rb
+++ b/spec/features/issues/spam_issues_spec.rb
@@ -3,7 +3,7 @@ require 'rails_helper'
describe 'New issue', js: true do
include StubENV
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:user) { create(:user)}
before do
diff --git a/spec/features/issues/todo_spec.rb b/spec/features/issues/todo_spec.rb
index 2460ae817f9..8405f1cd48d 100644
--- a/spec/features/issues/todo_spec.rb
+++ b/spec/features/issues/todo_spec.rb
@@ -1,7 +1,7 @@
require 'rails_helper'
feature 'Manually create a todo item from issue', js: true do
- let!(:project) { create(:empty_project) }
+ let!(:project) { create(:project) }
let!(:issue) { create(:issue, project: project) }
let!(:user) { create(:user)}
diff --git a/spec/features/issues/update_issues_spec.rb b/spec/features/issues/update_issues_spec.rb
index 389151e63f0..bcc6e9bab0f 100644
--- a/spec/features/issues/update_issues_spec.rb
+++ b/spec/features/issues/update_issues_spec.rb
@@ -1,7 +1,7 @@
require 'rails_helper'
feature 'Multiple issue updating from issues#index', :js do
- let!(:project) { create(:empty_project) }
+ let!(:project) { create(:project) }
let!(:issue) { create(:issue, project: project) }
let!(:user) { create(:user)}
@@ -14,7 +14,7 @@ feature 'Multiple issue updating from issues#index', :js do
it 'sets to closed' do
visit project_issues_path(project)
- click_button 'Edit Issues'
+ click_button 'Edit issues'
find('#check-all-issues').click
find('.js-issue-status').click
@@ -27,7 +27,7 @@ feature 'Multiple issue updating from issues#index', :js do
create_closed
visit project_issues_path(project, state: 'closed')
- click_button 'Edit Issues'
+ click_button 'Edit issues'
find('#check-all-issues').click
find('.js-issue-status').click
@@ -41,7 +41,7 @@ feature 'Multiple issue updating from issues#index', :js do
it 'updates to current user' do
visit project_issues_path(project)
- click_button 'Edit Issues'
+ click_button 'Edit issues'
find('#check-all-issues').click
click_update_assignee_button
@@ -57,7 +57,7 @@ feature 'Multiple issue updating from issues#index', :js do
create_assigned
visit project_issues_path(project)
- click_button 'Edit Issues'
+ click_button 'Edit issues'
find('#check-all-issues').click
click_update_assignee_button
@@ -73,7 +73,7 @@ feature 'Multiple issue updating from issues#index', :js do
it 'updates milestone' do
visit project_issues_path(project)
- click_button 'Edit Issues'
+ click_button 'Edit issues'
find('#check-all-issues').click
find('.issues-bulk-update .js-milestone-select').click
@@ -89,7 +89,7 @@ feature 'Multiple issue updating from issues#index', :js do
expect(first('.issue')).to have_content milestone.title
- click_button 'Edit Issues'
+ click_button 'Edit issues'
find('#check-all-issues').click
find('.issues-bulk-update .js-milestone-select').click
diff --git a/spec/features/issues/user_uses_slash_commands_spec.rb b/spec/features/issues/user_uses_slash_commands_spec.rb
index d28ad52ff56..4b63cc844f3 100644
--- a/spec/features/issues/user_uses_slash_commands_spec.rb
+++ b/spec/features/issues/user_uses_slash_commands_spec.rb
@@ -9,7 +9,7 @@ feature 'Issues > User uses quick actions', js: true do
describe 'issue-only commands' do
let(:user) { create(:user) }
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
before do
project.team << [user, :master]
diff --git a/spec/features/issues_spec.rb b/spec/features/issues_spec.rb
index 722237481ea..3c8e37ff920 100644
--- a/spec/features/issues_spec.rb
+++ b/spec/features/issues_spec.rb
@@ -6,7 +6,7 @@ describe 'Issues' do
include SortingHelper
let(:user) { create(:user) }
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
before do
sign_in(user)
@@ -367,7 +367,7 @@ describe 'Issues' do
end
describe 'when I want to reset my incoming email token' do
- let(:project1) { create(:empty_project, namespace: user.namespace) }
+ let(:project1) { create(:project, namespace: user.namespace) }
let!(:issue) { create(:issue, project: project1) }
before do
@@ -706,4 +706,29 @@ describe 'Issues' do
expect(page).to have_text("updated title")
end
end
+
+ describe 'confidential issue#show', js: true do
+ it 'shows confidential sibebar information as confidential and can be turned off' do
+ issue = create(:issue, :confidential, project: project)
+
+ visit project_issue_path(project, issue)
+
+ expect(page).to have_css('.confidential-issue-warning')
+ expect(page).to have_css('.is-confidential')
+ expect(page).not_to have_css('.is-not-confidential')
+
+ find('.confidential-edit').click
+ expect(page).to have_css('.confidential-warning-message')
+
+ within('.confidential-warning-message') do
+ find('.btn-close').click
+ end
+
+ wait_for_requests
+
+ visit project_issue_path(project, issue)
+
+ expect(page).not_to have_css('.is-confidential')
+ end
+ end
end
diff --git a/spec/features/merge_requests/closes_issues_spec.rb b/spec/features/merge_requests/closes_issues_spec.rb
index 0e97254eada..299b4f5708a 100644
--- a/spec/features/merge_requests/closes_issues_spec.rb
+++ b/spec/features/merge_requests/closes_issues_spec.rb
@@ -26,17 +26,11 @@ feature 'Merge Request closing issues message', js: true do
wait_for_requests
end
- context 'not closing or mentioning any issue' do
- it 'does not display closing issue message' do
- expect(page).not_to have_css('.mr-widget-footer')
- end
- end
-
context 'closing issues but not mentioning any other issue' do
let(:merge_request_description) { "Description\n\nclosing #{issue_1.to_reference}, #{issue_2.to_reference}" }
it 'does not display closing issue message' do
- expect(page).to have_content("Closes issues #{issue_1.to_reference} and #{issue_2.to_reference}")
+ expect(page).to have_content("Closes #{issue_1.to_reference} and #{issue_2.to_reference}")
end
end
@@ -44,7 +38,7 @@ feature 'Merge Request closing issues message', js: true do
let(:merge_request_description) { "Description\n\nRefers to #{issue_1.to_reference} and #{issue_2.to_reference}" }
it 'does not display closing issue message' do
- expect(page).to have_content("Issues #{issue_1.to_reference} and #{issue_2.to_reference} are mentioned but will not be closed.")
+ expect(page).to have_content("Mentions #{issue_1.to_reference} and #{issue_2.to_reference}")
end
end
@@ -52,8 +46,8 @@ feature 'Merge Request closing issues message', js: true do
let(:merge_request_title) { "closes #{issue_1.to_reference}\n\n refers to #{issue_2.to_reference}" }
it 'does not display closing issue message' do
- expect(page).to have_content("Closes issue #{issue_1.to_reference}.")
- expect(page).to have_content("Issue #{issue_2.to_reference} is mentioned but will not be closed.")
+ expect(page).to have_content("Closes #{issue_1.to_reference}")
+ expect(page).to have_content("Mentions #{issue_2.to_reference}")
end
end
@@ -61,7 +55,7 @@ feature 'Merge Request closing issues message', js: true do
let(:merge_request_title) { "closing #{issue_1.to_reference}, #{issue_2.to_reference}" }
it 'does not display closing issue message' do
- expect(page).to have_content("Closes issues #{issue_1.to_reference} and #{issue_2.to_reference}")
+ expect(page).to have_content("Closes #{issue_1.to_reference} and #{issue_2.to_reference}")
end
end
@@ -69,7 +63,7 @@ feature 'Merge Request closing issues message', js: true do
let(:merge_request_title) { "Refers to #{issue_1.to_reference} and #{issue_2.to_reference}" }
it 'does not display closing issue message' do
- expect(page).to have_content("Issues #{issue_1.to_reference} and #{issue_2.to_reference} are mentioned but will not be closed.")
+ expect(page).to have_content("Mentions #{issue_1.to_reference} and #{issue_2.to_reference}")
end
end
@@ -77,8 +71,8 @@ feature 'Merge Request closing issues message', js: true do
let(:merge_request_title) { "closes #{issue_1.to_reference}\n\n refers to #{issue_2.to_reference}" }
it 'does not display closing issue message' do
- expect(page).to have_content("Closes issue #{issue_1.to_reference}. Issue #{issue_2.to_reference} is mentioned but will not be closed.")
- expect(page).to have_content("Issue #{issue_2.to_reference} is mentioned but will not be closed.")
+ expect(page).to have_content("Closes #{issue_1.to_reference}")
+ expect(page).to have_content("Mentions #{issue_2.to_reference}")
end
end
end
diff --git a/spec/features/merge_requests/create_new_mr_spec.rb b/spec/features/merge_requests/create_new_mr_spec.rb
index 11a74276898..d7f3d91e625 100644
--- a/spec/features/merge_requests/create_new_mr_spec.rb
+++ b/spec/features/merge_requests/create_new_mr_spec.rb
@@ -67,8 +67,8 @@ feature 'Create New Merge Request', js: true do
visit project_new_merge_request_path(project, merge_request: { target_project_id: private_project.id })
- expect(page).not_to have_content private_project.path_with_namespace
- expect(page).to have_content project.path_with_namespace
+ expect(page).not_to have_content private_project.full_path
+ expect(page).to have_content project.full_path
end
end
@@ -78,8 +78,8 @@ feature 'Create New Merge Request', js: true do
visit project_new_merge_request_path(project, merge_request: { source_project_id: private_project.id })
- expect(page).not_to have_content private_project.path_with_namespace
- expect(page).to have_content project.path_with_namespace
+ expect(page).not_to have_content private_project.full_path
+ expect(page).to have_content project.full_path
end
end
diff --git a/spec/features/merge_requests/diff_notes_avatars_spec.rb b/spec/features/merge_requests/diff_notes_avatars_spec.rb
index 2d9419d6124..c4f02311f13 100644
--- a/spec/features/merge_requests/diff_notes_avatars_spec.rb
+++ b/spec/features/merge_requests/diff_notes_avatars_spec.rb
@@ -157,7 +157,7 @@ feature 'Diff note avatars', js: true do
end
page.within find("[id='#{position.line_code(project.repository)}']") do
- find('.diff-notes-collapse').click
+ find('.diff-notes-collapse').trigger('click')
expect(page).to have_selector('img.js-diff-comment-avatar', count: 3)
expect(find('.diff-comments-more-count')).to have_content '+1'
diff --git a/spec/features/merge_requests/diffs_spec.rb b/spec/features/merge_requests/diffs_spec.rb
index 201be4b9e40..a8f5dc275e4 100644
--- a/spec/features/merge_requests/diffs_spec.rb
+++ b/spec/features/merge_requests/diffs_spec.rb
@@ -5,7 +5,7 @@ feature 'Diffs URL', js: true do
let(:merge_request) { create(:merge_request, source_project: project) }
context 'when visit with */* as accept header' do
- before(:each) do
+ before do
page.driver.add_header('Accept', '*/*')
end
diff --git a/spec/features/merge_requests/discussion_spec.rb b/spec/features/merge_requests/discussion_spec.rb
index d1cc43e0690..05789bbd31d 100644
--- a/spec/features/merge_requests/discussion_spec.rb
+++ b/spec/features/merge_requests/discussion_spec.rb
@@ -26,7 +26,7 @@ feature 'Merge Request Discussions' do
let(:outdated_diff_refs) { project.commit("874797c3a73b60d2187ed6e2fcabd289ff75171e").diff_refs }
- before(:each) do
+ before do
visit project_merge_request_path(project, merge_request)
end
@@ -71,7 +71,7 @@ feature 'Merge Request Discussions' do
end
end
- before(:each) do
+ before do
visit project_merge_request_path(project, merge_request)
end
diff --git a/spec/features/merge_requests/filter_by_labels_spec.rb b/spec/features/merge_requests/filter_by_labels_spec.rb
index 1d52a4659ad..9912e8165e6 100644
--- a/spec/features/merge_requests/filter_by_labels_spec.rb
+++ b/spec/features/merge_requests/filter_by_labels_spec.rb
@@ -1,6 +1,6 @@
require 'rails_helper'
-feature 'Merge Request filtering by Labels', js: true do
+feature 'Merge Request filtering by Labels', :js do
include FilteredSearchHelpers
include MergeRequestHelpers
@@ -12,9 +12,9 @@ feature 'Merge Request filtering by Labels', js: true do
let!(:feature) { create(:label, project: project, title: 'feature') }
let!(:enhancement) { create(:label, project: project, title: 'enhancement') }
- let!(:mr1) { create(:merge_request, title: "Bugfix1", source_project: project, target_project: project, source_branch: "bugfix1") }
- let!(:mr2) { create(:merge_request, title: "Bugfix2", source_project: project, target_project: project, source_branch: "bugfix2") }
- let!(:mr3) { create(:merge_request, title: "Feature1", source_project: project, target_project: project, source_branch: "feature1") }
+ let!(:mr1) { create(:merge_request, title: "Bugfix1", source_project: project, target_project: project, source_branch: "fix") }
+ let!(:mr2) { create(:merge_request, title: "Bugfix2", source_project: project, target_project: project, source_branch: "wip") }
+ let!(:mr3) { create(:merge_request, title: "Feature1", source_project: project, target_project: project, source_branch: "improve/awesome") }
before do
mr1.labels << bug
@@ -25,7 +25,7 @@ feature 'Merge Request filtering by Labels', js: true do
mr3.title = "Feature1"
mr3.labels << feature
- project.team << [user, :master]
+ project.add_master(user)
sign_in(user)
visit project_merge_requests_path(project)
diff --git a/spec/features/merge_requests/filter_merge_requests_spec.rb b/spec/features/merge_requests/filter_merge_requests_spec.rb
index f0019be86ad..3686131fee4 100644
--- a/spec/features/merge_requests/filter_merge_requests_spec.rb
+++ b/spec/features/merge_requests/filter_merge_requests_spec.rb
@@ -12,7 +12,7 @@ describe 'Filter merge requests' do
let!(:wontfix) { create(:label, project: project, title: "Won't fix") }
before do
- project.team << [user, :master]
+ project.add_master(user)
group.add_developer(user)
sign_in(user)
create(:merge_request, source_project: project, target_project: project)
@@ -170,7 +170,7 @@ describe 'Filter merge requests' do
describe 'filter merge requests by text' do
before do
- create(:merge_request, title: "Bug", source_project: project, target_project: project, source_branch: "bug")
+ create(:merge_request, title: "Bug", source_project: project, target_project: project, source_branch: "wip")
bug_label = create(:label, project: project, title: 'bug')
milestone = create(:milestone, title: "8", project: project)
@@ -179,7 +179,7 @@ describe 'Filter merge requests' do
title: "Bug 2",
source_project: project,
target_project: project,
- source_branch: "bug2",
+ source_branch: "fix",
milestone: milestone,
author: user,
assignee: user)
@@ -259,12 +259,12 @@ describe 'Filter merge requests' do
end
end
- describe 'filter merge requests and sort', js: true do
+ describe 'filter merge requests and sort', :js do
before do
bug_label = create(:label, project: project, title: 'bug')
- mr1 = create(:merge_request, title: "Frontend", source_project: project, target_project: project, source_branch: "Frontend")
- mr2 = create(:merge_request, title: "Bug 2", source_project: project, target_project: project, source_branch: "bug2")
+ mr1 = create(:merge_request, title: "Frontend", source_project: project, target_project: project, source_branch: "wip")
+ mr2 = create(:merge_request, title: "Bug 2", source_project: project, target_project: project, source_branch: "fix")
mr1.labels << bug_label
mr2.labels << bug_label
diff --git a/spec/features/merge_requests/form_spec.rb b/spec/features/merge_requests/form_spec.rb
index 6ffb05c5030..89410b0e90f 100644
--- a/spec/features/merge_requests/form_spec.rb
+++ b/spec/features/merge_requests/form_spec.rb
@@ -41,7 +41,7 @@ describe 'New/edit merge request', :js do
expect(page).to have_content user2.name
end
- click_link 'Assign to me'
+ find('a', text: 'Assign to me').trigger('click')
expect(find('input[name="merge_request[assignee_id]"]', visible: false).value).to match(user.id.to_s)
page.within '.js-assignee-search' do
expect(page).to have_content user.name
diff --git a/spec/features/merge_requests/merge_when_pipeline_succeeds_spec.rb b/spec/features/merge_requests/merge_when_pipeline_succeeds_spec.rb
index 574f5fe353e..ac46cc1f0e4 100644
--- a/spec/features/merge_requests/merge_when_pipeline_succeeds_spec.rb
+++ b/spec/features/merge_requests/merge_when_pipeline_succeeds_spec.rb
@@ -41,8 +41,8 @@ feature 'Merge When Pipeline Succeeds', :js do
it 'activates the Merge when pipeline succeeds feature' do
click_button "Merge when pipeline succeeds"
- expect(page).to have_content "Set by #{user.name} to be merged automatically when the pipeline succeeds."
- expect(page).to have_content "The source branch will not be removed."
+ expect(page).to have_content "Set by #{user.name} to be merged automatically when the pipeline succeeds"
+ expect(page).to have_content "The source branch will not be removed"
expect(page).to have_selector ".js-cancel-auto-merge"
visit_merge_request(merge_request) # Needed to refresh the page
expect(page).to have_content /enabled an automatic merge when the pipeline for \h{8} succeeds/i
@@ -97,11 +97,11 @@ feature 'Merge When Pipeline Succeeds', :js do
describe 'enabling Merge when pipeline succeeds via dropdown' do
it 'activates the Merge when pipeline succeeds feature' do
- click_button 'Select merge moment'
+ find('.js-merge-moment').click
click_link 'Merge when pipeline succeeds'
- expect(page).to have_content "Set by #{user.name} to be merged automatically when the pipeline succeeds."
- expect(page).to have_content "The source branch will not be removed."
+ expect(page).to have_content "Set by #{user.name} to be merged automatically when the pipeline succeeds"
+ expect(page).to have_content "The source branch will not be removed"
expect(page).to have_link "Cancel automatic merge"
end
end
diff --git a/spec/features/merge_requests/only_allow_merge_if_build_succeeds_spec.rb b/spec/features/merge_requests/only_allow_merge_if_build_succeeds_spec.rb
index 5c6eec44ff7..59e67420333 100644
--- a/spec/features/merge_requests/only_allow_merge_if_build_succeeds_spec.rb
+++ b/spec/features/merge_requests/only_allow_merge_if_build_succeeds_spec.rb
@@ -43,7 +43,7 @@ feature 'Only allow merge requests to be merged if the pipeline succeeds', js: t
wait_for_requests
expect(page).to have_button 'Merge when pipeline succeeds'
- expect(page).not_to have_button 'Select merge moment'
+ expect(page).not_to have_button '.js-merge-moment'
end
end
@@ -56,7 +56,7 @@ feature 'Only allow merge requests to be merged if the pipeline succeeds', js: t
wait_for_requests
expect(page).to have_css('button[disabled="disabled"]', text: 'Merge')
- expect(page).to have_content('Please retry the job or push a new commit to fix the failure.')
+ expect(page).to have_content('Please retry the job or push a new commit to fix the failure')
end
end
@@ -69,7 +69,7 @@ feature 'Only allow merge requests to be merged if the pipeline succeeds', js: t
wait_for_requests
expect(page).not_to have_button 'Merge'
- expect(page).to have_content('Please retry the job or push a new commit to fix the failure.')
+ expect(page).to have_content('Please retry the job or push a new commit to fix the failure')
end
end
@@ -113,7 +113,7 @@ feature 'Only allow merge requests to be merged if the pipeline succeeds', js: t
expect(page).to have_button 'Merge when pipeline succeeds'
- click_button 'Select merge moment'
+ page.find('.js-merge-moment').click
expect(page).to have_content 'Merge immediately'
end
end
diff --git a/spec/features/merge_requests/pipelines_spec.rb b/spec/features/merge_requests/pipelines_spec.rb
index b3d6cf8deb4..347ce788b36 100644
--- a/spec/features/merge_requests/pipelines_spec.rb
+++ b/spec/features/merge_requests/pipelines_spec.rb
@@ -1,45 +1,88 @@
require 'spec_helper'
feature 'Pipelines for Merge Requests', js: true do
- given(:user) { create(:user) }
- given(:merge_request) { create(:merge_request) }
- given(:project) { merge_request.target_project }
+ describe 'pipeline tab' do
+ given(:user) { create(:user) }
+ given(:merge_request) { create(:merge_request) }
+ given(:project) { merge_request.target_project }
- before do
- project.team << [user, :master]
- sign_in user
- end
-
- context 'with pipelines' do
- let!(:pipeline) do
- create(:ci_empty_pipeline,
- project: merge_request.source_project,
- ref: merge_request.source_branch,
- sha: merge_request.diff_head_sha)
+ before do
+ project.team << [user, :master]
+ sign_in user
end
- before do
- visit project_merge_request_path(project, merge_request)
+ context 'with pipelines' do
+ let!(:pipeline) do
+ create(:ci_empty_pipeline,
+ project: merge_request.source_project,
+ ref: merge_request.source_branch,
+ sha: merge_request.diff_head_sha)
+ end
+
+ before do
+ visit project_merge_request_path(project, merge_request)
+ end
+
+ scenario 'user visits merge request pipelines tab' do
+ page.within('.merge-request-tabs') do
+ click_link('Pipelines')
+ end
+ wait_for_requests
+
+ expect(page).to have_selector('.stage-cell')
+ end
end
- scenario 'user visits merge request pipelines tab' do
- page.within('.merge-request-tabs') do
- click_link('Pipelines')
+ context 'without pipelines' do
+ before do
+ visit project_merge_request_path(project, merge_request)
end
- wait_for_requests
- expect(page).to have_selector('.stage-cell')
+ scenario 'user visits merge request page' do
+ page.within('.merge-request-tabs') do
+ expect(page).to have_no_link('Pipelines')
+ end
+ end
end
end
- context 'without pipelines' do
- before do
- visit project_merge_request_path(project, merge_request)
+ describe 'race condition' do
+ given(:project) { create(:project, :repository) }
+ given(:user) { create(:user) }
+ given(:build_push_data) { { ref: 'feature', checkout_sha: TestEnv::BRANCH_SHA['feature'] } }
+
+ given(:merge_request_params) do
+ { "source_branch" => "feature", "source_project_id" => project.id,
+ "target_branch" => "master", "target_project_id" => project.id, "title" => "A" }
+ end
+
+ background do
+ project.add_master(user)
+ sign_in user
end
- scenario 'user visits merge request page' do
- page.within('.merge-request-tabs') do
- expect(page).to have_no_link('Pipelines')
+ context 'when pipeline and merge request were created simultaneously' do
+ background do
+ stub_ci_pipeline_to_return_yaml_file
+
+ threads = []
+
+ threads << Thread.new do
+ @merge_request = MergeRequests::CreateService.new(project, user, merge_request_params).execute
+ end
+
+ threads << Thread.new do
+ @pipeline = Ci::CreatePipelineService.new(project, user, build_push_data).execute(:push)
+ end
+
+ threads.each { |thr| thr.join }
+ end
+
+ scenario 'user sees pipeline in merge request widget' do
+ visit project_merge_request_path(project, @merge_request)
+
+ expect(page.find(".ci-widget")).to have_content(TestEnv::BRANCH_SHA['feature'])
+ expect(page.find(".ci-widget")).to have_content("##{@pipeline.id}")
end
end
end
diff --git a/spec/features/merge_requests/reset_filters_spec.rb b/spec/features/merge_requests/reset_filters_spec.rb
index c1b90e5f875..eed95816bdf 100644
--- a/spec/features/merge_requests/reset_filters_spec.rb
+++ b/spec/features/merge_requests/reset_filters_spec.rb
@@ -1,6 +1,6 @@
require 'rails_helper'
-feature 'Merge requests filter clear button', js: true do
+feature 'Merge requests filter clear button', :js do
include FilteredSearchHelpers
include MergeRequestHelpers
include IssueHelpers
@@ -9,8 +9,8 @@ feature 'Merge requests filter clear button', js: true do
let!(:user) { create(:user) }
let!(:milestone) { create(:milestone, project: project) }
let!(:bug) { create(:label, project: project, name: 'bug')}
- let!(:mr1) { create(:merge_request, title: "Feature", source_project: project, target_project: project, source_branch: "Feature", milestone: milestone, author: user, assignee: user) }
- let!(:mr2) { create(:merge_request, title: "Bugfix1", source_project: project, target_project: project, source_branch: "Bugfix1") }
+ let!(:mr1) { create(:merge_request, title: "Feature", source_project: project, target_project: project, source_branch: "improve/awesome", milestone: milestone, author: user, assignee: user) }
+ let!(:mr2) { create(:merge_request, title: "Bugfix1", source_project: project, target_project: project, source_branch: "fix") }
let(:merge_request_css) { '.merge-request' }
let(:clear_search_css) { '.filtered-search-box .clear-search' }
diff --git a/spec/features/merge_requests/update_merge_requests_spec.rb b/spec/features/merge_requests/update_merge_requests_spec.rb
index cf30a687df8..e6dc284cba7 100644
--- a/spec/features/merge_requests/update_merge_requests_spec.rb
+++ b/spec/features/merge_requests/update_merge_requests_spec.rb
@@ -98,7 +98,7 @@ feature 'Multiple merge requests updating from merge_requests#index' do
end
def change_status(text)
- click_button 'Edit Merge Requests'
+ click_button 'Edit merge requests'
find('#check-all-issues').click
find('.js-issue-status').click
find('.dropdown-menu-status a', text: text).click
@@ -106,7 +106,7 @@ feature 'Multiple merge requests updating from merge_requests#index' do
end
def change_assignee(text)
- click_button 'Edit Merge Requests'
+ click_button 'Edit merge requests'
find('#check-all-issues').click
find('.js-update-assignee').click
wait_for_requests
@@ -119,7 +119,7 @@ feature 'Multiple merge requests updating from merge_requests#index' do
end
def change_milestone(text)
- click_button 'Edit Merge Requests'
+ click_button 'Edit merge requests'
find('#check-all-issues').click
find('.issues-bulk-update .js-milestone-select').click
find('.dropdown-menu-milestone a', text: text).click
diff --git a/spec/features/merge_requests/user_lists_merge_requests_spec.rb b/spec/features/merge_requests/user_lists_merge_requests_spec.rb
index d62b035b40b..20008b4e7f9 100644
--- a/spec/features/merge_requests/user_lists_merge_requests_spec.rb
+++ b/spec/features/merge_requests/user_lists_merge_requests_spec.rb
@@ -24,12 +24,10 @@ describe 'Projects > Merge requests > User lists merge requests' do
milestone: create(:milestone, due_date: '2013-12-12'),
created_at: 2.minutes.ago,
updated_at: 2.minutes.ago)
- # lfs in itself is not a great choice for the title if one wants to match the whole body content later on
- # just think about the scenario when faker generates 'Chester Runolfsson' as the user's name
create(:merge_request,
- title: 'merge_lfs',
+ title: 'merge-test',
source_project: project,
- source_branch: 'merge_lfs',
+ source_branch: 'merge-test',
created_at: 3.minutes.ago,
updated_at: 10.seconds.ago)
end
@@ -38,7 +36,7 @@ describe 'Projects > Merge requests > User lists merge requests' do
visit_merge_requests(project, assignee_id: IssuableFinder::NONE)
expect(current_path).to eq(project_merge_requests_path(project))
- expect(page).to have_content 'merge_lfs'
+ expect(page).to have_content 'merge-test'
expect(page).not_to have_content 'fix'
expect(page).not_to have_content 'markdown'
expect(count_merge_requests).to eq(1)
@@ -47,7 +45,7 @@ describe 'Projects > Merge requests > User lists merge requests' do
it 'filters on a specific assignee' do
visit_merge_requests(project, assignee_id: user.id)
- expect(page).not_to have_content 'merge_lfs'
+ expect(page).not_to have_content 'merge-test'
expect(page).to have_content 'fix'
expect(page).to have_content 'markdown'
expect(count_merge_requests).to eq(2)
@@ -57,14 +55,14 @@ describe 'Projects > Merge requests > User lists merge requests' do
visit_merge_requests(project, sort: sort_value_recently_created)
expect(first_merge_request).to include('fix')
- expect(last_merge_request).to include('merge_lfs')
+ expect(last_merge_request).to include('merge-test')
expect(count_merge_requests).to eq(3)
end
it 'sorts by oldest' do
visit_merge_requests(project, sort: sort_value_oldest_created)
- expect(first_merge_request).to include('merge_lfs')
+ expect(first_merge_request).to include('merge-test')
expect(last_merge_request).to include('fix')
expect(count_merge_requests).to eq(3)
end
@@ -72,7 +70,7 @@ describe 'Projects > Merge requests > User lists merge requests' do
it 'sorts by last updated' do
visit_merge_requests(project, sort: sort_value_recently_updated)
- expect(first_merge_request).to include('merge_lfs')
+ expect(first_merge_request).to include('merge-test')
expect(count_merge_requests).to eq(3)
end
diff --git a/spec/features/merge_requests/user_posts_diff_notes_spec.rb b/spec/features/merge_requests/user_posts_diff_notes_spec.rb
index 1cfd78663e5..f89dd38e5cd 100644
--- a/spec/features/merge_requests/user_posts_diff_notes_spec.rb
+++ b/spec/features/merge_requests/user_posts_diff_notes_spec.rb
@@ -71,7 +71,7 @@ feature 'Merge requests > User posts diff notes', :js do
end
context 'with an unfolded line' do
- before(:each) do
+ before do
find('.js-unfold', match: :first).click
wait_for_requests
end
@@ -120,7 +120,7 @@ feature 'Merge requests > User posts diff notes', :js do
end
context 'with an unfolded line' do
- before(:each) do
+ before do
find('.js-unfold', match: :first).click
wait_for_requests
end
diff --git a/spec/features/merge_requests/user_posts_notes_spec.rb b/spec/features/merge_requests/user_posts_notes_spec.rb
index 74d21822a59..d7cda73ab40 100644
--- a/spec/features/merge_requests/user_posts_notes_spec.rb
+++ b/spec/features/merge_requests/user_posts_notes_spec.rb
@@ -75,7 +75,6 @@ describe 'Merge requests > User posts notes', :js do
describe 'editing the note' do
before do
find('.note').hover
- open_more_actions_dropdown(note)
find('.js-note-edit').click
end
@@ -104,7 +103,6 @@ describe 'Merge requests > User posts notes', :js do
wait_for_requests
find('.note').hover
- open_more_actions_dropdown(note)
find('.js-note-edit').click
@@ -132,7 +130,6 @@ describe 'Merge requests > User posts notes', :js do
describe 'deleting an attachment' do
before do
find('.note').hover
- open_more_actions_dropdown(note)
find('.js-note-edit').click
end
diff --git a/spec/features/merge_requests/user_uses_slash_commands_spec.rb b/spec/features/merge_requests/user_uses_slash_commands_spec.rb
index 43cab65d287..95c50df1896 100644
--- a/spec/features/merge_requests/user_uses_slash_commands_spec.rb
+++ b/spec/features/merge_requests/user_uses_slash_commands_spec.rb
@@ -3,17 +3,17 @@ require 'rails_helper'
feature 'Merge Requests > User uses quick actions', js: true do
include QuickActionsHelpers
- let(:user) { create(:user) }
- let(:project) { create(:project, :public, :repository) }
- let(:merge_request) { create(:merge_request, source_project: project) }
- let!(:milestone) { create(:milestone, project: project, title: 'ASAP') }
-
it_behaves_like 'issuable record that supports quick actions in its description and notes', :merge_request do
let(:issuable) { create(:merge_request, source_project: project) }
let(:new_url_opts) { { merge_request: { source_branch: 'feature', target_branch: 'master' } } }
end
describe 'merge-request-only commands' do
+ let(:user) { create(:user) }
+ let(:project) { create(:project, :public, :repository) }
+ let(:merge_request) { create(:merge_request, source_project: project) }
+ let!(:milestone) { create(:milestone, project: project, title: 'ASAP') }
+
before do
project.team << [user, :master]
sign_in(user)
diff --git a/spec/features/merge_requests/widget_spec.rb b/spec/features/merge_requests/widget_spec.rb
index 69e31c7481f..fd991293ee9 100644
--- a/spec/features/merge_requests/widget_spec.rb
+++ b/spec/features/merge_requests/widget_spec.rb
@@ -219,4 +219,17 @@ describe 'Merge request', :js do
expect(page).to have_field('remove-source-branch-input', disabled: true)
end
end
+
+ context 'ongoing merge process' do
+ it 'shows Merging state' do
+ allow_any_instance_of(MergeRequest).to receive(:merge_ongoing?).and_return(true)
+
+ visit project_merge_request_path(project, merge_request)
+
+ wait_for_requests
+
+ expect(page).not_to have_button('Merge')
+ expect(page).to have_content('This merge request is in the process of being merged')
+ end
+ end
end
diff --git a/spec/features/milestone_spec.rb b/spec/features/milestone_spec.rb
index 1d05184d6fc..6c9dc67ad74 100644
--- a/spec/features/milestone_spec.rb
+++ b/spec/features/milestone_spec.rb
@@ -2,7 +2,7 @@ require 'rails_helper'
feature 'Milestone' do
let(:group) { create(:group, :public) }
- let(:project) { create(:empty_project, :public, namespace: group) }
+ let(:project) { create(:project, :public, namespace: group) }
let(:user) { create(:user) }
before do
diff --git a/spec/features/milestones/show_spec.rb b/spec/features/milestones/show_spec.rb
index 199a5ba83b3..20303359c46 100644
--- a/spec/features/milestones/show_spec.rb
+++ b/spec/features/milestones/show_spec.rb
@@ -2,7 +2,7 @@ require 'rails_helper'
describe 'Milestone show' do
let(:user) { create(:user) }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:milestone) { create(:milestone, project: project) }
let(:labels) { create_list(:label, 2, project: project) }
let(:issue_params) { { project: project, assignees: [user], author: user, milestone: milestone, labels: labels } }
diff --git a/spec/features/participants_autocomplete_spec.rb b/spec/features/participants_autocomplete_spec.rb
index 81b0a2f541b..a22d548eef3 100644
--- a/spec/features/participants_autocomplete_spec.rb
+++ b/spec/features/participants_autocomplete_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
feature 'Member autocomplete', :js do
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:user) { create(:user) }
let(:author) { create(:user) }
let(:note) { create(:note, noteable: noteable, project: noteable.project) }
diff --git a/spec/features/password_reset_spec.rb b/spec/features/password_reset_spec.rb
index 5e1e7dc078f..b45972b7f6b 100644
--- a/spec/features/password_reset_spec.rb
+++ b/spec/features/password_reset_spec.rb
@@ -16,7 +16,7 @@ feature 'Password reset' do
user.send_reset_password_instructions
user.update_attribute(:reset_password_sent_at, 5.minutes.ago)
- expect{ forgot_password(user) }.to change{ user.reset_password_sent_at }
+ expect { forgot_password(user) }.to change { user.reset_password_sent_at }
expect(page).to have_content(I18n.t('devise.passwords.send_paranoid_instructions'))
expect(current_path).to eq new_user_session_path
end
@@ -27,7 +27,7 @@ feature 'Password reset' do
# Reload because PG handles datetime less precisely than Ruby/Rails
user.reload
- expect{ forgot_password(user) }.not_to change{ user.reset_password_sent_at }
+ expect { forgot_password(user) }.not_to change { user.reset_password_sent_at }
expect(page).to have_content(I18n.t('devise.passwords.send_paranoid_instructions'))
expect(current_path).to eq new_user_session_path
end
diff --git a/spec/features/profiles/account_spec.rb b/spec/features/profiles/account_spec.rb
index 56c1f7ae9c7..dcd0449dbcb 100644
--- a/spec/features/profiles/account_spec.rb
+++ b/spec/features/profiles/account_spec.rb
@@ -27,7 +27,7 @@ feature 'Profile > Account' do
end
context 'with a project' do
- given!(:project) { create(:empty_project, namespace: user.namespace) }
+ given!(:project) { create(:project, namespace: user.namespace) }
given(:new_project_path) { "/#{new_username}/#{project.path}" }
given(:old_project_path) { "/#{user.username}/#{project.path}" }
@@ -35,7 +35,7 @@ feature 'Profile > Account' do
TestEnv.clean_test_path
end
- after(:example) do
+ after do
TestEnv.clean_test_path
end
diff --git a/spec/features/profiles/preferences_spec.rb b/spec/features/profiles/preferences_spec.rb
index 9123aa9d155..c935cdfd5c4 100644
--- a/spec/features/profiles/preferences_spec.rb
+++ b/spec/features/profiles/preferences_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe 'Profile > Preferences' do
+describe 'Profile > Preferences', :js do
let(:user) { create(:user) }
before do
@@ -8,28 +8,32 @@ describe 'Profile > Preferences' do
visit profile_preferences_path
end
- describe 'User changes their syntax highlighting theme', js: true do
+ describe 'User changes their syntax highlighting theme' do
it 'creates a flash message' do
choose 'user_color_scheme_id_5'
+ wait_for_requests
+
expect_preferences_saved_message
end
it 'updates their preference' do
choose 'user_color_scheme_id_5'
- allowing_for_delay do
- visit page.current_path
- expect(page).to have_checked_field('user_color_scheme_id_5')
- end
+ wait_for_requests
+ refresh
+
+ expect(page).to have_checked_field('user_color_scheme_id_5')
end
end
- describe 'User changes their default dashboard', js: true do
+ describe 'User changes their default dashboard' do
it 'creates a flash message' do
select 'Starred Projects', from: 'user_dashboard'
click_button 'Save'
+ wait_for_requests
+
expect_preferences_saved_message
end
@@ -37,12 +41,12 @@ describe 'Profile > Preferences' do
select 'Starred Projects', from: 'user_dashboard'
click_button 'Save'
- allowing_for_delay do
- find('#logo').click
+ wait_for_requests
+
+ find('#logo').click
- expect(page).to have_content("You don't have starred projects yet")
- expect(page.current_path).to eq starred_dashboard_projects_path
- end
+ expect(page).to have_content("You don't have starred projects yet")
+ expect(page.current_path).to eq starred_dashboard_projects_path
find('.shortcuts-activity').trigger('click')
diff --git a/spec/features/profiles/user_visits_notifications_tab_spec.rb b/spec/features/profiles/user_visits_notifications_tab_spec.rb
index e98cec79d87..48c1787c8b7 100644
--- a/spec/features/profiles/user_visits_notifications_tab_spec.rb
+++ b/spec/features/profiles/user_visits_notifications_tab_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
feature 'User visits the notifications tab', js: true do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:user) { create(:user) }
before do
diff --git a/spec/features/projects/activity/rss_spec.rb b/spec/features/projects/activity/rss_spec.rb
index b054f543dc6..84c2faa2015 100644
--- a/spec/features/projects/activity/rss_spec.rb
+++ b/spec/features/projects/activity/rss_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
feature 'Project Activity RSS' do
let(:user) { create(:user) }
- let(:project) { create(:empty_project, visibility_level: Gitlab::VisibilityLevel::PUBLIC) }
+ let(:project) { create(:project, visibility_level: Gitlab::VisibilityLevel::PUBLIC) }
let(:path) { activity_project_path(project) }
before do
diff --git a/spec/features/projects/artifacts/browse_spec.rb b/spec/features/projects/artifacts/browse_spec.rb
index f5f7eba8e40..42b47cb3301 100644
--- a/spec/features/projects/artifacts/browse_spec.rb
+++ b/spec/features/projects/artifacts/browse_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
feature 'Browse artifact', :js do
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:pipeline) { create(:ci_empty_pipeline, project: project) }
let(:job) { create(:ci_build, :artifacts, pipeline: pipeline) }
diff --git a/spec/features/projects/artifacts/download_spec.rb b/spec/features/projects/artifacts/download_spec.rb
index c1bba8c15c4..f1bdb2812c6 100644
--- a/spec/features/projects/artifacts/download_spec.rb
+++ b/spec/features/projects/artifacts/download_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
feature 'Download artifact', :js do
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:pipeline) { create(:ci_empty_pipeline, status: :success, project: project) }
let(:job) { create(:ci_build, :artifacts, :success, pipeline: pipeline) }
diff --git a/spec/features/projects/artifacts/file_spec.rb b/spec/features/projects/artifacts/file_spec.rb
index 4c268b876ea..b2be10a7e0c 100644
--- a/spec/features/projects/artifacts/file_spec.rb
+++ b/spec/features/projects/artifacts/file_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
feature 'Artifact file', :js do
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:pipeline) { create(:ci_empty_pipeline, project: project) }
let(:build) { create(:ci_build, :artifacts, pipeline: pipeline) }
diff --git a/spec/features/projects/artifacts/raw_spec.rb b/spec/features/projects/artifacts/raw_spec.rb
index 128e39e7803..0bec6e9ad31 100644
--- a/spec/features/projects/artifacts/raw_spec.rb
+++ b/spec/features/projects/artifacts/raw_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
feature 'Raw artifact', :js do
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:pipeline) { create(:ci_empty_pipeline, project: project) }
let(:job) { create(:ci_build, :artifacts, pipeline: pipeline) }
diff --git a/spec/features/projects/badges/coverage_spec.rb b/spec/features/projects/badges/coverage_spec.rb
index 8cf4bfbf978..368a046f741 100644
--- a/spec/features/projects/badges/coverage_spec.rb
+++ b/spec/features/projects/badges/coverage_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
feature 'test coverage badge' do
given!(:user) { create(:user) }
- given!(:project) { create(:empty_project, :private) }
+ given!(:project) { create(:project, :private) }
context 'when user has access to view badge' do
background do
diff --git a/spec/features/projects/blobs/edit_spec.rb b/spec/features/projects/blobs/edit_spec.rb
index 9855cfd85c4..62ac9fd0e95 100644
--- a/spec/features/projects/blobs/edit_spec.rb
+++ b/spec/features/projects/blobs/edit_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
feature 'Editing file blob', js: true do
include TreeHelper
- let(:project) { create(:project, :public) }
+ let(:project) { create(:project, :public, :repository) }
let(:merge_request) { create(:merge_request, source_project: project, source_branch: 'feature', target_branch: 'master') }
let(:branch) { 'master' }
let(:file_path) { project.repository.ls_files(project.repository.root_ref)[1] }
diff --git a/spec/features/projects/developer_views_empty_project_instructions_spec.rb b/spec/features/projects/developer_views_empty_project_instructions_spec.rb
index 7145e286229..fe8567ce348 100644
--- a/spec/features/projects/developer_views_empty_project_instructions_spec.rb
+++ b/spec/features/projects/developer_views_empty_project_instructions_spec.rb
@@ -1,7 +1,7 @@
require 'rails_helper'
feature 'Developer views empty project instructions' do
- let(:project) { create(:empty_project, :empty_repo) }
+ let(:project) { create(:project, :empty_repo) }
let(:developer) { create(:user) }
background do
diff --git a/spec/features/projects/edit_spec.rb b/spec/features/projects/edit_spec.rb
index 4b5436027f9..d3b1d1f7be3 100644
--- a/spec/features/projects/edit_spec.rb
+++ b/spec/features/projects/edit_spec.rb
@@ -2,7 +2,7 @@ require 'rails_helper'
feature 'Project edit', js: true do
let(:user) { create(:user) }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
before do
project.team << [user, :master]
@@ -20,7 +20,7 @@ feature 'Project edit', js: true do
end
context 'given project with merge_requests_disabled access level' do
- let(:project) { create(:empty_project, :merge_requests_disabled) }
+ let(:project) { create(:project, :merge_requests_disabled) }
it 'hides merge requests section' do
expect(page).to have_selector('.merge-requests-feature', visible: false)
@@ -36,7 +36,7 @@ feature 'Project edit', js: true do
end
context 'given project with builds_disabled access level' do
- let(:project) { create(:empty_project, :builds_disabled) }
+ let(:project) { create(:project, :builds_disabled) }
it 'hides builds select section' do
expect(page).to have_selector('.builds-feature', visible: false)
diff --git a/spec/features/projects/environments/environment_spec.rb b/spec/features/projects/environments/environment_spec.rb
index c6b7e611a5c..56addd64056 100644
--- a/spec/features/projects/environments/environment_spec.rb
+++ b/spec/features/projects/environments/environment_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
feature 'Environment' do
- given(:project) { create(:empty_project) }
+ given(:project) { create(:project) }
given(:user) { create(:user) }
given(:role) { :developer }
diff --git a/spec/features/projects/environments/environments_spec.rb b/spec/features/projects/environments/environments_spec.rb
index 36cf307fbe2..1c59e57c0a4 100644
--- a/spec/features/projects/environments/environments_spec.rb
+++ b/spec/features/projects/environments/environments_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
feature 'Environments page', :js do
- given(:project) { create(:empty_project) }
+ given(:project) { create(:project) }
given(:user) { create(:user) }
given(:role) { :developer }
diff --git a/spec/features/projects/features_visibility_spec.rb b/spec/features/projects/features_visibility_spec.rb
index 37fa61d038e..24691629063 100644
--- a/spec/features/projects/features_visibility_spec.rb
+++ b/spec/features/projects/features_visibility_spec.rb
@@ -20,21 +20,25 @@ describe 'Edit Project Settings' do
visit edit_project_path(project)
select 'Disabled', from: "project_project_feature_attributes_#{tool_name}_access_level"
- click_button 'Save changes'
+ page.within('.sharing-permissions') do
+ click_button 'Save changes'
+ end
wait_for_requests
expect(page).not_to have_selector(".shortcuts-#{shortcut_name}")
select 'Everyone with access', from: "project_project_feature_attributes_#{tool_name}_access_level"
- click_button 'Save changes'
+ page.within('.sharing-permissions') do
+ click_button 'Save changes'
+ end
wait_for_requests
expect(page).to have_selector(".shortcuts-#{shortcut_name}")
select 'Only team members', from: "project_project_feature_attributes_#{tool_name}_access_level"
- click_button 'Save changes'
+ page.within('.sharing-permissions') do
+ click_button 'Save changes'
+ end
wait_for_requests
expect(page).to have_selector(".shortcuts-#{shortcut_name}")
-
- sleep 0.1
end
end
end
@@ -174,7 +178,11 @@ describe 'Edit Project Settings' do
it "disables repository related features" do
select "Disabled", from: "project_project_feature_attributes_repository_access_level"
- expect(find(".edit-project")).to have_selector("select.disabled", count: 2)
+ page.within('.sharing-permissions') do
+ click_button "Save changes"
+ end
+
+ expect(find(".sharing-permissions")).to have_selector("select.disabled", count: 2)
end
it "shows empty features project homepage" do
@@ -182,7 +190,9 @@ describe 'Edit Project Settings' do
select "Disabled", from: "project_project_feature_attributes_issues_access_level"
select "Disabled", from: "project_project_feature_attributes_wiki_access_level"
- click_button "Save changes"
+ page.within('.sharing-permissions') do
+ click_button "Save changes"
+ end
wait_for_requests
visit project_path(project)
@@ -195,7 +205,9 @@ describe 'Edit Project Settings' do
select "Disabled", from: "project_project_feature_attributes_issues_access_level"
select "Disabled", from: "project_project_feature_attributes_wiki_access_level"
- click_button "Save changes"
+ page.within('.sharing-permissions') do
+ click_button "Save changes"
+ end
wait_for_requests
visit activity_project_path(project)
@@ -236,7 +248,9 @@ describe 'Edit Project Settings' do
end
def save_changes_and_check_activity_tab
- click_button "Save changes"
+ page.within('.sharing-permissions') do
+ click_button "Save changes"
+ end
wait_for_requests
visit activity_project_path(project)
@@ -249,7 +263,7 @@ describe 'Edit Project Settings' do
# Regression spec for https://gitlab.com/gitlab-org/gitlab-ce/issues/24056
describe 'project statistic visibility' do
- let!(:project) { create(:empty_project, :private) }
+ let!(:project) { create(:project, :private) }
before do
project.team << [member, :guest]
diff --git a/spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb b/spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb
index 1f4b3763b40..7bcab01c739 100644
--- a/spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb
+++ b/spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
feature 'project owner sees a link to create a license file in empty project', js: true do
let(:project_master) { create(:user) }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
background do
project.team << [project_master, :master]
sign_in(project_master)
diff --git a/spec/features/projects/gfm_autocomplete_load_spec.rb b/spec/features/projects/gfm_autocomplete_load_spec.rb
index b63e5ae46ee..cff3b1f5743 100644
--- a/spec/features/projects/gfm_autocomplete_load_spec.rb
+++ b/spec/features/projects/gfm_autocomplete_load_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe 'GFM autocomplete loading', js: true do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
before do
sign_in(create(:admin))
diff --git a/spec/features/projects/group_links_spec.rb b/spec/features/projects/group_links_spec.rb
index 698baad97ff..5195d027a9f 100644
--- a/spec/features/projects/group_links_spec.rb
+++ b/spec/features/projects/group_links_spec.rb
@@ -4,7 +4,7 @@ feature 'Project group links', :js do
include Select2Helper
let(:master) { create(:user) }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let!(:group) { create(:group) }
background do
@@ -35,7 +35,7 @@ feature 'Project group links', :js do
context 'nested group project' do
let!(:nested_group) { create(:group, parent: group) }
let!(:another_group) { create(:group) }
- let!(:project) { create(:empty_project, namespace: nested_group) }
+ let!(:project) { create(:project, namespace: nested_group) }
background do
group.add_master(master)
diff --git a/spec/features/projects/guest_navigation_menu_spec.rb b/spec/features/projects/guest_navigation_menu_spec.rb
index 1c5f89fa898..2385e1d9333 100644
--- a/spec/features/projects/guest_navigation_menu_spec.rb
+++ b/spec/features/projects/guest_navigation_menu_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe 'Guest navigation menu' do
- let(:project) { create(:empty_project, :private, public_builds: false) }
+ let(:project) { create(:project, :private, public_builds: false) }
let(:guest) { create(:user) }
before do
diff --git a/spec/features/projects/import_export/import_file_spec.rb b/spec/features/projects/import_export/import_file_spec.rb
index f924725870b..6a324d32ca7 100644
--- a/spec/features/projects/import_export/import_file_spec.rb
+++ b/spec/features/projects/import_export/import_file_spec.rb
@@ -10,7 +10,7 @@ feature 'Import/Export - project import integration test', js: true do
allow_any_instance_of(Gitlab::ImportExport).to receive(:storage_path).and_return(export_path)
end
- after(:each) do
+ after do
FileUtils.rm_rf(export_path, secure: true)
end
@@ -29,8 +29,9 @@ feature 'Import/Export - project import integration test', js: true do
fill_in :project_path, with: 'test-project-path', visible: true
click_link 'GitLab export'
- expect(page).to have_content('GitLab project export')
+ expect(page).to have_content('Import an exported GitLab project')
expect(URI.parse(current_url).query).to eq("namespace_id=#{namespace.id}&path=test-project-path")
+ expect(Gitlab::ImportExport).to receive(:import_upload_path).with(filename: /\A\h{32}_test-project-path\z/).and_call_original
attach_file('file', file)
@@ -46,7 +47,7 @@ feature 'Import/Export - project import integration test', js: true do
end
scenario 'invalid project' do
- project = create(:empty_project, namespace: namespace)
+ project = create(:project, namespace: namespace)
visit new_project_path
@@ -60,17 +61,6 @@ feature 'Import/Export - project import integration test', js: true do
expect(page).to have_content('Project could not be imported')
end
end
-
- scenario 'project with no name' do
- create(:empty_project, namespace: namespace)
-
- visit new_project_path
-
- select2(namespace.id, from: '#project_namespace_id')
-
- # Check for tooltip disabled import button
- expect(find('.import_gitlab_project')['title']).to eq('Please enter a valid project name.')
- end
end
context 'when limited to the default user namespace' do
diff --git a/spec/features/projects/import_export/namespace_export_file_spec.rb b/spec/features/projects/import_export/namespace_export_file_spec.rb
index 3917e72c39e..691b0e1e4ca 100644
--- a/spec/features/projects/import_export/namespace_export_file_spec.rb
+++ b/spec/features/projects/import_export/namespace_export_file_spec.rb
@@ -4,7 +4,7 @@ feature 'Import/Export - Namespace export file cleanup', js: true do
let(:export_path) { "#{Dir.tmpdir}/import_file_spec" }
let(:config_hash) { YAML.load_file(Gitlab::ImportExport.config_file).deep_stringify_keys }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
background do
allow_any_instance_of(Gitlab::ImportExport).to receive(:storage_path).and_return(export_path)
diff --git a/spec/features/projects/issuable_counts_caching_spec.rb b/spec/features/projects/issuable_counts_caching_spec.rb
index 703d1cbd327..1804d9dc244 100644
--- a/spec/features/projects/issuable_counts_caching_spec.rb
+++ b/spec/features/projects/issuable_counts_caching_spec.rb
@@ -4,7 +4,7 @@ describe 'Issuable counts caching', :use_clean_rails_memory_store_caching do
let!(:member) { create(:user) }
let!(:member_2) { create(:user) }
let!(:non_member) { create(:user) }
- let!(:project) { create(:empty_project, :public) }
+ let!(:project) { create(:project, :public) }
let!(:open_issue) { create(:issue, project: project) }
let!(:confidential_issue) { create(:issue, :confidential, project: project, author: non_member) }
let!(:closed_issue) { create(:issue, :closed, project: project) }
diff --git a/spec/features/projects/issues/list_spec.rb b/spec/features/projects/issues/list_spec.rb
index c2ca62508a4..9fc03f49f5b 100644
--- a/spec/features/projects/issues/list_spec.rb
+++ b/spec/features/projects/issues/list_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
feature 'Issues List' do
let(:user) { create(:user) }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
background do
project.team << [user, :developer]
diff --git a/spec/features/projects/issues/rss_spec.rb b/spec/features/projects/issues/rss_spec.rb
index d274a1760a4..58eeef8c258 100644
--- a/spec/features/projects/issues/rss_spec.rb
+++ b/spec/features/projects/issues/rss_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
feature 'Project Issues RSS' do
- let(:project) { create(:empty_project, visibility_level: Gitlab::VisibilityLevel::PUBLIC) }
+ let(:project) { create(:project, visibility_level: Gitlab::VisibilityLevel::PUBLIC) }
let(:path) { project_issues_path(project) }
before do
diff --git a/spec/features/projects/labels/issues_sorted_by_priority_spec.rb b/spec/features/projects/labels/issues_sorted_by_priority_spec.rb
index 2b0aead440c..0292a3192d8 100644
--- a/spec/features/projects/labels/issues_sorted_by_priority_spec.rb
+++ b/spec/features/projects/labels/issues_sorted_by_priority_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
feature 'Issue prioritization' do
let(:user) { create(:user) }
- let(:project) { create(:empty_project, name: 'test', namespace: user.namespace) }
+ let(:project) { create(:project, name: 'test', namespace: user.namespace) }
# Labels
let(:label_1) { create(:label, title: 'label_1', project: project, priority: 1) }
diff --git a/spec/features/projects/labels/subscription_spec.rb b/spec/features/projects/labels/subscription_spec.rb
index 3115a643d5d..5716d151250 100644
--- a/spec/features/projects/labels/subscription_spec.rb
+++ b/spec/features/projects/labels/subscription_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
feature 'Labels subscription' do
let(:user) { create(:user) }
let(:group) { create(:group) }
- let(:project) { create(:empty_project, :public, namespace: group) }
+ let(:project) { create(:project, :public, namespace: group) }
let!(:bug) { create(:label, project: project, title: 'bug') }
let!(:feature) { create(:group_label, group: group, title: 'feature') }
diff --git a/spec/features/projects/labels/update_prioritization_spec.rb b/spec/features/projects/labels/update_prioritization_spec.rb
index 223f94ff9f9..8f85e972027 100644
--- a/spec/features/projects/labels/update_prioritization_spec.rb
+++ b/spec/features/projects/labels/update_prioritization_spec.rb
@@ -5,7 +5,7 @@ feature 'Prioritize labels' do
let(:user) { create(:user) }
let(:group) { create(:group) }
- let(:project) { create(:empty_project, :public, namespace: group) }
+ let(:project) { create(:project, :public, namespace: group) }
let!(:bug) { create(:label, project: project, title: 'bug') }
let!(:wontfix) { create(:label, project: project, title: 'wontfix') }
let!(:feature) { create(:group_label, group: group, title: 'feature') }
diff --git a/spec/features/projects/members/anonymous_user_sees_members_spec.rb b/spec/features/projects/members/anonymous_user_sees_members_spec.rb
index a26e7becdb9..bf0990d675d 100644
--- a/spec/features/projects/members/anonymous_user_sees_members_spec.rb
+++ b/spec/features/projects/members/anonymous_user_sees_members_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
feature 'Projects > Members > Anonymous user sees members' do
let(:user) { create(:user) }
let(:group) { create(:group, :public) }
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
background do
project.team << [user, :master]
diff --git a/spec/features/projects/members/group_links_spec.rb b/spec/features/projects/members/group_links_spec.rb
index acda5808313..1c348b987d4 100644
--- a/spec/features/projects/members/group_links_spec.rb
+++ b/spec/features/projects/members/group_links_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
feature 'Projects > Members > Anonymous user sees members', js: true do
let(:user) { create(:user) }
let(:group) { create(:group, :public) }
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
background do
project.team << [user, :master]
diff --git a/spec/features/projects/members/group_member_cannot_leave_group_project_spec.rb b/spec/features/projects/members/group_member_cannot_leave_group_project_spec.rb
index 1fb5e000239..6b450fa4e45 100644
--- a/spec/features/projects/members/group_member_cannot_leave_group_project_spec.rb
+++ b/spec/features/projects/members/group_member_cannot_leave_group_project_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
feature 'Projects > Members > Group member cannot leave group project' do
let(:user) { create(:user) }
let(:group) { create(:group) }
- let(:project) { create(:empty_project, namespace: group) }
+ let(:project) { create(:project, namespace: group) }
background do
group.add_developer(user)
diff --git a/spec/features/projects/members/group_member_cannot_request_access_to_his_group_project_spec.rb b/spec/features/projects/members/group_member_cannot_request_access_to_his_group_project_spec.rb
index 8e3520f9f15..296a80a3c60 100644
--- a/spec/features/projects/members/group_member_cannot_request_access_to_his_group_project_spec.rb
+++ b/spec/features/projects/members/group_member_cannot_request_access_to_his_group_project_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
feature 'Projects > Members > Group member cannot request access to his group project' do
let(:user) { create(:user) }
let(:group) { create(:group) }
- let(:project) { create(:empty_project, namespace: group) }
+ let(:project) { create(:project, namespace: group) }
scenario 'owner does not see the request access button' do
group.add_owner(user)
diff --git a/spec/features/projects/members/group_members_spec.rb b/spec/features/projects/members/group_members_spec.rb
index 154f9f4a26c..c140fece41d 100644
--- a/spec/features/projects/members/group_members_spec.rb
+++ b/spec/features/projects/members/group_members_spec.rb
@@ -4,7 +4,7 @@ feature 'Projects members' do
let(:user) { create(:user) }
let(:developer) { create(:user) }
let(:group) { create(:group, :public, :access_requestable) }
- let(:project) { create(:empty_project, :public, :access_requestable, creator: user, group: group) }
+ let(:project) { create(:project, :public, :access_requestable, creator: user, group: group) }
let(:project_invitee) { create(:project_member, project: project, invite_token: '123', invite_email: 'test1@abc.com', user: nil) }
let(:group_invitee) { create(:group_member, group: group, invite_token: '123', invite_email: 'test2@abc.com', user: nil) }
let(:project_requester) { create(:user) }
diff --git a/spec/features/projects/members/group_requester_cannot_request_access_to_project_spec.rb b/spec/features/projects/members/group_requester_cannot_request_access_to_project_spec.rb
index 6865d721201..c8988aa63a7 100644
--- a/spec/features/projects/members/group_requester_cannot_request_access_to_project_spec.rb
+++ b/spec/features/projects/members/group_requester_cannot_request_access_to_project_spec.rb
@@ -4,7 +4,7 @@ feature 'Projects > Members > Group requester cannot request access to project',
let(:user) { create(:user) }
let(:owner) { create(:user) }
let(:group) { create(:group, :public, :access_requestable) }
- let(:project) { create(:empty_project, :public, :access_requestable, namespace: group) }
+ let(:project) { create(:project, :public, :access_requestable, namespace: group) }
background do
group.add_owner(owner)
diff --git a/spec/features/projects/members/list_spec.rb b/spec/features/projects/members/list_spec.rb
index f9c54d267b5..237c059e595 100644
--- a/spec/features/projects/members/list_spec.rb
+++ b/spec/features/projects/members/list_spec.rb
@@ -6,7 +6,7 @@ feature 'Project members list' do
let(:user1) { create(:user, name: 'John Doe') }
let(:user2) { create(:user, name: 'Mary Jane') }
let(:group) { create(:group) }
- let(:project) { create(:empty_project, namespace: group) }
+ let(:project) { create(:project, namespace: group) }
background do
sign_in(user1)
diff --git a/spec/features/projects/members/master_adds_member_with_expiration_date_spec.rb b/spec/features/projects/members/master_adds_member_with_expiration_date_spec.rb
index b4381ea373e..cd621b6b3ce 100644
--- a/spec/features/projects/members/master_adds_member_with_expiration_date_spec.rb
+++ b/spec/features/projects/members/master_adds_member_with_expiration_date_spec.rb
@@ -5,7 +5,7 @@ feature 'Projects > Members > Master adds member with expiration date', js: true
include ActiveSupport::Testing::TimeHelpers
let(:master) { create(:user) }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let!(:new_member) { create(:user) }
background do
diff --git a/spec/features/projects/members/master_manages_access_requests_spec.rb b/spec/features/projects/members/master_manages_access_requests_spec.rb
index 0f96a7cc70d..eb3c8034873 100644
--- a/spec/features/projects/members/master_manages_access_requests_spec.rb
+++ b/spec/features/projects/members/master_manages_access_requests_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
feature 'Projects > Members > Master manages access requests' do
let(:user) { create(:user) }
let(:master) { create(:user) }
- let(:project) { create(:empty_project, :public, :access_requestable) }
+ let(:project) { create(:project, :public, :access_requestable) }
background do
project.request_access(user)
diff --git a/spec/features/projects/members/member_cannot_request_access_to_his_project_spec.rb b/spec/features/projects/members/member_cannot_request_access_to_his_project_spec.rb
index 7f39f5b2513..04806f8fd9e 100644
--- a/spec/features/projects/members/member_cannot_request_access_to_his_project_spec.rb
+++ b/spec/features/projects/members/member_cannot_request_access_to_his_project_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
feature 'Projects > Members > Member cannot request access to his project' do
let(:member) { create(:user) }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
background do
project.team << [member, :developer]
diff --git a/spec/features/projects/members/owner_cannot_leave_project_spec.rb b/spec/features/projects/members/owner_cannot_leave_project_spec.rb
index 8b6d0aafcf8..15162d01c44 100644
--- a/spec/features/projects/members/owner_cannot_leave_project_spec.rb
+++ b/spec/features/projects/members/owner_cannot_leave_project_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
feature 'Projects > Members > Owner cannot leave project' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
background do
sign_in(project.owner)
diff --git a/spec/features/projects/members/owner_cannot_request_access_to_his_project_spec.rb b/spec/features/projects/members/owner_cannot_request_access_to_his_project_spec.rb
index d838af6d976..c27925c8dc4 100644
--- a/spec/features/projects/members/owner_cannot_request_access_to_his_project_spec.rb
+++ b/spec/features/projects/members/owner_cannot_request_access_to_his_project_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
feature 'Projects > Members > Owner cannot request access to his project' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
background do
sign_in(project.owner)
diff --git a/spec/features/projects/members/sorting_spec.rb b/spec/features/projects/members/sorting_spec.rb
index 45c2647e6e2..afa173c59e5 100644
--- a/spec/features/projects/members/sorting_spec.rb
+++ b/spec/features/projects/members/sorting_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
feature 'Projects > Members > Sorting' do
let(:master) { create(:user, name: 'John Doe') }
let(:developer) { create(:user, name: 'Mary Jane', last_sign_in_at: 5.days.ago) }
- let(:project) { create(:empty_project, namespace: master.namespace, creator: master) }
+ let(:project) { create(:project, namespace: master.namespace, creator: master) }
background do
create(:project_member, :developer, user: developer, project: project, created_at: 3.days.ago)
diff --git a/spec/features/projects/milestones/milestone_spec.rb b/spec/features/projects/milestones/milestone_spec.rb
index b1c38ecc9ab..30de3e83fbb 100644
--- a/spec/features/projects/milestones/milestone_spec.rb
+++ b/spec/features/projects/milestones/milestone_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
feature 'Project milestone' do
let(:user) { create(:user) }
- let(:project) { create(:empty_project, name: 'test', namespace: user.namespace) }
+ let(:project) { create(:project, name: 'test', namespace: user.namespace) }
let(:milestone) { create(:milestone, project: project) }
before do
diff --git a/spec/features/projects/milestones/milestones_sorting_spec.rb b/spec/features/projects/milestones/milestones_sorting_spec.rb
index 4bd1929ac1e..c531b81e04d 100644
--- a/spec/features/projects/milestones/milestones_sorting_spec.rb
+++ b/spec/features/projects/milestones/milestones_sorting_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
feature 'Milestones sorting', :js do
include SortingHelper
let(:user) { create(:user) }
- let(:project) { create(:empty_project, name: 'test', namespace: user.namespace) }
+ let(:project) { create(:project, name: 'test', namespace: user.namespace) }
before do
# Milestones
diff --git a/spec/features/projects/milestones/new_spec.rb b/spec/features/projects/milestones/new_spec.rb
index 7cfcccda439..f7900210fe6 100644
--- a/spec/features/projects/milestones/new_spec.rb
+++ b/spec/features/projects/milestones/new_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
feature 'Creating a new project milestone', :js do
let(:user) { create(:user) }
- let(:project) { create(:empty_project, name: 'test', namespace: user.namespace) }
+ let(:project) { create(:project, name: 'test', namespace: user.namespace) }
before do
login_as(user)
diff --git a/spec/features/projects/pages_spec.rb b/spec/features/projects/pages_spec.rb
index 42f23ee5dec..013ed6f2e58 100644
--- a/spec/features/projects/pages_spec.rb
+++ b/spec/features/projects/pages_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
feature 'Pages' do
- given(:project) { create(:empty_project) }
+ given(:project) { create(:project) }
given(:user) { create(:user) }
given(:role) { :master }
diff --git a/spec/features/projects/pipeline_schedules_spec.rb b/spec/features/projects/pipeline_schedules_spec.rb
index 605415d2af4..24b335a7068 100644
--- a/spec/features/projects/pipeline_schedules_spec.rb
+++ b/spec/features/projects/pipeline_schedules_spec.rb
@@ -219,6 +219,25 @@ feature 'Pipeline Schedules', :js do
end
end
end
+
+ context 'when active is true and next_run_at is NULL' do
+ background do
+ create(:ci_pipeline_schedule, project: project, owner: user).tap do |pipeline_schedule|
+ pipeline_schedule.update_attribute(:cron, nil) # Consequently next_run_at will be nil
+ end
+ end
+
+ scenario 'user edit and recover the problematic pipeline schedule' do
+ visit_pipelines_schedules
+ find(".content-list .pipeline-schedule-table-row:nth-child(1) .btn-group a[title='Edit']").click
+ fill_in 'schedule_cron', with: '* 1 2 3 4'
+ click_button 'Save pipeline schedule'
+
+ page.within('.pipeline-schedule-table-row:nth-child(1)') do
+ expect(page).to have_css(".next-run-cell time")
+ end
+ end
+ end
end
context 'logged in as non-member' do
diff --git a/spec/features/projects/pipelines/pipeline_spec.rb b/spec/features/projects/pipelines/pipeline_spec.rb
index 0b626749275..acbc5b046e6 100644
--- a/spec/features/projects/pipelines/pipeline_spec.rb
+++ b/spec/features/projects/pipelines/pipeline_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe 'Pipeline', :js do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:user) { create(:user) }
before do
diff --git a/spec/features/projects/pipelines/pipelines_spec.rb b/spec/features/projects/pipelines/pipelines_spec.rb
index 59dff22eca3..f7b40cb1820 100644
--- a/spec/features/projects/pipelines/pipelines_spec.rb
+++ b/spec/features/projects/pipelines/pipelines_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe 'Pipelines', :js do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
context 'when user is logged in' do
let(:user) { create(:user) }
diff --git a/spec/features/projects/project_settings_spec.rb b/spec/features/projects/project_settings_spec.rb
index 6001bcfff0a..80d91e5915f 100644
--- a/spec/features/projects/project_settings_spec.rb
+++ b/spec/features/projects/project_settings_spec.rb
@@ -4,7 +4,7 @@ describe 'Edit Project Settings' do
include Select2Helper
let(:user) { create(:user) }
- let(:project) { create(:empty_project, namespace: user.namespace, path: 'gitlab', name: 'sample') }
+ let(:project) { create(:project, namespace: user.namespace, path: 'gitlab', name: 'sample') }
before do
sign_in(user)
@@ -14,7 +14,9 @@ describe 'Edit Project Settings' do
it 'shows errors for invalid project name' do
visit edit_project_path(project)
fill_in 'project_name_edit', with: 'foo&bar'
- click_button 'Save changes'
+ page.within('.general-settings') do
+ click_button 'Save changes'
+ end
expect(page).to have_field 'project_name_edit', with: 'foo&bar'
expect(page).to have_content "Name can contain only letters, digits, emojis, '_', '.', dash, space. It must start with letter, digit, emoji or '_'."
expect(page).to have_button 'Save changes'
@@ -23,7 +25,9 @@ describe 'Edit Project Settings' do
it 'shows a successful notice when the project is updated' do
visit edit_project_path(project)
fill_in 'project_name_edit', with: 'hello world'
- click_button 'Save changes'
+ page.within('.general-settings') do
+ click_button 'Save changes'
+ end
expect(page).to have_content "Project 'hello world' was successfully updated."
end
end
@@ -61,7 +65,7 @@ describe 'Edit Project Settings' do
TestEnv.clean_test_path
end
- after(:example) do
+ after do
TestEnv.clean_test_path
end
@@ -86,7 +90,7 @@ describe 'Edit Project Settings' do
it 'overrides the redirect' do
old_path = project_path(project)
rename_project(project, path: 'bar')
- new_project = create(:empty_project, namespace: user.namespace, path: 'gitlabhq', name: 'quz')
+ new_project = create(:project, namespace: user.namespace, path: 'gitlabhq', name: 'quz')
visit old_path
expect(current_path).to eq(old_path)
expect(find('h1.title')).to have_content(new_project.name)
@@ -103,11 +107,11 @@ describe 'Edit Project Settings' do
TestEnv.clean_test_path
end
- before(:example) do
+ before do
group.add_owner(user)
end
- after(:example) do
+ after do
TestEnv.clean_test_path
end
@@ -132,7 +136,7 @@ describe 'Edit Project Settings' do
it 'overrides the redirect' do
old_path = project_path(project)
transfer_project(project, group)
- new_project = create(:empty_project, namespace: user.namespace, path: 'gitlabhq', name: 'quz')
+ new_project = create(:project, namespace: user.namespace, path: 'gitlabhq', name: 'quz')
visit old_path
expect(current_path).to eq(old_path)
expect(find('h1.title')).to have_content(new_project.name)
diff --git a/spec/features/projects/services/jira_service_spec.rb b/spec/features/projects/services/jira_service_spec.rb
index ecaa69c49dd..65e3a487d4b 100644
--- a/spec/features/projects/services/jira_service_spec.rb
+++ b/spec/features/projects/services/jira_service_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
feature 'Setup Jira service', :js do
let(:user) { create(:user) }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:service) { project.create_jira_service }
let(:url) { 'http://jira.example.com' }
diff --git a/spec/features/projects/services/mattermost_slash_command_spec.rb b/spec/features/projects/services/mattermost_slash_command_spec.rb
index 134d7e5e8b7..95d5e8b14b9 100644
--- a/spec/features/projects/services/mattermost_slash_command_spec.rb
+++ b/spec/features/projects/services/mattermost_slash_command_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
feature 'Setup Mattermost slash commands', :js do
let(:user) { create(:user) }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:service) { project.create_mattermost_slash_commands_service }
let(:mattermost_enabled) { true }
diff --git a/spec/features/projects/services/slack_service_spec.rb b/spec/features/projects/services/slack_service_spec.rb
index 824cae261e0..c10ec5e2987 100644
--- a/spec/features/projects/services/slack_service_spec.rb
+++ b/spec/features/projects/services/slack_service_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
feature 'Projects > Slack service > Setup events' do
let(:user) { create(:user) }
let(:service) { SlackService.new }
- let(:project) { create(:empty_project, slack_service: service) }
+ let(:project) { create(:project, slack_service: service) }
background do
service.fields
diff --git a/spec/features/projects/services/slack_slash_command_spec.rb b/spec/features/projects/services/slack_slash_command_spec.rb
index 6002c589fba..a8baf126269 100644
--- a/spec/features/projects/services/slack_slash_command_spec.rb
+++ b/spec/features/projects/services/slack_slash_command_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
feature 'Slack slash commands' do
given(:user) { create(:user) }
- given(:project) { create(:empty_project) }
+ given(:project) { create(:project) }
given(:service) { project.create_slack_slash_commands_service }
background do
diff --git a/spec/features/projects/settings/integration_settings_spec.rb b/spec/features/projects/settings/integration_settings_spec.rb
index 1de4918e142..d932c4e4d9a 100644
--- a/spec/features/projects/settings/integration_settings_spec.rb
+++ b/spec/features/projects/settings/integration_settings_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
feature 'Integration settings' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:user) { create(:user) }
let(:role) { :developer }
let(:integrations_path) { project_settings_integrations_path(project) }
diff --git a/spec/features/projects/settings/merge_requests_settings_spec.rb b/spec/features/projects/settings/merge_requests_settings_spec.rb
index 796e2026905..104ce08d9f3 100644
--- a/spec/features/projects/settings/merge_requests_settings_spec.rb
+++ b/spec/features/projects/settings/merge_requests_settings_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
feature 'Project settings > Merge Requests', :js do
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:user) { create(:user) }
background do
@@ -20,6 +20,9 @@ feature 'Project settings > Merge Requests', :js do
expect(page).to have_content('Only allow merge requests to be merged if all discussions are resolved')
select 'Disabled', from: "project_project_feature_attributes_merge_requests_access_level"
+ within('.sharing-permissions-form') do
+ click_on('Save changes')
+ end
expect(page).not_to have_content('Only allow merge requests to be merged if the pipeline succeeds')
expect(page).not_to have_content('Only allow merge requests to be merged if all discussions are resolved')
@@ -37,6 +40,9 @@ feature 'Project settings > Merge Requests', :js do
expect(page).to have_content('Only allow merge requests to be merged if all discussions are resolved')
select 'Everyone with access', from: "project_project_feature_attributes_builds_access_level"
+ within('.sharing-permissions-form') do
+ click_on('Save changes')
+ end
expect(page).to have_content('Only allow merge requests to be merged if the pipeline succeeds')
expect(page).to have_content('Only allow merge requests to be merged if all discussions are resolved')
@@ -55,6 +61,9 @@ feature 'Project settings > Merge Requests', :js do
expect(page).not_to have_content('Only allow merge requests to be merged if all discussions are resolved')
select 'Everyone with access', from: "project_project_feature_attributes_merge_requests_access_level"
+ within('.sharing-permissions-form') do
+ click_on('Save changes')
+ end
expect(page).to have_content('Only allow merge requests to be merged if the pipeline succeeds')
expect(page).to have_content('Only allow merge requests to be merged if all discussions are resolved')
@@ -73,7 +82,9 @@ feature 'Project settings > Merge Requests', :js do
scenario 'when unchecked sets :printing_merge_request_link_enabled to false' do
uncheck('project_printing_merge_request_link_enabled')
- click_on('Save')
+ within('.merge-request-settings-form') do
+ click_on('Save changes')
+ end
# Wait for save to complete and page to reload
checkbox = find_field('project_printing_merge_request_link_enabled')
diff --git a/spec/features/projects/settings/pipelines_settings_spec.rb b/spec/features/projects/settings/pipelines_settings_spec.rb
index f24d7ff64d0..232d796a200 100644
--- a/spec/features/projects/settings/pipelines_settings_spec.rb
+++ b/spec/features/projects/settings/pipelines_settings_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
feature "Pipelines settings" do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:user) { create(:user) }
let(:role) { :developer }
diff --git a/spec/features/projects/settings/visibility_settings_spec.rb b/spec/features/projects/settings/visibility_settings_spec.rb
index 1e705d211ea..1756c7d00fe 100644
--- a/spec/features/projects/settings/visibility_settings_spec.rb
+++ b/spec/features/projects/settings/visibility_settings_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
feature 'Visibility settings', js: true do
let(:user) { create(:user) }
- let(:project) { create(:empty_project, namespace: user.namespace, visibility_level: 20) }
+ let(:project) { create(:project, namespace: user.namespace, visibility_level: 20) }
context 'as owner' do
before do
diff --git a/spec/features/projects/shortcuts_spec.rb b/spec/features/projects/shortcuts_spec.rb
index 2c6d0a56311..bf18c444c3d 100644
--- a/spec/features/projects/shortcuts_spec.rb
+++ b/spec/features/projects/shortcuts_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
feature 'Project shortcuts' do
- let(:project) { create(:empty_project, name: 'Victorialand') }
+ let(:project) { create(:project, name: 'Victorialand') }
let(:user) { create(:user) }
describe 'On a project', js: true do
diff --git a/spec/features/projects/snippets/create_snippet_spec.rb b/spec/features/projects/snippets/create_snippet_spec.rb
index 7f0e7e3116c..3e79dba3f19 100644
--- a/spec/features/projects/snippets/create_snippet_spec.rb
+++ b/spec/features/projects/snippets/create_snippet_spec.rb
@@ -4,7 +4,7 @@ feature 'Create Snippet', :js do
include DropzoneHelper
let(:user) { create(:user) }
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
def fill_form
fill_in 'project_snippet_title', with: 'My Snippet Title'
diff --git a/spec/features/projects/snippets_spec.rb b/spec/features/projects/snippets_spec.rb
index 0822684a42c..1cfbbb4cb62 100644
--- a/spec/features/projects/snippets_spec.rb
+++ b/spec/features/projects/snippets_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe 'Project snippets', :js do
context 'when the project has snippets' do
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let!(:snippets) { create_list(:project_snippet, 2, :public, author: project.owner, project: project) }
let!(:other_snippet) { create(:project_snippet) }
diff --git a/spec/features/projects/sub_group_issuables_spec.rb b/spec/features/projects/sub_group_issuables_spec.rb
index 262dcc0abff..aaf64d42515 100644
--- a/spec/features/projects/sub_group_issuables_spec.rb
+++ b/spec/features/projects/sub_group_issuables_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe 'Subgroup Issuables', :js, :nested_groups do
let!(:group) { create(:group, name: 'group') }
let!(:subgroup) { create(:group, parent: group, name: 'subgroup') }
- let!(:project) { create(:empty_project, namespace: subgroup, name: 'project') }
+ let!(:project) { create(:project, namespace: subgroup, name: 'project') }
let(:user) { create(:user) }
before do
diff --git a/spec/features/projects/tags/download_buttons_spec.rb b/spec/features/projects/tags/download_buttons_spec.rb
index a6c5a486bcc..d38a5b1324b 100644
--- a/spec/features/projects/tags/download_buttons_spec.rb
+++ b/spec/features/projects/tags/download_buttons_spec.rb
@@ -5,7 +5,7 @@ feature 'Download buttons in tags page' do
given(:role) { :developer }
given(:status) { 'success' }
given(:tag) { 'v1.0.0' }
- given(:project) { create(:project) }
+ given(:project) { create(:project, :repository) }
given(:pipeline) do
create(:ci_pipeline,
diff --git a/spec/features/projects/user_edits_files_spec.rb b/spec/features/projects/user_edits_files_spec.rb
index 8ae89c980b9..3129aad8473 100644
--- a/spec/features/projects/user_edits_files_spec.rb
+++ b/spec/features/projects/user_edits_files_spec.rb
@@ -1,10 +1,6 @@
require 'spec_helper'
describe 'User edits files' do
- let(:fork_message) do
- "You're not allowed to make changes to this project directly. "\
- "A fork of this project has been created that you can make changes in, so you can submit a merge request."
- end
let(:project) { create(:project, :repository, name: 'Shop') }
let(:project2) { create(:project, :repository, name: 'Another Project', path: 'another-project') }
let(:project_tree_path_root_ref) { project_tree_path(project, project.repository.root_ref) }
@@ -24,6 +20,9 @@ describe 'User edits files' do
it 'inserts a content of a file', js: true do
click_link('.gitignore')
find('.js-edit-blob').click
+
+ wait_for_requests
+
execute_script("ace.edit('editor').setValue('*.rbca')")
expect(evaluate_script('ace.edit("editor").getValue()')).to eq('*.rbca')
@@ -39,6 +38,9 @@ describe 'User edits files' do
it 'commits an edited file', js: true do
click_link('.gitignore')
find('.js-edit-blob').click
+
+ wait_for_requests
+
execute_script("ace.edit('editor').setValue('*.rbca')")
fill_in(:commit_message, with: 'New commit message', visible: true)
click_button('Commit changes')
@@ -53,6 +55,9 @@ describe 'User edits files' do
it 'commits an edited file to a new branch', js: true do
click_link('.gitignore')
find('.js-edit-blob').click
+
+ wait_for_requests
+
execute_script("ace.edit('editor').setValue('*.rbca')")
fill_in(:commit_message, with: 'New commit message', visible: true)
fill_in(:branch_name, with: 'new_branch_name', visible: true)
@@ -69,6 +74,9 @@ describe 'User edits files' do
it 'shows the diff of an edited file', js: true do
click_link('.gitignore')
find('.js-edit-blob').click
+
+ wait_for_requests
+
execute_script("ace.edit('editor').setValue('*.rbca')")
click_link('Preview changes')
@@ -91,7 +99,12 @@ describe 'User edits files' do
click_link('Fork')
- expect(page).to have_content(fork_message)
+ expect(page).to have_content(
+ "You're not allowed to make changes to this project directly. "\
+ "A fork of this project has been created that you can make changes in, so you can submit a merge request."
+ )
+
+ wait_for_requests
execute_script("ace.edit('editor').setValue('*.rbca')")
@@ -106,6 +119,9 @@ describe 'User edits files' do
expect(page).to have_button('Cancel')
click_link('Fork')
+
+ wait_for_requests
+
execute_script("ace.edit('editor').setValue('*.rbca')")
fill_in(:commit_message, with: 'New commit message', visible: true)
click_button('Commit changes')
diff --git a/spec/features/projects/wiki/markdown_preview_spec.rb b/spec/features/projects/wiki/markdown_preview_spec.rb
index dbe98a38197..9a4ccf3c54d 100644
--- a/spec/features/projects/wiki/markdown_preview_spec.rb
+++ b/spec/features/projects/wiki/markdown_preview_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
feature 'Projects > Wiki > User previews markdown changes', js: true do
let(:user) { create(:user) }
- let(:project) { create(:empty_project, namespace: user.namespace) }
+ let(:project) { create(:project, namespace: user.namespace) }
let(:wiki_content) do
<<-HEREDOC
[regular link](regular)
@@ -38,10 +38,10 @@ feature 'Projects > Wiki > User previews markdown changes', js: true do
expect(page).to have_content("regular link")
- expect(page.html).to include("<a href=\"/#{project.path_with_namespace}/wikis/regular\">regular link</a>")
- expect(page.html).to include("<a href=\"/#{project.path_with_namespace}/wikis/a/b/relative\">relative link 1</a>")
- expect(page.html).to include("<a href=\"/#{project.path_with_namespace}/wikis/a/b/c/relative\">relative link 2</a>")
- expect(page.html).to include("<a href=\"/#{project.path_with_namespace}/wikis/a/b/c/e/f/relative\">relative link 3</a>")
+ expect(page.html).to include("<a href=\"/#{project.full_path}/wikis/regular\">regular link</a>")
+ expect(page.html).to include("<a href=\"/#{project.full_path}/wikis/a/b/relative\">relative link 1</a>")
+ expect(page.html).to include("<a href=\"/#{project.full_path}/wikis/a/b/c/relative\">relative link 2</a>")
+ expect(page.html).to include("<a href=\"/#{project.full_path}/wikis/a/b/c/e/f/relative\">relative link 3</a>")
end
end
@@ -60,10 +60,10 @@ feature 'Projects > Wiki > User previews markdown changes', js: true do
expect(page).to have_content("regular link")
- expect(page.html).to include("<a href=\"/#{project.path_with_namespace}/wikis/regular\">regular link</a>")
- expect(page.html).to include("<a href=\"/#{project.path_with_namespace}/wikis/a-page/b-page/relative\">relative link 1</a>")
- expect(page.html).to include("<a href=\"/#{project.path_with_namespace}/wikis/a-page/b-page/c-page/relative\">relative link 2</a>")
- expect(page.html).to include("<a href=\"/#{project.path_with_namespace}/wikis/a-page/b-page/c-page/e/f/relative\">relative link 3</a>")
+ expect(page.html).to include("<a href=\"/#{project.full_path}/wikis/regular\">regular link</a>")
+ expect(page.html).to include("<a href=\"/#{project.full_path}/wikis/a-page/b-page/relative\">relative link 1</a>")
+ expect(page.html).to include("<a href=\"/#{project.full_path}/wikis/a-page/b-page/c-page/relative\">relative link 2</a>")
+ expect(page.html).to include("<a href=\"/#{project.full_path}/wikis/a-page/b-page/c-page/e/f/relative\">relative link 3</a>")
end
end
@@ -82,10 +82,10 @@ feature 'Projects > Wiki > User previews markdown changes', js: true do
expect(page).to have_content("regular link")
- expect(page.html).to include("<a href=\"/#{project.path_with_namespace}/wikis/regular\">regular link</a>")
- expect(page.html).to include("<a href=\"/#{project.path_with_namespace}/wikis/a-page/b-page/relative\">relative link 1</a>")
- expect(page.html).to include("<a href=\"/#{project.path_with_namespace}/wikis/a-page/b-page/c-page/relative\">relative link 2</a>")
- expect(page.html).to include("<a href=\"/#{project.path_with_namespace}/wikis/a-page/b-page/c-page/e/f/relative\">relative link 3</a>")
+ expect(page.html).to include("<a href=\"/#{project.full_path}/wikis/regular\">regular link</a>")
+ expect(page.html).to include("<a href=\"/#{project.full_path}/wikis/a-page/b-page/relative\">relative link 1</a>")
+ expect(page.html).to include("<a href=\"/#{project.full_path}/wikis/a-page/b-page/c-page/relative\">relative link 2</a>")
+ expect(page.html).to include("<a href=\"/#{project.full_path}/wikis/a-page/b-page/c-page/e/f/relative\">relative link 3</a>")
end
end
end
@@ -115,10 +115,10 @@ feature 'Projects > Wiki > User previews markdown changes', js: true do
expect(page).to have_content("regular link")
- expect(page.html).to include("<a href=\"/#{project.path_with_namespace}/wikis/regular\">regular link</a>")
- expect(page.html).to include("<a href=\"/#{project.path_with_namespace}/wikis/a/b/relative\">relative link 1</a>")
- expect(page.html).to include("<a href=\"/#{project.path_with_namespace}/wikis/a/b/c/relative\">relative link 2</a>")
- expect(page.html).to include("<a href=\"/#{project.path_with_namespace}/wikis/a/b/c/e/f/relative\">relative link 3</a>")
+ expect(page.html).to include("<a href=\"/#{project.full_path}/wikis/regular\">regular link</a>")
+ expect(page.html).to include("<a href=\"/#{project.full_path}/wikis/a/b/relative\">relative link 1</a>")
+ expect(page.html).to include("<a href=\"/#{project.full_path}/wikis/a/b/c/relative\">relative link 2</a>")
+ expect(page.html).to include("<a href=\"/#{project.full_path}/wikis/a/b/c/e/f/relative\">relative link 3</a>")
end
end
@@ -132,10 +132,10 @@ feature 'Projects > Wiki > User previews markdown changes', js: true do
expect(page).to have_content("regular link")
- expect(page.html).to include("<a href=\"/#{project.path_with_namespace}/wikis/regular\">regular link</a>")
- expect(page.html).to include("<a href=\"/#{project.path_with_namespace}/wikis/a-page/b-page/relative\">relative link 1</a>")
- expect(page.html).to include("<a href=\"/#{project.path_with_namespace}/wikis/a-page/b-page/c-page/relative\">relative link 2</a>")
- expect(page.html).to include("<a href=\"/#{project.path_with_namespace}/wikis/a-page/b-page/c-page/e/f/relative\">relative link 3</a>")
+ expect(page.html).to include("<a href=\"/#{project.full_path}/wikis/regular\">regular link</a>")
+ expect(page.html).to include("<a href=\"/#{project.full_path}/wikis/a-page/b-page/relative\">relative link 1</a>")
+ expect(page.html).to include("<a href=\"/#{project.full_path}/wikis/a-page/b-page/c-page/relative\">relative link 2</a>")
+ expect(page.html).to include("<a href=\"/#{project.full_path}/wikis/a-page/b-page/c-page/e/f/relative\">relative link 3</a>")
end
end
@@ -149,10 +149,10 @@ feature 'Projects > Wiki > User previews markdown changes', js: true do
expect(page).to have_content("regular link")
- expect(page.html).to include("<a href=\"/#{project.path_with_namespace}/wikis/regular\">regular link</a>")
- expect(page.html).to include("<a href=\"/#{project.path_with_namespace}/wikis/a-page/b-page/relative\">relative link 1</a>")
- expect(page.html).to include("<a href=\"/#{project.path_with_namespace}/wikis/a-page/b-page/c-page/relative\">relative link 2</a>")
- expect(page.html).to include("<a href=\"/#{project.path_with_namespace}/wikis/a-page/b-page/c-page/e/f/relative\">relative link 3</a>")
+ expect(page.html).to include("<a href=\"/#{project.full_path}/wikis/regular\">regular link</a>")
+ expect(page.html).to include("<a href=\"/#{project.full_path}/wikis/a-page/b-page/relative\">relative link 1</a>")
+ expect(page.html).to include("<a href=\"/#{project.full_path}/wikis/a-page/b-page/c-page/relative\">relative link 2</a>")
+ expect(page.html).to include("<a href=\"/#{project.full_path}/wikis/a-page/b-page/c-page/e/f/relative\">relative link 3</a>")
end
end
end
diff --git a/spec/features/projects/wiki/shortcuts_spec.rb b/spec/features/projects/wiki/shortcuts_spec.rb
index 2c668185666..eaff5f876b6 100644
--- a/spec/features/projects/wiki/shortcuts_spec.rb
+++ b/spec/features/projects/wiki/shortcuts_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
feature 'Wiki shortcuts', :js do
let(:user) { create(:user) }
- let(:project) { create(:empty_project, namespace: user.namespace) }
+ let(:project) { create(:project, namespace: user.namespace) }
let(:wiki_page) do
WikiPages::CreateService.new(project, user, title: 'home', content: 'Home page').execute
end
diff --git a/spec/features/projects/wiki/user_creates_wiki_page_spec.rb b/spec/features/projects/wiki/user_creates_wiki_page_spec.rb
index 78c619f6301..9d66f482c8d 100644
--- a/spec/features/projects/wiki/user_creates_wiki_page_spec.rb
+++ b/spec/features/projects/wiki/user_creates_wiki_page_spec.rb
@@ -11,7 +11,7 @@ feature 'Projects > Wiki > User creates wiki page', :js do
end
context 'in the user namespace' do
- let(:project) { create(:empty_project, namespace: user.namespace) }
+ let(:project) { create(:project, namespace: user.namespace) }
context 'when wiki is empty' do
before do
@@ -157,7 +157,7 @@ feature 'Projects > Wiki > User creates wiki page', :js do
end
context 'in a group namespace' do
- let(:project) { create(:empty_project, namespace: create(:group, :public)) }
+ let(:project) { create(:project, namespace: create(:group, :public)) }
context 'when wiki is empty' do
before do
diff --git a/spec/features/projects/wiki/user_git_access_wiki_page_spec.rb b/spec/features/projects/wiki/user_git_access_wiki_page_spec.rb
index 9c58e336605..9a92622ba2b 100644
--- a/spec/features/projects/wiki/user_git_access_wiki_page_spec.rb
+++ b/spec/features/projects/wiki/user_git_access_wiki_page_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe 'Projects > Wiki > User views Git access wiki page' do
let(:user) { create(:user) }
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:wiki_page) do
WikiPages::CreateService.new(
project,
@@ -20,7 +20,7 @@ describe 'Projects > Wiki > User views Git access wiki page' do
visit project_wiki_path(project, wiki_page)
click_link 'Clone repository'
- expect(page).to have_text("Clone repository #{project.wiki.path_with_namespace}")
+ expect(page).to have_text("Clone repository #{project.wiki.full_path}")
expect(page).to have_text(project.wiki.http_url_to_repo)
end
end
diff --git a/spec/features/projects/wiki/user_updates_wiki_page_spec.rb b/spec/features/projects/wiki/user_updates_wiki_page_spec.rb
index 8271428582d..64a80aec205 100644
--- a/spec/features/projects/wiki/user_updates_wiki_page_spec.rb
+++ b/spec/features/projects/wiki/user_updates_wiki_page_spec.rb
@@ -12,7 +12,7 @@ feature 'Projects > Wiki > User updates wiki page' do
end
context 'in the user namespace' do
- let(:project) { create(:empty_project, namespace: user.namespace) }
+ let(:project) { create(:project, namespace: user.namespace) }
context 'the home page' do
scenario 'success when the wiki content is not empty' do
@@ -55,7 +55,7 @@ feature 'Projects > Wiki > User updates wiki page' do
scenario 'page has been updated since the user opened the edit page' do
click_link 'Edit'
- wiki_page.update('Update')
+ wiki_page.update(content: 'Update')
click_button 'Save changes'
@@ -64,7 +64,7 @@ feature 'Projects > Wiki > User updates wiki page' do
end
context 'in a group namespace' do
- let(:project) { create(:empty_project, namespace: create(:group, :public)) }
+ let(:project) { create(:project, namespace: create(:group, :public)) }
scenario 'the home page' do
click_link 'Edit'
diff --git a/spec/features/projects/wiki/user_views_project_wiki_page_spec.rb b/spec/features/projects/wiki/user_views_project_wiki_page_spec.rb
index 4f94ab1a609..92e96f11219 100644
--- a/spec/features/projects/wiki/user_views_project_wiki_page_spec.rb
+++ b/spec/features/projects/wiki/user_views_project_wiki_page_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
feature 'Projects > Wiki > User views the wiki page' do
let(:user) { create(:user) }
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:old_page_version_id) { wiki_page.versions.last.id }
let(:wiki_page) do
WikiPages::CreateService.new(
diff --git a/spec/features/projects/wiki/user_views_wiki_in_project_page_spec.rb b/spec/features/projects/wiki/user_views_wiki_in_project_page_spec.rb
index 8d1e6f66039..cf9fe4c1ad1 100644
--- a/spec/features/projects/wiki/user_views_wiki_in_project_page_spec.rb
+++ b/spec/features/projects/wiki/user_views_wiki_in_project_page_spec.rb
@@ -10,7 +10,7 @@ describe 'Projects > Wiki > User views wiki in project page' do
context 'when repository is disabled for project' do
let(:project) do
- create(:empty_project,
+ create(:project,
:repository_disabled,
:merge_requests_disabled,
:builds_disabled)
diff --git a/spec/features/projects_spec.rb b/spec/features/projects_spec.rb
index 3295f7f9174..d3d7915bebf 100644
--- a/spec/features/projects_spec.rb
+++ b/spec/features/projects_spec.rb
@@ -1,6 +1,27 @@
require 'spec_helper'
feature 'Project' do
+ describe 'creating from template' do
+ let(:user) { create(:user) }
+ let(:template) { Gitlab::ProjectTemplate.find(:rails) }
+
+ before do
+ sign_in user
+ visit new_project_path
+ end
+
+ it "allows creation from templates" do
+ page.choose(template.name)
+ fill_in("project_path", with: template.name)
+
+ page.within '#content-body' do
+ click_button "Create project"
+ end
+
+ expect(page).to have_content 'This project Loading..'
+ end
+ end
+
describe 'description' do
let(:project) { create(:project, :repository) }
let(:path) { project_path(project) }
@@ -36,7 +57,7 @@ feature 'Project' do
describe 'remove forked relationship', js: true do
let(:user) { create(:user) }
- let(:project) { create(:empty_project, namespace: user.namespace) }
+ let(:project) { create(:project, namespace: user.namespace) }
before do
sign_in user
@@ -57,7 +78,7 @@ feature 'Project' do
describe 'removal', js: true do
let(:user) { create(:user, username: 'test', name: 'test') }
- let(:project) { create(:empty_project, namespace: user.namespace, name: 'project1') }
+ let(:project) { create(:project, namespace: user.namespace, name: 'project1') }
before do
sign_in(user)
@@ -76,7 +97,7 @@ feature 'Project' do
describe 'project title' do
let(:user) { create(:user) }
- let(:project) { create(:empty_project, namespace: user.namespace) }
+ let(:project) { create(:project, namespace: user.namespace) }
before do
sign_in(user)
@@ -92,8 +113,8 @@ feature 'Project' do
describe 'project title' do
let(:user) { create(:user) }
- let(:project) { create(:empty_project, namespace: user.namespace) }
- let(:project2) { create(:empty_project, namespace: user.namespace, path: 'test') }
+ let(:project) { create(:project, namespace: user.namespace) }
+ let(:project2) { create(:project, namespace: user.namespace, path: 'test') }
let(:issue) { create(:issue, project: project) }
context 'on issues page', js: true do
@@ -146,6 +167,21 @@ feature 'Project' do
end
end
+ describe 'activity view' do
+ let(:user) { create(:user, project_view: 'activity') }
+ let(:project) { create(:project, :repository) }
+
+ before do
+ project.team << [user, :master]
+ sign_in user
+ visit project_path(project)
+ end
+
+ it 'loads activity', :js do
+ expect(page).to have_selector('.event-item')
+ end
+ end
+
def remove_with_confirm(button_text, confirm_with)
click_button button_text
fill_in 'confirm_name_input', with: confirm_with
diff --git a/spec/features/protected_tags_spec.rb b/spec/features/protected_tags_spec.rb
index c9ba1a8c088..8abd4403065 100644
--- a/spec/features/protected_tags_spec.rb
+++ b/spec/features/protected_tags_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-feature 'Projected Tags', js: true do
+feature 'Protected Tags', js: true do
let(:user) { create(:user, :admin) }
let(:project) { create(:project, :repository) }
diff --git a/spec/features/reportable_note/commit_spec.rb b/spec/features/reportable_note/commit_spec.rb
index 1074eb62b33..3bf25221e36 100644
--- a/spec/features/reportable_note/commit_spec.rb
+++ b/spec/features/reportable_note/commit_spec.rb
@@ -4,7 +4,7 @@ describe 'Reportable note on commit', :js do
include RepoHelpers
let(:user) { create(:user) }
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
before do
project.add_master(user)
diff --git a/spec/features/reportable_note/issue_spec.rb b/spec/features/reportable_note/issue_spec.rb
index 9964a32db2e..21e96f6f103 100644
--- a/spec/features/reportable_note/issue_spec.rb
+++ b/spec/features/reportable_note/issue_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe 'Reportable note on issue', :js do
let(:user) { create(:user) }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:issue) { create(:issue, project: project) }
let!(:note) { create(:note_on_issue, noteable: issue, project: project) }
diff --git a/spec/features/reportable_note/merge_request_spec.rb b/spec/features/reportable_note/merge_request_spec.rb
index a491abdb6cb..bb296546e06 100644
--- a/spec/features/reportable_note/merge_request_spec.rb
+++ b/spec/features/reportable_note/merge_request_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe 'Reportable note on merge request', :js do
let(:user) { create(:user) }
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:merge_request) { create(:merge_request, source_project: project) }
before do
diff --git a/spec/features/reportable_note/snippets_spec.rb b/spec/features/reportable_note/snippets_spec.rb
index 9a14024684c..f1e48ed46be 100644
--- a/spec/features/reportable_note/snippets_spec.rb
+++ b/spec/features/reportable_note/snippets_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe 'Reportable note on snippets', :js do
let(:user) { create(:user) }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
before do
project.add_master(user)
diff --git a/spec/features/runners_spec.rb b/spec/features/runners_spec.rb
index 1725b70acf3..cac31c34ad1 100644
--- a/spec/features/runners_spec.rb
+++ b/spec/features/runners_spec.rb
@@ -9,13 +9,13 @@ describe "Runners" do
describe "specific runners" do
before do
- @project = FactoryGirl.create :empty_project, shared_runners_enabled: false
+ @project = FactoryGirl.create :project, shared_runners_enabled: false
@project.team << [user, :master]
- @project2 = FactoryGirl.create :empty_project
+ @project2 = FactoryGirl.create :project
@project2.team << [user, :master]
- @project3 = FactoryGirl.create :empty_project
+ @project3 = FactoryGirl.create :project
@project3.team << [user, :developer]
@shared_runner = FactoryGirl.create :ci_runner, :shared
@@ -70,7 +70,7 @@ describe "Runners" do
describe "shared runners" do
before do
- @project = FactoryGirl.create :empty_project, shared_runners_enabled: false
+ @project = FactoryGirl.create :project, shared_runners_enabled: false
@project.team << [user, :master]
visit runners_path(@project)
end
@@ -87,7 +87,7 @@ describe "Runners" do
before do
stub_application_setting(shared_runners_text: shared_runners_text)
- project = FactoryGirl.create :empty_project, shared_runners_enabled: false
+ project = FactoryGirl.create :project, shared_runners_enabled: false
project.team << [user, :master]
visit runners_path(project)
end
@@ -99,7 +99,7 @@ describe "Runners" do
describe "show page" do
before do
- @project = FactoryGirl.create :empty_project
+ @project = FactoryGirl.create :project
@project.team << [user, :master]
@specific_runner = FactoryGirl.create :ci_runner
@project.runners << @specific_runner
@@ -113,7 +113,7 @@ describe "Runners" do
end
feature 'configuring runners ability to picking untagged jobs' do
- given(:project) { create(:empty_project) }
+ given(:project) { create(:project) }
given(:runner) { create(:ci_runner) }
background do
diff --git a/spec/features/search_spec.rb b/spec/features/search_spec.rb
index b29f19f1562..9b49fc2225d 100644
--- a/spec/features/search_spec.rb
+++ b/spec/features/search_spec.rb
@@ -4,7 +4,7 @@ describe "Search" do
include FilteredSearchHelpers
let(:user) { create(:user) }
- let(:project) { create(:empty_project, namespace: user.namespace) }
+ let(:project) { create(:project, namespace: user.namespace) }
let!(:issue) { create(:issue, project: project, assignees: [user]) }
let!(:issue2) { create(:issue, project: project, author: user) }
@@ -20,7 +20,7 @@ describe "Search" do
context 'search filters', js: true do
let(:group) { create(:group) }
- let!(:group_project) { create(:empty_project, group: group) }
+ let!(:group_project) { create(:project, group: group) }
before do
group.add_owner(user)
diff --git a/spec/features/security/group/internal_access_spec.rb b/spec/features/security/group/internal_access_spec.rb
index bf7be33013e..5067f0b0a49 100644
--- a/spec/features/security/group/internal_access_spec.rb
+++ b/spec/features/security/group/internal_access_spec.rb
@@ -4,7 +4,7 @@ describe 'Internal Group access' do
include AccessMatchers
let(:group) { create(:group, :internal) }
- let(:project) { create(:empty_project, :internal, group: group) }
+ let(:project) { create(:project, :internal, group: group) }
let(:project_guest) do
create(:user) do |user|
project.add_guest(user)
diff --git a/spec/features/security/group/private_access_spec.rb b/spec/features/security/group/private_access_spec.rb
index c399d7a0851..ff32413dc7e 100644
--- a/spec/features/security/group/private_access_spec.rb
+++ b/spec/features/security/group/private_access_spec.rb
@@ -4,7 +4,7 @@ describe 'Private Group access' do
include AccessMatchers
let(:group) { create(:group, :private) }
- let(:project) { create(:empty_project, :private, group: group) }
+ let(:project) { create(:project, :private, group: group) }
let(:project_guest) do
create(:user) do |user|
project.add_guest(user)
diff --git a/spec/features/security/group/public_access_spec.rb b/spec/features/security/group/public_access_spec.rb
index 63e4d7ca65c..16d114fb3f7 100644
--- a/spec/features/security/group/public_access_spec.rb
+++ b/spec/features/security/group/public_access_spec.rb
@@ -4,7 +4,7 @@ describe 'Public Group access' do
include AccessMatchers
let(:group) { create(:group, :public) }
- let(:project) { create(:empty_project, :public, group: group) }
+ let(:project) { create(:project, :public, group: group) }
let(:project_guest) do
create(:user) do |user|
project.add_guest(user)
diff --git a/spec/features/security/project/snippet/internal_access_spec.rb b/spec/features/security/project/snippet/internal_access_spec.rb
index 178782af56c..d7dc99c0a57 100644
--- a/spec/features/security/project/snippet/internal_access_spec.rb
+++ b/spec/features/security/project/snippet/internal_access_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe "Internal Project Snippets Access" do
include AccessMatchers
- let(:project) { create(:empty_project, :internal) }
+ let(:project) { create(:project, :internal) }
let(:internal_snippet) { create(:project_snippet, :internal, project: project, author: project.owner) }
let(:private_snippet) { create(:project_snippet, :private, project: project, author: project.owner) }
diff --git a/spec/features/security/project/snippet/private_access_spec.rb b/spec/features/security/project/snippet/private_access_spec.rb
index 7725c25ca1f..3ec1a388185 100644
--- a/spec/features/security/project/snippet/private_access_spec.rb
+++ b/spec/features/security/project/snippet/private_access_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe "Private Project Snippets Access" do
include AccessMatchers
- let(:project) { create(:empty_project, :private) }
+ let(:project) { create(:project, :private) }
let(:private_snippet) { create(:project_snippet, :private, project: project, author: project.owner) }
diff --git a/spec/features/security/project/snippet/public_access_spec.rb b/spec/features/security/project/snippet/public_access_spec.rb
index 52aec75dcd0..39b104bfe27 100644
--- a/spec/features/security/project/snippet/public_access_spec.rb
+++ b/spec/features/security/project/snippet/public_access_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe "Public Project Snippets Access" do
include AccessMatchers
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:public_snippet) { create(:project_snippet, :public, project: project, author: project.owner) }
let(:internal_snippet) { create(:project_snippet, :internal, project: project, author: project.owner) }
diff --git a/spec/features/snippets/notes_on_personal_snippets_spec.rb b/spec/features/snippets/notes_on_personal_snippets_spec.rb
index f1d0905738b..c0c293dee78 100644
--- a/spec/features/snippets/notes_on_personal_snippets_spec.rb
+++ b/spec/features/snippets/notes_on_personal_snippets_spec.rb
@@ -91,11 +91,7 @@ describe 'Comments on personal snippets', :js do
context 'when editing a note' do
it 'changes the text' do
- open_more_actions_dropdown(snippet_notes[0])
-
- page.within("#notes-list li#note_#{snippet_notes[0].id}") do
- click_on 'Edit comment'
- end
+ find('.js-note-edit').click
page.within('.current-note-edit-form') do
fill_in 'note[note]', with: 'new content'
diff --git a/spec/features/snippets/user_creates_snippet_spec.rb b/spec/features/snippets/user_creates_snippet_spec.rb
index a919f5fa20b..d732383a1e1 100644
--- a/spec/features/snippets/user_creates_snippet_spec.rb
+++ b/spec/features/snippets/user_creates_snippet_spec.rb
@@ -41,7 +41,7 @@ feature 'User creates snippet', :js do
expect(page).to have_content('My Snippet')
link = find('a.no-attachment-icon img[alt="banana_sample"]')['src']
- expect(link).to match(%r{/uploads/system/temp/\h{32}/banana_sample\.gif\z})
+ expect(link).to match(%r{/uploads/-/system/temp/\h{32}/banana_sample\.gif\z})
visit(link)
expect(page.status_code).to eq(200)
@@ -59,7 +59,7 @@ feature 'User creates snippet', :js do
wait_for_requests
link = find('a.no-attachment-icon img[alt="banana_sample"]')['src']
- expect(link).to match(%r{/uploads/system/personal_snippet/#{Snippet.last.id}/\h{32}/banana_sample\.gif\z})
+ expect(link).to match(%r{/uploads/-/system/personal_snippet/#{Snippet.last.id}/\h{32}/banana_sample\.gif\z})
visit(link)
expect(page.status_code).to eq(200)
@@ -84,7 +84,7 @@ feature 'User creates snippet', :js do
end
expect(page).to have_content('Hello World!')
link = find('a.no-attachment-icon img[alt="banana_sample"]')['src']
- expect(link).to match(%r{/uploads/system/personal_snippet/#{Snippet.last.id}/\h{32}/banana_sample\.gif\z})
+ expect(link).to match(%r{/uploads/-/system/personal_snippet/#{Snippet.last.id}/\h{32}/banana_sample\.gif\z})
visit(link)
expect(page.status_code).to eq(200)
diff --git a/spec/features/snippets/user_edits_snippet_spec.rb b/spec/features/snippets/user_edits_snippet_spec.rb
index 26070e508e2..71de6b6bd1c 100644
--- a/spec/features/snippets/user_edits_snippet_spec.rb
+++ b/spec/features/snippets/user_edits_snippet_spec.rb
@@ -33,7 +33,7 @@ feature 'User edits snippet', :js do
wait_for_requests
link = find('a.no-attachment-icon img[alt="banana_sample"]')['src']
- expect(link).to match(%r{/uploads/system/personal_snippet/#{snippet.id}/\h{32}/banana_sample\.gif\z})
+ expect(link).to match(%r{/uploads/-/system/personal_snippet/#{snippet.id}/\h{32}/banana_sample\.gif\z})
end
it 'updates the snippet to make it internal' do
diff --git a/spec/features/snippets_spec.rb b/spec/features/snippets_spec.rb
index ae3b876f87c..96c50f6c804 100644
--- a/spec/features/snippets_spec.rb
+++ b/spec/features/snippets_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe 'Snippets' do
context 'when the project has snippets' do
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let!(:snippets) { create_list(:project_snippet, 2, :public, author: project.owner, project: project) }
before do
allow(Snippet).to receive(:default_per_page).and_return(1)
diff --git a/spec/features/tags/master_creates_tag_spec.rb b/spec/features/tags/master_creates_tag_spec.rb
index 35e1ca32f67..39d79a3327b 100644
--- a/spec/features/tags/master_creates_tag_spec.rb
+++ b/spec/features/tags/master_creates_tag_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
feature 'Master creates tag' do
let(:user) { create(:user) }
- let(:project) { create(:project, namespace: user.namespace) }
+ let(:project) { create(:project, :repository, namespace: user.namespace) }
before do
project.team << [user, :master]
diff --git a/spec/features/tags/master_deletes_tag_spec.rb b/spec/features/tags/master_deletes_tag_spec.rb
index e3c904ef3aa..4d6fc13557f 100644
--- a/spec/features/tags/master_deletes_tag_spec.rb
+++ b/spec/features/tags/master_deletes_tag_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
feature 'Master deletes tag' do
let(:user) { create(:user) }
- let(:project) { create(:project, namespace: user.namespace) }
+ let(:project) { create(:project, :repository, namespace: user.namespace) }
before do
project.team << [user, :master]
diff --git a/spec/features/tags/master_updates_tag_spec.rb b/spec/features/tags/master_updates_tag_spec.rb
index d6e84a1c685..b93ad44dfd3 100644
--- a/spec/features/tags/master_updates_tag_spec.rb
+++ b/spec/features/tags/master_updates_tag_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
feature 'Master updates tag' do
let(:user) { create(:user) }
- let(:project) { create(:project, namespace: user.namespace) }
+ let(:project) { create(:project, :repository, namespace: user.namespace) }
before do
project.team << [user, :master]
diff --git a/spec/features/tags/master_views_tags_spec.rb b/spec/features/tags/master_views_tags_spec.rb
index 27936bc7f52..9edc7ced163 100644
--- a/spec/features/tags/master_views_tags_spec.rb
+++ b/spec/features/tags/master_views_tags_spec.rb
@@ -26,7 +26,7 @@ feature 'Master views tags' do
end
context 'when project has tags' do
- let(:project) { create(:project, namespace: user.namespace) }
+ let(:project) { create(:project, :repository, namespace: user.namespace) }
let(:repository) { project.repository }
before do
diff --git a/spec/features/task_lists_spec.rb b/spec/features/task_lists_spec.rb
index 7e198ce0677..580258f77eb 100644
--- a/spec/features/task_lists_spec.rb
+++ b/spec/features/task_lists_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
feature 'Task Lists' do
include Warden::Test::Helpers
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:user) { create(:user) }
let(:user2) { create(:user) }
@@ -52,8 +52,8 @@ feature 'Task Lists' do
before do
Warden.test_mode!
- project.team << [user, :master]
- project.team << [user2, :guest]
+ project.add_master(user)
+ project.add_guest(user2)
login_as(user)
end
diff --git a/spec/features/triggers_spec.rb b/spec/features/triggers_spec.rb
index 604fe326e96..47664de469a 100644
--- a/spec/features/triggers_spec.rb
+++ b/spec/features/triggers_spec.rb
@@ -9,7 +9,7 @@ feature 'Triggers', js: true do
before do
sign_in(user)
- @project = create(:empty_project)
+ @project = create(:project)
@project.team << [user, :master]
@project.team << [user2, :master]
@project.team << [guest_user, :guest]
@@ -82,7 +82,7 @@ feature 'Triggers', js: true do
end
describe 'trigger "Take ownership" workflow' do
- before(:each) do
+ before do
create(:ci_trigger, owner: user2, project: @project, description: trigger_title)
visit project_settings_ci_cd_path(@project)
end
@@ -104,7 +104,7 @@ feature 'Triggers', js: true do
end
describe 'trigger "Revoke" workflow' do
- before(:each) do
+ before do
create(:ci_trigger, owner: user2, project: @project, description: trigger_title)
visit project_settings_ci_cd_path(@project)
end
diff --git a/spec/features/unsubscribe_links_spec.rb b/spec/features/unsubscribe_links_spec.rb
index d728dc59b3f..392d8e3e1c1 100644
--- a/spec/features/unsubscribe_links_spec.rb
+++ b/spec/features/unsubscribe_links_spec.rb
@@ -5,7 +5,7 @@ describe 'Unsubscribe links' do
let(:recipient) { create(:user) }
let(:author) { create(:user) }
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:params) { { title: 'A bug!', description: 'Fix it!', assignees: [recipient] } }
let(:issue) { Issues::CreateService.new(project, author, params).execute }
diff --git a/spec/features/uploads/user_uploads_file_to_note_spec.rb b/spec/features/uploads/user_uploads_file_to_note_spec.rb
index 0654923d9a6..53cad623a35 100644
--- a/spec/features/uploads/user_uploads_file_to_note_spec.rb
+++ b/spec/features/uploads/user_uploads_file_to_note_spec.rb
@@ -4,7 +4,7 @@ feature 'User uploads file to note' do
include DropzoneHelper
let(:user) { create(:user) }
- let(:project) { create(:empty_project, creator: user, namespace: user.namespace) }
+ let(:project) { create(:project, creator: user, namespace: user.namespace) }
let(:issue) { create(:issue, project: project, author: user) }
before do
diff --git a/spec/features/user_callout_spec.rb b/spec/features/user_callout_spec.rb
index 93768aa46df..37d66b618af 100644
--- a/spec/features/user_callout_spec.rb
+++ b/spec/features/user_callout_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe 'User Callouts', js: true do
let(:user) { create(:user) }
let(:another_user) { create(:user) }
- let(:project) { create(:empty_project, path: 'gitlab', name: 'sample') }
+ let(:project) { create(:project, path: 'gitlab', name: 'sample') }
before do
sign_in(user)
diff --git a/spec/features/users/projects_spec.rb b/spec/features/users/projects_spec.rb
index b961d2337ed..f079771cee1 100644
--- a/spec/features/users/projects_spec.rb
+++ b/spec/features/users/projects_spec.rb
@@ -2,8 +2,8 @@ require 'spec_helper'
describe 'Projects tab on a user profile', :js do
let(:user) { create(:user) }
- let!(:project) { create(:empty_project, namespace: user.namespace) }
- let!(:project2) { create(:empty_project, namespace: user.namespace) }
+ let!(:project) { create(:project, namespace: user.namespace) }
+ let!(:project2) { create(:project, namespace: user.namespace) }
before do
allow(Project).to receive(:default_per_page).and_return(1)
diff --git a/spec/features/users_spec.rb b/spec/features/users_spec.rb
index ff004d85272..15b89dac572 100644
--- a/spec/features/users_spec.rb
+++ b/spec/features/users_spec.rb
@@ -73,7 +73,7 @@ feature 'Users', js: true do
let(:loading_icon) { '.fa.fa-spinner' }
let(:username_input) { 'new_user_username' }
- before(:each) do
+ before do
visit new_user_session_path
click_link 'Register'
end
@@ -104,7 +104,7 @@ feature 'Users', js: true do
end
def errors_on_page(page)
- page.find('#error_explanation').find('ul').all('li').map{ |item| item.text }.join("\n")
+ page.find('#error_explanation').find('ul').all('li').map { |item| item.text }.join("\n")
end
def number_of_errors_on_page(page)
diff --git a/spec/features/variables_spec.rb b/spec/features/variables_spec.rb
index dd770fe5043..6794bf4f4ba 100644
--- a/spec/features/variables_spec.rb
+++ b/spec/features/variables_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe 'Project variables', js: true do
let(:user) { create(:user) }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:variable) { create(:ci_variable, key: 'test_key', value: 'test value') }
before do
diff --git a/spec/finders/access_requests_finder_spec.rb b/spec/finders/access_requests_finder_spec.rb
index 1d0c15392b2..0789d3a9b44 100644
--- a/spec/finders/access_requests_finder_spec.rb
+++ b/spec/finders/access_requests_finder_spec.rb
@@ -5,7 +5,7 @@ describe AccessRequestsFinder do
let(:access_requester) { create(:user) }
let(:project) do
- create(:empty_project, :public, :access_requestable) do |project|
+ create(:project, :public, :access_requestable) do |project|
project.request_access(access_requester)
end
end
diff --git a/spec/finders/admin/projects_finder_spec.rb b/spec/finders/admin/projects_finder_spec.rb
index 296d6c51d04..28e36330029 100644
--- a/spec/finders/admin/projects_finder_spec.rb
+++ b/spec/finders/admin/projects_finder_spec.rb
@@ -6,19 +6,19 @@ describe Admin::ProjectsFinder do
let(:group) { create(:group, :public) }
let!(:private_project) do
- create(:empty_project, :private, name: 'A', path: 'A')
+ create(:project, :private, name: 'A', path: 'A')
end
let!(:internal_project) do
- create(:empty_project, :internal, group: group, name: 'B', path: 'B')
+ create(:project, :internal, group: group, name: 'B', path: 'B')
end
let!(:public_project) do
- create(:empty_project, :public, group: group, name: 'C', path: 'C')
+ create(:project, :public, group: group, name: 'C', path: 'C')
end
let!(:shared_project) do
- create(:empty_project, :private, name: 'D', path: 'D')
+ create(:project, :private, name: 'D', path: 'D')
end
let(:params) { {} }
@@ -38,9 +38,15 @@ describe Admin::ProjectsFinder do
it { is_expected.to match_array([shared_project, public_project, internal_project, private_project]) }
end
+ context 'with pending delete project' do
+ let!(:pending_delete_project) { create(:project, pending_delete: true) }
+
+ it { is_expected.not_to include(pending_delete_project) }
+ end
+
context 'filter by namespace_id' do
let(:namespace) { create(:namespace) }
- let!(:project_in_namespace) { create(:empty_project, namespace: namespace) }
+ let!(:project_in_namespace) { create(:project, namespace: namespace) }
let(:params) { { namespace_id: namespace.id } }
it { is_expected.to eq([project_in_namespace]) }
@@ -99,7 +105,7 @@ describe Admin::ProjectsFinder do
end
context 'filter by archived' do
- let!(:archived_project) { create(:empty_project, :public, :archived, name: 'E', path: 'E') }
+ let!(:archived_project) { create(:project, :public, :archived, name: 'E', path: 'E') }
context 'archived=false' do
let(:params) { { archived: false } }
@@ -115,7 +121,7 @@ describe Admin::ProjectsFinder do
end
context 'filter by personal' do
- let!(:personal_project) { create(:empty_project, namespace: user.namespace) }
+ let!(:personal_project) { create(:project, namespace: user.namespace) }
let(:params) { { personal: true } }
it { is_expected.to eq([personal_project]) }
diff --git a/spec/finders/contributed_projects_finder_spec.rb b/spec/finders/contributed_projects_finder_spec.rb
index 34f665826b6..60ea98e61c7 100644
--- a/spec/finders/contributed_projects_finder_spec.rb
+++ b/spec/finders/contributed_projects_finder_spec.rb
@@ -6,16 +6,16 @@ describe ContributedProjectsFinder do
let(:finder) { described_class.new(source_user) }
- let!(:public_project) { create(:empty_project, :public) }
- let!(:private_project) { create(:empty_project, :private) }
+ let!(:public_project) { create(:project, :public) }
+ let!(:private_project) { create(:project, :private) }
before do
private_project.add_master(source_user)
private_project.add_developer(current_user)
public_project.add_master(source_user)
- create(:event, :pushed, project: public_project, target: public_project, author: source_user)
- create(:event, :pushed, project: private_project, target: private_project, author: source_user)
+ create(:push_event, project: public_project, author: source_user)
+ create(:push_event, project: private_project, author: source_user)
end
describe 'without a current user' do
diff --git a/spec/finders/environments_finder_spec.rb b/spec/finders/environments_finder_spec.rb
index 0c063f6d5ee..3a8a1e7de74 100644
--- a/spec/finders/environments_finder_spec.rb
+++ b/spec/finders/environments_finder_spec.rb
@@ -12,7 +12,7 @@ describe EnvironmentsFinder do
context 'tagged deployment' do
before do
- create(:deployment, environment: environment, ref: '1.0', tag: true, sha: project.commit.id)
+ create(:deployment, environment: environment, ref: 'v1.1.0', tag: true, sha: project.commit.id)
end
it 'returns environment when with_tags is set' do
diff --git a/spec/finders/events_finder_spec.rb b/spec/finders/events_finder_spec.rb
index 30a2bd14f10..18d6c0cfd74 100644
--- a/spec/finders/events_finder_spec.rb
+++ b/spec/finders/events_finder_spec.rb
@@ -3,8 +3,8 @@ require 'spec_helper'
describe EventsFinder do
let(:user) { create(:user) }
let(:other_user) { create(:user) }
- let(:project1) { create(:empty_project, :private, creator_id: user.id, namespace: user.namespace) }
- let(:project2) { create(:empty_project, :private, creator_id: user.id, namespace: user.namespace) }
+ let(:project1) { create(:project, :private, creator_id: user.id, namespace: user.namespace) }
+ let(:project2) { create(:project, :private, creator_id: user.id, namespace: user.namespace) }
let(:closed_issue) { create(:closed_issue, project: project1, author: user) }
let(:opened_merge_request) { create(:merge_request, source_project: project2, author: user) }
let!(:closed_issue_event) { create(:event, project: project1, author: user, target: closed_issue, action: Event::CLOSED, created_at: Date.new(2016, 12, 30)) }
diff --git a/spec/finders/group_projects_finder_spec.rb b/spec/finders/group_projects_finder_spec.rb
index 3c7c9bdcd08..c6d257bc479 100644
--- a/spec/finders/group_projects_finder_spec.rb
+++ b/spec/finders/group_projects_finder_spec.rb
@@ -7,11 +7,11 @@ describe GroupProjectsFinder do
let(:finder) { described_class.new(group: group, current_user: current_user, options: options) }
- let!(:public_project) { create(:empty_project, :public, group: group, path: '1') }
- let!(:private_project) { create(:empty_project, :private, group: group, path: '2') }
- let!(:shared_project_1) { create(:empty_project, :public, path: '3') }
- let!(:shared_project_2) { create(:empty_project, :private, path: '4') }
- let!(:shared_project_3) { create(:empty_project, :internal, path: '5') }
+ let!(:public_project) { create(:project, :public, group: group, path: '1') }
+ let!(:private_project) { create(:project, :private, group: group, path: '2') }
+ let!(:shared_project_1) { create(:project, :public, path: '3') }
+ let!(:shared_project_2) { create(:project, :private, path: '4') }
+ let!(:shared_project_3) { create(:project, :internal, path: '5') }
before do
shared_project_1.project_group_links.create(group_access: Gitlab::Access::MASTER, group: group)
diff --git a/spec/finders/groups_finder_spec.rb b/spec/finders/groups_finder_spec.rb
index 9e70cccc3c4..abc470788e1 100644
--- a/spec/finders/groups_finder_spec.rb
+++ b/spec/finders/groups_finder_spec.rb
@@ -80,7 +80,7 @@ describe GroupsFinder do
context 'authorized to private project' do
context 'project one level deep' do
- let!(:subproject) { create(:empty_project, :private, namespace: private_subgroup) }
+ let!(:subproject) { create(:project, :private, namespace: private_subgroup) }
before do
subproject.add_guest(user)
end
@@ -98,7 +98,7 @@ describe GroupsFinder do
context 'project two levels deep' do
let!(:private_subsubgroup) { create(:group, :private, parent: private_subgroup) }
- let!(:subsubproject) { create(:empty_project, :private, namespace: private_subsubgroup) }
+ let!(:subsubproject) { create(:project, :private, namespace: private_subsubgroup) }
before do
subsubproject.add_guest(user)
end
diff --git a/spec/finders/issues_finder_spec.rb b/spec/finders/issues_finder_spec.rb
index bef4fd44331..8769a52863c 100644
--- a/spec/finders/issues_finder_spec.rb
+++ b/spec/finders/issues_finder_spec.rb
@@ -3,8 +3,8 @@ require 'spec_helper'
describe IssuesFinder do
set(:user) { create(:user) }
set(:user2) { create(:user) }
- set(:project1) { create(:empty_project) }
- set(:project2) { create(:empty_project) }
+ set(:project1) { create(:project) }
+ set(:project2) { create(:project) }
set(:milestone) { create(:milestone, project: project1) }
set(:label) { create(:label, project: project2) }
set(:issue1) { create(:issue, author: user, assignees: [user], project: project1, milestone: milestone, title: 'gitlab', created_at: 1.week.ago) }
@@ -87,9 +87,9 @@ describe IssuesFinder do
context 'filtering by upcoming milestone' do
let(:params) { { milestone_title: Milestone::Upcoming.name } }
- let(:project_no_upcoming_milestones) { create(:empty_project, :public) }
- let(:project_next_1_1) { create(:empty_project, :public) }
- let(:project_next_8_8) { create(:empty_project, :public) }
+ let(:project_no_upcoming_milestones) { create(:project, :public) }
+ let(:project_next_1_1) { create(:project, :public) }
+ let(:project_next_8_8) { create(:project, :public) }
let(:yesterday) { Date.today - 1.day }
let(:tomorrow) { Date.today + 1.day }
@@ -121,9 +121,9 @@ describe IssuesFinder do
context 'filtering by started milestone' do
let(:params) { { milestone_title: Milestone::Started.name } }
- let(:project_no_started_milestones) { create(:empty_project, :public) }
- let(:project_started_1_and_2) { create(:empty_project, :public) }
- let(:project_started_8) { create(:empty_project, :public) }
+ let(:project_no_started_milestones) { create(:project, :public) }
+ let(:project_started_1_and_2) { create(:project, :public) }
+ let(:project_started_8) { create(:project, :public) }
let(:yesterday) { Date.today - 1.day }
let(:tomorrow) { Date.today + 1.day }
@@ -268,7 +268,7 @@ describe IssuesFinder do
it 'finds issues user can access due to group' do
group = create(:group)
- project = create(:empty_project, group: group)
+ project = create(:project, group: group)
issue = create(:issue, project: project)
group.add_user(user, :owner)
@@ -296,7 +296,7 @@ describe IssuesFinder do
let(:scope) { nil }
it "doesn't return team-only issues to non team members" do
- project = create(:empty_project, :public, :issues_private)
+ project = create(:project, :public, :issues_private)
issue = create(:issue, project: project)
expect(issues).not_to include(issue)
@@ -315,7 +315,7 @@ describe IssuesFinder do
describe '#with_confidentiality_access_check' do
let(:guest) { create(:user) }
set(:authorized_user) { create(:user) }
- set(:project) { create(:empty_project, namespace: authorized_user.namespace) }
+ set(:project) { create(:project, namespace: authorized_user.namespace) }
set(:public_issue) { create(:issue, project: project) }
set(:confidential_issue) { create(:issue, project: project, confidential: true) }
diff --git a/spec/finders/joined_groups_finder_spec.rb b/spec/finders/joined_groups_finder_spec.rb
index 4c389746252..29a47e005a6 100644
--- a/spec/finders/joined_groups_finder_spec.rb
+++ b/spec/finders/joined_groups_finder_spec.rb
@@ -42,7 +42,7 @@ describe JoinedGroupsFinder do
context 'if profile visitor is in one of the private group projects' do
before do
- project = create(:empty_project, :private, group: private_group, name: 'B', path: 'B')
+ project = create(:project, :private, group: private_group, name: 'B', path: 'B')
project.add_user(profile_visitor, Gitlab::Access::DEVELOPER)
end
diff --git a/spec/finders/labels_finder_spec.rb b/spec/finders/labels_finder_spec.rb
index 95d96354b77..afa2a40ed2a 100644
--- a/spec/finders/labels_finder_spec.rb
+++ b/spec/finders/labels_finder_spec.rb
@@ -6,11 +6,11 @@ describe LabelsFinder do
let(:group_2) { create(:group) }
let(:group_3) { create(:group) }
- let(:project_1) { create(:empty_project, namespace: group_1) }
- let(:project_2) { create(:empty_project, namespace: group_2) }
- let(:project_3) { create(:empty_project) }
- let(:project_4) { create(:empty_project, :public) }
- let(:project_5) { create(:empty_project, namespace: group_1) }
+ let(:project_1) { create(:project, namespace: group_1) }
+ let(:project_2) { create(:project, namespace: group_2) }
+ let(:project_3) { create(:project) }
+ let(:project_4) { create(:project, :public) }
+ let(:project_5) { create(:project, namespace: group_1) }
let!(:project_label_1) { create(:label, project: project_1, title: 'Label 1') }
let!(:project_label_2) { create(:label, project: project_2, title: 'Label 2') }
@@ -68,7 +68,7 @@ describe LabelsFinder do
context 'as an administrator' do
it 'does not return labels from another project' do
# Purposefully creating a project with _nothing_ associated to it
- isolated_project = create(:empty_project)
+ isolated_project = create(:project)
admin = create(:admin)
# project_3 has a label associated to it, which we don't want coming
diff --git a/spec/finders/merge_requests_finder_spec.rb b/spec/finders/merge_requests_finder_spec.rb
index b46218bf72e..b54155a6704 100644
--- a/spec/finders/merge_requests_finder_spec.rb
+++ b/spec/finders/merge_requests_finder_spec.rb
@@ -4,9 +4,9 @@ describe MergeRequestsFinder do
let(:user) { create :user }
let(:user2) { create :user }
- let(:project1) { create(:empty_project) }
- let(:project2) { create(:empty_project, forked_from_project: project1) }
- let(:project3) { create(:empty_project, :archived, forked_from_project: project1) }
+ let(:project1) { create(:project) }
+ let(:project2) { create(:project, forked_from_project: project1) }
+ let(:project3) { create(:project, :archived, forked_from_project: project1) }
let!(:merge_request1) { create(:merge_request, :simple, author: user, source_project: project2, target_project: project1) }
let!(:merge_request2) { create(:merge_request, :simple, author: user, source_project: project2, target_project: project1, state: 'closed') }
@@ -67,7 +67,7 @@ describe MergeRequestsFinder do
end
context 'with created_after and created_before params' do
- let(:project4) { create(:empty_project, forked_from_project: project1) }
+ let(:project4) { create(:project, forked_from_project: project1) }
let!(:new_merge_request) do
create(:merge_request,
diff --git a/spec/finders/milestones_finder_spec.rb b/spec/finders/milestones_finder_spec.rb
index 32ec983c5b8..8ae08656e01 100644
--- a/spec/finders/milestones_finder_spec.rb
+++ b/spec/finders/milestones_finder_spec.rb
@@ -2,8 +2,8 @@ require 'spec_helper'
describe MilestonesFinder do
let(:group) { create(:group) }
- let(:project_1) { create(:empty_project, namespace: group) }
- let(:project_2) { create(:empty_project, namespace: group) }
+ let(:project_1) { create(:project, namespace: group) }
+ let(:project_2) { create(:project, namespace: group) }
let!(:milestone_1) { create(:milestone, group: group, title: 'one test', due_date: Date.today) }
let!(:milestone_2) { create(:milestone, group: group) }
let!(:milestone_3) { create(:milestone, project: project_1, state: 'active', due_date: Date.tomorrow) }
diff --git a/spec/finders/move_to_project_finder_spec.rb b/spec/finders/move_to_project_finder_spec.rb
index dea87980e25..e577083a2d0 100644
--- a/spec/finders/move_to_project_finder_spec.rb
+++ b/spec/finders/move_to_project_finder_spec.rb
@@ -2,13 +2,13 @@ require 'spec_helper'
describe MoveToProjectFinder do
let(:user) { create(:user) }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
- let(:no_access_project) { create(:empty_project) }
- let(:guest_project) { create(:empty_project) }
- let(:reporter_project) { create(:empty_project) }
- let(:developer_project) { create(:empty_project) }
- let(:master_project) { create(:empty_project) }
+ let(:no_access_project) { create(:project) }
+ let(:guest_project) { create(:project) }
+ let(:reporter_project) { create(:project) }
+ let(:developer_project) { create(:project) }
+ let(:master_project) { create(:project) }
subject { described_class.new(user) }
@@ -37,7 +37,7 @@ describe MoveToProjectFinder do
it 'does not return archived projects' do
reporter_project.team << [user, :reporter]
reporter_project.archive!
- other_reporter_project = create(:empty_project)
+ other_reporter_project = create(:project)
other_reporter_project.team << [user, :reporter]
expect(subject.execute(project).to_a).to eq([other_reporter_project])
@@ -46,7 +46,7 @@ describe MoveToProjectFinder do
it 'does not return projects for which issues are disabled' do
reporter_project.team << [user, :reporter]
reporter_project.update_attributes(issues_enabled: false)
- other_reporter_project = create(:empty_project)
+ other_reporter_project = create(:project)
other_reporter_project.team << [user, :reporter]
expect(subject.execute(project).to_a).to eq([other_reporter_project])
@@ -83,10 +83,10 @@ describe MoveToProjectFinder do
end
it 'returns projects matching a search query' do
- foo_project = create(:empty_project)
+ foo_project = create(:project)
foo_project.team << [user, :master]
- wadus_project = create(:empty_project, name: 'wadus')
+ wadus_project = create(:project, name: 'wadus')
wadus_project.team << [user, :master]
expect(subject.execute(project).to_a).to eq([wadus_project, foo_project])
diff --git a/spec/finders/notes_finder_spec.rb b/spec/finders/notes_finder_spec.rb
index ba6bbb3bce0..900fa2b12d1 100644
--- a/spec/finders/notes_finder_spec.rb
+++ b/spec/finders/notes_finder_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe NotesFinder do
let(:user) { create :user }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
before do
project.team << [user, :master]
@@ -43,7 +43,7 @@ describe NotesFinder do
context 'on restricted projects' do
let(:project) do
- create(:empty_project,
+ create(:project,
:public,
:issues_private,
:snippets_private,
@@ -156,7 +156,7 @@ describe NotesFinder do
end
describe '.search' do
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:note) { create(:note_on_issue, note: 'WoW', project: project) }
it 'returns notes with matching content' do
diff --git a/spec/finders/personal_projects_finder_spec.rb b/spec/finders/personal_projects_finder_spec.rb
index 304b0fb67fb..d0113ba87df 100644
--- a/spec/finders/personal_projects_finder_spec.rb
+++ b/spec/finders/personal_projects_finder_spec.rb
@@ -4,14 +4,14 @@ describe PersonalProjectsFinder do
let(:source_user) { create(:user) }
let(:current_user) { create(:user) }
let(:finder) { described_class.new(source_user) }
- let!(:public_project) { create(:empty_project, :public, namespace: source_user.namespace) }
+ let!(:public_project) { create(:project, :public, namespace: source_user.namespace) }
let!(:private_project) do
- create(:empty_project, :private, namespace: source_user.namespace, path: 'mepmep')
+ create(:project, :private, namespace: source_user.namespace, path: 'mepmep')
end
let!(:internal_project) do
- create(:empty_project, :internal, namespace: source_user.namespace, path: 'C')
+ create(:project, :internal, namespace: source_user.namespace, path: 'C')
end
before do
diff --git a/spec/finders/pipeline_schedules_finder_spec.rb b/spec/finders/pipeline_schedules_finder_spec.rb
index e184a87c9c7..b9538649b3f 100644
--- a/spec/finders/pipeline_schedules_finder_spec.rb
+++ b/spec/finders/pipeline_schedules_finder_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe PipelineSchedulesFinder do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let!(:active_schedule) { create(:ci_pipeline_schedule, project: project) }
let!(:inactive_schedule) { create(:ci_pipeline_schedule, :inactive, project: project) }
diff --git a/spec/finders/projects_finder_spec.rb b/spec/finders/projects_finder_spec.rb
index 03d98459e8c..a5de586e869 100644
--- a/spec/finders/projects_finder_spec.rb
+++ b/spec/finders/projects_finder_spec.rb
@@ -6,19 +6,19 @@ describe ProjectsFinder do
let(:group) { create(:group, :public) }
let!(:private_project) do
- create(:empty_project, :private, name: 'A', path: 'A')
+ create(:project, :private, name: 'A', path: 'A')
end
let!(:internal_project) do
- create(:empty_project, :internal, group: group, name: 'B', path: 'B')
+ create(:project, :internal, group: group, name: 'B', path: 'B')
end
let!(:public_project) do
- create(:empty_project, :public, group: group, name: 'C', path: 'C')
+ create(:project, :public, group: group, name: 'C', path: 'C')
end
let!(:shared_project) do
- create(:empty_project, :private, name: 'D', path: 'D')
+ create(:project, :private, name: 'D', path: 'D')
end
let(:params) { {} }
@@ -90,7 +90,7 @@ describe ProjectsFinder do
end
describe 'filter by personal' do
- let!(:personal_project) { create(:empty_project, namespace: user.namespace) }
+ let!(:personal_project) { create(:project, namespace: user.namespace) }
let(:params) { { personal: true } }
it { is_expected.to eq([personal_project]) }
@@ -109,7 +109,7 @@ describe ProjectsFinder do
end
describe 'filter by archived' do
- let!(:archived_project) { create(:empty_project, :public, :archived, name: 'E', path: 'E') }
+ let!(:archived_project) { create(:project, :public, :archived, name: 'E', path: 'E') }
context 'non_archived=true' do
let(:params) { { non_archived: true } }
@@ -139,7 +139,7 @@ describe ProjectsFinder do
describe 'filter by owned' do
let(:params) { { owned: true } }
- let!(:owned_project) { create(:empty_project, :private, namespace: current_user.namespace) }
+ let!(:owned_project) { create(:project, :private, namespace: current_user.namespace) }
it { is_expected.to eq([owned_project]) }
end
diff --git a/spec/finders/snippets_finder_spec.rb b/spec/finders/snippets_finder_spec.rb
index 35f1683eef9..7ae7b7d2140 100644
--- a/spec/finders/snippets_finder_spec.rb
+++ b/spec/finders/snippets_finder_spec.rb
@@ -5,8 +5,8 @@ describe SnippetsFinder do
let(:user1) { create :user }
let(:group) { create :group, :public }
- let(:project1) { create(:empty_project, :public, group: group) }
- let(:project2) { create(:empty_project, :private, group: group) }
+ let(:project1) { create(:project, :public, group: group) }
+ let(:project2) { create(:project, :private, group: group) }
context 'all snippets visible to a user' do
let!(:snippet1) { create(:personal_snippet, :private) }
diff --git a/spec/finders/todos_finder_spec.rb b/spec/finders/todos_finder_spec.rb
index 8be447418b0..884ce22091e 100644
--- a/spec/finders/todos_finder_spec.rb
+++ b/spec/finders/todos_finder_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe TodosFinder do
describe '#execute' do
let(:user) { create(:user) }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:finder) { described_class }
before do
diff --git a/spec/fixtures/api/schemas/entities/merge_request.json b/spec/fixtures/api/schemas/entities/merge_request.json
index 7ffa82fc4bd..2f12b671dec 100644
--- a/spec/fixtures/api/schemas/entities/merge_request.json
+++ b/spec/fixtures/api/schemas/entities/merge_request.json
@@ -19,7 +19,6 @@
"human_time_estimate": { "type": ["integer", "null"] },
"human_total_time_spent": { "type": ["integer", "null"] },
"in_progress_merge_commit_sha": { "type": ["string", "null"] },
- "locked_at": { "type": ["string", "null"] },
"merge_error": { "type": ["string", "null"] },
"merge_commit_sha": { "type": ["string", "null"] },
"merge_params": { "type": ["object", "null"] },
@@ -94,7 +93,8 @@
"commit_change_content_path": { "type": "string" },
"remove_wip_path": { "type": "string" },
"commits_count": { "type": "integer" },
- "remove_source_branch": { "type": ["boolean", "null"] }
+ "remove_source_branch": { "type": ["boolean", "null"] },
+ "merge_ongoing": { "type": "boolean" }
},
"additionalProperties": false
}
diff --git a/spec/fixtures/api/schemas/public_api/v4/comment.json b/spec/fixtures/api/schemas/public_api/v4/comment.json
new file mode 100644
index 00000000000..52cfe86aeeb
--- /dev/null
+++ b/spec/fixtures/api/schemas/public_api/v4/comment.json
@@ -0,0 +1,21 @@
+{
+ "type": "object",
+ "required" : [
+ "name",
+ "message",
+ "commit",
+ "release"
+ ],
+ "properties" : {
+ "name": { "type": "string" },
+ "message": { "type": ["string", "null"] },
+ "commit": { "$ref": "commit/basic.json" },
+ "release": {
+ "oneOf": [
+ { "type": "null" },
+ { "$ref": "release.json" }
+ ]
+ }
+ },
+ "additionalProperties": false
+}
diff --git a/spec/fixtures/api/schemas/public_api/v4/commit/detail.json b/spec/fixtures/api/schemas/public_api/v4/commit/detail.json
new file mode 100644
index 00000000000..b7b2535c204
--- /dev/null
+++ b/spec/fixtures/api/schemas/public_api/v4/commit/detail.json
@@ -0,0 +1,16 @@
+{
+ "type": "object",
+ "allOf": [
+ { "$ref": "basic.json" },
+ {
+ "required" : [
+ "stats",
+ "status"
+ ],
+ "properties": {
+ "stats": { "$ref": "../commit_stats.json" },
+ "status": { "type": ["string", "null"] }
+ }
+ }
+ ]
+}
diff --git a/spec/fixtures/api/schemas/public_api/v4/commit_note.json b/spec/fixtures/api/schemas/public_api/v4/commit_note.json
new file mode 100644
index 00000000000..02081989271
--- /dev/null
+++ b/spec/fixtures/api/schemas/public_api/v4/commit_note.json
@@ -0,0 +1,19 @@
+{
+ "type": "object",
+ "required" : [
+ "note",
+ "path",
+ "line",
+ "line_type",
+ "author",
+ "created_at"
+ ],
+ "properties" : {
+ "note": { "type": ["string", "null"] },
+ "path": { "type": ["string", "null"] },
+ "line": { "type": ["integer", "null"] },
+ "line_type": { "type": ["string", "null"] },
+ "author": { "$ref": "user/basic.json" },
+ "created_at": { "type": "date" }
+ }
+}
diff --git a/spec/fixtures/api/schemas/public_api/v4/commit_notes.json b/spec/fixtures/api/schemas/public_api/v4/commit_notes.json
new file mode 100644
index 00000000000..d65a7d677ea
--- /dev/null
+++ b/spec/fixtures/api/schemas/public_api/v4/commit_notes.json
@@ -0,0 +1,4 @@
+{
+ "type": "array",
+ "items": { "$ref": "commit_note.json" }
+}
diff --git a/spec/fixtures/api/schemas/public_api/v4/commit_stats.json b/spec/fixtures/api/schemas/public_api/v4/commit_stats.json
new file mode 100644
index 00000000000..779384c62e6
--- /dev/null
+++ b/spec/fixtures/api/schemas/public_api/v4/commit_stats.json
@@ -0,0 +1,14 @@
+{
+ "type": "object",
+ "required" : [
+ "additions",
+ "deletions",
+ "total"
+ ],
+ "properties" : {
+ "additions": { "type": "integer" },
+ "deletions": { "type": "integer" },
+ "total": { "type": "integer" }
+ },
+ "additionalProperties": false
+}
diff --git a/spec/fixtures/api/schemas/public_api/v4/commits.json b/spec/fixtures/api/schemas/public_api/v4/commits.json
new file mode 100644
index 00000000000..98b17a96071
--- /dev/null
+++ b/spec/fixtures/api/schemas/public_api/v4/commits.json
@@ -0,0 +1,4 @@
+{
+ "type": "array",
+ "items": { "$ref": "commit/basic.json" }
+}
diff --git a/spec/fixtures/api/schemas/public_api/v4/release.json b/spec/fixtures/api/schemas/public_api/v4/release.json
new file mode 100644
index 00000000000..6612c2a9911
--- /dev/null
+++ b/spec/fixtures/api/schemas/public_api/v4/release.json
@@ -0,0 +1,12 @@
+{
+ "type": "object",
+ "required" : [
+ "tag_name",
+ "description"
+ ],
+ "properties" : {
+ "tag_name": { "type": ["string", "null"] },
+ "description": { "type": "string" }
+ },
+ "additionalProperties": false
+}
diff --git a/spec/fixtures/api/schemas/public_api/v4/tag.json b/spec/fixtures/api/schemas/public_api/v4/tag.json
new file mode 100644
index 00000000000..52cfe86aeeb
--- /dev/null
+++ b/spec/fixtures/api/schemas/public_api/v4/tag.json
@@ -0,0 +1,21 @@
+{
+ "type": "object",
+ "required" : [
+ "name",
+ "message",
+ "commit",
+ "release"
+ ],
+ "properties" : {
+ "name": { "type": "string" },
+ "message": { "type": ["string", "null"] },
+ "commit": { "$ref": "commit/basic.json" },
+ "release": {
+ "oneOf": [
+ { "type": "null" },
+ { "$ref": "release.json" }
+ ]
+ }
+ },
+ "additionalProperties": false
+}
diff --git a/spec/fixtures/api/schemas/public_api/v4/tags.json b/spec/fixtures/api/schemas/public_api/v4/tags.json
new file mode 100644
index 00000000000..eae352e7f87
--- /dev/null
+++ b/spec/fixtures/api/schemas/public_api/v4/tags.json
@@ -0,0 +1,4 @@
+{
+ "type": "array",
+ "items": { "$ref": "tag.json" }
+}
diff --git a/spec/fixtures/api/schemas/public_api/v4/user/basic.json b/spec/fixtures/api/schemas/public_api/v4/user/basic.json
new file mode 100644
index 00000000000..9f69d31971c
--- /dev/null
+++ b/spec/fixtures/api/schemas/public_api/v4/user/basic.json
@@ -0,0 +1,15 @@
+{
+ "type": "object",
+ "required": [
+ "id",
+ "state",
+ "avatar_url",
+ "web_url"
+ ],
+ "properties": {
+ "id": { "type": "integer" },
+ "state": { "type": "string" },
+ "avatar_url": { "type": "string" },
+ "web_url": { "type": "string" }
+ }
+}
diff --git a/spec/fixtures/encoding/Japanese.md b/spec/fixtures/encoding/Japanese.md
new file mode 100644
index 00000000000..dd469c9f232
--- /dev/null
+++ b/spec/fixtures/encoding/Japanese.md
@@ -0,0 +1,42 @@
++++
+date = "2017-05-21T13:05:07+09:00"
+title = "レイヤ"
+weight = 10
+
++++
+
+## ã“ã®ãƒãƒ¥ãƒ¼ãƒˆãƒªã‚¢ãƒ«ã§æ‰±ã†å†…容
+1. Redactedã«ãŠã‘ã‚‹2D開発ã§ã®ãƒ¬ã‚¤ãƒ¤ã®åŸºæœ¬çš„ãªæ¦‚è¦
+2. スクリーン上ã®ã‚¹ãƒ—ライトã®é †åºä»˜ã‘方法
+
+### Redactedã«ãŠã‘ã‚‹2D開発ã§ã®ãƒ¬ã‚¤ãƒ¤ã®åŸºæœ¬çš„ãªæ¦‚è¦
+2Dã«ãŠã„ã¦ã¯z軸ãŒå­˜åœ¨ã—ãªã„ãŸã‚ã€ã‚·ãƒ¼ãƒ³å†…è¦ç´ ã®æç”»é †ã‚’制御ã™ã‚‹ãŸã‚ã«ã¯ä»£æ›¿ã¨ãªã‚‹ä»•組ã¿ãŒå¿…è¦ã§ã™ã€‚
+Redactedã§ã¯**レイヤ**ã«ãŠã‘ã‚‹**zIndex**属性を制御å¯èƒ½ã«ã™ã‚‹ã“ã¨ã§ã€ã“ã®èª²é¡Œã‚’解決ã—ã¦ã„ã¾ã™ã€‚
+**デフォルトã§ã¯ã€zIndexã¯0ã¨ãªã‚Šã‚ªãƒ–ジェクトã¯ãƒ¬ã‚¤ãƒ¤ã«è¿½åŠ ã•れãŸé †ç•ªã«æç”»ã•れã¾ã™ã€‚**
+
+レイヤã«ã¯ã„ãã¤ã‹ã®é‡è¦ãªç‰¹æ€§ãŒã‚りã¾ã™ã€‚
+
+* レイヤã«ã¯ãƒ¬ã‚¤ãƒ¤åŒ–ã•れãŸã‚ªãƒ–ジェクトã®ã¿ã‚’å«ã‚ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚(**3Dモデルã¯çµ¶å¯¾ã«è¿½åŠ ã—ãªã„ã§ãã ã•ã„**)
+* レイヤã¯ãƒ¬ã‚¤ãƒ¤åŒ–ã•れãŸã‚ªãƒ–ジェクトã§ã™ã€‚(ã—ãŸãŒã£ã¦ã€ãƒ¬ã‚¤ãƒ¤ã«ã¯ä»–ã®ãƒ¬ã‚¤ãƒ¤ã‚’å«ã‚ã‚‹ã“ã¨ãŒã§ãã¾ã™)
+* レイヤ化ã•れãŸã‚ªãƒ–ジェクトã¯ã€æœ€å¤§ã§1ã¤ã®ãƒ¬ã‚¤ãƒ¤ã«å±žã™ã“ã¨ãŒã§ãã¾ã™ã€‚
+
+ãƒ¬ã‚¤ãƒ¤ã‚’ç›´æŽ¥åˆæœŸåŒ–ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“ãŒã€ãã®æ´¾ç”Ÿã‚¯ãƒ©ã‚¹ã¯åˆæœŸåŒ–ã™ã‚‹ã“ã¨ãŒå¯èƒ½ã§ã™ã€‚**Scene2D**ã¨**コンテナ**ã¯ã€**レイヤ**ã‹ã‚‰æ´¾ç”Ÿã™ã‚‹2ã¤ã®ä¸»ãªã‚ªãƒ–ジェクトã§ã™ã€‚ã™ã¹ã¦ã®åˆæœŸåŒ–(createContainerã€instantiateã€...)ã¯ãƒ¬ã‚¤ãƒ¤ä¸Šã§è¡Œã‚れã¾ã™ã€‚ã¤ã¾ã‚Šã€2Dã§åˆæœŸåŒ–ã•れるã™ã¹ã¦ã®ã‚ªãƒ–ジェクトã¯ã€zIndexプロパティをæŒã¤ãƒ¬ã‚¤ãƒ¤åŒ–ã•れãŸã‚ªãƒ–ジェクトã§ã™ã€‚
+
+**zIndexã¯ã‚°ãƒ­ãƒ¼ãƒãƒ«ã§ã¯ã‚りã¾ã›ã‚“!**
+
+CSSã¨ã¯ç•°ãªã‚Šã€zIndexã¯ã™ã¹ã¦ã®ã‚ªãƒ–ジェクトã«å¯¾ã—ã¦ã‚°ãƒ­ãƒ¼ãƒãƒ«ã§ã¯ã‚りã¾ã›ã‚“。zIndexプロパティã¯è¦ªãƒ¬ã‚¤ãƒ¤ã«å¯¾ã—ã¦ãƒ­ãƒ¼ã‚«ãƒ«ã§ã™ã€‚詳細ã«ã¤ãã¾ã—ã¦ã¯ã€ã‚³ãƒ³ãƒ†ãƒŠãƒãƒ¥ãƒ¼ãƒˆãƒªã‚¢ãƒ«ã§èª¬æ˜Žã—ã¦ã„ã¾ã™ã€‚ [TODO: Link]。
+
+### スクリーン上ã®ã‚¹ãƒ—ライトã®é †åºä»˜ã‘方法
+ã“れã¾ã§å­¦ã‚“ã ã“ã¨ã‚’生ã‹ã—ã¦ã€ç”»é¢ã«ã‚¹ãƒ—ライトを表示ã—ã¦ã€zIndexã®è¨­å®šã‚’ã—ã¦ã¿ã¾ã—ょã†ï¼
+
+* ã¾ãšã€æœ€åˆã« (A,B,C) スプライトを生æˆã—ã¾ã™ã€‚
+* スプライトAをシーンã«è¿½åŠ ã—ã¾ã™ï¼ˆzIndex = 0ã€æ¨™æº–色)
+* スプライトBをシーン2ã«è¿½åŠ ã™ã‚‹ã¨ã€**スプライトAã®ä¸Šã«**表示ã•れã¾ã™ï¼ˆzIndex = 0ã€èµ¤è‰²ï¼‰
+* 最後ã«ã‚¹ãƒ—ライトCをシーンã«è¿½åŠ ã—ã¾ã™ï¼ˆé’色)ãŒã€ã‚¹ãƒ—ライトã®zIndexã‚’-1ã«è¨­å®šã™ã‚‹ã¨ã€ã‚¹ãƒ—ライトã¯Aã¨Bã®å¾Œå´ã«è¡¨ç¤ºã•れã¾ã™ã€‚
+
+{{< code "static/tutorials/layers.html" >}}
+
+### ソースコード全体
+```js
+{{< snippet "static/tutorials/layers.html" >}}
+```
diff --git a/spec/fixtures/markdown.md.erb b/spec/fixtures/markdown.md.erb
index 58b43805705..4f46e40ce7a 100644
--- a/spec/fixtures/markdown.md.erb
+++ b/spec/fixtures/markdown.md.erb
@@ -227,8 +227,11 @@ References should be parseable even inside _<%= merge_request.to_reference %>_ e
- Milestone in another project: <%= xmilestone.to_reference(project) %>
- Ignored in code: `<%= simple_milestone.to_reference %>`
- Ignored in links: [Link to <%= simple_milestone.to_reference %>](#milestone-link)
-- Milestone by URL: <%= urls.project_milestone_url(milestone.project, milestone) %>
+- Milestone by URL: <%= urls.milestone_url(milestone) %>
- Link to milestone by URL: [Milestone](<%= milestone.to_reference %>)
+- Group milestone by name: <%= Milestone.reference_prefix %><%= group_milestone.name %>
+- Group milestone by name in quotes: <%= group_milestone.to_reference(format: :name) %>
+- Group milestone by URL is ignore: <%= urls.milestone_url(group_milestone) %>
### Task Lists
diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb
index ac5a58ac189..10bc5f2ecd2 100644
--- a/spec/helpers/application_helper_spec.rb
+++ b/spec/helpers/application_helper_spec.rb
@@ -58,7 +58,7 @@ describe ApplicationHelper do
describe 'project_icon' do
it 'returns an url for the avatar' do
- project = create(:empty_project, avatar: File.open(uploaded_image_temp_path))
+ project = create(:project, avatar: File.open(uploaded_image_temp_path))
avatar_url = "/uploads/-/system/project/avatar/#{project.id}/banana_sample.gif"
expect(helper.project_icon(project.full_path).to_s)
@@ -72,7 +72,7 @@ describe ApplicationHelper do
end
it 'gives uploaded icon when present' do
- project = create(:empty_project)
+ project = create(:project)
allow_any_instance_of(Project).to receive(:avatar_in_git).and_return(true)
diff --git a/spec/helpers/blob_helper_spec.rb b/spec/helpers/blob_helper_spec.rb
index bd3a3d24b84..c654151564e 100644
--- a/spec/helpers/blob_helper_spec.rb
+++ b/spec/helpers/blob_helper_spec.rb
@@ -108,7 +108,7 @@ describe BlobHelper do
context 'viewer related' do
include FakeBlobHelpers
- let(:project) { build(:empty_project, lfs_enabled: true) }
+ let(:project) { build(:project, lfs_enabled: true) }
before do
allow(Gitlab.config.lfs).to receive(:enabled).and_return(true)
diff --git a/spec/helpers/button_helper_spec.rb b/spec/helpers/button_helper_spec.rb
index 7ecb75da8ce..250ba239033 100644
--- a/spec/helpers/button_helper_spec.rb
+++ b/spec/helpers/button_helper_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe ButtonHelper do
describe 'http_clone_button' do
let(:user) { create(:user) }
- let(:project) { create(:project) }
+ let(:project) { build_stubbed(:project) }
let(:has_tooltip_class) { 'has-tooltip' }
def element
diff --git a/spec/helpers/ci_status_helper_spec.rb b/spec/helpers/ci_status_helper_spec.rb
index e6bb953e9d8..6a3945c0ebc 100644
--- a/spec/helpers/ci_status_helper_spec.rb
+++ b/spec/helpers/ci_status_helper_spec.rb
@@ -48,7 +48,7 @@ describe CiStatusHelper do
describe "#pipeline_status_cache_key" do
it "builds a cache key for pipeline status" do
pipeline_status = Gitlab::Cache::Ci::ProjectPipelineStatus.new(
- build(:project),
+ build_stubbed(:project),
pipeline_info: {
sha: "123abc",
status: "success"
diff --git a/spec/helpers/commits_helper_spec.rb b/spec/helpers/commits_helper_spec.rb
index c245bb439db..7179185285c 100644
--- a/spec/helpers/commits_helper_spec.rb
+++ b/spec/helpers/commits_helper_spec.rb
@@ -28,7 +28,7 @@ describe CommitsHelper do
end
describe '#view_on_environment_button' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:environment) { create(:environment, external_url: 'http://example.com') }
let(:path) { 'source/file.html' }
let(:sha) { RepoHelpers.sample_commit.id }
diff --git a/spec/helpers/defer_script_tag_helper_spec.rb b/spec/helpers/defer_script_tag_helper_spec.rb
new file mode 100644
index 00000000000..d10b6f134e4
--- /dev/null
+++ b/spec/helpers/defer_script_tag_helper_spec.rb
@@ -0,0 +1,13 @@
+# coding: utf-8
+require 'spec_helper'
+
+describe DeferScriptTagHelper do
+ describe 'script tag' do
+ script_url = 'test.js'
+
+ it 'returns an script tag with defer=true' do
+ expect(javascript_include_tag(script_url).to_s)
+ .to eq "<script src=\"/javascripts/#{script_url}\" defer=\"defer\"></script>"
+ end
+ end
+end
diff --git a/spec/helpers/diff_helper_spec.rb b/spec/helpers/diff_helper_spec.rb
index 060c112e20d..f81a9b6492c 100644
--- a/spec/helpers/diff_helper_spec.rb
+++ b/spec/helpers/diff_helper_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe DiffHelper do
include RepoHelpers
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:repository) { project.repository }
let(:commit) { project.commit(sample_commit.id) }
let(:diffs) { commit.raw_diffs }
diff --git a/spec/helpers/events_helper_spec.rb b/spec/helpers/events_helper_spec.rb
index c3bd0cb3542..aa138f25bd3 100644
--- a/spec/helpers/events_helper_spec.rb
+++ b/spec/helpers/events_helper_spec.rb
@@ -72,13 +72,13 @@ describe EventsHelper do
end
it 'preserves style attribute for a label that can be accessed by current_user' do
- project = create(:empty_project, :public)
+ project = create(:project, :public)
expect(format_event_note(project)).to match(/span class=.*style=.*/)
end
it 'does not style a label that can not be accessed by current_user' do
- project = create(:empty_project, :private)
+ project = create(:project, :private)
expect(format_event_note(project)).to eq("<p>#{input}</p>")
end
diff --git a/spec/helpers/gitlab_routing_helper_spec.rb b/spec/helpers/gitlab_routing_helper_spec.rb
index 717ac1962d1..a44b200c5da 100644
--- a/spec/helpers/gitlab_routing_helper_spec.rb
+++ b/spec/helpers/gitlab_routing_helper_spec.rb
@@ -1,6 +1,9 @@
require 'spec_helper'
describe GitlabRoutingHelper do
+ let(:project) { build_stubbed(:project) }
+ let(:group) { build_stubbed(:group) }
+
describe 'Project URL helpers' do
describe '#project_member_path' do
let(:project_member) { create(:project_member) }
@@ -9,14 +12,10 @@ describe GitlabRoutingHelper do
end
describe '#request_access_project_members_path' do
- let(:project) { build_stubbed(:empty_project) }
-
it { expect(request_access_project_members_path(project)).to eq request_access_project_project_members_path(project) }
end
describe '#leave_project_members_path' do
- let(:project) { build_stubbed(:empty_project) }
-
it { expect(leave_project_members_path(project)).to eq leave_project_project_members_path(project) }
end
@@ -35,8 +34,6 @@ describe GitlabRoutingHelper do
describe 'Group URL helpers' do
describe '#group_members_url' do
- let(:group) { build_stubbed(:group) }
-
it { expect(group_members_url(group)).to eq group_group_members_url(group) }
end
@@ -47,14 +44,10 @@ describe GitlabRoutingHelper do
end
describe '#request_access_group_members_path' do
- let(:group) { build_stubbed(:group) }
-
it { expect(request_access_group_members_path(group)).to eq request_access_group_group_members_path(group) }
end
describe '#leave_group_members_path' do
- let(:group) { build_stubbed(:group) }
-
it { expect(leave_group_members_path(group)).to eq leave_group_group_members_path(group) }
end
diff --git a/spec/helpers/groups_helper_spec.rb b/spec/helpers/groups_helper_spec.rb
index 3a246f10283..9d6e03e3868 100644
--- a/spec/helpers/groups_helper_spec.rb
+++ b/spec/helpers/groups_helper_spec.rb
@@ -23,7 +23,7 @@ describe GroupsHelper do
describe 'group_lfs_status' do
let(:group) { create(:group) }
- let!(:project) { create(:empty_project, namespace_id: group.id) }
+ let!(:project) { create(:project, namespace_id: group.id) }
before do
allow(Gitlab.config.lfs).to receive(:enabled).and_return(true)
@@ -47,7 +47,7 @@ describe GroupsHelper do
context 'more than one project in group' do
before do
- create(:empty_project, namespace_id: group.id)
+ create(:project, namespace_id: group.id)
end
context 'LFS enabled in group' do
diff --git a/spec/helpers/hooks_helper_spec.rb b/spec/helpers/hooks_helper_spec.rb
index 9f0004bf8cf..2e21f1134b1 100644
--- a/spec/helpers/hooks_helper_spec.rb
+++ b/spec/helpers/hooks_helper_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe HooksHelper do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:project_hook) { create(:project_hook, project: project) }
let(:system_hook) { create(:system_hook) }
let(:trigger) { 'push_events' }
diff --git a/spec/helpers/issues_helper_spec.rb b/spec/helpers/issues_helper_spec.rb
index 9524a101e74..dc3100311f8 100644
--- a/spec/helpers/issues_helper_spec.rb
+++ b/spec/helpers/issues_helper_spec.rb
@@ -1,7 +1,7 @@
require "spec_helper"
describe IssuesHelper do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:issue) { create :issue, project: project }
let(:ext_project) { create :redmine_project }
diff --git a/spec/helpers/labels_helper_spec.rb b/spec/helpers/labels_helper_spec.rb
index a8d6044fda7..36d6e495ed0 100644
--- a/spec/helpers/labels_helper_spec.rb
+++ b/spec/helpers/labels_helper_spec.rb
@@ -2,18 +2,18 @@ require 'spec_helper'
describe LabelsHelper do
describe 'link_to_label' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:label) { create(:label, project: project) }
context 'without subject' do
it "uses the label's project" do
- expect(link_to_label(label)).to match %r{<a href="/#{label.project.path_with_namespace}/issues\?label_name%5B%5D=#{label.name}">.*</a>}
+ expect(link_to_label(label)).to match %r{<a href="/#{label.project.full_path}/issues\?label_name%5B%5D=#{label.name}">.*</a>}
end
end
context 'with a project as subject' do
let(:namespace) { build(:namespace, name: 'foo3') }
- let(:another_project) { build(:empty_project, namespace: namespace, name: 'bar3') }
+ let(:another_project) { build(:project, namespace: namespace, name: 'bar3') }
it 'links to project issues page' do
expect(link_to_label(label, subject: another_project)).to match %r{<a href="/foo3/bar3/issues\?label_name%5B%5D=#{label.name}">.*</a>}
@@ -32,7 +32,7 @@ describe LabelsHelper do
['issue', :issue, 'merge_request', :merge_request].each do |type|
context "set to #{type}" do
it 'links to correct page' do
- expect(link_to_label(label, type: type)).to match %r{<a href="/#{label.project.path_with_namespace}/#{type.to_s.pluralize}\?label_name%5B%5D=#{label.name}">.*</a>}
+ expect(link_to_label(label, type: type)).to match %r{<a href="/#{label.project.full_path}/#{type.to_s.pluralize}\?label_name%5B%5D=#{label.name}">.*</a>}
end
end
end
diff --git a/spec/helpers/markup_helper_spec.rb b/spec/helpers/markup_helper_spec.rb
index 4b6a351cf70..70eb01c9c44 100644
--- a/spec/helpers/markup_helper_spec.rb
+++ b/spec/helpers/markup_helper_spec.rb
@@ -210,11 +210,11 @@ describe MarkupHelper do
describe '#cross_project_reference' do
it 'shows the full MR reference' do
- expect(helper.cross_project_reference(project, merge_request)).to include(project.path_with_namespace)
+ expect(helper.cross_project_reference(project, merge_request)).to include(project.full_path)
end
it 'shows the full issue reference' do
- expect(helper.cross_project_reference(project, issue)).to include(project.path_with_namespace)
+ expect(helper.cross_project_reference(project, issue)).to include(project.full_path)
end
end
end
diff --git a/spec/helpers/members_helper_spec.rb b/spec/helpers/members_helper_spec.rb
index 2b455571d52..33186cf50d5 100644
--- a/spec/helpers/members_helper_spec.rb
+++ b/spec/helpers/members_helper_spec.rb
@@ -11,7 +11,7 @@ describe MembersHelper do
describe '#remove_member_message' do
let(:requester) { create(:user) }
- let(:project) { create(:empty_project, :public, :access_requestable) }
+ let(:project) { create(:project, :public, :access_requestable) }
let(:project_member) { build(:project_member, project: project) }
let(:project_member_invite) { build(:project_member, project: project).tap { |m| m.generate_invite_token! } }
let(:project_member_request) { project.request_access(requester) }
@@ -32,7 +32,7 @@ describe MembersHelper do
describe '#remove_member_title' do
let(:requester) { create(:user) }
- let(:project) { create(:empty_project, :public, :access_requestable) }
+ let(:project) { create(:project, :public, :access_requestable) }
let(:project_member) { build(:project_member, project: project) }
let(:project_member_request) { project.request_access(requester) }
let(:group) { create(:group, :access_requestable) }
@@ -46,7 +46,7 @@ describe MembersHelper do
end
describe '#leave_confirmation_message' do
- let(:project) { build_stubbed(:empty_project) }
+ let(:project) { build_stubbed(:project) }
let(:group) { build_stubbed(:group) }
let(:user) { build_stubbed(:user) }
diff --git a/spec/helpers/merge_requests_helper_spec.rb b/spec/helpers/merge_requests_helper_spec.rb
index 493a4ff9a93..7d1c17909bf 100644
--- a/spec/helpers/merge_requests_helper_spec.rb
+++ b/spec/helpers/merge_requests_helper_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe MergeRequestsHelper do
describe 'ci_build_details_path' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:merge_request) { MergeRequest.new }
let(:ci_service) { CiService.new }
let(:last_commit) { Ci::Pipeline.new({}) }
@@ -30,12 +30,12 @@ describe MergeRequestsHelper do
end
describe 'within different projects' do
- let(:project) { create(:empty_project) }
- let(:fork_project) { create(:empty_project, forked_from_project: project) }
+ let(:project) { create(:project) }
+ let(:fork_project) { create(:project, forked_from_project: project) }
let(:merge_request) { create(:merge_request, source_project: fork_project, target_project: project) }
subject { format_mr_branch_names(merge_request) }
- let(:source_title) { "#{fork_project.path_with_namespace}:#{merge_request.source_branch}" }
- let(:target_title) { "#{project.path_with_namespace}:#{merge_request.target_branch}" }
+ let(:source_title) { "#{fork_project.full_path}:#{merge_request.source_branch}" }
+ let(:target_title) { "#{project.full_path}:#{merge_request.target_branch}" }
it { is_expected.to eq([source_title, target_title]) }
end
diff --git a/spec/helpers/milestones_helper_spec.rb b/spec/helpers/milestones_helper_spec.rb
index b8f9c02a486..70b4a89cb86 100644
--- a/spec/helpers/milestones_helper_spec.rb
+++ b/spec/helpers/milestones_helper_spec.rb
@@ -2,8 +2,8 @@ require 'spec_helper'
describe MilestonesHelper do
describe '#milestones_filter_dropdown_path' do
- let(:project) { create(:empty_project) }
- let(:project2) { create(:empty_project) }
+ let(:project) { create(:project) }
+ let(:project2) { create(:project) }
let(:group) { create(:group) }
context 'when @project present' do
@@ -57,7 +57,7 @@ describe MilestonesHelper do
end
describe '#milestone_counts' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:counts) { helper.milestone_counts(project.milestones) }
context 'when there are milestones' do
diff --git a/spec/helpers/milestones_routing_helper_spec.rb b/spec/helpers/milestones_routing_helper_spec.rb
new file mode 100644
index 00000000000..dc13a43c2ab
--- /dev/null
+++ b/spec/helpers/milestones_routing_helper_spec.rb
@@ -0,0 +1,46 @@
+require 'spec_helper'
+
+describe MilestonesRoutingHelper do
+ let(:project) { build_stubbed(:project) }
+ let(:group) { build_stubbed(:group) }
+
+ describe '#milestone_path' do
+ context 'for a group milestone' do
+ let(:milestone) { build_stubbed(:milestone, group: group, iid: 1) }
+
+ it 'links to the group milestone page' do
+ expect(milestone_path(milestone))
+ .to eq(group_milestone_path(group, milestone))
+ end
+ end
+
+ context 'for a project milestone' do
+ let(:milestone) { build_stubbed(:milestone, project: project, iid: 1) }
+
+ it 'links to the project milestone page' do
+ expect(milestone_path(milestone))
+ .to eq(project_milestone_path(project, milestone))
+ end
+ end
+ end
+
+ describe '#milestone_url' do
+ context 'for a group milestone' do
+ let(:milestone) { build_stubbed(:milestone, group: group, iid: 1) }
+
+ it 'links to the group milestone page' do
+ expect(milestone_url(milestone))
+ .to eq(group_milestone_url(group, milestone))
+ end
+ end
+
+ context 'for a project milestone' do
+ let(:milestone) { build_stubbed(:milestone, project: project, iid: 1) }
+
+ it 'links to the project milestone page' do
+ expect(milestone_url(milestone))
+ .to eq(project_milestone_url(project, milestone))
+ end
+ end
+ end
+end
diff --git a/spec/helpers/notes_helper_spec.rb b/spec/helpers/notes_helper_spec.rb
index 56f252ba273..9921ca1af33 100644
--- a/spec/helpers/notes_helper_spec.rb
+++ b/spec/helpers/notes_helper_spec.rb
@@ -5,7 +5,7 @@ describe NotesHelper do
let(:owner) { create(:owner) }
let(:group) { create(:group) }
- let(:project) { create(:empty_project, namespace: group) }
+ let(:project) { create(:project, namespace: group) }
let(:master) { create(:user) }
let(:reporter) { create(:user) }
let(:guest) { create(:user) }
@@ -30,7 +30,7 @@ describe NotesHelper do
end
it 'handles access in different projects' do
- second_project = create(:empty_project)
+ second_project = create(:project)
second_project.team << [master, :reporter]
other_note = create(:note, author: master, project: second_project)
@@ -40,7 +40,7 @@ describe NotesHelper do
end
describe '#discussion_path' do
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
context 'for a merge request discusion' do
let(:merge_request) { create(:merge_request, source_project: project, target_project: project, importing: true) }
@@ -191,7 +191,7 @@ describe NotesHelper do
it 'return project notes path for project snippet' do
namespace = create(:namespace, path: 'nm')
- @project = create(:empty_project, path: 'test', namespace: namespace)
+ @project = create(:project, path: 'test', namespace: namespace)
@snippet = create(:project_snippet, project: @project)
@noteable = @snippet
@@ -200,7 +200,7 @@ describe NotesHelper do
it 'return project notes path for other noteables' do
namespace = create(:namespace, path: 'nm')
- @project = create(:empty_project, path: 'test', namespace: namespace)
+ @project = create(:project, path: 'test', namespace: namespace)
@noteable = create(:issue, project: @project)
expect(helper.notes_url).to eq("/nm/test/noteable/issue/#{@noteable.id}/notes")
@@ -216,7 +216,7 @@ describe NotesHelper do
it 'return project notes path for project snippet' do
namespace = create(:namespace, path: 'nm')
- @project = create(:empty_project, path: 'test', namespace: namespace)
+ @project = create(:project, path: 'test', namespace: namespace)
note = create(:note_on_project_snippet, project: @project)
expect(helper.note_url(note)).to eq("/nm/test/notes/#{note.id}")
@@ -224,7 +224,7 @@ describe NotesHelper do
it 'return project notes path for other noteables' do
namespace = create(:namespace, path: 'nm')
- @project = create(:empty_project, path: 'test', namespace: namespace)
+ @project = create(:project, path: 'test', namespace: namespace)
note = create(:note_on_issue, project: @project)
expect(helper.note_url(note)).to eq("/nm/test/notes/#{note.id}")
@@ -241,7 +241,7 @@ describe NotesHelper do
it 'returns namespace, project and note for project snippet' do
namespace = create(:namespace, path: 'nm')
- @project = create(:empty_project, path: 'test', namespace: namespace)
+ @project = create(:project, path: 'test', namespace: namespace)
@snippet = create(:project_snippet, project: @project)
@note = create(:note_on_personal_snippet)
@@ -250,7 +250,7 @@ describe NotesHelper do
it 'returns namespace, project and note path for other noteables' do
namespace = create(:namespace, path: 'nm')
- @project = create(:empty_project, path: 'test', namespace: namespace)
+ @project = create(:project, path: 'test', namespace: namespace)
@note = create(:note_on_issue, project: @project)
expect(helper.form_resources).to eq([@project.namespace, @project, @note])
@@ -258,7 +258,7 @@ describe NotesHelper do
end
describe '#noteable_note_url' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:issue) { create(:issue, project: project) }
let(:note) { create(:note_on_issue, noteable: issue, project: project) }
diff --git a/spec/helpers/pagination_helper_spec.rb b/spec/helpers/pagination_helper_spec.rb
new file mode 100644
index 00000000000..e235475fb47
--- /dev/null
+++ b/spec/helpers/pagination_helper_spec.rb
@@ -0,0 +1,23 @@
+require 'spec_helper'
+
+describe PaginationHelper do
+ describe '#paginate_collection' do
+ let(:collection) { User.all.page(1) }
+
+ it 'paginates a collection without using a COUNT' do
+ without_count = collection.without_count
+
+ expect(helper).to receive(:paginate_without_count)
+ .with(without_count)
+ .and_call_original
+
+ helper.paginate_collection(without_count)
+ end
+
+ it 'paginates a collection using a COUNT' do
+ expect(helper).to receive(:paginate_with_count).and_call_original
+
+ helper.paginate_collection(collection)
+ end
+ end
+end
diff --git a/spec/helpers/projects_helper_spec.rb b/spec/helpers/projects_helper_spec.rb
index 45066a60f50..d1efa318d14 100644
--- a/spec/helpers/projects_helper_spec.rb
+++ b/spec/helpers/projects_helper_spec.rb
@@ -46,25 +46,25 @@ describe ProjectsHelper do
end
describe "readme_cache_key" do
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
before do
helper.instance_variable_set(:@project, project)
end
it "returns a valid cach key" do
- expect(helper.send(:readme_cache_key)).to eq("#{project.path_with_namespace}-#{project.commit.id}-readme")
+ expect(helper.send(:readme_cache_key)).to eq("#{project.full_path}-#{project.commit.id}-readme")
end
it "returns a valid cache key if HEAD does not exist" do
allow(project).to receive(:commit) { nil }
- expect(helper.send(:readme_cache_key)).to eq("#{project.path_with_namespace}-nil-readme")
+ expect(helper.send(:readme_cache_key)).to eq("#{project.full_path}-nil-readme")
end
end
describe "#project_list_cache_key", clean_gitlab_redis_shared_state: true do
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
it "includes the route" do
expect(helper.project_list_cache_key(project)).to include(project.route.cache_key)
@@ -105,7 +105,7 @@ describe ProjectsHelper do
describe '#load_pipeline_status' do
it 'loads the pipeline status in batch' do
- project = build(:empty_project)
+ project = build(:project)
helper.load_pipeline_status([project])
# Skip lazy loading of the `pipeline_status` attribute
@@ -193,7 +193,7 @@ describe ProjectsHelper do
describe 'link_to_member' do
let(:group) { create(:group) }
- let(:project) { create(:empty_project, group: group) }
+ let(:project) { create(:project, group: group) }
let(:user) { create(:user) }
describe 'using the default options' do
@@ -225,7 +225,7 @@ describe ProjectsHelper do
end
describe '#license_short_name' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
context 'when project.repository has a license_key' do
it 'returns the nickname of the license if present' do
@@ -251,7 +251,7 @@ describe ProjectsHelper do
end
describe '#sanitized_import_error' do
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
before do
allow(project).to receive(:repository_storage_path).and_return('/base/repo/path')
@@ -312,7 +312,7 @@ describe ProjectsHelper do
end
describe "#project_feature_access_select" do
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:user) { create(:user) }
context "when project is internal or public" do
@@ -380,7 +380,7 @@ describe ProjectsHelper do
end
describe '#get_project_nav_tabs' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:user) { create(:user) }
before do
@@ -411,4 +411,54 @@ describe ProjectsHelper do
end
end
end
+
+ describe '#has_projects_or_name?' do
+ let(:projects) do
+ create(:project)
+ Project.all
+ end
+
+ it 'returns true when there are projects' do
+ expect(helper.has_projects_or_name?(projects, {})).to eq(true)
+ end
+
+ it 'returns true when there are no projects but a name is given' do
+ expect(helper.has_projects_or_name?(Project.none, name: 'foo')).to eq(true)
+ end
+
+ it 'returns false when there are no projects and there is no name' do
+ expect(helper.has_projects_or_name?(Project.none, {})).to eq(false)
+ end
+ end
+
+ describe '#any_projects?' do
+ let!(:project) { create(:project) }
+
+ it 'returns true when projects will be returned' do
+ expect(helper.any_projects?(Project.all)).to eq(true)
+ end
+
+ it 'returns false when no projects will be returned' do
+ expect(helper.any_projects?(Project.none)).to eq(false)
+ end
+
+ it 'returns true when using a non-empty Array' do
+ expect(helper.any_projects?([project])).to eq(true)
+ end
+
+ it 'returns false when using an empty Array' do
+ expect(helper.any_projects?([])).to eq(false)
+ end
+
+ it 'only executes a single query when a LIMIT is applied' do
+ relation = Project.limit(1)
+ recorder = ActiveRecord::QueryRecorder.new do
+ 2.times do
+ helper.any_projects?(relation)
+ end
+ end
+
+ expect(recorder.count).to eq(1)
+ end
+ end
end
diff --git a/spec/helpers/search_helper_spec.rb b/spec/helpers/search_helper_spec.rb
index b7e547dc1f5..463af15930d 100644
--- a/spec/helpers/search_helper_spec.rb
+++ b/spec/helpers/search_helper_spec.rb
@@ -47,7 +47,7 @@ describe SearchHelper do
end
it "includes the user's projects" do
- project = create(:empty_project, namespace: create(:namespace, owner: user))
+ project = create(:project, namespace: create(:namespace, owner: user))
expect(search_autocomplete_opts(project.name).size).to eq(1)
end
@@ -68,4 +68,38 @@ describe SearchHelper do
end
end
end
+
+ describe 'search_filter_input_options' do
+ context 'project' do
+ before do
+ @project = create(:project, :repository)
+ end
+
+ it 'includes id with type' do
+ expect(search_filter_input_options('type')[:id]).to eq('filtered-search-type')
+ end
+
+ it 'includes project-id' do
+ expect(search_filter_input_options('')[:data]['project-id']).to eq(@project.id)
+ end
+
+ it 'includes project base-endpoint' do
+ expect(search_filter_input_options('')[:data]['base-endpoint']).to eq(project_path(@project))
+ end
+ end
+
+ context 'group' do
+ before do
+ @group = create(:group, name: 'group')
+ end
+
+ it 'does not includes project-id' do
+ expect(search_filter_input_options('')[:data]['project-id']).to eq(nil)
+ end
+
+ it 'includes group base-endpoint' do
+ expect(search_filter_input_options('')[:data]['base-endpoint']).to eq("/groups#{group_path(@group)}")
+ end
+ end
+ end
end
diff --git a/spec/helpers/storage_health_helper_spec.rb b/spec/helpers/storage_health_helper_spec.rb
new file mode 100644
index 00000000000..874498e6338
--- /dev/null
+++ b/spec/helpers/storage_health_helper_spec.rb
@@ -0,0 +1,20 @@
+require 'spec_helper'
+
+describe StorageHealthHelper do
+ describe '#failing_storage_health_message' do
+ let(:health) do
+ Gitlab::Git::Storage::Health.new(
+ "<script>alert('storage name');)</script>",
+ []
+ )
+ end
+
+ it 'escapes storage names' do
+ escaped_storage_name = '&lt;script&gt;alert(&#39;storage name&#39;);)&lt;/script&gt;'
+
+ result = helper.failing_storage_health_message(health)
+
+ expect(result).to include(escaped_storage_name)
+ end
+ end
+end
diff --git a/spec/helpers/submodule_helper_spec.rb b/spec/helpers/submodule_helper_spec.rb
index 9e561d0f191..c4f4e0d21dc 100644
--- a/spec/helpers/submodule_helper_spec.rb
+++ b/spec/helpers/submodule_helper_spec.rb
@@ -91,7 +91,7 @@ describe SubmoduleHelper do
context 'in-repository submodule' do
let(:group) { create(:group, name: "Master Project", path: "master-project") }
- let(:project) { create(:empty_project, group: group) }
+ let(:project) { create(:project, group: group) }
before do
self.instance_variable_set(:@project, project)
end
@@ -158,7 +158,7 @@ describe SubmoduleHelper do
context 'submodules with relative links' do
let(:group) { create(:group, name: "Master Project", path: "master-project") }
- let(:project) { create(:empty_project, group: group) }
+ let(:project) { create(:project, group: group) }
let(:commit_id) { sample_commit[:id] }
before do
@@ -192,7 +192,7 @@ describe SubmoduleHelper do
context 'personal project' do
let(:user) { create(:user) }
- let(:project) { create(:empty_project, namespace: user.namespace) }
+ let(:project) { create(:project, namespace: user.namespace) }
it 'one level down with personal project' do
result = relative_self_links('../test.git', commit_id)
diff --git a/spec/helpers/todos_helper_spec.rb b/spec/helpers/todos_helper_spec.rb
index 18a41ca24e3..f55163c26e9 100644
--- a/spec/helpers/todos_helper_spec.rb
+++ b/spec/helpers/todos_helper_spec.rb
@@ -15,7 +15,7 @@ describe TodosHelper do
end
describe '#todo_projects_options' do
- let(:projects) { create_list(:empty_project, 3) }
+ let(:projects) { create_list(:project, 3) }
let(:user) { create(:user) }
it 'returns users authorised projects in json format' do
diff --git a/spec/helpers/visibility_level_helper_spec.rb b/spec/helpers/visibility_level_helper_spec.rb
index ad19cf9263d..c3cccbb0d95 100644
--- a/spec/helpers/visibility_level_helper_spec.rb
+++ b/spec/helpers/visibility_level_helper_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe VisibilityLevelHelper do
- let(:project) { build(:empty_project) }
+ let(:project) { build(:project) }
let(:group) { build(:group) }
let(:personal_snippet) { build(:personal_snippet) }
let(:project_snippet) { build(:project_snippet) }
@@ -60,8 +60,8 @@ describe VisibilityLevelHelper do
describe "skip_level?" do
describe "forks" do
- let(:project) { create(:empty_project, :internal) }
- let(:fork_project) { create(:empty_project, forked_from_project: project) }
+ let(:project) { create(:project, :internal) }
+ let(:fork_project) { create(:project, forked_from_project: project) }
it "skips levels" do
expect(skip_level?(fork_project, Gitlab::VisibilityLevel::PUBLIC)).to be_truthy
@@ -71,7 +71,7 @@ describe VisibilityLevelHelper do
end
describe "non-forked project" do
- let(:project) { create(:empty_project, :internal) }
+ let(:project) { create(:project, :internal) }
it "skips levels" do
expect(skip_level?(project, Gitlab::VisibilityLevel::PUBLIC)).to be_falsey
diff --git a/spec/initializers/6_validations_spec.rb b/spec/initializers/6_validations_spec.rb
index 0877770c167..83283f03940 100644
--- a/spec/initializers/6_validations_spec.rb
+++ b/spec/initializers/6_validations_spec.rb
@@ -23,6 +23,16 @@ describe '6_validations' do
end
end
+ context 'when one of the settings is incorrect' do
+ before do
+ mock_storages('foo' => { 'path' => 'tmp/tests/paths/a/b/c', 'failure_count_threshold' => 'not a number' })
+ end
+
+ it 'throws an error' do
+ expect { validate_storages_config }.to raise_error(/failure_count_threshold/)
+ end
+ end
+
context 'with invalid storage names' do
before do
mock_storages('name with spaces' => { 'path' => 'tmp/tests/paths/a/b/c' })
@@ -84,6 +94,17 @@ describe '6_validations' do
expect { validate_storages_paths }.not_to raise_error
end
end
+
+ describe 'inaccessible storage' do
+ before do
+ mock_storages('foo' => { 'path' => 'tmp/tests/a/path/that/does/not/exist' })
+ end
+
+ it 'passes through with a warning' do
+ expect(Rails.logger).to receive(:error)
+ expect { validate_storages_paths }.not_to raise_error
+ end
+ end
end
def mock_storages(storages)
diff --git a/spec/initializers/settings_spec.rb b/spec/initializers/settings_spec.rb
index ebdabcf93f1..e5ec90cb8f9 100644
--- a/spec/initializers/settings_spec.rb
+++ b/spec/initializers/settings_spec.rb
@@ -2,6 +2,17 @@ require 'spec_helper'
require_relative '../../config/initializers/1_settings'
describe Settings do
+ describe '#repositories' do
+ it 'assigns the default failure attributes' do
+ repository_settings = Gitlab.config.repositories.storages['broken']
+
+ expect(repository_settings['failure_count_threshold']).to eq(10)
+ expect(repository_settings['failure_wait_time']).to eq(30)
+ expect(repository_settings['failure_reset_time']).to eq(1800)
+ expect(repository_settings['storage_timeout']).to eq(5)
+ end
+ end
+
describe '#host_without_www' do
context 'URL with protocol' do
it 'returns the host' do
diff --git a/spec/javascripts/abuse_reports_spec.js b/spec/javascripts/abuse_reports_spec.js
index 069d857eab6..13cab81dd60 100644
--- a/spec/javascripts/abuse_reports_spec.js
+++ b/spec/javascripts/abuse_reports_spec.js
@@ -6,10 +6,10 @@ import '~/abuse_reports';
const FIXTURE = 'abuse_reports/abuse_reports_list.html.raw';
const MAX_MESSAGE_LENGTH = 500;
- let messages;
+ let $messages;
const assertMaxLength = $message => expect($message.text().length).toEqual(MAX_MESSAGE_LENGTH);
- const findMessage = searchText => messages.filter(
+ const findMessage = searchText => $messages.filter(
(index, element) => element.innerText.indexOf(searchText) > -1,
).first();
@@ -18,7 +18,7 @@ import '~/abuse_reports';
beforeEach(function () {
loadFixtures(FIXTURE);
this.abuseReports = new global.AbuseReports();
- messages = $('.abuse-reports .message');
+ $messages = $('.abuse-reports .message');
});
it('should truncate long messages', () => {
diff --git a/spec/javascripts/ajax_loading_spinner_spec.js b/spec/javascripts/ajax_loading_spinner_spec.js
index 1518ae68b0d..46e072a8ebb 100644
--- a/spec/javascripts/ajax_loading_spinner_spec.js
+++ b/spec/javascripts/ajax_loading_spinner_spec.js
@@ -1,4 +1,3 @@
-import '~/extensions/array';
import 'jquery';
import 'jquery-ujs';
import '~/ajax_loading_spinner';
diff --git a/spec/javascripts/blob/blob_file_dropzone_spec.js b/spec/javascripts/blob/blob_file_dropzone_spec.js
new file mode 100644
index 00000000000..2c8183ff77b
--- /dev/null
+++ b/spec/javascripts/blob/blob_file_dropzone_spec.js
@@ -0,0 +1,42 @@
+import 'dropzone';
+import BlobFileDropzone from '~/blob/blob_file_dropzone';
+
+describe('BlobFileDropzone', () => {
+ preloadFixtures('blob/show.html.raw');
+
+ beforeEach(() => {
+ loadFixtures('blob/show.html.raw');
+ const form = $('.js-upload-blob-form');
+ this.blobFileDropzone = new BlobFileDropzone(form, 'POST');
+ this.dropzone = $('.js-upload-blob-form .dropzone').get(0).dropzone;
+ this.replaceFileButton = $('#submit-all');
+ });
+
+ describe('submit button', () => {
+ it('requires file', () => {
+ spyOn(window, 'alert');
+
+ this.replaceFileButton.click();
+
+ expect(window.alert).toHaveBeenCalled();
+ });
+
+ it('is disabled while uploading', () => {
+ spyOn(window, 'alert');
+
+ const file = {
+ name: 'some-file.jpg',
+ type: 'jpg',
+ };
+ const fakeEvent = jQuery.Event('drop', {
+ dataTransfer: { files: [file] },
+ });
+
+ this.dropzone.listeners[0].events.drop(fakeEvent);
+ this.replaceFileButton.click();
+
+ expect(window.alert).not.toHaveBeenCalled();
+ expect(this.replaceFileButton.is(':disabled')).toEqual(true);
+ });
+ });
+});
diff --git a/spec/javascripts/blob/viewer/index_spec.js b/spec/javascripts/blob/viewer/index_spec.js
index af04e7c1e72..cfa6650d85f 100644
--- a/spec/javascripts/blob/viewer/index_spec.js
+++ b/spec/javascripts/blob/viewer/index_spec.js
@@ -3,10 +3,10 @@ import BlobViewer from '~/blob/viewer/index';
describe('Blob viewer', () => {
let blob;
- preloadFixtures('blob/show.html.raw');
+ preloadFixtures('snippets/show.html.raw');
beforeEach(() => {
- loadFixtures('blob/show.html.raw');
+ loadFixtures('snippets/show.html.raw');
$('#modal-upload-blob').remove();
blob = new BlobViewer();
diff --git a/spec/javascripts/boards/issue_card_spec.js b/spec/javascripts/boards/issue_card_spec.js
index bd9b4fbfdd3..69cfcbbce5a 100644
--- a/spec/javascripts/boards/issue_card_spec.js
+++ b/spec/javascripts/boards/issue_card_spec.js
@@ -238,12 +238,6 @@ describe('Issue card component', () => {
});
describe('labels', () => {
- it('does not render any', () => {
- expect(
- component.$el.querySelector('.label'),
- ).toBeNull();
- });
-
describe('exists', () => {
beforeEach((done) => {
component.issue.addLabel(label1);
@@ -251,16 +245,21 @@ describe('Issue card component', () => {
Vue.nextTick(() => done());
});
- it('does not render list label', () => {
+ it('renders list label', () => {
expect(
component.$el.querySelectorAll('.label').length,
- ).toBe(1);
+ ).toBe(2);
});
it('renders label', () => {
+ const nodes = [];
+ component.$el.querySelectorAll('.label').forEach((label) => {
+ nodes.push(label.title);
+ });
+
expect(
- component.$el.querySelector('.label').textContent,
- ).toContain(label1.title);
+ nodes.includes(label1.description),
+ ).toBe(true);
});
it('sets label description as title', () => {
@@ -270,9 +269,14 @@ describe('Issue card component', () => {
});
it('sets background color of button', () => {
+ const nodes = [];
+ component.$el.querySelectorAll('.label').forEach((label) => {
+ nodes.push(label.style.backgroundColor);
+ });
+
expect(
- component.$el.querySelector('.label').style.backgroundColor,
- ).toContain(label1.color);
+ nodes.includes(label1.color),
+ ).toBe(true);
});
});
});
diff --git a/spec/javascripts/breakpoints_spec.js b/spec/javascripts/breakpoints_spec.js
new file mode 100644
index 00000000000..b1b5d36c1fb
--- /dev/null
+++ b/spec/javascripts/breakpoints_spec.js
@@ -0,0 +1,15 @@
+import bp, {
+ breakpoints,
+} from '~/breakpoints';
+
+describe('breakpoints', () => {
+ Object.keys(breakpoints).forEach((key) => {
+ const size = breakpoints[key];
+
+ it(`returns ${key} when larger than ${size}`, () => {
+ spyOn(bp, 'windowWidth').and.returnValue(size + 10);
+
+ expect(bp.getBreakpointSize()).toBe(key);
+ });
+ });
+});
diff --git a/spec/javascripts/build_spec.js b/spec/javascripts/build_spec.js
index be90dbdd88a..35149611095 100644
--- a/spec/javascripts/build_spec.js
+++ b/spec/javascripts/build_spec.js
@@ -5,7 +5,6 @@ import '~/lib/utils/datetime_utility';
import '~/lib/utils/url_utility';
import '~/build';
import '~/breakpoints';
-import 'vendor/jquery.nicescroll';
describe('Build', () => {
const BUILD_URL = `${gl.TEST_HOST}/frontend-fixtures/builds-project/-/jobs/1`;
diff --git a/spec/javascripts/droplab/plugins/ajax_spec.js b/spec/javascripts/droplab/plugins/ajax_spec.js
new file mode 100644
index 00000000000..085f25764fe
--- /dev/null
+++ b/spec/javascripts/droplab/plugins/ajax_spec.js
@@ -0,0 +1,36 @@
+import AjaxCache from '~/lib/utils/ajax_cache';
+import Ajax from '~/droplab/plugins/ajax';
+
+describe('Ajax', () => {
+ describe('preprocessing', () => {
+ const config = {};
+
+ describe('is not configured', () => {
+ it('passes the data through', () => {
+ const data = ['data'];
+ expect(Ajax.preprocessing(config, data)).toEqual(data);
+ });
+ });
+
+ describe('is configured', () => {
+ const processedArray = ['processed'];
+
+ beforeEach(() => {
+ config.preprocessing = () => processedArray;
+ spyOn(config, 'preprocessing').and.callFake(() => processedArray);
+ });
+
+ it('calls preprocessing', () => {
+ Ajax.preprocessing(config, []);
+ expect(config.preprocessing.calls.count()).toBe(1);
+ });
+
+ it('overrides AjaxCache', () => {
+ spyOn(AjaxCache, 'override').and.callFake((endpoint, results) => expect(results).toEqual(processedArray));
+
+ Ajax.preprocessing(config, []);
+ expect(AjaxCache.override.calls.count()).toBe(1);
+ });
+ });
+ });
+});
diff --git a/spec/javascripts/extensions/array_spec.js b/spec/javascripts/extensions/array_spec.js
deleted file mode 100644
index b1b81b4efc2..00000000000
--- a/spec/javascripts/extensions/array_spec.js
+++ /dev/null
@@ -1,22 +0,0 @@
-/* eslint-disable space-before-function-paren, no-var */
-
-import '~/extensions/array';
-
-(function() {
- describe('Array extensions', function() {
- describe('first', function() {
- return it('returns the first item', function() {
- var arr;
- arr = [0, 1, 2, 3, 4, 5];
- return expect(arr.first()).toBe(0);
- });
- });
- describe('last', function() {
- return it('returns the last item', function() {
- var arr;
- arr = [0, 1, 2, 3, 4, 5];
- return expect(arr.last()).toBe(5);
- });
- });
- });
-}).call(window);
diff --git a/spec/javascripts/filtered_search/dropdown_utils_spec.js b/spec/javascripts/filtered_search/dropdown_utils_spec.js
index f55726379f3..b1b3d43f241 100644
--- a/spec/javascripts/filtered_search/dropdown_utils_spec.js
+++ b/spec/javascripts/filtered_search/dropdown_utils_spec.js
@@ -1,4 +1,3 @@
-import '~/extensions/array';
import '~/filtered_search/dropdown_utils';
import '~/filtered_search/filtered_search_tokenizer';
import '~/filtered_search/filtered_search_dropdown_manager';
@@ -191,6 +190,102 @@ describe('Dropdown Utils', () => {
});
});
+ describe('mergeDuplicateLabels', () => {
+ const dataMap = {
+ label: {
+ title: 'label',
+ color: '#FFFFFF',
+ },
+ };
+
+ it('should add label to dataMap if it is not a duplicate', () => {
+ const newLabel = {
+ title: 'new-label',
+ color: '#000000',
+ };
+
+ const updated = gl.DropdownUtils.mergeDuplicateLabels(dataMap, newLabel);
+ expect(updated[newLabel.title]).toEqual(newLabel);
+ });
+
+ it('should merge colors if label is a duplicate', () => {
+ const duplicate = {
+ title: 'label',
+ color: '#000000',
+ };
+
+ const updated = gl.DropdownUtils.mergeDuplicateLabels(dataMap, duplicate);
+ expect(updated.label.multipleColors).toEqual([dataMap.label.color, duplicate.color]);
+ });
+ });
+
+ describe('duplicateLabelColor', () => {
+ it('should linear-gradient 2 colors', () => {
+ const gradient = gl.DropdownUtils.duplicateLabelColor(['#FFFFFF', '#000000']);
+ expect(gradient).toEqual('linear-gradient(#FFFFFF 0%, #FFFFFF 50%, #000000 50%, #000000 100%)');
+ });
+
+ it('should linear-gradient 3 colors', () => {
+ const gradient = gl.DropdownUtils.duplicateLabelColor(['#FFFFFF', '#000000', '#333333']);
+ expect(gradient).toEqual('linear-gradient(#FFFFFF 0%, #FFFFFF 33%, #000000 33%, #000000 66%, #333333 66%, #333333 100%)');
+ });
+
+ it('should linear-gradient 4 colors', () => {
+ const gradient = gl.DropdownUtils.duplicateLabelColor(['#FFFFFF', '#000000', '#333333', '#DDDDDD']);
+ expect(gradient).toEqual('linear-gradient(#FFFFFF 0%, #FFFFFF 25%, #000000 25%, #000000 50%, #333333 50%, #333333 75%, #DDDDDD 75%, #DDDDDD 100%)');
+ });
+
+ it('should not linear-gradient more than 4 colors', () => {
+ const gradient = gl.DropdownUtils.duplicateLabelColor(['#FFFFFF', '#000000', '#333333', '#DDDDDD', '#EEEEEE']);
+ expect(gradient.indexOf('#EEEEEE') === -1).toEqual(true);
+ });
+ });
+
+ describe('duplicateLabelPreprocessing', () => {
+ it('should set preprocessed to true', () => {
+ const results = gl.DropdownUtils.duplicateLabelPreprocessing([]);
+ expect(results.preprocessed).toEqual(true);
+ });
+
+ it('should not mutate existing data if there are no duplicates', () => {
+ const data = [{
+ title: 'label1',
+ color: '#FFFFFF',
+ }, {
+ title: 'label2',
+ color: '#000000',
+ }];
+ const results = gl.DropdownUtils.duplicateLabelPreprocessing(data);
+
+ expect(results.length).toEqual(2);
+ expect(results[0]).toEqual(data[0]);
+ expect(results[1]).toEqual(data[1]);
+ });
+
+ describe('duplicate labels', () => {
+ const data = [{
+ title: 'label',
+ color: '#FFFFFF',
+ }, {
+ title: 'label',
+ color: '#000000',
+ }];
+ const results = gl.DropdownUtils.duplicateLabelPreprocessing(data);
+
+ it('should merge duplicate labels', () => {
+ expect(results.length).toEqual(1);
+ });
+
+ it('should convert multiple colored labels into linear-gradient', () => {
+ expect(results[0].color).toEqual(gl.DropdownUtils.duplicateLabelColor(['#FFFFFF', '#000000']));
+ });
+
+ it('should set multiple colored label text color to black', () => {
+ expect(results[0].text_color).toEqual('#000000');
+ });
+ });
+ });
+
describe('setDataValueIfSelected', () => {
beforeEach(() => {
spyOn(gl.FilteredSearchDropdownManager, 'addWordToInput')
diff --git a/spec/javascripts/filtered_search/filtered_search_dropdown_manager_spec.js b/spec/javascripts/filtered_search/filtered_search_dropdown_manager_spec.js
index 9e2076dc383..5c7e9115aac 100644
--- a/spec/javascripts/filtered_search/filtered_search_dropdown_manager_spec.js
+++ b/spec/javascripts/filtered_search/filtered_search_dropdown_manager_spec.js
@@ -1,4 +1,3 @@
-import '~/extensions/array';
import '~/filtered_search/filtered_search_visual_tokens';
import '~/filtered_search/filtered_search_tokenizer';
import '~/filtered_search/filtered_search_dropdown_manager';
diff --git a/spec/javascripts/filtered_search/filtered_search_token_keys_spec.js b/spec/javascripts/filtered_search/filtered_search_token_keys_spec.js
index 1a7631994b4..69b424c3af5 100644
--- a/spec/javascripts/filtered_search/filtered_search_token_keys_spec.js
+++ b/spec/javascripts/filtered_search/filtered_search_token_keys_spec.js
@@ -1,4 +1,3 @@
-import '~/extensions/array';
import '~/filtered_search/filtered_search_token_keys';
describe('Filtered Search Token Keys', () => {
diff --git a/spec/javascripts/filtered_search/filtered_search_tokenizer_spec.js b/spec/javascripts/filtered_search/filtered_search_tokenizer_spec.js
index e4a15c83c23..585bea9b499 100644
--- a/spec/javascripts/filtered_search/filtered_search_tokenizer_spec.js
+++ b/spec/javascripts/filtered_search/filtered_search_tokenizer_spec.js
@@ -1,4 +1,3 @@
-import '~/extensions/array';
import '~/filtered_search/filtered_search_token_keys';
import '~/filtered_search/filtered_search_tokenizer';
diff --git a/spec/javascripts/filtered_search/filtered_search_visual_tokens_spec.js b/spec/javascripts/filtered_search/filtered_search_visual_tokens_spec.js
index fa4343ffbc8..67166802c70 100644
--- a/spec/javascripts/filtered_search/filtered_search_visual_tokens_spec.js
+++ b/spec/javascripts/filtered_search/filtered_search_visual_tokens_spec.js
@@ -797,6 +797,69 @@ describe('Filtered Search Visual Tokens', () => {
});
});
+ describe('setTokenStyle', () => {
+ let originalTextColor;
+
+ beforeEach(() => {
+ originalTextColor = bugLabelToken.style.color;
+ });
+
+ it('should set backgroundColor', () => {
+ const originalBackgroundColor = bugLabelToken.style.backgroundColor;
+ const token = subject.setTokenStyle(bugLabelToken, 'blue', 'white');
+ expect(token.style.backgroundColor).toEqual('blue');
+ expect(token.style.backgroundColor).not.toEqual(originalBackgroundColor);
+ });
+
+ it('should not set backgroundColor when it is a linear-gradient', () => {
+ const token = subject.setTokenStyle(bugLabelToken, 'linear-gradient(135deg, red, blue)', 'white');
+ expect(token.style.backgroundColor).toEqual(bugLabelToken.style.backgroundColor);
+ });
+
+ it('should set textColor', () => {
+ const token = subject.setTokenStyle(bugLabelToken, 'white', 'black');
+ expect(token.style.color).toEqual('black');
+ expect(token.style.color).not.toEqual(originalTextColor);
+ });
+
+ it('should add inverted class when textColor is #FFFFFF', () => {
+ const token = subject.setTokenStyle(bugLabelToken, 'black', '#FFFFFF');
+ expect(token.style.color).toEqual('rgb(255, 255, 255)');
+ expect(token.style.color).not.toEqual(originalTextColor);
+ expect(token.querySelector('.remove-token').classList.contains('inverted')).toEqual(true);
+ });
+ });
+
+ describe('preprocessLabel', () => {
+ const endpoint = 'endpoint';
+
+ it('does not preprocess more than once', () => {
+ let labels = [];
+
+ spyOn(gl.DropdownUtils, 'duplicateLabelPreprocessing').and.callFake(() => []);
+
+ labels = gl.FilteredSearchVisualTokens.preprocessLabel(endpoint, labels);
+ gl.FilteredSearchVisualTokens.preprocessLabel(endpoint, labels);
+
+ expect(gl.DropdownUtils.duplicateLabelPreprocessing.calls.count()).toEqual(1);
+ });
+
+ describe('not preprocessed before', () => {
+ it('returns preprocessed labels', () => {
+ let labels = [];
+ expect(labels.preprocessed).not.toEqual(true);
+ labels = gl.FilteredSearchVisualTokens.preprocessLabel(endpoint, labels);
+ expect(labels.preprocessed).toEqual(true);
+ });
+
+ it('overrides AjaxCache with preprocessed results', () => {
+ spyOn(AjaxCache, 'override').and.callFake(() => {});
+ gl.FilteredSearchVisualTokens.preprocessLabel(endpoint, []);
+ expect(AjaxCache.override.calls.count()).toEqual(1);
+ });
+ });
+ });
+
describe('updateLabelTokenColor', () => {
const jsonFixtureName = 'labels/project_labels.json';
const dummyEndpoint = '/dummy/endpoint';
diff --git a/spec/javascripts/fixtures/abuse_reports.rb b/spec/javascripts/fixtures/abuse_reports.rb
index de673f94d72..387858cba77 100644
--- a/spec/javascripts/fixtures/abuse_reports.rb
+++ b/spec/javascripts/fixtures/abuse_reports.rb
@@ -14,7 +14,7 @@ describe Admin::AbuseReportsController, '(JavaScript fixtures)', type: :controll
clean_frontend_fixtures('abuse_reports/')
end
- before(:each) do
+ before do
sign_in(admin)
end
diff --git a/spec/javascripts/fixtures/balsamiq.rb b/spec/javascripts/fixtures/balsamiq.rb
index b5372821bf5..234e246119a 100644
--- a/spec/javascripts/fixtures/balsamiq.rb
+++ b/spec/javascripts/fixtures/balsamiq.rb
@@ -4,7 +4,7 @@ describe 'Balsamiq file', '(JavaScript fixtures)', type: :controller do
include JavaScriptFixturesHelpers
let(:namespace) { create(:namespace, name: 'frontend-fixtures' )}
- let(:project) { create(:project, namespace: namespace, path: 'balsamiq-project') }
+ let(:project) { create(:project, :repository, namespace: namespace, path: 'balsamiq-project') }
before(:all) do
clean_frontend_fixtures('blob/balsamiq/')
diff --git a/spec/javascripts/fixtures/blob.rb b/spec/javascripts/fixtures/blob.rb
index 16490ad5039..2dffc42b0ef 100644
--- a/spec/javascripts/fixtures/blob.rb
+++ b/spec/javascripts/fixtures/blob.rb
@@ -13,7 +13,7 @@ describe Projects::BlobController, '(JavaScript fixtures)', type: :controller do
clean_frontend_fixtures('blob/')
end
- before(:each) do
+ before do
sign_in(admin)
end
diff --git a/spec/javascripts/fixtures/boards.rb b/spec/javascripts/fixtures/boards.rb
index d7c3dc0a235..494c9cabdcc 100644
--- a/spec/javascripts/fixtures/boards.rb
+++ b/spec/javascripts/fixtures/boards.rb
@@ -13,7 +13,7 @@ describe Projects::BoardsController, '(JavaScript fixtures)', type: :controller
clean_frontend_fixtures('boards/')
end
- before(:each) do
+ before do
sign_in(admin)
end
diff --git a/spec/javascripts/fixtures/branches.rb b/spec/javascripts/fixtures/branches.rb
index a059818145b..bb3bdf7c215 100644
--- a/spec/javascripts/fixtures/branches.rb
+++ b/spec/javascripts/fixtures/branches.rb
@@ -13,7 +13,7 @@ describe Projects::BranchesController, '(JavaScript fixtures)', type: :controlle
clean_frontend_fixtures('branches/')
end
- before(:each) do
+ before do
sign_in(admin)
end
diff --git a/spec/javascripts/fixtures/dashboard.rb b/spec/javascripts/fixtures/dashboard.rb
index e83db8daaf2..793ffa7c220 100644
--- a/spec/javascripts/fixtures/dashboard.rb
+++ b/spec/javascripts/fixtures/dashboard.rb
@@ -13,7 +13,7 @@ describe Dashboard::ProjectsController, '(JavaScript fixtures)', type: :controll
clean_frontend_fixtures('dashboard/')
end
- before(:each) do
+ before do
sign_in(admin)
end
diff --git a/spec/javascripts/fixtures/deploy_keys.rb b/spec/javascripts/fixtures/deploy_keys.rb
index 16e598a4b29..bea161c514f 100644
--- a/spec/javascripts/fixtures/deploy_keys.rb
+++ b/spec/javascripts/fixtures/deploy_keys.rb
@@ -6,13 +6,13 @@ describe Projects::DeployKeysController, '(JavaScript fixtures)', type: :control
let(:admin) { create(:admin) }
let(:namespace) { create(:namespace, name: 'frontend-fixtures' )}
let(:project) { create(:project_empty_repo, namespace: namespace, path: 'todos-project') }
- let(:project2) { create(:empty_project, :internal)}
+ let(:project2) { create(:project, :internal)}
before(:all) do
clean_frontend_fixtures('deploy_keys/')
end
- before(:each) do
+ before do
sign_in(admin)
end
diff --git a/spec/javascripts/fixtures/environments.rb b/spec/javascripts/fixtures/environments.rb
index 3474f4696ef..d2457d75419 100644
--- a/spec/javascripts/fixtures/environments.rb
+++ b/spec/javascripts/fixtures/environments.rb
@@ -14,7 +14,7 @@ describe Projects::EnvironmentsController, '(JavaScript fixtures)', type: :contr
clean_frontend_fixtures('environments/metrics')
end
- before(:each) do
+ before do
sign_in(admin)
end
diff --git a/spec/javascripts/fixtures/issues.rb b/spec/javascripts/fixtures/issues.rb
index 1a30909977e..d3ad50af1b9 100644
--- a/spec/javascripts/fixtures/issues.rb
+++ b/spec/javascripts/fixtures/issues.rb
@@ -13,7 +13,7 @@ describe Projects::IssuesController, '(JavaScript fixtures)', type: :controller
clean_frontend_fixtures('issues/')
end
- before(:each) do
+ before do
sign_in(admin)
end
diff --git a/spec/javascripts/fixtures/jobs.rb b/spec/javascripts/fixtures/jobs.rb
index dc7dde1138c..83a96797506 100644
--- a/spec/javascripts/fixtures/jobs.rb
+++ b/spec/javascripts/fixtures/jobs.rb
@@ -17,7 +17,7 @@ describe Projects::JobsController, '(JavaScript fixtures)', type: :controller do
clean_frontend_fixtures('builds/')
end
- before(:each) do
+ before do
sign_in(admin)
end
diff --git a/spec/javascripts/fixtures/labels.rb b/spec/javascripts/fixtures/labels.rb
index 2e4811b64a4..814f065f3a4 100644
--- a/spec/javascripts/fixtures/labels.rb
+++ b/spec/javascripts/fixtures/labels.rb
@@ -22,7 +22,7 @@ describe 'Labels (JavaScript fixtures)' do
describe Groups::LabelsController, '(JavaScript fixtures)', type: :controller do
render_views
- before(:each) do
+ before do
sign_in(admin)
end
@@ -39,7 +39,7 @@ describe 'Labels (JavaScript fixtures)' do
describe Projects::LabelsController, '(JavaScript fixtures)', type: :controller do
render_views
- before(:each) do
+ before do
sign_in(admin)
end
diff --git a/spec/javascripts/fixtures/merge_requests.rb b/spec/javascripts/fixtures/merge_requests.rb
index 7e2f364ffa4..f97a5d2b5de 100644
--- a/spec/javascripts/fixtures/merge_requests.rb
+++ b/spec/javascripts/fixtures/merge_requests.rb
@@ -5,7 +5,7 @@ describe Projects::MergeRequestsController, '(JavaScript fixtures)', type: :cont
let(:admin) { create(:admin) }
let(:namespace) { create(:namespace, name: 'frontend-fixtures' )}
- let(:project) { create(:project, namespace: namespace, path: 'merge-requests-project') }
+ let(:project) { create(:project, :repository, namespace: namespace, path: 'merge-requests-project') }
let(:merge_request) { create(:merge_request, :with_diffs, source_project: project, target_project: project, description: '- [ ] Task List Item') }
let(:merged_merge_request) { create(:merge_request, :merged, source_project: project, target_project: project) }
let(:pipeline) do
@@ -33,7 +33,7 @@ describe Projects::MergeRequestsController, '(JavaScript fixtures)', type: :cont
clean_frontend_fixtures('merge_requests/')
end
- before(:each) do
+ before do
sign_in(admin)
end
diff --git a/spec/javascripts/fixtures/merge_requests_diffs.rb b/spec/javascripts/fixtures/merge_requests_diffs.rb
index ac5b06ace6d..6e0a97d2e3f 100644
--- a/spec/javascripts/fixtures/merge_requests_diffs.rb
+++ b/spec/javascripts/fixtures/merge_requests_diffs.rb
@@ -6,7 +6,7 @@ describe Projects::MergeRequests::DiffsController, '(JavaScript fixtures)', type
let(:admin) { create(:admin) }
let(:namespace) { create(:namespace, name: 'frontend-fixtures' )}
- let(:project) { create(:project, namespace: namespace, path: 'merge-requests-project') }
+ let(:project) { create(:project, :repository, namespace: namespace, path: 'merge-requests-project') }
let(:merge_request) { create(:merge_request, :with_diffs, source_project: project, target_project: project, description: '- [ ] Task List Item') }
let(:path) { "files/ruby/popen.rb" }
let(:position) do
@@ -25,7 +25,7 @@ describe Projects::MergeRequests::DiffsController, '(JavaScript fixtures)', type
clean_frontend_fixtures('merge_request_diffs/')
end
- before(:each) do
+ before do
sign_in(admin)
end
diff --git a/spec/javascripts/fixtures/pdf.rb b/spec/javascripts/fixtures/pdf.rb
index 6b2422a7986..ef9976b9fd3 100644
--- a/spec/javascripts/fixtures/pdf.rb
+++ b/spec/javascripts/fixtures/pdf.rb
@@ -4,7 +4,7 @@ describe 'PDF file', '(JavaScript fixtures)', type: :controller do
include JavaScriptFixturesHelpers
let(:namespace) { create(:namespace, name: 'frontend-fixtures' )}
- let(:project) { create(:project, namespace: namespace, path: 'pdf-project') }
+ let(:project) { create(:project, :repository, namespace: namespace, path: 'pdf-project') }
before(:all) do
clean_frontend_fixtures('blob/pdf/')
diff --git a/spec/javascripts/fixtures/pipelines.rb b/spec/javascripts/fixtures/pipelines.rb
index daafbac86db..bb85da50f0f 100644
--- a/spec/javascripts/fixtures/pipelines.rb
+++ b/spec/javascripts/fixtures/pipelines.rb
@@ -19,7 +19,7 @@ describe Projects::PipelinesController, '(JavaScript fixtures)', type: :controll
clean_frontend_fixtures('pipelines/')
end
- before(:each) do
+ before do
sign_in(admin)
end
diff --git a/spec/javascripts/fixtures/project_select_combo_button.html.haml b/spec/javascripts/fixtures/project_select_combo_button.html.haml
new file mode 100644
index 00000000000..54bc1a59279
--- /dev/null
+++ b/spec/javascripts/fixtures/project_select_combo_button.html.haml
@@ -0,0 +1,6 @@
+.project-item-select-holder
+ %input.project-item-select{ data: { group_id: '12345' , relative_path: 'issues/new' } }
+ %a.new-project-item-link{ data: { label: 'New issue' }, href: ''}
+ %i.fa.fa-spinner.spin
+ %a.new-project-item-select-button
+ %i.fa.fa-caret-down
diff --git a/spec/javascripts/fixtures/projects.rb b/spec/javascripts/fixtures/projects.rb
index 6c33b240e5c..f09d44a49d1 100644
--- a/spec/javascripts/fixtures/projects.rb
+++ b/spec/javascripts/fixtures/projects.rb
@@ -13,7 +13,7 @@ describe ProjectsController, '(JavaScript fixtures)', type: :controller do
clean_frontend_fixtures('projects/')
end
- before(:each) do
+ before do
sign_in(admin)
end
diff --git a/spec/javascripts/fixtures/prometheus_service.rb b/spec/javascripts/fixtures/prometheus_service.rb
index 3200577b326..7a46e47bb15 100644
--- a/spec/javascripts/fixtures/prometheus_service.rb
+++ b/spec/javascripts/fixtures/prometheus_service.rb
@@ -14,7 +14,7 @@ describe Projects::ServicesController, '(JavaScript fixtures)', type: :controlle
clean_frontend_fixtures('services/prometheus')
end
- before(:each) do
+ before do
sign_in(admin)
end
diff --git a/spec/javascripts/fixtures/raw.rb b/spec/javascripts/fixtures/raw.rb
index 17533443d76..25f5a3b0bb3 100644
--- a/spec/javascripts/fixtures/raw.rb
+++ b/spec/javascripts/fixtures/raw.rb
@@ -4,7 +4,7 @@ describe 'Raw files', '(JavaScript fixtures)', type: :controller do
include JavaScriptFixturesHelpers
let(:namespace) { create(:namespace, name: 'frontend-fixtures' )}
- let(:project) { create(:project, namespace: namespace, path: 'raw-project') }
+ let(:project) { create(:project, :repository, namespace: namespace, path: 'raw-project') }
before(:all) do
clean_frontend_fixtures('blob/notebook/')
diff --git a/spec/javascripts/fixtures/services.rb b/spec/javascripts/fixtures/services.rb
index 554451d1bbf..0a3c64d5d31 100644
--- a/spec/javascripts/fixtures/services.rb
+++ b/spec/javascripts/fixtures/services.rb
@@ -15,7 +15,7 @@ describe Projects::ServicesController, '(JavaScript fixtures)', type: :controlle
clean_frontend_fixtures('services/')
end
- before(:each) do
+ before do
sign_in(admin)
end
diff --git a/spec/javascripts/fixtures/snippet.rb b/spec/javascripts/fixtures/snippet.rb
new file mode 100644
index 00000000000..01bfb87b0c1
--- /dev/null
+++ b/spec/javascripts/fixtures/snippet.rb
@@ -0,0 +1,27 @@
+require 'spec_helper'
+
+describe SnippetsController, '(JavaScript fixtures)', type: :controller do
+ include JavaScriptFixturesHelpers
+
+ let(:admin) { create(:admin) }
+ let(:namespace) { create(:namespace, name: 'frontend-fixtures' )}
+ let(:project) { create(:project, :repository, namespace: namespace, path: 'branches-project') }
+ let(:snippet) { create(:personal_snippet, title: 'snippet.md', content: '# snippet', file_name: 'snippet.md', author: admin) }
+
+ render_views
+
+ before(:all) do
+ clean_frontend_fixtures('snippets/')
+ end
+
+ before do
+ sign_in(admin)
+ end
+
+ it 'snippets/show.html.raw' do |example|
+ get(:show, id: snippet.to_param)
+
+ expect(response).to be_success
+ store_frontend_fixture(response, example.description)
+ end
+end
diff --git a/spec/javascripts/fixtures/todos.rb b/spec/javascripts/fixtures/todos.rb
index a81ef8c5492..ba630365c18 100644
--- a/spec/javascripts/fixtures/todos.rb
+++ b/spec/javascripts/fixtures/todos.rb
@@ -18,7 +18,7 @@ describe 'Todos (JavaScript fixtures)' do
describe Dashboard::TodosController, '(JavaScript fixtures)', type: :controller do
render_views
- before(:each) do
+ before do
sign_in(admin)
end
@@ -33,7 +33,7 @@ describe 'Todos (JavaScript fixtures)' do
describe Projects::TodosController, '(JavaScript fixtures)', type: :controller do
render_views
- before(:each) do
+ before do
sign_in(admin)
end
diff --git a/spec/javascripts/fly_out_nav_spec.js b/spec/javascripts/fly_out_nav_spec.js
new file mode 100644
index 00000000000..65a7459c5ed
--- /dev/null
+++ b/spec/javascripts/fly_out_nav_spec.js
@@ -0,0 +1,329 @@
+import Cookies from 'js-cookie';
+import {
+ calculateTop,
+ showSubLevelItems,
+ canShowSubItems,
+ canShowActiveSubItems,
+ mouseEnterTopItems,
+ mouseLeaveTopItem,
+ setOpenMenu,
+ mousePos,
+ getHideSubItemsInterval,
+ documentMouseMove,
+} from '~/fly_out_nav';
+import bp from '~/breakpoints';
+
+describe('Fly out sidebar navigation', () => {
+ let el;
+ let breakpointSize = 'lg';
+
+ beforeEach(() => {
+ el = document.createElement('div');
+ el.style.position = 'relative';
+ document.body.appendChild(el);
+
+ spyOn(bp, 'getBreakpointSize').and.callFake(() => breakpointSize);
+
+ setOpenMenu(null);
+ });
+
+ afterEach(() => {
+ document.body.innerHTML = '';
+ breakpointSize = 'lg';
+ mousePos.length = 0;
+ });
+
+ describe('calculateTop', () => {
+ it('returns boundingRect top', () => {
+ const boundingRect = {
+ top: 100,
+ height: 100,
+ };
+
+ expect(
+ calculateTop(boundingRect, 100),
+ ).toBe(100);
+ });
+
+ it('returns boundingRect - bottomOverflow', () => {
+ const boundingRect = {
+ top: window.innerHeight - 50,
+ height: 100,
+ };
+
+ expect(
+ calculateTop(boundingRect, 100),
+ ).toBe(window.innerHeight - 50);
+ });
+ });
+
+ describe('getHideSubItemsInterval', () => {
+ beforeEach(() => {
+ el.innerHTML = '<div class="sidebar-sub-level-items" style="position: fixed; top: 0; left: 100px; height: 50px;"></div>';
+ });
+
+ it('returns 0 if currentOpenMenu is nil', () => {
+ expect(
+ getHideSubItemsInterval(),
+ ).toBe(0);
+ });
+
+ it('returns 0 when mouse above sub-items', () => {
+ showSubLevelItems(el);
+ documentMouseMove({
+ clientX: el.getBoundingClientRect().left,
+ clientY: el.getBoundingClientRect().top,
+ });
+ documentMouseMove({
+ clientX: el.getBoundingClientRect().left,
+ clientY: el.getBoundingClientRect().top - 50,
+ });
+
+ expect(
+ getHideSubItemsInterval(),
+ ).toBe(0);
+ });
+
+ it('returns 0 when mouse is below sub-items', () => {
+ const subItems = el.querySelector('.sidebar-sub-level-items');
+
+ showSubLevelItems(el);
+ documentMouseMove({
+ clientX: el.getBoundingClientRect().left,
+ clientY: el.getBoundingClientRect().top,
+ });
+ documentMouseMove({
+ clientX: el.getBoundingClientRect().left,
+ clientY: (el.getBoundingClientRect().top - subItems.getBoundingClientRect().height) + 50,
+ });
+
+ expect(
+ getHideSubItemsInterval(),
+ ).toBe(0);
+ });
+
+ it('returns 300 when mouse is moved towards sub-items', () => {
+ documentMouseMove({
+ clientX: el.getBoundingClientRect().left,
+ clientY: el.getBoundingClientRect().top,
+ });
+ showSubLevelItems(el);
+ documentMouseMove({
+ clientX: el.getBoundingClientRect().left + 20,
+ clientY: el.getBoundingClientRect().top + 10,
+ });
+
+ expect(
+ getHideSubItemsInterval(),
+ ).toBe(300);
+ });
+ });
+
+ describe('mouseLeaveTopItem', () => {
+ beforeEach(() => {
+ spyOn(el.classList, 'remove');
+ });
+
+ it('removes is-over class if currentOpenMenu is null', () => {
+ mouseLeaveTopItem(el);
+
+ expect(
+ el.classList.remove,
+ ).toHaveBeenCalledWith('is-over');
+ });
+
+ it('removes is-over class if currentOpenMenu is null & there are sub-items', () => {
+ el.innerHTML = '<div class="sidebar-sub-level-items" style="position: absolute;"></div>';
+
+ mouseLeaveTopItem(el);
+
+ expect(
+ el.classList.remove,
+ ).toHaveBeenCalledWith('is-over');
+ });
+
+ it('does not remove is-over class if currentOpenMenu is the passed in sub-items', () => {
+ el.innerHTML = '<div class="sidebar-sub-level-items" style="position: absolute;"></div>';
+
+ setOpenMenu(el.querySelector('.sidebar-sub-level-items'));
+ mouseLeaveTopItem(el);
+
+ expect(
+ el.classList.remove,
+ ).not.toHaveBeenCalled();
+ });
+ });
+
+ describe('mouseEnterTopItems', () => {
+ beforeEach(() => {
+ jasmine.clock().install();
+
+ el.innerHTML = '<div class="sidebar-sub-level-items" style="position: absolute; top: 0; left: 100px; height: 200px;"></div>';
+ });
+
+ afterEach(() => {
+ jasmine.clock().uninstall();
+ });
+
+ it('shows sub-items after 0ms if no menu is open', () => {
+ mouseEnterTopItems(el);
+
+ expect(
+ getHideSubItemsInterval(),
+ ).toBe(0);
+
+ jasmine.clock().tick(0);
+
+ expect(
+ el.querySelector('.sidebar-sub-level-items').style.display,
+ ).toBe('block');
+ });
+
+ it('shows sub-items after 300ms if a menu is currently open', () => {
+ documentMouseMove({
+ clientX: el.getBoundingClientRect().left,
+ clientY: el.getBoundingClientRect().top,
+ });
+
+ setOpenMenu(el.querySelector('.sidebar-sub-level-items'));
+
+ documentMouseMove({
+ clientX: el.getBoundingClientRect().left + 20,
+ clientY: el.getBoundingClientRect().top + 10,
+ });
+
+ mouseEnterTopItems(el);
+
+ expect(
+ getHideSubItemsInterval(),
+ ).toBe(300);
+
+ jasmine.clock().tick(300);
+
+ expect(
+ el.querySelector('.sidebar-sub-level-items').style.display,
+ ).toBe('block');
+ });
+ });
+
+ describe('showSubLevelItems', () => {
+ beforeEach(() => {
+ el.innerHTML = '<div class="sidebar-sub-level-items" style="position: absolute;"></div>';
+ });
+
+ it('adds is-over class to el', () => {
+ spyOn(el.classList, 'add');
+
+ showSubLevelItems(el);
+
+ expect(
+ el.classList.add,
+ ).toHaveBeenCalledWith('is-over');
+ });
+
+ it('does not show sub-items on mobile', () => {
+ breakpointSize = 'xs';
+
+ showSubLevelItems(el);
+
+ expect(
+ el.querySelector('.sidebar-sub-level-items').style.display,
+ ).not.toBe('block');
+ });
+
+ it('shows sub-items', () => {
+ showSubLevelItems(el);
+
+ expect(
+ el.querySelector('.sidebar-sub-level-items').style.display,
+ ).toBe('block');
+ });
+
+ it('sets transform of sub-items', () => {
+ const subItems = el.querySelector('.sidebar-sub-level-items');
+ showSubLevelItems(el);
+
+ expect(
+ subItems.style.transform,
+ ).toBe(`translate3d(0px, ${Math.floor(el.getBoundingClientRect().top)}px, 0px)`);
+ });
+
+ it('sets is-above when element is above', () => {
+ const subItems = el.querySelector('.sidebar-sub-level-items');
+ subItems.style.height = `${window.innerHeight + el.offsetHeight}px`;
+ el.style.top = `${window.innerHeight - el.offsetHeight}px`;
+
+ spyOn(subItems.classList, 'add');
+
+ showSubLevelItems(el);
+
+ expect(
+ subItems.classList.add,
+ ).toHaveBeenCalledWith('is-above');
+ });
+ });
+
+ describe('canShowSubItems', () => {
+ it('returns true if on desktop size', () => {
+ expect(
+ canShowSubItems(),
+ ).toBeTruthy();
+ });
+
+ it('returns false if on mobile size', () => {
+ breakpointSize = 'xs';
+
+ expect(
+ canShowSubItems(),
+ ).toBeFalsy();
+ });
+ });
+
+ describe('canShowActiveSubItems', () => {
+ afterEach(() => {
+ Cookies.remove('sidebar_collapsed');
+ });
+
+ it('returns true by default', () => {
+ expect(
+ canShowActiveSubItems(el),
+ ).toBeTruthy();
+ });
+
+ it('returns false when cookie is false & element is active', () => {
+ Cookies.set('sidebar_collapsed', 'false');
+ el.classList.add('active');
+
+ expect(
+ canShowActiveSubItems(el),
+ ).toBeFalsy();
+ });
+
+ it('returns true when cookie is false & element is active', () => {
+ Cookies.set('sidebar_collapsed', 'true');
+ el.classList.add('active');
+
+ expect(
+ canShowActiveSubItems(el),
+ ).toBeTruthy();
+ });
+
+ it('returns true when element is active & breakpoint is sm', () => {
+ breakpointSize = 'sm';
+ el.classList.add('active');
+
+ expect(
+ canShowActiveSubItems(el),
+ ).toBeTruthy();
+ });
+
+ it('returns true when element is active & breakpoint is md', () => {
+ breakpointSize = 'md';
+ el.classList.add('active');
+
+ expect(
+ canShowActiveSubItems(el),
+ ).toBeTruthy();
+ });
+ });
+});
diff --git a/spec/javascripts/gpg_badges_spec.js b/spec/javascripts/gpg_badges_spec.js
new file mode 100644
index 00000000000..7a826487bf9
--- /dev/null
+++ b/spec/javascripts/gpg_badges_spec.js
@@ -0,0 +1,48 @@
+import GpgBadges from '~/gpg_badges';
+
+describe('GpgBadges', () => {
+ const dummyCommitSha = 'n0m0rec0ffee';
+ const dummyBadgeHtml = 'dummy html';
+ const dummyResponse = {
+ signatures: [{
+ commit_sha: dummyCommitSha,
+ html: dummyBadgeHtml,
+ }],
+ };
+
+ beforeEach(() => {
+ setFixtures(`
+ <div class="parent-container">
+ <div class="js-loading-gpg-badge" data-commit-sha="${dummyCommitSha}"></div>
+ </div>
+ `);
+ });
+
+ it('displays a loading spinner', () => {
+ spyOn($, 'get').and.returnValue({
+ done() {
+ // intentionally left blank
+ },
+ });
+
+ GpgBadges.fetch();
+
+ expect(document.querySelector('.js-loading-gpg-badge:empty')).toBe(null);
+ const spinners = document.querySelectorAll('.js-loading-gpg-badge i.fa.fa-spinner.fa-spin');
+ expect(spinners.length).toBe(1);
+ });
+
+ it('replaces the loading spinner', () => {
+ spyOn($, 'get').and.returnValue({
+ done(callback) {
+ callback(dummyResponse);
+ },
+ });
+
+ GpgBadges.fetch();
+
+ expect(document.querySelector('.js-loading-gpg-badge')).toBe(null);
+ const parentContainer = document.querySelector('.parent-container');
+ expect(parentContainer.innerHTML.trim()).toEqual(dummyBadgeHtml);
+ });
+});
diff --git a/spec/javascripts/groups/group_identicon_spec.js b/spec/javascripts/groups/group_identicon_spec.js
new file mode 100644
index 00000000000..66772327503
--- /dev/null
+++ b/spec/javascripts/groups/group_identicon_spec.js
@@ -0,0 +1,60 @@
+import Vue from 'vue';
+import groupIdenticonComponent from '~/groups/components/group_identicon.vue';
+import GroupsStore from '~/groups/stores/groups_store';
+import { group1 } from './mock_data';
+
+const createComponent = () => {
+ const Component = Vue.extend(groupIdenticonComponent);
+ const store = new GroupsStore();
+ const group = store.decorateGroup(group1);
+
+ return new Component({
+ propsData: {
+ entityId: group.id,
+ entityName: group.name,
+ },
+ }).$mount();
+};
+
+describe('GroupIdenticonComponent', () => {
+ let vm;
+
+ beforeEach(() => {
+ vm = createComponent();
+ });
+
+ describe('computed', () => {
+ describe('identiconStyles', () => {
+ it('should return styles attribute value with `background-color` property', () => {
+ vm.entityId = 4;
+
+ expect(vm.identiconStyles).toBeDefined();
+ expect(vm.identiconStyles.indexOf('background-color: #E0F2F1;') > -1).toBeTruthy();
+ });
+
+ it('should return styles attribute value with `color` property', () => {
+ vm.entityId = 4;
+
+ expect(vm.identiconStyles).toBeDefined();
+ expect(vm.identiconStyles.indexOf('color: #555;') > -1).toBeTruthy();
+ });
+ });
+
+ describe('identiconTitle', () => {
+ it('should return first letter of entity title in uppercase', () => {
+ vm.entityName = 'dummy-group';
+
+ expect(vm.identiconTitle).toBeDefined();
+ expect(vm.identiconTitle).toBe('D');
+ });
+ });
+ });
+
+ describe('template', () => {
+ it('should render identicon', () => {
+ expect(vm.$el.nodeName).toBe('DIV');
+ expect(vm.$el.classList.contains('identicon')).toBeTruthy();
+ expect(vm.$el.getAttribute('style').indexOf('background-color') > -1).toBeTruthy();
+ });
+ });
+});
diff --git a/spec/javascripts/groups/groups_spec.js b/spec/javascripts/groups/groups_spec.js
index aaffb56fa94..b14153dbbfa 100644
--- a/spec/javascripts/groups/groups_spec.js
+++ b/spec/javascripts/groups/groups_spec.js
@@ -64,6 +64,19 @@ describe('Groups Component', () => {
expect(lists[2].querySelector('#group-1120').textContent).toContain(groups.id1119.subGroups.id1120.name);
});
+ it('should render group identicon when group avatar is not present', () => {
+ const avatar = component.$el.querySelector('#group-12 .avatar-container .avatar');
+ expect(avatar.nodeName).toBe('DIV');
+ expect(avatar.classList.contains('identicon')).toBeTruthy();
+ expect(avatar.getAttribute('style').indexOf('background-color') > -1).toBeTruthy();
+ });
+
+ it('should render group avatar when group avatar is present', () => {
+ const avatar = component.$el.querySelector('#group-1120 .avatar-container .avatar');
+ expect(avatar.nodeName).toBe('IMG');
+ expect(avatar.classList.contains('identicon')).toBeFalsy();
+ });
+
it('should remove prefix of parent group', () => {
expect(component.$el.querySelector('#group-12 #group-1128 .title').textContent).toContain('level2 / level3 / level4');
});
diff --git a/spec/javascripts/groups/mock_data.js b/spec/javascripts/groups/mock_data.js
index b3f5d791b89..5bb84b591f4 100644
--- a/spec/javascripts/groups/mock_data.js
+++ b/spec/javascripts/groups/mock_data.js
@@ -1,5 +1,5 @@
const group1 = {
- id: '12',
+ id: 12,
name: 'level1',
path: 'level1',
description: 'foo',
@@ -71,7 +71,7 @@ const group21 = {
path: 'chef',
description: 'foo',
visibility: 'public',
- avatar_url: null,
+ avatar_url: '/uploads/-/system/group/avatar/2/GitLab.png',
web_url: 'http://localhost:3000/groups/devops/chef',
group_path: '/devops/chef',
full_name: 'devops / chef',
diff --git a/spec/javascripts/labels_issue_sidebar_spec.js b/spec/javascripts/labels_issue_sidebar_spec.js
index c99f379b871..e47adc49224 100644
--- a/spec/javascripts/labels_issue_sidebar_spec.js
+++ b/spec/javascripts/labels_issue_sidebar_spec.js
@@ -4,7 +4,6 @@
import '~/gl_dropdown';
import 'select2';
-import 'vendor/jquery.nicescroll';
import '~/api';
import '~/create_label';
import '~/issuable_context';
diff --git a/spec/javascripts/lib/utils/ajax_cache_spec.js b/spec/javascripts/lib/utils/ajax_cache_spec.js
index 2c946802dcd..49971bd91e2 100644
--- a/spec/javascripts/lib/utils/ajax_cache_spec.js
+++ b/spec/javascripts/lib/utils/ajax_cache_spec.js
@@ -77,6 +77,15 @@ describe('AjaxCache', () => {
});
});
+ describe('override', () => {
+ it('overrides existing cache', () => {
+ AjaxCache.internalStorage.endpoint = 'existing-endpoint';
+ AjaxCache.override('endpoint', 'new-endpoint');
+
+ expect(AjaxCache.internalStorage.endpoint).toEqual('new-endpoint');
+ });
+ });
+
describe('retrieve', () => {
let ajaxSpy;
diff --git a/spec/javascripts/lib/utils/sticky_spec.js b/spec/javascripts/lib/utils/sticky_spec.js
new file mode 100644
index 00000000000..c3ee3ef9825
--- /dev/null
+++ b/spec/javascripts/lib/utils/sticky_spec.js
@@ -0,0 +1,52 @@
+import { isSticky } from '~/lib/utils/sticky';
+
+describe('sticky', () => {
+ const el = {
+ offsetTop: 0,
+ classList: {},
+ };
+
+ beforeEach(() => {
+ el.offsetTop = 0;
+ el.classList.add = jasmine.createSpy('spy');
+ el.classList.remove = jasmine.createSpy('spy');
+ });
+
+ describe('classList.remove', () => {
+ it('does not call classList.remove when stuck', () => {
+ isSticky(el, 0, 0);
+
+ expect(
+ el.classList.remove,
+ ).not.toHaveBeenCalled();
+ });
+
+ it('calls classList.remove when not stuck', () => {
+ el.offsetTop = 10;
+ isSticky(el, 0, 0);
+
+ expect(
+ el.classList.remove,
+ ).toHaveBeenCalledWith('is-stuck');
+ });
+ });
+
+ describe('classList.add', () => {
+ it('calls classList.add when stuck', () => {
+ isSticky(el, 0, 0);
+
+ expect(
+ el.classList.add,
+ ).toHaveBeenCalledWith('is-stuck');
+ });
+
+ it('does not call classList.add when not stuck', () => {
+ el.offsetTop = 10;
+ isSticky(el, 0, 0);
+
+ expect(
+ el.classList.add,
+ ).not.toHaveBeenCalled();
+ });
+ });
+});
diff --git a/spec/javascripts/pdf/index_spec.js b/spec/javascripts/pdf/index_spec.js
index f661fae5fe2..bebed432f91 100644
--- a/spec/javascripts/pdf/index_spec.js
+++ b/spec/javascripts/pdf/index_spec.js
@@ -1,8 +1,8 @@
/* eslint-disable import/no-unresolved */
import Vue from 'vue';
-import { PDFJS } from 'pdfjs-dist';
-import workerSrc from 'vendor/pdf.worker';
+import { PDFJS } from 'vendor/pdf';
+import workerSrc from 'vendor/pdf.worker.min';
import PDFLab from '~/pdf/index.vue';
import pdf from '../fixtures/blob/pdf/test.pdf';
diff --git a/spec/javascripts/pdf/page_spec.js b/spec/javascripts/pdf/page_spec.js
index ac76ebbfbe6..ac5b21e8f6c 100644
--- a/spec/javascripts/pdf/page_spec.js
+++ b/spec/javascripts/pdf/page_spec.js
@@ -1,8 +1,8 @@
/* eslint-disable import/no-unresolved */
import Vue from 'vue';
-import pdfjsLib from 'pdfjs-dist';
-import workerSrc from 'vendor/pdf.worker';
+import pdfjsLib from 'vendor/pdf';
+import workerSrc from 'vendor/pdf.worker.min';
import PageComponent from '~/pdf/page/index.vue';
import testPDF from '../fixtures/blob/pdf/test.pdf';
diff --git a/spec/javascripts/pipeline_schedules/pipeline_schedule_callout_spec.js b/spec/javascripts/pipeline_schedules/pipeline_schedule_callout_spec.js
index 6120d224ac0..ed481cb60a1 100644
--- a/spec/javascripts/pipeline_schedules/pipeline_schedule_callout_spec.js
+++ b/spec/javascripts/pipeline_schedules/pipeline_schedule_callout_spec.js
@@ -1,6 +1,6 @@
import Vue from 'vue';
import Cookies from 'js-cookie';
-import PipelineSchedulesCallout from '~/pipeline_schedules/components/pipeline_schedules_callout';
+import PipelineSchedulesCallout from '~/pipeline_schedules/components/pipeline_schedules_callout.vue';
const PipelineSchedulesCalloutComponent = Vue.extend(PipelineSchedulesCallout);
const cookieKey = 'pipeline_schedules_callout_dismissed';
diff --git a/spec/javascripts/project_select_combo_button_spec.js b/spec/javascripts/project_select_combo_button_spec.js
new file mode 100644
index 00000000000..e10a5a3bef6
--- /dev/null
+++ b/spec/javascripts/project_select_combo_button_spec.js
@@ -0,0 +1,105 @@
+import ProjectSelectComboButton from '~/project_select_combo_button';
+
+const fixturePath = 'static/project_select_combo_button.html.raw';
+
+describe('Project Select Combo Button', function () {
+ preloadFixtures(fixturePath);
+
+ beforeEach(function () {
+ this.defaults = {
+ label: 'Select project to create issue',
+ groupId: 12345,
+ projectMeta: {
+ name: 'My Cool Project',
+ url: 'http://mycoolproject.com',
+ },
+ newProjectMeta: {
+ name: 'My Other Cool Project',
+ url: 'http://myothercoolproject.com',
+ },
+ localStorageKey: 'group-12345-new-issue-recent-project',
+ relativePath: 'issues/new',
+ };
+
+ loadFixtures(fixturePath);
+
+ this.newItemBtn = document.querySelector('.new-project-item-link');
+ this.projectSelectInput = document.querySelector('.project-item-select');
+ });
+
+ describe('on page load when localStorage is empty', function () {
+ beforeEach(function () {
+ this.comboButton = new ProjectSelectComboButton(this.projectSelectInput);
+ });
+
+ it('newItemBtn is disabled', function () {
+ expect(this.newItemBtn.hasAttribute('disabled')).toBe(true);
+ expect(this.newItemBtn.classList.contains('disabled')).toBe(true);
+ });
+
+ it('newItemBtn href is null', function () {
+ expect(this.newItemBtn.getAttribute('href')).toBe('');
+ });
+
+ it('newItemBtn text is the plain default label', function () {
+ expect(this.newItemBtn.textContent).toBe(this.defaults.label);
+ });
+ });
+
+ describe('on page load when localStorage is filled', function () {
+ beforeEach(function () {
+ window.localStorage
+ .setItem(this.defaults.localStorageKey, JSON.stringify(this.defaults.projectMeta));
+ this.comboButton = new ProjectSelectComboButton(this.projectSelectInput);
+ });
+
+ it('newItemBtn is not disabled', function () {
+ expect(this.newItemBtn.hasAttribute('disabled')).toBe(false);
+ expect(this.newItemBtn.classList.contains('disabled')).toBe(false);
+ });
+
+ it('newItemBtn href is correctly set', function () {
+ expect(this.newItemBtn.getAttribute('href')).toBe(this.defaults.projectMeta.url);
+ });
+
+ it('newItemBtn text is the cached label', function () {
+ expect(this.newItemBtn.textContent)
+ .toBe(`New issue in ${this.defaults.projectMeta.name}`);
+ });
+
+ afterEach(function () {
+ window.localStorage.clear();
+ });
+ });
+
+ describe('after selecting a new project', function () {
+ beforeEach(function () {
+ this.comboButton = new ProjectSelectComboButton(this.projectSelectInput);
+
+ // mock the effect of selecting an item from the projects dropdown (select2)
+ $('.project-item-select')
+ .val(JSON.stringify(this.defaults.newProjectMeta))
+ .trigger('change');
+ });
+
+ it('newItemBtn is not disabled', function () {
+ expect(this.newItemBtn.hasAttribute('disabled')).toBe(false);
+ expect(this.newItemBtn.classList.contains('disabled')).toBe(false);
+ });
+
+ it('newItemBtn href is correctly set', function () {
+ expect(this.newItemBtn.getAttribute('href'))
+ .toBe('http://myothercoolproject.com/issues/new');
+ });
+
+ it('newItemBtn text is the selected project label', function () {
+ expect(this.newItemBtn.textContent)
+ .toBe(`New issue in ${this.defaults.newProjectMeta.name}`);
+ });
+
+ afterEach(function () {
+ window.localStorage.clear();
+ });
+ });
+});
+
diff --git a/spec/javascripts/projects/project_import_gitlab_project_spec.js b/spec/javascripts/projects/project_import_gitlab_project_spec.js
new file mode 100644
index 00000000000..2f1aae109e3
--- /dev/null
+++ b/spec/javascripts/projects/project_import_gitlab_project_spec.js
@@ -0,0 +1,25 @@
+import projectImportGitlab from '~/projects/project_import_gitlab_project';
+
+describe('Import Gitlab project', () => {
+ let projectName;
+ beforeEach(() => {
+ projectName = 'project';
+ window.history.pushState({}, null, `?path=${projectName}`);
+
+ setFixtures(`
+ <input class="js-path-name" />
+ `);
+
+ projectImportGitlab.bindEvents();
+ });
+
+ afterEach(() => {
+ window.history.pushState({}, null, '');
+ });
+
+ describe('path name', () => {
+ it('should fill in the project name derived from the previously filled project name', () => {
+ expect(document.querySelector('.js-path-name').value).toEqual(projectName);
+ });
+ });
+});
diff --git a/spec/javascripts/projects/project_new_spec.js b/spec/javascripts/projects/project_new_spec.js
new file mode 100644
index 00000000000..850768f0e4f
--- /dev/null
+++ b/spec/javascripts/projects/project_new_spec.js
@@ -0,0 +1,127 @@
+import projectNew from '~/projects/project_new';
+
+describe('New Project', () => {
+ let $projectImportUrl;
+ let $projectPath;
+
+ beforeEach(() => {
+ setFixtures(`
+ <input id="project_import_url" />
+ <input id="project_path" />
+ `);
+
+ $projectImportUrl = $('#project_import_url');
+ $projectPath = $('#project_path');
+ });
+
+ describe('deriveProjectPathFromUrl', () => {
+ const dummyImportUrl = `${gl.TEST_HOST}/dummy/import/url.git`;
+
+ beforeEach(() => {
+ projectNew.bindEvents();
+ $projectPath.val('').keyup().val(dummyImportUrl);
+ });
+
+ it('does not change project path for disabled $projectImportUrl', () => {
+ $projectImportUrl.attr('disabled', true);
+
+ projectNew.deriveProjectPathFromUrl($projectImportUrl, $projectPath);
+
+ expect($projectPath.val()).toEqual(dummyImportUrl);
+ });
+
+ describe('for enabled $projectImportUrl', () => {
+ beforeEach(() => {
+ $projectImportUrl.attr('disabled', false);
+ });
+
+ it('does not change project path if it is set by user', () => {
+ $projectPath.keyup();
+
+ projectNew.deriveProjectPathFromUrl($projectImportUrl, $projectPath);
+
+ expect($projectPath.val()).toEqual(dummyImportUrl);
+ });
+
+ it('does not change project path for empty $projectImportUrl', () => {
+ $projectImportUrl.val('');
+
+ projectNew.deriveProjectPathFromUrl($projectImportUrl, $projectPath);
+
+ expect($projectPath.val()).toEqual(dummyImportUrl);
+ });
+
+ it('does not change project path for whitespace $projectImportUrl', () => {
+ $projectImportUrl.val(' ');
+
+ projectNew.deriveProjectPathFromUrl($projectImportUrl, $projectPath);
+
+ expect($projectPath.val()).toEqual(dummyImportUrl);
+ });
+
+ it('does not change project path for $projectImportUrl without slashes', () => {
+ $projectImportUrl.val('has-no-slash');
+
+ projectNew.deriveProjectPathFromUrl($projectImportUrl, $projectPath);
+
+ expect($projectPath.val()).toEqual(dummyImportUrl);
+ });
+
+ it('changes project path to last $projectImportUrl component', () => {
+ $projectImportUrl.val('/this/is/last');
+
+ projectNew.deriveProjectPathFromUrl($projectImportUrl, $projectPath);
+
+ expect($projectPath.val()).toEqual('last');
+ });
+
+ it('ignores trailing slashes in $projectImportUrl', () => {
+ $projectImportUrl.val('/has/trailing/slash/');
+
+ projectNew.deriveProjectPathFromUrl($projectImportUrl, $projectPath);
+
+ expect($projectPath.val()).toEqual('slash');
+ });
+
+ it('ignores fragment identifier in $projectImportUrl', () => {
+ $projectImportUrl.val('/this/has/a#fragment-identifier/');
+
+ projectNew.deriveProjectPathFromUrl($projectImportUrl, $projectPath);
+
+ expect($projectPath.val()).toEqual('a');
+ });
+
+ it('ignores query string in $projectImportUrl', () => {
+ $projectImportUrl.val('/url/with?query=string');
+
+ projectNew.deriveProjectPathFromUrl($projectImportUrl, $projectPath);
+
+ expect($projectPath.val()).toEqual('with');
+ });
+
+ it('ignores trailing .git in $projectImportUrl', () => {
+ $projectImportUrl.val('/repository.git');
+
+ projectNew.deriveProjectPathFromUrl($projectImportUrl, $projectPath);
+
+ expect($projectPath.val()).toEqual('repository');
+ });
+
+ it('changes project path for HTTPS URL in $projectImportUrl', () => {
+ $projectImportUrl.val('https://username:password@gitlab.company.com/group/project.git');
+
+ projectNew.deriveProjectPathFromUrl($projectImportUrl, $projectPath);
+
+ expect($projectPath.val()).toEqual('project');
+ });
+
+ it('changes project path for SSH URL in $projectImportUrl', () => {
+ $projectImportUrl.val('git@gitlab.com:gitlab-org/gitlab-ce.git');
+
+ projectNew.deriveProjectPathFromUrl($projectImportUrl, $projectPath);
+
+ expect($projectPath.val()).toEqual('gitlab-ce');
+ });
+ });
+ });
+});
diff --git a/spec/javascripts/repo/components/repo_commit_section_spec.js b/spec/javascripts/repo/components/repo_commit_section_spec.js
new file mode 100644
index 00000000000..249a2f36fcd
--- /dev/null
+++ b/spec/javascripts/repo/components/repo_commit_section_spec.js
@@ -0,0 +1,160 @@
+import Vue from 'vue';
+import repoCommitSection from '~/repo/components/repo_commit_section.vue';
+import RepoStore from '~/repo/stores/repo_store';
+import Api from '~/api';
+
+describe('RepoCommitSection', () => {
+ const branch = 'master';
+ const projectUrl = 'projectUrl';
+ const changedFiles = [{
+ id: 0,
+ changed: true,
+ url: `/namespace/${projectUrl}/blob/${branch}/dir/file0.ext`,
+ path: 'dir/file0.ext',
+ newContent: 'a',
+ }, {
+ id: 1,
+ changed: true,
+ url: `/namespace/${projectUrl}/blob/${branch}/dir/file1.ext`,
+ path: 'dir/file1.ext',
+ newContent: 'b',
+ }];
+ const openedFiles = changedFiles.concat([{
+ id: 2,
+ url: `/namespace/${projectUrl}/blob/${branch}/dir/file2.ext`,
+ path: 'dir/file2.ext',
+ changed: false,
+ }]);
+
+ RepoStore.projectUrl = projectUrl;
+
+ function createComponent(el) {
+ const RepoCommitSection = Vue.extend(repoCommitSection);
+
+ return new RepoCommitSection().$mount(el);
+ }
+
+ it('renders a commit section', () => {
+ RepoStore.isCommitable = true;
+ RepoStore.currentBranch = branch;
+ RepoStore.targetBranch = branch;
+ RepoStore.openedFiles = openedFiles;
+
+ const vm = createComponent();
+ const changedFileElements = [...vm.$el.querySelectorAll('.changed-files > li')];
+ const commitMessage = vm.$el.querySelector('#commit-message');
+ const submitCommit = vm.$refs.submitCommit;
+ const targetBranch = vm.$el.querySelector('.target-branch');
+
+ expect(vm.$el.querySelector(':scope > form')).toBeTruthy();
+ expect(vm.$el.querySelector('.staged-files').textContent.trim()).toEqual('Staged files (2)');
+ expect(changedFileElements.length).toEqual(2);
+
+ changedFileElements.forEach((changedFile, i) => {
+ expect(changedFile.textContent.trim()).toEqual(changedFiles[i].path);
+ });
+
+ expect(commitMessage.tagName).toEqual('TEXTAREA');
+ expect(commitMessage.name).toEqual('commit-message');
+ expect(submitCommit.type).toEqual('submit');
+ expect(submitCommit.disabled).toBeTruthy();
+ expect(submitCommit.querySelector('.fa-spinner.fa-spin')).toBeFalsy();
+ expect(vm.$el.querySelector('.commit-summary').textContent.trim()).toEqual('Commit 2 files');
+ expect(targetBranch.querySelector(':scope > label').textContent.trim()).toEqual('Target branch');
+ expect(targetBranch.querySelector('.help-block').textContent.trim()).toEqual(branch);
+ });
+
+ it('does not render if not isCommitable', () => {
+ RepoStore.isCommitable = false;
+ RepoStore.openedFiles = [{
+ id: 0,
+ changed: true,
+ }];
+
+ const vm = createComponent();
+
+ expect(vm.$el.innerHTML).toBeFalsy();
+ });
+
+ it('does not render if no changedFiles', () => {
+ RepoStore.isCommitable = true;
+ RepoStore.openedFiles = [];
+
+ const vm = createComponent();
+
+ expect(vm.$el.innerHTML).toBeFalsy();
+ });
+
+ it('shows commit submit and summary if commitMessage and spinner if submitCommitsLoading', (done) => {
+ const projectId = 'projectId';
+ const commitMessage = 'commitMessage';
+ RepoStore.isCommitable = true;
+ RepoStore.currentBranch = branch;
+ RepoStore.targetBranch = branch;
+ RepoStore.openedFiles = openedFiles;
+ RepoStore.projectId = projectId;
+
+ // We need to append to body to get form `submit` events working
+ // Otherwise we run into, "Form submission canceled because the form is not connected"
+ // See https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#form-submission-algorithm
+ const el = document.createElement('div');
+ document.body.appendChild(el);
+
+ const vm = createComponent(el);
+ const commitMessageEl = vm.$el.querySelector('#commit-message');
+ const submitCommit = vm.$refs.submitCommit;
+
+ vm.commitMessage = commitMessage;
+
+ Vue.nextTick(() => {
+ expect(commitMessageEl.value).toBe(commitMessage);
+ expect(submitCommit.disabled).toBeFalsy();
+
+ spyOn(vm, 'makeCommit').and.callThrough();
+ spyOn(Api, 'commitMultiple');
+
+ submitCommit.click();
+
+ Vue.nextTick(() => {
+ expect(vm.makeCommit).toHaveBeenCalled();
+ expect(submitCommit.querySelector('.fa-spinner.fa-spin')).toBeTruthy();
+
+ const args = Api.commitMultiple.calls.allArgs()[0];
+ const { commit_message, actions, branch: payloadBranch } = args[1];
+
+ expect(args[0]).toBe(projectId);
+ expect(commit_message).toBe(commitMessage);
+ expect(actions.length).toEqual(2);
+ expect(payloadBranch).toEqual(branch);
+ expect(actions[0].action).toEqual('update');
+ expect(actions[1].action).toEqual('update');
+ expect(actions[0].content).toEqual(openedFiles[0].newContent);
+ expect(actions[1].content).toEqual(openedFiles[1].newContent);
+ expect(actions[0].file_path).toEqual(openedFiles[0].path);
+ expect(actions[1].file_path).toEqual(openedFiles[1].path);
+
+ done();
+ });
+ });
+ });
+
+ describe('methods', () => {
+ describe('resetCommitState', () => {
+ it('should reset store vars and scroll to top', () => {
+ const vm = {
+ submitCommitsLoading: true,
+ changedFiles: new Array(10),
+ commitMessage: 'commitMessage',
+ editMode: true,
+ };
+
+ repoCommitSection.methods.resetCommitState.call(vm);
+
+ expect(vm.submitCommitsLoading).toEqual(false);
+ expect(vm.changedFiles).toEqual([]);
+ expect(vm.commitMessage).toEqual('');
+ expect(vm.editMode).toEqual(false);
+ });
+ });
+ });
+});
diff --git a/spec/javascripts/repo/components/repo_edit_button_spec.js b/spec/javascripts/repo/components/repo_edit_button_spec.js
new file mode 100644
index 00000000000..29dc2d21e4b
--- /dev/null
+++ b/spec/javascripts/repo/components/repo_edit_button_spec.js
@@ -0,0 +1,51 @@
+import Vue from 'vue';
+import repoEditButton from '~/repo/components/repo_edit_button.vue';
+import RepoStore from '~/repo/stores/repo_store';
+
+describe('RepoEditButton', () => {
+ function createComponent() {
+ const RepoEditButton = Vue.extend(repoEditButton);
+
+ return new RepoEditButton().$mount();
+ }
+
+ it('renders an edit button that toggles the view state', (done) => {
+ RepoStore.isCommitable = true;
+ RepoStore.changedFiles = [];
+ RepoStore.binary = false;
+ RepoStore.openedFiles = [{}, {}];
+
+ const vm = createComponent();
+
+ expect(vm.$el.tagName).toEqual('BUTTON');
+ expect(vm.$el.textContent).toMatch('Edit');
+
+ spyOn(vm, 'editCancelClicked').and.callThrough();
+ spyOn(vm, 'toggleProjectRefsForm');
+
+ vm.$el.click();
+
+ Vue.nextTick(() => {
+ expect(vm.editCancelClicked).toHaveBeenCalled();
+ expect(vm.toggleProjectRefsForm).toHaveBeenCalled();
+ expect(vm.$el.textContent).toMatch('Cancel edit');
+ done();
+ });
+ });
+
+ it('does not render if not isCommitable', () => {
+ RepoStore.isCommitable = false;
+
+ const vm = createComponent();
+
+ expect(vm.$el.innerHTML).toBeUndefined();
+ });
+
+ describe('methods', () => {
+ describe('editCancelClicked', () => {
+ it('sets dialog to open when there are changedFiles');
+
+ it('toggles editMode and calls toggleBlobView');
+ });
+ });
+});
diff --git a/spec/javascripts/repo/components/repo_editor_spec.js b/spec/javascripts/repo/components/repo_editor_spec.js
new file mode 100644
index 00000000000..85d55d171f9
--- /dev/null
+++ b/spec/javascripts/repo/components/repo_editor_spec.js
@@ -0,0 +1,49 @@
+import Vue from 'vue';
+import repoEditor from '~/repo/components/repo_editor.vue';
+
+describe('RepoEditor', () => {
+ beforeEach(() => {
+ const RepoEditor = Vue.extend(repoEditor);
+
+ this.vm = new RepoEditor().$mount();
+ });
+
+ it('renders an ide container', (done) => {
+ this.vm.openedFiles = ['idiidid'];
+ this.vm.binary = false;
+
+ Vue.nextTick(() => {
+ expect(this.vm.shouldHideEditor).toBe(false);
+ expect(this.vm.$el.id).toEqual('ide');
+ expect(this.vm.$el.tagName).toBe('DIV');
+ done();
+ });
+ });
+
+ describe('when there are no open files', () => {
+ it('does not render the ide', (done) => {
+ this.vm.openedFiles = [];
+
+ Vue.nextTick(() => {
+ expect(this.vm.shouldHideEditor).toBe(true);
+ expect(this.vm.$el.tagName).not.toBeDefined();
+ done();
+ });
+ });
+ });
+
+ describe('when open file is binary and not raw', () => {
+ it('does not render the IDE', (done) => {
+ this.vm.binary = true;
+ this.vm.activeFile = {
+ raw: false,
+ };
+
+ Vue.nextTick(() => {
+ expect(this.vm.shouldHideEditor).toBe(true);
+ expect(this.vm.$el.tagName).not.toBeDefined();
+ done();
+ });
+ });
+ });
+});
diff --git a/spec/javascripts/repo/components/repo_file_buttons_spec.js b/spec/javascripts/repo/components/repo_file_buttons_spec.js
new file mode 100644
index 00000000000..dfab51710c3
--- /dev/null
+++ b/spec/javascripts/repo/components/repo_file_buttons_spec.js
@@ -0,0 +1,75 @@
+import Vue from 'vue';
+import repoFileButtons from '~/repo/components/repo_file_buttons.vue';
+import RepoStore from '~/repo/stores/repo_store';
+
+describe('RepoFileButtons', () => {
+ function createComponent() {
+ const RepoFileButtons = Vue.extend(repoFileButtons);
+
+ return new RepoFileButtons().$mount();
+ }
+
+ it('renders Raw, Blame, History, Permalink and Preview toggle', () => {
+ const activeFile = {
+ extension: 'md',
+ url: 'url',
+ raw_path: 'raw_path',
+ blame_path: 'blame_path',
+ commits_path: 'commits_path',
+ permalink: 'permalink',
+ };
+ const activeFileLabel = 'activeFileLabel';
+ RepoStore.openedFiles = new Array(1);
+ RepoStore.activeFile = activeFile;
+ RepoStore.activeFileLabel = activeFileLabel;
+ RepoStore.editMode = true;
+ RepoStore.binary = false;
+
+ const vm = createComponent();
+ const raw = vm.$el.querySelector('.raw');
+ const blame = vm.$el.querySelector('.blame');
+ const history = vm.$el.querySelector('.history');
+
+ expect(vm.$el.id).toEqual('repo-file-buttons');
+ expect(raw.href).toMatch(`/${activeFile.raw_path}`);
+ expect(raw.textContent.trim()).toEqual('Raw');
+ expect(blame.href).toMatch(`/${activeFile.blame_path}`);
+ expect(blame.textContent.trim()).toEqual('Blame');
+ expect(history.href).toMatch(`/${activeFile.commits_path}`);
+ expect(history.textContent.trim()).toEqual('History');
+ expect(vm.$el.querySelector('.permalink').textContent.trim()).toEqual('Permalink');
+ expect(vm.$el.querySelector('.preview').textContent.trim()).toEqual(activeFileLabel);
+ });
+
+ it('triggers rawPreviewToggle on preview click', () => {
+ const activeFile = {
+ extension: 'md',
+ url: 'url',
+ };
+ RepoStore.openedFiles = new Array(1);
+ RepoStore.activeFile = activeFile;
+ RepoStore.editMode = true;
+
+ const vm = createComponent();
+ const preview = vm.$el.querySelector('.preview');
+
+ spyOn(vm, 'rawPreviewToggle');
+
+ preview.click();
+
+ expect(vm.rawPreviewToggle).toHaveBeenCalled();
+ });
+
+ it('does not render preview toggle if not canPreview', () => {
+ const activeFile = {
+ extension: 'abcd',
+ url: 'url',
+ };
+ RepoStore.openedFiles = new Array(1);
+ RepoStore.activeFile = activeFile;
+
+ const vm = createComponent();
+
+ expect(vm.$el.querySelector('.preview')).toBeFalsy();
+ });
+});
diff --git a/spec/javascripts/repo/components/repo_file_options_spec.js b/spec/javascripts/repo/components/repo_file_options_spec.js
new file mode 100644
index 00000000000..9759b4bf12d
--- /dev/null
+++ b/spec/javascripts/repo/components/repo_file_options_spec.js
@@ -0,0 +1,33 @@
+import Vue from 'vue';
+import repoFileOptions from '~/repo/components/repo_file_options.vue';
+
+describe('RepoFileOptions', () => {
+ const projectName = 'projectName';
+
+ function createComponent(propsData) {
+ const RepoFileOptions = Vue.extend(repoFileOptions);
+
+ return new RepoFileOptions({
+ propsData,
+ }).$mount();
+ }
+
+ it('renders the title and new file/folder buttons if isMini is true', () => {
+ const vm = createComponent({
+ isMini: true,
+ projectName,
+ });
+
+ expect(vm.$el.classList.contains('repo-file-options')).toBeTruthy();
+ expect(vm.$el.querySelector('.title').textContent).toEqual(projectName);
+ });
+
+ it('does not render if isMini is false', () => {
+ const vm = createComponent({
+ isMini: false,
+ projectName,
+ });
+
+ expect(vm.$el.innerHTML).toBeFalsy();
+ });
+});
diff --git a/spec/javascripts/repo/components/repo_file_spec.js b/spec/javascripts/repo/components/repo_file_spec.js
new file mode 100644
index 00000000000..518a2d25ecf
--- /dev/null
+++ b/spec/javascripts/repo/components/repo_file_spec.js
@@ -0,0 +1,136 @@
+import Vue from 'vue';
+import repoFile from '~/repo/components/repo_file.vue';
+
+describe('RepoFile', () => {
+ const updated = 'updated';
+ const file = {
+ icon: 'icon',
+ url: 'url',
+ name: 'name',
+ lastCommitMessage: 'message',
+ lastCommitUpdate: Date.now(),
+ level: 10,
+ };
+ const activeFile = {
+ url: 'url',
+ };
+
+ function createComponent(propsData) {
+ const RepoFile = Vue.extend(repoFile);
+
+ return new RepoFile({
+ propsData,
+ }).$mount();
+ }
+
+ beforeEach(() => {
+ spyOn(repoFile.mixins[0].methods, 'timeFormated').and.returnValue(updated);
+ });
+
+ it('renders link, icon, name and last commit details', () => {
+ const vm = createComponent({
+ file,
+ activeFile,
+ });
+ const name = vm.$el.querySelector('.repo-file-name');
+ const fileIcon = vm.$el.querySelector('.file-icon');
+
+ expect(vm.$el.classList.contains('active')).toBeTruthy();
+ expect(vm.$el.querySelector(`.${file.icon}`).style.marginLeft).toEqual('100px');
+ expect(name.title).toEqual(file.url);
+ expect(name.href).toMatch(`/${file.url}`);
+ expect(name.textContent.trim()).toEqual(file.name);
+ expect(vm.$el.querySelector('.commit-message').textContent.trim()).toBe(file.lastCommitMessage);
+ expect(vm.$el.querySelector('.commit-update').textContent.trim()).toBe(updated);
+ expect(fileIcon.classList.contains(file.icon)).toBeTruthy();
+ expect(fileIcon.style.marginLeft).toEqual(`${file.level * 10}px`);
+ });
+
+ it('does render if hasFiles is true and is loading tree', () => {
+ const vm = createComponent({
+ file,
+ activeFile,
+ loading: {
+ tree: true,
+ },
+ hasFiles: true,
+ });
+
+ expect(vm.$el.innerHTML).toBeTruthy();
+ expect(vm.$el.querySelector('.fa-spin.fa-spinner')).toBeFalsy();
+ });
+
+ it('renders a spinner if the file is loading', () => {
+ file.loading = true;
+ const vm = createComponent({
+ file,
+ activeFile,
+ loading: {
+ tree: true,
+ },
+ hasFiles: true,
+ });
+
+ expect(vm.$el.innerHTML).toBeTruthy();
+ expect(vm.$el.querySelector('.fa-spin.fa-spinner').style.marginLeft).toEqual(`${file.level * 10}px`);
+ });
+
+ it('does not render if loading tree', () => {
+ const vm = createComponent({
+ file,
+ activeFile,
+ loading: {
+ tree: true,
+ },
+ });
+
+ expect(vm.$el.innerHTML).toBeFalsy();
+ });
+
+ it('does not render commit message and datetime if mini', () => {
+ const vm = createComponent({
+ file,
+ activeFile,
+ isMini: true,
+ });
+
+ expect(vm.$el.querySelector('.commit-message')).toBeFalsy();
+ expect(vm.$el.querySelector('.commit-update')).toBeFalsy();
+ });
+
+ it('does not set active class if file is active file', () => {
+ const vm = createComponent({
+ file,
+ activeFile: {},
+ });
+
+ expect(vm.$el.classList.contains('active')).toBeFalsy();
+ });
+
+ it('fires linkClicked when the link is clicked', () => {
+ const vm = createComponent({
+ file,
+ activeFile,
+ });
+
+ spyOn(vm, 'linkClicked');
+
+ vm.$el.querySelector('.repo-file-name').click();
+
+ expect(vm.linkClicked).toHaveBeenCalledWith(file);
+ });
+
+ describe('methods', () => {
+ describe('linkClicked', () => {
+ const vm = jasmine.createSpyObj('vm', ['$emit']);
+
+ it('$emits linkclicked with file obj', () => {
+ const theFile = {};
+
+ repoFile.methods.linkClicked.call(vm, theFile);
+
+ expect(vm.$emit).toHaveBeenCalledWith('linkclicked', theFile);
+ });
+ });
+ });
+});
diff --git a/spec/javascripts/repo/components/repo_loading_file_spec.js b/spec/javascripts/repo/components/repo_loading_file_spec.js
new file mode 100644
index 00000000000..a030314d749
--- /dev/null
+++ b/spec/javascripts/repo/components/repo_loading_file_spec.js
@@ -0,0 +1,79 @@
+import Vue from 'vue';
+import repoLoadingFile from '~/repo/components/repo_loading_file.vue';
+
+describe('RepoLoadingFile', () => {
+ function createComponent(propsData) {
+ const RepoLoadingFile = Vue.extend(repoLoadingFile);
+
+ return new RepoLoadingFile({
+ propsData,
+ }).$mount();
+ }
+
+ function assertLines(lines) {
+ lines.forEach((line, n) => {
+ const index = n + 1;
+ expect(line.classList.contains(`skeleton-line-${index}`)).toBeTruthy();
+ });
+ }
+
+ function assertColumns(columns) {
+ columns.forEach((column) => {
+ const container = column.querySelector('.animation-container');
+ const lines = [...container.querySelectorAll(':scope > div')];
+
+ expect(container).toBeTruthy();
+ expect(lines.length).toEqual(6);
+ assertLines(lines);
+ });
+ }
+
+ it('renders 3 columns of animated LoC', () => {
+ const vm = createComponent({
+ loading: {
+ tree: true,
+ },
+ hasFiles: false,
+ });
+ const columns = [...vm.$el.querySelectorAll('td')];
+
+ expect(columns.length).toEqual(3);
+ assertColumns(columns);
+ });
+
+ it('renders 1 column of animated LoC if isMini', () => {
+ const vm = createComponent({
+ loading: {
+ tree: true,
+ },
+ hasFiles: false,
+ isMini: true,
+ });
+ const columns = [...vm.$el.querySelectorAll('td')];
+
+ expect(columns.length).toEqual(1);
+ assertColumns(columns);
+ });
+
+ it('does not render if tree is not loading', () => {
+ const vm = createComponent({
+ loading: {
+ tree: false,
+ },
+ hasFiles: false,
+ });
+
+ expect(vm.$el.innerHTML).toBeFalsy();
+ });
+
+ it('does not render if hasFiles is true', () => {
+ const vm = createComponent({
+ loading: {
+ tree: true,
+ },
+ hasFiles: true,
+ });
+
+ expect(vm.$el.innerHTML).toBeFalsy();
+ });
+});
diff --git a/spec/javascripts/repo/components/repo_prev_directory_spec.js b/spec/javascripts/repo/components/repo_prev_directory_spec.js
new file mode 100644
index 00000000000..34dde545e6a
--- /dev/null
+++ b/spec/javascripts/repo/components/repo_prev_directory_spec.js
@@ -0,0 +1,43 @@
+import Vue from 'vue';
+import repoPrevDirectory from '~/repo/components/repo_prev_directory.vue';
+
+describe('RepoPrevDirectory', () => {
+ function createComponent(propsData) {
+ const RepoPrevDirectory = Vue.extend(repoPrevDirectory);
+
+ return new RepoPrevDirectory({
+ propsData,
+ }).$mount();
+ }
+
+ it('renders a prev dir link', () => {
+ const prevUrl = 'prevUrl';
+ const vm = createComponent({
+ prevUrl,
+ });
+ const link = vm.$el.querySelector('a');
+
+ spyOn(vm, 'linkClicked');
+
+ expect(link.href).toMatch(`/${prevUrl}`);
+ expect(link.textContent).toEqual('..');
+
+ link.click();
+
+ expect(vm.linkClicked).toHaveBeenCalledWith(prevUrl);
+ });
+
+ describe('methods', () => {
+ describe('linkClicked', () => {
+ const vm = jasmine.createSpyObj('vm', ['$emit']);
+
+ it('$emits linkclicked with file obj', () => {
+ const file = {};
+
+ repoPrevDirectory.methods.linkClicked.call(vm, file);
+
+ expect(vm.$emit).toHaveBeenCalledWith('linkclicked', file);
+ });
+ });
+ });
+});
diff --git a/spec/javascripts/repo/components/repo_preview_spec.js b/spec/javascripts/repo/components/repo_preview_spec.js
new file mode 100644
index 00000000000..4920cf02083
--- /dev/null
+++ b/spec/javascripts/repo/components/repo_preview_spec.js
@@ -0,0 +1,23 @@
+import Vue from 'vue';
+import repoPreview from '~/repo/components/repo_preview.vue';
+import RepoStore from '~/repo/stores/repo_store';
+
+describe('RepoPreview', () => {
+ function createComponent() {
+ const RepoPreview = Vue.extend(repoPreview);
+
+ return new RepoPreview().$mount();
+ }
+
+ it('renders a div with the activeFile html', () => {
+ const activeFile = {
+ html: '<p class="file-content">html</p>',
+ };
+ RepoStore.activeFile = activeFile;
+
+ const vm = createComponent();
+
+ expect(vm.$el.tagName).toEqual('DIV');
+ expect(vm.$el.innerHTML).toContain(activeFile.html);
+ });
+});
diff --git a/spec/javascripts/repo/components/repo_sidebar_spec.js b/spec/javascripts/repo/components/repo_sidebar_spec.js
new file mode 100644
index 00000000000..abcff8e537e
--- /dev/null
+++ b/spec/javascripts/repo/components/repo_sidebar_spec.js
@@ -0,0 +1,111 @@
+import Vue from 'vue';
+import Helper from '~/repo/helpers/repo_helper';
+import RepoService from '~/repo/services/repo_service';
+import RepoStore from '~/repo/stores/repo_store';
+import repoSidebar from '~/repo/components/repo_sidebar.vue';
+
+describe('RepoSidebar', () => {
+ function createComponent() {
+ const RepoSidebar = Vue.extend(repoSidebar);
+
+ return new RepoSidebar().$mount();
+ }
+
+ it('renders a sidebar', () => {
+ RepoStore.files = [{
+ id: 0,
+ }];
+ RepoStore.openedFiles = [];
+ const vm = createComponent();
+ const thead = vm.$el.querySelector('thead');
+ const tbody = vm.$el.querySelector('tbody');
+
+ expect(vm.$el.id).toEqual('sidebar');
+ expect(vm.$el.classList.contains('sidebar-mini')).toBeFalsy();
+ expect(thead.querySelector('.name').textContent).toEqual('Name');
+ expect(thead.querySelector('.last-commit').textContent).toEqual('Last Commit');
+ expect(thead.querySelector('.last-update').textContent).toEqual('Last Update');
+ expect(tbody.querySelector('.repo-file-options')).toBeFalsy();
+ expect(tbody.querySelector('.prev-directory')).toBeFalsy();
+ expect(tbody.querySelector('.loading-file')).toBeFalsy();
+ expect(tbody.querySelector('.file')).toBeTruthy();
+ });
+
+ it('does not render a thead, renders repo-file-options and sets sidebar-mini class if isMini', () => {
+ RepoStore.openedFiles = [{
+ id: 0,
+ }];
+ const vm = createComponent();
+
+ expect(vm.$el.classList.contains('sidebar-mini')).toBeTruthy();
+ expect(vm.$el.querySelector('thead')).toBeFalsy();
+ expect(vm.$el.querySelector('tbody .repo-file-options')).toBeTruthy();
+ });
+
+ it('renders 5 loading files if tree is loading and not hasFiles', () => {
+ RepoStore.loading = {
+ tree: true,
+ };
+ RepoStore.files = [];
+ const vm = createComponent();
+
+ expect(vm.$el.querySelectorAll('tbody .loading-file').length).toEqual(5);
+ });
+
+ it('renders a prev directory if isRoot', () => {
+ RepoStore.files = [{
+ id: 0,
+ }];
+ RepoStore.isRoot = true;
+ const vm = createComponent();
+
+ expect(vm.$el.querySelector('tbody .prev-directory')).toBeTruthy();
+ });
+
+ describe('methods', () => {
+ describe('fileClicked', () => {
+ it('should fetch data for new file', () => {
+ spyOn(Helper, 'getContent').and.callThrough();
+ const file1 = {
+ id: 0,
+ url: '',
+ };
+ RepoStore.files = [file1];
+ RepoStore.isRoot = true;
+ const vm = createComponent();
+
+ vm.fileClicked(file1);
+
+ expect(Helper.getContent).toHaveBeenCalledWith(file1);
+ });
+
+ it('should hide files in directory if already open', () => {
+ spyOn(RepoStore, 'removeChildFilesOfTree').and.callThrough();
+ const file1 = {
+ id: 0,
+ type: 'tree',
+ url: '',
+ opened: true,
+ };
+ RepoStore.files = [file1];
+ RepoStore.isRoot = true;
+ const vm = createComponent();
+
+ vm.fileClicked(file1);
+
+ expect(RepoStore.removeChildFilesOfTree).toHaveBeenCalledWith(file1);
+ });
+ });
+
+ describe('goToPreviousDirectoryClicked', () => {
+ it('should hide files in directory if already open', () => {
+ const prevUrl = 'foo/bar';
+ const vm = createComponent();
+
+ vm.goToPreviousDirectoryClicked(prevUrl);
+
+ expect(RepoService.url).toEqual(prevUrl);
+ });
+ });
+ });
+});
diff --git a/spec/javascripts/repo/components/repo_tab_spec.js b/spec/javascripts/repo/components/repo_tab_spec.js
new file mode 100644
index 00000000000..d2a790ad73a
--- /dev/null
+++ b/spec/javascripts/repo/components/repo_tab_spec.js
@@ -0,0 +1,70 @@
+import Vue from 'vue';
+import repoTab from '~/repo/components/repo_tab.vue';
+
+describe('RepoTab', () => {
+ function createComponent(propsData) {
+ const RepoTab = Vue.extend(repoTab);
+
+ return new RepoTab({
+ propsData,
+ }).$mount();
+ }
+
+ it('renders a close link and a name link', () => {
+ const tab = {
+ url: 'url',
+ name: 'name',
+ };
+ const vm = createComponent({
+ tab,
+ });
+ const close = vm.$el.querySelector('.close');
+ const name = vm.$el.querySelector(`a[title="${tab.url}"]`);
+
+ spyOn(vm, 'closeTab');
+ spyOn(vm, 'tabClicked');
+
+ expect(close.querySelector('.fa-times')).toBeTruthy();
+ expect(name.textContent.trim()).toEqual(tab.name);
+
+ close.click();
+ name.click();
+
+ expect(vm.closeTab).toHaveBeenCalledWith(tab);
+ expect(vm.tabClicked).toHaveBeenCalledWith(tab);
+ });
+
+ it('renders an fa-circle icon if tab is changed', () => {
+ const tab = {
+ url: 'url',
+ name: 'name',
+ changed: true,
+ };
+ const vm = createComponent({
+ tab,
+ });
+
+ expect(vm.$el.querySelector('.close .fa-circle')).toBeTruthy();
+ });
+
+ describe('methods', () => {
+ describe('closeTab', () => {
+ const vm = jasmine.createSpyObj('vm', ['$emit']);
+
+ it('returns undefined and does not $emit if file is changed', () => {
+ const file = { changed: true };
+ const returnVal = repoTab.methods.closeTab.call(vm, file);
+
+ expect(returnVal).toBeUndefined();
+ expect(vm.$emit).not.toHaveBeenCalled();
+ });
+
+ it('$emits tabclosed event with file obj', () => {
+ const file = { changed: false };
+ repoTab.methods.closeTab.call(vm, file);
+
+ expect(vm.$emit).toHaveBeenCalledWith('tabclosed', file);
+ });
+ });
+ });
+});
diff --git a/spec/javascripts/repo/components/repo_tabs_spec.js b/spec/javascripts/repo/components/repo_tabs_spec.js
new file mode 100644
index 00000000000..a02b54efafc
--- /dev/null
+++ b/spec/javascripts/repo/components/repo_tabs_spec.js
@@ -0,0 +1,45 @@
+import Vue from 'vue';
+import RepoStore from '~/repo/stores/repo_store';
+import repoTabs from '~/repo/components/repo_tabs.vue';
+
+describe('RepoTabs', () => {
+ const openedFiles = [{
+ id: 0,
+ active: true,
+ }, {
+ id: 1,
+ }];
+
+ function createComponent() {
+ const RepoTabs = Vue.extend(repoTabs);
+
+ return new RepoTabs().$mount();
+ }
+
+ it('renders a list of tabs', () => {
+ RepoStore.openedFiles = openedFiles;
+
+ const vm = createComponent();
+ const tabs = [...vm.$el.querySelectorAll(':scope > li')];
+
+ expect(vm.$el.id).toEqual('tabs');
+ expect(tabs.length).toEqual(3);
+ expect(tabs[0].classList.contains('active')).toBeTruthy();
+ expect(tabs[1].classList.contains('active')).toBeFalsy();
+ expect(tabs[2].classList.contains('tabs-divider')).toBeTruthy();
+ });
+
+ describe('methods', () => {
+ describe('tabClosed', () => {
+ it('calls removeFromOpenedFiles with file obj', () => {
+ const file = {};
+
+ spyOn(RepoStore, 'removeFromOpenedFiles');
+
+ repoTabs.methods.tabClosed(file);
+
+ expect(RepoStore.removeFromOpenedFiles).toHaveBeenCalledWith(file);
+ });
+ });
+ });
+});
diff --git a/spec/javascripts/repo/monaco_loader_spec.js b/spec/javascripts/repo/monaco_loader_spec.js
new file mode 100644
index 00000000000..be6e779c50f
--- /dev/null
+++ b/spec/javascripts/repo/monaco_loader_spec.js
@@ -0,0 +1,17 @@
+/* global __webpack_public_path__ */
+import monacoContext from 'monaco-editor/dev/vs/loader';
+
+describe('MonacoLoader', () => {
+ it('calls require.config and exports require', () => {
+ spyOn(monacoContext.require, 'config');
+
+ const monacoLoader = require('~/repo/monaco_loader'); // eslint-disable-line global-require
+
+ expect(monacoContext.require.config).toHaveBeenCalledWith({
+ paths: {
+ vs: `${__webpack_public_path__}monaco-editor/vs`, // eslint-disable-line camelcase
+ },
+ });
+ expect(monacoLoader.default).toBe(monacoContext.require);
+ });
+});
diff --git a/spec/javascripts/repo/services/repo_service_spec.js b/spec/javascripts/repo/services/repo_service_spec.js
new file mode 100644
index 00000000000..d74e6a67b1e
--- /dev/null
+++ b/spec/javascripts/repo/services/repo_service_spec.js
@@ -0,0 +1,121 @@
+import axios from 'axios';
+import RepoService from '~/repo/services/repo_service';
+
+describe('RepoService', () => {
+ it('has default json format param', () => {
+ expect(RepoService.options.params.format).toBe('json');
+ });
+
+ describe('buildParams', () => {
+ let newParams;
+ const url = 'url';
+
+ beforeEach(() => {
+ newParams = {};
+
+ spyOn(Object, 'assign').and.returnValue(newParams);
+ });
+
+ it('clones params', () => {
+ const params = RepoService.buildParams(url);
+
+ expect(Object.assign).toHaveBeenCalledWith({}, RepoService.options.params);
+
+ expect(params).toBe(newParams);
+ });
+
+ it('sets and returns viewer params to richif urlIsRichBlob is true', () => {
+ spyOn(RepoService, 'urlIsRichBlob').and.returnValue(true);
+
+ const params = RepoService.buildParams(url);
+
+ expect(params.viewer).toEqual('rich');
+ });
+
+ it('returns params urlIsRichBlob is false', () => {
+ spyOn(RepoService, 'urlIsRichBlob').and.returnValue(false);
+
+ const params = RepoService.buildParams(url);
+
+ expect(params.viewer).toBeUndefined();
+ });
+
+ it('calls urlIsRichBlob with the objects url prop if no url arg is provided', () => {
+ spyOn(RepoService, 'urlIsRichBlob');
+ RepoService.url = url;
+
+ RepoService.buildParams();
+
+ expect(RepoService.urlIsRichBlob).toHaveBeenCalledWith(url);
+ });
+ });
+
+ describe('urlIsRichBlob', () => {
+ it('returns true for md extension', () => {
+ const isRichBlob = RepoService.urlIsRichBlob('url.md');
+
+ expect(isRichBlob).toBeTruthy();
+ });
+
+ it('returns false for js extension', () => {
+ const isRichBlob = RepoService.urlIsRichBlob('url.js');
+
+ expect(isRichBlob).toBeFalsy();
+ });
+ });
+
+ describe('getContent', () => {
+ const params = {};
+ const url = 'url';
+ const requestPromise = Promise.resolve();
+
+ beforeEach(() => {
+ spyOn(RepoService, 'buildParams').and.returnValue(params);
+ spyOn(axios, 'get').and.returnValue(requestPromise);
+ });
+
+ it('calls buildParams and axios.get', () => {
+ const request = RepoService.getContent(url);
+
+ expect(RepoService.buildParams).toHaveBeenCalledWith(url);
+ expect(axios.get).toHaveBeenCalledWith(url, {
+ params,
+ });
+ expect(request).toBe(requestPromise);
+ });
+
+ it('uses object url prop if no url arg is provided', () => {
+ RepoService.url = url;
+
+ RepoService.getContent();
+
+ expect(axios.get).toHaveBeenCalledWith(url, {
+ params,
+ });
+ });
+ });
+
+ describe('getBase64Content', () => {
+ const url = 'url';
+ const response = { data: 'data' };
+
+ beforeEach(() => {
+ spyOn(RepoService, 'bufferToBase64');
+ spyOn(axios, 'get').and.returnValue(Promise.resolve(response));
+ });
+
+ it('calls axios.get and bufferToBase64 on completion', (done) => {
+ const request = RepoService.getBase64Content(url);
+
+ expect(axios.get).toHaveBeenCalledWith(url, {
+ responseType: 'arraybuffer',
+ });
+ expect(request).toEqual(jasmine.any(Promise));
+
+ request.then(() => {
+ expect(RepoService.bufferToBase64).toHaveBeenCalledWith(response.data);
+ done();
+ }).catch(done.fail);
+ });
+ });
+});
diff --git a/spec/javascripts/sidebar/confidential_edit_buttons_spec.js b/spec/javascripts/sidebar/confidential_edit_buttons_spec.js
new file mode 100644
index 00000000000..482be466aad
--- /dev/null
+++ b/spec/javascripts/sidebar/confidential_edit_buttons_spec.js
@@ -0,0 +1,39 @@
+import Vue from 'vue';
+import editFormButtons from '~/sidebar/components/confidential/edit_form_buttons.vue';
+
+describe('Edit Form Buttons', () => {
+ let vm1;
+ let vm2;
+
+ beforeEach(() => {
+ const Component = Vue.extend(editFormButtons);
+ const toggleForm = () => { };
+ const updateConfidentialAttribute = () => { };
+
+ vm1 = new Component({
+ propsData: {
+ isConfidential: true,
+ toggleForm,
+ updateConfidentialAttribute,
+ },
+ }).$mount();
+
+ vm2 = new Component({
+ propsData: {
+ isConfidential: false,
+ toggleForm,
+ updateConfidentialAttribute,
+ },
+ }).$mount();
+ });
+
+ it('renders on or off text based on confidentiality', () => {
+ expect(
+ vm1.$el.innerHTML.includes('Turn Off'),
+ ).toBe(true);
+
+ expect(
+ vm2.$el.innerHTML.includes('Turn On'),
+ ).toBe(true);
+ });
+});
diff --git a/spec/javascripts/sidebar/confidential_edit_form_buttons_spec.js b/spec/javascripts/sidebar/confidential_edit_form_buttons_spec.js
new file mode 100644
index 00000000000..724f5126945
--- /dev/null
+++ b/spec/javascripts/sidebar/confidential_edit_form_buttons_spec.js
@@ -0,0 +1,39 @@
+import Vue from 'vue';
+import editForm from '~/sidebar/components/confidential/edit_form.vue';
+
+describe('Edit Form Dropdown', () => {
+ let vm1;
+ let vm2;
+
+ beforeEach(() => {
+ const Component = Vue.extend(editForm);
+ const toggleForm = () => { };
+ const updateConfidentialAttribute = () => { };
+
+ vm1 = new Component({
+ propsData: {
+ isConfidential: true,
+ toggleForm,
+ updateConfidentialAttribute,
+ },
+ }).$mount();
+
+ vm2 = new Component({
+ propsData: {
+ isConfidential: false,
+ toggleForm,
+ updateConfidentialAttribute,
+ },
+ }).$mount();
+ });
+
+ it('renders on the appropriate warning text', () => {
+ expect(
+ vm1.$el.innerHTML.includes('You are going to turn off the confidentiality.'),
+ ).toBe(true);
+
+ expect(
+ vm2.$el.innerHTML.includes('You are going to turn on the confidentiality.'),
+ ).toBe(true);
+ });
+});
diff --git a/spec/javascripts/sidebar/confidential_issue_sidebar_spec.js b/spec/javascripts/sidebar/confidential_issue_sidebar_spec.js
new file mode 100644
index 00000000000..2e16adffb5b
--- /dev/null
+++ b/spec/javascripts/sidebar/confidential_issue_sidebar_spec.js
@@ -0,0 +1,65 @@
+import Vue from 'vue';
+import confidentialIssueSidebar from '~/sidebar/components/confidential/confidential_issue_sidebar.vue';
+
+describe('Confidential Issue Sidebar Block', () => {
+ let vm1;
+ let vm2;
+
+ beforeEach(() => {
+ const Component = Vue.extend(confidentialIssueSidebar);
+ const service = {
+ update: () => new Promise((resolve, reject) => {
+ resolve(true);
+ reject('failed!');
+ }),
+ };
+
+ vm1 = new Component({
+ propsData: {
+ isConfidential: true,
+ isEditable: true,
+ service,
+ },
+ }).$mount();
+
+ vm2 = new Component({
+ propsData: {
+ isConfidential: false,
+ isEditable: false,
+ service,
+ },
+ }).$mount();
+ });
+
+ it('shows if confidential and/or editable', () => {
+ expect(
+ vm1.$el.innerHTML.includes('Edit'),
+ ).toBe(true);
+
+ expect(
+ vm1.$el.innerHTML.includes('This issue is confidential'),
+ ).toBe(true);
+
+ expect(
+ vm2.$el.innerHTML.includes('This issue is not confidential'),
+ ).toBe(true);
+ });
+
+ it('displays the edit form when editable', (done) => {
+ expect(vm1.edit).toBe(false);
+
+ vm1.$el.querySelector('.confidential-edit').click();
+
+ expect(vm1.edit).toBe(true);
+
+ setTimeout(() => {
+ expect(
+ vm1.$el
+ .innerHTML
+ .includes('You are going to turn off the confidentiality.'),
+ ).toBe(true);
+
+ done();
+ });
+ });
+});
diff --git a/spec/javascripts/vue_mr_widget/components/mr_widget_deployment_spec.js b/spec/javascripts/vue_mr_widget/components/mr_widget_deployment_spec.js
index ab8a3f6c64c..7ee998c8fce 100644
--- a/spec/javascripts/vue_mr_widget/components/mr_widget_deployment_spec.js
+++ b/spec/javascripts/vue_mr_widget/components/mr_widget_deployment_spec.js
@@ -1,7 +1,6 @@
import Vue from 'vue';
import deploymentComponent from '~/vue_merge_request_widget/components/mr_widget_deployment';
import MRWidgetService from '~/vue_merge_request_widget/services/mr_widget_service';
-import { statusIconEntityMap } from '~/vue_shared/ci_status_icons';
const deploymentMockData = [
{
@@ -43,15 +42,6 @@ describe('MRWidgetDeployment', () => {
});
});
- describe('computed', () => {
- describe('svg', () => {
- it('should have the proper SVG icon', () => {
- const vm = createComponent(deploymentMockData);
- expect(vm.svg).toEqual(statusIconEntityMap.icon_status_success);
- });
- });
- });
-
describe('methods', () => {
let vm = createComponent();
const deployment = deploymentMockData[0];
diff --git a/spec/javascripts/vue_mr_widget/components/mr_widget_memory_usage_spec.js b/spec/javascripts/vue_mr_widget/components/mr_widget_memory_usage_spec.js
index 6adcbc73ed7..2ae3adc1f93 100644
--- a/spec/javascripts/vue_mr_widget/components/mr_widget_memory_usage_spec.js
+++ b/spec/javascripts/vue_mr_widget/components/mr_widget_memory_usage_spec.js
@@ -52,10 +52,10 @@ const createComponent = () => {
};
const messages = {
- loadingMetrics: 'Loading deployment statistics.',
+ loadingMetrics: 'Loading deployment statistics',
hasMetrics: 'Memory usage unchanged from 0MB to 0MB',
- loadFailed: 'Failed to load deployment statistics.',
- metricsUnavailable: 'Deployment statistics are not available currently.',
+ loadFailed: 'Failed to load deployment statistics',
+ metricsUnavailable: 'Deployment statistics are not available currently',
};
describe('MemoryUsage', () => {
diff --git a/spec/javascripts/vue_mr_widget/components/mr_widget_pipeline_spec.js b/spec/javascripts/vue_mr_widget/components/mr_widget_pipeline_spec.js
index 647b59520f8..c763487d12f 100644
--- a/spec/javascripts/vue_mr_widget/components/mr_widget_pipeline_spec.js
+++ b/spec/javascripts/vue_mr_widget/components/mr_widget_pipeline_spec.js
@@ -81,13 +81,12 @@ describe('MRWidgetPipeline', () => {
expect(el.querySelectorAll('.ci-status-icon.ci-status-icon-success').length).toEqual(1);
expect(el.querySelector('.pipeline-id').textContent).toContain(`#${pipeline.id}`);
expect(el.innerText).toContain('passed');
- expect(el.innerText).toContain('with stages');
expect(el.querySelector('.pipeline-id').getAttribute('href')).toEqual(pipeline.path);
expect(el.querySelectorAll('.stage-container').length).toEqual(2);
expect(el.querySelector('.js-ci-error')).toEqual(null);
expect(el.querySelector('.js-commit-link').getAttribute('href')).toEqual(pipeline.commit.commit_path);
expect(el.querySelector('.js-commit-link').textContent).toContain(pipeline.commit.short_id);
- expect(el.querySelector('.js-mr-coverage').textContent).toContain(`Coverage ${pipeline.coverage}%.`);
+ expect(el.querySelector('.js-mr-coverage').textContent).toContain(`Coverage ${pipeline.coverage}%`);
});
it('should list single stage', (done) => {
@@ -95,7 +94,6 @@ describe('MRWidgetPipeline', () => {
Vue.nextTick(() => {
expect(el.querySelectorAll('.stage-container button').length).toEqual(1);
- expect(el.innerText).toContain('with stage');
done();
});
});
diff --git a/spec/javascripts/vue_mr_widget/components/mr_widget_related_links_spec.js b/spec/javascripts/vue_mr_widget/components/mr_widget_related_links_spec.js
index f6e0c3dfb74..f86fb6a0b4b 100644
--- a/spec/javascripts/vue_mr_widget/components/mr_widget_related_links_spec.js
+++ b/spec/javascripts/vue_mr_widget/components/mr_widget_related_links_spec.js
@@ -22,15 +22,16 @@ describe('MRWidgetRelatedLinks', () => {
});
describe('computed', () => {
+ const data = {
+ relatedLinks: {
+ closing: '/foo',
+ mentioned: '/foo',
+ assignToMe: '/foo',
+ },
+ };
+
describe('hasLinks', () => {
it('should return correct value when we have links reference', () => {
- const data = {
- relatedLinks: {
- closing: '/foo',
- mentioned: '/foo',
- assignToMe: '/foo',
- },
- };
const vm = createComponent(data);
expect(vm.hasLinks).toBeTruthy();
@@ -44,44 +45,24 @@ describe('MRWidgetRelatedLinks', () => {
expect(vm.hasLinks).toBeFalsy();
});
});
- });
-
- describe('methods', () => {
- const data = {
- relatedLinks: {
- closing: '<a href="#">#23</a> and <a>#42</a>',
- mentioned: '<a href="#">#7</a>',
- },
- };
- const vm = createComponent(data);
-
- describe('hasMultipleIssues', () => {
- it('should return true if the given text has multiple issues', () => {
- expect(vm.hasMultipleIssues(data.relatedLinks.closing)).toBeTruthy();
- });
-
- it('should return false if the given text has one issue', () => {
- expect(vm.hasMultipleIssues(data.relatedLinks.mentioned)).toBeFalsy();
- });
- });
- describe('issueLabel', () => {
- it('should return true if the given text has multiple issues', () => {
- expect(vm.issueLabel('closing')).toEqual('issues');
- });
-
- it('should return false if the given text has one issue', () => {
- expect(vm.issueLabel('mentioned')).toEqual('issue');
+ describe('closesText', () => {
+ it('returns correct text for open merge request', () => {
+ data.state = 'open';
+ const vm = createComponent(data);
+ expect(vm.closesText).toEqual('Closes');
});
- });
- describe('verbLabel', () => {
- it('should return true if the given text has multiple issues', () => {
- expect(vm.verbLabel('closing')).toEqual('are');
+ it('returns correct text for closed merge request', () => {
+ data.state = 'closed';
+ const vm = createComponent(data);
+ expect(vm.closesText).toEqual('Did not close');
});
- it('should return false if the given text has one issue', () => {
- expect(vm.verbLabel('mentioned')).toEqual('is');
+ it('returns correct tense for merged request', () => {
+ data.state = 'merged';
+ const vm = createComponent(data);
+ expect(vm.closesText).toEqual('Closed');
});
});
});
@@ -95,8 +76,8 @@ describe('MRWidgetRelatedLinks', () => {
});
const content = vm.$el.textContent.replace(/\n(\s)+/g, ' ').trim();
- expect(content).toContain('Closes issues #23 and #42');
- expect(content).not.toContain('mentioned');
+ expect(content).toContain('Closes #23 and #42');
+ expect(content).not.toContain('Mentions');
});
it('should have only have mentioned issues text', () => {
@@ -106,8 +87,7 @@ describe('MRWidgetRelatedLinks', () => {
},
});
- expect(vm.$el.innerText).toContain('issue #7');
- expect(vm.$el.innerText).toContain('is mentioned but will not be closed.');
+ expect(vm.$el.innerText).toContain('Mentions #7');
expect(vm.$el.innerText).not.toContain('Closes');
});
@@ -120,9 +100,8 @@ describe('MRWidgetRelatedLinks', () => {
});
const content = vm.$el.textContent.replace(/\n(\s)+/g, ' ').trim();
- expect(content).toContain('Closes issue #7.');
- expect(content).toContain('issues #23 and #42');
- expect(content).toContain('are mentioned but will not be closed.');
+ expect(content).toContain('Closes #7');
+ expect(content).toContain('Mentions #23 and #42');
});
it('should have assing issues link', () => {
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_archived_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_archived_spec.js
index cac2f561a0b..4869fb17d96 100644
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_archived_spec.js
+++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_archived_spec.js
@@ -12,7 +12,7 @@ describe('MRWidgetArchived', () => {
expect(el.classList.contains('mr-widget-body')).toBeTruthy();
expect(el.querySelector('button').classList.contains('btn-success')).toBeTruthy();
expect(el.querySelector('button').disabled).toBeTruthy();
- expect(el.innerText).toContain('This project is archived, write access has been disabled.');
+ expect(el.innerText).toContain('This project is archived, write access has been disabled');
});
});
});
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_auto_merge_failed_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_auto_merge_failed_spec.js
index 47b4ba893e0..6042d7384d5 100644
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_auto_merge_failed_spec.js
+++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_auto_merge_failed_spec.js
@@ -24,8 +24,8 @@ describe('MRWidgetAutoMergeFailed', () => {
it('should have correct elements', () => {
expect(vm.$el.classList.contains('mr-widget-body')).toBeTruthy();
- expect(vm.$el.querySelector('button').getAttribute('disabled')).toBeTruthy();
- expect(vm.$el.innerText).toContain('This merge request failed to be merged automatically.');
+ expect(vm.$el.querySelector('button').getAttribute('disabled')).toBeFalsy();
+ expect(vm.$el.innerText).toContain('This merge request failed to be merged automatically');
expect(vm.$el.innerText).toContain(mergeError);
});
});
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_checking_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_checking_spec.js
index 3be11d47227..6b7aa935ad3 100644
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_checking_spec.js
+++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_checking_spec.js
@@ -12,7 +12,7 @@ describe('MRWidgetChecking', () => {
expect(el.classList.contains('mr-widget-body')).toBeTruthy();
expect(el.querySelector('button').classList.contains('btn-success')).toBeTruthy();
expect(el.querySelector('button').disabled).toBeTruthy();
- expect(el.innerText).toContain('Checking ability to merge automatically.');
+ expect(el.innerText).toContain('Checking ability to merge automatically');
expect(el.querySelector('i')).toBeDefined();
});
});
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_conflicts_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_conflicts_spec.js
index e7ae85caec4..3b7b7d93662 100644
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_conflicts_spec.js
+++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_conflicts_spec.js
@@ -29,15 +29,16 @@ describe('MRWidgetConflicts', () => {
describe('template', () => {
it('should have correct elements', () => {
const el = createComponent().$el;
- const resolveButton = el.querySelectorAll('.btn-group .btn')[0];
- const mergeLocallyButton = el.querySelectorAll('.btn-group .btn')[1];
+ const resolveButton = el.querySelector('.js-resolve-conflicts-button');
+ const mergeButton = el.querySelector('.mr-widget-body .btn');
+ const mergeLocallyButton = el.querySelector('.js-merge-locally-button');
- expect(el.textContent).toContain('There are merge conflicts.');
+ expect(el.textContent).toContain('There are merge conflicts');
expect(el.textContent).not.toContain('ask someone with write access');
expect(el.querySelector('.btn-success').disabled).toBeTruthy();
- expect(el.querySelectorAll('.btn-group .btn').length).toBe(2);
expect(resolveButton.textContent).toContain('Resolve conflicts');
expect(resolveButton.getAttribute('href')).toEqual(path);
+ expect(mergeButton.textContent).toContain('Merge');
expect(mergeLocallyButton.textContent).toContain('Merge locally');
});
@@ -59,8 +60,8 @@ describe('MRWidgetConflicts', () => {
it('should not have action buttons', (done) => {
Vue.nextTick(() => {
expect(vm.$el.querySelectorAll('.btn').length).toBe(1);
- expect(vm.$el.querySelector('a.js-resolve-conflicts-button')).toEqual(null);
- expect(vm.$el.querySelector('a.js-merge-locally-button')).toEqual(null);
+ expect(vm.$el.querySelector('.js-resolve-conflicts-button')).toEqual(null);
+ expect(vm.$el.querySelector('.js-merge-locally-button')).toEqual(null);
done();
});
});
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_failed_to_merge_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_failed_to_merge_spec.js
index 587b83430d9..cef365eec8a 100644
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_failed_to_merge_spec.js
+++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_failed_to_merge_spec.js
@@ -94,7 +94,7 @@ describe('MRWidgetFailedToMerge', () => {
expect(el.querySelector('button').innerText).toContain('Merge');
expect(el.querySelector('.js-refresh-button').innerText).toContain('Refresh now');
expect(el.querySelector('.js-refresh-label')).toEqual(null);
- expect(el.innerText).not.toContain('Refreshing now...');
+ expect(el.innerText).not.toContain('Refreshing now');
setTimeout(() => {
expect(el.innerText).toContain('Refreshing in 9 seconds');
done();
@@ -115,7 +115,7 @@ describe('MRWidgetFailedToMerge', () => {
vm.refresh();
Vue.nextTick(() => {
expect(el.innerText).not.toContain('Merge failed. Refreshing');
- expect(el.innerText).toContain('Refreshing now...');
+ expect(el.innerText).toContain('Refreshing now');
});
});
});
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_locked_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_locked_spec.js
index fb2ef606604..237035648cf 100644
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_locked_spec.js
+++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_locked_spec.js
@@ -1,10 +1,10 @@
import Vue from 'vue';
-import lockedComponent from '~/vue_merge_request_widget/components/states/mr_widget_locked';
+import mergingComponent from '~/vue_merge_request_widget/components/states/mr_widget_merging';
-describe('MRWidgetLocked', () => {
+describe('MRWidgetMerging', () => {
describe('props', () => {
it('should have props', () => {
- const { mr } = lockedComponent.props;
+ const { mr } = mergingComponent.props;
expect(mr.type instanceof Object).toBeTruthy();
expect(mr.required).toBeTruthy();
@@ -13,7 +13,7 @@ describe('MRWidgetLocked', () => {
describe('template', () => {
it('should have correct elements', () => {
- const Component = Vue.extend(lockedComponent);
+ const Component = Vue.extend(mergingComponent);
const mr = {
targetBranchPath: '/branch-path',
targetBranch: 'branch',
@@ -24,7 +24,7 @@ describe('MRWidgetLocked', () => {
}).$el;
expect(el.classList.contains('mr-widget-body')).toBeTruthy();
- expect(el.innerText).toContain('it is locked');
+ expect(el.innerText).toContain('This merge request is in the process of being merged');
expect(el.innerText).toContain('changes will be merged into');
expect(el.querySelector('.label-branch a').getAttribute('href')).toEqual(mr.targetBranchPath);
expect(el.querySelector('.label-branch a').textContent).toContain(mr.targetBranch);
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_merge_when_pipeline_succeeds_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_merge_when_pipeline_succeeds_spec.js
index 8d8b90cea16..9a71d0b47d7 100644
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_merge_when_pipeline_succeeds_spec.js
+++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_merge_when_pipeline_succeeds_spec.js
@@ -162,10 +162,10 @@ describe('MRWidgetMergeWhenPipelineSucceeds', () => {
it('should have correct elements', () => {
expect(el.classList.contains('mr-widget-body')).toBeTruthy();
- expect(el.innerText).toContain('to be merged automatically when the pipeline succeeds.');
+ expect(el.innerText).toContain('to be merged automatically when the pipeline succeeds');
expect(el.innerText).toContain('The changes will be merged into');
expect(el.innerText).toContain(targetBranch);
- expect(el.innerText).toContain('The source branch will not be removed.');
+ expect(el.innerText).toContain('The source branch will not be removed');
expect(el.querySelector('.js-cancel-auto-merge').innerText).toContain('Cancel automatic merge');
expect(el.querySelector('.js-cancel-auto-merge').getAttribute('disabled')).toBeFalsy();
expect(el.querySelector('.js-remove-source-branch').innerText).toContain('Remove source branch');
@@ -186,8 +186,8 @@ describe('MRWidgetMergeWhenPipelineSucceeds', () => {
Vue.nextTick(() => {
const normalizedText = el.innerText.replace(/\s+/g, ' ');
- expect(normalizedText).toContain('The source branch will be removed.');
- expect(normalizedText).not.toContain('The source branch will not be removed.');
+ expect(normalizedText).toContain('The source branch will be removed');
+ expect(normalizedText).not.toContain('The source branch will not be removed');
done();
});
});
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_merged_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_merged_spec.js
index 6628010112d..afaa750199a 100644
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_merged_spec.js
+++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_merged_spec.js
@@ -142,19 +142,19 @@ describe('MRWidgetMerged', () => {
expect(el.querySelector('.js-mr-widget-author')).toBeDefined();
expect(el.innerText).toContain('The changes were merged into');
expect(el.innerText).toContain(targetBranch);
- expect(el.innerText).toContain('The source branch has been removed.');
+ expect(el.innerText).toContain('The source branch has been removed');
expect(el.innerText).toContain('Revert');
expect(el.innerText).toContain('Cherry-pick');
- expect(el.innerText).not.toContain('You can remove source branch now.');
- expect(el.innerText).not.toContain('The source branch is being removed.');
+ expect(el.innerText).not.toContain('You can remove source branch now');
+ expect(el.innerText).not.toContain('The source branch is being removed');
});
it('should not show source branch removed text', (done) => {
vm.mr.sourceBranchRemoved = false;
Vue.nextTick(() => {
- expect(el.innerText).toContain('You can remove source branch now.');
- expect(el.innerText).not.toContain('The source branch has been removed.');
+ expect(el.innerText).toContain('You can remove source branch now');
+ expect(el.innerText).not.toContain('The source branch has been removed');
done();
});
});
@@ -164,9 +164,9 @@ describe('MRWidgetMerged', () => {
vm.mr.sourceBranchRemoved = false;
Vue.nextTick(() => {
- expect(el.innerText).toContain('The source branch is being removed.');
- expect(el.innerText).not.toContain('You can remove source branch now.');
- expect(el.innerText).not.toContain('The source branch has been removed.');
+ expect(el.innerText).toContain('The source branch is being removed');
+ expect(el.innerText).not.toContain('You can remove source branch now');
+ expect(el.innerText).not.toContain('The source branch has been removed');
done();
});
});
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_missing_branch_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_missing_branch_spec.js
index 98674d12afb..720effb5c1c 100644
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_missing_branch_spec.js
+++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_missing_branch_spec.js
@@ -49,7 +49,7 @@ describe('MRWidgetMissingBranch', () => {
expect(el.classList.contains('mr-widget-body')).toBeTruthy();
expect(el.querySelector('button').getAttribute('disabled')).toBeTruthy();
expect(content).toContain('source branch does not exist.');
- expect(content).toContain('Please restore the source branch or use a different source branch.');
+ expect(content).toContain('Please restore it or use a different source branch');
});
});
});
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_not_allowed_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_not_allowed_spec.js
index 61e00f4cf79..33f20ab132d 100644
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_not_allowed_spec.js
+++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_not_allowed_spec.js
@@ -11,7 +11,7 @@ describe('MRWidgetNotAllowed', () => {
expect(vm.$el.classList.contains('mr-widget-body')).toBeTruthy();
expect(vm.$el.querySelector('button').getAttribute('disabled')).toBeTruthy();
expect(vm.$el.innerText).toContain('Ready to be merged automatically.');
- expect(vm.$el.innerText).toContain('Ask someone with write access to this repository to merge this request.');
+ expect(vm.$el.innerText).toContain('Ask someone with write access to this repository to merge this request');
});
});
});
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_pipeline_blocked_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_pipeline_blocked_spec.js
index b293d118571..d0702f9f503 100644
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_pipeline_blocked_spec.js
+++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_pipeline_blocked_spec.js
@@ -10,7 +10,7 @@ describe('MRWidgetPipelineBlocked', () => {
it('should have correct elements', () => {
expect(vm.$el.classList.contains('mr-widget-body')).toBeTruthy();
expect(vm.$el.querySelector('button').getAttribute('disabled')).toBeTruthy();
- expect(vm.$el.innerText).toContain('Pipeline blocked. The pipeline for this merge request requires a manual action to proceed.');
+ expect(vm.$el.innerText).toContain('Pipeline blocked. The pipeline for this merge request requires a manual action to proceed');
});
});
});
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_pipeline_failed_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_pipeline_failed_spec.js
index 807fba705d4..78bac1c61a5 100644
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_pipeline_failed_spec.js
+++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_pipeline_failed_spec.js
@@ -10,7 +10,7 @@ describe('MRWidgetPipelineFailed', () => {
it('should have correct elements', () => {
expect(vm.$el.classList.contains('mr-widget-body')).toBeTruthy();
expect(vm.$el.querySelector('button').getAttribute('disabled')).toBeTruthy();
- expect(vm.$el.innerText).toContain('The pipeline for this merge request failed. Please retry the job or push a new commit to fix the failure.');
+ expect(vm.$el.innerText).toContain('The pipeline for this merge request failed. Please retry the job or push a new commit to fix the failure');
});
});
});
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js
index 732b516badd..c607c9746a4 100644
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js
+++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js
@@ -72,7 +72,7 @@ describe('MRWidgetReadyToMerge', () => {
const withDesc = 'Include description in commit message';
const withoutDesc = "Don't include description in commit message";
- it('should return message wit description', () => {
+ it('should return message with description', () => {
expect(vm.commitMessageLinkTitle).toEqual(withDesc);
});
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_sha_mismatch_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_sha_mismatch_spec.js
index 5fb1d69a8b3..4c67504b642 100644
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_sha_mismatch_spec.js
+++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_sha_mismatch_spec.js
@@ -10,7 +10,7 @@ describe('MRWidgetSHAMismatch', () => {
it('should have correct elements', () => {
expect(vm.$el.classList.contains('mr-widget-body')).toBeTruthy();
expect(vm.$el.querySelector('button').getAttribute('disabled')).toBeTruthy();
- expect(vm.$el.innerText).toContain('The source branch HEAD has recently changed. Please reload the page and review the changes before merging.');
+ expect(vm.$el.innerText).toContain('The source branch HEAD has recently changed. Please reload the page and review the changes before merging');
});
});
});
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_wip_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_wip_spec.js
index 45bd1a69964..2cb3aaa6951 100644
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_wip_spec.js
+++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_wip_spec.js
@@ -78,7 +78,7 @@ describe('MRWidgetWIP', () => {
it('should have correct elements', () => {
expect(el.classList.contains('mr-widget-body')).toBeTruthy();
- expect(el.innerText).toContain('This merge request is currently Work In Progress and therefore unable to merge');
+ expect(el.innerText).toContain('This is a Work in Progress');
expect(el.querySelector('button').getAttribute('disabled')).toBeTruthy();
expect(el.querySelector('button').innerText).toContain('Merge');
expect(el.querySelector('.js-remove-wip').innerText).toContain('Resolve WIP status');
diff --git a/spec/javascripts/vue_mr_widget/mock_data.js b/spec/javascripts/vue_mr_widget/mock_data.js
index e6f96d5588b..0795d0aaa82 100644
--- a/spec/javascripts/vue_mr_widget/mock_data.js
+++ b/spec/javascripts/vue_mr_widget/mock_data.js
@@ -20,7 +20,6 @@ export default {
"human_time_estimate": null,
"human_total_time_spent": null,
"in_progress_merge_commit_sha": null,
- "locked_at": null,
"merge_commit_sha": "53027d060246c8f47e4a9310fb332aa52f221775",
"merge_error": null,
"merge_params": {
@@ -30,6 +29,7 @@ export default {
"merge_user_id": null,
"merge_when_pipeline_succeeds": false,
"source_branch": "daaaa",
+ "source_branch_link": "daaaa",
"source_project_id": 19,
"target_branch": "master",
"target_project_id": 19,
diff --git a/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js b/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js
index 3a0c50b750f..669ee248bf1 100644
--- a/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js
+++ b/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js
@@ -342,7 +342,7 @@ describe('mrWidgetOptions', () => {
expect(comps['mr-widget-related-links']).toBeDefined();
expect(comps['mr-widget-merged']).toBeDefined();
expect(comps['mr-widget-closed']).toBeDefined();
- expect(comps['mr-widget-locked']).toBeDefined();
+ expect(comps['mr-widget-merging']).toBeDefined();
expect(comps['mr-widget-failed-to-merge']).toBeDefined();
expect(comps['mr-widget-wip']).toBeDefined();
expect(comps['mr-widget-archived']).toBeDefined();
diff --git a/spec/lib/api/helpers/pagination_spec.rb b/spec/lib/api/helpers/pagination_spec.rb
index 267318faed4..fb3ef04b860 100644
--- a/spec/lib/api/helpers/pagination_spec.rb
+++ b/spec/lib/api/helpers/pagination_spec.rb
@@ -32,7 +32,7 @@ describe API::Helpers::Pagination do
context 'when resource can be paginated' do
before do
- create_list(:empty_project, 3)
+ create_list(:project, 3)
end
describe 'first page' do
diff --git a/spec/lib/banzai/filter/abstract_reference_filter_spec.rb b/spec/lib/banzai/filter/abstract_reference_filter_spec.rb
index 27532f96f56..7c0ba9ee67f 100644
--- a/spec/lib/banzai/filter/abstract_reference_filter_spec.rb
+++ b/spec/lib/banzai/filter/abstract_reference_filter_spec.rb
@@ -1,11 +1,11 @@
require 'spec_helper'
describe Banzai::Filter::AbstractReferenceFilter do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
describe '#references_per_project' do
it 'returns a Hash containing references grouped per project paths' do
- doc = Nokogiri::HTML.fragment("#1 #{project.path_with_namespace}#2")
+ doc = Nokogiri::HTML.fragment("#1 #{project.full_path}#2")
filter = described_class.new(doc, project: project)
expect(filter).to receive(:object_class).exactly(4).times.and_return(Issue)
@@ -14,7 +14,7 @@ describe Banzai::Filter::AbstractReferenceFilter do
refs = filter.references_per_project
expect(refs).to be_an_instance_of(Hash)
- expect(refs[project.path_with_namespace]).to eq(Set.new(%w[1 2]))
+ expect(refs[project.full_path]).to eq(Set.new(%w[1 2]))
end
end
@@ -24,10 +24,10 @@ describe Banzai::Filter::AbstractReferenceFilter do
filter = described_class.new(doc, project: project)
expect(filter).to receive(:references_per_project)
- .and_return({ project.path_with_namespace => Set.new(%w[1]) })
+ .and_return({ project.full_path => Set.new(%w[1]) })
expect(filter.projects_per_reference)
- .to eq({ project.path_with_namespace => project })
+ .to eq({ project.full_path => project })
end
end
@@ -37,7 +37,7 @@ describe Banzai::Filter::AbstractReferenceFilter do
context 'with RequestStore disabled' do
it 'returns a list of Projects for a list of paths' do
- expect(filter.find_projects_for_paths([project.path_with_namespace]))
+ expect(filter.find_projects_for_paths([project.full_path]))
.to eq([project])
end
@@ -49,7 +49,7 @@ describe Banzai::Filter::AbstractReferenceFilter do
context 'with RequestStore enabled', :request_store do
it 'returns a list of Projects for a list of paths' do
- expect(filter.find_projects_for_paths([project.path_with_namespace]))
+ expect(filter.find_projects_for_paths([project.full_path]))
.to eq([project])
end
@@ -88,7 +88,7 @@ describe Banzai::Filter::AbstractReferenceFilter do
doc = Nokogiri::HTML.fragment('')
filter = described_class.new(doc, project: project)
- expect(filter.current_project_path).to eq(project.path_with_namespace)
+ expect(filter.current_project_path).to eq(project.full_path)
end
end
end
diff --git a/spec/lib/banzai/filter/commit_range_reference_filter_spec.rb b/spec/lib/banzai/filter/commit_range_reference_filter_spec.rb
index 11d48387544..935146c17fc 100644
--- a/spec/lib/banzai/filter/commit_range_reference_filter_spec.rb
+++ b/spec/lib/banzai/filter/commit_range_reference_filter_spec.rb
@@ -100,7 +100,7 @@ describe Banzai::Filter::CommitRangeReferenceFilter do
context 'cross-project / cross-namespace complete reference' do
let(:project2) { create(:project, :public, :repository) }
- let(:reference) { "#{project2.path_with_namespace}@#{commit1.id}...#{commit2.id}" }
+ let(:reference) { "#{project2.full_path}@#{commit1.id}...#{commit2.id}" }
it 'links to a valid reference' do
doc = reference_filter("See #{reference}")
@@ -113,20 +113,20 @@ describe Banzai::Filter::CommitRangeReferenceFilter do
doc = reference_filter("Fixed (#{reference}.)")
expect(doc.css('a').first.text)
- .to eql("#{project2.path_with_namespace}@#{commit1.short_id}...#{commit2.short_id}")
+ .to eql("#{project2.full_path}@#{commit1.short_id}...#{commit2.short_id}")
end
it 'has valid text' do
doc = reference_filter("Fixed (#{reference}.)")
- expect(doc.text).to eql("Fixed (#{project2.path_with_namespace}@#{commit1.short_id}...#{commit2.short_id}.)")
+ expect(doc.text).to eql("Fixed (#{project2.full_path}@#{commit1.short_id}...#{commit2.short_id}.)")
end
it 'ignores invalid commit IDs on the referenced project' do
- exp = act = "Fixed #{project2.path_with_namespace}@#{commit1.id.reverse}...#{commit2.id}"
+ exp = act = "Fixed #{project2.full_path}@#{commit1.id.reverse}...#{commit2.id}"
expect(reference_filter(act).to_html).to eq exp
- exp = act = "Fixed #{project2.path_with_namespace}@#{commit1.id}...#{commit2.id.reverse}"
+ exp = act = "Fixed #{project2.full_path}@#{commit1.id}...#{commit2.id.reverse}"
expect(reference_filter(act).to_html).to eq exp
end
end
diff --git a/spec/lib/banzai/filter/commit_reference_filter_spec.rb b/spec/lib/banzai/filter/commit_reference_filter_spec.rb
index fb2a36d1ba1..702fcac0c6f 100644
--- a/spec/lib/banzai/filter/commit_reference_filter_spec.rb
+++ b/spec/lib/banzai/filter/commit_reference_filter_spec.rb
@@ -98,18 +98,18 @@ describe Banzai::Filter::CommitReferenceFilter do
let(:namespace) { create(:namespace) }
let(:project2) { create(:project, :public, :repository, namespace: namespace) }
let(:commit) { project2.commit }
- let(:reference) { "#{project2.path_with_namespace}@#{commit.short_id}" }
+ let(:reference) { "#{project2.full_path}@#{commit.short_id}" }
it 'link has valid text' do
doc = reference_filter("See (#{reference}.)")
- expect(doc.css('a').first.text).to eql("#{project2.path_with_namespace}@#{commit.short_id}")
+ expect(doc.css('a').first.text).to eql("#{project2.full_path}@#{commit.short_id}")
end
it 'has valid text' do
doc = reference_filter("See (#{reference}.)")
- expect(doc.text).to eql("See (#{project2.path_with_namespace}@#{commit.short_id}.)")
+ expect(doc.text).to eql("See (#{project2.full_path}@#{commit.short_id}.)")
end
it 'ignores invalid commit IDs on the referenced project' do
@@ -121,10 +121,10 @@ describe Banzai::Filter::CommitReferenceFilter do
context 'cross-project / same-namespace complete reference' do
let(:namespace) { create(:namespace) }
- let(:project) { create(:empty_project, namespace: namespace) }
+ let(:project) { create(:project, namespace: namespace) }
let(:project2) { create(:project, :public, :repository, namespace: namespace) }
let(:commit) { project2.commit }
- let(:reference) { "#{project2.path_with_namespace}@#{commit.short_id}" }
+ let(:reference) { "#{project2.full_path}@#{commit.short_id}" }
it 'link has valid text' do
doc = reference_filter("See (#{reference}.)")
@@ -147,10 +147,10 @@ describe Banzai::Filter::CommitReferenceFilter do
context 'cross-project shorthand reference' do
let(:namespace) { create(:namespace) }
- let(:project) { create(:empty_project, namespace: namespace) }
+ let(:project) { create(:project, namespace: namespace) }
let(:project2) { create(:project, :public, :repository, namespace: namespace) }
let(:commit) { project2.commit }
- let(:reference) { "#{project2.path_with_namespace}@#{commit.short_id}" }
+ let(:reference) { "#{project2.full_path}@#{commit.short_id}" }
it 'link has valid text' do
doc = reference_filter("See (#{reference}.)")
diff --git a/spec/lib/banzai/filter/gollum_tags_filter_spec.rb b/spec/lib/banzai/filter/gollum_tags_filter_spec.rb
index 663e3514436..97d612e6347 100644
--- a/spec/lib/banzai/filter/gollum_tags_filter_spec.rb
+++ b/spec/lib/banzai/filter/gollum_tags_filter_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe Banzai::Filter::GollumTagsFilter do
include FilterSpecHelper
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:user) { double }
let(:project_wiki) { ProjectWiki.new(project, user) }
diff --git a/spec/lib/banzai/filter/issuable_state_filter_spec.rb b/spec/lib/banzai/filter/issuable_state_filter_spec.rb
index bc7cae1df8d..cacb33d3372 100644
--- a/spec/lib/banzai/filter/issuable_state_filter_spec.rb
+++ b/spec/lib/banzai/filter/issuable_state_filter_spec.rb
@@ -7,8 +7,8 @@ describe Banzai::Filter::IssuableStateFilter do
let(:user) { create(:user) }
let(:context) { { current_user: user, issuable_state_filter_enabled: true } }
let(:closed_issue) { create_issue(:closed) }
- let(:project) { create(:empty_project, :public) }
- let(:other_project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
+ let(:other_project) { create(:project, :public) }
def create_link(text, data)
link_to(text, '', class: 'gfm has-tooltip', data: data)
diff --git a/spec/lib/banzai/filter/issue_reference_filter_spec.rb b/spec/lib/banzai/filter/issue_reference_filter_spec.rb
index 045bf3e0cc9..9c74c9b8c99 100644
--- a/spec/lib/banzai/filter/issue_reference_filter_spec.rb
+++ b/spec/lib/banzai/filter/issue_reference_filter_spec.rb
@@ -7,7 +7,7 @@ describe Banzai::Filter::IssueReferenceFilter do
IssuesHelper
end
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:issue) { create(:issue, project: project) }
it 'requires project context' do
@@ -125,9 +125,9 @@ describe Banzai::Filter::IssueReferenceFilter do
context 'cross-project / cross-namespace complete reference' do
it_behaves_like 'a reference containing an element node'
- let(:project2) { create(:empty_project, :public) }
+ let(:project2) { create(:project, :public) }
let(:issue) { create(:issue, project: project2) }
- let(:reference) { "#{project2.path_with_namespace}##{issue.iid}" }
+ let(:reference) { "#{project2.full_path}##{issue.iid}" }
it 'ignores valid references when cross-reference project uses external tracker' do
expect_any_instance_of(described_class).to receive(:find_object)
@@ -148,13 +148,13 @@ describe Banzai::Filter::IssueReferenceFilter do
it 'link has valid text' do
doc = reference_filter("Fixed (#{reference}.)")
- expect(doc.css('a').first.text).to eql("#{project2.path_with_namespace}##{issue.iid}")
+ expect(doc.css('a').first.text).to eql("#{project2.full_path}##{issue.iid}")
end
it 'has valid text' do
doc = reference_filter("Fixed (#{reference}.)")
- expect(doc.text).to eq("Fixed (#{project2.path_with_namespace}##{issue.iid}.)")
+ expect(doc.text).to eq("Fixed (#{project2.full_path}##{issue.iid}.)")
end
it 'ignores invalid issue IDs on the referenced project' do
@@ -168,10 +168,10 @@ describe Banzai::Filter::IssueReferenceFilter do
it_behaves_like 'a reference containing an element node'
let(:namespace) { create(:namespace) }
- let(:project) { create(:empty_project, :public, namespace: namespace) }
- let(:project2) { create(:empty_project, :public, namespace: namespace) }
+ let(:project) { create(:project, :public, namespace: namespace) }
+ let(:project2) { create(:project, :public, namespace: namespace) }
let(:issue) { create(:issue, project: project2) }
- let(:reference) { "#{project2.path_with_namespace}##{issue.iid}" }
+ let(:reference) { "#{project2.full_path}##{issue.iid}" }
it 'ignores valid references when cross-reference project uses external tracker' do
expect_any_instance_of(described_class).to receive(:find_object)
@@ -212,8 +212,8 @@ describe Banzai::Filter::IssueReferenceFilter do
it_behaves_like 'a reference containing an element node'
let(:namespace) { create(:namespace) }
- let(:project) { create(:empty_project, :public, namespace: namespace) }
- let(:project2) { create(:empty_project, :public, namespace: namespace) }
+ let(:project) { create(:project, :public, namespace: namespace) }
+ let(:project2) { create(:project, :public, namespace: namespace) }
let(:issue) { create(:issue, project: project2) }
let(:reference) { "#{project2.path}##{issue.iid}" }
@@ -256,7 +256,7 @@ describe Banzai::Filter::IssueReferenceFilter do
it_behaves_like 'a reference containing an element node'
let(:namespace) { create(:namespace, name: 'cross-reference') }
- let(:project2) { create(:empty_project, :public, namespace: namespace) }
+ let(:project2) { create(:project, :public, namespace: namespace) }
let(:issue) { create(:issue, project: project2) }
let(:reference) { helper.url_for_issue(issue.iid, project2) + "#note_123" }
@@ -277,7 +277,7 @@ describe Banzai::Filter::IssueReferenceFilter do
it_behaves_like 'a reference containing an element node'
let(:namespace) { create(:namespace, name: 'cross-reference') }
- let(:project2) { create(:empty_project, :public, namespace: namespace) }
+ let(:project2) { create(:project, :public, namespace: namespace) }
let(:issue) { create(:issue, project: project2) }
let(:reference) { issue.to_reference(project) }
let(:reference_link) { %{<a href="#{reference}">Reference</a>} }
@@ -299,7 +299,7 @@ describe Banzai::Filter::IssueReferenceFilter do
it_behaves_like 'a reference containing an element node'
let(:namespace) { create(:namespace, name: 'cross-reference') }
- let(:project2) { create(:empty_project, :public, namespace: namespace) }
+ let(:project2) { create(:project, :public, namespace: namespace) }
let(:issue) { create(:issue, project: project2) }
let(:reference) { "#{helper.url_for_issue(issue.iid, project2) + "#note_123"}" }
let(:reference_link) { %{<a href="#{reference}">Reference</a>} }
@@ -324,10 +324,10 @@ describe Banzai::Filter::IssueReferenceFilter do
filter = described_class.new(doc, project: project)
expect(filter).to receive(:projects_per_reference)
- .and_return({ project.path_with_namespace => project })
+ .and_return({ project.full_path => project })
expect(filter).to receive(:references_per_project)
- .and_return({ project.path_with_namespace => Set.new([issue.iid]) })
+ .and_return({ project.full_path => Set.new([issue.iid]) })
expect(filter.issues_per_project)
.to eq({ project => { issue.iid => issue } })
diff --git a/spec/lib/banzai/filter/label_reference_filter_spec.rb b/spec/lib/banzai/filter/label_reference_filter_spec.rb
index 1daa6ac7f9e..2cd30a5e302 100644
--- a/spec/lib/banzai/filter/label_reference_filter_spec.rb
+++ b/spec/lib/banzai/filter/label_reference_filter_spec.rb
@@ -4,7 +4,7 @@ require 'html/pipeline'
describe Banzai::Filter::LabelReferenceFilter do
include FilterSpecHelper
- let(:project) { create(:empty_project, :public, name: 'sample-project') }
+ let(:project) { create(:project, :public, name: 'sample-project') }
let(:label) { create(:label, project: project) }
let(:reference) { label.to_reference }
@@ -315,7 +315,7 @@ describe Banzai::Filter::LabelReferenceFilter do
describe 'group label references' do
let(:group) { create(:group) }
- let(:project) { create(:empty_project, :public, namespace: group) }
+ let(:project) { create(:project, :public, namespace: group) }
let(:group_label) { create(:group_label, name: 'gfm references', group: group) }
context 'without project reference' do
@@ -366,9 +366,9 @@ describe Banzai::Filter::LabelReferenceFilter do
end
describe 'cross-project / cross-namespace complete reference' do
- let(:project2) { create(:empty_project) }
+ let(:project2) { create(:project) }
let(:label) { create(:label, project: project2, color: '#00ff00') }
- let(:reference) { "#{project2.path_with_namespace}~#{label.name}" }
+ let(:reference) { "#{project2.full_path}~#{label.name}" }
let!(:result) { reference_filter("See #{reference}") }
it 'links to a valid reference' do
@@ -397,10 +397,10 @@ describe Banzai::Filter::LabelReferenceFilter do
describe 'cross-project / same-namespace complete reference' do
let(:namespace) { create(:namespace) }
- let(:project) { create(:empty_project, namespace: namespace) }
- let(:project2) { create(:empty_project, namespace: namespace) }
+ let(:project) { create(:project, namespace: namespace) }
+ let(:project2) { create(:project, namespace: namespace) }
let(:label) { create(:label, project: project2, color: '#00ff00') }
- let(:reference) { "#{project2.path_with_namespace}~#{label.name}" }
+ let(:reference) { "#{project2.full_path}~#{label.name}" }
let!(:result) { reference_filter("See #{reference}") }
it 'links to a valid reference' do
@@ -429,8 +429,8 @@ describe Banzai::Filter::LabelReferenceFilter do
describe 'cross-project shorthand reference' do
let(:namespace) { create(:namespace) }
- let(:project) { create(:empty_project, namespace: namespace) }
- let(:project2) { create(:empty_project, namespace: namespace) }
+ let(:project) { create(:project, namespace: namespace) }
+ let(:project2) { create(:project, namespace: namespace) }
let(:label) { create(:label, project: project2, color: '#00ff00') }
let(:reference) { "#{project2.path}~#{label.name}" }
let!(:result) { reference_filter("See #{reference}") }
@@ -462,11 +462,11 @@ describe Banzai::Filter::LabelReferenceFilter do
describe 'cross group label references' do
let(:group) { create(:group) }
- let(:project) { create(:empty_project, :public, namespace: group) }
+ let(:project) { create(:project, :public, namespace: group) }
let(:another_group) { create(:group) }
- let(:another_project) { create(:empty_project, :public, namespace: another_group) }
+ let(:another_project) { create(:project, :public, namespace: another_group) }
let(:group_label) { create(:group_label, group: another_group, color: '#00ff00') }
- let(:reference) { "#{another_project.path_with_namespace}~#{group_label.name}" }
+ let(:reference) { "#{another_project.full_path}~#{group_label.name}" }
let!(:result) { reference_filter("See #{reference}", project: project) }
it 'points to referenced project issues page' do
@@ -498,10 +498,10 @@ describe Banzai::Filter::LabelReferenceFilter do
describe 'cross-project / same-group_label complete reference' do
let(:group) { create(:group) }
- let(:project) { create(:empty_project, :public, namespace: group) }
- let(:another_project) { create(:empty_project, :public, namespace: group) }
+ let(:project) { create(:project, :public, namespace: group) }
+ let(:another_project) { create(:project, :public, namespace: group) }
let(:group_label) { create(:group_label, group: group, color: '#00ff00') }
- let(:reference) { "#{another_project.path_with_namespace}~#{group_label.name}" }
+ let(:reference) { "#{another_project.full_path}~#{group_label.name}" }
let!(:result) { reference_filter("See #{reference}", project: project) }
it 'points to referenced project issues page' do
@@ -533,9 +533,9 @@ describe Banzai::Filter::LabelReferenceFilter do
describe 'same project / same group_label complete reference' do
let(:group) { create(:group) }
- let(:project) { create(:empty_project, :public, namespace: group) }
+ let(:project) { create(:project, :public, namespace: group) }
let(:group_label) { create(:group_label, group: group, color: '#00ff00') }
- let(:reference) { "#{project.path_with_namespace}~#{group_label.name}" }
+ let(:reference) { "#{project.full_path}~#{group_label.name}" }
let!(:result) { reference_filter("See #{reference}", project: project) }
it 'points to referenced project issues page' do
@@ -565,7 +565,7 @@ describe Banzai::Filter::LabelReferenceFilter do
describe 'same project / same group_label shorthand reference' do
let(:group) { create(:group) }
- let(:project) { create(:empty_project, :public, namespace: group) }
+ let(:project) { create(:project, :public, namespace: group) }
let(:group_label) { create(:group_label, group: group, color: '#00ff00') }
let(:reference) { "#{project.path}~#{group_label.name}" }
let!(:result) { reference_filter("See #{reference}", project: project) }
diff --git a/spec/lib/banzai/filter/merge_request_reference_filter_spec.rb b/spec/lib/banzai/filter/merge_request_reference_filter_spec.rb
index 683972a3112..ed2788f8a33 100644
--- a/spec/lib/banzai/filter/merge_request_reference_filter_spec.rb
+++ b/spec/lib/banzai/filter/merge_request_reference_filter_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe Banzai::Filter::MergeRequestReferenceFilter do
include FilterSpecHelper
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:merge) { create(:merge_request, source_project: project) }
it 'requires project context' do
@@ -100,9 +100,9 @@ describe Banzai::Filter::MergeRequestReferenceFilter do
end
context 'cross-project / cross-namespace complete reference' do
- let(:project2) { create(:empty_project, :public) }
+ let(:project2) { create(:project, :public) }
let(:merge) { create(:merge_request, source_project: project2) }
- let(:reference) { "#{project2.path_with_namespace}!#{merge.iid}" }
+ let(:reference) { "#{project2.full_path}!#{merge.iid}" }
it 'links to a valid reference' do
doc = reference_filter("See #{reference}")
@@ -132,10 +132,10 @@ describe Banzai::Filter::MergeRequestReferenceFilter do
context 'cross-project / same-namespace complete reference' do
let(:namespace) { create(:namespace) }
- let(:project) { create(:empty_project, :public, namespace: namespace) }
- let(:project2) { create(:empty_project, :public, namespace: namespace) }
+ let(:project) { create(:project, :public, namespace: namespace) }
+ let(:project2) { create(:project, :public, namespace: namespace) }
let!(:merge) { create(:merge_request, source_project: project2) }
- let(:reference) { "#{project2.path_with_namespace}!#{merge.iid}" }
+ let(:reference) { "#{project2.full_path}!#{merge.iid}" }
it 'links to a valid reference' do
doc = reference_filter("See #{reference}")
@@ -165,8 +165,8 @@ describe Banzai::Filter::MergeRequestReferenceFilter do
context 'cross-project shorthand reference' do
let(:namespace) { create(:namespace) }
- let(:project) { create(:empty_project, :public, namespace: namespace) }
- let(:project2) { create(:empty_project, :public, namespace: namespace) }
+ let(:project) { create(:project, :public, namespace: namespace) }
+ let(:project2) { create(:project, :public, namespace: namespace) }
let!(:merge) { create(:merge_request, source_project: project2) }
let(:reference) { "#{project2.path}!#{merge.iid}" }
@@ -198,7 +198,7 @@ describe Banzai::Filter::MergeRequestReferenceFilter do
context 'cross-project URL reference' do
let(:namespace) { create(:namespace, name: 'cross-reference') }
- let(:project2) { create(:empty_project, :public, namespace: namespace) }
+ let(:project2) { create(:project, :public, namespace: namespace) }
let(:merge) { create(:merge_request, source_project: project2, target_project: project2) }
let(:reference) { urls.project_merge_request_url(project2, merge) + '/diffs#note_123' }
diff --git a/spec/lib/banzai/filter/milestone_reference_filter_spec.rb b/spec/lib/banzai/filter/milestone_reference_filter_spec.rb
index 8fe05dc2e53..ebd6c79077e 100644
--- a/spec/lib/banzai/filter/milestone_reference_filter_spec.rb
+++ b/spec/lib/banzai/filter/milestone_reference_filter_spec.rb
@@ -3,57 +3,57 @@ require 'spec_helper'
describe Banzai::Filter::MilestoneReferenceFilter do
include FilterSpecHelper
- let(:project) { create(:empty_project, :public) }
- let(:milestone) { create(:milestone, project: project) }
- let(:reference) { milestone.to_reference }
+ let(:group) { create(:group, :public) }
+ let(:project) { create(:project, :public, group: group) }
it 'requires project context' do
expect { described_class.call('') }.to raise_error(ArgumentError, /:project/)
end
- %w(pre code a style).each do |elem|
- it "ignores valid references contained inside '#{elem}' element" do
- exp = act = "<#{elem}>milestone #{milestone.to_reference}</#{elem}>"
- expect(reference_filter(act).to_html).to eq exp
+ shared_examples 'reference parsing' do
+ %w(pre code a style).each do |elem|
+ it "ignores valid references contained inside '#{elem}' element" do
+ exp = act = "<#{elem}>milestone #{reference}</#{elem}>"
+ expect(reference_filter(act).to_html).to eq exp
+ end
end
- end
- it 'includes default classes' do
- doc = reference_filter("Milestone #{reference}")
- expect(doc.css('a').first.attr('class')).to eq 'gfm gfm-milestone has-tooltip'
- end
+ it 'includes default classes' do
+ doc = reference_filter("Milestone #{reference}")
- it 'includes a data-project attribute' do
- doc = reference_filter("Milestone #{reference}")
- link = doc.css('a').first
+ expect(doc.css('a').first.attr('class')).to eq 'gfm gfm-milestone has-tooltip'
+ end
- expect(link).to have_attribute('data-project')
- expect(link.attr('data-project')).to eq project.id.to_s
- end
+ it 'includes a data-project attribute' do
+ doc = reference_filter("Milestone #{reference}")
+ link = doc.css('a').first
- it 'includes a data-milestone attribute' do
- doc = reference_filter("See #{reference}")
- link = doc.css('a').first
+ expect(link).to have_attribute('data-project')
+ expect(link.attr('data-project')).to eq project.id.to_s
+ end
- expect(link).to have_attribute('data-milestone')
- expect(link.attr('data-milestone')).to eq milestone.id.to_s
- end
+ it 'includes a data-milestone attribute' do
+ doc = reference_filter("See #{reference}")
+ link = doc.css('a').first
- it 'supports an :only_path context' do
- doc = reference_filter("Milestone #{reference}", only_path: true)
- link = doc.css('a').first.attr('href')
+ expect(link).to have_attribute('data-milestone')
+ expect(link.attr('data-milestone')).to eq milestone.id.to_s
+ end
+
+ it 'supports an :only_path context' do
+ doc = reference_filter("Milestone #{reference}", only_path: true)
+ link = doc.css('a').first.attr('href')
- expect(link).not_to match %r(https?://)
- expect(link).to eq urls
- .project_milestone_path(project, milestone)
+ expect(link).not_to match %r(https?://)
+ expect(link).to eq urls.milestone_path(milestone)
+ end
end
- context 'Integer-based references' do
+ shared_examples 'Integer-based references' do
it 'links to a valid reference' do
doc = reference_filter("See #{reference}")
- expect(doc.css('a').first.attr('href')).to eq urls
- .project_milestone_url(project, milestone)
+ expect(doc.css('a').first.attr('href')).to eq urls.milestone_url(milestone)
end
it 'links with adjacent text' do
@@ -68,15 +68,17 @@ describe Banzai::Filter::MilestoneReferenceFilter do
end
end
- context 'String-based single-word references' do
- let(:milestone) { create(:milestone, name: 'gfm', project: project) }
+ shared_examples 'String-based single-word references' do
let(:reference) { "#{Milestone.reference_prefix}#{milestone.name}" }
+ before do
+ milestone.update!(name: 'gfm')
+ end
+
it 'links to a valid reference' do
doc = reference_filter("See #{reference}")
- expect(doc.css('a').first.attr('href')).to eq urls
- .project_milestone_url(project, milestone)
+ expect(doc.css('a').first.attr('href')).to eq urls.milestone_url(milestone)
expect(doc.text).to eq 'See gfm'
end
@@ -92,15 +94,17 @@ describe Banzai::Filter::MilestoneReferenceFilter do
end
end
- context 'String-based multi-word references in quotes' do
- let(:milestone) { create(:milestone, name: 'gfm references', project: project) }
+ shared_examples 'String-based multi-word references in quotes' do
let(:reference) { milestone.to_reference(format: :name) }
+ before do
+ milestone.update!(name: 'gfm references')
+ end
+
it 'links to a valid reference' do
doc = reference_filter("See #{reference}")
- expect(doc.css('a').first.attr('href')).to eq urls
- .project_milestone_url(project, milestone)
+ expect(doc.css('a').first.attr('href')).to eq urls.milestone_url(milestone)
expect(doc.text).to eq 'See gfm references'
end
@@ -116,23 +120,27 @@ describe Banzai::Filter::MilestoneReferenceFilter do
end
end
- describe 'referencing a milestone in a link href' do
- let(:reference) { %Q{<a href="#{milestone.to_reference}">Milestone</a>} }
+ shared_examples 'referencing a milestone in a link href' do
+ let(:unquoted_reference) { "#{Milestone.reference_prefix}#{milestone.name}" }
+ let(:link_reference) { %Q{<a href="#{unquoted_reference}">Milestone</a>} }
+
+ before do
+ milestone.update!(name: 'gfm')
+ end
it 'links to a valid reference' do
- doc = reference_filter("See #{reference}")
+ doc = reference_filter("See #{link_reference}")
- expect(doc.css('a').first.attr('href')).to eq urls
- .project_milestone_url(project, milestone)
+ expect(doc.css('a').first.attr('href')).to eq urls.milestone_url(milestone)
end
it 'links with adjacent text' do
- doc = reference_filter("Milestone (#{reference}.)")
+ doc = reference_filter("Milestone (#{link_reference}.)")
expect(doc.to_html).to match(%r(\(<a.+>Milestone</a>\.\)))
end
it 'includes a data-project attribute' do
- doc = reference_filter("Milestone #{reference}")
+ doc = reference_filter("Milestone #{link_reference}")
link = doc.css('a').first
expect(link).to have_attribute('data-project')
@@ -140,7 +148,35 @@ describe Banzai::Filter::MilestoneReferenceFilter do
end
it 'includes a data-milestone attribute' do
- doc = reference_filter("See #{reference}")
+ doc = reference_filter("See #{link_reference}")
+ link = doc.css('a').first
+
+ expect(link).to have_attribute('data-milestone')
+ expect(link.attr('data-milestone')).to eq milestone.id.to_s
+ end
+ end
+
+ shared_examples 'linking to a milestone as the entire link' do
+ let(:unquoted_reference) { "#{Milestone.reference_prefix}#{milestone.name}" }
+ let(:link) { urls.milestone_url(milestone) }
+ let(:link_reference) { %Q{<a href="#{link}">#{link}</a>} }
+
+ it 'replaces the link text with the milestone reference' do
+ doc = reference_filter("See #{link}")
+
+ expect(doc.css('a').first.text).to eq(unquoted_reference)
+ end
+
+ it 'includes a data-project attribute' do
+ doc = reference_filter("Milestone #{link_reference}")
+ link = doc.css('a').first
+
+ expect(link).to have_attribute('data-project')
+ expect(link.attr('data-project')).to eq project.id.to_s
+ end
+
+ it 'includes a data-milestone attribute' do
+ doc = reference_filter("See #{link_reference}")
link = doc.css('a').first
expect(link).to have_attribute('data-milestone')
@@ -148,11 +184,11 @@ describe Banzai::Filter::MilestoneReferenceFilter do
end
end
- describe 'cross-project / cross-namespace complete reference' do
+ shared_examples 'cross-project / cross-namespace complete reference' do
let(:namespace) { create(:namespace) }
- let(:another_project) { create(:empty_project, :public, namespace: namespace) }
+ let(:another_project) { create(:project, :public, namespace: namespace) }
let(:milestone) { create(:milestone, project: another_project) }
- let(:reference) { "#{another_project.path_with_namespace}%#{milestone.iid}" }
+ let(:reference) { "#{another_project.full_path}%#{milestone.iid}" }
let!(:result) { reference_filter("See #{reference}") }
it 'points to referenced project milestone page' do
@@ -164,14 +200,14 @@ describe Banzai::Filter::MilestoneReferenceFilter do
doc = reference_filter("See (#{reference}.)")
expect(doc.css('a').first.text)
- .to eq("#{milestone.name} in #{another_project.path_with_namespace}")
+ .to eq("#{milestone.name} in #{another_project.full_path}")
end
it 'has valid text' do
doc = reference_filter("See (#{reference}.)")
expect(doc.text)
- .to eq("See (#{milestone.name} in #{another_project.path_with_namespace}.)")
+ .to eq("See (#{milestone.name} in #{another_project.full_path}.)")
end
it 'escapes the name attribute' do
@@ -180,16 +216,16 @@ describe Banzai::Filter::MilestoneReferenceFilter do
doc = reference_filter("See #{reference}")
expect(doc.css('a').first.text)
- .to eq "#{milestone.name} in #{another_project.path_with_namespace}"
+ .to eq "#{milestone.name} in #{another_project.full_path}"
end
end
- describe 'cross-project / same-namespace complete reference' do
+ shared_examples 'cross-project / same-namespace complete reference' do
let(:namespace) { create(:namespace) }
- let(:project) { create(:empty_project, :public, namespace: namespace) }
- let(:another_project) { create(:empty_project, :public, namespace: namespace) }
+ let(:project) { create(:project, :public, namespace: namespace) }
+ let(:another_project) { create(:project, :public, namespace: namespace) }
let(:milestone) { create(:milestone, project: another_project) }
- let(:reference) { "#{another_project.path_with_namespace}%#{milestone.iid}" }
+ let(:reference) { "#{another_project.full_path}%#{milestone.iid}" }
let!(:result) { reference_filter("See #{reference}") }
it 'points to referenced project milestone page' do
@@ -221,10 +257,10 @@ describe Banzai::Filter::MilestoneReferenceFilter do
end
end
- describe 'cross project shorthand reference' do
+ shared_examples 'cross project shorthand reference' do
let(:namespace) { create(:namespace) }
- let(:project) { create(:empty_project, :public, namespace: namespace) }
- let(:another_project) { create(:empty_project, :public, namespace: namespace) }
+ let(:project) { create(:project, :public, namespace: namespace) }
+ let(:another_project) { create(:project, :public, namespace: namespace) }
let(:milestone) { create(:milestone, project: another_project) }
let(:reference) { "#{another_project.path}%#{milestone.iid}" }
let!(:result) { reference_filter("See #{reference}") }
@@ -257,4 +293,54 @@ describe Banzai::Filter::MilestoneReferenceFilter do
.to eq "#{milestone.name} in #{another_project.path}"
end
end
+
+ context 'project milestones' do
+ let(:milestone) { create(:milestone, project: project) }
+ let(:reference) { milestone.to_reference }
+
+ include_examples 'reference parsing'
+
+ it_behaves_like 'Integer-based references'
+ it_behaves_like 'String-based single-word references'
+ it_behaves_like 'String-based multi-word references in quotes'
+ it_behaves_like 'referencing a milestone in a link href'
+ it_behaves_like 'cross-project / cross-namespace complete reference'
+ it_behaves_like 'cross-project / same-namespace complete reference'
+ it_behaves_like 'cross project shorthand reference'
+ end
+
+ context 'group milestones' do
+ let(:milestone) { create(:milestone, group: group) }
+ let(:reference) { milestone.to_reference(format: :name) }
+
+ include_examples 'reference parsing'
+
+ it_behaves_like 'String-based single-word references'
+ it_behaves_like 'String-based multi-word references in quotes'
+ it_behaves_like 'referencing a milestone in a link href'
+
+ it 'does not support references by IID' do
+ doc = reference_filter("See #{Milestone.reference_prefix}#{milestone.iid}")
+
+ expect(doc.css('a')).to be_empty
+ end
+
+ it 'does not support references by link' do
+ doc = reference_filter("See #{urls.milestone_url(milestone)}")
+
+ expect(doc.css('a').first.text).to eq(urls.milestone_url(milestone))
+ end
+
+ it 'does not support cross-project references' do
+ another_group = create(:group)
+ another_project = create(:project, :public, group: group)
+ project_reference = another_project.to_reference(project)
+
+ milestone.update!(group: another_group)
+
+ doc = reference_filter("See #{project_reference}#{reference}")
+
+ expect(doc.css('a')).to be_empty
+ end
+ end
end
diff --git a/spec/lib/banzai/filter/redactor_filter_spec.rb b/spec/lib/banzai/filter/redactor_filter_spec.rb
index fb6b81d4f10..68643effb66 100644
--- a/spec/lib/banzai/filter/redactor_filter_spec.rb
+++ b/spec/lib/banzai/filter/redactor_filter_spec.rb
@@ -17,7 +17,7 @@ describe Banzai::Filter::RedactorFilter do
it 'skips when the skip_redaction flag is set' do
user = create(:user)
- project = create(:empty_project)
+ project = create(:project)
link = reference_link(project: project.id, reference_type: 'test')
doc = filter(link, current_user: user, skip_redaction: true)
@@ -45,7 +45,7 @@ describe Banzai::Filter::RedactorFilter do
it 'allows permitted Project references' do
user = create(:user)
- project = create(:empty_project)
+ project = create(:project)
project.team << [user, :master]
link = reference_link(project: project.id, reference_type: 'test')
@@ -62,7 +62,7 @@ describe Banzai::Filter::RedactorFilter do
it 'removes unpermitted references' do
user = create(:user)
- project = create(:empty_project)
+ project = create(:project)
link = reference_link(project: project.id, reference_type: 'test')
doc = filter(link, current_user: user)
@@ -82,7 +82,7 @@ describe Banzai::Filter::RedactorFilter do
context 'for confidential issues' do
it 'removes references for non project members' do
non_member = create(:user)
- project = create(:empty_project, :public)
+ project = create(:project, :public)
issue = create(:issue, :confidential, project: project)
link = reference_link(project: project.id, issue: issue.id, reference_type: 'issue')
@@ -93,7 +93,7 @@ describe Banzai::Filter::RedactorFilter do
it 'removes references for project members with guest role' do
member = create(:user)
- project = create(:empty_project, :public)
+ project = create(:project, :public)
project.team << [member, :guest]
issue = create(:issue, :confidential, project: project)
@@ -105,7 +105,7 @@ describe Banzai::Filter::RedactorFilter do
it 'allows references for author' do
author = create(:user)
- project = create(:empty_project, :public)
+ project = create(:project, :public)
issue = create(:issue, :confidential, project: project, author: author)
link = reference_link(project: project.id, issue: issue.id, reference_type: 'issue')
@@ -116,7 +116,7 @@ describe Banzai::Filter::RedactorFilter do
it 'allows references for assignee' do
assignee = create(:user)
- project = create(:empty_project, :public)
+ project = create(:project, :public)
issue = create(:issue, :confidential, project: project, assignees: [assignee])
link = reference_link(project: project.id, issue: issue.id, reference_type: 'issue')
@@ -127,7 +127,7 @@ describe Banzai::Filter::RedactorFilter do
it 'allows references for project members' do
member = create(:user)
- project = create(:empty_project, :public)
+ project = create(:project, :public)
project.team << [member, :developer]
issue = create(:issue, :confidential, project: project)
@@ -139,7 +139,7 @@ describe Banzai::Filter::RedactorFilter do
it 'allows references for admin' do
admin = create(:admin)
- project = create(:empty_project, :public)
+ project = create(:project, :public)
issue = create(:issue, :confidential, project: project)
link = reference_link(project: project.id, issue: issue.id, reference_type: 'issue')
@@ -151,7 +151,7 @@ describe Banzai::Filter::RedactorFilter do
it 'allows references for non confidential issues' do
user = create(:user)
- project = create(:empty_project, :public)
+ project = create(:project, :public)
issue = create(:issue, project: project)
link = reference_link(project: project.id, issue: issue.id, reference_type: 'issue')
diff --git a/spec/lib/banzai/filter/reference_filter_spec.rb b/spec/lib/banzai/filter/reference_filter_spec.rb
index b9ca68e8935..f96b6c83b0a 100644
--- a/spec/lib/banzai/filter/reference_filter_spec.rb
+++ b/spec/lib/banzai/filter/reference_filter_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Banzai::Filter::ReferenceFilter do
- let(:project) { build(:project) }
+ let(:project) { build_stubbed(:project) }
describe '#each_node' do
it 'iterates over the nodes in a document' do
diff --git a/spec/lib/banzai/filter/relative_link_filter_spec.rb b/spec/lib/banzai/filter/relative_link_filter_spec.rb
index ddebf2264d9..08beede62db 100644
--- a/spec/lib/banzai/filter/relative_link_filter_spec.rb
+++ b/spec/lib/banzai/filter/relative_link_filter_spec.rb
@@ -26,7 +26,7 @@ describe Banzai::Filter::RelativeLinkFilter do
end
let(:project) { create(:project, :repository) }
- let(:project_path) { project.path_with_namespace }
+ let(:project_path) { project.full_path }
let(:ref) { 'markdown' }
let(:commit) { project.commit(ref) }
let(:project_wiki) { nil }
@@ -56,7 +56,7 @@ describe Banzai::Filter::RelativeLinkFilter do
end
context 'without a repository' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
include_examples :preserve_unchanged
end
diff --git a/spec/lib/banzai/filter/snippet_reference_filter_spec.rb b/spec/lib/banzai/filter/snippet_reference_filter_spec.rb
index 5f548888223..90ac4c7b238 100644
--- a/spec/lib/banzai/filter/snippet_reference_filter_spec.rb
+++ b/spec/lib/banzai/filter/snippet_reference_filter_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe Banzai::Filter::SnippetReferenceFilter do
include FilterSpecHelper
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:snippet) { create(:project_snippet, project: project) }
let(:reference) { snippet.to_reference }
@@ -81,9 +81,9 @@ describe Banzai::Filter::SnippetReferenceFilter do
context 'cross-project / cross-namespace complete reference' do
let(:namespace) { create(:namespace) }
- let(:project2) { create(:empty_project, :public, namespace: namespace) }
+ let(:project2) { create(:project, :public, namespace: namespace) }
let!(:snippet) { create(:project_snippet, project: project2) }
- let(:reference) { "#{project2.path_with_namespace}$#{snippet.id}" }
+ let(:reference) { "#{project2.full_path}$#{snippet.id}" }
it 'links to a valid reference' do
doc = reference_filter("See #{reference}")
@@ -113,10 +113,10 @@ describe Banzai::Filter::SnippetReferenceFilter do
context 'cross-project / same-namespace complete reference' do
let(:namespace) { create(:namespace) }
- let(:project) { create(:empty_project, :public, namespace: namespace) }
- let(:project2) { create(:empty_project, :public, namespace: namespace) }
+ let(:project) { create(:project, :public, namespace: namespace) }
+ let(:project2) { create(:project, :public, namespace: namespace) }
let!(:snippet) { create(:project_snippet, project: project2) }
- let(:reference) { "#{project2.path_with_namespace}$#{snippet.id}" }
+ let(:reference) { "#{project2.full_path}$#{snippet.id}" }
it 'links to a valid reference' do
doc = reference_filter("See #{reference}")
@@ -146,8 +146,8 @@ describe Banzai::Filter::SnippetReferenceFilter do
context 'cross-project shorthand reference' do
let(:namespace) { create(:namespace) }
- let(:project) { create(:empty_project, :public, namespace: namespace) }
- let(:project2) { create(:empty_project, :public, namespace: namespace) }
+ let(:project) { create(:project, :public, namespace: namespace) }
+ let(:project2) { create(:project, :public, namespace: namespace) }
let!(:snippet) { create(:project_snippet, project: project2) }
let(:reference) { "#{project2.path}$#{snippet.id}" }
@@ -179,7 +179,7 @@ describe Banzai::Filter::SnippetReferenceFilter do
context 'cross-project URL reference' do
let(:namespace) { create(:namespace, name: 'cross-reference') }
- let(:project2) { create(:empty_project, :public, namespace: namespace) }
+ let(:project2) { create(:project, :public, namespace: namespace) }
let(:snippet) { create(:project_snippet, project: project2) }
let(:reference) { urls.project_snippet_url(project2, snippet) }
diff --git a/spec/lib/banzai/filter/upload_link_filter_spec.rb b/spec/lib/banzai/filter/upload_link_filter_spec.rb
index 3bc9635b50e..60a88e903ef 100644
--- a/spec/lib/banzai/filter/upload_link_filter_spec.rb
+++ b/spec/lib/banzai/filter/upload_link_filter_spec.rb
@@ -29,7 +29,7 @@ describe Banzai::Filter::UploadLinkFilter do
%(<div><a href="#{path}">#{path}</a></div>)
end
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
shared_examples :preserve_unchanged do
it 'does not modify any relative URL in anchor' do
@@ -52,21 +52,21 @@ describe Banzai::Filter::UploadLinkFilter do
it 'rebuilds relative URL for a link' do
doc = filter(link('/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg'))
expect(doc.at_css('a')['href'])
- .to eq "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg"
+ .to eq "#{Gitlab.config.gitlab.url}/#{project.full_path}/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg"
doc = filter(nested_link('/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg'))
expect(doc.at_css('a')['href'])
- .to eq "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg"
+ .to eq "#{Gitlab.config.gitlab.url}/#{project.full_path}/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg"
end
it 'rebuilds relative URL for an image' do
doc = filter(image('/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg'))
expect(doc.at_css('img')['src'])
- .to eq "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg"
+ .to eq "#{Gitlab.config.gitlab.url}/#{project.full_path}/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg"
doc = filter(nested_image('/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg'))
expect(doc.at_css('img')['src'])
- .to eq "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg"
+ .to eq "#{Gitlab.config.gitlab.url}/#{project.full_path}/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg"
end
it 'does not modify absolute URL' do
@@ -85,7 +85,7 @@ describe Banzai::Filter::UploadLinkFilter do
.to receive(:image?).with(path).and_return(true)
doc = filter(image(escaped))
- expect(doc.at_css('img')['src']).to match "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/uploads/%ED%95%9C%EA%B8%80.png"
+ expect(doc.at_css('img')['src']).to match "#{Gitlab.config.gitlab.url}/#{project.full_path}/uploads/%ED%95%9C%EA%B8%80.png"
end
end
diff --git a/spec/lib/banzai/filter/user_reference_filter_spec.rb b/spec/lib/banzai/filter/user_reference_filter_spec.rb
index 7ea9df5eda5..34dac1db69a 100644
--- a/spec/lib/banzai/filter/user_reference_filter_spec.rb
+++ b/spec/lib/banzai/filter/user_reference_filter_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe Banzai::Filter::UserReferenceFilter do
include FilterSpecHelper
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:user) { create(:user) }
let(:reference) { user.to_reference }
diff --git a/spec/lib/banzai/filter/wiki_link_filter_spec.rb b/spec/lib/banzai/filter/wiki_link_filter_spec.rb
index ceafd12a68e..9596f004052 100644
--- a/spec/lib/banzai/filter/wiki_link_filter_spec.rb
+++ b/spec/lib/banzai/filter/wiki_link_filter_spec.rb
@@ -4,7 +4,7 @@ describe Banzai::Filter::WikiLinkFilter do
include FilterSpecHelper
let(:namespace) { build_stubbed(:namespace, name: "wiki_link_ns") }
- let(:project) { build_stubbed(:empty_project, :public, name: "wiki_link_project", namespace: namespace) }
+ let(:project) { build_stubbed(:project, :public, name: "wiki_link_project", namespace: namespace) }
let(:user) { double }
let(:wiki) { ProjectWiki.new(project, user) }
diff --git a/spec/lib/banzai/issuable_extractor_spec.rb b/spec/lib/banzai/issuable_extractor_spec.rb
index 728271e757b..69763476dac 100644
--- a/spec/lib/banzai/issuable_extractor_spec.rb
+++ b/spec/lib/banzai/issuable_extractor_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Banzai::IssuableExtractor do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:user) { create(:user) }
let(:extractor) { described_class.new(project, user) }
let(:issue) { create(:issue, project: project) }
diff --git a/spec/lib/banzai/object_renderer_spec.rb b/spec/lib/banzai/object_renderer_spec.rb
index dd2674f9f20..7f5d481c36c 100644
--- a/spec/lib/banzai/object_renderer_spec.rb
+++ b/spec/lib/banzai/object_renderer_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Banzai::ObjectRenderer do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:user) { project.owner }
let(:renderer) { described_class.new(project, user, custom_value: 'value') }
let(:object) { Note.new(note: 'hello', note_html: '<p dir="auto">hello</p>', cached_markdown_version: CacheMarkdownField::CACHE_VERSION) }
@@ -28,7 +28,7 @@ describe Banzai::ObjectRenderer do
it 'passes context to PostProcessPipeline' do
another_user = create(:user)
- another_project = create(:empty_project)
+ another_project = create(:project)
object = Note.new(
note: 'hello',
note_html: 'hello',
diff --git a/spec/lib/banzai/pipeline/full_pipeline_spec.rb b/spec/lib/banzai/pipeline/full_pipeline_spec.rb
index 2501b638774..e9c7a2f352e 100644
--- a/spec/lib/banzai/pipeline/full_pipeline_spec.rb
+++ b/spec/lib/banzai/pipeline/full_pipeline_spec.rb
@@ -2,7 +2,7 @@ require 'rails_helper'
describe Banzai::Pipeline::FullPipeline do
describe 'References' do
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:issue) { create(:issue, project: project) }
it 'handles markdown inside a reference' do
diff --git a/spec/lib/banzai/pipeline/gfm_pipeline_spec.rb b/spec/lib/banzai/pipeline/gfm_pipeline_spec.rb
index 601ffbb5456..75413596431 100644
--- a/spec/lib/banzai/pipeline/gfm_pipeline_spec.rb
+++ b/spec/lib/banzai/pipeline/gfm_pipeline_spec.rb
@@ -36,7 +36,7 @@ describe Banzai::Pipeline::GfmPipeline do
end
it 'parses cross-project references to regular issues' do
- other_project = create(:empty_project, :public)
+ other_project = create(:project, :public)
issue = create(:issue, project: other_project)
markdown = issue.to_reference(project, full: true)
@@ -74,7 +74,7 @@ describe Banzai::Pipeline::GfmPipeline do
end
it 'parses cross-project references to regular issues' do
- other_project = create(:empty_project, :public)
+ other_project = create(:project, :public)
issue = create(:issue, project: other_project)
markdown = issue.to_reference(project, full: true)
diff --git a/spec/lib/banzai/pipeline/wiki_pipeline_spec.rb b/spec/lib/banzai/pipeline/wiki_pipeline_spec.rb
index ac9bde6baf1..88ae4c1e07a 100644
--- a/spec/lib/banzai/pipeline/wiki_pipeline_spec.rb
+++ b/spec/lib/banzai/pipeline/wiki_pipeline_spec.rb
@@ -53,7 +53,7 @@ describe Banzai::Pipeline::WikiPipeline do
describe "Links" do
let(:namespace) { create(:namespace, name: "wiki_link_ns") }
- let(:project) { create(:empty_project, :public, name: "wiki_link_project", namespace: namespace) }
+ let(:project) { create(:project, :public, name: "wiki_link_project", namespace: namespace) }
let(:project_wiki) { ProjectWiki.new(project, double(:user)) }
let(:page) { build(:wiki_page, wiki: project_wiki, page: OpenStruct.new(url_path: 'nested/twice/start-page')) }
diff --git a/spec/lib/banzai/redactor_spec.rb b/spec/lib/banzai/redactor_spec.rb
index 81ae5685b10..2424c3fdc66 100644
--- a/spec/lib/banzai/redactor_spec.rb
+++ b/spec/lib/banzai/redactor_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe Banzai::Redactor do
let(:user) { build(:user) }
- let(:project) { build(:empty_project) }
+ let(:project) { build(:project) }
let(:redactor) { described_class.new(project, user) }
describe '#redact' do
diff --git a/spec/lib/banzai/reference_parser/base_parser_spec.rb b/spec/lib/banzai/reference_parser/base_parser_spec.rb
index 0bf45329657..6175d4c4ca9 100644
--- a/spec/lib/banzai/reference_parser/base_parser_spec.rb
+++ b/spec/lib/banzai/reference_parser/base_parser_spec.rb
@@ -4,7 +4,7 @@ describe Banzai::ReferenceParser::BaseParser do
include ReferenceParserHelpers
let(:user) { create(:user) }
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
subject do
klass = Class.new(described_class) do
diff --git a/spec/lib/banzai/reference_parser/commit_parser_spec.rb b/spec/lib/banzai/reference_parser/commit_parser_spec.rb
index 69bf28cdf85..3505659c2c3 100644
--- a/spec/lib/banzai/reference_parser/commit_parser_spec.rb
+++ b/spec/lib/banzai/reference_parser/commit_parser_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe Banzai::ReferenceParser::CommitParser do
include ReferenceParserHelpers
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:user) { create(:user) }
subject { described_class.new(project, user) }
let(:link) { empty_html_link }
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 b384a59bfb4..21813177deb 100644
--- a/spec/lib/banzai/reference_parser/commit_range_parser_spec.rb
+++ b/spec/lib/banzai/reference_parser/commit_range_parser_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe Banzai::ReferenceParser::CommitRangeParser do
include ReferenceParserHelpers
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:user) { create(:user) }
subject { described_class.new(project, user) }
let(:link) { empty_html_link }
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 a3256afdbb1..25969b65168 100644
--- a/spec/lib/banzai/reference_parser/external_issue_parser_spec.rb
+++ b/spec/lib/banzai/reference_parser/external_issue_parser_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe Banzai::ReferenceParser::ExternalIssueParser do
include ReferenceParserHelpers
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:user) { create(:user) }
subject { described_class.new(project, user) }
let(:link) { empty_html_link }
diff --git a/spec/lib/banzai/reference_parser/issue_parser_spec.rb b/spec/lib/banzai/reference_parser/issue_parser_spec.rb
index 94b989fe91d..23dbe2b6238 100644
--- a/spec/lib/banzai/reference_parser/issue_parser_spec.rb
+++ b/spec/lib/banzai/reference_parser/issue_parser_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe Banzai::ReferenceParser::IssueParser do
include ReferenceParserHelpers
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:user) { create(:user) }
let(:issue) { create(:issue, project: project) }
let(:link) { empty_html_link }
diff --git a/spec/lib/banzai/reference_parser/label_parser_spec.rb b/spec/lib/banzai/reference_parser/label_parser_spec.rb
index cf1b2a92195..b700161d6c2 100644
--- a/spec/lib/banzai/reference_parser/label_parser_spec.rb
+++ b/spec/lib/banzai/reference_parser/label_parser_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe Banzai::ReferenceParser::LabelParser do
include ReferenceParserHelpers
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:user) { create(:user) }
let(:label) { create(:label, project: project) }
subject { described_class.new(project, user) }
diff --git a/spec/lib/banzai/reference_parser/milestone_parser_spec.rb b/spec/lib/banzai/reference_parser/milestone_parser_spec.rb
index 2cfcafa8798..7dacdf8d629 100644
--- a/spec/lib/banzai/reference_parser/milestone_parser_spec.rb
+++ b/spec/lib/banzai/reference_parser/milestone_parser_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe Banzai::ReferenceParser::MilestoneParser do
include ReferenceParserHelpers
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:user) { create(:user) }
let(:milestone) { create(:milestone, project: project) }
subject { described_class.new(project, user) }
diff --git a/spec/lib/banzai/reference_parser/snippet_parser_spec.rb b/spec/lib/banzai/reference_parser/snippet_parser_spec.rb
index c6d0b7be254..69ec3f66aa8 100644
--- a/spec/lib/banzai/reference_parser/snippet_parser_spec.rb
+++ b/spec/lib/banzai/reference_parser/snippet_parser_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe Banzai::ReferenceParser::SnippetParser do
include ReferenceParserHelpers
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:user) { create(:user) }
let(:external_user) { create(:user, :external) }
diff --git a/spec/lib/banzai/reference_parser/user_parser_spec.rb b/spec/lib/banzai/reference_parser/user_parser_spec.rb
index 64f2b607d7c..e49726aca6c 100644
--- a/spec/lib/banzai/reference_parser/user_parser_spec.rb
+++ b/spec/lib/banzai/reference_parser/user_parser_spec.rb
@@ -5,7 +5,7 @@ describe Banzai::ReferenceParser::UserParser do
let(:group) { create(:group) }
let(:user) { create(:user) }
- let(:project) { create(:empty_project, :public, group: group, creator: user) }
+ let(:project) { create(:project, :public, group: group, creator: user) }
subject { described_class.new(project, user) }
let(:link) { empty_html_link }
@@ -125,7 +125,7 @@ describe Banzai::ReferenceParser::UserParser do
end
it 'returns the nodes if the user can read the project' do
- other_project = create(:empty_project, :public)
+ other_project = create(:project, :public)
link['data-project'] = other_project.id.to_s
@@ -137,7 +137,7 @@ describe Banzai::ReferenceParser::UserParser do
end
it 'returns an empty Array if the user can not read the project' do
- other_project = create(:empty_project, :public)
+ other_project = create(:project, :public)
link['data-project'] = other_project.id.to_s
@@ -161,7 +161,7 @@ describe Banzai::ReferenceParser::UserParser do
describe '#nodes_user_can_reference' do
context 'when the link has a data-author attribute' do
it 'returns the nodes when the user is a member of the project' do
- other_project = create(:empty_project)
+ other_project = create(:project)
other_project.team << [user, :developer]
link['data-project'] = other_project.id.to_s
@@ -178,7 +178,7 @@ describe Banzai::ReferenceParser::UserParser do
end
it 'returns an empty Array when the user could not be found' do
- other_project = create(:empty_project)
+ other_project = create(:project)
link['data-project'] = other_project.id.to_s
link['data-author'] = ''
@@ -187,7 +187,7 @@ describe Banzai::ReferenceParser::UserParser do
end
it 'returns an empty Array when the user is not a team member' do
- other_project = create(:empty_project)
+ other_project = create(:project)
link['data-project'] = other_project.id.to_s
link['data-author'] = user.id.to_s
diff --git a/spec/lib/bitbucket/paginator_spec.rb b/spec/lib/bitbucket/paginator_spec.rb
index 2c972da682e..bdf10a5e2a2 100644
--- a/spec/lib/bitbucket/paginator_spec.rb
+++ b/spec/lib/bitbucket/paginator_spec.rb
@@ -15,7 +15,7 @@ describe Bitbucket::Paginator do
expect(paginator.items).to match(['item_2'])
allow(paginator).to receive(:fetch_next_page).and_return(nil)
- expect{ paginator.items }.to raise_error(StopIteration)
+ expect { paginator.items }.to raise_error(StopIteration)
end
end
end
diff --git a/spec/lib/ci/charts_spec.rb b/spec/lib/ci/charts_spec.rb
index 8e2d2724426..f0769deef21 100644
--- a/spec/lib/ci/charts_spec.rb
+++ b/spec/lib/ci/charts_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe Ci::Charts do
context "pipeline_times" do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:chart) { Ci::Charts::PipelineTime.new(project) }
subject { chart.pipeline_times }
diff --git a/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb b/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb
index ed571a2ba05..ee28387cd48 100644
--- a/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb
+++ b/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb
@@ -1323,11 +1323,11 @@ EOT
describe "Error handling" do
it "fails to parse YAML" do
- expect{GitlabCiYamlProcessor.new("invalid: yaml: test")}.to raise_error(Psych::SyntaxError)
+ expect {GitlabCiYamlProcessor.new("invalid: yaml: test")}.to raise_error(Psych::SyntaxError)
end
it "indicates that object is invalid" do
- expect{GitlabCiYamlProcessor.new("invalid_yaml")}.to raise_error(GitlabCiYamlProcessor::ValidationError)
+ expect {GitlabCiYamlProcessor.new("invalid_yaml")}.to raise_error(GitlabCiYamlProcessor::ValidationError)
end
it "returns errors if tags parameter is invalid" do
diff --git a/spec/lib/constraints/project_url_constrainer_spec.rb b/spec/lib/constraints/project_url_constrainer_spec.rb
index e4b5dfc574a..92331eb2e5d 100644
--- a/spec/lib/constraints/project_url_constrainer_spec.rb
+++ b/spec/lib/constraints/project_url_constrainer_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe ProjectUrlConstrainer do
- let!(:project) { create(:empty_project) }
+ let!(:project) { create(:project) }
let!(:namespace) { project.namespace }
describe '#matches?' do
diff --git a/spec/lib/container_registry/blob_spec.rb b/spec/lib/container_registry/blob_spec.rb
index 175fd2e7e13..c73faa55513 100644
--- a/spec/lib/container_registry/blob_spec.rb
+++ b/spec/lib/container_registry/blob_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe ContainerRegistry::Blob do
let(:group) { create(:group, name: 'group') }
- let(:project) { create(:empty_project, path: 'test', group: group) }
+ let(:project) { create(:project, path: 'test', group: group) }
let(:repository) do
create(:container_repository, name: 'image',
diff --git a/spec/lib/container_registry/path_spec.rb b/spec/lib/container_registry/path_spec.rb
index c2bcb54210b..84cacdd3f0d 100644
--- a/spec/lib/container_registry/path_spec.rb
+++ b/spec/lib/container_registry/path_spec.rb
@@ -90,7 +90,7 @@ describe ContainerRegistry::Path do
describe '#has_repository?' do
context 'when project exists' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:path) { "#{project.full_path}/my/image" }
context 'when path already has matching repository' do
@@ -123,8 +123,8 @@ describe ContainerRegistry::Path do
let(:path) { 'some_group/some_project' }
before do
- create(:empty_project, group: group, name: 'some_project')
- create(:empty_project, name: 'some_project')
+ create(:project, group: group, name: 'some_project')
+ create(:project, name: 'some_project')
end
it 'returns a correct project' do
@@ -142,7 +142,7 @@ describe ContainerRegistry::Path do
context 'when matching multi-level path' do
let(:project) do
- create(:empty_project, group: group, name: 'some_project')
+ create(:project, group: group, name: 'some_project')
end
context 'when using the zero-level path' do
@@ -192,7 +192,7 @@ describe ContainerRegistry::Path do
let(:group) { create(:group, path: 'Some_Group') }
before do
- create(:empty_project, group: group, name: 'some_project')
+ create(:project, group: group, name: 'some_project')
end
context 'when project path equal repository path' do
@@ -235,7 +235,7 @@ describe ContainerRegistry::Path do
let(:group) { create(:group, path: 'SomeGroup') }
before do
- create(:empty_project, group: group, name: 'MyProject')
+ create(:project, group: group, name: 'MyProject')
end
it 'returns downcased project path' do
diff --git a/spec/lib/container_registry/tag_spec.rb b/spec/lib/container_registry/tag_spec.rb
index cb4ae3be525..e76463b5e7c 100644
--- a/spec/lib/container_registry/tag_spec.rb
+++ b/spec/lib/container_registry/tag_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe ContainerRegistry::Tag do
let(:group) { create(:group, name: 'group') }
- let(:project) { create(:project, path: 'test', group: group) }
+ let(:project) { create(:project, :repository, path: 'test', group: group) }
let(:repository) do
create(:container_repository, name: '', project: project)
diff --git a/spec/lib/event_filter_spec.rb b/spec/lib/event_filter_spec.rb
index b1366e74802..87ae6b6cf01 100644
--- a/spec/lib/event_filter_spec.rb
+++ b/spec/lib/event_filter_spec.rb
@@ -3,9 +3,9 @@ require 'spec_helper'
describe EventFilter do
describe '#apply_filter' do
let(:source_user) { create(:user) }
- let!(:public_project) { create(:empty_project, :public) }
+ let!(:public_project) { create(:project, :public) }
- let!(:push_event) { create(:event, :pushed, project: public_project, target: public_project, author: source_user) }
+ let!(:push_event) { create(:push_event, project: public_project, author: source_user) }
let!(:merged_event) { create(:event, :merged, project: public_project, target: public_project, author: source_user) }
let!(:created_event) { create(:event, :created, project: public_project, target: public_project, author: source_user) }
let!(:updated_event) { create(:event, :updated, project: public_project, target: public_project, author: source_user) }
diff --git a/spec/lib/extracts_path_spec.rb b/spec/lib/extracts_path_spec.rb
index 9b89f47ae7e..e13406d1972 100644
--- a/spec/lib/extracts_path_spec.rb
+++ b/spec/lib/extracts_path_spec.rb
@@ -14,7 +14,7 @@ describe ExtractsPath do
repo = double(ref_names: ['master', 'foo/bar/baz', 'v1.0.0', 'v2.0.0',
'release/app', 'release/app/v1.0.0'])
allow(project).to receive(:repository).and_return(repo)
- allow(project).to receive(:path_with_namespace)
+ allow(project).to receive(:full_path)
.and_return('gitlab/gitlab-ci')
allow(request).to receive(:format=)
end
@@ -29,7 +29,7 @@ describe ExtractsPath do
it "log tree path has no escape sequences" do
assign_ref_vars
- expect(@logs_path).to eq("/#{@project.path_with_namespace}/refs/#{ref}/logs_tree/files/ruby/popen.rb")
+ expect(@logs_path).to eq("/#{@project.full_path}/refs/#{ref}/logs_tree/files/ruby/popen.rb")
end
context 'ref contains %20' do
@@ -56,7 +56,7 @@ describe ExtractsPath do
context 'subclass overrides get_id' do
it 'uses ref returned by get_id' do
- allow_any_instance_of(self.class).to receive(:get_id){ '38008cb17ce1466d8fec2dfa6f6ab8dcfe5cf49e' }
+ allow_any_instance_of(self.class).to receive(:get_id) { '38008cb17ce1466d8fec2dfa6f6ab8dcfe5cf49e' }
assign_ref_vars
diff --git a/spec/lib/gitlab/allowable_spec.rb b/spec/lib/gitlab/allowable_spec.rb
index 87733d53e92..9d80d480b52 100644
--- a/spec/lib/gitlab/allowable_spec.rb
+++ b/spec/lib/gitlab/allowable_spec.rb
@@ -9,7 +9,7 @@ describe Gitlab::Allowable do
let(:user) { create(:user) }
context 'when user is allowed to do something' do
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
it 'reports correct ability to perform action' do
expect(subject.can?(user, :read_project, project)).to be true
@@ -17,7 +17,7 @@ describe Gitlab::Allowable do
end
context 'when user is not allowed to do something' do
- let(:project) { create(:empty_project, :private) }
+ let(:project) { create(:project, :private) }
it 'reports correct ability to perform action' do
expect(subject.can?(user, :read_project, project)).to be false
diff --git a/spec/lib/gitlab/auth_spec.rb b/spec/lib/gitlab/auth_spec.rb
index a9db0d5164d..4a498e79c87 100644
--- a/spec/lib/gitlab/auth_spec.rb
+++ b/spec/lib/gitlab/auth_spec.rb
@@ -65,7 +65,7 @@ describe Gitlab::Auth do
end
it 'recognizes other ci services' do
- project = create(:empty_project)
+ project = create(:project)
project.create_drone_ci_service(active: true)
project.drone_ci_service.update(token: 'token')
@@ -313,7 +313,8 @@ describe Gitlab::Auth do
def full_authentication_abilities
read_authentication_abilities + [
:push_code,
- :create_container_image
+ :create_container_image,
+ :admin_container_image
]
end
end
diff --git a/spec/lib/gitlab/background_migration/deserialize_merge_request_diffs_and_commits_spec.rb b/spec/lib/gitlab/background_migration/deserialize_merge_request_diffs_and_commits_spec.rb
new file mode 100644
index 00000000000..7cd2ce82eda
--- /dev/null
+++ b/spec/lib/gitlab/background_migration/deserialize_merge_request_diffs_and_commits_spec.rb
@@ -0,0 +1,199 @@
+require 'spec_helper'
+
+describe Gitlab::BackgroundMigration::DeserializeMergeRequestDiffsAndCommits do
+ describe '#perform' do
+ set(:merge_request) { create(:merge_request) }
+ set(:merge_request_diff) { merge_request.merge_request_diff }
+ let(:updated_merge_request_diff) { MergeRequestDiff.find(merge_request_diff.id) }
+
+ def diffs_to_hashes(diffs)
+ diffs.as_json(only: Gitlab::Git::Diff::SERIALIZE_KEYS).map(&:with_indifferent_access)
+ end
+
+ def quote_yaml(value)
+ MergeRequestDiff.connection.quote(YAML.dump(value))
+ end
+
+ def convert_to_yaml(merge_request_diff_id, commits, diffs)
+ MergeRequestDiff.where(id: merge_request_diff_id).update_all(
+ "st_commits = #{quote_yaml(commits)}, st_diffs = #{quote_yaml(diffs)}"
+ )
+ end
+
+ shared_examples 'updated MR diff' do
+ before do
+ convert_to_yaml(merge_request_diff.id, commits, diffs)
+
+ MergeRequestDiffCommit.delete_all
+ MergeRequestDiffFile.delete_all
+
+ subject.perform(merge_request_diff.id, merge_request_diff.id)
+ end
+
+ it 'creates correct entries in the merge_request_diff_commits table' do
+ expect(updated_merge_request_diff.merge_request_diff_commits.count).to eq(commits.count)
+ expect(updated_merge_request_diff.commits.map(&:to_hash)).to eq(commits)
+ end
+
+ it 'creates correct entries in the merge_request_diff_files table' do
+ expect(updated_merge_request_diff.merge_request_diff_files.count).to eq(expected_diffs.count)
+ expect(diffs_to_hashes(updated_merge_request_diff.raw_diffs)).to eq(expected_diffs)
+ end
+
+ it 'sets the st_commits and st_diffs columns to nil' do
+ expect(updated_merge_request_diff.st_commits_before_type_cast).to be_nil
+ expect(updated_merge_request_diff.st_diffs_before_type_cast).to be_nil
+ end
+ end
+
+ context 'when the diff IDs passed do not exist' do
+ it 'does not raise' do
+ expect { subject.perform(0, 0) }.not_to raise_exception
+ end
+ end
+
+ context 'when the merge request diff has no serialised commits or diffs' do
+ before do
+ merge_request_diff.update(st_commits: nil, st_diffs: nil)
+ end
+
+ it 'does not raise' do
+ expect { subject.perform(merge_request_diff.id, merge_request_diff.id) }
+ .not_to raise_exception
+ end
+ end
+
+ context 'processing multiple merge request diffs' do
+ let(:start_id) { described_class::MergeRequestDiff.minimum(:id) }
+ let(:stop_id) { described_class::MergeRequestDiff.maximum(:id) }
+
+ before do
+ merge_request.reload_diff(true)
+
+ convert_to_yaml(start_id, merge_request_diff.commits, merge_request_diff.diffs)
+ convert_to_yaml(stop_id, updated_merge_request_diff.commits, updated_merge_request_diff.diffs)
+
+ MergeRequestDiffCommit.delete_all
+ MergeRequestDiffFile.delete_all
+ end
+
+ context 'when BUFFER_ROWS is exceeded' do
+ before do
+ stub_const("#{described_class}::BUFFER_ROWS", 1)
+ end
+
+ it 'updates and continues' do
+ expect(described_class::MergeRequestDiff).to receive(:transaction).twice
+
+ subject.perform(start_id, stop_id)
+ end
+ end
+
+ context 'when BUFFER_ROWS is not exceeded' do
+ it 'only updates once' do
+ expect(described_class::MergeRequestDiff).to receive(:transaction).once
+
+ subject.perform(start_id, stop_id)
+ end
+ end
+ end
+
+ context 'when the merge request diff update fails' do
+ before do
+ allow(described_class::MergeRequestDiff)
+ .to receive(:update_all).and_raise(ActiveRecord::Rollback)
+ end
+
+ it 'does not add any diff commits' do
+ expect { subject.perform(merge_request_diff.id, merge_request_diff.id) }
+ .not_to change { MergeRequestDiffCommit.count }
+ end
+
+ it 'does not add any diff files' do
+ expect { subject.perform(merge_request_diff.id, merge_request_diff.id) }
+ .not_to change { MergeRequestDiffFile.count }
+ end
+ end
+
+ context 'when the merge request diff has valid commits and diffs' do
+ let(:commits) { merge_request_diff.commits.map(&:to_hash) }
+ let(:diffs) { diffs_to_hashes(merge_request_diff.merge_request_diff_files) }
+ let(:expected_diffs) { diffs }
+
+ include_examples 'updated MR diff'
+ end
+
+ context 'when the merge request diffs do not have too_large set' do
+ let(:commits) { merge_request_diff.commits.map(&:to_hash) }
+ let(:expected_diffs) { diffs_to_hashes(merge_request_diff.merge_request_diff_files) }
+
+ let(:diffs) do
+ expected_diffs.map { |diff| diff.except(:too_large) }
+ end
+
+ include_examples 'updated MR diff'
+ end
+
+ context 'when the merge request diffs have binary content' do
+ let(:commits) { merge_request_diff.commits.map(&:to_hash) }
+ let(:expected_diffs) { diffs }
+
+ # The start of a PDF created by Illustrator
+ let(:binary_string) do
+ "\x25\x50\x44\x46\x2d\x31\x2e\x35\x0d\x25\xe2\xe3\xcf\xd3\x0d\x0a".force_encoding(Encoding::BINARY)
+ end
+
+ let(:diffs) do
+ [
+ {
+ 'diff' => binary_string,
+ 'new_path' => 'path',
+ 'old_path' => 'path',
+ 'a_mode' => '100644',
+ 'b_mode' => '100644',
+ 'new_file' => false,
+ 'renamed_file' => false,
+ 'deleted_file' => false,
+ 'too_large' => false
+ }
+ ]
+ end
+
+ include_examples 'updated MR diff'
+ end
+
+ context 'when the merge request diff has commits, but no diffs' do
+ let(:commits) { merge_request_diff.commits.map(&:to_hash) }
+ let(:diffs) { [] }
+ let(:expected_diffs) { diffs }
+
+ include_examples 'updated MR diff'
+ end
+
+ context 'when the merge request diffs have invalid content' do
+ let(:commits) { merge_request_diff.commits.map(&:to_hash) }
+ let(:diffs) { ['--broken-diff'] }
+ let(:expected_diffs) { [] }
+
+ include_examples 'updated MR diff'
+ end
+
+ context 'when the merge request diffs are Rugged::Patch instances' do
+ let(:commits) { merge_request_diff.commits.map(&:to_hash) }
+ let(:first_commit) { merge_request.project.repository.commit(merge_request_diff.head_commit_sha) }
+ let(:diffs) { first_commit.rugged_diff_from_parent.patches }
+ let(:expected_diffs) { [] }
+
+ include_examples 'updated MR diff'
+ end
+
+ context 'when the merge request diffs are Rugged::Diff::Delta instances' do
+ let(:commits) { merge_request_diff.commits.map(&:to_hash) }
+ let(:first_commit) { merge_request.project.repository.commit(merge_request_diff.head_commit_sha) }
+ let(:diffs) { first_commit.rugged_diff_from_parent.deltas }
+ let(:expected_diffs) { [] }
+
+ include_examples 'updated MR diff'
+ end
+ end
+end
diff --git a/spec/lib/gitlab/background_migration/migrate_events_to_push_event_payloads_spec.rb b/spec/lib/gitlab/background_migration/migrate_events_to_push_event_payloads_spec.rb
new file mode 100644
index 00000000000..87f45619e7a
--- /dev/null
+++ b/spec/lib/gitlab/background_migration/migrate_events_to_push_event_payloads_spec.rb
@@ -0,0 +1,423 @@
+require 'spec_helper'
+
+describe Gitlab::BackgroundMigration::MigrateEventsToPushEventPayloads::Event do
+ describe '#commit_title' do
+ it 'returns nil when there are no commits' do
+ expect(described_class.new.commit_title).to be_nil
+ end
+
+ it 'returns nil when there are commits without commit messages' do
+ event = described_class.new
+
+ allow(event).to receive(:commits).and_return([{ id: '123' }])
+
+ expect(event.commit_title).to be_nil
+ end
+
+ it 'returns the commit message when it is less than 70 characters long' do
+ event = described_class.new
+
+ allow(event).to receive(:commits).and_return([{ message: 'Hello world' }])
+
+ expect(event.commit_title).to eq('Hello world')
+ end
+
+ it 'returns the first line of a commit message if multiple lines are present' do
+ event = described_class.new
+
+ allow(event).to receive(:commits).and_return([{ message: "Hello\n\nworld" }])
+
+ expect(event.commit_title).to eq('Hello')
+ end
+
+ it 'truncates the commit to 70 characters when it is too long' do
+ event = described_class.new
+
+ allow(event).to receive(:commits).and_return([{ message: 'a' * 100 }])
+
+ expect(event.commit_title).to eq(('a' * 67) + '...')
+ end
+ end
+
+ describe '#commit_from_sha' do
+ it 'returns nil when pushing to a new ref' do
+ event = described_class.new
+
+ allow(event).to receive(:create?).and_return(true)
+
+ expect(event.commit_from_sha).to be_nil
+ end
+
+ it 'returns the ID of the first commit when pushing to an existing ref' do
+ event = described_class.new
+
+ allow(event).to receive(:create?).and_return(false)
+ allow(event).to receive(:data).and_return(before: '123')
+
+ expect(event.commit_from_sha).to eq('123')
+ end
+ end
+
+ describe '#commit_to_sha' do
+ it 'returns nil when removing an existing ref' do
+ event = described_class.new
+
+ allow(event).to receive(:remove?).and_return(true)
+
+ expect(event.commit_to_sha).to be_nil
+ end
+
+ it 'returns the ID of the last commit when pushing to an existing ref' do
+ event = described_class.new
+
+ allow(event).to receive(:remove?).and_return(false)
+ allow(event).to receive(:data).and_return(after: '123')
+
+ expect(event.commit_to_sha).to eq('123')
+ end
+ end
+
+ describe '#data' do
+ it 'returns the deserialized data' do
+ event = described_class.new(data: { before: '123' })
+
+ expect(event.data).to eq(before: '123')
+ end
+
+ it 'returns an empty hash when no data is present' do
+ event = described_class.new
+
+ expect(event.data).to eq({})
+ end
+ end
+
+ describe '#commits' do
+ it 'returns an Array of commits' do
+ event = described_class.new(data: { commits: [{ id: '123' }] })
+
+ expect(event.commits).to eq([{ id: '123' }])
+ end
+
+ it 'returns an empty array when no data is present' do
+ event = described_class.new
+
+ expect(event.commits).to eq([])
+ end
+ end
+
+ describe '#commit_count' do
+ it 'returns the number of commits' do
+ event = described_class.new(data: { total_commits_count: 2 })
+
+ expect(event.commit_count).to eq(2)
+ end
+
+ it 'returns 0 when no data is present' do
+ event = described_class.new
+
+ expect(event.commit_count).to eq(0)
+ end
+ end
+
+ describe '#ref' do
+ it 'returns the name of the ref' do
+ event = described_class.new(data: { ref: 'refs/heads/master' })
+
+ expect(event.ref).to eq('refs/heads/master')
+ end
+ end
+
+ describe '#trimmed_ref_name' do
+ it 'returns the trimmed ref name for a branch' do
+ event = described_class.new(data: { ref: 'refs/heads/master' })
+
+ expect(event.trimmed_ref_name).to eq('master')
+ end
+
+ it 'returns the trimmed ref name for a tag' do
+ event = described_class.new(data: { ref: 'refs/tags/v1.2' })
+
+ expect(event.trimmed_ref_name).to eq('v1.2')
+ end
+ end
+
+ describe '#create?' do
+ it 'returns true when creating a new ref' do
+ event = described_class.new(data: { before: described_class::BLANK_REF })
+
+ expect(event.create?).to eq(true)
+ end
+
+ it 'returns false when pushing to an existing ref' do
+ event = described_class.new(data: { before: '123' })
+
+ expect(event.create?).to eq(false)
+ end
+ end
+
+ describe '#remove?' do
+ it 'returns true when removing an existing ref' do
+ event = described_class.new(data: { after: described_class::BLANK_REF })
+
+ expect(event.remove?).to eq(true)
+ end
+
+ it 'returns false when pushing to an existing ref' do
+ event = described_class.new(data: { after: '123' })
+
+ expect(event.remove?).to eq(false)
+ end
+ end
+
+ describe '#push_action' do
+ let(:event) { described_class.new }
+
+ it 'returns :created when creating a new ref' do
+ allow(event).to receive(:create?).and_return(true)
+
+ expect(event.push_action).to eq(:created)
+ end
+
+ it 'returns :removed when removing an existing ref' do
+ allow(event).to receive(:create?).and_return(false)
+ allow(event).to receive(:remove?).and_return(true)
+
+ expect(event.push_action).to eq(:removed)
+ end
+
+ it 'returns :pushed when pushing to an existing ref' do
+ allow(event).to receive(:create?).and_return(false)
+ allow(event).to receive(:remove?).and_return(false)
+
+ expect(event.push_action).to eq(:pushed)
+ end
+ end
+
+ describe '#ref_type' do
+ let(:event) { described_class.new }
+
+ it 'returns :tag for a tag' do
+ allow(event).to receive(:ref).and_return('refs/tags/1.2')
+
+ expect(event.ref_type).to eq(:tag)
+ end
+
+ it 'returns :branch for a branch' do
+ allow(event).to receive(:ref).and_return('refs/heads/1.2')
+
+ expect(event.ref_type).to eq(:branch)
+ end
+ end
+end
+
+describe Gitlab::BackgroundMigration::MigrateEventsToPushEventPayloads do
+ let(:migration) { described_class.new }
+ let(:project) { create(:project_empty_repo) }
+ let(:author) { create(:user) }
+
+ # We can not rely on FactoryGirl as the state of Event may change in ways that
+ # the background migration does not expect, hence we use the Event class of
+ # the migration itself.
+ def create_push_event(project, author, data = nil)
+ klass = Gitlab::BackgroundMigration::MigrateEventsToPushEventPayloads::Event
+
+ klass.create!(
+ action: klass::PUSHED,
+ project_id: project.id,
+ author_id: author.id,
+ data: data
+ )
+ end
+
+ # The background migration relies on a temporary table, hence we're migrating
+ # to a specific version of the database where said table is still present.
+ before :all do
+ ActiveRecord::Migration.verbose = false
+
+ ActiveRecord::Migrator
+ .migrate(ActiveRecord::Migrator.migrations_paths, 20170608152748)
+ end
+
+ after :all do
+ ActiveRecord::Migrator.migrate(ActiveRecord::Migrator.migrations_paths)
+
+ ActiveRecord::Migration.verbose = true
+ end
+
+ describe '#perform' do
+ it 'returns if data should not be migrated' do
+ allow(migration).to receive(:migrate?).and_return(false)
+
+ expect(migration).not_to receive(:find_events)
+
+ migration.perform(1, 10)
+ end
+
+ it 'migrates the range of events if data is to be migrated' do
+ event1 = create_push_event(project, author, { commits: [] })
+ event2 = create_push_event(project, author, { commits: [] })
+
+ allow(migration).to receive(:migrate?).and_return(true)
+
+ expect(migration).to receive(:process_event).twice
+
+ migration.perform(event1.id, event2.id)
+ end
+ end
+
+ describe '#process_event' do
+ it 'processes a regular event' do
+ event = double(:event, push_event?: false)
+
+ expect(migration).to receive(:replicate_event)
+ expect(migration).not_to receive(:create_push_event_payload)
+
+ migration.process_event(event)
+ end
+
+ it 'processes a push event' do
+ event = double(:event, push_event?: true)
+
+ expect(migration).to receive(:replicate_event)
+ expect(migration).to receive(:create_push_event_payload)
+
+ migration.process_event(event)
+ end
+ end
+
+ describe '#replicate_event' do
+ it 'replicates the event to the "events_for_migration" table' do
+ event = create_push_event(
+ project,
+ author,
+ data: { commits: [] },
+ title: 'bla'
+ )
+
+ attributes = event
+ .attributes.with_indifferent_access.except(:title, :data)
+
+ expect(described_class::EventForMigration)
+ .to receive(:create!)
+ .with(attributes)
+
+ migration.replicate_event(event)
+ end
+ end
+
+ describe '#create_push_event_payload' do
+ let(:push_data) do
+ {
+ commits: [],
+ ref: 'refs/heads/master',
+ before: '156e0e9adc587a383a7eeb5b21ddecb9044768a8',
+ after: '0' * 40,
+ total_commits_count: 1
+ }
+ end
+
+ let(:event) do
+ create_push_event(project, author, push_data)
+ end
+
+ before do
+ # The foreign key in push_event_payloads at this point points to the
+ # "events_for_migration" table so we need to make sure a row exists in
+ # said table.
+ migration.replicate_event(event)
+ end
+
+ it 'creates a push event payload for an event' do
+ payload = migration.create_push_event_payload(event)
+
+ expect(PushEventPayload.count).to eq(1)
+ expect(payload.valid?).to eq(true)
+ end
+
+ it 'does not create push event payloads for removed events' do
+ allow(event).to receive(:id).and_return(-1)
+
+ payload = migration.create_push_event_payload(event)
+
+ expect(payload).to be_nil
+ expect(PushEventPayload.count).to eq(0)
+ end
+
+ it 'encodes and decodes the commit IDs from and to binary data' do
+ payload = migration.create_push_event_payload(event)
+ packed = migration.pack(push_data[:before])
+
+ expect(payload.commit_from).to eq(packed)
+ expect(payload.commit_to).to be_nil
+ end
+ end
+
+ describe '#find_events' do
+ it 'returns the events for the given ID range' do
+ event1 = create_push_event(project, author, { commits: [] })
+ event2 = create_push_event(project, author, { commits: [] })
+ event3 = create_push_event(project, author, { commits: [] })
+ events = migration.find_events(event1.id, event2.id)
+
+ expect(events.length).to eq(2)
+ expect(events.pluck(:id)).not_to include(event3.id)
+ end
+ end
+
+ describe '#migrate?' do
+ it 'returns true when data should be migrated' do
+ allow(described_class::Event)
+ .to receive(:table_exists?).and_return(true)
+
+ allow(described_class::PushEventPayload)
+ .to receive(:table_exists?).and_return(true)
+
+ allow(described_class::EventForMigration)
+ .to receive(:table_exists?).and_return(true)
+
+ expect(migration.migrate?).to eq(true)
+ end
+
+ it 'returns false if the "events" table does not exist' do
+ allow(described_class::Event)
+ .to receive(:table_exists?).and_return(false)
+
+ expect(migration.migrate?).to eq(false)
+ end
+
+ it 'returns false if the "push_event_payloads" table does not exist' do
+ allow(described_class::Event)
+ .to receive(:table_exists?).and_return(true)
+
+ allow(described_class::PushEventPayload)
+ .to receive(:table_exists?).and_return(false)
+
+ expect(migration.migrate?).to eq(false)
+ end
+
+ it 'returns false when the "events_for_migration" table does not exist' do
+ allow(described_class::Event)
+ .to receive(:table_exists?).and_return(true)
+
+ allow(described_class::PushEventPayload)
+ .to receive(:table_exists?).and_return(true)
+
+ allow(described_class::EventForMigration)
+ .to receive(:table_exists?).and_return(false)
+
+ expect(migration.migrate?).to eq(false)
+ end
+ end
+
+ describe '#pack' do
+ it 'packs a SHA1 into a 20 byte binary string' do
+ packed = migration.pack('156e0e9adc587a383a7eeb5b21ddecb9044768a8')
+
+ expect(packed.bytesize).to eq(20)
+ end
+
+ it 'returns nil if the input value is nil' do
+ expect(migration.pack(nil)).to be_nil
+ end
+ end
+end
diff --git a/spec/lib/gitlab/background_migration/migrate_system_uploads_to_new_folder_spec.rb b/spec/lib/gitlab/background_migration/migrate_system_uploads_to_new_folder_spec.rb
index a910fb105a5..59f69d1e4b1 100644
--- a/spec/lib/gitlab/background_migration/migrate_system_uploads_to_new_folder_spec.rb
+++ b/spec/lib/gitlab/background_migration/migrate_system_uploads_to_new_folder_spec.rb
@@ -9,7 +9,7 @@ describe Gitlab::BackgroundMigration::MigrateSystemUploadsToNewFolder do
describe '#perform' do
it 'renames the path of system-uploads', truncate: true do
- upload = create(:upload, model: create(:empty_project), path: 'uploads/system/project/avatar.jpg')
+ upload = create(:upload, model: create(:project), path: 'uploads/system/project/avatar.jpg')
migration.perform('uploads/system/', 'uploads/-/system/')
diff --git a/spec/lib/gitlab/background_migration/move_personal_snippet_files_spec.rb b/spec/lib/gitlab/background_migration/move_personal_snippet_files_spec.rb
new file mode 100644
index 00000000000..ee60e498b59
--- /dev/null
+++ b/spec/lib/gitlab/background_migration/move_personal_snippet_files_spec.rb
@@ -0,0 +1,72 @@
+require 'spec_helper'
+
+describe Gitlab::BackgroundMigration::MovePersonalSnippetFiles do
+ let(:test_dir) { File.join(Rails.root, 'tmp', 'tests', 'move_snippet_files_test') }
+ let(:old_uploads_dir) { File.join('uploads', 'system', 'personal_snippet') }
+ let(:new_uploads_dir) { File.join('uploads', '-', 'system', 'personal_snippet') }
+ let(:snippet) do
+ snippet = create(:personal_snippet)
+ create_upload_for_snippet(snippet)
+ snippet.update_attributes!(description: markdown_linking_file(snippet))
+ snippet
+ end
+
+ let(:migration) { described_class.new }
+
+ before do
+ allow(migration).to receive(:base_directory) { test_dir }
+ end
+
+ describe '#perform' do
+ it 'moves the file on the disk' do
+ expected_path = File.join(test_dir, new_uploads_dir, snippet.id.to_s, "secret#{snippet.id}", 'upload.txt')
+
+ migration.perform(old_uploads_dir, new_uploads_dir)
+
+ expect(File.exist?(expected_path)).to be_truthy
+ end
+
+ it 'updates the markdown of the snippet' do
+ expected_path = File.join(new_uploads_dir, snippet.id.to_s, "secret#{snippet.id}", 'upload.txt')
+ expected_markdown = "[an upload](#{expected_path})"
+
+ migration.perform(old_uploads_dir, new_uploads_dir)
+
+ expect(snippet.reload.description).to eq(expected_markdown)
+ end
+
+ it 'updates the markdown of notes' do
+ expected_path = File.join(new_uploads_dir, snippet.id.to_s, "secret#{snippet.id}", 'upload.txt')
+ expected_markdown = "with [an upload](#{expected_path})"
+
+ note = create(:note_on_personal_snippet, noteable: snippet, note: "with #{markdown_linking_file(snippet)}")
+
+ migration.perform(old_uploads_dir, new_uploads_dir)
+
+ expect(note.reload.note).to eq(expected_markdown)
+ end
+ end
+
+ def create_upload_for_snippet(snippet)
+ snippet_path = path_for_file_in_snippet(snippet)
+ path = File.join(old_uploads_dir, snippet.id.to_s, snippet_path)
+ absolute_path = File.join(test_dir, path)
+
+ FileUtils.mkdir_p(File.dirname(absolute_path))
+ FileUtils.touch(absolute_path)
+
+ create(:upload, model: snippet, path: snippet_path, uploader: PersonalFileUploader)
+ end
+
+ def path_for_file_in_snippet(snippet)
+ secret = "secret#{snippet.id}"
+ filename = 'upload.txt'
+
+ File.join(secret, filename)
+ end
+
+ def markdown_linking_file(snippet)
+ path = File.join(old_uploads_dir, snippet.id.to_s, path_for_file_in_snippet(snippet))
+ "[an upload](#{path})"
+ end
+end
diff --git a/spec/lib/gitlab/backup/repository_spec.rb b/spec/lib/gitlab/backup/repository_spec.rb
index db860b01ba4..535cce12780 100644
--- a/spec/lib/gitlab/backup/repository_spec.rb
+++ b/spec/lib/gitlab/backup/repository_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe Backup::Repository do
let(:progress) { StringIO.new }
- let!(:project) { create(:empty_project) }
+ let!(:project) { create(:project) }
before do
allow(progress).to receive(:puts)
@@ -60,4 +60,58 @@ describe Backup::Repository do
end
end
end
+
+ describe '#empty_repo?' do
+ context 'for a wiki' do
+ let(:wiki) { create(:project_wiki) }
+
+ context 'wiki repo has content' do
+ let!(:wiki_page) { create(:wiki_page, wiki: wiki) }
+
+ before do
+ wiki.repository.exists? # initial cache
+ end
+
+ context '`repository.exists?` is incorrectly cached as false' do
+ before do
+ repo = wiki.repository
+ repo.send(:cache).expire(:exists?)
+ repo.send(:cache).fetch(:exists?) { false }
+ repo.send(:instance_variable_set, :@exists, false)
+ end
+
+ it 'returns false, regardless of bad cache value' do
+ expect(described_class.new.send(:empty_repo?, wiki)).to be_falsey
+ end
+ end
+
+ context '`repository.exists?` is correctly cached as true' do
+ it 'returns false' do
+ expect(described_class.new.send(:empty_repo?, wiki)).to be_falsey
+ end
+ end
+ end
+
+ context 'wiki repo does not have content' do
+ context '`repository.exists?` is incorrectly cached as true' do
+ before do
+ repo = wiki.repository
+ repo.send(:cache).expire(:exists?)
+ repo.send(:cache).fetch(:exists?) { true }
+ repo.send(:instance_variable_set, :@exists, true)
+ end
+
+ it 'returns true, regardless of bad cache value' do
+ expect(described_class.new.send(:empty_repo?, wiki)).to be_truthy
+ end
+ end
+
+ context '`repository.exists?` is correctly cached as false' do
+ it 'returns true' do
+ expect(described_class.new.send(:empty_repo?, wiki)).to be_truthy
+ end
+ end
+ end
+ end
+ end
end
diff --git a/spec/lib/gitlab/badge/coverage/metadata_spec.rb b/spec/lib/gitlab/badge/coverage/metadata_spec.rb
index 5e93935ea37..74eaf7eaf8b 100644
--- a/spec/lib/gitlab/badge/coverage/metadata_spec.rb
+++ b/spec/lib/gitlab/badge/coverage/metadata_spec.rb
@@ -3,7 +3,7 @@ require 'lib/gitlab/badge/shared/metadata'
describe Gitlab::Badge::Coverage::Metadata do
let(:badge) do
- double(project: create(:empty_project), ref: 'feature', job: 'test')
+ double(project: create(:project), ref: 'feature', job: 'test')
end
let(:metadata) { described_class.new(badge) }
diff --git a/spec/lib/gitlab/badge/coverage/report_spec.rb b/spec/lib/gitlab/badge/coverage/report_spec.rb
index 1547bd3228c..da789bf3705 100644
--- a/spec/lib/gitlab/badge/coverage/report_spec.rb
+++ b/spec/lib/gitlab/badge/coverage/report_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Gitlab::Badge::Coverage::Report do
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:job_name) { nil }
let(:badge) do
diff --git a/spec/lib/gitlab/badge/pipeline/metadata_spec.rb b/spec/lib/gitlab/badge/pipeline/metadata_spec.rb
index d537ce8803c..9032a8e9016 100644
--- a/spec/lib/gitlab/badge/pipeline/metadata_spec.rb
+++ b/spec/lib/gitlab/badge/pipeline/metadata_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
require 'lib/gitlab/badge/shared/metadata'
describe Gitlab::Badge::Pipeline::Metadata do
- let(:badge) { double(project: create(:empty_project), ref: 'feature') }
+ let(:badge) { double(project: create(:project), ref: 'feature') }
let(:metadata) { described_class.new(badge) }
it_behaves_like 'badge metadata'
diff --git a/spec/lib/gitlab/bitbucket_import/importer_spec.rb b/spec/lib/gitlab/bitbucket_import/importer_spec.rb
index df66a031fec..a66347ead76 100644
--- a/spec/lib/gitlab/bitbucket_import/importer_spec.rb
+++ b/spec/lib/gitlab/bitbucket_import/importer_spec.rb
@@ -52,9 +52,9 @@ describe Gitlab::BitbucketImport::Importer do
let(:project) do
create(
- :empty_project,
+ :project,
import_source: project_identifier,
- import_data: ProjectImportData.new(credentials: data)
+ import_data_attributes: { credentials: data }
)
end
diff --git a/spec/lib/gitlab/bitbucket_import/project_creator_spec.rb b/spec/lib/gitlab/bitbucket_import/project_creator_spec.rb
index d7f7b26740d..ae5b31dc12d 100644
--- a/spec/lib/gitlab/bitbucket_import/project_creator_spec.rb
+++ b/spec/lib/gitlab/bitbucket_import/project_creator_spec.rb
@@ -15,7 +15,7 @@ describe Gitlab::BitbucketImport::ProjectCreator do
has_wiki?: false)
end
- let(:namespace){ create(:group, owner: user) }
+ let(:namespace) { create(:group, owner: user) }
let(:token) { "asdasd12345" }
let(:secret) { "sekrettt" }
let(:access_params) { { bitbucket_access_token: token, bitbucket_access_token_secret: secret } }
diff --git a/spec/lib/gitlab/cache/ci/project_pipeline_status_spec.rb b/spec/lib/gitlab/cache/ci/project_pipeline_status_spec.rb
index 0daf41a7c86..16704ff5e77 100644
--- a/spec/lib/gitlab/cache/ci/project_pipeline_status_spec.rb
+++ b/spec/lib/gitlab/cache/ci/project_pipeline_status_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Gitlab::Cache::Ci::ProjectPipelineStatus, :clean_gitlab_redis_cache do
- let!(:project) { create(:project) }
+ let!(:project) { create(:project, :repository) }
let(:pipeline_status) { described_class.new(project) }
let(:cache_key) { "projects/#{project.id}/pipeline_status" }
@@ -18,7 +18,7 @@ describe Gitlab::Cache::Ci::ProjectPipelineStatus, :clean_gitlab_redis_cache do
let(:sha) { '424d1b73bc0d3cb726eb7dc4ce17a4d48552f8c6' }
let(:ref) { 'master' }
let(:pipeline_info) { { sha: sha, status: status, ref: ref } }
- let!(:project_without_status) { create(:project) }
+ let!(:project_without_status) { create(:project, :repository) }
describe '.load_in_batch_for_projects' do
it 'preloads pipeline_status on projects' do
@@ -48,8 +48,9 @@ describe Gitlab::Cache::Ci::ProjectPipelineStatus, :clean_gitlab_redis_cache do
described_class.load_in_batch_for_projects([project_without_status])
end
- it 'only connects to redis_cache twice' do
- # Once to load, once to store in the cache
+ it 'only connects to redis twice' do
+ # Stub circuitbreaker so it doesn't count the redis connections in there
+ stub_circuit_breaker(project_without_status)
expect(Gitlab::Redis::Cache).to receive(:with).exactly(2).and_call_original
described_class.load_in_batch_for_projects([project_without_status])
@@ -195,7 +196,7 @@ describe Gitlab::Cache::Ci::ProjectPipelineStatus, :clean_gitlab_redis_cache do
end
it "doesn't fail for an empty project" do
- status_for_empty_commit = described_class.new(create(:empty_project))
+ status_for_empty_commit = described_class.new(create(:project))
status_for_empty_commit.load_status
@@ -243,7 +244,7 @@ describe Gitlab::Cache::Ci::ProjectPipelineStatus, :clean_gitlab_redis_cache do
end
it "deletes the cache if the repository doesn't have a head commit" do
- empty_project = create(:empty_project)
+ empty_project = create(:project)
Gitlab::Redis::Cache.with do |redis|
redis.mapped_hmset(cache_key,
{ sha: 'sha', status: 'pending', ref: 'master' })
@@ -301,4 +302,13 @@ describe Gitlab::Cache::Ci::ProjectPipelineStatus, :clean_gitlab_redis_cache do
end
end
end
+
+ def stub_circuit_breaker(project)
+ fake_circuitbreaker = double
+ allow(fake_circuitbreaker).to receive(:perform).and_yield
+ allow(project.repository.raw_repository)
+ .to receive(:circuit_breaker).and_return(fake_circuitbreaker)
+ allow(project.repository)
+ .to receive(:circuit_breaker).and_return(fake_circuitbreaker)
+ end
end
diff --git a/spec/lib/gitlab/checks/force_push_spec.rb b/spec/lib/gitlab/checks/force_push_spec.rb
index 6c4cfa1203e..f8c8b83a3ac 100644
--- a/spec/lib/gitlab/checks/force_push_spec.rb
+++ b/spec/lib/gitlab/checks/force_push_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe Gitlab::Checks::ForcePush do
let(:project) { create(:project, :repository) }
- context "exit code checking" do
+ context "exit code checking", skip_gitaly_mock: true do
it "does not raise a runtime error if the `popen` call to git returns a zero exit code" do
allow(Gitlab::Popen).to receive(:popen).and_return(['normal output', 0])
diff --git a/spec/lib/gitlab/ci/status/pipeline/common_spec.rb b/spec/lib/gitlab/ci/status/pipeline/common_spec.rb
index f5fd31e8d03..4a5b45e7cae 100644
--- a/spec/lib/gitlab/ci/status/pipeline/common_spec.rb
+++ b/spec/lib/gitlab/ci/status/pipeline/common_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe Gitlab::Ci::Status::Pipeline::Common do
let(:user) { create(:user) }
- let(:project) { create(:empty_project, :private) }
+ let(:project) { create(:project, :private) }
let(:pipeline) { create(:ci_pipeline, project: project) }
subject do
diff --git a/spec/lib/gitlab/ci/status/stage/common_spec.rb b/spec/lib/gitlab/ci/status/stage/common_spec.rb
index 8814a7614a0..f5f03ac0395 100644
--- a/spec/lib/gitlab/ci/status/stage/common_spec.rb
+++ b/spec/lib/gitlab/ci/status/stage/common_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe Gitlab::Ci::Status::Stage::Common do
let(:user) { create(:user) }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:pipeline) { create(:ci_empty_pipeline, project: project) }
let(:stage) do
diff --git a/spec/lib/gitlab/ci/status/stage/factory_spec.rb b/spec/lib/gitlab/ci/status/stage/factory_spec.rb
index bbb40e2c1ab..432b07e4902 100644
--- a/spec/lib/gitlab/ci/status/stage/factory_spec.rb
+++ b/spec/lib/gitlab/ci/status/stage/factory_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe Gitlab::Ci::Status::Stage::Factory do
let(:user) { create(:user) }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:pipeline) { create(:ci_empty_pipeline, project: project) }
let(:stage) do
diff --git a/spec/lib/gitlab/closing_issue_extractor_spec.rb b/spec/lib/gitlab/closing_issue_extractor_spec.rb
index 8ff6125ada1..15012495247 100644
--- a/spec/lib/gitlab/closing_issue_extractor_spec.rb
+++ b/spec/lib/gitlab/closing_issue_extractor_spec.rb
@@ -1,8 +1,8 @@
require 'spec_helper'
describe Gitlab::ClosingIssueExtractor do
- let(:project) { create(:empty_project) }
- let(:project2) { create(:empty_project) }
+ let(:project) { create(:project) }
+ let(:project2) { create(:project) }
let(:forked_project) { Projects::ForkService.new(project, project.creator).execute }
let(:issue) { create(:issue, project: project) }
let(:issue2) { create(:issue, project: project2) }
diff --git a/spec/lib/gitlab/contributions_calendar_spec.rb b/spec/lib/gitlab/contributions_calendar_spec.rb
index 79632e2b6a3..f1655854486 100644
--- a/spec/lib/gitlab/contributions_calendar_spec.rb
+++ b/spec/lib/gitlab/contributions_calendar_spec.rb
@@ -5,29 +5,31 @@ describe Gitlab::ContributionsCalendar do
let(:user) { create(:user) }
let(:private_project) do
- create(:empty_project, :private) do |project|
+ create(:project, :private) do |project|
create(:project_member, user: contributor, project: project)
end
end
let(:public_project) do
- create(:empty_project, :public) do |project|
+ create(:project, :public) do |project|
create(:project_member, user: contributor, project: project)
end
end
let(:feature_project) do
- create(:empty_project, :public, :issues_private) do |project|
+ create(:project, :public, :issues_private) do |project|
create(:project_member, user: contributor, project: project).project
end
end
- let(:today) { Time.now.to_date }
+ let(:today) { Time.now.utc.to_date }
+ let(:yesterday) { today - 1.day }
+ let(:tomorrow) { today + 1.day }
let(:last_week) { today - 7.days }
let(:last_year) { today - 1.year }
before do
- travel_to today
+ travel_to Time.now.utc.end_of_day
end
after do
@@ -38,7 +40,7 @@ describe Gitlab::ContributionsCalendar do
described_class.new(contributor, current_user)
end
- def create_event(project, day)
+ def create_event(project, day, hour = 0)
@targets ||= {}
@targets[project] ||= create(:issue, project: project, author: contributor)
@@ -47,7 +49,7 @@ describe Gitlab::ContributionsCalendar do
action: Event::CREATED,
target: @targets[project],
author: contributor,
- created_at: day
+ created_at: DateTime.new(day.year, day.month, day.day, hour)
)
end
@@ -68,6 +70,34 @@ describe Gitlab::ContributionsCalendar do
expect(calendar(user).activity_dates[today]).to eq(0)
expect(calendar(contributor).activity_dates[today]).to eq(2)
end
+
+ context "when events fall under different dates depending on the time zone" do
+ before do
+ create_event(public_project, today, 1)
+ create_event(public_project, today, 4)
+ create_event(public_project, today, 10)
+ create_event(public_project, today, 16)
+ create_event(public_project, today, 23)
+ end
+
+ it "renders correct event counts within the UTC timezone" do
+ Time.use_zone('UTC') do
+ expect(calendar.activity_dates).to eq(today => 5)
+ end
+ end
+
+ it "renders correct event counts within the Sydney timezone" do
+ Time.use_zone('Sydney') do
+ expect(calendar.activity_dates).to eq(today => 3, tomorrow => 2)
+ end
+ end
+
+ it "renders correct event counts within the US Central timezone" do
+ Time.use_zone('Central Time (US & Canada)') do
+ expect(calendar.activity_dates).to eq(yesterday => 2, today => 3)
+ end
+ end
+ end
end
describe '#events_by_date' do
diff --git a/spec/lib/gitlab/cycle_analytics/base_event_fetcher_spec.rb b/spec/lib/gitlab/cycle_analytics/base_event_fetcher_spec.rb
index d8757c601ab..854aaa34c73 100644
--- a/spec/lib/gitlab/cycle_analytics/base_event_fetcher_spec.rb
+++ b/spec/lib/gitlab/cycle_analytics/base_event_fetcher_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe Gitlab::CycleAnalytics::BaseEventFetcher do
let(:max_events) { 2 }
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:user) { create(:user, :admin) }
let(:start_time_attrs) { Issue.arel_table[:created_at] }
let(:end_time_attrs) { [Issue::Metrics.arel_table[:first_associated_with_milestone_at]] }
diff --git a/spec/lib/gitlab/cycle_analytics/events_spec.rb b/spec/lib/gitlab/cycle_analytics/events_spec.rb
index a1b3fe8509e..28ea7d4c303 100644
--- a/spec/lib/gitlab/cycle_analytics/events_spec.rb
+++ b/spec/lib/gitlab/cycle_analytics/events_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe 'cycle analytics events' do
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:from_date) { 10.days.ago }
let(:user) { create(:user, :admin) }
let!(:context) { create(:issue, project: project, created_at: 2.days.ago) }
diff --git a/spec/lib/gitlab/cycle_analytics/permissions_spec.rb b/spec/lib/gitlab/cycle_analytics/permissions_spec.rb
index 2d85e712db0..2a0dd7be439 100644
--- a/spec/lib/gitlab/cycle_analytics/permissions_spec.rb
+++ b/spec/lib/gitlab/cycle_analytics/permissions_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Gitlab::CycleAnalytics::Permissions do
- let(:project) { create(:empty_project, public_builds: false) }
+ let(:project) { create(:project, public_builds: false) }
let(:user) { create(:user) }
subject { described_class.get(user: user, project: project) }
diff --git a/spec/lib/gitlab/cycle_analytics/shared_event_spec.rb b/spec/lib/gitlab/cycle_analytics/shared_event_spec.rb
index 9c5e57342e9..c22d27f60d6 100644
--- a/spec/lib/gitlab/cycle_analytics/shared_event_spec.rb
+++ b/spec/lib/gitlab/cycle_analytics/shared_event_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
shared_examples 'default query config' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:event) { described_class.new(project: project, stage: stage_name, options: { from: 1.day.ago }) }
it 'has the stage attribute' do
diff --git a/spec/lib/gitlab/cycle_analytics/stage_summary_spec.rb b/spec/lib/gitlab/cycle_analytics/stage_summary_spec.rb
index 592448aef96..2e67c1c7f78 100644
--- a/spec/lib/gitlab/cycle_analytics/stage_summary_spec.rb
+++ b/spec/lib/gitlab/cycle_analytics/stage_summary_spec.rb
@@ -15,7 +15,7 @@ describe Gitlab::CycleAnalytics::StageSummary do
end
it "doesn't find issues from other projects" do
- Timecop.freeze(5.days.from_now) { create(:issue, project: create(:empty_project)) }
+ Timecop.freeze(5.days.from_now) { create(:issue, project: create(:project)) }
expect(subject.first[:value]).to eq(0)
end
diff --git a/spec/lib/gitlab/daemon_spec.rb b/spec/lib/gitlab/daemon_spec.rb
new file mode 100644
index 00000000000..2bdb0dfc736
--- /dev/null
+++ b/spec/lib/gitlab/daemon_spec.rb
@@ -0,0 +1,103 @@
+require 'spec_helper'
+
+describe Gitlab::Daemon do
+ subject { described_class.new }
+
+ before do
+ allow(subject).to receive(:start_working)
+ allow(subject).to receive(:stop_working)
+ end
+
+ describe '.instance' do
+ before do
+ allow(Kernel).to receive(:at_exit)
+ end
+
+ after do
+ described_class.instance_variable_set(:@instance, nil)
+ end
+
+ it 'provides instance of Daemon' do
+ expect(described_class.instance).to be_instance_of(described_class)
+ end
+
+ it 'subsequent invocations provide the same instance' do
+ expect(described_class.instance).to eq(described_class.instance)
+ end
+
+ it 'creates at_exit hook when instance is created' do
+ expect(described_class.instance).not_to be_nil
+
+ expect(Kernel).to have_received(:at_exit)
+ end
+ end
+
+ describe 'when Daemon is enabled' do
+ before do
+ allow(subject).to receive(:enabled?).and_return(true)
+ end
+
+ describe 'when Daemon is stopped' do
+ describe '#start' do
+ it 'starts the Daemon' do
+ expect { subject.start.join }.to change { subject.thread? }.from(false).to(true)
+
+ expect(subject).to have_received(:start_working)
+ end
+ end
+
+ describe '#stop' do
+ it "doesn't shutdown stopped Daemon" do
+ expect { subject.stop }.not_to change { subject.thread? }
+
+ expect(subject).not_to have_received(:start_working)
+ end
+ end
+ end
+
+ describe 'when Daemon is running' do
+ before do
+ subject.start.join
+ end
+
+ describe '#start' do
+ it "doesn't start running Daemon" do
+ expect { subject.start.join }.not_to change { subject.thread? }
+
+ expect(subject).to have_received(:start_working).once
+ end
+ end
+
+ describe '#stop' do
+ it 'shutdowns Daemon' do
+ expect { subject.stop }.to change { subject.thread? }.from(true).to(false)
+
+ expect(subject).to have_received(:stop_working)
+ end
+ end
+ end
+ end
+
+ describe 'when Daemon is disabled' do
+ before do
+ allow(subject).to receive(:enabled?).and_return(false)
+ end
+
+ describe '#start' do
+ it "doesn't start working" do
+ expect(subject.start).to be_nil
+ expect { subject.start }.not_to change { subject.thread? }
+
+ expect(subject).not_to have_received(:start_working)
+ end
+ end
+
+ describe '#stop' do
+ it "doesn't stop working" do
+ expect { subject.stop }.not_to change { subject.thread? }
+
+ expect(subject).not_to have_received(:stop_working)
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/data_builder/note_spec.rb b/spec/lib/gitlab/data_builder/note_spec.rb
index 6415e4083d6..aaa42566a4d 100644
--- a/spec/lib/gitlab/data_builder/note_spec.rb
+++ b/spec/lib/gitlab/data_builder/note_spec.rb
@@ -6,7 +6,7 @@ describe Gitlab::DataBuilder::Note do
let(:data) { described_class.build(note, user) }
let(:fixed_time) { Time.at(1425600000) } # Avoid time precision errors
- before(:each) do
+ before do
expect(data).to have_key(:object_attributes)
expect(data[:object_attributes]).to have_key(:url)
expect(data[:object_attributes][:url])
diff --git a/spec/lib/gitlab/database/migration_helpers_spec.rb b/spec/lib/gitlab/database/migration_helpers_spec.rb
index d3dbd82e8ba..ec2274a70aa 100644
--- a/spec/lib/gitlab/database/migration_helpers_spec.rb
+++ b/spec/lib/gitlab/database/migration_helpers_spec.rb
@@ -276,7 +276,7 @@ describe Gitlab::Database::MigrationHelpers do
before do
expect(model).to receive(:transaction_open?).and_return(false)
- create_list(:empty_project, 5)
+ create_list(:project, 5)
end
it 'updates all the rows in a table' do
diff --git a/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_base_spec.rb b/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_base_spec.rb
index df7d1b5d27a..90aa4f63dd5 100644
--- a/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_base_spec.rb
+++ b/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_base_spec.rb
@@ -29,7 +29,7 @@ describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameBase, :trunca
end
describe '#remove_cached_html_for_projects' do
- let(:project) { create(:empty_project, description_html: 'Project description') }
+ let(:project) { create(:project, description_html: 'Project description') }
it 'removes description_html from projects' do
subject.remove_cached_html_for_projects([project.id])
@@ -94,7 +94,7 @@ describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameBase, :trunca
end
it "renames the route for projects of the namespace" do
- project = create(:project, path: "project-path", namespace: namespace)
+ project = create(:project, :repository, path: "project-path", namespace: namespace)
subject.rename_path_for_routable(migration_namespace(namespace))
@@ -110,7 +110,7 @@ describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameBase, :trunca
it "doesn't rename routes that start with a similar name" do
other_namespace = create(:namespace, path: 'the-path-but-not-really')
- project = create(:empty_project, path: 'the-project', namespace: other_namespace)
+ project = create(:project, path: 'the-project', namespace: other_namespace)
subject.rename_path_for_routable(migration_namespace(namespace))
@@ -120,7 +120,7 @@ describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameBase, :trunca
context "the-path namespace -> subgroup -> the-path0 project" do
it "updates the route of the project correctly" do
subgroup = create(:group, path: "subgroup", parent: namespace)
- project = create(:project, path: "the-path0", namespace: subgroup)
+ project = create(:project, :repository, path: "the-path0", namespace: subgroup)
subject.rename_path_for_routable(migration_namespace(namespace))
@@ -131,7 +131,7 @@ describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameBase, :trunca
context 'for projects' do
let(:parent) { create(:namespace, path: 'the-parent') }
- let(:project) { create(:empty_project, path: 'the-path', namespace: parent) }
+ let(:project) { create(:project, path: 'the-path', namespace: parent) }
it 'renames the project called `the-path`' do
subject.rename_path_for_routable(migration_project(project))
@@ -165,7 +165,7 @@ describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameBase, :trunca
it 'renames all the routes for the namespace' do
child = create(:group, path: 'child', parent: namespace)
- project = create(:project, namespace: child, path: 'the-project')
+ project = create(:project, :repository, namespace: child, path: 'the-project')
other_one = create(:namespace, path: 'the-path-is-similar')
subject.perform_rename(migration_namespace(namespace), 'the-path', 'renamed')
diff --git a/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_namespaces_spec.rb b/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_namespaces_spec.rb
index 803e923b4a5..32ac0b88a9b 100644
--- a/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_namespaces_spec.rb
+++ b/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_namespaces_spec.rb
@@ -94,7 +94,7 @@ describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameNamespaces, :
describe '#move_repositories' do
let(:namespace) { create(:group, name: 'hello-group') }
it 'moves a project for a namespace' do
- create(:project, namespace: namespace, path: 'hello-project')
+ create(:project, :repository, namespace: namespace, path: 'hello-project')
expected_path = File.join(TestEnv.repos_path, 'bye-group', 'hello-project.git')
subject.move_repositories(namespace, 'hello-group', 'bye-group')
@@ -104,7 +104,7 @@ describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameNamespaces, :
it 'moves a namespace in a subdirectory correctly' do
child_namespace = create(:group, name: 'sub-group', parent: namespace)
- create(:project, namespace: child_namespace, path: 'hello-project')
+ create(:project, :repository, namespace: child_namespace, path: 'hello-project')
expected_path = File.join(TestEnv.repos_path, 'hello-group', 'renamed-sub-group', 'hello-project.git')
@@ -115,7 +115,7 @@ describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameNamespaces, :
it 'moves a parent namespace with subdirectories' do
child_namespace = create(:group, name: 'sub-group', parent: namespace)
- create(:project, namespace: child_namespace, path: 'hello-project')
+ create(:project, :repository, namespace: child_namespace, path: 'hello-project')
expected_path = File.join(TestEnv.repos_path, 'renamed-group', 'sub-group', 'hello-project.git')
subject.move_repositories(child_namespace, 'hello-group', 'renamed-group')
@@ -166,7 +166,7 @@ describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameNamespaces, :
describe '#rename_namespace_dependencies' do
it "moves the the repository for a project in the namespace" do
- create(:project, namespace: namespace, path: "the-path-project")
+ create(:project, :repository, namespace: namespace, path: "the-path-project")
expected_repo = File.join(TestEnv.repos_path, "the-path0", "the-path-project.git")
subject.rename_namespace_dependencies(namespace, 'the-path', 'the-path0')
@@ -187,7 +187,7 @@ describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameNamespaces, :
end
it 'invalidates the markdown cache of related projects' do
- project = create(:empty_project, namespace: namespace, path: "the-path-project")
+ project = create(:project, namespace: namespace, path: "the-path-project")
expect(subject).to receive(:remove_cached_html_for_projects).with([project.id])
@@ -243,7 +243,7 @@ describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameNamespaces, :
describe '#revert_renames', redis: true do
it 'renames the routes back to the previous values' do
- project = create(:project, path: 'a-project', namespace: namespace)
+ project = create(:project, :repository, path: 'a-project', namespace: namespace)
subject.rename_namespace(namespace)
expect(subject).to receive(:perform_rename)
@@ -261,7 +261,7 @@ describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameNamespaces, :
end
it 'moves the repositories back to their original place' do
- project = create(:project, path: 'a-project', namespace: namespace)
+ project = create(:project, :repository, path: 'a-project', namespace: namespace)
project.create_repository
subject.rename_namespace(namespace)
diff --git a/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_projects_spec.rb b/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_projects_spec.rb
index 0e240a5ccf1..595e06a9748 100644
--- a/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_projects_spec.rb
+++ b/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_projects_spec.rb
@@ -4,7 +4,7 @@ describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameProjects, :tr
let(:migration) { FakeRenameReservedPathMigrationV1.new }
let(:subject) { described_class.new(['the-path'], migration) }
let(:project) do
- create(:empty_project,
+ create(:project,
path: 'the-path',
namespace: create(:namespace, path: 'known-parent' ))
end
@@ -17,7 +17,7 @@ describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameProjects, :tr
describe '#projects_for_paths' do
it 'searches using nested paths' do
namespace = create(:namespace, path: 'hello')
- project = create(:empty_project, path: 'THE-path', namespace: namespace)
+ project = create(:project, path: 'THE-path', namespace: namespace)
result_ids = described_class.new(['Hello/the-path'], migration)
.projects_for_paths.map(&:id)
@@ -26,8 +26,8 @@ describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameProjects, :tr
end
it 'includes the correct projects' do
- project = create(:empty_project, path: 'THE-path')
- _other_project = create(:empty_project)
+ project = create(:project, path: 'THE-path')
+ _other_project = create(:project)
result_ids = subject.projects_for_paths.map(&:id)
@@ -36,7 +36,7 @@ describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameProjects, :tr
end
describe '#rename_projects' do
- let!(:projects) { create_list(:empty_project, 2, path: 'the-path') }
+ let!(:projects) { create_list(:project, 2, path: 'the-path') }
it 'renames each project' do
expect(subject).to receive(:rename_project).twice
@@ -104,7 +104,7 @@ describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameProjects, :tr
describe '#move_repository' do
let(:known_parent) { create(:namespace, path: 'known-parent') }
- let(:project) { create(:project, path: 'the-path', namespace: known_parent) }
+ let(:project) { create(:project, :repository, path: 'the-path', namespace: known_parent) }
it 'moves the repository for a project' do
expected_path = File.join(TestEnv.repos_path, 'known-parent', 'new-repo.git')
diff --git a/spec/lib/gitlab/database_spec.rb b/spec/lib/gitlab/database_spec.rb
index c5f9aecd867..5fa94999d25 100644
--- a/spec/lib/gitlab/database_spec.rb
+++ b/spec/lib/gitlab/database_spec.rb
@@ -51,6 +51,28 @@ describe Gitlab::Database do
end
end
+ describe '.join_lateral_supported?' do
+ it 'returns false when using MySQL' do
+ allow(described_class).to receive(:postgresql?).and_return(false)
+
+ expect(described_class.join_lateral_supported?).to eq(false)
+ end
+
+ it 'returns false when using PostgreSQL 9.2' do
+ allow(described_class).to receive(:postgresql?).and_return(true)
+ allow(described_class).to receive(:version).and_return('9.2.1')
+
+ expect(described_class.join_lateral_supported?).to eq(false)
+ end
+
+ it 'returns true when using PostgreSQL 9.3.0 or newer' do
+ allow(described_class).to receive(:postgresql?).and_return(true)
+ allow(described_class).to receive(:version).and_return('9.3.0')
+
+ expect(described_class.join_lateral_supported?).to eq(true)
+ end
+ end
+
describe '.nulls_last_order' do
context 'when using PostgreSQL' do
before do
diff --git a/spec/lib/gitlab/diff/file_spec.rb b/spec/lib/gitlab/diff/file_spec.rb
index cd2fa98b14c..d3d841b0668 100644
--- a/spec/lib/gitlab/diff/file_spec.rb
+++ b/spec/lib/gitlab/diff/file_spec.rb
@@ -47,14 +47,6 @@ describe Gitlab::Diff::File do
end
end
- describe '#old_content_commit' do
- it 'returns base commit' do
- old_content_commit = diff_file.old_content_commit
-
- expect(old_content_commit.id).to eq('6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9')
- end
- end
-
describe '#old_blob' do
it 'returns blob of commit of base commit' do
old_data = diff_file.old_blob.data
diff --git a/spec/lib/gitlab/diff/parser_spec.rb b/spec/lib/gitlab/diff/parser_spec.rb
index c71568e2a65..8af49ed50ff 100644
--- a/spec/lib/gitlab/diff/parser_spec.rb
+++ b/spec/lib/gitlab/diff/parser_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe Gitlab::Diff::Parser do
include RepoHelpers
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:commit) { project.commit(sample_commit.id) }
let(:diff) { commit.raw_diffs.first }
let(:parser) { described_class.new }
diff --git a/spec/lib/gitlab/email/handler/create_note_handler_spec.rb b/spec/lib/gitlab/email/handler/create_note_handler_spec.rb
index 0127b012c91..d0fa16ce4d1 100644
--- a/spec/lib/gitlab/email/handler/create_note_handler_spec.rb
+++ b/spec/lib/gitlab/email/handler/create_note_handler_spec.rb
@@ -36,15 +36,6 @@ describe Gitlab::Email::Handler::CreateNoteHandler do
end
end
- context "when the email was auto generated" do
- let!(:mail_key) { '636ca428858779856c226bb145ef4fad' }
- let!(:email_raw) { fixture_file("emails/auto_reply.eml") }
-
- it "raises an AutoGeneratedEmailError" do
- expect { receiver.execute }.to raise_error(Gitlab::Email::AutoGeneratedEmailError)
- end
- end
-
context "when the noteable could not be found" do
before do
noteable.destroy
diff --git a/spec/lib/gitlab/email/handler/unsubscribe_handler_spec.rb b/spec/lib/gitlab/email/handler/unsubscribe_handler_spec.rb
index 66c38498e4e..21796694f26 100644
--- a/spec/lib/gitlab/email/handler/unsubscribe_handler_spec.rb
+++ b/spec/lib/gitlab/email/handler/unsubscribe_handler_spec.rb
@@ -10,7 +10,7 @@ describe Gitlab::Email::Handler::UnsubscribeHandler do
end
let(:email_raw) { fixture_file('emails/valid_reply.eml').gsub(mail_key, "#{mail_key}+unsubscribe") }
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:user) { create(:user) }
let(:noteable) { create(:issue, project: project) }
diff --git a/spec/lib/gitlab/email/message/repository_push_spec.rb b/spec/lib/gitlab/email/message/repository_push_spec.rb
index 7b3291b8315..83c4d177cae 100644
--- a/spec/lib/gitlab/email/message/repository_push_spec.rb
+++ b/spec/lib/gitlab/email/message/repository_push_spec.rb
@@ -117,7 +117,7 @@ describe Gitlab::Email::Message::RepositoryPush do
describe '#subject' do
subject { message.subject }
- it { is_expected.to include "[Git][#{project.path_with_namespace}]" }
+ it { is_expected.to include "[Git][#{project.full_path}]" }
it { is_expected.to include "#{compare.commits.length} commits" }
it { is_expected.to include compare.commits.first.message.split("\n").first }
end
diff --git a/spec/lib/gitlab/email/receiver_spec.rb b/spec/lib/gitlab/email/receiver_spec.rb
index 88565ea5311..59f43abf26d 100644
--- a/spec/lib/gitlab/email/receiver_spec.rb
+++ b/spec/lib/gitlab/email/receiver_spec.rb
@@ -28,14 +28,6 @@ describe Gitlab::Email::Receiver do
it "raises an UnknownIncomingEmail error" do
expect { receiver.execute }.to raise_error(Gitlab::Email::UnknownIncomingEmail)
end
-
- context "and the email contains no references header" do
- let(:email_raw) { fixture_file("emails/auto_reply.eml").gsub(mail_key, "!!!") }
-
- it "raises an UnknownIncomingEmail error" do
- expect { receiver.execute }.to raise_error(Gitlab::Email::UnknownIncomingEmail)
- end
- end
end
context "when the email is blank" do
@@ -45,4 +37,12 @@ describe Gitlab::Email::Receiver do
expect { receiver.execute }.to raise_error(Gitlab::Email::EmptyEmailError)
end
end
+
+ context "when the email was auto generated" do
+ let(:email_raw) { fixture_file("emails/auto_reply.eml") }
+
+ it "raises an AutoGeneratedEmailError" do
+ expect { receiver.execute }.to raise_error(Gitlab::Email::AutoGeneratedEmailError)
+ end
+ end
end
diff --git a/spec/lib/gitlab/encoding_helper_spec.rb b/spec/lib/gitlab/encoding_helper_spec.rb
index 1482ef7132d..8b14b227e65 100644
--- a/spec/lib/gitlab/encoding_helper_spec.rb
+++ b/spec/lib/gitlab/encoding_helper_spec.rb
@@ -30,6 +30,53 @@ describe Gitlab::EncodingHelper do
it 'leaves binary string as is' do
expect(ext_class.encode!(binary_string)).to eq(binary_string)
end
+
+ context 'with corrupted diff' do
+ let(:corrupted_diff) do
+ with_empty_bare_repository do |repo|
+ content = File.read(Rails.root.join(
+ 'spec/fixtures/encoding/Japanese.md').to_s)
+ commit_a = commit(repo, 'Japanese.md', content)
+ commit_b = commit(repo, 'Japanese.md',
+ content.sub('[TODO: Link]', '[ç¾åœ¨ä½œæ¥­ä¸­ã§ã™: Link]'))
+
+ repo.diff(commit_a, commit_b).each_line.map(&:content).join
+ end
+ end
+
+ let(:cleaned_diff) do
+ corrupted_diff.dup.force_encoding('UTF-8')
+ .encode!('UTF-8', invalid: :replace, replace: '')
+ end
+
+ let(:encoded_diff) do
+ described_class.encode!(corrupted_diff.dup)
+ end
+
+ it 'does not corrupt data but remove invalid characters' do
+ expect(encoded_diff).to eq(cleaned_diff)
+ end
+
+ def commit(repo, path, content)
+ oid = repo.write(content, :blob)
+ index = repo.index
+
+ index.read_tree(repo.head.target.tree) unless repo.empty?
+
+ index.add(path: path, oid: oid, mode: 0100644)
+ user = { name: 'Test', email: 'test@example.com' }
+
+ Rugged::Commit.create(
+ repo,
+ tree: index.write_tree(repo),
+ author: user,
+ committer: user,
+ message: "Update #{path}",
+ parents: repo.empty? ? [] : [repo.head.target].compact,
+ update_ref: 'HEAD'
+ )
+ end
+ end
end
describe '#encode_utf8' do
diff --git a/spec/lib/gitlab/gfm/reference_rewriter_spec.rb b/spec/lib/gitlab/gfm/reference_rewriter_spec.rb
index eaec699ad90..a3d323fe28a 100644
--- a/spec/lib/gitlab/gfm/reference_rewriter_spec.rb
+++ b/spec/lib/gitlab/gfm/reference_rewriter_spec.rb
@@ -2,8 +2,8 @@ require 'spec_helper'
describe Gitlab::Gfm::ReferenceRewriter do
let(:text) { 'some text' }
- let(:old_project) { create(:empty_project, name: 'old-project') }
- let(:new_project) { create(:empty_project, name: 'new-project') }
+ let(:old_project) { create(:project, name: 'old-project') }
+ let(:new_project) { create(:project, name: 'new-project') }
let(:user) { create(:user) }
before do
diff --git a/spec/lib/gitlab/gfm/uploads_rewriter_spec.rb b/spec/lib/gitlab/gfm/uploads_rewriter_spec.rb
index c3016f63ebf..39e3b875c49 100644
--- a/spec/lib/gitlab/gfm/uploads_rewriter_spec.rb
+++ b/spec/lib/gitlab/gfm/uploads_rewriter_spec.rb
@@ -2,8 +2,8 @@ require 'spec_helper'
describe Gitlab::Gfm::UploadsRewriter do
let(:user) { create(:user) }
- let(:old_project) { create(:empty_project) }
- let(:new_project) { create(:empty_project) }
+ let(:old_project) { create(:project) }
+ let(:new_project) { create(:project) }
let(:rewriter) { described_class.new(text, old_project, user) }
context 'text contains links to uploads' do
@@ -39,8 +39,8 @@ describe Gitlab::Gfm::UploadsRewriter do
it 'copies files' do
expect(new_files).to all(exist)
expect(old_paths).not_to match_array new_paths
- expect(old_paths).to all(include(old_project.path_with_namespace))
- expect(new_paths).to all(include(new_project.path_with_namespace))
+ expect(old_paths).to all(include(old_project.full_path))
+ expect(new_paths).to all(include(new_project.full_path))
end
it 'does not remove old files' do
diff --git a/spec/lib/gitlab/git/blame_spec.rb b/spec/lib/gitlab/git/blame_spec.rb
index 66c016d14b3..800c245b130 100644
--- a/spec/lib/gitlab/git/blame_spec.rb
+++ b/spec/lib/gitlab/git/blame_spec.rb
@@ -7,63 +7,73 @@ describe Gitlab::Git::Blame, seed_helper: true do
Gitlab::Git::Blame.new(repository, SeedRepo::Commit::ID, "CONTRIBUTING.md")
end
- context "each count" do
- it do
- data = []
- blame.each do |commit, line|
- data << {
- commit: commit,
- line: line
- }
- end
-
- expect(data.size).to eq(95)
- expect(data.first[:commit]).to be_kind_of(Gitlab::Git::Commit)
- expect(data.first[:line]).to eq("# Contribute to GitLab")
- expect(data.first[:line]).to be_utf8
- end
- end
+ shared_examples 'blaming a file' do
+ context "each count" do
+ it do
+ data = []
+ blame.each do |commit, line|
+ data << {
+ commit: commit,
+ line: line
+ }
+ end
- context "ISO-8859 encoding" do
- let(:blame) do
- Gitlab::Git::Blame.new(repository, SeedRepo::EncodingCommit::ID, "encoding/iso8859.txt")
+ expect(data.size).to eq(95)
+ expect(data.first[:commit]).to be_kind_of(Gitlab::Git::Commit)
+ expect(data.first[:line]).to eq("# Contribute to GitLab")
+ expect(data.first[:line]).to be_utf8
+ end
end
- it 'converts to UTF-8' do
- data = []
- blame.each do |commit, line|
- data << {
- commit: commit,
- line: line
- }
+ context "ISO-8859 encoding" do
+ let(:blame) do
+ Gitlab::Git::Blame.new(repository, SeedRepo::EncodingCommit::ID, "encoding/iso8859.txt")
end
- expect(data.size).to eq(1)
- expect(data.first[:commit]).to be_kind_of(Gitlab::Git::Commit)
- expect(data.first[:line]).to eq("Ä ü")
- expect(data.first[:line]).to be_utf8
- end
- end
+ it 'converts to UTF-8' do
+ data = []
+ blame.each do |commit, line|
+ data << {
+ commit: commit,
+ line: line
+ }
+ end
- context "unknown encoding" do
- let(:blame) do
- Gitlab::Git::Blame.new(repository, SeedRepo::EncodingCommit::ID, "encoding/iso8859.txt")
+ expect(data.size).to eq(1)
+ expect(data.first[:commit]).to be_kind_of(Gitlab::Git::Commit)
+ expect(data.first[:line]).to eq("Ä ü")
+ expect(data.first[:line]).to be_utf8
+ end
end
- it 'converts to UTF-8' do
- expect(CharlockHolmes::EncodingDetector).to receive(:detect).and_return(nil)
- data = []
- blame.each do |commit, line|
- data << {
+ context "unknown encoding" do
+ let(:blame) do
+ Gitlab::Git::Blame.new(repository, SeedRepo::EncodingCommit::ID, "encoding/iso8859.txt")
+ end
+
+ it 'converts to UTF-8' do
+ expect(CharlockHolmes::EncodingDetector).to receive(:detect).and_return(nil)
+ data = []
+ blame.each do |commit, line|
+ data << {
commit: commit,
line: line
- }
- end
+ }
+ end
- expect(data.size).to eq(1)
- expect(data.first[:commit]).to be_kind_of(Gitlab::Git::Commit)
- expect(data.first[:line]).to eq(" ")
- expect(data.first[:line]).to be_utf8
+ expect(data.size).to eq(1)
+ expect(data.first[:commit]).to be_kind_of(Gitlab::Git::Commit)
+ expect(data.first[:line]).to eq(" ")
+ expect(data.first[:line]).to be_utf8
+ end
end
end
+
+ context 'when Gitaly blame feature is enabled' do
+ it_behaves_like 'blaming a file'
+ end
+
+ context 'when Gitaly blame feature is disabled', skip_gitaly_mock: true do
+ it_behaves_like 'blaming a file'
+ end
end
diff --git a/spec/lib/gitlab/git/blob_spec.rb b/spec/lib/gitlab/git/blob_spec.rb
index 3c784eda4f8..dfab0c2fe85 100644
--- a/spec/lib/gitlab/git/blob_spec.rb
+++ b/spec/lib/gitlab/git/blob_spec.rb
@@ -78,12 +78,18 @@ describe Gitlab::Git::Blob, seed_helper: true do
context 'large file' do
let(:blob) { Gitlab::Git::Blob.find(repository, SeedRepo::Commit::ID, 'files/images/6049019_460s.jpg') }
let(:blob_size) { 111803 }
+ let(:stub_limit) { 1000 }
+
+ before do
+ stub_const('Gitlab::Git::Blob::MAX_DATA_DISPLAY_SIZE', stub_limit)
+ end
it { expect(blob.size).to eq(blob_size) }
- it { expect(blob.data.length).to eq(blob_size) }
+ it { expect(blob.data.length).to eq(stub_limit) }
it 'check that this test is sane' do
- expect(blob.size).to be <= Gitlab::Git::Blob::MAX_DATA_DISPLAY_SIZE
+ # It only makes sense to test limiting if the blob is larger than the limit.
+ expect(blob.size).to be > Gitlab::Git::Blob::MAX_DATA_DISPLAY_SIZE
end
it 'can load all data' do
@@ -146,6 +152,77 @@ describe Gitlab::Git::Blob, seed_helper: true do
end
end
+ describe '.batch' do
+ let(:blob_references) do
+ [
+ [SeedRepo::Commit::ID, "files/ruby/popen.rb"],
+ [SeedRepo::Commit::ID, 'six']
+ ]
+ end
+
+ subject { described_class.batch(repository, blob_references) }
+
+ it { expect(subject.size).to eq(blob_references.size) }
+
+ context 'first blob' do
+ let(:blob) { subject[0] }
+
+ it { expect(blob.id).to eq(SeedRepo::RubyBlob::ID) }
+ it { expect(blob.name).to eq(SeedRepo::RubyBlob::NAME) }
+ it { expect(blob.path).to eq("files/ruby/popen.rb") }
+ it { expect(blob.commit_id).to eq(SeedRepo::Commit::ID) }
+ it { expect(blob.data[0..10]).to eq(SeedRepo::RubyBlob::CONTENT[0..10]) }
+ it { expect(blob.size).to eq(669) }
+ it { expect(blob.mode).to eq("100644") }
+ end
+
+ context 'second blob' do
+ let(:blob) { subject[1] }
+
+ it { expect(blob.id).to eq('409f37c4f05865e4fb208c771485f211a22c4c2d') }
+ it { expect(blob.data).to eq('') }
+ it 'does not mark the blob as binary' do
+ expect(blob).not_to be_binary
+ end
+ end
+
+ context 'limiting' do
+ subject { described_class.batch(repository, blob_references, blob_size_limit: blob_size_limit) }
+
+ context 'default' do
+ let(:blob_size_limit) { nil }
+
+ it 'limits to MAX_DATA_DISPLAY_SIZE' do
+ stub_const('Gitlab::Git::Blob::MAX_DATA_DISPLAY_SIZE', 100)
+
+ expect(subject.first.data.size).to eq(100)
+ end
+ end
+
+ context 'positive' do
+ let(:blob_size_limit) { 10 }
+
+ it { expect(subject.first.data.size).to eq(10) }
+ end
+
+ context 'zero' do
+ let(:blob_size_limit) { 0 }
+
+ it { expect(subject.first.data).to eq('') }
+ end
+
+ context 'negative' do
+ let(:blob_size_limit) { -1 }
+
+ it 'ignores MAX_DATA_DISPLAY_SIZE' do
+ stub_const('Gitlab::Git::Blob::MAX_DATA_DISPLAY_SIZE', 100)
+
+ expect(subject.first.data.size).to eq(669)
+ end
+ end
+ end
+ end
+
describe 'encoding' do
context 'file with russian text' do
let(:blob) { Gitlab::Git::Blob.find(repository, SeedRepo::Commit::ID, "encoding/russian.rb") }
diff --git a/spec/lib/gitlab/git/commit_spec.rb b/spec/lib/gitlab/git/commit_spec.rb
index 730fdb112d9..ac33cd8a2c9 100644
--- a/spec/lib/gitlab/git/commit_spec.rb
+++ b/spec/lib/gitlab/git/commit_spec.rb
@@ -2,7 +2,7 @@ require "spec_helper"
describe Gitlab::Git::Commit, seed_helper: true do
let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH) }
- let(:commit) { Gitlab::Git::Commit.find(repository, SeedRepo::Commit::ID) }
+ let(:commit) { described_class.find(repository, SeedRepo::Commit::ID) }
let(:rugged_commit) do
repository.rugged.lookup(SeedRepo::Commit::ID)
end
@@ -24,7 +24,7 @@ describe Gitlab::Git::Commit, seed_helper: true do
}
@parents = [repo.head.target]
- @gitlab_parents = @parents.map { |c| Gitlab::Git::Commit.decorate(c) }
+ @gitlab_parents = @parents.map { |c| described_class.decorate(repository, c) }
@tree = @parents.first.tree
sha = Rugged::Commit.create(
@@ -38,7 +38,7 @@ describe Gitlab::Git::Commit, seed_helper: true do
)
@raw_commit = repo.lookup(sha)
- @commit = Gitlab::Git::Commit.new(@raw_commit)
+ @commit = described_class.new(repository, @raw_commit)
end
it { expect(@commit.short_id).to eq(@raw_commit.oid[0..10]) }
@@ -66,6 +66,7 @@ describe Gitlab::Git::Commit, seed_helper: true do
describe "Commit info from gitaly commit" do
let(:id) { 'f00' }
+ let(:parent_ids) { %w(b45 b46) }
let(:subject) { "My commit".force_encoding('ASCII-8BIT') }
let(:body) { subject + "My body".force_encoding('ASCII-8BIT') }
let(:committer) do
@@ -88,10 +89,11 @@ describe Gitlab::Git::Commit, seed_helper: true do
subject: subject,
body: body,
author: author,
- committer: committer
+ committer: committer,
+ parent_ids: parent_ids
)
end
- let(:commit) { described_class.new(Gitlab::GitalyClient::Commit.new(repository, gitaly_commit)) }
+ let(:commit) { described_class.new(repository, gitaly_commit) }
it { expect(commit.short_id).to eq(id[0..10]) }
it { expect(commit.id).to eq(id) }
@@ -102,6 +104,7 @@ describe Gitlab::Git::Commit, seed_helper: true do
it { expect(commit.author_name).to eq(author.name) }
it { expect(commit.committer_name).to eq(committer.name) }
it { expect(commit.committer_email).to eq(committer.email) }
+ it { expect(commit.parent_ids).to eq(parent_ids) }
context 'no body' do
let(:body) { "".force_encoding('ASCII-8BIT') }
@@ -113,45 +116,45 @@ describe Gitlab::Git::Commit, seed_helper: true do
context 'Class methods' do
describe '.find' do
it "should return first head commit if without params" do
- expect(Gitlab::Git::Commit.last(repository).id).to eq(
- repository.raw.head.target.oid
+ expect(described_class.last(repository).id).to eq(
+ repository.rugged.head.target.oid
)
end
it "should return valid commit" do
- expect(Gitlab::Git::Commit.find(repository, SeedRepo::Commit::ID)).to be_valid_commit
+ expect(described_class.find(repository, SeedRepo::Commit::ID)).to be_valid_commit
end
it "should return valid commit for tag" do
- expect(Gitlab::Git::Commit.find(repository, 'v1.0.0').id).to eq('6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9')
+ expect(described_class.find(repository, 'v1.0.0').id).to eq('6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9')
end
it "should return nil for non-commit ids" do
blob = Gitlab::Git::Blob.find(repository, SeedRepo::Commit::ID, "files/ruby/popen.rb")
- expect(Gitlab::Git::Commit.find(repository, blob.id)).to be_nil
+ expect(described_class.find(repository, blob.id)).to be_nil
end
it "should return nil for parent of non-commit object" do
blob = Gitlab::Git::Blob.find(repository, SeedRepo::Commit::ID, "files/ruby/popen.rb")
- expect(Gitlab::Git::Commit.find(repository, "#{blob.id}^")).to be_nil
+ expect(described_class.find(repository, "#{blob.id}^")).to be_nil
end
it "should return nil for nonexisting ids" do
- expect(Gitlab::Git::Commit.find(repository, "+123_4532530XYZ")).to be_nil
+ expect(described_class.find(repository, "+123_4532530XYZ")).to be_nil
end
context 'with broken repo' do
let(:repository) { Gitlab::Git::Repository.new('default', TEST_BROKEN_REPO_PATH) }
it 'returns nil' do
- expect(Gitlab::Git::Commit.find(repository, SeedRepo::Commit::ID)).to be_nil
+ expect(described_class.find(repository, SeedRepo::Commit::ID)).to be_nil
end
end
end
describe '.last_for_path' do
context 'no path' do
- subject { Gitlab::Git::Commit.last_for_path(repository, 'master') }
+ subject { described_class.last_for_path(repository, 'master') }
describe '#id' do
subject { super().id }
@@ -160,7 +163,7 @@ describe Gitlab::Git::Commit, seed_helper: true do
end
context 'path' do
- subject { Gitlab::Git::Commit.last_for_path(repository, 'master', 'files/ruby') }
+ subject { described_class.last_for_path(repository, 'master', 'files/ruby') }
describe '#id' do
subject { super().id }
@@ -169,7 +172,7 @@ describe Gitlab::Git::Commit, seed_helper: true do
end
context 'ref + path' do
- subject { Gitlab::Git::Commit.last_for_path(repository, SeedRepo::Commit::ID, 'encoding') }
+ subject { described_class.last_for_path(repository, SeedRepo::Commit::ID, 'encoding') }
describe '#id' do
subject { super().id }
@@ -181,7 +184,7 @@ describe Gitlab::Git::Commit, seed_helper: true do
describe '.where' do
context 'path is empty string' do
subject do
- commits = Gitlab::Git::Commit.where(
+ commits = described_class.where(
repo: repository,
ref: 'master',
path: '',
@@ -199,7 +202,7 @@ describe Gitlab::Git::Commit, seed_helper: true do
context 'path is nil' do
subject do
- commits = Gitlab::Git::Commit.where(
+ commits = described_class.where(
repo: repository,
ref: 'master',
path: nil,
@@ -217,7 +220,7 @@ describe Gitlab::Git::Commit, seed_helper: true do
context 'ref is branch name' do
subject do
- commits = Gitlab::Git::Commit.where(
+ commits = described_class.where(
repo: repository,
ref: 'master',
path: 'files',
@@ -237,7 +240,7 @@ describe Gitlab::Git::Commit, seed_helper: true do
context 'ref is commit id' do
subject do
- commits = Gitlab::Git::Commit.where(
+ commits = described_class.where(
repo: repository,
ref: "874797c3a73b60d2187ed6e2fcabd289ff75171e",
path: 'files',
@@ -257,7 +260,7 @@ describe Gitlab::Git::Commit, seed_helper: true do
context 'ref is tag' do
subject do
- commits = Gitlab::Git::Commit.where(
+ commits = described_class.where(
repo: repository,
ref: 'v1.0.0',
path: 'files',
@@ -278,7 +281,7 @@ describe Gitlab::Git::Commit, seed_helper: true do
describe '.between' do
subject do
- commits = Gitlab::Git::Commit.between(repository, SeedRepo::Commit::PARENT_ID, SeedRepo::Commit::ID)
+ commits = described_class.between(repository, SeedRepo::Commit::PARENT_ID, SeedRepo::Commit::ID)
commits.map { |c| c.id }
end
@@ -294,12 +297,12 @@ describe Gitlab::Git::Commit, seed_helper: true do
it 'should return a return a collection of commits' do
commits = described_class.find_all(repository)
- expect(commits).to all( be_a_kind_of(Gitlab::Git::Commit) )
+ expect(commits).to all( be_a_kind_of(described_class) )
end
context 'max_count' do
subject do
- commits = Gitlab::Git::Commit.find_all(
+ commits = described_class.find_all(
repository,
max_count: 50
)
@@ -307,8 +310,8 @@ describe Gitlab::Git::Commit, seed_helper: true do
commits.map(&:id)
end
- it 'has 33 elements' do
- expect(subject.size).to eq(33)
+ it 'has 34 elements' do
+ expect(subject.size).to eq(34)
end
it 'includes the expected commits' do
@@ -322,7 +325,7 @@ describe Gitlab::Git::Commit, seed_helper: true do
context 'ref + max_count + skip' do
subject do
- commits = Gitlab::Git::Commit.find_all(
+ commits = described_class.find_all(
repository,
ref: 'master',
max_count: 50,
@@ -374,7 +377,7 @@ describe Gitlab::Git::Commit, seed_helper: true do
end
describe '#init_from_rugged' do
- let(:gitlab_commit) { Gitlab::Git::Commit.new(rugged_commit) }
+ let(:gitlab_commit) { described_class.new(repository, rugged_commit) }
subject { gitlab_commit }
describe '#id' do
@@ -384,7 +387,7 @@ describe Gitlab::Git::Commit, seed_helper: true do
end
describe '#init_from_hash' do
- let(:commit) { Gitlab::Git::Commit.new(sample_commit_hash) }
+ let(:commit) { described_class.new(repository, sample_commit_hash) }
subject { commit }
describe '#id' do
@@ -451,7 +454,7 @@ describe Gitlab::Git::Commit, seed_helper: true do
end
describe '#ref_names' do
- let(:commit) { Gitlab::Git::Commit.find(repository, 'master') }
+ let(:commit) { described_class.find(repository, 'master') }
subject { commit.ref_names(repository) }
it 'has 1 element' do
diff --git a/spec/lib/gitlab/git/diff_collection_spec.rb b/spec/lib/gitlab/git/diff_collection_spec.rb
index 0cfb210e390..3494f0cc98d 100644
--- a/spec/lib/gitlab/git/diff_collection_spec.rb
+++ b/spec/lib/gitlab/git/diff_collection_spec.rb
@@ -384,7 +384,7 @@ describe Gitlab::Git::DiffCollection, seed_helper: true do
context 'when go over safe limits on files' do
let(:iterator) { [fake_diff(1, 1)] * 4 }
- before(:each) do
+ before do
stub_const('Gitlab::Git::DiffCollection::DEFAULT_LIMITS', { max_files: 2, max_lines: max_lines })
end
@@ -409,7 +409,7 @@ describe Gitlab::Git::DiffCollection, seed_helper: true do
]
end
- before(:each) do
+ before do
stub_const('Gitlab::Git::DiffCollection::DEFAULT_LIMITS', { max_files: max_files, max_lines: 80 })
end
@@ -434,7 +434,7 @@ describe Gitlab::Git::DiffCollection, seed_helper: true do
]
end
- before(:each) do
+ before do
stub_const('Gitlab::Git::DiffCollection::DEFAULT_LIMITS', { max_files: max_files, max_lines: 80 })
end
diff --git a/spec/lib/gitlab/git/repository_spec.rb b/spec/lib/gitlab/git/repository_spec.rb
index 50736d353ad..4ef5d9070a2 100644
--- a/spec/lib/gitlab/git/repository_spec.rb
+++ b/spec/lib/gitlab/git/repository_spec.rb
@@ -22,7 +22,6 @@ describe Gitlab::Git::Repository, seed_helper: true do
describe "Respond to" do
subject { repository }
- it { is_expected.to respond_to(:raw) }
it { is_expected.to respond_to(:rugged) }
it { is_expected.to respond_to(:root_ref) }
it { is_expected.to respond_to(:tags) }
@@ -55,6 +54,20 @@ describe Gitlab::Git::Repository, seed_helper: true do
end
describe "#rugged" do
+ describe 'when storage is broken', broken_storage: true do
+ it 'raises a storage exception when storage is not available' do
+ broken_repo = described_class.new('broken', 'a/path.git')
+
+ expect { broken_repo.rugged }.to raise_error(Gitlab::Git::Storage::Inaccessible)
+ end
+ end
+
+ it 'raises a no repository exception when there is no repo' do
+ broken_repo = described_class.new('default', 'a/path.git')
+
+ expect { broken_repo.rugged }.to raise_error(Gitlab::Git::Repository::NoRepository)
+ end
+
context 'with no Git env stored' do
before do
expect(Gitlab::Git::Env).to receive(:all).and_return({})
@@ -276,7 +289,13 @@ describe Gitlab::Git::Repository, seed_helper: true do
it { expect(submodule_url('six')).to eq('git://github.com/randx/six.git') }
end
- context 'no submodules at commit' do
+ context 'no .gitmodules at commit' do
+ let(:ref) { '9596bc54a6f0c0c98248fe97077eb5ccf48a98d0' }
+
+ it { expect(submodule_url('six')).to eq(nil) }
+ end
+
+ context 'no gitlink entry' do
let(:ref) { '6d39438' }
it { expect(submodule_url('six')).to eq(nil) }
@@ -361,20 +380,20 @@ describe Gitlab::Git::Repository, seed_helper: true do
end
describe '#commit_count' do
- shared_examples 'counting commits' do
+ shared_examples 'simple commit counting' do
it { expect(repository.commit_count("master")).to eq(25) }
it { expect(repository.commit_count("feature")).to eq(9) }
end
context 'when Gitaly commit_count feature is enabled' do
- it_behaves_like 'counting commits'
+ it_behaves_like 'simple commit counting'
it_behaves_like 'wrapping gRPC errors', Gitlab::GitalyClient::CommitService, :commit_count do
subject { repository.commit_count('master') }
end
end
context 'when Gitaly commit_count feature is disabled', skip_gitaly_mock: true do
- it_behaves_like 'counting commits'
+ it_behaves_like 'simple commit counting'
end
end
@@ -409,11 +428,11 @@ describe Gitlab::Git::Repository, seed_helper: true do
it "should fail if we create an existing branch" do
@repo.create_branch('duplicated_branch', 'master')
- expect{@repo.create_branch('duplicated_branch', 'master')}.to raise_error("Branch duplicated_branch already exists")
+ expect {@repo.create_branch('duplicated_branch', 'master')}.to raise_error("Branch duplicated_branch already exists")
end
it "should fail if we create a branch from a non existing ref" do
- expect{@repo.create_branch('branch_based_in_wrong_ref', 'master_2_the_revenge')}.to raise_error("Invalid reference master_2_the_revenge")
+ expect {@repo.create_branch('branch_based_in_wrong_ref', 'master_2_the_revenge')}.to raise_error("Invalid reference master_2_the_revenge")
end
after(:all) do
@@ -492,17 +511,22 @@ describe Gitlab::Git::Repository, seed_helper: true do
end
describe "#log" do
- commit_with_old_name = nil
- commit_with_new_name = nil
- rename_commit = nil
+ let(:commit_with_old_name) do
+ Gitlab::Git::Commit.decorate(repository, @commit_with_old_name_id)
+ end
+ let(:commit_with_new_name) do
+ Gitlab::Git::Commit.decorate(repository, @commit_with_new_name_id)
+ end
+ let(:rename_commit) do
+ Gitlab::Git::Commit.decorate(repository, @rename_commit_id)
+ end
before(:context) do
# Add new commits so that there's a renamed file in the commit history
repo = Gitlab::Git::Repository.new('default', TEST_REPO_PATH).rugged
-
- commit_with_old_name = Gitlab::Git::Commit.decorate(new_commit_edit_old_file(repo))
- rename_commit = Gitlab::Git::Commit.decorate(new_commit_move_file(repo))
- commit_with_new_name = Gitlab::Git::Commit.decorate(new_commit_edit_new_file(repo))
+ @commit_with_old_name_id = new_commit_edit_old_file(repo)
+ @rename_commit_id = new_commit_move_file(repo)
+ @commit_with_new_name_id = new_commit_edit_new_file(repo)
end
after(:context) do
@@ -741,7 +765,7 @@ describe Gitlab::Git::Repository, seed_helper: true do
let(:options) { { ref: 'master', path: ['PROCESS.md', 'README.md'] } }
def commit_files(commit)
- commit.diff_from_parent.deltas.flat_map do |delta|
+ commit.rugged_diff_from_parent.deltas.flat_map do |delta|
[delta.old_file[:path], delta.new_file[:path]].uniq.compact
end
end
@@ -757,13 +781,13 @@ describe Gitlab::Git::Repository, seed_helper: true do
end
end
- describe "#commits_between" do
+ describe "#rugged_commits_between" do
context 'two SHAs' do
let(:first_sha) { 'b0e52af38d7ea43cf41d8a6f2471351ac036d6c9' }
let(:second_sha) { '0e50ec4d3c7ce42ab74dda1d422cb2cbffe1e326' }
it 'returns the number of commits between' do
- expect(repository.commits_between(first_sha, second_sha).count).to eq(3)
+ expect(repository.rugged_commits_between(first_sha, second_sha).count).to eq(3)
end
end
@@ -772,11 +796,11 @@ describe Gitlab::Git::Repository, seed_helper: true do
let(:branch) { 'master' }
it 'returns the number of commits between a sha and a branch' do
- expect(repository.commits_between(sha, branch).count).to eq(5)
+ expect(repository.rugged_commits_between(sha, branch).count).to eq(5)
end
it 'returns the number of commits between a branch and a sha' do
- expect(repository.commits_between(branch, sha).count).to eq(0) # sha is before branch
+ expect(repository.rugged_commits_between(branch, sha).count).to eq(0) # sha is before branch
end
end
@@ -785,7 +809,7 @@ describe Gitlab::Git::Repository, seed_helper: true do
let(:second_branch) { 'master' }
it 'returns the number of commits between' do
- expect(repository.commits_between(first_branch, second_branch).count).to eq(17)
+ expect(repository.rugged_commits_between(first_branch, second_branch).count).to eq(17)
end
end
end
@@ -797,28 +821,38 @@ describe Gitlab::Git::Repository, seed_helper: true do
end
describe '#count_commits' do
- context 'with after timestamp' do
- it 'returns the number of commits after timestamp' do
- options = { ref: 'master', limit: nil, after: Time.iso8601('2013-03-03T20:15:01+00:00') }
+ shared_examples 'extended commit counting' do
+ context 'with after timestamp' do
+ it 'returns the number of commits after timestamp' do
+ options = { ref: 'master', limit: nil, after: Time.iso8601('2013-03-03T20:15:01+00:00') }
- expect(repository.count_commits(options)).to eq(25)
+ expect(repository.count_commits(options)).to eq(25)
+ end
end
- end
- context 'with before timestamp' do
- it 'returns the number of commits after timestamp' do
- options = { ref: 'feature', limit: nil, before: Time.iso8601('2015-03-03T20:15:01+00:00') }
+ context 'with before timestamp' do
+ it 'returns the number of commits before timestamp' do
+ options = { ref: 'feature', limit: nil, before: Time.iso8601('2015-03-03T20:15:01+00:00') }
+
+ expect(repository.count_commits(options)).to eq(9)
+ end
+ end
+
+ context 'with path' do
+ it 'returns the number of commits with path ' do
+ options = { ref: 'master', limit: nil, path: "encoding" }
- expect(repository.count_commits(options)).to eq(9)
+ expect(repository.count_commits(options)).to eq(2)
+ end
end
end
- context 'with path' do
- it 'returns the number of commits with path ' do
- options = { ref: 'master', limit: nil, path: "encoding" }
+ context 'when Gitaly count_commits feature is enabled' do
+ it_behaves_like 'extended commit counting'
+ end
- expect(repository.count_commits(options)).to eq(2)
- end
+ context 'when Gitaly count_commits feature is disabled', skip_gitaly_mock: true do
+ it_behaves_like 'extended commit counting'
end
end
@@ -958,7 +992,7 @@ describe Gitlab::Git::Repository, seed_helper: true do
describe '#branch_count' do
it 'returns the number of branches' do
- expect(repository.branch_count).to eq(9)
+ expect(repository.branch_count).to eq(10)
end
end
@@ -974,7 +1008,7 @@ describe Gitlab::Git::Repository, seed_helper: true do
expect(master_file_paths).to include("files/html/500.html")
end
- it "dose not read submodule directory and empty directory of master branch" do
+ it "does not read submodule directory and empty directory of master branch" do
expect(master_file_paths).not_to include("six")
end
@@ -995,7 +1029,7 @@ describe Gitlab::Git::Repository, seed_helper: true do
end
context "with no .gitattrbutes" do
- before(:each) do
+ before do
repository.copy_gitattributes("master")
end
@@ -1003,13 +1037,13 @@ describe Gitlab::Git::Repository, seed_helper: true do
expect(File.exist?(attributes_path)).to be_falsey
end
- after(:each) do
+ after do
FileUtils.rm_rf(attributes_path)
end
end
context "with .gitattrbutes" do
- before(:each) do
+ before do
repository.copy_gitattributes("gitattributes")
end
@@ -1022,13 +1056,13 @@ describe Gitlab::Git::Repository, seed_helper: true do
expect(contents).to eq("*.md binary\n")
end
- after(:each) do
+ after do
FileUtils.rm_rf(attributes_path)
end
end
context "with updated .gitattrbutes" do
- before(:each) do
+ before do
repository.copy_gitattributes("gitattributes")
repository.copy_gitattributes("gitattributes-updated")
end
@@ -1042,13 +1076,13 @@ describe Gitlab::Git::Repository, seed_helper: true do
expect(contents).to eq("*.txt binary\n")
end
- after(:each) do
+ after do
FileUtils.rm_rf(attributes_path)
end
end
context "with no .gitattrbutes in HEAD but with previous info/attributes" do
- before(:each) do
+ before do
repository.copy_gitattributes("gitattributes")
repository.copy_gitattributes("master")
end
@@ -1057,7 +1091,7 @@ describe Gitlab::Git::Repository, seed_helper: true do
expect(File.exist?(attributes_path)).to be_falsey
end
- after(:each) do
+ after do
FileUtils.rm_rf(attributes_path)
end
end
@@ -1127,6 +1161,45 @@ describe Gitlab::Git::Repository, seed_helper: true do
end
end
+ describe '#languages' do
+ shared_examples 'languages' do
+ it 'returns exactly the expected results' do
+ languages = repository.languages('4b4918a572fa86f9771e5ba40fbd48e1eb03e2c6')
+ expected_languages = [
+ { value: 66.63, label: "Ruby", color: "#701516", highlight: "#701516" },
+ { value: 22.96, label: "JavaScript", color: "#f1e05a", highlight: "#f1e05a" },
+ { value: 7.9, label: "HTML", color: "#e44b23", highlight: "#e44b23" },
+ { value: 2.51, label: "CoffeeScript", color: "#244776", highlight: "#244776" }
+ ]
+
+ expect(languages.size).to eq(expected_languages.size)
+
+ expected_languages.size.times do |i|
+ a = expected_languages[i]
+ b = languages[i]
+
+ expect(a.keys.sort).to eq(b.keys.sort)
+ expect(a[:value]).to be_within(0.1).of(b[:value])
+
+ non_float_keys = a.keys - [:value]
+ expect(a.values_at(*non_float_keys)).to eq(b.values_at(*non_float_keys))
+ end
+ end
+
+ it "uses the repository's HEAD when no ref is passed" do
+ lang = repository.languages.first
+
+ expect(lang[:label]).to eq('Ruby')
+ end
+ end
+
+ it_behaves_like 'languages'
+
+ context 'with rugged', skip_gitaly_mock: true do
+ it_behaves_like 'languages'
+ end
+ end
+
def create_remote_branch(repository, remote_name, branch_name, source_branch_name)
source_branch = repository.branches.find { |branch| branch.name == source_branch_name }
rugged = repository.rugged
diff --git a/spec/lib/gitlab/git/storage/circuit_breaker_spec.rb b/spec/lib/gitlab/git/storage/circuit_breaker_spec.rb
new file mode 100644
index 00000000000..9d1763b96ad
--- /dev/null
+++ b/spec/lib/gitlab/git/storage/circuit_breaker_spec.rb
@@ -0,0 +1,290 @@
+require 'spec_helper'
+
+describe Gitlab::Git::Storage::CircuitBreaker, clean_gitlab_redis_shared_state: true, broken_storage: true do
+ let(:circuit_breaker) { described_class.new('default') }
+ let(:hostname) { Gitlab::Environment.hostname }
+ let(:cache_key) { "storage_accessible:default:#{hostname}" }
+
+ def value_from_redis(name)
+ Gitlab::Git::Storage.redis.with do |redis|
+ redis.hmget(cache_key, name)
+ end.first
+ end
+
+ def set_in_redis(name, value)
+ Gitlab::Git::Storage.redis.with do |redis|
+ redis.hmset(cache_key, name, value)
+ end.first
+ end
+
+ describe '.reset_all!' do
+ it 'clears all entries form redis' do
+ set_in_redis(:failure_count, 10)
+
+ described_class.reset_all!
+
+ key_exists = Gitlab::Git::Storage.redis.with { |redis| redis.exists(cache_key) }
+
+ expect(key_exists).to be_falsey
+ end
+ end
+
+ describe '.for_storage' do
+ it 'only builds a single circuitbreaker per storage' do
+ expect(described_class).to receive(:new).once.and_call_original
+
+ breaker = described_class.for_storage('default')
+
+ expect(breaker).to be_a(described_class)
+ expect(described_class.for_storage('default')).to eq(breaker)
+ end
+ end
+
+ describe '#initialize' do
+ it 'assigns the settings' do
+ expect(circuit_breaker.hostname).to eq(hostname)
+ expect(circuit_breaker.storage).to eq('default')
+ expect(circuit_breaker.storage_path).to eq(TestEnv.repos_path)
+ expect(circuit_breaker.failure_count_threshold).to eq(10)
+ expect(circuit_breaker.failure_wait_time).to eq(30)
+ expect(circuit_breaker.failure_reset_time).to eq(1800)
+ expect(circuit_breaker.storage_timeout).to eq(5)
+ end
+ end
+
+ describe '#perform' do
+ it 'raises an exception with retry time when the circuit is open' do
+ allow(circuit_breaker).to receive(:circuit_broken?).and_return(true)
+
+ expect { |b| circuit_breaker.perform(&b) }
+ .to raise_error(Gitlab::Git::Storage::CircuitOpen)
+ end
+
+ it 'yields the block' do
+ expect { |b| circuit_breaker.perform(&b) }
+ .to yield_control
+ end
+
+ it 'checks if the storage is available' do
+ expect(circuit_breaker).to receive(:check_storage_accessible!)
+
+ circuit_breaker.perform { 'hello world' }
+ end
+
+ it 'returns the value of the block' do
+ result = circuit_breaker.perform { 'return value' }
+
+ expect(result).to eq('return value')
+ end
+
+ it 'raises possible errors' do
+ expect { circuit_breaker.perform { raise Rugged::OSError.new('Broken') } }
+ .to raise_error(Rugged::OSError)
+ end
+
+ context 'with the feature disabled' do
+ it 'returns the block without checking accessibility' do
+ stub_feature_flags(git_storage_circuit_breaker: false)
+
+ expect(circuit_breaker).not_to receive(:circuit_broken?)
+
+ result = circuit_breaker.perform { 'hello' }
+
+ expect(result).to eq('hello')
+ end
+ end
+ end
+
+ describe '#circuit_broken?' do
+ it 'is closed when there is no last failure' do
+ set_in_redis(:last_failure, nil)
+ set_in_redis(:failure_count, 0)
+
+ expect(circuit_breaker.circuit_broken?).to be_falsey
+ end
+
+ it 'is open when there was a recent failure' do
+ Timecop.freeze do
+ set_in_redis(:last_failure, 1.second.ago.to_f)
+ set_in_redis(:failure_count, 1)
+
+ expect(circuit_breaker.circuit_broken?).to be_truthy
+ end
+ end
+
+ it 'is open when there are to many failures' do
+ set_in_redis(:last_failure, 1.day.ago.to_f)
+ set_in_redis(:failure_count, 200)
+
+ expect(circuit_breaker.circuit_broken?).to be_truthy
+ end
+ end
+
+ describe "storage_available?" do
+ context 'when the storage is available' do
+ it 'tracks that the storage was accessible an raises the error' do
+ expect(circuit_breaker).to receive(:track_storage_accessible)
+
+ circuit_breaker.storage_available?
+ end
+
+ it 'only performs the check once' do
+ expect(Gitlab::Git::Storage::ForkedStorageCheck)
+ .to receive(:storage_available?).once.and_call_original
+
+ 2.times { circuit_breaker.storage_available? }
+ end
+ end
+
+ context 'when storage is not available' do
+ let(:circuit_breaker) { described_class.new('broken') }
+
+ it 'tracks that the storage was inaccessible' do
+ expect(circuit_breaker).to receive(:track_storage_inaccessible)
+
+ circuit_breaker.storage_available?
+ end
+ end
+ end
+
+ describe '#check_storage_accessible!' do
+ it 'raises an exception with retry time when the circuit is open' do
+ allow(circuit_breaker).to receive(:circuit_broken?).and_return(true)
+
+ expect { circuit_breaker.check_storage_accessible! }
+ .to raise_error do |exception|
+ expect(exception).to be_kind_of(Gitlab::Git::Storage::CircuitOpen)
+ expect(exception.retry_after).to eq(30)
+ end
+ end
+
+ context 'when the storage is not available' do
+ let(:circuit_breaker) { described_class.new('broken') }
+
+ it 'raises an error' do
+ expect(circuit_breaker).to receive(:track_storage_inaccessible)
+
+ expect { circuit_breaker.check_storage_accessible! }
+ .to raise_error do |exception|
+ expect(exception).to be_kind_of(Gitlab::Git::Storage::Inaccessible)
+ expect(exception.retry_after).to eq(30)
+ end
+ end
+ end
+ end
+
+ describe '#track_storage_inaccessible' do
+ around do |example|
+ Timecop.freeze { example.run }
+ end
+
+ it 'records the failure time in redis' do
+ circuit_breaker.track_storage_inaccessible
+
+ failure_time = value_from_redis(:last_failure)
+
+ expect(Time.at(failure_time.to_i)).to be_within(1.second).of(Time.now)
+ end
+
+ it 'sets the failure time on the breaker without reloading' do
+ circuit_breaker.track_storage_inaccessible
+
+ expect(circuit_breaker).not_to receive(:get_failure_info)
+ expect(circuit_breaker.last_failure).to eq(Time.now)
+ end
+
+ it 'increments the failure count in redis' do
+ set_in_redis(:failure_count, 10)
+
+ circuit_breaker.track_storage_inaccessible
+
+ expect(value_from_redis(:failure_count).to_i).to be(11)
+ end
+
+ it 'increments the failure count on the breaker without reloading' do
+ set_in_redis(:failure_count, 10)
+
+ circuit_breaker.track_storage_inaccessible
+
+ expect(circuit_breaker).not_to receive(:get_failure_info)
+ expect(circuit_breaker.failure_count).to eq(11)
+ end
+ end
+
+ describe '#track_storage_accessible' do
+ it 'sets the failure count to zero in redis' do
+ set_in_redis(:failure_count, 10)
+
+ circuit_breaker.track_storage_accessible
+
+ expect(value_from_redis(:failure_count).to_i).to be(0)
+ end
+
+ it 'sets the failure count to zero on the breaker without reloading' do
+ set_in_redis(:failure_count, 10)
+
+ circuit_breaker.track_storage_accessible
+
+ expect(circuit_breaker).not_to receive(:get_failure_info)
+ expect(circuit_breaker.failure_count).to eq(0)
+ end
+
+ it 'removes the last failure time from redis' do
+ set_in_redis(:last_failure, Time.now.to_i)
+
+ circuit_breaker.track_storage_accessible
+
+ expect(circuit_breaker).not_to receive(:get_failure_info)
+ expect(circuit_breaker.last_failure).to be_nil
+ end
+
+ it 'removes the last failure time from the breaker without reloading' do
+ set_in_redis(:last_failure, Time.now.to_i)
+
+ circuit_breaker.track_storage_accessible
+
+ expect(value_from_redis(:last_failure)).to be_empty
+ end
+
+ it 'wont connect to redis when there are no failures' do
+ expect(Gitlab::Git::Storage.redis).to receive(:with).once
+ .and_call_original
+ expect(circuit_breaker).to receive(:track_storage_accessible)
+ .and_call_original
+
+ circuit_breaker.track_storage_accessible
+ end
+ end
+
+ describe '#no_failures?' do
+ it 'is false when a failure was tracked' do
+ set_in_redis(:last_failure, Time.now.to_i)
+ set_in_redis(:failure_count, 1)
+
+ expect(circuit_breaker.no_failures?).to be_falsey
+ end
+ end
+
+ describe '#last_failure' do
+ it 'returns the last failure time' do
+ time = Time.parse("2017-05-26 17:52:30")
+ set_in_redis(:last_failure, time.to_i)
+
+ expect(circuit_breaker.last_failure).to eq(time)
+ end
+ end
+
+ describe '#failure_count' do
+ it 'returns the failure count' do
+ set_in_redis(:failure_count, 7)
+
+ expect(circuit_breaker.failure_count).to eq(7)
+ end
+ end
+
+ describe '#cache_key' do
+ it 'includes storage and host' do
+ expect(circuit_breaker.cache_key).to eq(cache_key)
+ end
+ end
+end
diff --git a/spec/lib/gitlab/git/storage/forked_storage_check_spec.rb b/spec/lib/gitlab/git/storage/forked_storage_check_spec.rb
new file mode 100644
index 00000000000..12366151f44
--- /dev/null
+++ b/spec/lib/gitlab/git/storage/forked_storage_check_spec.rb
@@ -0,0 +1,58 @@
+require 'spec_helper'
+
+describe Gitlab::Git::Storage::ForkedStorageCheck, skip_database_cleaner: true do
+ let(:existing_path) do
+ existing_path = TestEnv.repos_path
+ FileUtils.mkdir_p(existing_path)
+ existing_path
+ end
+
+ describe '.storage_accessible?' do
+ it 'detects when a storage is not available' do
+ expect(described_class.storage_available?('/non/existant/path')).to be_falsey
+ end
+
+ it 'detects when a storage is available' do
+ expect(described_class.storage_available?(existing_path)).to be_truthy
+ end
+
+ it 'returns false when the check takes to long' do
+ # We're forking a process here that takes too long
+ # It will be killed it's parent process will be killed by it's parent
+ # and waited for inside `Gitlab::Git::Storage::ForkedStorageCheck.timeout_check`
+ allow(described_class).to receive(:check_filesystem_in_process) do
+ Process.spawn("sleep 10")
+ end
+ result = true
+
+ runtime = Benchmark.realtime do
+ result = described_class.storage_available?(existing_path, 0.5)
+ end
+
+ expect(result).to be_falsey
+ expect(runtime).to be < 1.0
+ end
+
+ describe 'when using paths with spaces' do
+ let(:test_dir) { Rails.root.join('tmp', 'tests', 'storage_check') }
+ let(:path_with_spaces) { File.join(test_dir, 'path with spaces') }
+
+ around do |example|
+ FileUtils.mkdir_p(path_with_spaces)
+ example.run
+ FileUtils.rm_r(test_dir)
+ end
+
+ it 'works for paths with spaces' do
+ expect(described_class.storage_available?(path_with_spaces)).to be_truthy
+ end
+
+ it 'works for a realpath with spaces' do
+ symlink_location = File.join(test_dir, 'a symlink')
+ FileUtils.ln_s(path_with_spaces, symlink_location)
+
+ expect(described_class.storage_available?(symlink_location)).to be_truthy
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/git/storage/health_spec.rb b/spec/lib/gitlab/git/storage/health_spec.rb
new file mode 100644
index 00000000000..2d3af387971
--- /dev/null
+++ b/spec/lib/gitlab/git/storage/health_spec.rb
@@ -0,0 +1,87 @@
+require 'spec_helper'
+
+describe Gitlab::Git::Storage::Health, clean_gitlab_redis_shared_state: true, broken_storage: true do
+ let(:host1_key) { 'storage_accessible:broken:web01' }
+ let(:host2_key) { 'storage_accessible:default:kiq01' }
+
+ def set_in_redis(cache_key, value)
+ Gitlab::Git::Storage.redis.with do |redis|
+ redis.hmset(cache_key, :failure_count, value)
+ end.first
+ end
+
+ describe '.for_failing_storages' do
+ it 'only includes health status for failures' do
+ set_in_redis(host1_key, 10)
+ set_in_redis(host2_key, 0)
+
+ expect(described_class.for_failing_storages.map(&:storage_name))
+ .to contain_exactly('broken')
+ end
+ end
+
+ describe '.load_for_keys' do
+ let(:subject) do
+ results = Gitlab::Git::Storage.redis.with do |redis|
+ fake_future = double
+ allow(fake_future).to receive(:value).and_return([host1_key])
+ described_class.load_for_keys({ 'broken' => fake_future }, redis)
+ end
+
+ # Make sure the `Redis#future is loaded
+ results.inject({}) do |result, (name, info)|
+ info.each { |i| i[:failure_count] = i[:failure_count].value.to_i }
+
+ result[name] = info
+
+ result
+ end
+ end
+
+ it 'loads when there is no info in redis' do
+ expect(subject).to eq('broken' => [{ name: host1_key, failure_count: 0 }])
+ end
+
+ it 'reads the correct values for a storage from redis' do
+ set_in_redis(host1_key, 5)
+ set_in_redis(host2_key, 7)
+
+ expect(subject).to eq('broken' => [{ name: host1_key, failure_count: 5 }])
+ end
+ end
+
+ describe '.for_all_storages' do
+ it 'loads health status for all configured storages' do
+ healths = described_class.for_all_storages
+
+ expect(healths.map(&:storage_name)).to contain_exactly('default', 'broken')
+ end
+ end
+
+ describe '#failing_info' do
+ it 'only contains storages that have failures' do
+ health = described_class.new('broken', [{ name: host1_key, failure_count: 0 },
+ { name: host2_key, failure_count: 3 }])
+
+ expect(health.failing_info).to contain_exactly({ name: host2_key, failure_count: 3 })
+ end
+ end
+
+ describe '#total_failures' do
+ it 'sums up all the failures' do
+ health = described_class.new('broken', [{ name: host1_key, failure_count: 2 },
+ { name: host2_key, failure_count: 3 }])
+
+ expect(health.total_failures).to eq(5)
+ end
+ end
+
+ describe '#failing_on_hosts' do
+ it 'collects only the failing hostnames' do
+ health = described_class.new('broken', [{ name: host1_key, failure_count: 2 },
+ { name: host2_key, failure_count: 0 }])
+
+ expect(health.failing_on_hosts).to contain_exactly('web01')
+ end
+ end
+end
diff --git a/spec/lib/gitlab/gitaly_client/commit_service_spec.rb b/spec/lib/gitlab/gitaly_client/commit_service_spec.rb
index 0868c793a33..7fe698fcb18 100644
--- a/spec/lib/gitlab/gitaly_client/commit_service_spec.rb
+++ b/spec/lib/gitlab/gitaly_client/commit_service_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe Gitlab::GitalyClient::CommitService do
let(:project) { create(:project, :repository) }
let(:storage_name) { project.repository_storage }
- let(:relative_path) { project.path_with_namespace + '.git' }
+ let(:relative_path) { project.disk_path + '.git' }
let(:repository) { project.repository }
let(:repository_message) { repository.gitaly_repository }
let(:revision) { '913c66a37b4a45b9769037c55c2d238bd0942d2e' }
@@ -30,7 +30,7 @@ describe Gitlab::GitalyClient::CommitService do
context 'when a commit does not have a parent' do
it 'sends an RPC request with empty tree ref as left commit' do
- initial_commit = project.commit('1a0b36b3cdad1d2ee32457c102a8c0b7056fa863')
+ initial_commit = project.commit('1a0b36b3cdad1d2ee32457c102a8c0b7056fa863').raw
request = Gitaly::CommitDiffRequest.new(
repository: repository_message,
left_commit_id: '4b825dc642cb6eb9a060e54bf8d69288fbee4904',
@@ -46,18 +46,10 @@ describe Gitlab::GitalyClient::CommitService do
end
end
- it 'returns a Gitlab::Git::DiffCollection' do
+ it 'returns a Gitlab::GitalyClient::DiffStitcher' do
ret = client.diff_from_parent(commit)
- expect(ret).to be_kind_of(Gitlab::Git::DiffCollection)
- end
-
- it 'passes options to Gitlab::Git::DiffCollection' do
- options = { max_files: 31, max_lines: 13, from_gitaly: true }
-
- expect(Gitlab::Git::DiffCollection).to receive(:new).with(kind_of(Enumerable), options)
-
- client.diff_from_parent(commit, options)
+ expect(ret).to be_kind_of(Gitlab::GitalyClient::DiffStitcher)
end
end
@@ -120,4 +112,18 @@ describe Gitlab::GitalyClient::CommitService do
client.tree_entries(repository, revision, path)
end
end
+
+ describe '#find_commit' do
+ let(:revision) { '4b825dc642cb6eb9a060e54bf8d69288fbee4904' }
+ it 'sends an RPC request' do
+ request = Gitaly::FindCommitRequest.new(
+ repository: repository_message, revision: revision
+ )
+
+ expect_any_instance_of(Gitaly::CommitService::Stub).to receive(:find_commit)
+ .with(request, kind_of(Hash)).and_return(double(commit: nil))
+
+ described_class.new(repository).find_commit(revision)
+ end
+ end
end
diff --git a/spec/lib/gitlab/gitaly_client/notification_service_spec.rb b/spec/lib/gitlab/gitaly_client/notification_service_spec.rb
index d9597c4aa78..ffc3a09be30 100644
--- a/spec/lib/gitlab/gitaly_client/notification_service_spec.rb
+++ b/spec/lib/gitlab/gitaly_client/notification_service_spec.rb
@@ -2,9 +2,9 @@ require 'spec_helper'
describe Gitlab::GitalyClient::NotificationService do
describe '#post_receive' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:storage_name) { project.repository_storage }
- let(:relative_path) { project.path_with_namespace + '.git' }
+ let(:relative_path) { project.disk_path + '.git' }
subject { described_class.new(project.repository) }
it 'sends a post_receive message' do
diff --git a/spec/lib/gitlab/gitaly_client/ref_service_spec.rb b/spec/lib/gitlab/gitaly_client/ref_service_spec.rb
index 0b1c890f956..46efc1b18f0 100644
--- a/spec/lib/gitlab/gitaly_client/ref_service_spec.rb
+++ b/spec/lib/gitlab/gitaly_client/ref_service_spec.rb
@@ -1,9 +1,9 @@
require 'spec_helper'
describe Gitlab::GitalyClient::RefService do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:storage_name) { project.repository_storage }
- let(:relative_path) { project.path_with_namespace + '.git' }
+ let(:relative_path) { project.disk_path + '.git' }
let(:client) { described_class.new(project.repository) }
describe '#branches' do
diff --git a/spec/lib/gitlab/gitaly_client/repository_service_spec.rb b/spec/lib/gitlab/gitaly_client/repository_service_spec.rb
deleted file mode 100644
index 5a9f3fc130c..00000000000
--- a/spec/lib/gitlab/gitaly_client/repository_service_spec.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-require 'spec_helper'
-
-describe Gitlab::GitalyClient::RepositoryService do
- set(:project) { create(:empty_project) }
- let(:storage_name) { project.repository_storage }
- let(:relative_path) { project.path_with_namespace + '.git' }
- let(:client) { described_class.new(project.repository) }
-
- describe '#exists?' do
- it 'sends an exists message' do
- expect_any_instance_of(Gitaly::RepositoryService::Stub)
- .to receive(:exists)
- .with(gitaly_request_with_path(storage_name, relative_path), kind_of(Hash))
- .and_call_original
-
- client.exists?
- end
- end
-end
diff --git a/spec/lib/gitlab/github_import/comment_formatter_spec.rb b/spec/lib/gitlab/github_import/comment_formatter_spec.rb
index ef89634685a..035ac8c7c1f 100644
--- a/spec/lib/gitlab/github_import/comment_formatter_spec.rb
+++ b/spec/lib/gitlab/github_import/comment_formatter_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe Gitlab::GithubImport::CommentFormatter do
let(:client) { double }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:octocat) { double(id: 123456, login: 'octocat', email: 'octocat@example.com') }
let(:created_at) { DateTime.strptime('2013-04-10T20:09:31Z') }
let(:updated_at) { DateTime.strptime('2014-03-03T18:58:10Z') }
diff --git a/spec/lib/gitlab/github_import/importer_spec.rb b/spec/lib/gitlab/github_import/importer_spec.rb
index d00a2deaf7b..d570f34985b 100644
--- a/spec/lib/gitlab/github_import/importer_spec.rb
+++ b/spec/lib/gitlab/github_import/importer_spec.rb
@@ -207,7 +207,7 @@ describe Gitlab::GithubImport::Importer do
end
end
- let(:project) { create(:project, :wiki_disabled, import_url: "#{repo_root}/octocat/Hello-World.git") }
+ let(:project) { create(:project, :repository, :wiki_disabled, import_url: "#{repo_root}/octocat/Hello-World.git") }
let(:octocat) { double(id: 123456, login: 'octocat', email: 'octocat@example.com') }
let(:credentials) { { user: 'joe' } }
diff --git a/spec/lib/gitlab/github_import/issue_formatter_spec.rb b/spec/lib/gitlab/github_import/issue_formatter_spec.rb
index 39b15926193..0fc56d92aa6 100644
--- a/spec/lib/gitlab/github_import/issue_formatter_spec.rb
+++ b/spec/lib/gitlab/github_import/issue_formatter_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe Gitlab::GithubImport::IssueFormatter do
let(:client) { double }
- let!(:project) { create(:empty_project, namespace: create(:namespace, path: 'octocat')) }
+ let!(:project) { create(:project, namespace: create(:namespace, path: 'octocat')) }
let(:octocat) { double(id: 123456, login: 'octocat', email: 'octocat@example.com') }
let(:created_at) { DateTime.strptime('2011-01-26T19:01:12Z') }
let(:updated_at) { DateTime.strptime('2011-01-27T19:01:12Z') }
diff --git a/spec/lib/gitlab/github_import/label_formatter_spec.rb b/spec/lib/gitlab/github_import/label_formatter_spec.rb
index 2cc7ac0b446..83fdd2cc415 100644
--- a/spec/lib/gitlab/github_import/label_formatter_spec.rb
+++ b/spec/lib/gitlab/github_import/label_formatter_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Gitlab::GithubImport::LabelFormatter do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:raw) { double(name: 'improvements', color: 'e6e6e6') }
subject { described_class.new(project, raw) }
diff --git a/spec/lib/gitlab/github_import/milestone_formatter_spec.rb b/spec/lib/gitlab/github_import/milestone_formatter_spec.rb
index 310e0536fd7..683fa51b78e 100644
--- a/spec/lib/gitlab/github_import/milestone_formatter_spec.rb
+++ b/spec/lib/gitlab/github_import/milestone_formatter_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Gitlab::GithubImport::MilestoneFormatter do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:created_at) { DateTime.strptime('2011-01-26T19:01:12Z') }
let(:updated_at) { DateTime.strptime('2011-01-27T19:01:12Z') }
let(:base_data) do
diff --git a/spec/lib/gitlab/github_import/release_formatter_spec.rb b/spec/lib/gitlab/github_import/release_formatter_spec.rb
index 1357cb636ae..926bf725d6a 100644
--- a/spec/lib/gitlab/github_import/release_formatter_spec.rb
+++ b/spec/lib/gitlab/github_import/release_formatter_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Gitlab::GithubImport::ReleaseFormatter do
- let!(:project) { create(:empty_project, namespace: create(:namespace, path: 'octocat')) }
+ let!(:project) { create(:project, namespace: create(:namespace, path: 'octocat')) }
let(:octocat) { double(id: 123456, login: 'octocat') }
let(:created_at) { DateTime.strptime('2011-01-26T19:01:12Z') }
diff --git a/spec/lib/gitlab/github_import/wiki_formatter_spec.rb b/spec/lib/gitlab/github_import/wiki_formatter_spec.rb
index de50265bc14..fcd90fab547 100644
--- a/spec/lib/gitlab/github_import/wiki_formatter_spec.rb
+++ b/spec/lib/gitlab/github_import/wiki_formatter_spec.rb
@@ -9,9 +9,9 @@ describe Gitlab::GithubImport::WikiFormatter do
subject(:wiki) { described_class.new(project) }
- describe '#path_with_namespace' do
+ describe '#disk_path' do
it 'appends .wiki to project path' do
- expect(wiki.path_with_namespace).to eq 'gitlabhq/gitlabhq.wiki'
+ expect(wiki.disk_path).to eq project.disk_path + '.wiki'
end
end
diff --git a/spec/lib/gitlab/gitlab_import/importer_spec.rb b/spec/lib/gitlab/gitlab_import/importer_spec.rb
index 16b14474b89..e1d935602b5 100644
--- a/spec/lib/gitlab/gitlab_import/importer_spec.rb
+++ b/spec/lib/gitlab/gitlab_import/importer_spec.rb
@@ -24,7 +24,7 @@ describe Gitlab::GitlabImport::Importer do
end
it 'persists issues' do
- project = create(:empty_project, import_source: 'asd/vim')
+ project = create(:project, import_source: 'asd/vim')
project.build_import_data(credentials: { password: 'password' })
subject = described_class.new(project)
diff --git a/spec/lib/gitlab/gitlab_import/project_creator_spec.rb b/spec/lib/gitlab/gitlab_import/project_creator_spec.rb
index da48d8f0670..82548c7fd31 100644
--- a/spec/lib/gitlab/gitlab_import/project_creator_spec.rb
+++ b/spec/lib/gitlab/gitlab_import/project_creator_spec.rb
@@ -12,7 +12,7 @@ describe Gitlab::GitlabImport::ProjectCreator do
owner: { name: "john" }
}.with_indifferent_access
end
- let(:namespace){ create(:group, owner: user) }
+ let(:namespace) { create(:group, owner: user) }
let(:token) { "asdffg" }
let(:access_params) { { gitlab_access_token: token } }
diff --git a/spec/lib/gitlab/gl_repository_spec.rb b/spec/lib/gitlab/gl_repository_spec.rb
index ac3558ab386..4e09020471b 100644
--- a/spec/lib/gitlab/gl_repository_spec.rb
+++ b/spec/lib/gitlab/gl_repository_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe ::Gitlab::GlRepository do
describe '.parse' do
- set(:project) { create(:project) }
+ set(:project) { create(:project, :repository) }
it 'parses a project gl_repository' do
expect(described_class.parse("project-#{project.id}")).to eq([project, false])
diff --git a/spec/lib/gitlab/google_code_import/importer_spec.rb b/spec/lib/gitlab/google_code_import/importer_spec.rb
index 85f40825005..798ea0bac58 100644
--- a/spec/lib/gitlab/google_code_import/importer_spec.rb
+++ b/spec/lib/gitlab/google_code_import/importer_spec.rb
@@ -10,7 +10,7 @@ describe Gitlab::GoogleCodeImport::Importer do
'user_map' => { 'thilo...' => "@#{mapped_user.username}" }
}
end
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
subject { described_class.new(project) }
diff --git a/spec/lib/gitlab/google_code_import/project_creator_spec.rb b/spec/lib/gitlab/google_code_import/project_creator_spec.rb
index aad53938d52..8d5b60d50de 100644
--- a/spec/lib/gitlab/google_code_import/project_creator_spec.rb
+++ b/spec/lib/gitlab/google_code_import/project_creator_spec.rb
@@ -9,7 +9,7 @@ describe Gitlab::GoogleCodeImport::ProjectCreator do
"repositoryUrls" => ["https://vim.googlecode.com/git/"]
)
end
- let(:namespace){ create(:group, owner: user) }
+ let(:namespace) { create(:group, owner: user) }
before do
namespace.add_owner(user)
diff --git a/spec/lib/gitlab/gpg_spec.rb b/spec/lib/gitlab/gpg_spec.rb
index 8041518117d..30ad033b204 100644
--- a/spec/lib/gitlab/gpg_spec.rb
+++ b/spec/lib/gitlab/gpg_spec.rb
@@ -43,6 +43,58 @@ describe Gitlab::Gpg do
).to eq []
end
end
+
+ describe '.current_home_dir' do
+ let(:default_home_dir) { GPGME::Engine.dirinfo('homedir') }
+
+ it 'returns the default value when no explicit home dir has been set' do
+ expect(described_class.current_home_dir).to eq default_home_dir
+ end
+
+ it 'returns the explicitely set home dir' do
+ GPGME::Engine.home_dir = '/tmp/gpg'
+
+ expect(described_class.current_home_dir).to eq '/tmp/gpg'
+
+ GPGME::Engine.home_dir = GPGME::Engine.dirinfo('homedir')
+ end
+
+ it 'returns the default value when explicitely setting the home dir to nil' do
+ GPGME::Engine.home_dir = nil
+
+ expect(described_class.current_home_dir).to eq default_home_dir
+ end
+ end
+
+ describe '.using_tmp_keychain' do
+ it "the second thread does not change the first thread's directory" do
+ thread1 = Thread.new do
+ described_class.using_tmp_keychain do
+ dir = described_class.current_home_dir
+ sleep 0.1
+ expect(described_class.current_home_dir).to eq dir
+ end
+ end
+
+ thread2 = Thread.new do
+ described_class.using_tmp_keychain do
+ sleep 0.2
+ end
+ end
+
+ thread1.join
+ thread2.join
+ end
+
+ it 'allows recursive execution in the same thread' do
+ expect do
+ described_class.using_tmp_keychain do
+ described_class.using_tmp_keychain do
+ end
+ end
+ end.not_to raise_error(ThreadError)
+ end
+ end
end
describe Gitlab::Gpg::CurrentKeyChain do
diff --git a/spec/lib/gitlab/graphs/commits_spec.rb b/spec/lib/gitlab/graphs/commits_spec.rb
index 3f9382a9143..b2084f56640 100644
--- a/spec/lib/gitlab/graphs/commits_spec.rb
+++ b/spec/lib/gitlab/graphs/commits_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Gitlab::Graphs::Commits do
- let!(:project) { create(:empty_project, :public) }
+ let!(:project) { create(:project, :public) }
let!(:commit1) { create(:commit, git_commit: RepoHelpers.sample_commit, project: project, committed_date: Time.now) }
let!(:commit1_yesterday) { create(:commit, git_commit: RepoHelpers.sample_commit, project: project, committed_date: 1.day.ago)}
diff --git a/spec/lib/gitlab/health_checks/fs_shards_check_spec.rb b/spec/lib/gitlab/health_checks/fs_shards_check_spec.rb
index 8abc4320c59..f5c9680bf59 100644
--- a/spec/lib/gitlab/health_checks/fs_shards_check_spec.rb
+++ b/spec/lib/gitlab/health_checks/fs_shards_check_spec.rb
@@ -44,6 +44,15 @@ describe Gitlab::HealthChecks::FsShardsCheck do
describe '#readiness' do
subject { described_class.readiness }
+ context 'storage has a tripped circuitbreaker', broken_storage: true do
+ let(:repository_storages) { ['broken'] }
+ let(:storages_paths) do
+ Gitlab.config.repositories.storages
+ end
+
+ it { is_expected.to include(result_class.new(false, 'circuitbreaker tripped', shard: 'broken')) }
+ end
+
context 'storage points to not existing folder' do
let(:storages_paths) do
{
@@ -51,6 +60,10 @@ describe Gitlab::HealthChecks::FsShardsCheck do
}.with_indifferent_access
end
+ before do
+ allow(described_class).to receive(:storage_circuitbreaker_test) { true }
+ end
+
it { is_expected.to include(result_class.new(false, 'cannot stat storage', shard: :default)) }
end
@@ -93,12 +106,6 @@ describe Gitlab::HealthChecks::FsShardsCheck do
}.with_indifferent_access
end
- # Unsolved intermittent failure in CI https://gitlab.com/gitlab-org/gitlab-ce/issues/31128
- around(:each) do |example| # rubocop:disable RSpec/AroundBlock
- times_to_try = ENV['CI'] ? 4 : 1
- example.run_with_retry retry: times_to_try
- end
-
it 'provides metrics' do
metrics = described_class.metrics
@@ -109,6 +116,7 @@ describe Gitlab::HealthChecks::FsShardsCheck do
expect(metrics).to include(an_object_having_attributes(name: :filesystem_access_latency_seconds, value: be >= 0))
expect(metrics).to include(an_object_having_attributes(name: :filesystem_read_latency_seconds, value: be >= 0))
expect(metrics).to include(an_object_having_attributes(name: :filesystem_write_latency_seconds, value: be >= 0))
+ expect(metrics).to include(an_object_having_attributes(name: :filesystem_circuitbreaker_latency_seconds, value: be >= 0))
end
end
@@ -127,6 +135,7 @@ describe Gitlab::HealthChecks::FsShardsCheck do
expect(metrics).to include(an_object_having_attributes(name: :filesystem_access_latency_seconds, value: be >= 0))
expect(metrics).to include(an_object_having_attributes(name: :filesystem_read_latency_seconds, value: be >= 0))
expect(metrics).to include(an_object_having_attributes(name: :filesystem_write_latency_seconds, value: be >= 0))
+ expect(metrics).to include(an_object_having_attributes(name: :filesystem_circuitbreaker_latency_seconds, value: be >= 0))
end
it 'cleans up files used for metrics' do
diff --git a/spec/lib/gitlab/identifier_spec.rb b/spec/lib/gitlab/identifier_spec.rb
index 29912da2e25..cfaeb1f0d4f 100644
--- a/spec/lib/gitlab/identifier_spec.rb
+++ b/spec/lib/gitlab/identifier_spec.rb
@@ -5,7 +5,7 @@ describe Gitlab::Identifier do
Class.new { include Gitlab::Identifier }.new
end
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:user) { create(:user) }
let(:key) { create(:key, user: user) }
diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml
index e6c7f3bdf74..f323777b13a 100644
--- a/spec/lib/gitlab/import_export/all_models.yml
+++ b/spec/lib/gitlab/import_export/all_models.yml
@@ -22,6 +22,7 @@ events:
- author
- project
- target
+- push_event_payload
notes:
- award_emoji
- project
@@ -272,3 +273,5 @@ timelogs:
- issue
- merge_request
- user
+push_event_payload:
+- event
diff --git a/spec/lib/gitlab/import_export/attribute_cleaner_spec.rb b/spec/lib/gitlab/import_export/attribute_cleaner_spec.rb
index 574748756bd..cd5a1b2982b 100644
--- a/spec/lib/gitlab/import_export/attribute_cleaner_spec.rb
+++ b/spec/lib/gitlab/import_export/attribute_cleaner_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Gitlab::ImportExport::AttributeCleaner do
- let(:relation_class){ double('relation_class').as_null_object }
+ let(:relation_class) { double('relation_class').as_null_object }
let(:unsafe_hash) do
{
'id' => 101,
diff --git a/spec/lib/gitlab/import_export/avatar_restorer_spec.rb b/spec/lib/gitlab/import_export/avatar_restorer_spec.rb
index a7b292c8558..a93a921e459 100644
--- a/spec/lib/gitlab/import_export/avatar_restorer_spec.rb
+++ b/spec/lib/gitlab/import_export/avatar_restorer_spec.rb
@@ -4,7 +4,7 @@ describe Gitlab::ImportExport::AvatarRestorer do
include UploadHelpers
let(:shared) { Gitlab::ImportExport::Shared.new(relative_path: 'test') }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
before do
allow_any_instance_of(described_class).to receive(:avatar_export_file)
diff --git a/spec/lib/gitlab/import_export/avatar_saver_spec.rb b/spec/lib/gitlab/import_export/avatar_saver_spec.rb
index 814f85de03b..3fb5ddde8b5 100644
--- a/spec/lib/gitlab/import_export/avatar_saver_spec.rb
+++ b/spec/lib/gitlab/import_export/avatar_saver_spec.rb
@@ -3,8 +3,8 @@ require 'spec_helper'
describe Gitlab::ImportExport::AvatarSaver do
let(:shared) { Gitlab::ImportExport::Shared.new(relative_path: 'test') }
let(:export_path) { "#{Dir.tmpdir}/project_tree_saver_spec" }
- let(:project_with_avatar) { create(:empty_project, avatar: fixture_file_upload(Rails.root + "spec/fixtures/dk.png", "image/png")) }
- let(:project) { create(:empty_project) }
+ let(:project_with_avatar) { create(:project, avatar: fixture_file_upload(Rails.root + "spec/fixtures/dk.png", "image/png")) }
+ let(:project) { create(:project) }
before do
FileUtils.mkdir_p("#{shared.export_path}/avatar/")
diff --git a/spec/lib/gitlab/import_export/file_importer_spec.rb b/spec/lib/gitlab/import_export/file_importer_spec.rb
index 690c7625c52..162b776e107 100644
--- a/spec/lib/gitlab/import_export/file_importer_spec.rb
+++ b/spec/lib/gitlab/import_export/file_importer_spec.rb
@@ -5,6 +5,7 @@ describe Gitlab::ImportExport::FileImporter do
let(:export_path) { "#{Dir.tmpdir}/file_importer_spec" }
let(:valid_file) { "#{shared.export_path}/valid.json" }
let(:symlink_file) { "#{shared.export_path}/invalid.json" }
+ let(:hidden_symlink_file) { "#{shared.export_path}/.hidden" }
let(:subfolder_symlink_file) { "#{shared.export_path}/subfolder/invalid.json" }
before do
@@ -25,6 +26,10 @@ describe Gitlab::ImportExport::FileImporter do
expect(File.exist?(symlink_file)).to be false
end
+ it 'removes hidden symlinks in root folder' do
+ expect(File.exist?(hidden_symlink_file)).to be false
+ end
+
it 'removes symlinks in subfolders' do
expect(File.exist?(subfolder_symlink_file)).to be false
end
diff --git a/spec/lib/gitlab/import_export/fork_spec.rb b/spec/lib/gitlab/import_export/fork_spec.rb
index 08588a76fe6..c7fbc2bc92f 100644
--- a/spec/lib/gitlab/import_export/fork_spec.rb
+++ b/spec/lib/gitlab/import_export/fork_spec.rb
@@ -2,11 +2,11 @@ require 'spec_helper'
describe 'forked project import' do
let(:user) { create(:user) }
- let!(:project_with_repo) { create(:project, name: 'test-repo-restorer', path: 'test-repo-restorer') }
- let!(:project) { create(:empty_project, name: 'test-repo-restorer-no-repo', path: 'test-repo-restorer-no-repo') }
+ let!(:project_with_repo) { create(:project, :repository, name: 'test-repo-restorer', path: 'test-repo-restorer') }
+ let!(:project) { create(:project, name: 'test-repo-restorer-no-repo', path: 'test-repo-restorer-no-repo') }
let(:export_path) { "#{Dir.tmpdir}/project_tree_saver_spec" }
- let(:shared) { Gitlab::ImportExport::Shared.new(relative_path: project.path_with_namespace) }
- let(:forked_from_project) { create(:project) }
+ let(:shared) { Gitlab::ImportExport::Shared.new(relative_path: project.full_path) }
+ let(:forked_from_project) { create(:project, :repository) }
let(:fork_link) { create(:forked_project_link, forked_from_project: project_with_repo) }
let(:repo_saver) { Gitlab::ImportExport::RepoSaver.new(project: project_with_repo, shared: shared) }
let(:bundle_path) { File.join(shared.export_path, Gitlab::ImportExport.project_bundle_filename) }
diff --git a/spec/lib/gitlab/import_export/import_export_spec.rb b/spec/lib/gitlab/import_export/import_export_spec.rb
index 07415d41f93..40a5f2294a2 100644
--- a/spec/lib/gitlab/import_export/import_export_spec.rb
+++ b/spec/lib/gitlab/import_export/import_export_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe Gitlab::ImportExport do
describe 'export filename' do
let(:group) { create(:group, :nested) }
- let(:project) { create(:empty_project, :public, path: 'project-path', namespace: group) }
+ let(:project) { create(:project, :public, path: 'project-path', namespace: group) }
it 'contains the project path' do
expect(described_class.export_filename(project: project)).to include(project.path)
diff --git a/spec/lib/gitlab/import_export/members_mapper_spec.rb b/spec/lib/gitlab/import_export/members_mapper_spec.rb
index f66a2ab7dda..246f009ad27 100644
--- a/spec/lib/gitlab/import_export/members_mapper_spec.rb
+++ b/spec/lib/gitlab/import_export/members_mapper_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe Gitlab::ImportExport::MembersMapper do
describe 'map members' do
let(:user) { create(:admin) }
- let(:project) { create(:empty_project, :public, name: 'searchable_project') }
+ let(:project) { create(:project, :public, name: 'searchable_project') }
let(:user2) { create(:user) }
let(:exported_user_id) { 99 }
let(:exported_members) do
@@ -96,7 +96,7 @@ describe Gitlab::ImportExport::MembersMapper do
context 'importer same as group member' do
let(:user2) { create(:admin) }
let(:group) { create(:group) }
- let(:project) { create(:empty_project, :public, name: 'searchable_project', namespace: group) }
+ let(:project) { create(:project, :public, name: 'searchable_project', namespace: group) }
let(:members_mapper) do
described_class.new(
exported_members: exported_members, user: user2, project: project)
@@ -119,7 +119,7 @@ describe Gitlab::ImportExport::MembersMapper do
context 'importing group members' do
let(:group) { create(:group) }
- let(:project) { create(:empty_project, namespace: group) }
+ let(:project) { create(:project, namespace: group) }
let(:members_mapper) do
described_class.new(
exported_members: exported_members, user: user, project: project)
diff --git a/spec/lib/gitlab/import_export/merge_request_parser_spec.rb b/spec/lib/gitlab/import_export/merge_request_parser_spec.rb
index f2b66c4421c..4d87f27ce05 100644
--- a/spec/lib/gitlab/import_export/merge_request_parser_spec.rb
+++ b/spec/lib/gitlab/import_export/merge_request_parser_spec.rb
@@ -2,8 +2,8 @@ require 'spec_helper'
describe Gitlab::ImportExport::MergeRequestParser do
let(:user) { create(:user) }
- let!(:project) { create(:project, name: 'test-repo-restorer', path: 'test-repo-restorer') }
- let(:forked_from_project) { create(:project) }
+ let!(:project) { create(:project, :repository, name: 'test-repo-restorer', path: 'test-repo-restorer') }
+ let(:forked_from_project) { create(:project, :repository) }
let(:fork_link) { create(:forked_project_link, forked_from_project: project) }
let!(:merge_request) do
diff --git a/spec/lib/gitlab/import_export/project.json b/spec/lib/gitlab/import_export/project.json
index 469a014e4d2..4e631e13410 100644
--- a/spec/lib/gitlab/import_export/project.json
+++ b/spec/lib/gitlab/import_export/project.json
@@ -2534,7 +2534,6 @@
"iid": 9,
"description": null,
"position": 0,
- "locked_at": null,
"updated_by_id": null,
"merge_error": null,
"merge_params": {
@@ -2983,7 +2982,6 @@
"iid": 8,
"description": null,
"position": 0,
- "locked_at": null,
"updated_by_id": null,
"merge_error": null,
"merge_params": {
@@ -3267,7 +3265,6 @@
"iid": 7,
"description": "Et commodi deserunt aspernatur vero rerum. Ut non dolorum alias in odit est libero. Voluptatibus eos in et vitae repudiandae facilis ex mollitia.",
"position": 0,
- "locked_at": null,
"updated_by_id": null,
"merge_error": null,
"merge_params": {
@@ -3551,7 +3548,6 @@
"iid": 6,
"description": "Dicta magnam non voluptates nam dignissimos nostrum deserunt. Dolorum et suscipit iure quae doloremque. Necessitatibus saepe aut labore sed.",
"position": 0,
- "locked_at": null,
"updated_by_id": null,
"merge_error": null,
"merge_params": {
@@ -4241,7 +4237,6 @@
"iid": 5,
"description": "Est eaque quasi qui qui. Similique voluptatem impedit iusto ratione reprehenderit. Itaque est illum ut nulla aut.",
"position": 0,
- "locked_at": null,
"updated_by_id": null,
"merge_error": null,
"merge_params": {
@@ -4789,7 +4784,6 @@
"iid": 4,
"description": "Nam magnam odit velit rerum. Sapiente dolore sunt saepe debitis. Culpa maiores ut ad dolores dolorem et.",
"position": 0,
- "locked_at": null,
"updated_by_id": null,
"merge_error": null,
"merge_params": {
@@ -5288,7 +5282,6 @@
"iid": 3,
"description": "Libero nesciunt mollitia quis odit eos vero quasi. Iure voluptatem ut sint pariatur voluptates ut aut. Laborum possimus unde illum ipsum eum.",
"position": 0,
- "locked_at": null,
"updated_by_id": null,
"merge_error": null,
"merge_params": {
@@ -5548,7 +5541,6 @@
"iid": 2,
"description": "Ut dolor quia aliquid dolore et nisi. Est minus suscipit enim quaerat sapiente consequatur rerum. Eveniet provident consequatur dolor accusantium reiciendis.",
"position": 0,
- "locked_at": null,
"updated_by_id": null,
"merge_error": null,
"merge_params": {
@@ -6238,7 +6230,6 @@
"iid": 1,
"description": "Eveniet nihil ratione veniam similique qui aut sapiente tempora. Sed praesentium iusto dignissimos possimus id repudiandae quo nihil. Qui doloremque autem et iure fugit.",
"position": 0,
- "locked_at": null,
"updated_by_id": null,
"merge_error": null,
"merge_params": {
diff --git a/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb b/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb
index d1ec0e45bbd..7ee0e22f28d 100644
--- a/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb
+++ b/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb
@@ -9,7 +9,7 @@ describe Gitlab::ImportExport::ProjectTreeRestorer do
RSpec::Mocks.with_temporary_scope do
@shared = Gitlab::ImportExport::Shared.new(relative_path: "", project_path: 'path')
allow(@shared).to receive(:export_path).and_return('spec/lib/gitlab/import_export/')
- @project = create(:empty_project, :builds_disabled, :issues_disabled, name: 'project', path: 'project')
+ @project = create(:project, :builds_disabled, :issues_disabled, name: 'project', path: 'project')
project_tree_restorer = described_class.new(user: @user, shared: @shared, project: @project)
@restored_project_json = project_tree_restorer.restore
end
@@ -178,7 +178,7 @@ describe Gitlab::ImportExport::ProjectTreeRestorer do
context 'Light JSON' do
let(:user) { create(:user) }
let(:shared) { Gitlab::ImportExport::Shared.new(relative_path: "", project_path: 'path') }
- let!(:project) { create(:empty_project, :builds_disabled, :issues_disabled, name: 'project', path: 'project') }
+ let!(:project) { create(:project, :builds_disabled, :issues_disabled, name: 'project', path: 'project') }
let(:project_tree_restorer) { described_class.new(user: user, shared: shared, project: project) }
let(:restored_project_json) { project_tree_restorer.restore }
@@ -210,7 +210,7 @@ describe Gitlab::ImportExport::ProjectTreeRestorer do
context 'with group' do
let!(:project) do
- create(:empty_project,
+ create(:project,
:builds_disabled,
:issues_disabled,
name: 'project',
diff --git a/spec/lib/gitlab/import_export/project_tree_saver_spec.rb b/spec/lib/gitlab/import_export/project_tree_saver_spec.rb
index 0c7e733b01f..a278f89c1a1 100644
--- a/spec/lib/gitlab/import_export/project_tree_saver_spec.rb
+++ b/spec/lib/gitlab/import_export/project_tree_saver_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe Gitlab::ImportExport::ProjectTreeSaver do
describe 'saves the project tree into a json object' do
- let(:shared) { Gitlab::ImportExport::Shared.new(relative_path: project.path_with_namespace) }
+ let(:shared) { Gitlab::ImportExport::Shared.new(relative_path: project.full_path) }
let(:project_tree_saver) { described_class.new(project: project, current_user: user, shared: shared) }
let(:export_path) { "#{Dir.tmpdir}/project_tree_saver_spec" }
let(:user) { create(:user) }
diff --git a/spec/lib/gitlab/import_export/relation_factory_spec.rb b/spec/lib/gitlab/import_export/relation_factory_spec.rb
index baa90af84f7..f1df44cea75 100644
--- a/spec/lib/gitlab/import_export/relation_factory_spec.rb
+++ b/spec/lib/gitlab/import_export/relation_factory_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Gitlab::ImportExport::RelationFactory do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:members_mapper) { double('members_mapper').as_null_object }
let(:user) { create(:admin) }
let(:created_object) do
diff --git a/spec/lib/gitlab/import_export/repo_restorer_spec.rb b/spec/lib/gitlab/import_export/repo_restorer_spec.rb
index d3be2965bf4..2786bc92fe5 100644
--- a/spec/lib/gitlab/import_export/repo_restorer_spec.rb
+++ b/spec/lib/gitlab/import_export/repo_restorer_spec.rb
@@ -3,10 +3,10 @@ require 'spec_helper'
describe Gitlab::ImportExport::RepoRestorer do
describe 'bundle a project Git repo' do
let(:user) { create(:user) }
- let!(:project_with_repo) { create(:project, name: 'test-repo-restorer', path: 'test-repo-restorer') }
- let!(:project) { create(:empty_project) }
+ let!(:project_with_repo) { create(:project, :repository, name: 'test-repo-restorer', path: 'test-repo-restorer') }
+ let!(:project) { create(:project) }
let(:export_path) { "#{Dir.tmpdir}/project_tree_saver_spec" }
- let(:shared) { Gitlab::ImportExport::Shared.new(relative_path: project.path_with_namespace) }
+ let(:shared) { Gitlab::ImportExport::Shared.new(relative_path: project.full_path) }
let(:bundler) { Gitlab::ImportExport::RepoSaver.new(project: project_with_repo, shared: shared) }
let(:bundle_path) { File.join(shared.export_path, Gitlab::ImportExport.project_bundle_filename) }
let(:restorer) do
diff --git a/spec/lib/gitlab/import_export/repo_saver_spec.rb b/spec/lib/gitlab/import_export/repo_saver_spec.rb
index 87af13e0beb..e6ad516deef 100644
--- a/spec/lib/gitlab/import_export/repo_saver_spec.rb
+++ b/spec/lib/gitlab/import_export/repo_saver_spec.rb
@@ -3,9 +3,9 @@ require 'spec_helper'
describe Gitlab::ImportExport::RepoSaver do
describe 'bundle a project Git repo' do
let(:user) { create(:user) }
- let!(:project) { create(:empty_project, :public, name: 'searchable_project') }
+ let!(:project) { create(:project, :public, name: 'searchable_project') }
let(:export_path) { "#{Dir.tmpdir}/project_tree_saver_spec" }
- let(:shared) { Gitlab::ImportExport::Shared.new(relative_path: project.path_with_namespace) }
+ let(:shared) { Gitlab::ImportExport::Shared.new(relative_path: project.full_path) }
let(:bundler) { described_class.new(project: project, shared: shared) }
before do
diff --git a/spec/lib/gitlab/import_export/safe_model_attributes.yml b/spec/lib/gitlab/import_export/safe_model_attributes.yml
index 2d5a60fe6b8..a5e03e149a7 100644
--- a/spec/lib/gitlab/import_export/safe_model_attributes.yml
+++ b/spec/lib/gitlab/import_export/safe_model_attributes.yml
@@ -36,6 +36,14 @@ Event:
- updated_at
- action
- author_id
+PushEventPayload:
+- commit_count
+- action
+- ref_type
+- commit_from
+- commit_to
+- ref
+- commit_title
Note:
- id
- note
@@ -145,7 +153,6 @@ MergeRequest:
- iid
- description
- position
-- locked_at
- updated_by_id
- merge_error
- merge_params
diff --git a/spec/lib/gitlab/import_export/wiki_repo_saver_spec.rb b/spec/lib/gitlab/import_export/wiki_repo_saver_spec.rb
index 78137aeff5e..0e55993c8ef 100644
--- a/spec/lib/gitlab/import_export/wiki_repo_saver_spec.rb
+++ b/spec/lib/gitlab/import_export/wiki_repo_saver_spec.rb
@@ -3,9 +3,9 @@ require 'spec_helper'
describe Gitlab::ImportExport::WikiRepoSaver do
describe 'bundle a wiki Git repo' do
let(:user) { create(:user) }
- let!(:project) { create(:empty_project, :public, name: 'searchable_project') }
+ let!(:project) { create(:project, :public, name: 'searchable_project') }
let(:export_path) { "#{Dir.tmpdir}/project_tree_saver_spec" }
- let(:shared) { Gitlab::ImportExport::Shared.new(relative_path: project.path_with_namespace) }
+ let(:shared) { Gitlab::ImportExport::Shared.new(relative_path: project.full_path) }
let(:wiki_bundler) { described_class.new(project: project, shared: shared) }
let!(:project_wiki) { ProjectWiki.new(project, user) }
diff --git a/spec/lib/gitlab/import_sources_spec.rb b/spec/lib/gitlab/import_sources_spec.rb
index b3b5e5e7e33..c5725f47453 100644
--- a/spec/lib/gitlab/import_sources_spec.rb
+++ b/spec/lib/gitlab/import_sources_spec.rb
@@ -56,7 +56,7 @@ describe Gitlab::ImportSources do
describe '.importer' do
import_sources = {
- 'github' => Gitlab::GithubImport::Importer,
+ 'github' => Github::Import,
'bitbucket' => Gitlab::BitbucketImport::Importer,
'gitlab' => Gitlab::GitlabImport::Importer,
'google_code' => Gitlab::GoogleCodeImport::Importer,
diff --git a/spec/lib/gitlab/issuable_sorter_spec.rb b/spec/lib/gitlab/issuable_sorter_spec.rb
index aeb32ef96d6..642a6cb6caa 100644
--- a/spec/lib/gitlab/issuable_sorter_spec.rb
+++ b/spec/lib/gitlab/issuable_sorter_spec.rb
@@ -1,25 +1,25 @@
require 'spec_helper'
describe Gitlab::IssuableSorter do
- let(:namespace1) { build(:namespace, id: 1) }
- let(:project1) { build(:project, id: 1, namespace: namespace1) }
+ let(:namespace1) { build_stubbed(:namespace, id: 1) }
+ let(:project1) { build_stubbed(:project, id: 1, namespace: namespace1) }
- let(:project2) { build(:project, id: 2, path: "a", namespace: project1.namespace) }
- let(:project3) { build(:project, id: 3, path: "b", namespace: project1.namespace) }
+ let(:project2) { build_stubbed(:project, id: 2, path: "a", namespace: project1.namespace) }
+ let(:project3) { build_stubbed(:project, id: 3, path: "b", namespace: project1.namespace) }
- let(:namespace2) { build(:namespace, id: 2, path: "a") }
- let(:namespace3) { build(:namespace, id: 3, path: "b") }
- let(:project4) { build(:project, id: 4, path: "a", namespace: namespace2) }
- let(:project5) { build(:project, id: 5, path: "b", namespace: namespace2) }
- let(:project6) { build(:project, id: 6, path: "a", namespace: namespace3) }
+ let(:namespace2) { build_stubbed(:namespace, id: 2, path: "a") }
+ let(:namespace3) { build_stubbed(:namespace, id: 3, path: "b") }
+ let(:project4) { build_stubbed(:project, id: 4, path: "a", namespace: namespace2) }
+ let(:project5) { build_stubbed(:project, id: 5, path: "b", namespace: namespace2) }
+ let(:project6) { build_stubbed(:project, id: 6, path: "a", namespace: namespace3) }
let(:unsorted) { [sorted[2], sorted[3], sorted[0], sorted[1]] }
let(:sorted) do
- [build(:issue, iid: 1, project: project1),
- build(:issue, iid: 2, project: project1),
- build(:issue, iid: 10, project: project1),
- build(:issue, iid: 20, project: project1)]
+ [build_stubbed(:issue, iid: 1, project: project1),
+ build_stubbed(:issue, iid: 2, project: project1),
+ build_stubbed(:issue, iid: 10, project: project1),
+ build_stubbed(:issue, iid: 20, project: project1)]
end
it 'sorts references by a given key' do
@@ -41,14 +41,14 @@ describe Gitlab::IssuableSorter do
context 'for references from multiple projects and namespaces' do
let(:sorted) do
- [build(:issue, iid: 1, project: project1),
- build(:issue, iid: 2, project: project1),
- build(:issue, iid: 10, project: project1),
- build(:issue, iid: 1, project: project2),
- build(:issue, iid: 1, project: project3),
- build(:issue, iid: 1, project: project4),
- build(:issue, iid: 1, project: project5),
- build(:issue, iid: 1, project: project6)]
+ [build_stubbed(:issue, iid: 1, project: project1),
+ build_stubbed(:issue, iid: 2, project: project1),
+ build_stubbed(:issue, iid: 10, project: project1),
+ build_stubbed(:issue, iid: 1, project: project2),
+ build_stubbed(:issue, iid: 1, project: project3),
+ build_stubbed(:issue, iid: 1, project: project4),
+ build_stubbed(:issue, iid: 1, project: project5),
+ build_stubbed(:issue, iid: 1, project: project6)]
end
let(:unsorted) do
[sorted[3], sorted[1], sorted[4], sorted[2],
diff --git a/spec/lib/gitlab/key_fingerprint_spec.rb b/spec/lib/gitlab/key_fingerprint_spec.rb
index d7bebaca675..f5fd5a96bc9 100644
--- a/spec/lib/gitlab/key_fingerprint_spec.rb
+++ b/spec/lib/gitlab/key_fingerprint_spec.rb
@@ -1,12 +1,82 @@
-require "spec_helper"
+require 'spec_helper'
-describe Gitlab::KeyFingerprint do
- let(:key) { "ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEAiPWx6WM4lhHNedGfBpPJNPpZ7yKu+dnn1SJejgt4596k6YjzGGphH2TUxwKzxcKDKKezwkpfnxPkSMkuEspGRt/aZZ9wa++Oi7Qkr8prgHc4soW6NUlfDzpvZK2H5E7eQaSeP3SAwGmQKUFHCddNaP0L+hM7zhFNzjFvpaMgJw0=" }
- let(:fingerprint) { "3f:a2:ee:de:b5:de:53:c3:aa:2f:9c:45:24:4c:47:7b" }
+describe Gitlab::KeyFingerprint, lib: true do
+ KEYS = {
+ rsa:
+ 'example.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC5z65PwQ1GE6foJgwk' \
+ '9rmQi/glaXbUeVa5uvQpnZ3Z5+forcI7aTngh3aZ/H2UDP2L70TGy7kKNyp0J3a8/OdG' \
+ 'Z08y5yi3JlbjFARO1NyoFEjw2H1SJxeJ43L6zmvTlu+hlK1jSAlidl7enS0ufTlzEEj4' \
+ 'iJcuTPKdVzKRgZuTRVm9woWNVKqIrdRC0rJiTinERnfSAp/vNYERMuaoN4oJt8p/NEek' \
+ 'rmFoDsQOsyDW5RAnCnjWUU+jFBKDpfkJQ1U2n6BjJewC9dl6ODK639l3yN4WOLZEk4tN' \
+ 'UysfbGeF3rmMeflaD6O1Jplpv3YhwVGFNKa7fMq6k3Z0tszTJPYh',
+ ecdsa:
+ 'example.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAI' \
+ 'bmlzdHAyNTYAAABBBKTJy43NZzJSfNxpv/e2E6Zy3qoHoTQbmOsU5FEfpWfWa1MdTeXQ' \
+ 'YvKOi+qz/1AaNx6BK421jGu74JCDJtiZWT8=',
+ ed25519:
+ '@revoked example.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfuCHKVTjq' \
+ 'uxvt6CM6tdG4SLp1Btn/nOeHHE5UOzRdf',
+ dss:
+ 'example.com ssh-dss AAAAB3NzaC1kc3MAAACBAP1/U4EddRIpUt9KnC7s5Of2EbdS' \
+ 'PO9EAMMeP4C2USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f' \
+ '6AR7ECLCT7up1/63xhv4O1fnxqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv8iID' \
+ 'GZ3RSAHHAAAAFQCXYFCPFSMLzLKSuYKi64QL8Fgc9QAAAIEA9+GghdabPd7LvKtcNrhX' \
+ 'uXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCBgLRJFnEj6EwoFhO3zwkyjMim4TwW' \
+ 'eotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImog9/hWuWfBpKLZl6A' \
+ 'e1UlZAFMO/7PSSoAAACBAJcQ4JODqhuGbXIEpqxetm7PWbdbCcr3y/GzIZ066pRovpL6' \
+ 'qm3qCVIym4cyChxWwb8qlyCIi+YRUUWm1z/wiBYT2Vf3S4FXBnyymCkKEaV/EY7+jd4X' \
+ '1bXI58OD2u+bLCB/sInM4fGB8CZUIWT9nJH0Ve9jJUge2ms348/QOJ1+'
+ }.freeze
- describe "#fingerprint" do
- it "generates the key's fingerprint" do
- expect(described_class.new(key).fingerprint).to eq(fingerprint)
+ MD5_FINGERPRINTS = {
+ rsa: '06:b2:8a:92:df:0e:11:2c:ca:7b:8f:a4:ba:6e:4b:fd',
+ ecdsa: '45:ff:5b:98:9a:b6:8a:41:13:c1:30:8b:09:5e:7b:4e',
+ ed25519: '2e:65:6a:c8:cf:bf:b2:8b:9a:bd:6d:9f:11:5c:12:16',
+ dss: '57:98:86:02:5f:9c:f4:9b:ad:5a:1e:51:92:0e:fd:2b'
+ }.freeze
+
+ BIT_COUNTS = {
+ rsa: 2048,
+ ecdsa: 256,
+ ed25519: 256,
+ dss: 1024
+ }.freeze
+
+ describe '#type' do
+ KEYS.each do |type, key|
+ it "calculates the type of #{type} keys" do
+ calculated_type = described_class.new(key).type
+
+ expect(calculated_type).to eq(type.to_s.upcase)
+ end
+ end
+ end
+
+ describe '#fingerprint' do
+ KEYS.each do |type, key|
+ it "calculates the MD5 fingerprint for #{type} keys" do
+ fp = described_class.new(key).fingerprint
+
+ expect(fp).to eq(MD5_FINGERPRINTS[type])
+ end
+ end
+ end
+
+ describe '#bits' do
+ KEYS.each do |type, key|
+ it "calculates the number of bits in #{type} keys" do
+ bits = described_class.new(key).bits
+
+ expect(bits).to eq(BIT_COUNTS[type])
+ end
+ end
+ end
+
+ describe '#key' do
+ it 'carries the unmodified key data' do
+ key = described_class.new(KEYS[:rsa]).key
+
+ expect(key).to eq(KEYS[:rsa])
end
end
end
diff --git a/spec/lib/gitlab/ldap/config_spec.rb b/spec/lib/gitlab/ldap/config_spec.rb
index 292ec064a67..ca2213cd112 100644
--- a/spec/lib/gitlab/ldap/config_spec.rb
+++ b/spec/lib/gitlab/ldap/config_spec.rb
@@ -7,7 +7,7 @@ describe Gitlab::LDAP::Config do
describe '#initialize' do
it 'requires a provider' do
- expect{ described_class.new }.to raise_error ArgumentError
+ expect { described_class.new }.to raise_error ArgumentError
end
it 'works' do
@@ -15,7 +15,7 @@ describe Gitlab::LDAP::Config do
end
it 'raises an error if a unknown provider is used' do
- expect{ described_class.new 'unknown' }.to raise_error(RuntimeError)
+ expect { described_class.new 'unknown' }.to raise_error(RuntimeError)
end
end
diff --git a/spec/lib/gitlab/ldap/user_spec.rb b/spec/lib/gitlab/ldap/user_spec.rb
index 175ceec44d7..5100a5a609e 100644
--- a/spec/lib/gitlab/ldap/user_spec.rb
+++ b/spec/lib/gitlab/ldap/user_spec.rb
@@ -61,12 +61,12 @@ describe Gitlab::LDAP::User do
it "finds the user if already existing" do
create(:omniauth_user, extern_uid: 'my-uid', provider: 'ldapmain')
- expect{ ldap_user.save }.not_to change{ User.count }
+ expect { ldap_user.save }.not_to change { User.count }
end
it "connects to existing non-ldap user if the email matches" do
existing_user = create(:omniauth_user, email: 'john@example.com', provider: "twitter")
- expect{ ldap_user.save }.not_to change{ User.count }
+ expect { ldap_user.save }.not_to change { User.count }
existing_user.reload
expect(existing_user.ldap_identity.extern_uid).to eql 'my-uid'
@@ -75,7 +75,7 @@ describe Gitlab::LDAP::User do
it 'connects to existing ldap user if the extern_uid changes' do
existing_user = create(:omniauth_user, email: 'john@example.com', extern_uid: 'old-uid', provider: 'ldapmain')
- expect{ ldap_user.save }.not_to change{ User.count }
+ expect { ldap_user.save }.not_to change { User.count }
existing_user.reload
expect(existing_user.ldap_identity.extern_uid).to eql 'my-uid'
@@ -85,7 +85,7 @@ describe Gitlab::LDAP::User do
it 'connects to existing ldap user if the extern_uid changes and email address has upper case characters' do
existing_user = create(:omniauth_user, email: 'john@example.com', extern_uid: 'old-uid', provider: 'ldapmain')
- expect{ ldap_user_upper_case.save }.not_to change{ User.count }
+ expect { ldap_user_upper_case.save }.not_to change { User.count }
existing_user.reload
expect(existing_user.ldap_identity.extern_uid).to eql 'my-uid'
@@ -106,7 +106,7 @@ describe Gitlab::LDAP::User do
end
it "creates a new user if not found" do
- expect{ ldap_user.save }.to change{ User.count }.by(1)
+ expect { ldap_user.save }.to change { User.count }.by(1)
end
context 'when signup is disabled' do
diff --git a/spec/lib/gitlab/metrics/influx_sampler_spec.rb b/spec/lib/gitlab/metrics/influx_sampler_spec.rb
index 0bc68d64276..999a9536d82 100644
--- a/spec/lib/gitlab/metrics/influx_sampler_spec.rb
+++ b/spec/lib/gitlab/metrics/influx_sampler_spec.rb
@@ -11,7 +11,7 @@ describe Gitlab::Metrics::InfluxSampler do
it 'runs once and gathers a sample at a given interval' do
expect(sampler).to receive(:sleep).with(a_kind_of(Numeric)).twice
expect(sampler).to receive(:sample).once
- expect(sampler).to receive(:running).and_return(false, true, false)
+ expect(sampler).to receive(:running).and_return(true, false)
sampler.start.join
end
diff --git a/spec/lib/gitlab/metrics/requests_rack_middleware_spec.rb b/spec/lib/gitlab/metrics/requests_rack_middleware_spec.rb
index 461b1e4182a..ebe66948a91 100644
--- a/spec/lib/gitlab/metrics/requests_rack_middleware_spec.rb
+++ b/spec/lib/gitlab/metrics/requests_rack_middleware_spec.rb
@@ -4,10 +4,6 @@ describe Gitlab::Metrics::RequestsRackMiddleware do
let(:app) { double('app') }
subject { described_class.new(app) }
- around do |example|
- Timecop.freeze { example.run }
- end
-
describe '#call' do
let(:status) { 100 }
let(:env) { { 'REQUEST_METHOD' => 'GET' } }
@@ -28,16 +24,14 @@ describe Gitlab::Metrics::RequestsRackMiddleware do
subject.call(env)
end
- it 'measures execution time' do
- execution_time = 10
- allow(app).to receive(:call) do |*args|
- Timecop.freeze(execution_time.seconds)
- [200, nil, nil]
- end
+ RSpec::Matchers.define :a_positive_execution_time do
+ match { |actual| actual > 0 }
+ end
- expect(described_class).to receive_message_chain(:http_request_duration_seconds, :observe).with({ status: 200, method: 'get' }, execution_time)
+ it 'measures execution time' do
+ expect(described_class).to receive_message_chain(:http_request_duration_seconds, :observe).with({ status: 200, method: 'get' }, a_positive_execution_time)
- subject.call(env)
+ Timecop.scale(3600) { subject.call(env) }
end
end
diff --git a/spec/lib/gitlab/metrics/sidekiq_metrics_exporter_spec.rb b/spec/lib/gitlab/metrics/sidekiq_metrics_exporter_spec.rb
new file mode 100644
index 00000000000..6721e02fb85
--- /dev/null
+++ b/spec/lib/gitlab/metrics/sidekiq_metrics_exporter_spec.rb
@@ -0,0 +1,101 @@
+require 'spec_helper'
+
+describe Gitlab::Metrics::SidekiqMetricsExporter do
+ let(:exporter) { described_class.new }
+ let(:server) { double('server') }
+
+ before do
+ allow(::WEBrick::HTTPServer).to receive(:new).and_return(server)
+ allow(server).to receive(:mount)
+ allow(server).to receive(:start)
+ allow(server).to receive(:shutdown)
+ end
+
+ describe 'when exporter is enabled' do
+ before do
+ allow(Settings.monitoring.sidekiq_exporter).to receive(:enabled).and_return(true)
+ end
+
+ describe 'when exporter is stopped' do
+ describe '#start' do
+ it 'starts the exporter' do
+ expect { exporter.start.join }.to change { exporter.thread? }.from(false).to(true)
+
+ expect(server).to have_received(:start)
+ end
+
+ describe 'with custom settings' do
+ let(:port) { 99999 }
+ let(:address) { 'sidekiq_exporter_address' }
+
+ before do
+ allow(Settings.monitoring.sidekiq_exporter).to receive(:port).and_return(port)
+ allow(Settings.monitoring.sidekiq_exporter).to receive(:address).and_return(address)
+ end
+
+ it 'starts server with port and address from settings' do
+ exporter.start.join
+
+ expect(::WEBrick::HTTPServer).to have_received(:new).with(
+ Port: port,
+ BindAddress: address
+ )
+ end
+ end
+ end
+
+ describe '#stop' do
+ it "doesn't shutdown stopped server" do
+ expect { exporter.stop }.not_to change { exporter.thread? }
+
+ expect(server).not_to have_received(:shutdown)
+ end
+ end
+ end
+
+ describe 'when exporter is running' do
+ before do
+ exporter.start.join
+ end
+
+ describe '#start' do
+ it "doesn't start running server" do
+ expect { exporter.start.join }.not_to change { exporter.thread? }
+
+ expect(server).to have_received(:start).once
+ end
+ end
+
+ describe '#stop' do
+ it 'shutdowns server' do
+ expect { exporter.stop }.to change { exporter.thread? }.from(true).to(false)
+
+ expect(server).to have_received(:shutdown)
+ end
+ end
+ end
+ end
+
+ describe 'when exporter is disabled' do
+ before do
+ allow(Settings.monitoring.sidekiq_exporter).to receive(:enabled).and_return(false)
+ end
+
+ describe '#start' do
+ it "doesn't start" do
+ expect(exporter.start).to be_nil
+ expect { exporter.start }.not_to change { exporter.thread? }
+
+ expect(server).not_to have_received(:start)
+ end
+ end
+
+ describe '#stop' do
+ it "doesn't shutdown" do
+ expect { exporter.stop }.not_to change { exporter.thread? }
+
+ expect(server).not_to have_received(:shutdown)
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/o_auth/user_spec.rb b/spec/lib/gitlab/o_auth/user_spec.rb
index 47aa19d5fd9..15edb820908 100644
--- a/spec/lib/gitlab/o_auth/user_spec.rb
+++ b/spec/lib/gitlab/o_auth/user_spec.rb
@@ -147,7 +147,7 @@ describe Gitlab::OAuth::User do
end
it 'throws an error' do
- expect{ oauth_user.save }.to raise_error StandardError
+ expect { oauth_user.save }.to raise_error StandardError
end
end
@@ -157,7 +157,7 @@ describe Gitlab::OAuth::User do
end
it 'throws an error' do
- expect{ oauth_user.save }.to raise_error StandardError
+ expect { oauth_user.save }.to raise_error StandardError
end
end
end
@@ -457,4 +457,34 @@ describe Gitlab::OAuth::User do
end
end
end
+
+ describe 'generating username' do
+ context 'when no collision with existing user' do
+ it 'generates the username with no counter' do
+ expect(gl_user.username).to eq('johngitlab-ETC')
+ end
+ end
+
+ context 'when collision with existing user' do
+ it 'generates the username with a counter' do
+ oauth_user.save
+ oauth_user2 = described_class.new(OmniAuth::AuthHash.new(uid: 'my-uid2', provider: provider, info: { nickname: 'johngitlab-ETC@othermail.com', email: 'john@othermail.com' }))
+
+ expect(oauth_user2.gl_user.username).to eq('johngitlab-ETC1')
+ end
+ end
+
+ context 'when username is a reserved word' do
+ let(:info_hash) do
+ {
+ nickname: 'admin@othermail.com',
+ email: 'admin@othermail.com'
+ }
+ end
+
+ it 'generates the username with a counter' do
+ expect(gl_user.username).to eq('admin1')
+ end
+ end
+ end
end
diff --git a/spec/lib/gitlab/project_authorizations_spec.rb b/spec/lib/gitlab/project_authorizations_spec.rb
index 9ce33685697..953cfbb8b88 100644
--- a/spec/lib/gitlab/project_authorizations_spec.rb
+++ b/spec/lib/gitlab/project_authorizations_spec.rb
@@ -2,9 +2,9 @@ require 'spec_helper'
describe Gitlab::ProjectAuthorizations do
let(:group) { create(:group) }
- let!(:owned_project) { create(:empty_project) }
- let!(:other_project) { create(:empty_project) }
- let!(:group_project) { create(:empty_project, namespace: group) }
+ let!(:owned_project) { create(:project) }
+ let!(:other_project) { create(:project) }
+ let!(:group_project) { create(:project, namespace: group) }
let(:user) { owned_project.namespace.owner }
@@ -49,7 +49,7 @@ describe Gitlab::ProjectAuthorizations do
if Group.supports_nested_groups?
context 'with nested groups' do
let!(:nested_group) { create(:group, parent: group) }
- let!(:nested_project) { create(:empty_project, namespace: nested_group) }
+ let!(:nested_project) { create(:project, namespace: nested_group) }
it 'includes nested groups' do
expect(authorizations.pluck(:project_id)).to include(nested_project.id)
diff --git a/spec/lib/gitlab/project_search_results_spec.rb b/spec/lib/gitlab/project_search_results_spec.rb
index d17b436b910..9c3e7d7e9ba 100644
--- a/spec/lib/gitlab/project_search_results_spec.rb
+++ b/spec/lib/gitlab/project_search_results_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe Gitlab::ProjectSearchResults do
let(:user) { create(:user) }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:query) { 'hello world' }
describe 'initialize with empty ref' do
@@ -154,7 +154,7 @@ describe Gitlab::ProjectSearchResults do
let(:non_member) { create(:user) }
let(:member) { create(:user) }
let(:admin) { create(:admin) }
- let(:project) { create(:empty_project, :internal) }
+ let(:project) { create(:project, :internal) }
let!(:issue) { create(:issue, project: project, title: 'Issue 1') }
let!(:security_issue_1) { create(:issue, :confidential, project: project, title: 'Security issue 1', author: author) }
let!(:security_issue_2) { create(:issue, :confidential, title: 'Security issue 2', project: project, assignees: [assignee]) }
@@ -226,7 +226,7 @@ describe Gitlab::ProjectSearchResults do
describe 'notes search' do
it 'lists notes' do
- project = create(:empty_project, :public)
+ project = create(:project, :public)
note = create(:note, project: project)
results = described_class.new(user, project, note.note)
@@ -235,7 +235,7 @@ describe Gitlab::ProjectSearchResults do
end
it "doesn't list issue notes when access is restricted" do
- project = create(:empty_project, :public, :issues_private)
+ project = create(:project, :public, :issues_private)
note = create(:note_on_issue, project: project)
results = described_class.new(user, project, note.note)
@@ -244,7 +244,7 @@ describe Gitlab::ProjectSearchResults do
end
it "doesn't list merge_request notes when access is restricted" do
- project = create(:empty_project, :public, :merge_requests_private)
+ project = create(:project, :public, :merge_requests_private)
note = create(:note_on_merge_request, project: project)
results = described_class.new(user, project, note.note)
diff --git a/spec/lib/gitlab/project_template_spec.rb b/spec/lib/gitlab/project_template_spec.rb
new file mode 100644
index 00000000000..d19bd611919
--- /dev/null
+++ b/spec/lib/gitlab/project_template_spec.rb
@@ -0,0 +1,65 @@
+require 'spec_helper'
+
+describe Gitlab::ProjectTemplate do
+ describe '.all' do
+ it 'returns a all templates' do
+ expected = [
+ described_class.new('rails', 'Ruby on Rails'),
+ described_class.new('spring', 'Spring'),
+ described_class.new('express', 'NodeJS Express')
+ ]
+
+ expect(described_class.all).to be_an(Array)
+ expect(described_class.all).to eq(expected)
+ end
+ end
+
+ describe '.find' do
+ subject { described_class.find(query) }
+
+ context 'when there is a match' do
+ let(:query) { :rails }
+
+ it { is_expected.to be_a(described_class) }
+ end
+
+ context 'when there is no match' do
+ let(:query) { 'no-match' }
+
+ it { is_expected.to be(nil) }
+ end
+ end
+
+ describe 'instance methods' do
+ subject { described_class.new('phoenix', 'Phoenix Framework') }
+
+ it { is_expected.to respond_to(:logo, :file, :archive_path) }
+ end
+
+ describe 'validate all templates' do
+ set(:admin) { create(:admin) }
+
+ described_class.all.each do |template|
+ it "#{template.name} has a valid archive" do
+ archive = template.archive_path
+
+ expect(File.exist?(archive)).to be(true)
+ end
+
+ context 'with valid parameters' do
+ it 'can be imported' do
+ params = {
+ template_name: template.name,
+ namespace_id: admin.namespace.id,
+ path: template.name
+ }
+
+ project = Projects::CreateFromTemplateService.new(admin, params).execute
+
+ expect(project).to be_valid
+ expect(project).to be_persisted
+ end
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/prometheus/queries/additional_metrics_deployment_query_spec.rb b/spec/lib/gitlab/prometheus/queries/additional_metrics_deployment_query_spec.rb
index e42e034f4fb..c7169717fc1 100644
--- a/spec/lib/gitlab/prometheus/queries/additional_metrics_deployment_query_spec.rb
+++ b/spec/lib/gitlab/prometheus/queries/additional_metrics_deployment_query_spec.rb
@@ -1,19 +1,14 @@
require 'spec_helper'
describe Gitlab::Prometheus::Queries::AdditionalMetricsDeploymentQuery do
- include Prometheus::MetricBuilders
-
- let(:client) { double('prometheus_client') }
- let(:environment) { create(:environment, slug: 'environment-slug') }
- let(:deployment) { create(:deployment, environment: environment) }
-
- subject(:query_result) { described_class.new(client).query(deployment.id) }
-
around do |example|
Timecop.freeze(Time.local(2008, 9, 1, 12, 0, 0)) { example.run }
end
include_examples 'additional metrics query' do
+ let(:deployment) { create(:deployment, environment: environment) }
+ let(:query_params) { [deployment.id] }
+
it 'queries using specific time' do
expect(client).to receive(:query_range).with(anything,
start: (deployment.created_at - 30.minutes).to_f,
diff --git a/spec/lib/gitlab/prometheus/queries/additional_metrics_environment_query_spec.rb b/spec/lib/gitlab/prometheus/queries/additional_metrics_environment_query_spec.rb
index e9fd66d45fe..5a88b23aa82 100644
--- a/spec/lib/gitlab/prometheus/queries/additional_metrics_environment_query_spec.rb
+++ b/spec/lib/gitlab/prometheus/queries/additional_metrics_environment_query_spec.rb
@@ -1,20 +1,16 @@
require 'spec_helper'
describe Gitlab::Prometheus::Queries::AdditionalMetricsEnvironmentQuery do
- include Prometheus::MetricBuilders
-
- let(:client) { double('prometheus_client') }
- let(:environment) { create(:environment, slug: 'environment-slug') }
-
- subject(:query_result) { described_class.new(client).query(environment.id) }
-
around do |example|
Timecop.freeze { example.run }
end
include_examples 'additional metrics query' do
+ let(:query_params) { [environment.id] }
+
it 'queries using specific time' do
expect(client).to receive(:query_range).with(anything, start: 8.hours.ago.to_f, stop: Time.now.to_f)
+
expect(query_result).not_to be_nil
end
end
diff --git a/spec/lib/gitlab/quick_actions/dsl_spec.rb b/spec/lib/gitlab/quick_actions/dsl_spec.rb
index a4bb3f911d7..ff59dc48bcb 100644
--- a/spec/lib/gitlab/quick_actions/dsl_spec.rb
+++ b/spec/lib/gitlab/quick_actions/dsl_spec.rb
@@ -42,13 +42,18 @@ describe Gitlab::QuickActions::Dsl do
command :with_params_parsing do |parsed|
parsed
end
+
+ params '<Comment>'
+ substitution :something do |text|
+ "#{text} Some complicated thing you want in here"
+ end
end
end
describe '.command_definitions' do
it 'returns an array with commands definitions' do
no_args_def, explanation_with_aliases_def, dynamic_description_def,
- cc_def, cond_action_def, with_params_parsing_def =
+ cc_def, cond_action_def, with_params_parsing_def, substitution_def =
DummyClass.command_definitions
expect(no_args_def.name).to eq(:no_args)
@@ -104,6 +109,15 @@ describe Gitlab::QuickActions::Dsl do
expect(with_params_parsing_def.condition_block).to be_nil
expect(with_params_parsing_def.action_block).to be_a_kind_of(Proc)
expect(with_params_parsing_def.parse_params_block).to be_a_kind_of(Proc)
+
+ expect(substitution_def.name).to eq(:something)
+ expect(substitution_def.aliases).to eq([])
+ expect(substitution_def.description).to eq('')
+ expect(substitution_def.explanation).to eq('')
+ expect(substitution_def.params).to eq(['<Comment>'])
+ expect(substitution_def.condition_block).to be_nil
+ expect(substitution_def.action_block.call('text')).to eq('text Some complicated thing you want in here')
+ expect(substitution_def.parse_params_block).to be_nil
end
end
end
diff --git a/spec/lib/gitlab/quick_actions/extractor_spec.rb b/spec/lib/gitlab/quick_actions/extractor_spec.rb
index 9d32938e155..f7c288f2393 100644
--- a/spec/lib/gitlab/quick_actions/extractor_spec.rb
+++ b/spec/lib/gitlab/quick_actions/extractor_spec.rb
@@ -9,6 +9,11 @@ describe Gitlab::QuickActions::Extractor do
command(:assign) { }
command(:labels) { }
command(:power) { }
+ command(:noop_command)
+ substitution(:substitution) { 'foo' }
+ substitution :shrug do |comment|
+ "#{comment} SHRUG"
+ end
end.command_definitions
end
@@ -177,6 +182,38 @@ describe Gitlab::QuickActions::Extractor do
expect(msg).to eq "hello\nworld"
end
+ it 'does not extract noop commands' do
+ msg = %(hello\nworld\n/reopen\n/noop_command)
+ msg, commands = extractor.extract_commands(msg)
+
+ expect(commands).to eq [['reopen']]
+ expect(msg).to eq "hello\nworld\n/noop_command"
+ end
+
+ it 'extracts and performs substitution commands' do
+ msg = %(hello\nworld\n/reopen\n/substitution)
+ msg, commands = extractor.extract_commands(msg)
+
+ expect(commands).to eq [['reopen'], ['substitution']]
+ expect(msg).to eq "hello\nworld\nfoo"
+ end
+
+ it 'extracts and performs substitution commands' do
+ msg = %(hello\nworld\n/reopen\n/shrug this is great?)
+ msg, commands = extractor.extract_commands(msg)
+
+ expect(commands).to eq [['reopen'], ['shrug', 'this is great?']]
+ expect(msg).to eq "hello\nworld\nthis is great? SHRUG"
+ end
+
+ it 'extracts and performs substitution commands with comments' do
+ msg = %(hello\nworld\n/reopen\n/substitution wow this is a thing.)
+ msg, commands = extractor.extract_commands(msg)
+
+ expect(commands).to eq [['reopen'], ['substitution', 'wow this is a thing.']]
+ expect(msg).to eq "hello\nworld\nfoo"
+ end
+
it 'extracts multiple commands' do
msg = %(hello\n/power @user.name %9.10 ~"bar baz.2" label\nworld\n/reopen)
msg, commands = extractor.extract_commands(msg)
diff --git a/spec/lib/gitlab/quick_actions/substitution_definition_spec.rb b/spec/lib/gitlab/quick_actions/substitution_definition_spec.rb
new file mode 100644
index 00000000000..1bb8bc51c96
--- /dev/null
+++ b/spec/lib/gitlab/quick_actions/substitution_definition_spec.rb
@@ -0,0 +1,42 @@
+require 'spec_helper'
+
+describe Gitlab::QuickActions::SubstitutionDefinition do
+ let(:content) do
+ <<EOF
+Hello! Let's do this!
+/sub_name I like this stuff
+EOF
+ end
+ subject do
+ described_class.new(:sub_name, action_block: proc { |text| "#{text} foo" })
+ end
+
+ describe '#perform_substitution!' do
+ it 'returns nil if content is nil' do
+ expect(subject.perform_substitution(self, nil)).to be_nil
+ end
+
+ it 'performs the substitution by default' do
+ expect(subject.perform_substitution(self, content)).to eq <<EOF
+Hello! Let's do this!
+I like this stuff foo
+EOF
+ end
+ end
+
+ describe '#match' do
+ it 'checks the content for the command' do
+ expect(subject.match(content)).to be_truthy
+ end
+
+ it 'returns the match data' do
+ data = subject.match(content)
+ expect(data).to be_a(MatchData)
+ expect(data[1]).to eq('I like this stuff')
+ end
+
+ it 'is nil if content does not have the command' do
+ expect(subject.match('blah')).to be_falsey
+ end
+ end
+end
diff --git a/spec/lib/gitlab/reference_extractor_spec.rb b/spec/lib/gitlab/reference_extractor_spec.rb
index 1a0357534f2..476a3f1998d 100644
--- a/spec/lib/gitlab/reference_extractor_spec.rb
+++ b/spec/lib/gitlab/reference_extractor_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Gitlab::ReferenceExtractor do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
before do
project.team << [project.creator, :developer]
@@ -215,7 +215,7 @@ describe Gitlab::ReferenceExtractor do
end
context 'with a project with an underscore' do
- let(:other_project) { create(:empty_project, path: 'test_project') }
+ let(:other_project) { create(:project, path: 'test_project') }
let(:issue) { create(:issue, project: other_project) }
before do
diff --git a/spec/lib/gitlab/repo_path_spec.rb b/spec/lib/gitlab/repo_path_spec.rb
index efea4f429bf..1a925a15e0c 100644
--- a/spec/lib/gitlab/repo_path_spec.rb
+++ b/spec/lib/gitlab/repo_path_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe ::Gitlab::RepoPath do
describe '.parse' do
- set(:project) { create(:project) }
+ set(:project) { create(:project, :repository) }
context 'a repository storage path' do
it 'parses a full repository path' do
@@ -65,7 +65,7 @@ describe ::Gitlab::RepoPath do
end
describe '.find_project' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:redirect) { project.route.create_redirect('foo/bar/baz') }
context 'when finding a project by its canonical path' do
diff --git a/spec/lib/gitlab/request_context_spec.rb b/spec/lib/gitlab/request_context_spec.rb
index e272bdb9284..8a28ad0e597 100644
--- a/spec/lib/gitlab/request_context_spec.rb
+++ b/spec/lib/gitlab/request_context_spec.rb
@@ -7,7 +7,7 @@ describe Gitlab::RequestContext do
let(:env) { Hash.new }
context 'when RequestStore::Middleware is used' do
- around(:each) do |example|
+ around do |example|
RequestStore::Middleware.new(-> (env) { example.run }).call({})
end
diff --git a/spec/lib/gitlab/saml/user_spec.rb b/spec/lib/gitlab/saml/user_spec.rb
index 2827a18515e..19710029224 100644
--- a/spec/lib/gitlab/saml/user_spec.rb
+++ b/spec/lib/gitlab/saml/user_spec.rb
@@ -109,7 +109,7 @@ describe Gitlab::Saml::User do
end
it 'does not throw an error' do
- expect{ saml_user.save }.not_to raise_error
+ expect { saml_user.save }.not_to raise_error
end
end
@@ -119,7 +119,7 @@ describe Gitlab::Saml::User do
end
it 'throws an error' do
- expect{ saml_user.save }.to raise_error StandardError
+ expect { saml_user.save }.to raise_error StandardError
end
end
end
diff --git a/spec/lib/gitlab/search_results_spec.rb b/spec/lib/gitlab/search_results_spec.rb
index 31c3cd4d53c..4c5efbde69a 100644
--- a/spec/lib/gitlab/search_results_spec.rb
+++ b/spec/lib/gitlab/search_results_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe Gitlab::SearchResults do
let(:user) { create(:user) }
- let!(:project) { create(:empty_project, name: 'foo') }
+ let!(:project) { create(:project, name: 'foo') }
let!(:issue) { create(:issue, project: project, title: 'foo') }
let!(:merge_request) do
@@ -42,7 +42,7 @@ describe Gitlab::SearchResults do
end
it 'includes merge requests from source and target projects' do
- forked_project = create(:empty_project, forked_from_project: project)
+ forked_project = create(:project, forked_from_project: project)
merge_request_2 = create(:merge_request, target_project: project, source_project: forked_project, title: 'foo')
results = described_class.new(user, Project.where(id: forked_project.id), 'foo')
@@ -52,17 +52,17 @@ describe Gitlab::SearchResults do
end
it 'does not list issues on private projects' do
- private_project = create(:empty_project, :private)
+ private_project = create(:project, :private)
issue = create(:issue, project: private_project, title: 'foo')
expect(results.objects('issues')).not_to include issue
end
describe 'confidential issues' do
- let(:project_1) { create(:empty_project, :internal) }
- let(:project_2) { create(:empty_project, :internal) }
- let(:project_3) { create(:empty_project, :internal) }
- let(:project_4) { create(:empty_project, :internal) }
+ let(:project_1) { create(:project, :internal) }
+ let(:project_2) { create(:project, :internal) }
+ let(:project_3) { create(:project, :internal) }
+ let(:project_4) { create(:project, :internal) }
let(:query) { 'issue' }
let(:limit_projects) { Project.where(id: [project_1.id, project_2.id, project_3.id]) }
let(:author) { create(:user) }
diff --git a/spec/lib/gitlab/shell_spec.rb b/spec/lib/gitlab/shell_spec.rb
index b90d8dede0f..2345874cf10 100644
--- a/spec/lib/gitlab/shell_spec.rb
+++ b/spec/lib/gitlab/shell_spec.rb
@@ -174,20 +174,94 @@ describe Gitlab::Shell do
end
describe '#fetch_remote' do
+ def fetch_remote(ssh_auth = nil)
+ gitlab_shell.fetch_remote('current/storage', 'project/path', 'new/storage', ssh_auth: ssh_auth)
+ end
+
+ def expect_popen(vars = {})
+ popen_args = [
+ projects_path,
+ 'fetch-remote',
+ 'current/storage',
+ 'project/path.git',
+ 'new/storage',
+ Gitlab.config.gitlab_shell.git_timeout.to_s
+ ]
+
+ expect(Gitlab::Popen).to receive(:popen).with(popen_args, nil, popen_vars.merge(vars))
+ end
+
+ def build_ssh_auth(opts = {})
+ defaults = {
+ ssh_import?: true,
+ ssh_key_auth?: false,
+ ssh_known_hosts: nil,
+ ssh_private_key: nil
+ }
+
+ double(:ssh_auth, defaults.merge(opts))
+ end
+
it 'returns true when the command succeeds' do
- expect(Gitlab::Popen).to receive(:popen)
- .with([projects_path, 'fetch-remote', 'current/storage', 'project/path.git', 'new/storage', '800'],
- nil, popen_vars).and_return([nil, 0])
+ expect_popen.and_return([nil, 0])
- expect(gitlab_shell.fetch_remote('current/storage', 'project/path', 'new/storage')).to be true
+ expect(fetch_remote).to be_truthy
end
it 'raises an exception when the command fails' do
- expect(Gitlab::Popen).to receive(:popen)
- .with([projects_path, 'fetch-remote', 'current/storage', 'project/path.git', 'new/storage', '800'],
- nil, popen_vars).and_return(["error", 1])
+ expect_popen.and_return(["error", 1])
+
+ expect { fetch_remote }.to raise_error(Gitlab::Shell::Error, "error")
+ end
+
+ context 'SSH auth' do
+ it 'passes the SSH key if specified' do
+ expect_popen('GITLAB_SHELL_SSH_KEY' => 'foo').and_return([nil, 0])
+
+ ssh_auth = build_ssh_auth(ssh_key_auth?: true, ssh_private_key: 'foo')
+
+ expect(fetch_remote(ssh_auth)).to be_truthy
+ end
+
+ it 'does not pass an empty SSH key' do
+ expect_popen.and_return([nil, 0])
+
+ ssh_auth = build_ssh_auth(ssh_key_auth: true, ssh_private_key: '')
+
+ expect(fetch_remote(ssh_auth)).to be_truthy
+ end
+
+ it 'does not pass the key unless SSH key auth is to be used' do
+ expect_popen.and_return([nil, 0])
+
+ ssh_auth = build_ssh_auth(ssh_key_auth: false, ssh_private_key: 'foo')
+
+ expect(fetch_remote(ssh_auth)).to be_truthy
+ end
+
+ it 'passes the known_hosts data if specified' do
+ expect_popen('GITLAB_SHELL_KNOWN_HOSTS' => 'foo').and_return([nil, 0])
+
+ ssh_auth = build_ssh_auth(ssh_known_hosts: 'foo')
+
+ expect(fetch_remote(ssh_auth)).to be_truthy
+ end
+
+ it 'does not pass empty known_hosts data' do
+ expect_popen.and_return([nil, 0])
+
+ ssh_auth = build_ssh_auth(ssh_known_hosts: '')
+
+ expect(fetch_remote(ssh_auth)).to be_truthy
+ end
+
+ it 'does not pass known_hosts data unless SSH is to be used' do
+ expect_popen(popen_vars).and_return([nil, 0])
+
+ ssh_auth = build_ssh_auth(ssh_import?: false, ssh_known_hosts: 'foo')
- expect { gitlab_shell.fetch_remote('current/storage', 'project/path', 'new/storage') }.to raise_error(Gitlab::Shell::Error, "error")
+ expect(fetch_remote(ssh_auth)).to be_truthy
+ end
end
end
diff --git a/spec/lib/gitlab/slash_commands/command_spec.rb b/spec/lib/gitlab/slash_commands/command_spec.rb
index f0ecf59406a..0173a45d480 100644
--- a/spec/lib/gitlab/slash_commands/command_spec.rb
+++ b/spec/lib/gitlab/slash_commands/command_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Gitlab::SlashCommands::Command do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:user) { create(:user) }
describe '#execute' do
@@ -11,7 +11,7 @@ describe Gitlab::SlashCommands::Command do
context 'when no command is available' do
let(:params) { { text: 'issue show 1' } }
- let(:project) { create(:empty_project, has_external_issue_tracker: true) }
+ let(:project) { create(:project, has_external_issue_tracker: true) }
it 'displays 404 messages' do
expect(subject[:response_type]).to be(:ephemeral)
@@ -80,7 +80,7 @@ describe Gitlab::SlashCommands::Command do
it 'returns error' do
expect(subject[:response_type]).to be(:ephemeral)
- expect(subject[:text]).to include('Too many actions defined')
+ expect(subject[:text]).to include("Couldn't find a deployment manual action.")
end
end
end
diff --git a/spec/lib/gitlab/slash_commands/deploy_spec.rb b/spec/lib/gitlab/slash_commands/deploy_spec.rb
index e52aaed7328..74b5ef4bb26 100644
--- a/spec/lib/gitlab/slash_commands/deploy_spec.rb
+++ b/spec/lib/gitlab/slash_commands/deploy_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe Gitlab::SlashCommands::Deploy do
describe '#execute' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:user) { create(:user) }
let(:regex_match) { described_class.match('deploy staging to production') }
@@ -22,7 +22,7 @@ describe Gitlab::SlashCommands::Deploy do
context 'if no environment is defined' do
it 'does not execute an action' do
expect(subject[:response_type]).to be(:ephemeral)
- expect(subject[:text]).to eq("No action found to be executed")
+ expect(subject[:text]).to eq "Couldn't find a deployment manual action."
end
end
@@ -35,12 +35,12 @@ describe Gitlab::SlashCommands::Deploy do
context 'without actions' do
it 'does not execute an action' do
expect(subject[:response_type]).to be(:ephemeral)
- expect(subject[:text]).to eq("No action found to be executed")
+ expect(subject[:text]).to eq "Couldn't find a deployment manual action."
end
end
- context 'with action' do
- let!(:manual1) do
+ context 'when single action has been matched' do
+ before do
create(:ci_build, :manual, pipeline: pipeline,
name: 'first',
environment: 'production')
@@ -48,31 +48,61 @@ describe Gitlab::SlashCommands::Deploy do
it 'returns success result' do
expect(subject[:response_type]).to be(:in_channel)
- expect(subject[:text]).to start_with('Deployment started from staging to production')
+ expect(subject[:text])
+ .to start_with('Deployment started from staging to production')
end
+ end
+
+ context 'when more than one action has been matched' do
+ context 'when there is no specific actions with a environment name' do
+ before do
+ create(:ci_build, :manual, pipeline: pipeline,
+ name: 'first',
+ environment: 'production')
- context 'when duplicate action exists' do
- let!(:manual2) do
create(:ci_build, :manual, pipeline: pipeline,
name: 'second',
environment: 'production')
end
- it 'returns error' do
+ it 'returns error about too many actions defined' do
+ expect(subject[:text]).to eq("Couldn't find a deployment manual action.")
expect(subject[:response_type]).to be(:ephemeral)
- expect(subject[:text]).to eq('Too many actions defined')
end
end
- context 'when teardown action exists' do
- let!(:teardown) do
+ context 'when one of the actions is environement specific action' do
+ before do
+ create(:ci_build, :manual, pipeline: pipeline,
+ name: 'first',
+ environment: 'production')
+
+ create(:ci_build, :manual, pipeline: pipeline,
+ name: 'production',
+ environment: 'production')
+ end
+
+ it 'deploys to production' do
+ expect(subject[:text])
+ .to start_with('Deployment started from staging to production')
+ expect(subject[:response_type]).to be(:in_channel)
+ end
+ end
+
+ context 'when one of the actions is a teardown action' do
+ before do
+ create(:ci_build, :manual, pipeline: pipeline,
+ name: 'first',
+ environment: 'production')
+
create(:ci_build, :manual, :teardown_environment,
pipeline: pipeline, name: 'teardown', environment: 'production')
end
- it 'returns the success message' do
+ it 'deploys to production' do
+ expect(subject[:text])
+ .to start_with('Deployment started from staging to production')
expect(subject[:response_type]).to be(:in_channel)
- expect(subject[:text]).to start_with('Deployment started from staging to production')
end
end
end
diff --git a/spec/lib/gitlab/slash_commands/issue_new_spec.rb b/spec/lib/gitlab/slash_commands/issue_new_spec.rb
index 5dfb1b506bc..75ae58d0582 100644
--- a/spec/lib/gitlab/slash_commands/issue_new_spec.rb
+++ b/spec/lib/gitlab/slash_commands/issue_new_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe Gitlab::SlashCommands::IssueNew do
describe '#execute' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:user) { create(:user) }
let(:regex_match) { described_class.match("issue create bird is the word") }
diff --git a/spec/lib/gitlab/slash_commands/issue_search_spec.rb b/spec/lib/gitlab/slash_commands/issue_search_spec.rb
index e5409fe2339..51f59216413 100644
--- a/spec/lib/gitlab/slash_commands/issue_search_spec.rb
+++ b/spec/lib/gitlab/slash_commands/issue_search_spec.rb
@@ -4,7 +4,7 @@ describe Gitlab::SlashCommands::IssueSearch do
describe '#execute' do
let!(:issue) { create(:issue, project: project, title: 'find me') }
let!(:confidential) { create(:issue, :confidential, project: project, title: 'mepmep find') }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:user) { issue.author }
let(:regex_match) { described_class.match("issue search find") }
diff --git a/spec/lib/gitlab/slash_commands/issue_show_spec.rb b/spec/lib/gitlab/slash_commands/issue_show_spec.rb
index f67a17c7922..08c380ca8f1 100644
--- a/spec/lib/gitlab/slash_commands/issue_show_spec.rb
+++ b/spec/lib/gitlab/slash_commands/issue_show_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe Gitlab::SlashCommands::IssueShow do
describe '#execute' do
let(:issue) { create(:issue, project: project) }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:user) { issue.author }
let(:regex_match) { described_class.match("issue show #{issue.iid}") }
diff --git a/spec/lib/gitlab/slash_commands/presenters/deploy_spec.rb b/spec/lib/gitlab/slash_commands/presenters/deploy_spec.rb
index dee3c77db27..d16d122c64e 100644
--- a/spec/lib/gitlab/slash_commands/presenters/deploy_spec.rb
+++ b/spec/lib/gitlab/slash_commands/presenters/deploy_spec.rb
@@ -17,8 +17,8 @@ describe Gitlab::SlashCommands::Presenters::Deploy do
end
end
- describe '#no_actions' do
- subject { described_class.new(nil).no_actions }
+ describe '#action_not_found' do
+ subject { described_class.new(nil).action_not_found }
it { is_expected.to have_key(:text) }
it { is_expected.to have_key(:response_type) }
@@ -27,21 +27,7 @@ describe Gitlab::SlashCommands::Presenters::Deploy do
it 'tells the user there is no action' do
expect(subject[:response_type]).to be(:ephemeral)
- expect(subject[:text]).to eq("No action found to be executed")
- end
- end
-
- describe '#too_many_actions' do
- subject { described_class.new([]).too_many_actions }
-
- it { is_expected.to have_key(:text) }
- it { is_expected.to have_key(:response_type) }
- it { is_expected.to have_key(:status) }
- it { is_expected.not_to have_key(:attachments) }
-
- it 'tells the user there is no action' do
- expect(subject[:response_type]).to be(:ephemeral)
- expect(subject[:text]).to eq("Too many actions defined")
+ expect(subject[:text]).to eq "Couldn't find a deployment manual action."
end
end
end
diff --git a/spec/lib/gitlab/slash_commands/presenters/issue_new_spec.rb b/spec/lib/gitlab/slash_commands/presenters/issue_new_spec.rb
index 7f81ebb47db..76e4bad88fd 100644
--- a/spec/lib/gitlab/slash_commands/presenters/issue_new_spec.rb
+++ b/spec/lib/gitlab/slash_commands/presenters/issue_new_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Gitlab::SlashCommands::Presenters::IssueNew do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:issue) { create(:issue, project: project) }
let(:attachment) { subject[:attachments].first }
diff --git a/spec/lib/gitlab/slash_commands/presenters/issue_search_spec.rb b/spec/lib/gitlab/slash_commands/presenters/issue_search_spec.rb
index 7e57a0addcb..5a7ec0685fe 100644
--- a/spec/lib/gitlab/slash_commands/presenters/issue_search_spec.rb
+++ b/spec/lib/gitlab/slash_commands/presenters/issue_search_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Gitlab::SlashCommands::Presenters::IssueSearch do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:message) { subject[:text] }
before do
diff --git a/spec/lib/gitlab/slash_commands/presenters/issue_show_spec.rb b/spec/lib/gitlab/slash_commands/presenters/issue_show_spec.rb
index 2a6ed860737..8f607d7a9c9 100644
--- a/spec/lib/gitlab/slash_commands/presenters/issue_show_spec.rb
+++ b/spec/lib/gitlab/slash_commands/presenters/issue_show_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Gitlab::SlashCommands::Presenters::IssueShow do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:issue) { create(:issue, project: project) }
let(:attachment) { subject[:attachments].first }
diff --git a/spec/lib/gitlab/sql/union_spec.rb b/spec/lib/gitlab/sql/union_spec.rb
index 5346881444d..baf8f6644bf 100644
--- a/spec/lib/gitlab/sql/union_spec.rb
+++ b/spec/lib/gitlab/sql/union_spec.rb
@@ -19,7 +19,7 @@ describe Gitlab::SQL::Union do
empty_relation = User.none
union = described_class.new([empty_relation, relation_1, relation_2])
- expect{User.where("users.id IN (#{union.to_sql})").to_a}.not_to raise_error
+ expect {User.where("users.id IN (#{union.to_sql})").to_a}.not_to raise_error
expect(union.to_sql).to eq("#{to_sql(relation_1)}\nUNION\n#{to_sql(relation_2)}")
end
end
diff --git a/spec/lib/gitlab/template/issue_template_spec.rb b/spec/lib/gitlab/template/issue_template_spec.rb
index bf45c8d16d6..7098499f996 100644
--- a/spec/lib/gitlab/template/issue_template_spec.rb
+++ b/spec/lib/gitlab/template/issue_template_spec.rb
@@ -1,41 +1,28 @@
require 'spec_helper'
describe Gitlab::Template::IssueTemplate do
- subject { described_class }
-
- let(:user) { create(:user) }
-
- let(:project) do
- create(:project,
- :repository,
- create_template: {
- user: user,
- access: Gitlab::Access::MASTER,
- path: 'issue_templates'
- })
- end
+ let(:project) { create(:project, :repository, create_templates: :issue) }
describe '.all' do
it 'strips the md suffix' do
- expect(subject.all(project).first.name).not_to end_with('.issue_template')
+ expect(described_class.all(project).first.name).not_to end_with('.issue_template')
end
it 'combines the globals and rest' do
- all = subject.all(project).map(&:name)
+ all = described_class.all(project).map(&:name)
expect(all).to include('bug')
expect(all).to include('feature_proposal')
- expect(all).to include('template_test')
end
end
describe '.find' do
it 'returns nil if the file does not exist' do
- expect { subject.find('mepmep-yadida', project) }.to raise_error(Gitlab::Template::Finders::RepoTemplateFinder::FileNotFoundError)
+ expect { described_class.find('mepmep-yadida', project) }.to raise_error(Gitlab::Template::Finders::RepoTemplateFinder::FileNotFoundError)
end
it 'returns the issue object of a valid file' do
- ruby = subject.find('bug', project)
+ ruby = described_class.find('bug', project)
expect(ruby).to be_a described_class
expect(ruby.name).to eq('bug')
@@ -44,21 +31,17 @@ describe Gitlab::Template::IssueTemplate do
describe '.by_category' do
it 'return array of templates' do
- all = subject.by_category('', project).map(&:name)
+ all = described_class.by_category('', project).map(&:name)
expect(all).to include('bug')
expect(all).to include('feature_proposal')
- expect(all).to include('template_test')
end
context 'when repo is bare or empty' do
- let(:empty_project) { create(:empty_project) }
-
- before do
- empty_project.add_user(user, Gitlab::Access::MASTER)
- end
+ let(:empty_project) { create(:project) }
it "returns empty array" do
- templates = subject.by_category('', empty_project)
+ templates = described_class.by_category('', empty_project)
+
expect(templates).to be_empty
end
end
@@ -66,26 +49,23 @@ describe Gitlab::Template::IssueTemplate do
describe '#content' do
it 'loads the full file' do
- issue_template = subject.new('.gitlab/issue_templates/bug.md', project)
+ issue_template = described_class.new('.gitlab/issue_templates/bug.md', project)
expect(issue_template.name).to eq 'bug'
expect(issue_template.content).to eq('something valid')
end
it 'raises error when file is not found' do
- issue_template = subject.new('.gitlab/issue_templates/bugnot.md', project)
+ issue_template = described_class.new('.gitlab/issue_templates/bugnot.md', project)
expect { issue_template.content }.to raise_error(Gitlab::Template::Finders::RepoTemplateFinder::FileNotFoundError)
end
context "when repo is empty" do
- let(:empty_project) { create(:empty_project) }
-
- before do
- empty_project.add_user(user, Gitlab::Access::MASTER)
- end
+ let(:empty_project) { create(:project) }
it "raises file not found" do
- issue_template = subject.new('.gitlab/issue_templates/not_existent.md', empty_project)
+ issue_template = described_class.new('.gitlab/issue_templates/not_existent.md', empty_project)
+
expect { issue_template.content }.to raise_error(Gitlab::Template::Finders::RepoTemplateFinder::FileNotFoundError)
end
end
diff --git a/spec/lib/gitlab/template/merge_request_template_spec.rb b/spec/lib/gitlab/template/merge_request_template_spec.rb
index 8479f92c8df..bd7ff64aa8a 100644
--- a/spec/lib/gitlab/template/merge_request_template_spec.rb
+++ b/spec/lib/gitlab/template/merge_request_template_spec.rb
@@ -1,41 +1,28 @@
require 'spec_helper'
describe Gitlab::Template::MergeRequestTemplate do
- subject { described_class }
-
- let(:user) { create(:user) }
-
- let(:project) do
- create(:project,
- :repository,
- create_template: {
- user: user,
- access: Gitlab::Access::MASTER,
- path: 'merge_request_templates'
- })
- end
+ let(:project) { create(:project, :repository, create_templates: :merge_request) }
describe '.all' do
it 'strips the md suffix' do
- expect(subject.all(project).first.name).not_to end_with('.issue_template')
+ expect(described_class.all(project).first.name).not_to end_with('.issue_template')
end
it 'combines the globals and rest' do
- all = subject.all(project).map(&:name)
+ all = described_class.all(project).map(&:name)
expect(all).to include('bug')
expect(all).to include('feature_proposal')
- expect(all).to include('template_test')
end
end
describe '.find' do
it 'returns nil if the file does not exist' do
- expect { subject.find('mepmep-yadida', project) }.to raise_error(Gitlab::Template::Finders::RepoTemplateFinder::FileNotFoundError)
+ expect { described_class.find('mepmep-yadida', project) }.to raise_error(Gitlab::Template::Finders::RepoTemplateFinder::FileNotFoundError)
end
it 'returns the merge request object of a valid file' do
- ruby = subject.find('bug', project)
+ ruby = described_class.find('bug', project)
expect(ruby).to be_a described_class
expect(ruby.name).to eq('bug')
@@ -44,21 +31,17 @@ describe Gitlab::Template::MergeRequestTemplate do
describe '.by_category' do
it 'return array of templates' do
- all = subject.by_category('', project).map(&:name)
+ all = described_class.by_category('', project).map(&:name)
expect(all).to include('bug')
expect(all).to include('feature_proposal')
- expect(all).to include('template_test')
end
context 'when repo is bare or empty' do
- let(:empty_project) { create(:empty_project) }
-
- before do
- empty_project.add_user(user, Gitlab::Access::MASTER)
- end
+ let(:empty_project) { create(:project) }
it "returns empty array" do
- templates = subject.by_category('', empty_project)
+ templates = described_class.by_category('', empty_project)
+
expect(templates).to be_empty
end
end
@@ -66,26 +49,23 @@ describe Gitlab::Template::MergeRequestTemplate do
describe '#content' do
it 'loads the full file' do
- issue_template = subject.new('.gitlab/merge_request_templates/bug.md', project)
+ issue_template = described_class.new('.gitlab/merge_request_templates/bug.md', project)
expect(issue_template.name).to eq 'bug'
expect(issue_template.content).to eq('something valid')
end
it 'raises error when file is not found' do
- issue_template = subject.new('.gitlab/merge_request_templates/bugnot.md', project)
+ issue_template = described_class.new('.gitlab/merge_request_templates/bugnot.md', project)
expect { issue_template.content }.to raise_error(Gitlab::Template::Finders::RepoTemplateFinder::FileNotFoundError)
end
context "when repo is empty" do
- let(:empty_project) { create(:empty_project) }
-
- before do
- empty_project.add_user(user, Gitlab::Access::MASTER)
- end
+ let(:empty_project) { create(:project) }
it "raises file not found" do
- issue_template = subject.new('.gitlab/merge_request_templates/not_existent.md', empty_project)
+ issue_template = described_class.new('.gitlab/merge_request_templates/not_existent.md', empty_project)
+
expect { issue_template.content }.to raise_error(Gitlab::Template::Finders::RepoTemplateFinder::FileNotFoundError)
end
end
diff --git a/spec/lib/gitlab/uploads_transfer_spec.rb b/spec/lib/gitlab/uploads_transfer_spec.rb
index 109559bb01c..4275e7b015b 100644
--- a/spec/lib/gitlab/uploads_transfer_spec.rb
+++ b/spec/lib/gitlab/uploads_transfer_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe Gitlab::UploadsTransfer do
it 'leaves avatar uploads where they are' do
- project_with_avatar = create(:empty_project, :with_avatar)
+ project_with_avatar = create(:project, :with_avatar)
described_class.new.rename_namespace('project', 'project-renamed')
diff --git a/spec/lib/gitlab/url_blocker_spec.rb b/spec/lib/gitlab/url_blocker_spec.rb
index f5b4882815f..f18823b61ef 100644
--- a/spec/lib/gitlab/url_blocker_spec.rb
+++ b/spec/lib/gitlab/url_blocker_spec.rb
@@ -20,6 +20,34 @@ describe Gitlab::UrlBlocker do
expect(described_class.blocked_url?('https://gitlab.com:25/foo/foo.git')).to be true
end
+ it 'returns true for a non-alphanumeric hostname' do
+ stub_resolv
+
+ aggregate_failures do
+ expect(described_class).to be_blocked_url('ssh://-oProxyCommand=whoami/a')
+
+ # The leading character here is a Unicode "soft hyphen"
+ expect(described_class).to be_blocked_url('ssh://­oProxyCommand=whoami/a')
+
+ # Unicode alphanumerics are allowed
+ expect(described_class).not_to be_blocked_url('ssh://ÄŸitlab.com/a')
+ end
+ end
+
+ it 'returns true for a non-alphanumeric username' do
+ stub_resolv
+
+ aggregate_failures do
+ expect(described_class).to be_blocked_url('ssh://-oProxyCommand=whoami@example.com/a')
+
+ # The leading character here is a Unicode "soft hyphen"
+ expect(described_class).to be_blocked_url('ssh://­oProxyCommand=whoami@example.com/a')
+
+ # Unicode alphanumerics are allowed
+ expect(described_class).not_to be_blocked_url('ssh://ÄŸitlab@example.com/a')
+ end
+ end
+
it 'returns true for invalid URL' do
expect(described_class.blocked_url?('http://:8080')).to be true
end
@@ -28,4 +56,10 @@ describe Gitlab::UrlBlocker do
expect(described_class.blocked_url?('https://gitlab.com/foo/foo.git')).to be false
end
end
+
+ # Resolv does not support resolving UTF-8 domain names
+ # See https://bugs.ruby-lang.org/issues/4270
+ def stub_resolv
+ allow(Resolv).to receive(:getaddresses).and_return([])
+ end
end
diff --git a/spec/lib/gitlab/url_builder_spec.rb b/spec/lib/gitlab/url_builder_spec.rb
index 50422020823..b81749cf428 100644
--- a/spec/lib/gitlab/url_builder_spec.rb
+++ b/spec/lib/gitlab/url_builder_spec.rb
@@ -8,7 +8,7 @@ describe Gitlab::UrlBuilder do
url = described_class.build(commit)
- expect(url).to eq "#{Settings.gitlab['url']}/#{commit.project.path_with_namespace}/commit/#{commit.id}"
+ expect(url).to eq "#{Settings.gitlab['url']}/#{commit.project.full_path}/commit/#{commit.id}"
end
end
@@ -18,7 +18,7 @@ describe Gitlab::UrlBuilder do
url = described_class.build(issue)
- expect(url).to eq "#{Settings.gitlab['url']}/#{issue.project.path_with_namespace}/issues/#{issue.iid}"
+ expect(url).to eq "#{Settings.gitlab['url']}/#{issue.project.full_path}/issues/#{issue.iid}"
end
end
@@ -28,7 +28,7 @@ describe Gitlab::UrlBuilder do
url = described_class.build(merge_request)
- expect(url).to eq "#{Settings.gitlab['url']}/#{merge_request.project.path_with_namespace}/merge_requests/#{merge_request.iid}"
+ expect(url).to eq "#{Settings.gitlab['url']}/#{merge_request.project.full_path}/merge_requests/#{merge_request.iid}"
end
end
@@ -39,7 +39,7 @@ describe Gitlab::UrlBuilder do
url = described_class.build(note)
- expect(url).to eq "#{Settings.gitlab['url']}/#{note.project.path_with_namespace}/commit/#{note.commit_id}#note_#{note.id}"
+ expect(url).to eq "#{Settings.gitlab['url']}/#{note.project.full_path}/commit/#{note.commit_id}#note_#{note.id}"
end
end
@@ -49,7 +49,7 @@ describe Gitlab::UrlBuilder do
url = described_class.build(note)
- expect(url).to eq "#{Settings.gitlab['url']}/#{note.project.path_with_namespace}/commit/#{note.commit_id}#note_#{note.id}"
+ expect(url).to eq "#{Settings.gitlab['url']}/#{note.project.full_path}/commit/#{note.commit_id}#note_#{note.id}"
end
end
@@ -60,7 +60,7 @@ describe Gitlab::UrlBuilder do
url = described_class.build(note)
- expect(url).to eq "#{Settings.gitlab['url']}/#{issue.project.path_with_namespace}/issues/#{issue.iid}#note_#{note.id}"
+ expect(url).to eq "#{Settings.gitlab['url']}/#{issue.project.full_path}/issues/#{issue.iid}#note_#{note.id}"
end
end
@@ -71,7 +71,7 @@ describe Gitlab::UrlBuilder do
url = described_class.build(note)
- expect(url).to eq "#{Settings.gitlab['url']}/#{merge_request.project.path_with_namespace}/merge_requests/#{merge_request.iid}#note_#{note.id}"
+ expect(url).to eq "#{Settings.gitlab['url']}/#{merge_request.project.full_path}/merge_requests/#{merge_request.iid}#note_#{note.id}"
end
end
@@ -82,7 +82,7 @@ describe Gitlab::UrlBuilder do
url = described_class.build(note)
- expect(url).to eq "#{Settings.gitlab['url']}/#{merge_request.project.path_with_namespace}/merge_requests/#{merge_request.iid}#note_#{note.id}"
+ expect(url).to eq "#{Settings.gitlab['url']}/#{merge_request.project.full_path}/merge_requests/#{merge_request.iid}#note_#{note.id}"
end
end
@@ -93,7 +93,7 @@ describe Gitlab::UrlBuilder do
url = described_class.build(note)
- expect(url).to eq "#{Settings.gitlab['url']}/#{project_snippet.project.path_with_namespace}/snippets/#{note.noteable_id}#note_#{note.id}"
+ expect(url).to eq "#{Settings.gitlab['url']}/#{project_snippet.project.full_path}/snippets/#{note.noteable_id}#note_#{note.id}"
end
end
@@ -110,7 +110,7 @@ describe Gitlab::UrlBuilder do
context 'on another object' do
it 'returns a proper URL' do
- project = build_stubbed(:empty_project)
+ project = build_stubbed(:project)
expect { described_class.build(project) }
.to raise_error(NotImplementedError, 'No URL builder defined for Project')
diff --git a/spec/lib/gitlab/user_access_spec.rb b/spec/lib/gitlab/user_access_spec.rb
index 5ebaf6c1507..cd97416bcc9 100644
--- a/spec/lib/gitlab/user_access_spec.rb
+++ b/spec/lib/gitlab/user_access_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe Gitlab::UserAccess do
let(:access) { described_class.new(user, project: project) }
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
describe '#can_push_to_branch?' do
diff --git a/spec/lib/gitlab/version_info_spec.rb b/spec/lib/gitlab/version_info_spec.rb
index e7e1a92ae54..c8a1e433d59 100644
--- a/spec/lib/gitlab/version_info_spec.rb
+++ b/spec/lib/gitlab/version_info_spec.rb
@@ -50,8 +50,8 @@ describe 'Gitlab::VersionInfo' do
context 'unknown' do
it { expect(@unknown).not_to be @v0_0_1 }
it { expect(@unknown).not_to be Gitlab::VersionInfo.new }
- it { expect{@unknown > @v0_0_1}.to raise_error(ArgumentError) }
- it { expect{@unknown < @v0_0_1}.to raise_error(ArgumentError) }
+ it { expect {@unknown > @v0_0_1}.to raise_error(ArgumentError) }
+ it { expect {@unknown < @v0_0_1}.to raise_error(ArgumentError) }
end
context 'parse' do
diff --git a/spec/lib/gitlab/view/presenter/base_spec.rb b/spec/lib/gitlab/view/presenter/base_spec.rb
index f2c152cdcd4..32a946ca034 100644
--- a/spec/lib/gitlab/view/presenter/base_spec.rb
+++ b/spec/lib/gitlab/view/presenter/base_spec.rb
@@ -26,7 +26,7 @@ describe Gitlab::View::Presenter::Base do
describe '#can?' do
context 'user is not allowed' do
it 'returns false' do
- presenter = presenter_class.new(build_stubbed(:empty_project))
+ presenter = presenter_class.new(build_stubbed(:project))
expect(presenter.can?(nil, :read_project)).to be_falsy
end
@@ -34,7 +34,7 @@ describe Gitlab::View::Presenter::Base do
context 'user is allowed' do
it 'returns true' do
- presenter = presenter_class.new(build_stubbed(:empty_project, :public))
+ presenter = presenter_class.new(build_stubbed(:project, :public))
expect(presenter.can?(nil, :read_project)).to be_truthy
end
@@ -42,9 +42,9 @@ describe Gitlab::View::Presenter::Base do
context 'subject is overriden' do
it 'returns true' do
- presenter = presenter_class.new(build_stubbed(:empty_project, :public))
+ presenter = presenter_class.new(build_stubbed(:project, :public))
- expect(presenter.can?(nil, :read_project, build_stubbed(:empty_project))).to be_falsy
+ expect(presenter.can?(nil, :read_project, build_stubbed(:project))).to be_falsy
end
end
end
diff --git a/spec/lib/gitlab/workhorse_spec.rb b/spec/lib/gitlab/workhorse_spec.rb
index 654397ccffb..b66afafa174 100644
--- a/spec/lib/gitlab/workhorse_spec.rb
+++ b/spec/lib/gitlab/workhorse_spec.rb
@@ -202,7 +202,6 @@ describe Gitlab::Workhorse do
context 'when Gitaly is enabled' do
let(:gitaly_params) do
{
- GitalyAddress: Gitlab::GitalyClient.address('default'),
GitalyServer: {
address: Gitlab::GitalyClient.address('default'),
token: Gitlab::GitalyClient.token('default')
@@ -217,7 +216,9 @@ describe Gitlab::Workhorse do
it 'includes a Repository param' do
repo_param = { Repository: {
storage_name: 'default',
- relative_path: project.full_path + '.git'
+ relative_path: project.full_path + '.git',
+ git_object_directory: '',
+ git_alternate_object_directories: []
} }
expect(subject).to include(repo_param)
diff --git a/spec/lib/json_web_token/rsa_token_spec.rb b/spec/lib/json_web_token/rsa_token_spec.rb
index e7022bd06f8..d6edc964844 100644
--- a/spec/lib/json_web_token/rsa_token_spec.rb
+++ b/spec/lib/json_web_token/rsa_token_spec.rb
@@ -27,7 +27,7 @@ describe JSONWebToken::RSAToken do
subject { JWT.decode(rsa_encoded, rsa_key) }
- it { expect{subject}.not_to raise_error }
+ it { expect {subject}.not_to raise_error }
it { expect(subject.first).to include('key' => 'value') }
it do
expect(subject.second).to eq(
@@ -41,7 +41,7 @@ describe JSONWebToken::RSAToken do
let(:new_key) { OpenSSL::PKey::RSA.generate(512) }
subject { JWT.decode(rsa_encoded, new_key) }
- it { expect{subject}.to raise_error(JWT::DecodeError) }
+ it { expect {subject}.to raise_error(JWT::DecodeError) }
end
end
end
diff --git a/spec/lib/mattermost/session_spec.rb b/spec/lib/mattermost/session_spec.rb
index be3908e8f6a..3db19d06305 100644
--- a/spec/lib/mattermost/session_spec.rb
+++ b/spec/lib/mattermost/session_spec.rb
@@ -20,9 +20,10 @@ describe Mattermost::Session, type: :request do
describe '#with session' do
let(:location) { 'http://location.tld' }
+ let(:cookie_header) {'MMOAUTH=taskik8az7rq8k6rkpuas7htia; Path=/;'}
let!(:stub) do
WebMock.stub_request(:get, "#{mattermost_url}/api/v3/oauth/gitlab/login")
- .to_return(headers: { 'location' => location }, status: 307)
+ .to_return(headers: { 'location' => location, 'Set-Cookie' => cookie_header }, status: 307)
end
context 'without oauth uri' do
@@ -34,9 +35,9 @@ describe Mattermost::Session, type: :request do
context 'with oauth_uri' do
let!(:doorkeeper) do
Doorkeeper::Application.create(
- name: "GitLab Mattermost",
+ name: 'GitLab Mattermost',
redirect_uri: "#{mattermost_url}/signup/gitlab/complete\n#{mattermost_url}/login/gitlab/complete",
- scopes: "")
+ scopes: '')
end
context 'without token_uri' do
diff --git a/spec/lib/repository_cache_spec.rb b/spec/lib/repository_cache_spec.rb
index 0c15ba22bf2..8b0c7254b5e 100644
--- a/spec/lib/repository_cache_spec.rb
+++ b/spec/lib/repository_cache_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe RepositoryCache do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:backend) { double('backend').as_null_object }
let(:cache) { described_class.new('example', project.id, backend) }
diff --git a/spec/lib/rspec_flaky/example_spec.rb b/spec/lib/rspec_flaky/example_spec.rb
new file mode 100644
index 00000000000..5b4fd5ddf3e
--- /dev/null
+++ b/spec/lib/rspec_flaky/example_spec.rb
@@ -0,0 +1,89 @@
+require 'spec_helper'
+
+describe RspecFlaky::Example do
+ let(:example_attrs) do
+ {
+ id: 'spec/foo/bar_spec.rb:2',
+ metadata: {
+ file_path: 'spec/foo/bar_spec.rb',
+ line_number: 2,
+ full_description: 'hello world'
+ },
+ execution_result: double(status: 'passed', exception: 'BOOM!'),
+ attempts: 1
+ }
+ end
+ let(:rspec_example) { double(example_attrs) }
+
+ describe '#initialize' do
+ shared_examples 'a valid Example instance' do
+ it 'returns valid attributes' do
+ example = described_class.new(args)
+
+ expect(example.example_id).to eq(example_attrs[:id])
+ end
+ end
+
+ context 'when given an Rspec::Core::Example that responds to #example' do
+ let(:args) { double(example: rspec_example) }
+
+ it_behaves_like 'a valid Example instance'
+ end
+
+ context 'when given an Rspec::Core::Example that does not respond to #example' do
+ let(:args) { rspec_example }
+
+ it_behaves_like 'a valid Example instance'
+ end
+ end
+
+ subject { described_class.new(rspec_example) }
+
+ describe '#uid' do
+ it 'returns a hash of the full description' do
+ expect(subject.uid).to eq(Digest::MD5.hexdigest("#{subject.description}-#{subject.file}"))
+ end
+ end
+
+ describe '#example_id' do
+ it 'returns the ID of the RSpec::Core::Example' do
+ expect(subject.example_id).to eq(rspec_example.id)
+ end
+ end
+
+ describe '#attempts' do
+ it 'returns the attempts of the RSpec::Core::Example' do
+ expect(subject.attempts).to eq(rspec_example.attempts)
+ end
+ end
+
+ describe '#file' do
+ it 'returns the metadata[:file_path] of the RSpec::Core::Example' do
+ expect(subject.file).to eq(rspec_example.metadata[:file_path])
+ end
+ end
+
+ describe '#line' do
+ it 'returns the metadata[:line_number] of the RSpec::Core::Example' do
+ expect(subject.line).to eq(rspec_example.metadata[:line_number])
+ end
+ end
+
+ describe '#description' do
+ it 'returns the metadata[:full_description] of the RSpec::Core::Example' do
+ expect(subject.description).to eq(rspec_example.metadata[:full_description])
+ end
+ end
+
+ describe '#status' do
+ it 'returns the execution_result.status of the RSpec::Core::Example' do
+ expect(subject.status).to eq(rspec_example.execution_result.status)
+ end
+ end
+
+ describe '#exception' do
+ it 'returns the execution_result.exception of the RSpec::Core::Example' do
+ expect(subject.exception).to eq(rspec_example.execution_result.exception)
+ end
+ end
+end
diff --git a/spec/lib/rspec_flaky/flaky_example_spec.rb b/spec/lib/rspec_flaky/flaky_example_spec.rb
new file mode 100644
index 00000000000..cbfc1e538ab
--- /dev/null
+++ b/spec/lib/rspec_flaky/flaky_example_spec.rb
@@ -0,0 +1,104 @@
+require 'spec_helper'
+
+describe RspecFlaky::FlakyExample do
+ let(:flaky_example_attrs) do
+ {
+ example_id: 'spec/foo/bar_spec.rb:2',
+ file: 'spec/foo/bar_spec.rb',
+ line: 2,
+ description: 'hello world',
+ first_flaky_at: 1234,
+ last_flaky_at: 2345,
+ last_attempts_count: 2,
+ flaky_reports: 1
+ }
+ end
+ let(:example_attrs) do
+ {
+ uid: 'abc123',
+ example_id: flaky_example_attrs[:example_id],
+ file: flaky_example_attrs[:file],
+ line: flaky_example_attrs[:line],
+ description: flaky_example_attrs[:description],
+ status: 'passed',
+ exception: 'BOOM!',
+ attempts: flaky_example_attrs[:last_attempts_count]
+ }
+ end
+ let(:example) { double(example_attrs) }
+
+ describe '#initialize' do
+ shared_examples 'a valid FlakyExample instance' do
+ it 'returns valid attributes' do
+ flaky_example = described_class.new(args)
+
+ expect(flaky_example.uid).to eq(flaky_example_attrs[:uid])
+ expect(flaky_example.example_id).to eq(flaky_example_attrs[:example_id])
+ end
+ end
+
+ context 'when given an Rspec::Example' do
+ let(:args) { example }
+
+ it_behaves_like 'a valid FlakyExample instance'
+ end
+
+ context 'when given a hash' do
+ let(:args) { flaky_example_attrs }
+
+ it_behaves_like 'a valid FlakyExample instance'
+ end
+ end
+
+ describe '#to_h' do
+ before do
+ # Stub these env variables otherwise specs don't behave the same on the CI
+ stub_env('CI_PROJECT_URL', nil)
+ stub_env('CI_JOB_ID', nil)
+ end
+
+ shared_examples 'a valid FlakyExample hash' do
+ let(:additional_attrs) { {} }
+
+ it 'returns a valid hash' do
+ flaky_example = described_class.new(args)
+ final_hash = flaky_example_attrs
+ .merge(last_flaky_at: instance_of(Time), last_flaky_job: nil)
+ .merge(additional_attrs)
+
+ expect(flaky_example.to_h).to match(hash_including(final_hash))
+ end
+ end
+
+ context 'when given an Rspec::Example' do
+ let(:args) { example }
+
+ context 'when run locally' do
+ it_behaves_like 'a valid FlakyExample hash' do
+ let(:additional_attrs) do
+ { first_flaky_at: instance_of(Time) }
+ end
+ end
+ end
+
+ context 'when run on the CI' do
+ before do
+ stub_env('CI_PROJECT_URL', 'https://gitlab.com/gitlab-org/gitlab-ce')
+ stub_env('CI_JOB_ID', 42)
+ end
+
+ it_behaves_like 'a valid FlakyExample hash' do
+ let(:additional_attrs) do
+ { first_flaky_at: instance_of(Time), last_flaky_job: "https://gitlab.com/gitlab-org/gitlab-ce/-/jobs/42" }
+ end
+ end
+ end
+ end
+
+ context 'when given a hash' do
+ let(:args) { flaky_example_attrs }
+
+ it_behaves_like 'a valid FlakyExample hash'
+ end
+ end
+end
diff --git a/spec/lib/rspec_flaky/listener_spec.rb b/spec/lib/rspec_flaky/listener_spec.rb
new file mode 100644
index 00000000000..0e193bf408b
--- /dev/null
+++ b/spec/lib/rspec_flaky/listener_spec.rb
@@ -0,0 +1,178 @@
+require 'spec_helper'
+
+describe RspecFlaky::Listener do
+ let(:flaky_example_report) do
+ {
+ 'abc123' => {
+ example_id: 'spec/foo/bar_spec.rb:2',
+ file: 'spec/foo/bar_spec.rb',
+ line: 2,
+ description: 'hello world',
+ first_flaky_at: 1234,
+ last_flaky_at: instance_of(Time),
+ last_attempts_count: 2,
+ flaky_reports: 1,
+ last_flaky_job: nil
+ }
+ }
+ end
+ let(:example_attrs) do
+ {
+ id: 'spec/foo/baz_spec.rb:3',
+ metadata: {
+ file_path: 'spec/foo/baz_spec.rb',
+ line_number: 3,
+ full_description: 'hello GitLab'
+ },
+ execution_result: double(status: 'passed', exception: nil)
+ }
+ end
+
+ before do
+ # Stub these env variables otherwise specs don't behave the same on the CI
+ stub_env('CI_PROJECT_URL', nil)
+ stub_env('CI_JOB_ID', nil)
+ end
+
+ describe '#initialize' do
+ shared_examples 'a valid Listener instance' do
+ let(:expected_all_flaky_examples) { {} }
+
+ it 'returns a valid Listener instance' do
+ listener = described_class.new
+
+ expect(listener.to_report(listener.all_flaky_examples))
+ .to match(hash_including(expected_all_flaky_examples))
+ expect(listener.new_flaky_examples).to eq({})
+ end
+ end
+
+ context 'when no report file exists' do
+ it_behaves_like 'a valid Listener instance'
+ end
+
+ context 'when a report file exists and set by ALL_FLAKY_RSPEC_REPORT_PATH' do
+ let(:report_file) do
+ Tempfile.new(%w[rspec_flaky_report .json]).tap do |f|
+ f.write(JSON.pretty_generate(flaky_example_report))
+ f.rewind
+ end
+ end
+
+ before do
+ stub_env('ALL_FLAKY_RSPEC_REPORT_PATH', report_file.path)
+ end
+
+ after do
+ report_file.close
+ report_file.unlink
+ end
+
+ it_behaves_like 'a valid Listener instance' do
+ let(:expected_all_flaky_examples) { flaky_example_report }
+ end
+ end
+ end
+
+ describe '#example_passed' do
+ let(:rspec_example) { double(example_attrs) }
+ let(:notification) { double(example: rspec_example) }
+
+ shared_examples 'a non-flaky example' do
+ it 'does not change the flaky examples hash' do
+ expect { subject.example_passed(notification) }
+ .not_to change { subject.all_flaky_examples }
+ end
+ end
+
+ describe 'when the RSpec example does not respond to attempts' do
+ it_behaves_like 'a non-flaky example'
+ end
+
+ describe 'when the RSpec example has 1 attempt' do
+ let(:rspec_example) { double(example_attrs.merge(attempts: 1)) }
+
+ it_behaves_like 'a non-flaky example'
+ end
+
+ describe 'when the RSpec example has 2 attempts' do
+ let(:rspec_example) { double(example_attrs.merge(attempts: 2)) }
+ let(:expected_new_flaky_example) do
+ {
+ example_id: 'spec/foo/baz_spec.rb:3',
+ file: 'spec/foo/baz_spec.rb',
+ line: 3,
+ description: 'hello GitLab',
+ first_flaky_at: instance_of(Time),
+ last_flaky_at: instance_of(Time),
+ last_attempts_count: 2,
+ flaky_reports: 1,
+ last_flaky_job: nil
+ }
+ end
+
+ it 'does not change the flaky examples hash' do
+ expect { subject.example_passed(notification) }
+ .to change { subject.all_flaky_examples }
+
+ new_example = RspecFlaky::Example.new(rspec_example)
+
+ expect(subject.all_flaky_examples[new_example.uid].to_h)
+ .to match(hash_including(expected_new_flaky_example))
+ end
+ end
+ end
+
+ describe '#dump_summary' do
+ let(:rspec_example) { double(example_attrs) }
+ let(:notification) { double(example: rspec_example) }
+
+ context 'when a report file path is set by ALL_FLAKY_RSPEC_REPORT_PATH' do
+ let(:report_file_path) { Rails.root.join('tmp', 'rspec_flaky_report.json') }
+
+ before do
+ stub_env('ALL_FLAKY_RSPEC_REPORT_PATH', report_file_path)
+ FileUtils.rm(report_file_path) if File.exist?(report_file_path)
+ end
+
+ after do
+ FileUtils.rm(report_file_path) if File.exist?(report_file_path)
+ end
+
+ context 'when FLAKY_RSPEC_GENERATE_REPORT == "false"' do
+ before do
+ stub_env('FLAKY_RSPEC_GENERATE_REPORT', 'false')
+ end
+
+ it 'does not write the report file' do
+ subject.example_passed(notification)
+
+ subject.dump_summary(nil)
+
+ expect(File.exist?(report_file_path)).to be(false)
+ end
+ end
+
+ context 'when FLAKY_RSPEC_GENERATE_REPORT == "true"' do
+ before do
+ stub_env('FLAKY_RSPEC_GENERATE_REPORT', 'true')
+ end
+
+ it 'writes the report file' do
+ subject.example_passed(notification)
+
+ subject.dump_summary(nil)
+
+ expect(File.exist?(report_file_path)).to be(true)
+ end
+ end
+ end
+ end
+
+ describe '#to_report' do
+ it 'transforms the internal hash to a JSON-ready hash' do
+ expect(subject.to_report('abc123' => RspecFlaky::FlakyExample.new(flaky_example_report['abc123'])))
+ .to match(hash_including(flaky_example_report))
+ end
+ end
+end
diff --git a/spec/lib/system_check/simple_executor_spec.rb b/spec/lib/system_check/simple_executor_spec.rb
index 025ea2673b4..4de5da984ba 100644
--- a/spec/lib/system_check/simple_executor_spec.rb
+++ b/spec/lib/system_check/simple_executor_spec.rb
@@ -240,7 +240,7 @@ describe SystemCheck::SimpleExecutor do
context 'when there is an exception' do
it 'rescues the exception' do
- expect{ subject.run_check(BugousCheck) }.not_to raise_exception
+ expect { subject.run_check(BugousCheck) }.not_to raise_exception
end
end
end
diff --git a/spec/mailers/notify_spec.rb b/spec/mailers/notify_spec.rb
index 683e893968b..1fa59ebd22b 100644
--- a/spec/mailers/notify_spec.rb
+++ b/spec/mailers/notify_spec.rb
@@ -348,7 +348,7 @@ describe Notify do
end
describe 'project was moved' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:user) { create(:user) }
subject { described_class.project_was_moved_email(project.id, user.id, "gitlab/gitlab") }
@@ -366,7 +366,7 @@ describe Notify do
describe 'project access requested' do
context 'for a project in a user namespace' do
let(:project) do
- create(:empty_project, :public, :access_requestable) do |project|
+ create(:project, :public, :access_requestable) do |project|
project.team << [project.owner, :master, project.owner]
end
end
@@ -397,7 +397,7 @@ describe Notify do
context 'for a project in a group' do
let(:group_owner) { create(:user) }
let(:group) { create(:group).tap { |g| g.add_owner(group_owner) } }
- let(:project) { create(:empty_project, :public, :access_requestable, namespace: group) }
+ let(:project) { create(:project, :public, :access_requestable, namespace: group) }
let(:user) { create(:user) }
let(:project_member) do
project.request_access(user)
@@ -423,7 +423,7 @@ describe Notify do
end
describe 'project access denied' do
- let(:project) { create(:empty_project, :public, :access_requestable) }
+ let(:project) { create(:project, :public, :access_requestable) }
let(:user) { create(:user) }
let(:project_member) do
project.request_access(user)
@@ -444,7 +444,7 @@ describe Notify do
describe 'project access changed' do
let(:owner) { create(:user, name: "Chang O'Keefe") }
- let(:project) { create(:empty_project, :public, :access_requestable, namespace: owner.namespace) }
+ let(:project) { create(:project, :public, :access_requestable, namespace: owner.namespace) }
let(:user) { create(:user) }
let(:project_member) { create(:project_member, project: project, user: user) }
subject { described_class.member_access_granted_email('project', project_member.id) }
@@ -474,7 +474,7 @@ describe Notify do
end
describe 'project invitation' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:master) { create(:user).tap { |u| project.team << [u, :master] } }
let(:project_member) { invite_to_project(project, inviter: master) }
@@ -494,7 +494,7 @@ describe Notify do
end
describe 'project invitation accepted' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:invited_user) { create(:user, name: 'invited user') }
let(:master) { create(:user).tap { |u| project.team << [u, :master] } }
let(:project_member) do
@@ -519,7 +519,7 @@ describe Notify do
end
describe 'project invitation declined' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:master) { create(:user).tap { |u| project.team << [u, :master] } }
let(:project_member) do
invitee = invite_to_project(project, inviter: master)
@@ -545,7 +545,7 @@ describe Notify do
let(:note_author) { create(:user, name: 'author_name') }
let(:note) { create(:note, project: project, author: note_author) }
- before :each do
+ before do
allow(Note).to receive(:find).with(note.id).and_return(note)
end
@@ -661,7 +661,7 @@ describe Notify do
let(:project) { create(:project, :repository) }
let(:note_author) { create(:user, name: 'author_name') }
- before :each do
+ before do
allow(Note).to receive(:find).with(note.id).and_return(note)
end
@@ -779,7 +779,7 @@ describe Notify do
context 'items that are noteable, the email for a diff discussion note' do
let(:note_author) { create(:user, name: 'author_name') }
- before :each do
+ before do
allow(Note).to receive(:find).with(note.id).and_return(note)
end
@@ -1242,7 +1242,7 @@ describe Notify do
end
describe 'HTML emails setting' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:user) { create(:user) }
let(:multipart_mail) { described_class.project_was_moved_email(project.id, user.id, "gitlab/gitlab") }
diff --git a/spec/migrations/add_head_pipeline_for_each_merge_request_spec.rb b/spec/migrations/add_head_pipeline_for_each_merge_request_spec.rb
index 65bea662b02..862907c5d01 100644
--- a/spec/migrations/add_head_pipeline_for_each_merge_request_spec.rb
+++ b/spec/migrations/add_head_pipeline_for_each_merge_request_spec.rb
@@ -4,7 +4,7 @@ require Rails.root.join('db', 'post_migrate', '20170508170547_add_head_pipeline_
describe AddHeadPipelineForEachMergeRequest, :truncate do
let(:migration) { described_class.new }
- let!(:project) { create(:empty_project) }
+ let!(:project) { create(:project) }
let!(:forked_project_link) { create(:forked_project_link, forked_from_project: project) }
let!(:other_project) { forked_project_link.forked_to_project }
diff --git a/spec/migrations/calculate_conv_dev_index_percentages_spec.rb b/spec/migrations/calculate_conv_dev_index_percentages_spec.rb
new file mode 100644
index 00000000000..597d8eab51c
--- /dev/null
+++ b/spec/migrations/calculate_conv_dev_index_percentages_spec.rb
@@ -0,0 +1,41 @@
+# encoding: utf-8
+
+require 'spec_helper'
+require Rails.root.join('db', 'post_migrate', '20170803090603_calculate_conv_dev_index_percentages.rb')
+
+describe CalculateConvDevIndexPercentages, truncate: true do
+ let(:migration) { described_class.new }
+ let!(:conv_dev_index) do
+ create(:conversational_development_index_metric,
+ leader_notes: 0,
+ instance_milestones: 0,
+ percentage_issues: 0,
+ percentage_notes: 0,
+ percentage_milestones: 0,
+ percentage_boards: 0,
+ percentage_merge_requests: 0,
+ percentage_ci_pipelines: 0,
+ percentage_environments: 0,
+ percentage_deployments: 0,
+ percentage_projects_prometheus_active: 0,
+ percentage_service_desk_issues: 0)
+ end
+
+ describe '#up' do
+ it 'calculates percentages correctly' do
+ migration.up
+ conv_dev_index.reload
+
+ expect(conv_dev_index.percentage_issues).to be_within(0.1).of(13.3)
+ expect(conv_dev_index.percentage_notes).to be_zero # leader 0
+ expect(conv_dev_index.percentage_milestones).to be_zero # instance 0
+ expect(conv_dev_index.percentage_boards).to be_within(0.1).of(62.4)
+ expect(conv_dev_index.percentage_merge_requests).to eq(50.0)
+ expect(conv_dev_index.percentage_ci_pipelines).to be_within(0.1).of(19.3)
+ expect(conv_dev_index.percentage_environments).to be_within(0.1).of(66.7)
+ expect(conv_dev_index.percentage_deployments).to be_within(0.1).of(64.2)
+ expect(conv_dev_index.percentage_projects_prometheus_active).to be_within(0.1).of(98.2)
+ expect(conv_dev_index.percentage_service_desk_issues).to be_within(0.1).of(84.0)
+ end
+ end
+end
diff --git a/spec/migrations/clean_upload_symlinks_spec.rb b/spec/migrations/clean_upload_symlinks_spec.rb
index cecb3ddac53..26653b9c008 100644
--- a/spec/migrations/clean_upload_symlinks_spec.rb
+++ b/spec/migrations/clean_upload_symlinks_spec.rb
@@ -5,7 +5,7 @@ describe CleanUploadSymlinks do
let(:migration) { described_class.new }
let(:test_dir) { File.join(Rails.root, "tmp", "tests", "move_uploads_test") }
let(:uploads_dir) { File.join(test_dir, "public", "uploads") }
- let(:new_uploads_dir) { File.join(uploads_dir, "system") }
+ let(:new_uploads_dir) { File.join(uploads_dir, "-", "system") }
let(:original_path) { File.join(new_uploads_dir, 'user') }
let(:symlink_path) { File.join(uploads_dir, 'user') }
diff --git a/spec/migrations/cleanup_namespaceless_pending_delete_projects_spec.rb b/spec/migrations/cleanup_namespaceless_pending_delete_projects_spec.rb
index 49e750a3f4d..12cac1d033d 100644
--- a/spec/migrations/cleanup_namespaceless_pending_delete_projects_spec.rb
+++ b/spec/migrations/cleanup_namespaceless_pending_delete_projects_spec.rb
@@ -4,15 +4,15 @@ require Rails.root.join('db', 'post_migrate', '20170502101023_cleanup_namespacel
describe CleanupNamespacelessPendingDeleteProjects do
before do
# Stub after_save callbacks that will fail when Project has no namespace
- allow_any_instance_of(Project).to receive(:ensure_dir_exist).and_return(nil)
+ allow_any_instance_of(Project).to receive(:ensure_storage_path_exist).and_return(nil)
allow_any_instance_of(Project).to receive(:update_project_statistics).and_return(nil)
end
describe '#up' do
it 'only cleans up pending delete projects' do
- create(:empty_project)
- create(:empty_project, pending_delete: true)
- project = build(:empty_project, pending_delete: true, namespace_id: nil)
+ create(:project)
+ create(:project, pending_delete: true)
+ project = build(:project, pending_delete: true, namespace_id: nil)
project.save(validate: false)
expect(NamespacelessProjectDestroyWorker).to receive(:bulk_perform_async).with([[project.id]])
@@ -21,8 +21,8 @@ describe CleanupNamespacelessPendingDeleteProjects do
end
it 'does nothing when no pending delete projects without namespace found' do
- create(:empty_project)
- create(:empty_project, pending_delete: true)
+ create(:project)
+ create(:project, pending_delete: true)
expect(NamespacelessProjectDestroyWorker).not_to receive(:bulk_perform_async)
diff --git a/spec/migrations/fix_wrongly_renamed_routes_spec.rb b/spec/migrations/fix_wrongly_renamed_routes_spec.rb
index 148290b0e7d..5ef10b92a3a 100644
--- a/spec/migrations/fix_wrongly_renamed_routes_spec.rb
+++ b/spec/migrations/fix_wrongly_renamed_routes_spec.rb
@@ -37,7 +37,7 @@ describe FixWronglyRenamedRoutes, truncate: true do
describe '#routes_in_namespace_query' do
it 'includes only the required routes' do
namespace = create(:group, path: 'hello')
- project = create(:empty_project, namespace: namespace)
+ project = create(:project, namespace: namespace)
_other_namespace = create(:group, path: 'hello0')
result = Route.where(subject.routes_in_namespace_query('hello'))
@@ -48,7 +48,7 @@ describe FixWronglyRenamedRoutes, truncate: true do
describe '#up' do
let(:broken_project) do
- project = create(:empty_project, namespace: broken_namespace, path: 'broken-project')
+ project = create(:project, namespace: broken_namespace, path: 'broken-project')
project.route.update_attribute(:path, 'api0is/broken-project')
project
end
diff --git a/spec/migrations/migrate_old_artifacts_spec.rb b/spec/migrations/migrate_old_artifacts_spec.rb
index 50f4bbda001..cfe1ca481b2 100644
--- a/spec/migrations/migrate_old_artifacts_spec.rb
+++ b/spec/migrations/migrate_old_artifacts_spec.rb
@@ -16,9 +16,9 @@ describe MigrateOldArtifacts do
end
context 'with migratable data' do
- let(:project1) { create(:empty_project, ci_id: 2) }
- let(:project2) { create(:empty_project, ci_id: 3) }
- let(:project3) { create(:empty_project) }
+ let(:project1) { create(:project, ci_id: 2) }
+ let(:project2) { create(:project, ci_id: 3) }
+ let(:project3) { create(:project) }
let(:pipeline1) { create(:ci_empty_pipeline, project: project1) }
let(:pipeline2) { create(:ci_empty_pipeline, project: project2) }
diff --git a/spec/migrations/migrate_process_commit_worker_jobs_spec.rb b/spec/migrations/migrate_process_commit_worker_jobs_spec.rb
index 5b633dd349b..e5793a3c0ee 100644
--- a/spec/migrations/migrate_process_commit_worker_jobs_spec.rb
+++ b/spec/migrations/migrate_process_commit_worker_jobs_spec.rb
@@ -6,7 +6,7 @@ require Rails.root.join('db', 'migrate', '20161124141322_migrate_process_commit_
describe MigrateProcessCommitWorkerJobs do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
- let(:commit) { project.commit.raw.raw_commit }
+ let(:commit) { project.commit.raw.rugged_commit }
describe 'Project' do
describe 'find_including_path' do
@@ -20,7 +20,7 @@ describe MigrateProcessCommitWorkerJobs do
.find_including_path(project.id)
expect(migration_project[:path_with_namespace])
- .to eq(project.path_with_namespace)
+ .to eq(project.full_path)
end
end
diff --git a/spec/migrations/move_personal_snippets_files_spec.rb b/spec/migrations/move_personal_snippets_files_spec.rb
index 8505c7bf3e3..1a319eccc0d 100644
--- a/spec/migrations/move_personal_snippets_files_spec.rb
+++ b/spec/migrations/move_personal_snippets_files_spec.rb
@@ -5,7 +5,7 @@ describe MovePersonalSnippetsFiles do
let(:migration) { described_class.new }
let(:test_dir) { File.join(Rails.root, "tmp", "tests", "move_snippet_files_test") }
let(:uploads_dir) { File.join(test_dir, 'uploads') }
- let(:new_uploads_dir) { File.join(uploads_dir, 'system') }
+ let(:new_uploads_dir) { File.join(uploads_dir, '-', 'system') }
before do
allow(CarrierWave).to receive(:root).and_return(test_dir)
@@ -42,7 +42,7 @@ describe MovePersonalSnippetsFiles do
describe 'updating the markdown' do
it 'includes the new path when the file exists' do
secret = "secret#{snippet.id}"
- file_location = "/uploads/system/personal_snippet/#{snippet.id}/#{secret}/picture.jpg"
+ file_location = "/uploads/-/system/personal_snippet/#{snippet.id}/#{secret}/picture.jpg"
migration.up
@@ -60,7 +60,7 @@ describe MovePersonalSnippetsFiles do
it 'updates the note markdown' do
secret = "secret#{snippet.id}"
- file_location = "/uploads/system/personal_snippet/#{snippet.id}/#{secret}/picture.jpg"
+ file_location = "/uploads/-/system/personal_snippet/#{snippet.id}/#{secret}/picture.jpg"
markdown = markdown_linking_file('picture.jpg', snippet)
note = create(:note_on_personal_snippet, noteable: snippet, note: "with #{markdown}")
@@ -108,7 +108,7 @@ describe MovePersonalSnippetsFiles do
it 'keeps the markdown as is when the file is missing' do
secret = "secret#{snippet_with_missing_file.id}"
- file_location = "/uploads/system/personal_snippet/#{snippet_with_missing_file.id}/#{secret}/picture.jpg"
+ file_location = "/uploads/-/system/personal_snippet/#{snippet_with_missing_file.id}/#{secret}/picture.jpg"
migration.down
@@ -167,7 +167,7 @@ describe MovePersonalSnippetsFiles do
def markdown_linking_file(filename, snippet, in_new_path: false)
markdown = "![#{filename.split('.')[0]}]"
markdown += '(/uploads'
- markdown += '/system' if in_new_path
+ markdown += '/-/system' if in_new_path
markdown += "/#{model_file_path(filename, snippet)})"
markdown
end
diff --git a/spec/migrations/move_system_upload_folder_spec.rb b/spec/migrations/move_system_upload_folder_spec.rb
index b622b4e9536..d3180477db3 100644
--- a/spec/migrations/move_system_upload_folder_spec.rb
+++ b/spec/migrations/move_system_upload_folder_spec.rb
@@ -33,6 +33,15 @@ describe MoveSystemUploadFolder do
expect(File.symlink?(File.join(test_base, 'system'))).to be_truthy
expect(File.exist?(File.join(test_base, 'system', 'file'))).to be_truthy
end
+
+ it 'does not move if the target directory already exists' do
+ FileUtils.mkdir_p(File.join(test_base, '-', 'system'))
+
+ expect(FileUtils).not_to receive(:mv)
+ expect(migration).to receive(:say).with(/already exists. No need to redo the move/)
+
+ migration.up
+ end
end
describe '#down' do
@@ -58,5 +67,14 @@ describe MoveSystemUploadFolder do
expect(File.directory?(File.join(test_base, 'system'))).to be_truthy
expect(File.symlink?(File.join(test_base, 'system'))).to be_falsey
end
+
+ it 'does not move if the old directory already exists' do
+ FileUtils.mkdir_p(File.join(test_base, 'system'))
+
+ expect(FileUtils).not_to receive(:mv)
+ expect(migration).to receive(:say).with(/already exists and is not a symlink, no need to revert/)
+
+ migration.down
+ end
end
end
diff --git a/spec/migrations/move_uploads_to_system_dir_spec.rb b/spec/migrations/move_uploads_to_system_dir_spec.rb
index 37d66452447..ca11a2004c5 100644
--- a/spec/migrations/move_uploads_to_system_dir_spec.rb
+++ b/spec/migrations/move_uploads_to_system_dir_spec.rb
@@ -5,7 +5,7 @@ describe MoveUploadsToSystemDir do
let(:migration) { described_class.new }
let(:test_dir) { File.join(Rails.root, "tmp", "move_uploads_test") }
let(:uploads_dir) { File.join(test_dir, "public", "uploads") }
- let(:new_uploads_dir) { File.join(uploads_dir, "system") }
+ let(:new_uploads_dir) { File.join(uploads_dir, "-", "system") }
before do
FileUtils.remove_dir(test_dir) if File.directory?(test_dir)
diff --git a/spec/migrations/rename_more_reserved_project_names_spec.rb b/spec/migrations/rename_more_reserved_project_names_spec.rb
index 4bd8d4ac0d1..ae3a4cb9b29 100644
--- a/spec/migrations/rename_more_reserved_project_names_spec.rb
+++ b/spec/migrations/rename_more_reserved_project_names_spec.rb
@@ -8,7 +8,7 @@ require Rails.root.join('db', 'post_migrate', '20170313133418_rename_more_reserv
# around this we use the TRUNCATE cleaning strategy.
describe RenameMoreReservedProjectNames, truncate: true do
let(:migration) { described_class.new }
- let!(:project) { create(:empty_project) }
+ let!(:project) { create(:project) }
before do
project.path = 'artifacts'
diff --git a/spec/migrations/rename_reserved_project_names_spec.rb b/spec/migrations/rename_reserved_project_names_spec.rb
index 05e021c2e32..462f4c08d63 100644
--- a/spec/migrations/rename_reserved_project_names_spec.rb
+++ b/spec/migrations/rename_reserved_project_names_spec.rb
@@ -8,7 +8,7 @@ require Rails.root.join('db', 'post_migrate', '20161221153951_rename_reserved_pr
# around this we use the TRUNCATE cleaning strategy.
describe RenameReservedProjectNames, truncate: true do
let(:migration) { described_class.new }
- let!(:project) { create(:empty_project) }
+ let!(:project) { create(:project) }
before do
project.path = 'projects'
diff --git a/spec/migrations/rename_system_namespaces_spec.rb b/spec/migrations/rename_system_namespaces_spec.rb
deleted file mode 100644
index 626a6005838..00000000000
--- a/spec/migrations/rename_system_namespaces_spec.rb
+++ /dev/null
@@ -1,254 +0,0 @@
-require "spec_helper"
-require Rails.root.join("db", "migrate", "20170316163800_rename_system_namespaces.rb")
-
-describe RenameSystemNamespaces, truncate: true do
- let(:migration) { described_class.new }
- let(:test_dir) { File.join(Rails.root, "tmp", "tests", "rename_namespaces_test") }
- let(:uploads_dir) { File.join(test_dir, "public", "uploads") }
- let(:system_namespace) do
- namespace = build(:namespace, path: "system")
- namespace.save(validate: false)
- namespace
- end
-
- def save_invalid_routable(routable)
- routable.__send__(:prepare_route)
- routable.save(validate: false)
- end
-
- before do
- FileUtils.remove_dir(test_dir) if File.directory?(test_dir)
- FileUtils.mkdir_p(uploads_dir)
- FileUtils.remove_dir(TestEnv.repos_path) if File.directory?(TestEnv.repos_path)
- allow(migration).to receive(:say)
- allow(migration).to receive(:uploads_dir).and_return(uploads_dir)
- end
-
- describe "#system_namespace" do
- it "only root namespaces called with path `system`" do
- system_namespace
- system_namespace_with_parent = build(:namespace, path: 'system', parent: create(:namespace))
- system_namespace_with_parent.save(validate: false)
-
- expect(migration.system_namespace.id).to eq(system_namespace.id)
- end
- end
-
- describe "#up" do
- before do
- system_namespace
- end
-
- it "doesn't break if there are no namespaces called system" do
- Namespace.delete_all
-
- migration.up
- end
-
- it "renames namespaces called system" do
- migration.up
-
- expect(system_namespace.reload.path).to eq("system0")
- end
-
- it "renames the route to the namespace" do
- migration.up
-
- expect(system_namespace.reload.full_path).to eq("system0")
- end
-
- it "renames the route for projects of the namespace" do
- project = build(:project, path: "project-path", namespace: system_namespace)
- save_invalid_routable(project)
-
- migration.up
-
- expect(project.route.reload.path).to eq("system0/project-path")
- end
-
- it "doesn't touch routes of namespaces that look like system" do
- namespace = create(:group, path: 'systemlookalike')
- project = create(:project, namespace: namespace, path: 'the-project')
-
- migration.up
-
- expect(project.route.reload.path).to eq('systemlookalike/the-project')
- expect(namespace.route.reload.path).to eq('systemlookalike')
- end
-
- it "moves the the repository for a project in the namespace" do
- project = build(:project, namespace: system_namespace, path: "system-project")
- save_invalid_routable(project)
- TestEnv.copy_repo(project,
- bare_repo: TestEnv.factory_repo_path_bare,
- refs: TestEnv::BRANCH_SHA)
- expected_repo = File.join(TestEnv.repos_path, "system0", "system-project.git")
-
- migration.up
-
- expect(File.directory?(expected_repo)).to be(true)
- end
-
- it "moves the uploads for the namespace" do
- allow(migration).to receive(:move_namespace_folders).with(Settings.pages.path, "system", "system0")
- expect(migration).to receive(:move_namespace_folders).with(uploads_dir, "system", "system0")
-
- migration.up
- end
-
- it "moves the pages for the namespace" do
- allow(migration).to receive(:move_namespace_folders).with(uploads_dir, "system", "system0")
- expect(migration).to receive(:move_namespace_folders).with(Settings.pages.path, "system", "system0")
-
- migration.up
- end
-
- describe "clears the markdown cache for projects in the system namespace" do
- let!(:project) do
- project = build(:project, namespace: system_namespace)
- save_invalid_routable(project)
- project
- end
-
- it 'removes description_html from projects' do
- migration.up
-
- expect(project.reload.description_html).to be_nil
- end
-
- it 'removes issue descriptions' do
- issue = create(:issue, project: project, description_html: 'Issue description')
-
- migration.up
-
- expect(issue.reload.description_html).to be_nil
- end
-
- it 'removes merge request descriptions' do
- merge_request = create(:merge_request,
- source_project: project,
- target_project: project,
- description_html: 'MergeRequest description')
-
- migration.up
-
- expect(merge_request.reload.description_html).to be_nil
- end
-
- it 'removes note html' do
- note = create(:note,
- project: project,
- noteable: create(:issue, project: project),
- note_html: 'note description')
-
- migration.up
-
- expect(note.reload.note_html).to be_nil
- end
-
- it 'removes milestone description' do
- milestone = create(:milestone,
- project: project,
- description_html: 'milestone description')
-
- migration.up
-
- expect(milestone.reload.description_html).to be_nil
- end
- end
-
- context "system namespace -> subgroup -> system0 project" do
- it "updates the route of the project correctly" do
- subgroup = build(:group, path: "subgroup", parent: system_namespace)
- save_invalid_routable(subgroup)
- project = build(:project, path: "system0", namespace: subgroup)
- save_invalid_routable(project)
-
- migration.up
-
- expect(project.route.reload.path).to eq("system0/subgroup/system0")
- end
- end
- end
-
- describe "#move_repositories" do
- let(:namespace) { create(:group, name: "hello-group") }
- it "moves a project for a namespace" do
- create(:project, namespace: namespace, path: "hello-project")
- expected_path = File.join(TestEnv.repos_path, "bye-group", "hello-project.git")
-
- migration.move_repositories(namespace, "hello-group", "bye-group")
-
- expect(File.directory?(expected_path)).to be(true)
- end
-
- it "moves a namespace in a subdirectory correctly" do
- child_namespace = create(:group, name: "sub-group", parent: namespace)
- create(:project, namespace: child_namespace, path: "hello-project")
-
- expected_path = File.join(TestEnv.repos_path, "hello-group", "renamed-sub-group", "hello-project.git")
-
- migration.move_repositories(child_namespace, "hello-group/sub-group", "hello-group/renamed-sub-group")
-
- expect(File.directory?(expected_path)).to be(true)
- end
-
- it "moves a parent namespace with subdirectories" do
- child_namespace = create(:group, name: "sub-group", parent: namespace)
- create(:project, namespace: child_namespace, path: "hello-project")
- expected_path = File.join(TestEnv.repos_path, "renamed-group", "sub-group", "hello-project.git")
-
- migration.move_repositories(child_namespace, "hello-group", "renamed-group")
-
- expect(File.directory?(expected_path)).to be(true)
- end
- end
-
- describe "#move_namespace_folders" do
- it "moves a namespace with files" do
- source = File.join(uploads_dir, "parent-group", "sub-group")
- FileUtils.mkdir_p(source)
- destination = File.join(uploads_dir, "parent-group", "moved-group")
- FileUtils.touch(File.join(source, "test.txt"))
- expected_file = File.join(destination, "test.txt")
-
- migration.move_namespace_folders(uploads_dir, File.join("parent-group", "sub-group"), File.join("parent-group", "moved-group"))
-
- expect(File.exist?(expected_file)).to be(true)
- end
-
- it "moves a parent namespace uploads" do
- source = File.join(uploads_dir, "parent-group", "sub-group")
- FileUtils.mkdir_p(source)
- destination = File.join(uploads_dir, "moved-parent", "sub-group")
- FileUtils.touch(File.join(source, "test.txt"))
- expected_file = File.join(destination, "test.txt")
-
- migration.move_namespace_folders(uploads_dir, "parent-group", "moved-parent")
-
- expect(File.exist?(expected_file)).to be(true)
- end
- end
-
- describe "#child_ids_for_parent" do
- it "collects child ids for all levels" do
- parent = create(:group)
- first_child = create(:group, parent: parent)
- second_child = create(:group, parent: parent)
- third_child = create(:group, parent: second_child)
- all_ids = [parent.id, first_child.id, second_child.id, third_child.id]
-
- collected_ids = migration.child_ids_for_parent(parent, ids: [parent.id])
-
- expect(collected_ids).to contain_exactly(*all_ids)
- end
- end
-
- describe "#remove_last_ocurrence" do
- it "removes only the last occurance of a string" do
- input = "this/is/system/namespace/with/system"
-
- expect(migration.remove_last_occurrence(input, "system")).to eq("this/is/system/namespace/with/")
- end
- end
-end
diff --git a/spec/migrations/schedule_merge_request_diff_migrations_spec.rb b/spec/migrations/schedule_merge_request_diff_migrations_spec.rb
new file mode 100644
index 00000000000..f95bd6e3511
--- /dev/null
+++ b/spec/migrations/schedule_merge_request_diff_migrations_spec.rb
@@ -0,0 +1,59 @@
+require 'spec_helper'
+require Rails.root.join('db', 'post_migrate', '20170703130158_schedule_merge_request_diff_migrations')
+
+describe ScheduleMergeRequestDiffMigrations, :migration, :sidekiq do
+ matcher :be_scheduled_migration do |time, *expected|
+ match do |migration|
+ BackgroundMigrationWorker.jobs.any? do |job|
+ job['args'] == [migration, expected] &&
+ job['at'].to_i == time.to_i
+ end
+ end
+
+ failure_message do |migration|
+ "Migration `#{migration}` with args `#{expected.inspect}` not scheduled!"
+ end
+ end
+
+ let(:merge_request_diffs) { table(:merge_request_diffs) }
+ let(:merge_requests) { table(:merge_requests) }
+ let(:projects) { table(:projects) }
+
+ before do
+ stub_const("#{described_class.name}::BATCH_SIZE", 1)
+
+ projects.create!(id: 1, name: 'gitlab', path: 'gitlab')
+
+ merge_requests.create!(id: 1, target_project_id: 1, source_project_id: 1, target_branch: 'feature', source_branch: 'master')
+
+ merge_request_diffs.create!(id: 1, merge_request_id: 1, st_commits: YAML.dump([]), st_diffs: nil)
+ merge_request_diffs.create!(id: 2, merge_request_id: 1, st_commits: nil, st_diffs: YAML.dump([]))
+ merge_request_diffs.create!(id: 3, merge_request_id: 1, st_commits: nil, st_diffs: nil)
+ merge_request_diffs.create!(id: 4, merge_request_id: 1, st_commits: YAML.dump([]), st_diffs: YAML.dump([]))
+ end
+
+ it 'correctly schedules background migrations' do
+ Sidekiq::Testing.fake! do
+ Timecop.freeze do
+ migrate!
+
+ expect(described_class::MIGRATION).to be_scheduled_migration(5.minutes.from_now, 1, 1)
+ expect(described_class::MIGRATION).to be_scheduled_migration(10.minutes.from_now, 2, 2)
+ expect(described_class::MIGRATION).to be_scheduled_migration(15.minutes.from_now, 4, 4)
+ expect(BackgroundMigrationWorker.jobs.size).to eq 3
+ end
+ end
+ end
+
+ it 'schedules background migrations' do
+ Sidekiq::Testing.inline! do
+ non_empty = 'st_commits IS NOT NULL OR st_diffs IS NOT NULL'
+
+ expect(merge_request_diffs.where(non_empty).count).to eq 3
+
+ migrate!
+
+ expect(merge_request_diffs.where(non_empty).count).to eq 0
+ end
+ end
+end
diff --git a/spec/migrations/turn_nested_groups_into_regular_groups_for_mysql_spec.rb b/spec/migrations/turn_nested_groups_into_regular_groups_for_mysql_spec.rb
index 42109fd0743..6f7a730edff 100644
--- a/spec/migrations/turn_nested_groups_into_regular_groups_for_mysql_spec.rb
+++ b/spec/migrations/turn_nested_groups_into_regular_groups_for_mysql_spec.rb
@@ -44,7 +44,7 @@ describe TurnNestedGroupsIntoRegularGroupsForMysql do
end
it 'renames projects of the nested group' do
- expect(updated_project.path_with_namespace)
+ expect(updated_project.full_path)
.to eq("#{parent_group.name}-#{child_group.name}/#{updated_project.path}")
end
diff --git a/spec/migrations/update_upload_paths_to_system_spec.rb b/spec/migrations/update_upload_paths_to_system_spec.rb
index 7df44515424..0a45c5ea32d 100644
--- a/spec/migrations/update_upload_paths_to_system_spec.rb
+++ b/spec/migrations/update_upload_paths_to_system_spec.rb
@@ -11,9 +11,9 @@ describe UpdateUploadPathsToSystem do
describe "#uploads_to_switch_to_new_path" do
it "contains only uploads with the old path for the correct models" do
_upload_for_other_type = create(:upload, model: create(:ci_pipeline), path: "uploads/ci_pipeline/avatar.jpg")
- _upload_with_system_path = create(:upload, model: create(:empty_project), path: "uploads/system/project/avatar.jpg")
- _upload_with_other_path = create(:upload, model: create(:empty_project), path: "thelongsecretforafileupload/avatar.jpg")
- old_upload = create(:upload, model: create(:empty_project), path: "uploads/project/avatar.jpg")
+ _upload_with_system_path = create(:upload, model: create(:project), path: "uploads/-/system/project/avatar.jpg")
+ _upload_with_other_path = create(:upload, model: create(:project), path: "thelongsecretforafileupload/avatar.jpg")
+ old_upload = create(:upload, model: create(:project), path: "uploads/project/avatar.jpg")
group_upload = create(:upload, model: create(:group), path: "uploads/group/avatar.jpg")
expect(Upload.where(migration.uploads_to_switch_to_new_path)).to contain_exactly(old_upload, group_upload)
@@ -23,9 +23,9 @@ describe UpdateUploadPathsToSystem do
describe "#uploads_to_switch_to_old_path" do
it "contains only uploads with the new path for the correct models" do
_upload_for_other_type = create(:upload, model: create(:ci_pipeline), path: "uploads/ci_pipeline/avatar.jpg")
- upload_with_system_path = create(:upload, model: create(:empty_project), path: "uploads/system/project/avatar.jpg")
- _upload_with_other_path = create(:upload, model: create(:empty_project), path: "thelongsecretforafileupload/avatar.jpg")
- _old_upload = create(:upload, model: create(:empty_project), path: "uploads/project/avatar.jpg")
+ upload_with_system_path = create(:upload, model: create(:project), path: "uploads/-/system/project/avatar.jpg")
+ _upload_with_other_path = create(:upload, model: create(:project), path: "thelongsecretforafileupload/avatar.jpg")
+ _old_upload = create(:upload, model: create(:project), path: "uploads/project/avatar.jpg")
expect(Upload.where(migration.uploads_to_switch_to_old_path)).to contain_exactly(upload_with_system_path)
end
@@ -33,17 +33,17 @@ describe UpdateUploadPathsToSystem do
describe "#up", truncate: true do
it "updates old upload records to the new path" do
- old_upload = create(:upload, model: create(:empty_project), path: "uploads/project/avatar.jpg")
+ old_upload = create(:upload, model: create(:project), path: "uploads/project/avatar.jpg")
migration.up
- expect(old_upload.reload.path).to eq("uploads/system/project/avatar.jpg")
+ expect(old_upload.reload.path).to eq("uploads/-/system/project/avatar.jpg")
end
end
describe "#down", truncate: true do
it "updates the new system patsh to the old paths" do
- new_upload = create(:upload, model: create(:empty_project), path: "uploads/system/project/avatar.jpg")
+ new_upload = create(:upload, model: create(:project), path: "uploads/-/system/project/avatar.jpg")
migration.down
diff --git a/spec/models/ability_spec.rb b/spec/models/ability_spec.rb
index aa019288700..71aa51e1857 100644
--- a/spec/models/ability_spec.rb
+++ b/spec/models/ability_spec.rb
@@ -8,7 +8,7 @@ describe Ability do
end
describe '.can_edit_note?' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:note) { create(:note_on_issue, project: project) }
context 'using an anonymous user' do
@@ -66,7 +66,7 @@ describe Ability do
describe '.users_that_can_read_project' do
context 'using a public project' do
it 'returns all the users' do
- project = create(:empty_project, :public)
+ project = create(:project, :public)
user = build(:user)
expect(described_class.users_that_can_read_project([user], project))
@@ -75,7 +75,7 @@ describe Ability do
end
context 'using an internal project' do
- let(:project) { create(:empty_project, :internal) }
+ let(:project) { create(:project, :internal) }
it 'returns users that are administrators' do
user = build(:user, admin: true)
@@ -126,7 +126,7 @@ describe Ability do
end
context 'using a private project' do
- let(:project) { create(:empty_project, :private) }
+ let(:project) { create(:project, :private) }
it 'returns users that are administrators' do
user = build(:user, admin: true)
@@ -253,7 +253,7 @@ describe Ability do
end
describe '.project_disabled_features_rules' do
- let(:project) { create(:empty_project, :wiki_disabled) }
+ let(:project) { create(:project, :wiki_disabled) }
subject { described_class.policy_for(project.owner, project) }
diff --git a/spec/models/appearance_spec.rb b/spec/models/appearance_spec.rb
index 7cd3a84d592..b5d5d58697b 100644
--- a/spec/models/appearance_spec.rb
+++ b/spec/models/appearance_spec.rb
@@ -9,4 +9,39 @@ RSpec.describe Appearance do
it { is_expected.to validate_presence_of(:description) }
it { is_expected.to have_many(:uploads).dependent(:destroy) }
+
+ describe '.current', :use_clean_rails_memory_store_caching do
+ let!(:appearance) { create(:appearance) }
+
+ it 'returns the current appearance row' do
+ expect(described_class.current).to eq(appearance)
+ end
+
+ it 'caches the result' do
+ expect(described_class).to receive(:first).once
+
+ 2.times { described_class.current }
+ end
+ end
+
+ describe '#flush_redis_cache' do
+ it 'flushes the cache in Redis' do
+ appearance = create(:appearance)
+
+ expect(Rails.cache).to receive(:delete).with(described_class::CACHE_KEY)
+
+ appearance.flush_redis_cache
+ end
+ end
+
+ describe '#single_appearance_row' do
+ it 'adds an error when more than 1 row exists' do
+ create(:appearance)
+
+ new_row = build(:appearance)
+ new_row.save
+
+ expect(new_row.valid?).to eq(false)
+ end
+ end
end
diff --git a/spec/models/blob_spec.rb b/spec/models/blob_spec.rb
index e1193e0d19a..47342f98283 100644
--- a/spec/models/blob_spec.rb
+++ b/spec/models/blob_spec.rb
@@ -4,7 +4,7 @@ require 'rails_helper'
describe Blob do
include FakeBlobHelpers
- let(:project) { build(:empty_project, lfs_enabled: true) }
+ let(:project) { build(:project, lfs_enabled: true) }
before do
allow(Gitlab.config.lfs).to receive(:enabled).and_return(true)
diff --git a/spec/models/blob_viewer/base_spec.rb b/spec/models/blob_viewer/base_spec.rb
index e3640097dff..7ba28f72215 100644
--- a/spec/models/blob_viewer/base_spec.rb
+++ b/spec/models/blob_viewer/base_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe BlobViewer::Base do
include FakeBlobHelpers
- let(:project) { build(:empty_project) }
+ let(:project) { build(:project) }
let(:viewer_class) do
Class.new(described_class) do
diff --git a/spec/models/blob_viewer/composer_json_spec.rb b/spec/models/blob_viewer/composer_json_spec.rb
index 82f6f7e5046..85b0d9668a0 100644
--- a/spec/models/blob_viewer/composer_json_spec.rb
+++ b/spec/models/blob_viewer/composer_json_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe BlobViewer::ComposerJson do
include FakeBlobHelpers
- let(:project) { build(:project) }
+ let(:project) { build_stubbed(:project) }
let(:data) do
<<-SPEC.strip_heredoc
{
diff --git a/spec/models/blob_viewer/gemspec_spec.rb b/spec/models/blob_viewer/gemspec_spec.rb
index 14cc5f3c0fd..d8c4490637f 100644
--- a/spec/models/blob_viewer/gemspec_spec.rb
+++ b/spec/models/blob_viewer/gemspec_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe BlobViewer::Gemspec do
include FakeBlobHelpers
- let(:project) { build(:project) }
+ let(:project) { build_stubbed(:project) }
let(:data) do
<<-SPEC.strip_heredoc
Gem::Specification.new do |s|
diff --git a/spec/models/blob_viewer/gitlab_ci_yml_spec.rb b/spec/models/blob_viewer/gitlab_ci_yml_spec.rb
index 7a4f9866375..bed364a8c14 100644
--- a/spec/models/blob_viewer/gitlab_ci_yml_spec.rb
+++ b/spec/models/blob_viewer/gitlab_ci_yml_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe BlobViewer::GitlabCiYml do
include FakeBlobHelpers
- let(:project) { build(:project) }
+ let(:project) { build_stubbed(:project) }
let(:data) { File.read(Rails.root.join('spec/support/gitlab_stubs/gitlab_ci.yml')) }
let(:blob) { fake_blob(path: '.gitlab-ci.yml', data: data) }
subject { described_class.new(blob) }
diff --git a/spec/models/blob_viewer/package_json_spec.rb b/spec/models/blob_viewer/package_json_spec.rb
index 96fb1b08c99..0f8330e91c1 100644
--- a/spec/models/blob_viewer/package_json_spec.rb
+++ b/spec/models/blob_viewer/package_json_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe BlobViewer::PackageJson do
include FakeBlobHelpers
- let(:project) { build(:project) }
+ let(:project) { build_stubbed(:project) }
let(:data) do
<<-SPEC.strip_heredoc
{
diff --git a/spec/models/blob_viewer/podspec_json_spec.rb b/spec/models/blob_viewer/podspec_json_spec.rb
index f510077a87b..9a23877b23f 100644
--- a/spec/models/blob_viewer/podspec_json_spec.rb
+++ b/spec/models/blob_viewer/podspec_json_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe BlobViewer::PodspecJson do
include FakeBlobHelpers
- let(:project) { build(:project) }
+ let(:project) { build_stubbed(:project) }
let(:data) do
<<-SPEC.strip_heredoc
{
diff --git a/spec/models/blob_viewer/podspec_spec.rb b/spec/models/blob_viewer/podspec_spec.rb
index 7c38083550c..02d06ea24d6 100644
--- a/spec/models/blob_viewer/podspec_spec.rb
+++ b/spec/models/blob_viewer/podspec_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe BlobViewer::Podspec do
include FakeBlobHelpers
- let(:project) { build(:project) }
+ let(:project) { build_stubbed(:project) }
let(:data) do
<<-SPEC.strip_heredoc
Pod::Spec.new do |spec|
diff --git a/spec/models/blob_viewer/route_map_spec.rb b/spec/models/blob_viewer/route_map_spec.rb
index 115731b4970..c13662427b0 100644
--- a/spec/models/blob_viewer/route_map_spec.rb
+++ b/spec/models/blob_viewer/route_map_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe BlobViewer::RouteMap do
include FakeBlobHelpers
- let(:project) { build(:project) }
+ let(:project) { build_stubbed(:project) }
let(:data) do
<<-MAP.strip_heredoc
# Team data
diff --git a/spec/models/blob_viewer/server_side_spec.rb b/spec/models/blob_viewer/server_side_spec.rb
index 2639eec9e84..63790486200 100644
--- a/spec/models/blob_viewer/server_side_spec.rb
+++ b/spec/models/blob_viewer/server_side_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe BlobViewer::ServerSide do
include FakeBlobHelpers
- let(:project) { build(:empty_project) }
+ let(:project) { build(:project) }
let(:viewer_class) do
Class.new(BlobViewer::Base) do
@@ -25,7 +25,7 @@ describe BlobViewer::ServerSide do
describe '#render_error' do
context 'when the blob is stored externally' do
- let(:project) { build(:empty_project, lfs_enabled: true) }
+ let(:project) { build(:project, lfs_enabled: true) }
let(:blob) { fake_blob(path: 'file.pdf', lfs: true) }
diff --git a/spec/models/broadcast_message_spec.rb b/spec/models/broadcast_message_spec.rb
index a8ca1d110e4..3369aef1d3e 100644
--- a/spec/models/broadcast_message_spec.rb
+++ b/spec/models/broadcast_message_spec.rb
@@ -20,7 +20,7 @@ describe BroadcastMessage do
it { is_expected.not_to allow_value('000').for(:font) }
end
- describe '.current' do
+ describe '.current', :use_clean_rails_memory_store_caching do
it 'returns message if time match' do
message = create(:broadcast_message)
@@ -45,6 +45,14 @@ describe BroadcastMessage do
expect(described_class.current).to be_empty
end
+
+ it 'caches the output of the query' do
+ create(:broadcast_message)
+
+ expect(described_class).to receive(:where).and_call_original.once
+
+ 2.times { described_class.current }
+ end
end
describe '#active?' do
@@ -102,4 +110,14 @@ describe BroadcastMessage do
end
end
end
+
+ describe '#flush_redis_cache' do
+ it 'flushes the Redis cache' do
+ message = create(:broadcast_message)
+
+ expect(Rails.cache).to receive(:delete).with(described_class::CACHE_KEY)
+
+ message.flush_redis_cache
+ end
+ end
end
diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb
index b0efa689a07..ac75c6501ee 100644
--- a/spec/models/ci/pipeline_spec.rb
+++ b/spec/models/ci/pipeline_spec.rb
@@ -1,10 +1,8 @@
require 'spec_helper'
-describe Ci::Pipeline do
- include EmailHelpers
-
+describe Ci::Pipeline, :mailer do
let(:user) { create(:user) }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:pipeline) do
create(:ci_empty_pipeline, status: :created, project: project)
@@ -93,7 +91,7 @@ describe Ci::Pipeline do
end
describe "coverage" do
- let(:project) { create(:empty_project, build_coverage_regex: "/.*/") }
+ let(:project) { create(:project, build_coverage_regex: "/.*/") }
let(:pipeline) { create(:ci_empty_pipeline, project: project) }
it "calculates average when there are two builds with coverage" do
@@ -1147,7 +1145,7 @@ describe Ci::Pipeline do
end
describe "#merge_requests" do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:pipeline) { create(:ci_empty_pipeline, status: 'created', project: project, ref: 'master', sha: 'a288a022a53a5a944fae87bcec6efc87b7061808') }
it "returns merge requests whose `diff_head_sha` matches the pipeline's SHA" do
@@ -1172,7 +1170,7 @@ describe Ci::Pipeline do
end
describe "#all_merge_requests" do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:pipeline) { create(:ci_empty_pipeline, status: 'created', project: project, ref: 'master') }
it "returns all merge requests having the same source branch" do
@@ -1248,8 +1246,6 @@ describe Ci::Pipeline do
pipeline.user.global_notification_setting
.update(level: 'custom', failed_pipeline: true, success_pipeline: true)
- reset_delivered_emails!
-
perform_enqueued_jobs do
pipeline.enqueue
pipeline.run
diff --git a/spec/models/ci/runner_spec.rb b/spec/models/ci/runner_spec.rb
index 8d12a9c09ca..48f878bbee6 100644
--- a/spec/models/ci/runner_spec.rb
+++ b/spec/models/ci/runner_spec.rb
@@ -37,7 +37,7 @@ describe Ci::Runner do
end
describe '#assign_to' do
- let!(:project) { FactoryGirl.create :empty_project }
+ let!(:project) { FactoryGirl.create :project }
let!(:shared_runner) { FactoryGirl.create(:ci_runner, :shared) }
before do
@@ -339,8 +339,8 @@ describe Ci::Runner do
describe '.assignable_for' do
let(:runner) { create(:ci_runner) }
- let(:project) { create(:empty_project) }
- let(:another_project) { create(:empty_project) }
+ let(:project) { create(:project) }
+ let(:another_project) { create(:project) }
before do
project.runners << runner
@@ -400,8 +400,8 @@ describe Ci::Runner do
describe "belongs_to_one_project?" do
it "returns false if there are two projects runner assigned to" do
runner = FactoryGirl.create(:ci_runner)
- project = FactoryGirl.create(:empty_project)
- project1 = FactoryGirl.create(:empty_project)
+ project = FactoryGirl.create(:project)
+ project1 = FactoryGirl.create(:project)
project.runners << runner
project1.runners << runner
@@ -410,7 +410,7 @@ describe Ci::Runner do
it "returns true" do
runner = FactoryGirl.create(:ci_runner)
- project = FactoryGirl.create(:empty_project)
+ project = FactoryGirl.create(:project)
project.runners << runner
expect(runner.belongs_to_one_project?).to be_truthy
diff --git a/spec/models/ci/trigger_spec.rb b/spec/models/ci/trigger_spec.rb
index de51f4879fd..bd9c837402f 100644
--- a/spec/models/ci/trigger_spec.rb
+++ b/spec/models/ci/trigger_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Ci::Trigger do
- let(:project) { create :empty_project }
+ let(:project) { create :project }
describe 'associations' do
it { is_expected.to belong_to(:project) }
diff --git a/spec/models/commit_range_spec.rb b/spec/models/commit_range_spec.rb
index 07e10b44938..38829773599 100644
--- a/spec/models/commit_range_spec.rb
+++ b/spec/models/commit_range_spec.rb
@@ -45,7 +45,7 @@ describe CommitRange do
end
describe '#to_reference' do
- let(:cross) { create(:empty_project, namespace: project.namespace) }
+ let(:cross) { create(:project, namespace: project.namespace) }
it 'returns a String reference to the object' do
expect(range.to_reference).to eq "#{full_sha_from}...#{full_sha_to}"
@@ -61,7 +61,7 @@ describe CommitRange do
end
describe '#reference_link_text' do
- let(:cross) { create(:empty_project, namespace: project.namespace) }
+ let(:cross) { create(:project, namespace: project.namespace) }
it 'returns a String reference to the object' do
expect(range.reference_link_text).to eq "#{sha_from}...#{sha_to}"
diff --git a/spec/models/commit_spec.rb b/spec/models/commit_spec.rb
index 2285c338599..c18c635d811 100644
--- a/spec/models/commit_spec.rb
+++ b/spec/models/commit_spec.rb
@@ -33,7 +33,6 @@ describe Commit do
describe '#to_reference' do
let(:project) { create(:project, :repository, path: 'sample-project') }
- let(:commit) { project.commit }
it 'returns a String reference to the object' do
expect(commit.to_reference).to eq commit.id
@@ -47,7 +46,6 @@ describe Commit do
describe '#reference_link_text' do
let(:project) { create(:project, :repository, path: 'sample-project') }
- let(:commit) { project.commit }
it 'returns a String reference to the object' do
expect(commit.reference_link_text).to eq commit.short_id
@@ -151,7 +149,7 @@ eos
describe '#closes_issues' do
let(:issue) { create :issue, project: project }
- let(:other_project) { create(:empty_project, :public) }
+ let(:other_project) { create(:project, :public) }
let(:other_issue) { create :issue, project: other_project }
let(:commiter) { create :user }
@@ -161,7 +159,7 @@ eos
end
it 'detects issues that this commit is marked as closing' do
- ext_ref = "#{other_project.path_with_namespace}##{other_issue.iid}"
+ ext_ref = "#{other_project.full_path}##{other_issue.iid}"
allow(commit).to receive_messages(
safe_message: "Fixes ##{issue.iid} and #{ext_ref}",
@@ -191,7 +189,7 @@ eos
it { expect(data).to be_a(Hash) }
it { expect(data[:message]).to include('adds bar folder and branch-test text file to check Repository merged_to_root_ref method') }
- it { expect(data[:timestamp]).to eq('2016-09-27T14:37:46+00:00') }
+ it { expect(data[:timestamp]).to eq('2016-09-27T14:37:46Z') }
it { expect(data[:added]).to eq(["bar/branch-test.txt"]) }
it { expect(data[:modified]).to eq([]) }
it { expect(data[:removed]).to eq([]) }
diff --git a/spec/models/commit_status_spec.rb b/spec/models/commit_status_spec.rb
index 4e915d73ced..f7583645e69 100644
--- a/spec/models/commit_status_spec.rb
+++ b/spec/models/commit_status_spec.rb
@@ -425,7 +425,7 @@ describe CommitStatus do
end
it "raise exception when trying to update" do
- expect{ commit_status.save }.to raise_error(ActiveRecord::StaleObjectError)
+ expect { commit_status.save }.to raise_error(ActiveRecord::StaleObjectError)
end
end
diff --git a/spec/models/concerns/access_requestable_spec.rb b/spec/models/concerns/access_requestable_spec.rb
index 97b7e48bb3c..04d6cfa2c02 100644
--- a/spec/models/concerns/access_requestable_spec.rb
+++ b/spec/models/concerns/access_requestable_spec.rb
@@ -24,14 +24,14 @@ describe AccessRequestable do
describe 'Project' do
describe '#request_access' do
- let(:project) { create(:empty_project, :public, :access_requestable) }
+ let(:project) { create(:project, :public, :access_requestable) }
let(:user) { create(:user) }
it { expect(project.request_access(user)).to be_a(ProjectMember) }
end
describe '#access_requested?' do
- let(:project) { create(:empty_project, :public, :access_requestable) }
+ let(:project) { create(:project, :public, :access_requestable) }
let(:user) { create(:user) }
before do
diff --git a/spec/models/concerns/issuable_spec.rb b/spec/models/concerns/issuable_spec.rb
index 505039c9d88..dfbe1a7c192 100644
--- a/spec/models/concerns/issuable_spec.rb
+++ b/spec/models/concerns/issuable_spec.rb
@@ -155,7 +155,7 @@ describe Issuable do
end
describe "#sort" do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
context "by milestone due date" do
# Correct order is:
@@ -296,11 +296,11 @@ describe Issuable do
end
describe '#labels_array' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:bug) { create(:label, project: project, title: 'bug') }
let(:issue) { create(:issue, project: project) }
- before(:each) do
+ before do
issue.labels << bug
end
@@ -310,7 +310,7 @@ describe Issuable do
end
describe '#user_notes_count' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:issue1) { create(:issue, project: project) }
let(:issue2) { create(:issue, project: project) }
@@ -340,7 +340,7 @@ describe Issuable do
end
describe '.order_due_date_and_labels_priority' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
def create_issue(milestone, labels)
create(:labeled_issue, milestone: milestone, labels: labels, project: project)
@@ -394,7 +394,7 @@ describe Issuable do
end
describe ".with_label" do
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:bug) { create(:label, project: project, title: 'bug') }
let(:feature) { create(:label, project: project, title: 'feature') }
let(:enhancement) { create(:label, project: project, title: 'enhancement') }
@@ -402,7 +402,7 @@ describe Issuable do
let(:issue2) { create(:issue, title: "Bugfix2", project: project) }
let(:issue3) { create(:issue, title: "Feature1", project: project) }
- before(:each) do
+ before do
issue1.labels << bug
issue1.labels << feature
issue2.labels << bug
diff --git a/spec/models/concerns/mentionable_spec.rb b/spec/models/concerns/mentionable_spec.rb
index 1ad811736af..8b545aec7f5 100644
--- a/spec/models/concerns/mentionable_spec.rb
+++ b/spec/models/concerns/mentionable_spec.rb
@@ -13,7 +13,7 @@ describe Mentionable do
end
describe 'references' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:mentionable) { Example.new }
it 'excludes JIRA references' do
@@ -48,10 +48,10 @@ describe Issue, "Mentionable" do
describe '#referenced_mentionables' do
context 'with an issue on a private project' do
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:issue) { create(:issue, project: project) }
let(:public_issue) { create(:issue, project: project) }
- let(:private_project) { create(:empty_project, :private) }
+ let(:private_project) { create(:project, :private) }
let(:private_issue) { create(:issue, project: private_project) }
let(:user) { create(:user) }
@@ -102,7 +102,7 @@ describe Issue, "Mentionable" do
end
describe '#create_new_cross_references!' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:author) { create(:author) }
let(:issues) { create_list(:issue, 2, project: project, author: author) }
@@ -204,7 +204,7 @@ describe Commit, 'Mentionable' do
end
context 'with external issue tracker' do
- let(:project) { create(:jira_project) }
+ let(:project) { create(:jira_project, :repository) }
it 'is true if external issues referenced' do
allow(commit.raw).to receive(:message).and_return 'JIRA-123'
diff --git a/spec/models/concerns/milestoneish_spec.rb b/spec/models/concerns/milestoneish_spec.rb
index cefe7fb6fea..66353935427 100644
--- a/spec/models/concerns/milestoneish_spec.rb
+++ b/spec/models/concerns/milestoneish_spec.rb
@@ -7,7 +7,7 @@ describe Milestone, 'Milestoneish' do
let(:member) { create(:user) }
let(:guest) { create(:user) }
let(:admin) { create(:admin) }
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:milestone) { create(:milestone, project: project) }
let!(:issue) { create(:issue, project: project, milestone: milestone) }
let!(:security_issue_1) { create(:issue, :confidential, project: project, author: author, milestone: milestone) }
diff --git a/spec/models/concerns/project_features_compatibility_spec.rb b/spec/models/concerns/project_features_compatibility_spec.rb
index 6cf5877424d..9041690023f 100644
--- a/spec/models/concerns/project_features_compatibility_spec.rb
+++ b/spec/models/concerns/project_features_compatibility_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe ProjectFeaturesCompatibility do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:features) { %w(issues wiki builds merge_requests snippets) }
# We had issues_enabled, snippets_enabled, builds_enabled, merge_requests_enabled and issues_enabled fields on projects table
diff --git a/spec/models/concerns/reactive_caching_spec.rb b/spec/models/concerns/reactive_caching_spec.rb
index 5f9b7e0a367..a5d505af001 100644
--- a/spec/models/concerns/reactive_caching_spec.rb
+++ b/spec/models/concerns/reactive_caching_spec.rb
@@ -31,7 +31,7 @@ describe ReactiveCaching, :use_clean_rails_memory_store_caching do
let(:now) { Time.now.utc }
- around(:each) do |example|
+ around do |example|
Timecop.freeze(now) { example.run }
end
diff --git a/spec/models/concerns/relative_positioning_spec.rb b/spec/models/concerns/relative_positioning_spec.rb
index 494e6f1b6f6..729056b6abc 100644
--- a/spec/models/concerns/relative_positioning_spec.rb
+++ b/spec/models/concerns/relative_positioning_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe RelativePositioning do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:issue) { create(:issue, project: project) }
let(:issue1) { create(:issue, project: project) }
let(:new_issue) { create(:issue, project: project) }
diff --git a/spec/models/concerns/resolvable_note_spec.rb b/spec/models/concerns/resolvable_note_spec.rb
index 53eaa6f8461..d00faa4f8be 100644
--- a/spec/models/concerns/resolvable_note_spec.rb
+++ b/spec/models/concerns/resolvable_note_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Note, ResolvableNote do
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:merge_request) { create(:merge_request, source_project: project) }
subject { create(:discussion_note_on_merge_request, noteable: merge_request, project: project) }
diff --git a/spec/models/concerns/routable_spec.rb b/spec/models/concerns/routable_spec.rb
index 36aedd2f701..b463d12e448 100644
--- a/spec/models/concerns/routable_spec.rb
+++ b/spec/models/concerns/routable_spec.rb
@@ -156,13 +156,13 @@ end
describe Project, 'Routable' do
describe '#full_path' do
- let(:project) { build_stubbed(:empty_project) }
+ let(:project) { build_stubbed(:project) }
it { expect(project.full_path).to eq "#{project.namespace.full_path}/#{project.path}" }
end
describe '#full_name' do
- let(:project) { build_stubbed(:empty_project) }
+ let(:project) { build_stubbed(:project) }
it { expect(project.full_name).to eq "#{project.namespace.human_name} / #{project.name}" }
end
diff --git a/spec/models/concerns/subscribable_spec.rb b/spec/models/concerns/subscribable_spec.rb
index 58f5c164116..28ff8158e0e 100644
--- a/spec/models/concerns/subscribable_spec.rb
+++ b/spec/models/concerns/subscribable_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Subscribable, 'Subscribable' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:resource) { create(:issue, project: project) }
let(:user_1) { create(:user) }
diff --git a/spec/models/container_repository_spec.rb b/spec/models/container_repository_spec.rb
index eff41d85972..bae88cb1d24 100644
--- a/spec/models/container_repository_spec.rb
+++ b/spec/models/container_repository_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe ContainerRepository do
let(:group) { create(:group, name: 'group') }
- let(:project) { create(:project, path: 'test', group: group) }
+ let(:project) { create(:project, :repository, path: 'test', group: group) }
let(:repository) do
create(:container_repository, name: 'my_image', project: project)
@@ -41,7 +41,7 @@ describe ContainerRepository do
end
context 'when path contains uppercase letters' do
- let(:project) { create(:project, path: 'MY_PROJECT', group: group) }
+ let(:project) { create(:project, :repository, path: 'MY_PROJECT', group: group) }
it 'returns a full path without capital letters' do
expect(repository.path).to eq('group/my_project/my_image')
diff --git a/spec/models/conversational_development_index/metric_spec.rb b/spec/models/conversational_development_index/metric_spec.rb
new file mode 100644
index 00000000000..b3193619503
--- /dev/null
+++ b/spec/models/conversational_development_index/metric_spec.rb
@@ -0,0 +1,11 @@
+require 'rails_helper'
+
+describe ConversationalDevelopmentIndex::Metric do
+ let(:conv_dev_index) { create(:conversational_development_index_metric) }
+
+ describe '#percentage_score' do
+ it 'returns stored percentage score' do
+ expect(conv_dev_index.percentage_score('issues')).to eq(13.331)
+ end
+ end
+end
diff --git a/spec/models/deploy_key_spec.rb b/spec/models/deploy_key_spec.rb
index 2aece75b817..3d7283e2164 100644
--- a/spec/models/deploy_key_spec.rb
+++ b/spec/models/deploy_key_spec.rb
@@ -1,8 +1,6 @@
require 'spec_helper'
-describe DeployKey do
- include EmailHelpers
-
+describe DeployKey, :mailer do
describe "Associations" do
it { is_expected.to have_many(:deploy_keys_projects) }
it { is_expected.to have_many(:projects) }
diff --git a/spec/models/deploy_keys_project_spec.rb b/spec/models/deploy_keys_project_spec.rb
index f10b65ba9d8..0345fefb254 100644
--- a/spec/models/deploy_keys_project_spec.rb
+++ b/spec/models/deploy_keys_project_spec.rb
@@ -12,7 +12,7 @@ describe DeployKeysProject do
end
describe "Destroying" do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
subject { create(:deploy_keys_project, project: project) }
let(:deploy_key) { subject.deploy_key }
@@ -39,7 +39,7 @@ describe DeployKeysProject do
end
context "when the deploy key is used by more than one project" do
- let!(:other_project) { create(:empty_project) }
+ let!(:other_project) { create(:project) }
before do
other_project.deploy_keys << deploy_key
diff --git a/spec/models/deployment_spec.rb b/spec/models/deployment_spec.rb
index 6447095078b..c5708e70ef9 100644
--- a/spec/models/deployment_spec.rb
+++ b/spec/models/deployment_spec.rb
@@ -91,7 +91,7 @@ describe Deployment do
end
describe '#additional_metrics' do
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:deployment) { create(:deployment, project: project) }
subject { deployment.additional_metrics }
diff --git a/spec/models/diff_discussion_spec.rb b/spec/models/diff_discussion_spec.rb
index 2704698f6c9..fa02434b0fd 100644
--- a/spec/models/diff_discussion_spec.rb
+++ b/spec/models/diff_discussion_spec.rb
@@ -5,7 +5,7 @@ describe DiffDiscussion do
subject { described_class.new([diff_note]) }
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
let(:diff_note) { create(:diff_note_on_merge_request, noteable: merge_request, project: project) }
diff --git a/spec/models/environment_spec.rb b/spec/models/environment_spec.rb
index ebf2c070116..ea8512a5eae 100644
--- a/spec/models/environment_spec.rb
+++ b/spec/models/environment_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Environment do
- set(:project) { create(:empty_project) }
+ set(:project) { create(:project) }
subject(:environment) { create(:environment, project: project) }
it { is_expected.to belong_to(:project) }
@@ -21,7 +21,7 @@ describe Environment do
it { is_expected.to validate_uniqueness_of(:external_url).scoped_to(:project_id) }
describe '.order_by_last_deployed_at' do
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let!(:environment1) { create(:environment, project: project) }
let!(:environment2) { create(:environment, project: project) }
let!(:environment3) { create(:environment, project: project) }
diff --git a/spec/models/event_collection_spec.rb b/spec/models/event_collection_spec.rb
new file mode 100644
index 00000000000..e0a87c18cc7
--- /dev/null
+++ b/spec/models/event_collection_spec.rb
@@ -0,0 +1,51 @@
+require 'spec_helper'
+
+describe EventCollection do
+ describe '#to_a' do
+ let(:project) { create(:project_empty_repo) }
+ let(:projects) { Project.where(id: project.id) }
+ let(:user) { create(:user) }
+
+ before do
+ 20.times do
+ event = create(:push_event, project: project, author: user)
+
+ create(:push_event_payload, event: event)
+ end
+
+ create(:closed_issue_event, project: project, author: user)
+ end
+
+ it 'returns an Array of events' do
+ events = described_class.new(projects).to_a
+
+ expect(events).to be_an_instance_of(Array)
+ end
+
+ it 'applies a limit to the number of events' do
+ events = described_class.new(projects).to_a
+
+ expect(events.length).to eq(20)
+ end
+
+ it 'can paginate through events' do
+ events = described_class.new(projects, offset: 20).to_a
+
+ expect(events.length).to eq(1)
+ end
+
+ it 'returns an empty Array when crossing the maximum page number' do
+ events = described_class.new(projects, limit: 1, offset: 15).to_a
+
+ expect(events).to be_empty
+ end
+
+ it 'allows filtering of events using an EventFilter' do
+ filter = EventFilter.new(EventFilter.issue)
+ events = described_class.new(projects, filter: filter).to_a
+
+ expect(events.length).to eq(1)
+ expect(events[0].action).to eq(Event::CLOSED)
+ end
+ end
+end
diff --git a/spec/models/event_spec.rb b/spec/models/event_spec.rb
index 4a4b84c9566..ff3224dd298 100644
--- a/spec/models/event_spec.rb
+++ b/spec/models/event_spec.rb
@@ -15,7 +15,7 @@ describe Event do
end
describe 'Callbacks' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
describe 'after_create :reset_project_activity' do
it 'calls the reset_project_activity method' do
@@ -53,7 +53,7 @@ describe Event do
end
describe "Push event" do
- let(:project) { create(:empty_project, :private) }
+ let(:project) { create(:project, :private) }
let(:user) { project.owner }
let(:event) { create_push_event(project, user) }
@@ -111,7 +111,7 @@ describe Event do
end
describe '#visible_to_user?' do
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:non_member) { create(:user) }
let(:member) { create(:user) }
let(:guest) { create(:user) }
@@ -143,7 +143,7 @@ describe Event do
end
context 'private project' do
- let(:project) { create(:empty_project, :private) }
+ let(:project) { create(:project, :private) }
it do
aggregate_failures do
@@ -213,7 +213,7 @@ describe Event do
end
context 'merge request diff note event' do
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:merge_request) { create(:merge_request, source_project: project, author: author, assignee: assignee) }
let(:note_on_merge_request) { create(:legacy_diff_note_on_merge_request, noteable: merge_request, project: project) }
let(:target) { note_on_merge_request }
@@ -228,7 +228,7 @@ describe Event do
end
context 'private project' do
- let(:project) { create(:empty_project, :private) }
+ let(:project) { create(:project, :private) }
it do
expect(event.visible_to_user?(non_member)).to eq false
@@ -260,7 +260,7 @@ describe Event do
end
describe '#reset_project_activity' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
context 'when a project was updated less than 1 hour ago' do
it 'does not update the project' do
@@ -304,27 +304,15 @@ describe Event do
end
end
- def create_push_event(project, user, attrs = {})
- data = {
- before: Gitlab::Git::BLANK_SHA,
- after: "0220c11b9a3e6c69dc8fd35321254ca9a7b98f7e",
- ref: "refs/heads/master",
- user_id: user.id,
- user_name: user.name,
- repository: {
- name: project.name,
- url: "localhost/rubinius",
- description: "",
- homepage: "localhost/rubinius",
- private: true
- }
- }
-
- described_class.create({
- project: project,
- action: described_class::PUSHED,
- data: data,
- author_id: user.id
- }.merge!(attrs))
+ def create_push_event(project, user)
+ event = create(:push_event, project: project, author: user)
+
+ create(:push_event_payload,
+ event: event,
+ commit_to: '1cf19a015df3523caf0a1f9d40c98a267d6a2fc2',
+ commit_count: 0,
+ ref: 'master')
+
+ event
end
end
diff --git a/spec/models/forked_project_link_spec.rb b/spec/models/forked_project_link_spec.rb
index 38fbdd2536a..7dbeb4d2e74 100644
--- a/spec/models/forked_project_link_spec.rb
+++ b/spec/models/forked_project_link_spec.rb
@@ -41,7 +41,7 @@ describe ForkedProjectLink, "add link on fork" do
end
describe '#forked?' do
- let(:project_to) { create(:project, forked_project_link: forked_project_link) }
+ let(:project_to) { create(:project, :repository, forked_project_link: forked_project_link) }
let(:forked_project_link) { create(:forked_project_link) }
before do
diff --git a/spec/models/generic_commit_status_spec.rb b/spec/models/generic_commit_status_spec.rb
index aedc74deb78..7f1909710d8 100644
--- a/spec/models/generic_commit_status_spec.rb
+++ b/spec/models/generic_commit_status_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe GenericCommitStatus do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:pipeline) { create(:ci_pipeline, project: project) }
let(:external_url) { 'http://example.gitlab.com/status' }
diff --git a/spec/models/global_milestone_spec.rb b/spec/models/global_milestone_spec.rb
index 5584a1a5a31..ab58f5c5021 100644
--- a/spec/models/global_milestone_spec.rb
+++ b/spec/models/global_milestone_spec.rb
@@ -4,9 +4,9 @@ describe GlobalMilestone do
let(:user) { create(:user) }
let(:user2) { create(:user) }
let(:group) { create(:group) }
- let(:project1) { create(:empty_project, group: group) }
- let(:project2) { create(:empty_project, path: 'gitlab-ci', group: group) }
- let(:project3) { create(:empty_project, path: 'cookbook-gitlab', group: group) }
+ let(:project1) { create(:project, group: group) }
+ let(:project2) { create(:project, path: 'gitlab-ci', group: group) }
+ let(:project3) { create(:project, path: 'cookbook-gitlab', group: group) }
describe '.build_collection' do
let(:milestone1_due_date) { 2.weeks.from_now.to_date }
diff --git a/spec/models/gpg_key_spec.rb b/spec/models/gpg_key_spec.rb
index 59c074199db..e48f20bf53b 100644
--- a/spec/models/gpg_key_spec.rb
+++ b/spec/models/gpg_key_spec.rb
@@ -114,9 +114,7 @@ describe GpgKey do
end
end
- describe 'notification' do
- include EmailHelpers
-
+ describe 'notification', :mailer do
let(:user) { create(:user) }
it 'sends a notification' do
diff --git a/spec/models/gpg_signature_spec.rb b/spec/models/gpg_signature_spec.rb
index 9a9b1900aa5..c58fd46762a 100644
--- a/spec/models/gpg_signature_spec.rb
+++ b/spec/models/gpg_signature_spec.rb
@@ -16,7 +16,7 @@ RSpec.describe GpgSignature do
describe '#commit' do
it 'fetches the commit through the project' do
commit_sha = '0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33'
- project = create :project
+ project = create :project, :repository
commit = create :commit, project: project
gpg_signature = create :gpg_signature, commit_sha: commit_sha
diff --git a/spec/models/group_label_spec.rb b/spec/models/group_label_spec.rb
index f7828059295..d0fc1eaa3ec 100644
--- a/spec/models/group_label_spec.rb
+++ b/spec/models/group_label_spec.rb
@@ -39,8 +39,8 @@ describe GroupLabel do
context 'cross-project' do
let(:namespace) { build_stubbed(:namespace) }
- let(:source_project) { build_stubbed(:empty_project, name: 'project-1', namespace: namespace) }
- let(:target_project) { build_stubbed(:empty_project, name: 'project-2', namespace: namespace) }
+ let(:source_project) { build_stubbed(:project, name: 'project-1', namespace: namespace) }
+ let(:target_project) { build_stubbed(:project, name: 'project-2', namespace: namespace) }
it 'returns a String reference to the object' do
expect(label.to_reference(source_project, target_project: target_project)).to eq %(project-1~#{label.id})
diff --git a/spec/models/group_milestone_spec.rb b/spec/models/group_milestone_spec.rb
index ac76c927c39..b60676afc91 100644
--- a/spec/models/group_milestone_spec.rb
+++ b/spec/models/group_milestone_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe GroupMilestone do
let(:group) { create(:group) }
- let(:project) { create(:empty_project, group: group) }
+ let(:project) { create(:project, group: group) }
let(:project_milestone) do
create(:milestone, title: "Milestone v1.2", project: project)
end
diff --git a/spec/models/group_spec.rb b/spec/models/group_spec.rb
index 112bd605a64..c5bfae47606 100644
--- a/spec/models/group_spec.rb
+++ b/spec/models/group_spec.rb
@@ -425,7 +425,7 @@ describe Group do
end
describe '#secret_variables_for' do
- let(:project) { create(:empty_project, group: group) }
+ let(:project) { create(:project, group: group) }
let!(:secret_variable) do
create(:ci_group_variable, value: 'secret', group: group)
diff --git a/spec/models/guest_spec.rb b/spec/models/guest_spec.rb
index 0e9b94aac97..2afdd6751a4 100644
--- a/spec/models/guest_spec.rb
+++ b/spec/models/guest_spec.rb
@@ -1,9 +1,9 @@
require 'spec_helper'
describe Guest do
- let(:public_project) { build_stubbed(:empty_project, :public) }
- let(:private_project) { build_stubbed(:empty_project, :private) }
- let(:internal_project) { build_stubbed(:empty_project, :internal) }
+ let(:public_project) { build_stubbed(:project, :public) }
+ let(:private_project) { build_stubbed(:project, :private) }
+ let(:internal_project) { build_stubbed(:project, :internal) }
describe '.can_pull?' do
context 'when project is private' do
diff --git a/spec/models/hooks/system_hook_spec.rb b/spec/models/hooks/system_hook_spec.rb
index eadc232a989..431e3db9f00 100644
--- a/spec/models/hooks/system_hook_spec.rb
+++ b/spec/models/hooks/system_hook_spec.rb
@@ -16,7 +16,7 @@ describe SystemHook do
describe "execute" do
let(:system_hook) { create(:system_hook) }
let(:user) { create(:user) }
- let(:project) { create(:empty_project, namespace: user.namespace) }
+ let(:project) { create(:project, namespace: user.namespace) }
let(:group) { create(:group) }
let(:params) do
{ name: 'John Doe', username: 'jduser', email: 'jg@example.com', password: 'mydummypass' }
diff --git a/spec/models/issue/metrics_spec.rb b/spec/models/issue/metrics_spec.rb
index 6ceff7d24d4..1bf0ecb98ad 100644
--- a/spec/models/issue/metrics_spec.rb
+++ b/spec/models/issue/metrics_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Issue::Metrics do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
subject { create(:issue, project: project) }
diff --git a/spec/models/issue_collection_spec.rb b/spec/models/issue_collection_spec.rb
index 04d23d4c4fd..34d98a3c975 100644
--- a/spec/models/issue_collection_spec.rb
+++ b/spec/models/issue_collection_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe IssueCollection do
let(:user) { create(:user) }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:issue1) { create(:issue, project: project) }
let(:issue2) { create(:issue, project: project) }
let(:collection) { described_class.new([issue1, issue2]) }
diff --git a/spec/models/issue_spec.rb b/spec/models/issue_spec.rb
index d72790eefe5..9203f6562f2 100644
--- a/spec/models/issue_spec.rb
+++ b/spec/models/issue_spec.rb
@@ -24,7 +24,7 @@ describe Issue do
end
describe '#order_by_position_and_priority' do
- let(:project) { create :empty_project }
+ let(:project) { create :project }
let(:p1) { create(:label, title: 'P1', project: project, priority: 1) }
let(:p2) { create(:label, title: 'P2', project: project, priority: 2) }
let!(:issue1) { create(:labeled_issue, project: project, labels: [p1]) }
@@ -57,24 +57,20 @@ describe Issue do
end
describe '#closed_at' do
- after do
- Timecop.return
- end
-
- let!(:now) { Timecop.freeze(Time.now) }
-
it 'sets closed_at to Time.now when issue is closed' do
issue = create(:issue, state: 'opened')
+ expect(issue.closed_at).to be_nil
+
issue.close
- expect(issue.closed_at).to eq(now)
+ expect(issue.closed_at).to be_present
end
end
describe '#to_reference' do
let(:namespace) { build(:namespace, path: 'sample-namespace') }
- let(:project) { build(:empty_project, name: 'sample-project', namespace: namespace) }
+ let(:project) { build(:project, name: 'sample-project', namespace: namespace) }
let(:issue) { build(:issue, iid: 1, project: project) }
let(:group) { create(:group, name: 'Group', path: 'sample-group') }
@@ -99,7 +95,7 @@ describe Issue do
end
context 'when cross namespace project argument' do
- let(:another_namespace_project) { create(:empty_project, name: 'another-project') }
+ let(:another_namespace_project) { create(:project, name: 'another-project') }
it 'returns complete path to the issue' do
expect(issue.to_reference(another_namespace_project)).to eq 'sample-namespace/sample-project#1'
@@ -107,12 +103,12 @@ describe Issue do
end
it 'supports a cross-project reference' do
- another_project = build(:empty_project, name: 'another-project', namespace: project.namespace)
+ another_project = build(:project, name: 'another-project', namespace: project.namespace)
expect(issue.to_reference(another_project)).to eq "sample-project#1"
end
context 'when same namespace / cross-project argument' do
- let(:another_project) { create(:empty_project, namespace: namespace) }
+ let(:another_project) { create(:project, namespace: namespace) }
it 'returns path to the issue with the project name' do
expect(issue.to_reference(another_project)).to eq 'sample-project#1'
@@ -121,7 +117,7 @@ describe Issue do
context 'when different namespace / cross-project argument' do
let(:another_namespace) { create(:namespace, path: 'another-namespace') }
- let(:another_project) { create(:empty_project, path: 'another-project', namespace: another_namespace) }
+ let(:another_project) { create(:project, path: 'another-project', namespace: another_namespace) }
it 'returns full path to the issue' do
expect(issue.to_reference(another_project)).to eq 'sample-namespace/sample-project#1'
@@ -191,14 +187,10 @@ describe Issue do
end
it 'returns the merge request to close this issue' do
- mr
-
expect(issue.closed_by_merge_requests(mr.author)).to eq([mr])
end
it "returns an empty array when the merge request is closed already" do
- closed_mr
-
expect(issue.closed_by_merge_requests(closed_mr.author)).to eq([])
end
@@ -209,7 +201,7 @@ describe Issue do
describe '#referenced_merge_requests' do
it 'returns the referenced merge requests' do
- project = create(:empty_project, :public)
+ project = create(:project, :public)
mr1 = create(:merge_request,
source_project: project,
@@ -242,7 +234,7 @@ describe Issue do
end
context 'user is reporter in project issue belongs to' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:issue) { create(:issue, project: project) }
before do
@@ -258,7 +250,7 @@ describe Issue do
context 'checking destination project also' do
subject { issue.can_move?(user, to_project) }
- let(:to_project) { create(:empty_project) }
+ let(:to_project) { create(:project) }
context 'destination project allowed' do
before do
@@ -354,7 +346,7 @@ describe Issue do
subject { create(:issue, project: create(:project, :repository)) }
let(:backref_text) { "issue #{subject.to_reference}" }
- let(:set_mentionable_text) { ->(txt){ subject.description = txt } }
+ let(:set_mentionable_text) { ->(txt) { subject.description = txt } }
end
it_behaves_like 'a Taskable' do
@@ -380,7 +372,7 @@ describe Issue do
describe '#participants' do
context 'using a public project' do
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:issue) { create(:issue, project: project) }
let!(:note1) do
@@ -402,7 +394,7 @@ describe Issue do
context 'using a private project' do
it 'does not include mentioned users that do not have access to the project' do
- project = create(:empty_project)
+ project = create(:project)
user = create(:user)
issue = create(:issue, project: project)
@@ -420,7 +412,7 @@ describe Issue do
it 'updates when assignees change' do
user1 = create(:user)
user2 = create(:user)
- project = create(:empty_project)
+ project = create(:project)
issue = create(:issue, assignees: [user1], project: project)
project.add_developer(user1)
project.add_developer(user2)
@@ -490,7 +482,7 @@ describe Issue do
let(:user) { create(:user) }
context 'using a public project' do
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
it 'returns true for a regular issue' do
issue = build(:issue, project: project)
@@ -506,7 +498,7 @@ describe Issue do
end
context 'using an internal project' do
- let(:project) { create(:empty_project, :internal) }
+ let(:project) { create(:project, :internal) }
context 'using an internal user' do
it 'returns true for a regular issue' do
@@ -542,7 +534,7 @@ describe Issue do
end
context 'using a private project' do
- let(:project) { create(:empty_project, :private) }
+ let(:project) { create(:project, :private) }
it 'returns false for a regular issue' do
issue = build(:issue, project: project)
@@ -578,7 +570,7 @@ describe Issue do
context 'with a regular user that is a team member' do
let(:user) { create(:user) }
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
context 'using a public project' do
before do
@@ -599,7 +591,7 @@ describe Issue do
end
context 'using an internal project' do
- let(:project) { create(:empty_project, :internal) }
+ let(:project) { create(:project, :internal) }
before do
project.team << [user, Gitlab::Access::DEVELOPER]
@@ -619,7 +611,7 @@ describe Issue do
end
context 'using a private project' do
- let(:project) { create(:empty_project, :private) }
+ let(:project) { create(:project, :private) }
before do
project.team << [user, Gitlab::Access::DEVELOPER]
@@ -640,7 +632,7 @@ describe Issue do
end
context 'with an admin user' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:user) { create(:admin) }
it 'returns true for a regular issue' do
@@ -659,7 +651,7 @@ describe Issue do
describe '#publicly_visible?' do
context 'using a public project' do
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
it 'returns true for a regular issue' do
issue = build(:issue, project: project)
@@ -675,7 +667,7 @@ describe Issue do
end
context 'using an internal project' do
- let(:project) { create(:empty_project, :internal) }
+ let(:project) { create(:project, :internal) }
it 'returns false for a regular issue' do
issue = build(:issue, project: project)
@@ -691,7 +683,7 @@ describe Issue do
end
context 'using a private project' do
- let(:project) { create(:empty_project, :private) }
+ let(:project) { create(:project, :private) }
it 'returns false for a regular issue' do
issue = build(:issue, project: project)
diff --git a/spec/models/key_spec.rb b/spec/models/key_spec.rb
index d41717d0223..3508391c721 100644
--- a/spec/models/key_spec.rb
+++ b/spec/models/key_spec.rb
@@ -1,8 +1,6 @@
require 'spec_helper'
-describe Key do
- include EmailHelpers
-
+describe Key, :mailer do
describe "Associations" do
it { is_expected.to belong_to(:user) }
end
@@ -85,24 +83,16 @@ describe Key do
expect(build(:key)).to be_valid
end
- it 'rejects an unfingerprintable key that contains a space' do
+ it 'accepts a key with newline charecters after stripping them' do
key = build(:key)
-
- # Not always the middle, but close enough
- key.key = key.key[0..100] + ' ' + key.key[101..-1]
-
- expect(key).not_to be_valid
+ key.key = key.key.insert(100, "\n")
+ key.key = key.key.insert(40, "\r\n")
+ expect(key).to be_valid
end
it 'rejects the unfingerprintable key (not a key)' do
expect(build(:key, key: 'ssh-rsa an-invalid-key==')).not_to be_valid
end
-
- it 'rejects the multiple line key' do
- key = build(:key)
- key.key.tr!(' ', "\n")
- expect(key).not_to be_valid
- end
end
context 'callbacks' do
diff --git a/spec/models/lfs_objects_project_spec.rb b/spec/models/lfs_objects_project_spec.rb
index 8c74f1f9e86..d24d4cf7695 100644
--- a/spec/models/lfs_objects_project_spec.rb
+++ b/spec/models/lfs_objects_project_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe LfsObjectsProject do
subject { create(:lfs_objects_project, project: project) }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
describe 'associations' do
it { is_expected.to belong_to(:project) }
diff --git a/spec/models/member_spec.rb b/spec/models/member_spec.rb
index 8bfd70b8d46..87513e18b25 100644
--- a/spec/models/member_spec.rb
+++ b/spec/models/member_spec.rb
@@ -57,7 +57,7 @@ describe Member do
describe 'Scopes & finders' do
before do
- project = create(:empty_project, :public, :access_requestable)
+ project = create(:project, :public, :access_requestable)
group = create(:group)
@owner_user = create(:user).tap { |u| group.add_owner(u) }
@owner = group.members.find_by(user_id: @owner_user.id)
@@ -516,7 +516,7 @@ describe Member do
describe "destroying a record", truncate: true do
it "refreshes user's authorized projects" do
- project = create(:empty_project, :private)
+ project = create(:project, :private)
user = create(:user)
member = project.team << [user, :reporter]
diff --git a/spec/models/members/project_member_spec.rb b/spec/models/members/project_member_spec.rb
index 025fb2bf441..fa3e80ba062 100644
--- a/spec/models/members/project_member_spec.rb
+++ b/spec/models/members/project_member_spec.rb
@@ -24,7 +24,7 @@ describe ProjectMember do
describe '.add_user' do
it 'adds the user as a member' do
user = create(:user)
- project = create(:empty_project)
+ project = create(:project)
expect(project.users).not_to include(user)
@@ -82,8 +82,8 @@ describe ProjectMember do
describe '.import_team' do
before do
- @project_1 = create(:empty_project)
- @project_2 = create(:empty_project)
+ @project_1 = create(:project)
+ @project_2 = create(:project)
@user_1 = create :user
@user_2 = create :user
@@ -112,7 +112,7 @@ describe ProjectMember do
describe '.add_users_to_projects' do
it 'adds the given users to the given projects' do
- projects = create_list(:empty_project, 2)
+ projects = create_list(:project, 2)
users = create_list(:user, 2)
described_class.add_users_to_projects(
@@ -130,8 +130,8 @@ describe ProjectMember do
describe '.truncate_teams' do
before do
- @project_1 = create(:empty_project)
- @project_2 = create(:empty_project)
+ @project_1 = create(:project)
+ @project_2 = create(:project)
@user_1 = create :user
@user_2 = create :user
@@ -149,7 +149,7 @@ describe ProjectMember do
describe 'notifications' do
describe '#after_accept_request' do
it 'calls NotificationService.new_project_member' do
- member = create(:project_member, user: build_stubbed(:user), requested_at: Time.now)
+ member = create(:project_member, user: create(:user), requested_at: Time.now)
expect_any_instance_of(NotificationService).to receive(:new_project_member)
diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb
index b2dd02553c1..026bdbd26d1 100644
--- a/spec/models/merge_request_spec.rb
+++ b/spec/models/merge_request_spec.rb
@@ -237,7 +237,7 @@ describe MergeRequest do
end
describe '#to_reference' do
- let(:project) { build(:empty_project, name: 'sample-project') }
+ let(:project) { build(:project, name: 'sample-project') }
let(:merge_request) { build(:merge_request, target_project: project, iid: 1) }
it 'returns a String reference to the object' do
@@ -245,12 +245,12 @@ describe MergeRequest do
end
it 'supports a cross-project reference' do
- another_project = build(:empty_project, name: 'another-project', namespace: project.namespace)
+ another_project = build(:project, name: 'another-project', namespace: project.namespace)
expect(merge_request.to_reference(another_project)).to eq "sample-project!1"
end
it 'returns a String reference with the full path' do
- expect(merge_request.to_reference(full: true)).to eq(project.path_with_namespace + '!1')
+ expect(merge_request.to_reference(full: true)).to eq(project.full_path + '!1')
end
end
@@ -392,8 +392,8 @@ describe MergeRequest do
describe '#for_fork?' do
it 'returns true if the merge request is for a fork' do
- subject.source_project = build_stubbed(:empty_project, namespace: create(:group))
- subject.target_project = build_stubbed(:empty_project, namespace: create(:group))
+ subject.source_project = build_stubbed(:project, namespace: create(:group))
+ subject.target_project = build_stubbed(:project, namespace: create(:group))
expect(subject.for_fork?).to be_truthy
end
@@ -681,7 +681,7 @@ describe MergeRequest do
end
it 'does not crash' do
- expect{ subject.diverged_commits_count }.not_to raise_error
+ expect { subject.diverged_commits_count }.not_to raise_error
end
it 'returns 0' do
@@ -714,7 +714,7 @@ describe MergeRequest do
end
describe 'caching' do
- before(:example) do
+ before do
allow(Rails).to receive(:cache).and_return(ActiveSupport::Cache::MemoryStore.new)
end
@@ -753,7 +753,7 @@ describe MergeRequest do
subject { create(:merge_request, :simple) }
let(:backref_text) { "merge request #{subject.to_reference}" }
- let(:set_mentionable_text) { ->(txt){ subject.description = txt } }
+ let(:set_mentionable_text) { ->(txt) { subject.description = txt } }
end
it_behaves_like 'a Taskable' do
@@ -889,7 +889,7 @@ describe MergeRequest do
end
describe '#participants' do
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:mr) do
create(:merge_request, source_project: project, target_project: project)
@@ -932,7 +932,7 @@ describe MergeRequest do
end
describe '#check_if_can_be_merged' do
- let(:project) { create(:empty_project, only_allow_merge_if_pipeline_succeeds: true) }
+ let(:project) { create(:project, only_allow_merge_if_pipeline_succeeds: true) }
subject { create(:merge_request, source_project: project, merge_status: :unchecked) }
@@ -970,7 +970,7 @@ describe MergeRequest do
end
describe '#mergeable?' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
subject { create(:merge_request, source_project: project) }
@@ -1055,7 +1055,7 @@ describe MergeRequest do
end
describe '#mergeable_ci_state?' do
- let(:project) { create(:empty_project, only_allow_merge_if_pipeline_succeeds: true) }
+ let(:project) { create(:project, only_allow_merge_if_pipeline_succeeds: true) }
let(:pipeline) { create(:ci_empty_pipeline) }
subject { build(:merge_request, target_project: project) }
@@ -1098,7 +1098,7 @@ describe MergeRequest do
end
context 'when merges are not restricted to green builds' do
- subject { build(:merge_request, target_project: build(:empty_project, only_allow_merge_if_pipeline_succeeds: false)) }
+ subject { build(:merge_request, target_project: build(:project, only_allow_merge_if_pipeline_succeeds: false)) }
context 'and a failed pipeline is associated' do
before do
@@ -1332,8 +1332,8 @@ describe MergeRequest do
end
describe "#source_project_missing?" do
- let(:project) { create(:empty_project) }
- let(:fork_project) { create(:empty_project, forked_from_project: project) }
+ let(:project) { create(:project) }
+ let(:fork_project) { create(:project, forked_from_project: project) }
let(:user) { create(:user) }
let(:unlink_project) { Projects::UnlinkForkService.new(fork_project, user) }
@@ -1369,9 +1369,35 @@ describe MergeRequest do
end
end
+ describe '#merge_ongoing?' do
+ it 'returns true when merge process is ongoing for merge_jid' do
+ merge_request = create(:merge_request, merge_jid: 'foo')
+
+ allow(Gitlab::SidekiqStatus).to receive(:num_running).with(['foo']).and_return(1)
+
+ expect(merge_request.merge_ongoing?).to be(true)
+ end
+
+ it 'returns false when no merge process running for merge_jid' do
+ merge_request = build(:merge_request, merge_jid: 'foo')
+
+ allow(Gitlab::SidekiqStatus).to receive(:num_running).with(['foo']).and_return(0)
+
+ expect(merge_request.merge_ongoing?).to be(false)
+ end
+
+ it 'returns false when merge_jid is nil' do
+ merge_request = build(:merge_request, merge_jid: nil)
+
+ expect(Gitlab::SidekiqStatus).not_to receive(:num_running)
+
+ expect(merge_request.merge_ongoing?).to be(false)
+ end
+ end
+
describe "#closed_without_fork?" do
- let(:project) { create(:empty_project) }
- let(:fork_project) { create(:empty_project, forked_from_project: project) }
+ let(:project) { create(:project) }
+ let(:fork_project) { create(:project, forked_from_project: project) }
let(:user) { create(:user) }
let(:unlink_project) { Projects::UnlinkForkService.new(fork_project, user) }
@@ -1416,9 +1442,9 @@ describe MergeRequest do
end
context 'forked project' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:user) { create(:user) }
- let(:fork_project) { create(:empty_project, forked_from_project: project, namespace: user.namespace) }
+ let(:fork_project) { create(:project, forked_from_project: project, namespace: user.namespace) }
let!(:merge_request) do
create(:closed_merge_request,
diff --git a/spec/models/milestone_spec.rb b/spec/models/milestone_spec.rb
index aa376e242e8..d3da0107d5c 100644
--- a/spec/models/milestone_spec.rb
+++ b/spec/models/milestone_spec.rb
@@ -21,7 +21,7 @@ describe Milestone do
it { is_expected.to have_many(:issues) }
end
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:milestone) { create(:milestone, project: project) }
let(:issue) { create(:issue, project: project) }
let(:user) { create(:user) }
@@ -42,7 +42,7 @@ describe Milestone do
end
it "accepts the same title in another project" do
- project = create(:empty_project)
+ project = create(:project)
new_milestone = described_class.new(project: project, title: milestone.title)
expect(new_milestone).to be_valid
@@ -197,9 +197,9 @@ describe Milestone do
end
describe '.upcoming_ids_by_projects' do
- let(:project_1) { create(:empty_project) }
- let(:project_2) { create(:empty_project) }
- let(:project_3) { create(:empty_project) }
+ let(:project_1) { create(:project) }
+ let(:project_2) { create(:project) }
+ let(:project_3) { create(:project) }
let(:projects) { [project_1, project_2, project_3] }
let!(:past_milestone_project_1) { create(:milestone, project: project_1, due_date: Time.now - 1.day) }
@@ -230,21 +230,45 @@ describe Milestone do
end
describe '#to_reference' do
- let(:project) { build(:empty_project, name: 'sample-project') }
- let(:milestone) { build(:milestone, iid: 1, project: project) }
+ let(:group) { build_stubbed(:group) }
+ let(:project) { build_stubbed(:project, name: 'sample-project') }
+ let(:another_project) { build_stubbed(:project, name: 'another-project', namespace: project.namespace) }
+
+ context 'for a project milestone' do
+ let(:milestone) { build_stubbed(:milestone, iid: 1, project: project, name: 'milestone') }
+
+ it 'returns a String reference to the object' do
+ expect(milestone.to_reference).to eq '%1'
+ end
- it 'returns a String reference to the object' do
- expect(milestone.to_reference).to eq "%1"
+ it 'returns a reference by name when the format is set to :name' do
+ expect(milestone.to_reference(format: :name)).to eq '%"milestone"'
+ end
+
+ it 'supports a cross-project reference' do
+ expect(milestone.to_reference(another_project)).to eq 'sample-project%1'
+ end
end
- it 'supports a cross-project reference' do
- another_project = build(:empty_project, name: 'another-project', namespace: project.namespace)
- expect(milestone.to_reference(another_project)).to eq "sample-project%1"
+ context 'for a group milestone' do
+ let(:milestone) { build_stubbed(:milestone, iid: 1, group: group, name: 'milestone') }
+
+ it 'returns nil with the default format' do
+ expect(milestone.to_reference).to be_nil
+ end
+
+ it 'returns a reference by name when the format is set to :name' do
+ expect(milestone.to_reference(format: :name)).to eq '%"milestone"'
+ end
+
+ it 'does not supports cross-project references' do
+ expect(milestone.to_reference(another_project, format: :name)).to eq '%"milestone"'
+ end
end
end
describe '#participants' do
- let(:project) { build(:empty_project, name: 'sample-project') }
+ let(:project) { build(:project, name: 'sample-project') }
let(:milestone) { build(:milestone, iid: 1, project: project) }
it 'returns participants without duplicates' do
diff --git a/spec/models/namespace_spec.rb b/spec/models/namespace_spec.rb
index f12fe226e6b..69286eff984 100644
--- a/spec/models/namespace_spec.rb
+++ b/spec/models/namespace_spec.rb
@@ -111,7 +111,7 @@ describe Namespace do
let(:namespace) { create :namespace }
let(:project1) do
- create(:empty_project,
+ create(:project,
namespace: namespace,
statistics: build(:project_statistics,
storage_size: 606,
@@ -121,7 +121,7 @@ describe Namespace do
end
let(:project2) do
- create(:empty_project,
+ create(:project,
namespace: namespace,
statistics: build(:project_statistics,
storage_size: 60,
@@ -177,7 +177,7 @@ describe Namespace do
stub_container_registry_config(enabled: true)
stub_container_registry_tags(repository: :any, tags: ['tag'])
- create(:empty_project, namespace: @namespace, container_repositories: [container_repository])
+ create(:project, namespace: @namespace, container_repositories: [container_repository])
allow(@namespace).to receive(:path_was).and_return(@namespace.path)
allow(@namespace).to receive(:path).and_return('new_path')
@@ -315,6 +315,20 @@ describe Namespace do
end
end
+ describe '#self_and_ancestors', :nested_groups do
+ let(:group) { create(:group) }
+ let(:nested_group) { create(:group, parent: group) }
+ let(:deep_nested_group) { create(:group, parent: nested_group) }
+ let(:very_deep_nested_group) { create(:group, parent: deep_nested_group) }
+
+ it 'returns the correct ancestors' do
+ expect(very_deep_nested_group.self_and_ancestors).to contain_exactly(group, nested_group, deep_nested_group, very_deep_nested_group)
+ expect(deep_nested_group.self_and_ancestors).to contain_exactly(group, nested_group, deep_nested_group)
+ expect(nested_group.self_and_ancestors).to contain_exactly(group, nested_group)
+ expect(group.self_and_ancestors).to contain_exactly(group)
+ end
+ end
+
describe '#descendants', :nested_groups do
let!(:group) { create(:group, path: 'git_lab') }
let!(:nested_group) { create(:group, parent: group) }
@@ -331,6 +345,22 @@ describe Namespace do
end
end
+ describe '#self_and_descendants', :nested_groups do
+ let!(:group) { create(:group, path: 'git_lab') }
+ let!(:nested_group) { create(:group, parent: group) }
+ let!(:deep_nested_group) { create(:group, parent: nested_group) }
+ let!(:very_deep_nested_group) { create(:group, parent: deep_nested_group) }
+ let!(:another_group) { create(:group, path: 'gitllab') }
+ let!(:another_group_nested) { create(:group, path: 'foo', parent: another_group) }
+
+ it 'returns the correct descendants' do
+ expect(very_deep_nested_group.self_and_descendants).to contain_exactly(very_deep_nested_group)
+ expect(deep_nested_group.self_and_descendants).to contain_exactly(deep_nested_group, very_deep_nested_group)
+ expect(nested_group.self_and_descendants).to contain_exactly(nested_group, deep_nested_group, very_deep_nested_group)
+ expect(group.self_and_descendants).to contain_exactly(group, nested_group, deep_nested_group, very_deep_nested_group)
+ end
+ end
+
describe '#users_with_descendants', :nested_groups do
let(:user_a) { create(:user) }
let(:user_b) { create(:user) }
diff --git a/spec/models/note_spec.rb b/spec/models/note_spec.rb
index cbe6d42ef53..b214074fdce 100644
--- a/spec/models/note_spec.rb
+++ b/spec/models/note_spec.rb
@@ -46,7 +46,7 @@ describe Note do
context 'when noteable and note project differ' do
subject do
build(:note, noteable: build_stubbed(:issue),
- project: build_stubbed(:empty_project))
+ project: build_stubbed(:project))
end
it { is_expected.to be_invalid }
@@ -97,8 +97,8 @@ describe Note do
describe 'authorization' do
before do
- @p1 = create(:empty_project)
- @p2 = create(:empty_project)
+ @p1 = create(:project)
+ @p2 = create(:project)
@u1 = create(:user)
@u2 = create(:user)
@u3 = create(:user)
@@ -195,10 +195,10 @@ describe Note do
describe "cross_reference_not_visible_for?" do
let(:private_user) { create(:user) }
- let(:private_project) { create(:empty_project, namespace: private_user.namespace) { |p| p.team << [private_user, :master] } }
+ let(:private_project) { create(:project, namespace: private_user.namespace) { |p| p.team << [private_user, :master] } }
let(:private_issue) { create(:issue, project: private_project) }
- let(:ext_proj) { create(:empty_project, :public) }
+ let(:ext_proj) { create(:project, :public) }
let(:ext_issue) { create(:issue, project: ext_proj) }
let(:note) do
@@ -241,7 +241,7 @@ describe Note do
describe '#participants' do
it 'includes the note author' do
- project = create(:empty_project, :public)
+ project = create(:project, :public)
issue = create(:issue, project: project)
note = create(:note_on_issue, noteable: issue, project: project)
diff --git a/spec/models/notification_setting_spec.rb b/spec/models/notification_setting_spec.rb
index 07e296424ca..2a0d102d3fe 100644
--- a/spec/models/notification_setting_spec.rb
+++ b/spec/models/notification_setting_spec.rb
@@ -63,24 +63,20 @@ RSpec.describe NotificationSetting do
end
end
- describe 'event_enabled?' do
+ describe '#event_enabled?' do
before do
subject.update!(user: create(:user))
end
context 'for an event with a matching column name' do
- before do
- subject.update!(events: { new_note: true }.to_json)
- end
-
it 'returns the value of the column' do
- subject.update!(new_note: false)
+ subject.update!(new_note: true)
- expect(subject.event_enabled?(:new_note)).to be(false)
+ expect(subject.event_enabled?(:new_note)).to be(true)
end
context 'when the column has a nil value' do
- it 'returns the value from the events hash' do
+ it 'returns false' do
expect(subject.event_enabled?(:new_note)).to be(false)
end
end
diff --git a/spec/models/project_authorization_spec.rb b/spec/models/project_authorization_spec.rb
index ee6bdc39c8c..9e7e525b2c0 100644
--- a/spec/models/project_authorization_spec.rb
+++ b/spec/models/project_authorization_spec.rb
@@ -2,8 +2,8 @@ require 'spec_helper'
describe ProjectAuthorization do
let(:user) { create(:user) }
- let(:project1) { create(:empty_project) }
- let(:project2) { create(:empty_project) }
+ let(:project1) { create(:project) }
+ let(:project2) { create(:project) }
describe '.insert_authorizations' do
it 'inserts the authorizations' do
diff --git a/spec/models/project_feature_spec.rb b/spec/models/project_feature_spec.rb
index 580c83c12c0..de3e86b627f 100644
--- a/spec/models/project_feature_spec.rb
+++ b/spec/models/project_feature_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe ProjectFeature do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:user) { create(:user) }
describe '.quoted_access_level_column' do
@@ -47,7 +47,7 @@ describe ProjectFeature do
it "returns true when user is a member of project group" do
group = create(:group)
- project = create(:empty_project, namespace: group)
+ project = create(:project, namespace: group)
group.add_developer(user)
features.each do |feature|
diff --git a/spec/models/project_group_link_spec.rb b/spec/models/project_group_link_spec.rb
index d68d8b719cd..b3513c80150 100644
--- a/spec/models/project_group_link_spec.rb
+++ b/spec/models/project_group_link_spec.rb
@@ -32,7 +32,7 @@ describe ProjectGroupLink do
describe "destroying a record", truncate: true do
it "refreshes group users' authorized projects" do
- project = create(:empty_project, :private)
+ project = create(:project, :private)
group = create(:group)
reporter = create(:user)
group_users = group.users
diff --git a/spec/models/project_label_spec.rb b/spec/models/project_label_spec.rb
index add7e85f388..689d4e505e5 100644
--- a/spec/models/project_label_spec.rb
+++ b/spec/models/project_label_spec.rb
@@ -10,7 +10,7 @@ describe ProjectLabel do
context 'validates if title must not exist at group level' do
let(:group) { create(:group, name: 'gitlab-org') }
- let(:project) { create(:empty_project, group: group) }
+ let(:project) { create(:project, group: group) }
before do
create(:group_label, group: group, title: 'Bug')
@@ -33,7 +33,7 @@ describe ProjectLabel do
end
it 'does not returns error if project does not belong to group' do
- another_project = create(:empty_project)
+ another_project = create(:project)
label = described_class.new(project: another_project, title: 'Bug')
label.valid?
@@ -66,7 +66,7 @@ describe ProjectLabel do
describe '#subject' do
it 'aliases project to subject' do
- subject = described_class.new(project: build(:empty_project))
+ subject = described_class.new(project: build(:project))
expect(subject.subject).to be(subject.project)
end
@@ -100,19 +100,19 @@ describe ProjectLabel do
end
context 'cross project reference' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
context 'using name' do
it 'returns cross reference with label name' do
expect(label.to_reference(project, format: :name))
- .to eq %Q(#{label.project.path_with_namespace}~"#{label.name}")
+ .to eq %Q(#{label.project.full_path}~"#{label.name}")
end
end
context 'using id' do
it 'returns cross reference with label id' do
expect(label.to_reference(project, format: :id))
- .to eq %Q(#{label.project.path_with_namespace}~#{label.id})
+ .to eq %Q(#{label.project.full_path}~#{label.id})
end
end
end
diff --git a/spec/models/project_services/asana_service_spec.rb b/spec/models/project_services/asana_service_spec.rb
index 4684c970885..04440d890aa 100644
--- a/spec/models/project_services/asana_service_spec.rb
+++ b/spec/models/project_services/asana_service_spec.rb
@@ -18,7 +18,7 @@ describe AsanaService do
describe 'Execute' do
let(:user) { create(:user) }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
def create_data_for_commits(*messages)
{
diff --git a/spec/models/project_services/bamboo_service_spec.rb b/spec/models/project_services/bamboo_service_spec.rb
index 82f02126de1..85baaccf035 100644
--- a/spec/models/project_services/bamboo_service_spec.rb
+++ b/spec/models/project_services/bamboo_service_spec.rb
@@ -7,7 +7,7 @@ describe BambooService, :use_clean_rails_memory_store_caching do
subject(:service) do
described_class.create(
- project: create(:empty_project),
+ project: create(:project),
properties: {
bamboo_url: bamboo_url,
username: 'mic',
diff --git a/spec/models/project_services/buildkite_service_spec.rb b/spec/models/project_services/buildkite_service_spec.rb
index 3f7eb33e08a..1615a93a4ca 100644
--- a/spec/models/project_services/buildkite_service_spec.rb
+++ b/spec/models/project_services/buildkite_service_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe BuildkiteService, :use_clean_rails_memory_store_caching do
include ReactiveCachingHelpers
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
subject(:service) do
described_class.create(
diff --git a/spec/models/project_services/chat_notification_service_spec.rb b/spec/models/project_services/chat_notification_service_spec.rb
index 413ceed73bf..3aa1039d8bf 100644
--- a/spec/models/project_services/chat_notification_service_spec.rb
+++ b/spec/models/project_services/chat_notification_service_spec.rb
@@ -12,7 +12,7 @@ describe ChatNotificationService do
describe '#can_test?' do
context 'with empty repository' do
it 'returns true' do
- subject.project = create(:empty_project, :empty_repo)
+ subject.project = create(:project, :empty_repo)
expect(subject.can_test?).to be true
end
@@ -20,7 +20,7 @@ describe ChatNotificationService do
context 'with repository' do
it 'returns true' do
- subject.project = create(:project)
+ subject.project = create(:project, :repository)
expect(subject.can_test?).to be true
end
diff --git a/spec/models/project_services/drone_ci_service_spec.rb b/spec/models/project_services/drone_ci_service_spec.rb
index 5b0f24ce306..d8972aff407 100644
--- a/spec/models/project_services/drone_ci_service_spec.rb
+++ b/spec/models/project_services/drone_ci_service_spec.rb
@@ -43,7 +43,7 @@ describe DroneCiService, :use_clean_rails_memory_store_caching do
let(:build_page) { "#{drone_url}/gitlab/#{path}/redirect/commits/#{sha}?branch=#{branch}" }
let(:commit_status_path) { "#{drone_url}/gitlab/#{path}/commits/#{sha}?branch=#{branch}&access_token=#{token}" }
- before(:each) do
+ before do
allow(drone).to receive_messages(
project_id: project.id,
project: project,
diff --git a/spec/models/project_services/external_wiki_service_spec.rb b/spec/models/project_services/external_wiki_service_spec.rb
index 22cd9d5e31e..25e6ce7e804 100644
--- a/spec/models/project_services/external_wiki_service_spec.rb
+++ b/spec/models/project_services/external_wiki_service_spec.rb
@@ -27,7 +27,7 @@ describe ExternalWikiService do
end
describe 'External wiki' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
context 'when it is active' do
before do
diff --git a/spec/models/project_services/gitlab_issue_tracker_service_spec.rb b/spec/models/project_services/gitlab_issue_tracker_service_spec.rb
index d19dab8fd39..3237b660a16 100644
--- a/spec/models/project_services/gitlab_issue_tracker_service_spec.rb
+++ b/spec/models/project_services/gitlab_issue_tracker_service_spec.rb
@@ -8,21 +8,21 @@ describe GitlabIssueTrackerService do
describe 'Validations' do
context 'when service is active' do
- subject { described_class.new(project: create(:empty_project), active: true) }
+ subject { described_class.new(project: create(:project), active: true) }
it { is_expected.to validate_presence_of(:issues_url) }
it_behaves_like 'issue tracker service URL attribute', :issues_url
end
context 'when service is inactive' do
- subject { described_class.new(project: create(:empty_project), active: false) }
+ subject { described_class.new(project: create(:project), active: false) }
it { is_expected.not_to validate_presence_of(:issues_url) }
end
end
describe 'project and issue urls' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:service) { project.create_gitlab_issue_tracker_service(active: true) }
context 'with absolute urls' do
@@ -31,9 +31,9 @@ describe GitlabIssueTrackerService do
end
it 'gives the correct path' do
- expect(service.project_url).to eq("http://#{Gitlab.config.gitlab.host}/gitlab/root/#{project.path_with_namespace}/issues")
- expect(service.new_issue_url).to eq("http://#{Gitlab.config.gitlab.host}/gitlab/root/#{project.path_with_namespace}/issues/new")
- expect(service.issue_url(432)).to eq("http://#{Gitlab.config.gitlab.host}/gitlab/root/#{project.path_with_namespace}/issues/432")
+ expect(service.project_url).to eq("http://#{Gitlab.config.gitlab.host}/gitlab/root/#{project.full_path}/issues")
+ expect(service.new_issue_url).to eq("http://#{Gitlab.config.gitlab.host}/gitlab/root/#{project.full_path}/issues/new")
+ expect(service.issue_url(432)).to eq("http://#{Gitlab.config.gitlab.host}/gitlab/root/#{project.full_path}/issues/432")
end
end
@@ -43,9 +43,9 @@ describe GitlabIssueTrackerService do
end
it 'gives the correct path' do
- expect(service.issue_tracker_path).to eq("/gitlab/root/#{project.path_with_namespace}/issues")
- expect(service.new_issue_path).to eq("/gitlab/root/#{project.path_with_namespace}/issues/new")
- expect(service.issue_path(432)).to eq("/gitlab/root/#{project.path_with_namespace}/issues/432")
+ expect(service.issue_tracker_path).to eq("/gitlab/root/#{project.full_path}/issues")
+ expect(service.new_issue_path).to eq("/gitlab/root/#{project.full_path}/issues/new")
+ expect(service.issue_path(432)).to eq("/gitlab/root/#{project.full_path}/issues/432")
end
end
end
diff --git a/spec/models/project_services/hipchat_service_spec.rb b/spec/models/project_services/hipchat_service_spec.rb
index 7614bb897e8..23db29cb541 100644
--- a/spec/models/project_services/hipchat_service_spec.rb
+++ b/spec/models/project_services/hipchat_service_spec.rb
@@ -36,7 +36,7 @@ describe HipchatService do
Gitlab::DataBuilder::Push.build_sample(project, user)
end
- before(:each) do
+ before do
allow(hipchat).to receive_messages(
project_id: project.id,
project: project,
diff --git a/spec/models/project_services/jira_service_spec.rb b/spec/models/project_services/jira_service_spec.rb
index 8f34b44930e..63bf131cfc5 100644
--- a/spec/models/project_services/jira_service_spec.rb
+++ b/spec/models/project_services/jira_service_spec.rb
@@ -29,7 +29,7 @@ describe JiraService do
context 'validating urls' do
let(:service) do
described_class.new(
- project: create(:empty_project),
+ project: create(:project),
active: true,
username: 'username',
password: 'test',
@@ -74,7 +74,7 @@ describe JiraService do
describe '#close_issue' do
let(:custom_base_url) { 'http://custom_url' }
let(:user) { create(:user) }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:merge_request) { create(:merge_request) }
before do
@@ -135,7 +135,7 @@ describe JiraService do
body: hash_including(
GlobalID: "GitLab",
object: {
- url: "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/commit/#{merge_request.diff_head_sha}",
+ url: "#{Gitlab.config.gitlab.url}/#{project.full_path}/commit/#{merge_request.diff_head_sha}",
title: "GitLab: Solved by commit #{merge_request.diff_head_sha}.",
icon: { title: "GitLab", url16x16: "https://gitlab.com/favicon.ico" },
status: { resolved: true }
@@ -153,13 +153,22 @@ describe JiraService do
expect(WebMock).not_to have_requested(:post, @remote_link_url)
end
+ it "does not send comment or remote links to issues with unknown resolution" do
+ allow_any_instance_of(JIRA::Resource::Issue).to receive(:respond_to?).with(:resolution).and_return(false)
+
+ @jira_service.close_issue(merge_request, ExternalIssue.new("JIRA-123", project))
+
+ expect(WebMock).not_to have_requested(:post, @comment_url)
+ expect(WebMock).not_to have_requested(:post, @remote_link_url)
+ end
+
it "references the GitLab commit/merge request" do
stub_config_setting(base_url: custom_base_url)
@jira_service.close_issue(merge_request, ExternalIssue.new("JIRA-123", project))
expect(WebMock).to have_requested(:post, @comment_url).with(
- body: /#{custom_base_url}\/#{project.path_with_namespace}\/commit\/#{merge_request.diff_head_sha}/
+ body: /#{custom_base_url}\/#{project.full_path}\/commit\/#{merge_request.diff_head_sha}/
).once
end
@@ -174,7 +183,7 @@ describe JiraService do
@jira_service.close_issue(merge_request, ExternalIssue.new("JIRA-123", project))
expect(WebMock).to have_requested(:post, @comment_url).with(
- body: /#{Gitlab.config.gitlab.url}\/#{project.path_with_namespace}\/commit\/#{merge_request.diff_head_sha}/
+ body: /#{Gitlab.config.gitlab.url}\/#{project.full_path}\/commit\/#{merge_request.diff_head_sha}/
).once
end
@@ -233,7 +242,7 @@ describe JiraService do
end
describe "Stored password invalidation" do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
context "when a password was previously set" do
before do
@@ -338,7 +347,7 @@ describe JiraService do
end
describe 'description and title' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
context 'when it is not set' do
before do
@@ -373,7 +382,7 @@ describe JiraService do
end
describe 'project and issue urls' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
context 'when gitlab.yml was initialized' do
before do
diff --git a/spec/models/project_services/mattermost_slash_commands_service_spec.rb b/spec/models/project_services/mattermost_slash_commands_service_spec.rb
index 4c21c8b88bd..522cf15f3ba 100644
--- a/spec/models/project_services/mattermost_slash_commands_service_spec.rb
+++ b/spec/models/project_services/mattermost_slash_commands_service_spec.rb
@@ -4,7 +4,7 @@ describe MattermostSlashCommandsService do
it_behaves_like "chat slash commands service"
context 'Mattermost API' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:service) { project.build_mattermost_slash_commands_service }
let(:user) { create(:user) }
diff --git a/spec/models/project_services/pipelines_email_service_spec.rb b/spec/models/project_services/pipelines_email_service_spec.rb
index 03932895b0e..5faab9ba38b 100644
--- a/spec/models/project_services/pipelines_email_service_spec.rb
+++ b/spec/models/project_services/pipelines_email_service_spec.rb
@@ -1,8 +1,6 @@
require 'spec_helper'
-describe PipelinesEmailService do
- include EmailHelpers
-
+describe PipelinesEmailService, :mailer do
let(:pipeline) do
create(:ci_pipeline, project: project, sha: project.commit('master').sha)
end
@@ -14,10 +12,6 @@ describe PipelinesEmailService do
Gitlab::DataBuilder::Pipeline.build(pipeline)
end
- before do
- reset_delivered_emails!
- end
-
describe 'Validations' do
context 'when service is active' do
before do
diff --git a/spec/models/project_services/slack_slash_commands_service_spec.rb b/spec/models/project_services/slack_slash_commands_service_spec.rb
index aea674c4f6b..0d95f454819 100644
--- a/spec/models/project_services/slack_slash_commands_service_spec.rb
+++ b/spec/models/project_services/slack_slash_commands_service_spec.rb
@@ -5,7 +5,7 @@ describe SlackSlashCommandsService do
describe '#trigger' do
context 'when an auth url is generated' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:params) do
{
team_domain: 'http://domain.tld',
diff --git a/spec/models/project_services/teamcity_service_spec.rb b/spec/models/project_services/teamcity_service_spec.rb
index 47fd0c79e0b..43a0ed99296 100644
--- a/spec/models/project_services/teamcity_service_spec.rb
+++ b/spec/models/project_services/teamcity_service_spec.rb
@@ -7,7 +7,7 @@ describe TeamcityService, :use_clean_rails_memory_store_caching do
subject(:service) do
described_class.create(
- project: create(:empty_project),
+ project: create(:project),
properties: {
teamcity_url: teamcity_url,
username: 'mic',
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index 473b7a88d61..eba71ba2f72 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -82,7 +82,7 @@ describe Project do
end
describe '#members & #requesters' do
- let(:project) { create(:empty_project, :public, :access_requestable) }
+ let(:project) { create(:project, :public, :access_requestable) }
let(:requester) { create(:user) }
let(:developer) { create(:user) }
before do
@@ -131,7 +131,7 @@ describe Project do
end
describe 'validation' do
- let!(:project) { create(:empty_project) }
+ let!(:project) { create(:project) }
it { is_expected.to validate_presence_of(:name) }
it { is_expected.to validate_uniqueness_of(:name).scoped_to(:namespace_id) }
@@ -154,7 +154,7 @@ describe Project do
it { is_expected.to validate_presence_of(:repository_storage) }
it 'does not allow new projects beyond user limits' do
- project2 = build(:empty_project)
+ project2 = build(:project)
allow(project2).to receive(:creator).and_return(double(can_create_project?: false, projects_limit: 0).as_null_object)
expect(project2).not_to be_valid
expect(project2.errors[:limit_reached].first).to match(/Personal project creation is not allowed/)
@@ -163,7 +163,7 @@ describe Project do
describe 'wiki path conflict' do
context "when the new path has been used by the wiki of other Project" do
it 'has an error on the name attribute' do
- new_project = build_stubbed(:empty_project, namespace_id: project.namespace_id, path: "#{project.path}.wiki")
+ new_project = build_stubbed(:project, namespace_id: project.namespace_id, path: "#{project.path}.wiki")
expect(new_project).not_to be_valid
expect(new_project.errors[:name].first).to eq('has already been taken')
@@ -172,8 +172,8 @@ describe Project do
context "when the new wiki path has been used by the path of other Project" do
it 'has an error on the name attribute' do
- project_with_wiki_suffix = create(:empty_project, path: 'foo.wiki')
- new_project = build_stubbed(:empty_project, namespace_id: project_with_wiki_suffix.namespace_id, path: 'foo')
+ project_with_wiki_suffix = create(:project, path: 'foo.wiki')
+ new_project = build_stubbed(:project, namespace_id: project_with_wiki_suffix.namespace_id, path: 'foo')
expect(new_project).not_to be_valid
expect(new_project.errors[:name].first).to eq('has already been taken')
@@ -182,7 +182,7 @@ describe Project do
end
context 'repository storages inclussion' do
- let(:project2) { build(:empty_project, repository_storage: 'missing') }
+ let(:project2) { build(:project, repository_storage: 'missing') }
before do
storages = { 'custom' => { 'path' => 'tmp/tests/custom_repositories' } }
@@ -196,44 +196,44 @@ describe Project do
end
it 'does not allow an invalid URI as import_url' do
- project2 = build(:empty_project, import_url: 'invalid://')
+ project2 = build(:project, import_url: 'invalid://')
expect(project2).not_to be_valid
end
it 'does allow a valid URI as import_url' do
- project2 = build(:empty_project, import_url: 'ssh://test@gitlab.com/project.git')
+ project2 = build(:project, import_url: 'ssh://test@gitlab.com/project.git')
expect(project2).to be_valid
end
it 'allows an empty URI' do
- project2 = build(:empty_project, import_url: '')
+ project2 = build(:project, import_url: '')
expect(project2).to be_valid
end
it 'does not produce import data on an empty URI' do
- project2 = build(:empty_project, import_url: '')
+ project2 = build(:project, import_url: '')
expect(project2.import_data).to be_nil
end
it 'does not produce import data on an invalid URI' do
- project2 = build(:empty_project, import_url: 'test://')
+ project2 = build(:project, import_url: 'test://')
expect(project2.import_data).to be_nil
end
it "does not allow blocked import_url localhost" do
- project2 = build(:empty_project, import_url: 'http://localhost:9000/t.git')
+ project2 = build(:project, import_url: 'http://localhost:9000/t.git')
expect(project2).to be_invalid
expect(project2.errors[:import_url]).to include('imports are not allowed from that URL')
end
it "does not allow blocked import_url port" do
- project2 = build(:empty_project, import_url: 'http://github.com:25/t.git')
+ project2 = build(:project, import_url: 'http://github.com:25/t.git')
expect(project2).to be_invalid
expect(project2.errors[:import_url]).to include('imports are not allowed from that URL')
@@ -241,11 +241,11 @@ describe Project do
describe 'project pending deletion' do
let!(:project_pending_deletion) do
- create(:empty_project,
+ create(:project,
pending_delete: true)
end
let(:new_project) do
- build(:empty_project,
+ build(:project,
name: project_pending_deletion.name,
namespace: project_pending_deletion.namespace)
end
@@ -290,12 +290,12 @@ describe Project do
describe 'project token' do
it 'sets an random token if none provided' do
- project = FactoryGirl.create :empty_project, runners_token: ''
+ project = FactoryGirl.create :project, runners_token: ''
expect(project.runners_token).not_to eq('')
end
it 'does not set an random token if one provided' do
- project = FactoryGirl.create :empty_project, runners_token: 'my-token'
+ project = FactoryGirl.create :project, runners_token: 'my-token'
expect(project.runners_token).to eq('my-token')
end
end
@@ -306,6 +306,7 @@ describe Project do
it { is_expected.to respond_to(:execute_hooks) }
it { is_expected.to respond_to(:owner) }
it { is_expected.to respond_to(:path_with_namespace) }
+ it { is_expected.to respond_to(:full_path) }
end
describe 'delegation' do
@@ -322,7 +323,7 @@ describe Project do
describe '#to_reference' do
let(:owner) { create(:user, name: 'Gitlab') }
let(:namespace) { create(:namespace, path: 'sample-namespace', owner: owner) }
- let(:project) { create(:empty_project, path: 'sample-project', namespace: namespace) }
+ let(:project) { create(:project, path: 'sample-project', namespace: namespace) }
let(:group) { create(:group, name: 'Group', path: 'sample-group', owner: owner) }
context 'when nil argument' do
@@ -346,7 +347,7 @@ describe Project do
end
context 'when cross namespace project argument' do
- let(:another_namespace_project) { create(:empty_project, name: 'another-project') }
+ let(:another_namespace_project) { create(:project, name: 'another-project') }
it 'returns complete path to the project' do
expect(project.to_reference(another_namespace_project)).to eq 'sample-namespace/sample-project'
@@ -354,7 +355,7 @@ describe Project do
end
context 'when same namespace / cross-project argument' do
- let(:another_project) { create(:empty_project, namespace: namespace) }
+ let(:another_project) { create(:project, namespace: namespace) }
it 'returns path to the project' do
expect(project.to_reference(another_project)).to eq 'sample-project'
@@ -363,7 +364,7 @@ describe Project do
context 'when different namespace / cross-project argument' do
let(:another_namespace) { create(:namespace, path: 'another-namespace', owner: owner) }
- let(:another_project) { create(:empty_project, path: 'another-project', namespace: another_namespace) }
+ let(:another_project) { create(:project, path: 'another-project', namespace: another_namespace) }
it 'returns full path to the project' do
expect(project.to_reference(another_project)).to eq 'sample-namespace/sample-project'
@@ -388,7 +389,7 @@ describe Project do
describe '#to_human_reference' do
let(:owner) { create(:user, name: 'Gitlab') }
let(:namespace) { create(:namespace, name: 'Sample namespace', owner: owner) }
- let(:project) { create(:empty_project, name: 'Sample project', namespace: namespace) }
+ let(:project) { create(:project, name: 'Sample project', namespace: namespace) }
context 'when nil argument' do
it 'returns nil' do
@@ -403,7 +404,7 @@ describe Project do
end
context 'when cross namespace project argument' do
- let(:another_namespace_project) { create(:empty_project, name: 'another-project') }
+ let(:another_namespace_project) { create(:project, name: 'another-project') }
it 'returns complete name with namespace of the project' do
expect(project.to_human_reference(another_namespace_project)).to eq 'Gitlab / Sample project'
@@ -411,7 +412,7 @@ describe Project do
end
context 'when same namespace / cross-project argument' do
- let(:another_project) { create(:empty_project, namespace: namespace) }
+ let(:another_project) { create(:project, namespace: namespace) }
it 'returns name of the project' do
expect(project.to_human_reference(another_project)).to eq 'Sample project'
@@ -420,7 +421,7 @@ describe Project do
end
describe '#repository_storage_path' do
- let(:project) { create(:empty_project, repository_storage: 'custom') }
+ let(:project) { create(:project, repository_storage: 'custom') }
before do
FileUtils.mkdir('tmp/tests/custom_repositories')
@@ -443,7 +444,7 @@ describe Project do
end
describe "#web_url" do
- let(:project) { create(:empty_project, path: "somewhere") }
+ let(:project) { create(:project, path: "somewhere") }
it 'returns the full web URL for this repo' do
expect(project.web_url).to eq("#{Gitlab.config.gitlab.url}/#{project.namespace.full_path}/somewhere")
@@ -451,7 +452,7 @@ describe Project do
end
describe "#new_issue_address" do
- let(:project) { create(:empty_project, path: "somewhere") }
+ let(:project) { create(:project, path: "somewhere") }
let(:user) { create(:user) }
context 'incoming email enabled' do
@@ -460,7 +461,7 @@ describe Project do
end
it 'returns the address to create a new issue' do
- address = "p+#{project.path_with_namespace}+#{user.incoming_email_token}@gl.ab"
+ address = "p+#{project.full_path}+#{user.incoming_email_token}@gl.ab"
expect(project.new_issue_address(user)).to eq(address)
end
@@ -480,11 +481,11 @@ describe Project do
describe 'last_activity methods' do
let(:timestamp) { 2.hours.ago }
# last_activity_at gets set to created_at upon creation
- let(:project) { create(:empty_project, created_at: timestamp, updated_at: timestamp) }
+ let(:project) { create(:project, created_at: timestamp, updated_at: timestamp) }
describe 'last_activity' do
it 'alias last_activity to last_event' do
- last_event = create(:event, project: project)
+ last_event = create(:event, :closed, project: project)
expect(project.last_activity).to eq(last_event)
end
@@ -492,7 +493,7 @@ describe Project do
describe 'last_activity_date' do
it 'returns the creation date of the project\'s last event if present' do
- new_event = create(:event, project: project, created_at: Time.now)
+ new_event = create(:event, :closed, project: project, created_at: Time.now)
project.reload
expect(project.last_activity_at.to_i).to eq(new_event.created_at.to_i)
@@ -505,7 +506,7 @@ describe Project do
end
describe '#get_issue' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let!(:issue) { create(:issue, project: project) }
let(:user) { create(:user) }
@@ -580,7 +581,7 @@ describe Project do
end
describe '#issue_exists?' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
it 'is truthy when issue exists' do
expect(project).to receive(:get_issue).and_return(double)
@@ -597,7 +598,7 @@ describe Project do
context 'with namespace' do
before do
@group = create :group, name: 'gitlab'
- @project = create(:empty_project, name: 'gitlabhq', namespace: @group)
+ @project = create(:project, name: 'gitlabhq', namespace: @group)
end
it { expect(@project.to_param).to eq('gitlabhq') }
@@ -605,7 +606,7 @@ describe Project do
context 'with invalid path' do
it 'returns previous path to keep project suitable for use in URLs when persisted' do
- project = create(:empty_project, path: 'gitlab')
+ project = create(:project, path: 'gitlab')
project.path = 'foo&bar'
expect(project).not_to be_valid
@@ -613,7 +614,7 @@ describe Project do
end
it 'returns current path when new record' do
- project = build(:empty_project, path: 'gitlab')
+ project = build(:project, path: 'gitlab')
project.path = 'foo&bar'
expect(project).not_to be_valid
@@ -632,7 +633,7 @@ describe Project do
describe '#default_issues_tracker?' do
it "is true if used internal tracker" do
- project = build(:empty_project)
+ project = build(:project)
expect(project.default_issues_tracker?).to be_truthy
end
@@ -646,11 +647,11 @@ describe Project do
end
describe '#external_issue_tracker' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:ext_project) { create(:redmine_project) }
context 'on existing projects with no value for has_external_issue_tracker' do
- before(:each) do
+ before do
project.update_column(:has_external_issue_tracker, nil)
ext_project.update_column(:has_external_issue_tracker, nil)
end
@@ -681,7 +682,7 @@ describe Project do
end
describe '#cache_has_external_issue_tracker' do
- let(:project) { create(:empty_project, has_external_issue_tracker: nil) }
+ let(:project) { create(:project, has_external_issue_tracker: nil) }
it 'stores true if there is any external_issue_tracker' do
services = double(:service, external_issue_trackers: [RedmineService.new])
@@ -703,9 +704,9 @@ describe Project do
end
describe '#has_wiki?' do
- let(:no_wiki_project) { create(:empty_project, :wiki_disabled, has_external_wiki: false) }
- let(:wiki_enabled_project) { create(:empty_project) }
- let(:external_wiki_project) { create(:empty_project, has_external_wiki: true) }
+ let(:no_wiki_project) { create(:project, :wiki_disabled, has_external_wiki: false) }
+ let(:wiki_enabled_project) { create(:project) }
+ let(:external_wiki_project) { create(:project, has_external_wiki: true) }
it 'returns true if project is wiki enabled or has external wiki' do
expect(wiki_enabled_project).to have_wiki
@@ -715,7 +716,7 @@ describe Project do
end
describe '#external_wiki' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
context 'with an active external wiki' do
before do
@@ -769,7 +770,7 @@ describe Project do
it 'counts stars from multiple users' do
user1 = create :user
user2 = create :user
- project = create(:empty_project, :public)
+ project = create(:project, :public)
expect(project.star_count).to eq(0)
@@ -791,8 +792,8 @@ describe Project do
it 'counts stars on the right project' do
user = create :user
- project1 = create(:empty_project, :public)
- project2 = create(:empty_project, :public)
+ project1 = create(:project, :public)
+ project2 = create(:project, :public)
expect(project1.star_count).to eq(0)
expect(project2.star_count).to eq(0)
@@ -824,7 +825,7 @@ describe Project do
end
describe '#avatar_type' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
it 'is true if avatar is image' do
project.update_attribute(:avatar, 'uploads/avatar.png')
@@ -840,10 +841,10 @@ describe Project do
describe '#avatar_url' do
subject { project.avatar_url }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
context 'when avatar file is uploaded' do
- let(:project) { create(:empty_project, :with_avatar) }
+ let(:project) { create(:project, :with_avatar) }
let(:avatar_path) { "/uploads/-/system/project/avatar/#{project.id}/dk.png" }
let(:gitlab_host) { "http://#{Gitlab.config.gitlab.host}" }
@@ -868,7 +869,7 @@ describe Project do
end
context 'when git repo is empty' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
it { is_expected.to eq nil }
end
@@ -909,7 +910,7 @@ describe Project do
end
describe '#builds_enabled' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
subject { project.builds_enabled }
@@ -920,7 +921,7 @@ describe Project do
subject { described_class.with_shared_runners }
context 'when shared runners are enabled for project' do
- let!(:project) { create(:empty_project, shared_runners_enabled: true) }
+ let!(:project) { create(:project, shared_runners_enabled: true) }
it "returns a project" do
is_expected.to eq([project])
@@ -928,7 +929,7 @@ describe Project do
end
context 'when shared runners are disabled for project' do
- let!(:project) { create(:empty_project, shared_runners_enabled: false) }
+ let!(:project) { create(:project, shared_runners_enabled: false) }
it "returns an empty array" do
is_expected.to be_empty
@@ -938,8 +939,8 @@ describe Project do
describe '.cached_count', :use_clean_rails_memory_store_caching do
let(:group) { create(:group, :public) }
- let!(:project1) { create(:empty_project, :public, group: group) }
- let!(:project2) { create(:empty_project, :public, group: group) }
+ let!(:project1) { create(:project, :public, group: group) }
+ let!(:project2) { create(:project, :public, group: group) }
it 'returns total project count' do
expect(described_class).to receive(:count).once.and_call_original
@@ -952,8 +953,8 @@ describe Project do
describe '.trending' do
let(:group) { create(:group, :public) }
- let(:project1) { create(:empty_project, :public, group: group) }
- let(:project2) { create(:empty_project, :public, group: group) }
+ let(:project1) { create(:project, :public, group: group) }
+ let(:project2) { create(:project, :public, group: group) }
before do
2.times do
@@ -984,9 +985,9 @@ describe Project do
it 'returns only projects starred by the given user' do
user1 = create(:user)
user2 = create(:user)
- project1 = create(:empty_project)
- project2 = create(:empty_project)
- create(:empty_project)
+ project1 = create(:project)
+ project2 = create(:project)
+ create(:project)
user1.toggle_star(project1)
user2.toggle_star(project2)
@@ -995,7 +996,7 @@ describe Project do
end
describe '.visible_to_user' do
- let!(:project) { create(:empty_project, :private) }
+ let!(:project) { create(:project, :private) }
let!(:user) { create(:user) }
subject { described_class.visible_to_user(user) }
@@ -1014,7 +1015,7 @@ describe Project do
end
context 'repository storage by default' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
before do
storages = {
@@ -1032,7 +1033,7 @@ describe Project do
end
context 'shared runners by default' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
subject { project.shared_runners_enabled }
@@ -1054,7 +1055,7 @@ describe Project do
end
describe '#any_runners' do
- let(:project) { create(:empty_project, shared_runners_enabled: shared_runners_enabled) }
+ let(:project) { create(:project, shared_runners_enabled: shared_runners_enabled) }
let(:specific_runner) { create(:ci_runner) }
let(:shared_runner) { create(:ci_runner, :shared) }
@@ -1102,7 +1103,7 @@ describe Project do
subject { project.shared_runners }
context 'when shared runners are enabled for project' do
- let!(:project) { create(:empty_project, shared_runners_enabled: true) }
+ let!(:project) { create(:project, shared_runners_enabled: true) }
it "returns a list of shared runners" do
is_expected.to eq([runner])
@@ -1110,7 +1111,7 @@ describe Project do
end
context 'when shared runners are disabled for project' do
- let!(:project) { create(:empty_project, shared_runners_enabled: false) }
+ let!(:project) { create(:project, shared_runners_enabled: false) }
it "returns a empty list" do
is_expected.to be_empty
@@ -1119,7 +1120,7 @@ describe Project do
end
describe '#visibility_level_allowed?' do
- let(:project) { create(:empty_project, :internal) }
+ let(:project) { create(:project, :internal) }
context 'when checking on non-forked project' do
it { expect(project.visibility_level_allowed?(Gitlab::VisibilityLevel::PRIVATE)).to be_truthy }
@@ -1128,8 +1129,8 @@ describe Project do
end
context 'when checking on forked project' do
- let(:project) { create(:empty_project, :internal) }
- let(:forked_project) { create(:empty_project, forked_from_project: project) }
+ let(:project) { create(:project, :internal) }
+ let(:forked_project) { create(:project, forked_from_project: project) }
it { expect(forked_project.visibility_level_allowed?(Gitlab::VisibilityLevel::PRIVATE)).to be_truthy }
it { expect(forked_project.visibility_level_allowed?(Gitlab::VisibilityLevel::INTERNAL)).to be_truthy }
@@ -1138,7 +1139,7 @@ describe Project do
end
describe '#pages_deployed?' do
- let(:project) { create :empty_project }
+ let(:project) { create :project }
subject { project.pages_deployed? }
@@ -1155,8 +1156,35 @@ describe Project do
end
end
+ describe '#pages_url' do
+ let(:group) { create :group, name: group_name }
+ let(:project) { create :project, namespace: group, name: project_name }
+ let(:domain) { 'Example.com' }
+
+ subject { project.pages_url }
+
+ before do
+ allow(Settings.pages).to receive(:host).and_return(domain)
+ allow(Gitlab.config.pages).to receive(:url).and_return('http://example.com')
+ end
+
+ context 'group page' do
+ let(:group_name) { 'Group' }
+ let(:project_name) { 'group.example.com' }
+
+ it { is_expected.to eq("http://group.example.com") }
+ end
+
+ context 'project page' do
+ let(:group_name) { 'Group' }
+ let(:project_name) { 'Project' }
+
+ it { is_expected.to eq("http://group.example.com/project") }
+ end
+ end
+
describe '.search' do
- let(:project) { create(:empty_project, description: 'kitten mittens') }
+ let(:project) { create(:project, description: 'kitten mittens') }
it 'returns projects with a matching name' do
expect(described_class.search(project.name)).to eq([project])
@@ -1213,7 +1241,7 @@ describe Project do
end
describe 'with pending_delete project' do
- let(:pending_delete_project) { create(:empty_project, pending_delete: true) }
+ let(:pending_delete_project) { create(:project, pending_delete: true) }
it 'shows pending deletion project' do
search_result = described_class.search(pending_delete_project.name)
@@ -1273,7 +1301,7 @@ describe Project do
subject { project.rename_repo }
- it { expect{subject}.to raise_error(StandardError) }
+ it { expect {subject}.to raise_error(StandardError) }
end
end
@@ -1299,7 +1327,7 @@ describe Project do
end
describe '.search_by_title' do
- let(:project) { create(:empty_project, name: 'kittens') }
+ let(:project) { create(:project, name: 'kittens') }
it 'returns projects with a matching name' do
expect(described_class.search_by_title(project.name)).to eq([project])
@@ -1318,8 +1346,8 @@ describe Project do
let(:private_group) { create(:group, visibility_level: 0) }
let(:internal_group) { create(:group, visibility_level: 10) }
- let(:private_project) { create :empty_project, :private, group: private_group }
- let(:internal_project) { create :empty_project, :internal, group: internal_group }
+ let(:private_project) { create :project, :private, group: private_group }
+ let(:internal_project) { create :project, :internal, group: internal_group }
context 'when group is private project can not be internal' do
it { expect(private_project.visibility_level_allowed?(Gitlab::VisibilityLevel::INTERNAL)).to be_falsey }
@@ -1341,7 +1369,7 @@ describe Project do
context 'using a regular repository' do
it 'creates the repository' do
expect(shell).to receive(:add_repository)
- .with(project.repository_storage_path, project.path_with_namespace)
+ .with(project.repository_storage_path, project.disk_path)
.and_return(true)
expect(project.repository).to receive(:after_create)
@@ -1351,7 +1379,7 @@ describe Project do
it 'adds an error if the repository could not be created' do
expect(shell).to receive(:add_repository)
- .with(project.repository_storage_path, project.path_with_namespace)
+ .with(project.repository_storage_path, project.disk_path)
.and_return(false)
expect(project.repository).not_to receive(:after_create)
@@ -1384,7 +1412,7 @@ describe Project do
.and_return(false)
allow(shell).to receive(:add_repository)
- .with(project.repository_storage_path, project.path_with_namespace)
+ .with(project.repository_storage_path, project.disk_path)
.and_return(true)
expect(project).to receive(:create_repository).with(force: true)
@@ -1408,7 +1436,7 @@ describe Project do
.and_return(false)
expect(shell).to receive(:add_repository)
- .with(project.repository_storage_path, project.path_with_namespace)
+ .with(project.repository_storage_path, project.disk_path)
.and_return(true)
project.ensure_repository
@@ -1416,7 +1444,7 @@ describe Project do
end
describe '#user_can_push_to_empty_repo?' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:user) { create(:user) }
it 'returns false when default_branch_protection is in full protection and user is developer' do
@@ -1455,7 +1483,7 @@ describe Project do
end
describe '#container_registry_url' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
subject { project.container_registry_url }
@@ -1482,7 +1510,7 @@ describe Project do
end
describe '#has_container_registry_tags?' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
context 'when container registry is enabled' do
before do
@@ -1546,7 +1574,7 @@ describe Project do
end
describe '#ci_config_path=' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
it 'sets nil' do
project.update!(ci_config_path: nil)
@@ -1568,11 +1596,11 @@ describe Project do
end
describe 'Project import job' do
- let(:project) { create(:empty_project, import_url: generate(:url)) }
+ let(:project) { create(:project, import_url: generate(:url)) }
before do
allow_any_instance_of(Gitlab::Shell).to receive(:import_repository)
- .with(project.repository_storage_path, project.path_with_namespace, project.import_url)
+ .with(project.repository_storage_path, project.disk_path, project.import_url)
.and_return(true)
expect_any_instance_of(Repository).to receive(:after_import)
@@ -1605,7 +1633,7 @@ describe Project do
end
it 'does not perform housekeeping when project repository does not exist' do
- project = create(:empty_project, :import_started, import_type: :github)
+ project = create(:project, :import_started, import_type: :github)
project.import_finish
@@ -1613,7 +1641,7 @@ describe Project do
end
it 'does not perform housekeeping when project does not have a valid import type' do
- project = create(:empty_project, :import_started, import_type: nil)
+ project = create(:project, :import_started, import_type: nil)
project.import_finish
@@ -1710,7 +1738,7 @@ describe Project do
it 'schedules a RepositoryForkWorker job' do
expect(RepositoryForkWorker).to receive(:perform_async)
.with(project.id, forked_from_project.repository_storage_path,
- forked_from_project.path_with_namespace, project.namespace.full_path)
+ forked_from_project.disk_path, project.namespace.full_path)
project.add_import_job
end
@@ -1718,7 +1746,7 @@ describe Project do
context 'not forked' do
it 'schedules a RepositoryImportWorker job' do
- project = create(:empty_project, import_url: generate(:url))
+ project = create(:project, import_url: generate(:url))
expect(RepositoryImportWorker).to receive(:perform_async).with(project.id)
@@ -1728,19 +1756,19 @@ describe Project do
end
describe '#gitlab_project_import?' do
- subject(:project) { build(:empty_project, import_type: 'gitlab_project') }
+ subject(:project) { build(:project, import_type: 'gitlab_project') }
it { expect(project.gitlab_project_import?).to be true }
end
describe '#gitea_import?' do
- subject(:project) { build(:empty_project, import_type: 'gitea') }
+ subject(:project) { build(:project, import_type: 'gitea') }
it { expect(project.gitea_import?).to be true }
end
describe '#lfs_enabled?' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
shared_examples 'project overrides group' do
it 'returns true when enabled in project' do
@@ -1804,6 +1832,11 @@ describe Project do
describe '#change_head' do
let(:project) { create(:project, :repository) }
+ it 'returns error if branch does not exist' do
+ expect(project.change_head('unexisted-branch')).to be false
+ expect(project.errors.size).to eq(1)
+ end
+
it 'calls the before_change_head and after_change_head methods' do
expect(project.repository).to receive(:before_change_head)
expect(project.repository).to receive(:after_change_head)
@@ -1830,7 +1863,7 @@ describe Project do
end
describe '#pushes_since_gc' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
after do
project.reset_pushes_since_gc
@@ -1852,7 +1885,7 @@ describe Project do
end
describe '#increment_pushes_since_gc' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
after do
project.reset_pushes_since_gc
@@ -1866,7 +1899,7 @@ describe Project do
end
describe '#reset_pushes_since_gc' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
after do
project.reset_pushes_since_gc
@@ -1883,7 +1916,7 @@ describe Project do
describe '#deployment_variables' do
context 'when project has no deployment service' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
it 'returns an empty array' do
expect(project.deployment_variables).to eq []
@@ -1902,7 +1935,7 @@ describe Project do
end
describe '#secret_variables_for' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let!(:secret_variable) do
create(:ci_variable, value: 'secret', project: project)
@@ -1949,7 +1982,7 @@ describe Project do
end
describe '#protected_for?' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
subject { project.protected_for?('ref') }
@@ -1986,7 +2019,7 @@ describe Project do
end
describe '#update_project_statistics' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
it "is called after creation" do
expect(project.statistics).to be_a ProjectStatistics
@@ -2006,9 +2039,9 @@ describe Project do
end
describe 'inside_path' do
- let!(:project1) { create(:empty_project, namespace: create(:namespace, path: 'name_pace')) }
- let!(:project2) { create(:empty_project) }
- let!(:project3) { create(:empty_project, namespace: create(:namespace, path: 'namespace')) }
+ let!(:project1) { create(:project, namespace: create(:namespace, path: 'name_pace')) }
+ let!(:project2) { create(:project) }
+ let!(:project3) { create(:project, namespace: create(:namespace, path: 'namespace')) }
let!(:path) { project1.namespace.full_path }
it 'returns correct project' do
@@ -2017,7 +2050,7 @@ describe Project do
end
describe '#route_map_for' do
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:route_map) do
<<-MAP.strip_heredoc
- source: /source/(.*)/
@@ -2054,7 +2087,7 @@ describe Project do
end
describe '#public_path_for_source_path' do
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:route_map) do
Gitlab::RouteMap.new(<<-MAP.strip_heredoc)
- source: /source/(.*)/
@@ -2093,13 +2126,13 @@ describe Project do
end
describe '#parent' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
it { expect(project.parent).to eq(project.namespace) }
end
describe '#parent_changed?' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
before do
project.namespace_id = 7
@@ -2125,7 +2158,7 @@ describe Project do
end
context 'top-level group' do
- let(:project) { create :empty_project, namespace: group, name: project_name }
+ let(:project) { create :project, namespace: group, name: project_name }
context 'group page' do
let(:project_name) { 'group.example.com' }
@@ -2141,7 +2174,7 @@ describe Project do
end
context 'nested group' do
- let(:project) { create :empty_project, namespace: nested_group, name: project_name }
+ let(:project) { create :project, namespace: nested_group, name: project_name }
let(:expected_url) { "http://group.example.com/#{nested_group.path}/#{project.path}" }
context 'group page' do
@@ -2159,7 +2192,7 @@ describe Project do
end
describe '#http_url_to_repo' do
- let(:project) { create :empty_project }
+ let(:project) { create :project }
it 'returns the url to the repo without a username' do
expect(project.http_url_to_repo).to eq("#{project.web_url}.git")
@@ -2168,7 +2201,7 @@ describe Project do
end
describe '#pipeline_status' do
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
it 'builds a pipeline status' do
expect(project.pipeline_status).to be_a(Gitlab::Cache::Ci::ProjectPipelineStatus)
end
@@ -2199,7 +2232,7 @@ describe Project do
describe '#last_repository_updated_at' do
it 'sets to created_at upon creation' do
- project = create(:empty_project, created_at: 2.hours.ago)
+ project = create(:project, created_at: 2.hours.ago)
expect(project.last_repository_updated_at.to_i).to eq(project.created_at.to_i)
end
@@ -2209,10 +2242,10 @@ describe Project do
let!(:user) { create(:user) }
let!(:private_project) do
- create(:empty_project, :private, creator: user, namespace: user.namespace)
+ create(:project, :private, creator: user, namespace: user.namespace)
end
- let!(:public_project) { create(:empty_project, :public) }
+ let!(:public_project) { create(:project, :public) }
context 'with a user' do
let(:projects) do
@@ -2238,19 +2271,53 @@ describe Project do
end
describe '#remove_private_deploy_keys' do
- it 'removes the private deploy keys of a project' do
- project = create(:empty_project)
+ let!(:project) { create(:project) }
+
+ context 'for a private deploy key' do
+ let!(:key) { create(:deploy_key, public: false) }
+ let!(:deploy_keys_project) { create(:deploy_keys_project, deploy_key: key, project: project) }
+
+ context 'when the key is not linked to another project' do
+ it 'removes the key' do
+ project.remove_private_deploy_keys
- private_key = create(:deploy_key, public: false)
- public_key = create(:deploy_key, public: true)
+ expect(project.deploy_keys).not_to include(key)
+ end
+ end
+
+ context 'when the key is linked to another project' do
+ before do
+ another_project = create(:project)
+ create(:deploy_keys_project, deploy_key: key, project: another_project)
+ end
+
+ it 'does not remove the key' do
+ project.remove_private_deploy_keys
+
+ expect(project.deploy_keys).to include(key)
+ end
+ end
+ end
+
+ context 'for a public deploy key' do
+ let!(:key) { create(:deploy_key, public: true) }
+ let!(:deploy_keys_project) { create(:deploy_keys_project, deploy_key: key, project: project) }
+
+ it 'does not remove the key' do
+ project.remove_private_deploy_keys
+
+ expect(project.deploy_keys).to include(key)
+ end
+ end
+ end
- create(:deploy_keys_project, deploy_key: private_key, project: project)
- create(:deploy_keys_project, deploy_key: public_key, project: project)
+ describe '#forks_count' do
+ it 'returns the number of forks' do
+ project = build(:project)
- project.remove_private_deploy_keys
+ allow(project.forks).to receive(:count).and_return(1)
- expect(project.deploy_keys.where(public: false).any?).to eq(false)
- expect(project.deploy_keys.where(public: true).any?).to eq(true)
+ expect(project.forks_count).to eq(1)
end
end
end
diff --git a/spec/models/project_statistics_spec.rb b/spec/models/project_statistics_spec.rb
index be1b37730b1..59e20e84c2f 100644
--- a/spec/models/project_statistics_spec.rb
+++ b/spec/models/project_statistics_spec.rb
@@ -1,7 +1,7 @@
require 'rails_helper'
describe ProjectStatistics do
- let(:project) { create :empty_project }
+ let(:project) { create :project }
let(:statistics) { project.statistics }
describe 'constants' do
diff --git a/spec/models/project_team_spec.rb b/spec/models/project_team_spec.rb
index 68228a038a8..314824b32da 100644
--- a/spec/models/project_team_spec.rb
+++ b/spec/models/project_team_spec.rb
@@ -7,7 +7,7 @@ describe ProjectTeam do
let(:nonmember) { create(:user) }
context 'personal project' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
before do
project.add_master(master)
@@ -37,7 +37,7 @@ describe ProjectTeam do
context 'group project' do
let(:group) { create(:group) }
- let!(:project) { create(:empty_project, group: group) }
+ let!(:project) { create(:project, group: group) }
before do
group.add_master(master)
@@ -75,7 +75,7 @@ describe ProjectTeam do
describe '#fetch_members' do
context 'personal project' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
it 'returns project members' do
user = create(:user)
@@ -119,7 +119,7 @@ describe ProjectTeam do
context 'group project' do
let(:group) { create(:group) }
- let!(:project) { create(:empty_project, group: group) }
+ let!(:project) { create(:project, group: group) }
it 'returns project members' do
group_member = create(:group_member, group: group)
@@ -139,7 +139,7 @@ describe ProjectTeam do
describe '#find_member' do
context 'personal project' do
let(:project) do
- create(:empty_project, :public, :access_requestable)
+ create(:project, :public, :access_requestable)
end
let(:requester) { create(:user) }
@@ -160,7 +160,7 @@ describe ProjectTeam do
context 'group project' do
let(:group) { create(:group, :access_requestable) }
- let(:project) { create(:empty_project, group: group) }
+ let(:project) { create(:project, group: group) }
let(:requester) { create(:user) }
before do
@@ -182,7 +182,7 @@ describe ProjectTeam do
it 'returns Master role' do
user = create(:user)
group = create(:group)
- project = create(:empty_project, namespace: group)
+ project = create(:project, namespace: group)
group.add_master(user)
@@ -192,7 +192,7 @@ describe ProjectTeam do
it 'returns Owner role' do
user = create(:user)
group = create(:group)
- project = create(:empty_project, namespace: group)
+ project = create(:project, namespace: group)
group.add_owner(user)
@@ -205,7 +205,7 @@ describe ProjectTeam do
context 'personal project' do
let(:project) do
- create(:empty_project, :public, :access_requestable)
+ create(:project, :public, :access_requestable)
end
context 'when project is not shared with group' do
@@ -253,7 +253,7 @@ describe ProjectTeam do
context 'group project' do
let(:group) { create(:group, :access_requestable) }
let!(:project) do
- create(:empty_project, group: group)
+ create(:project, group: group)
end
before do
@@ -277,15 +277,15 @@ describe ProjectTeam do
let(:master) { create(:user) }
let(:personal_project) do
- create(:empty_project, namespace: developer.namespace)
+ create(:project, namespace: developer.namespace)
end
let(:group_project) do
- create(:empty_project, namespace: group)
+ create(:project, namespace: group)
end
- let(:members_project) { create(:empty_project) }
- let(:shared_project) { create(:empty_project) }
+ let(:members_project) { create(:project) }
+ let(:shared_project) { create(:project) }
before do
group.add_master(master)
diff --git a/spec/models/project_wiki_spec.rb b/spec/models/project_wiki_spec.rb
index c6ceb092810..953df7746eb 100644
--- a/spec/models/project_wiki_spec.rb
+++ b/spec/models/project_wiki_spec.rb
@@ -1,7 +1,7 @@
require "spec_helper"
describe ProjectWiki do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:repository) { project.repository }
let(:user) { project.owner }
let(:gitlab_shell) { Gitlab::Shell.new }
@@ -15,19 +15,23 @@ describe ProjectWiki do
describe "#path_with_namespace" do
it "returns the project path with namespace with the .wiki extension" do
- expect(subject.path_with_namespace).to eq(project.path_with_namespace + ".wiki")
+ expect(subject.path_with_namespace).to eq(project.full_path + '.wiki')
+ end
+
+ it 'returns the same value as #full_path' do
+ expect(subject.path_with_namespace).to eq(subject.full_path)
end
end
describe '#web_url' do
it 'returns the full web URL to the wiki' do
- expect(subject.web_url).to eq("#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/wikis/home")
+ expect(subject.web_url).to eq("#{Gitlab.config.gitlab.url}/#{project.full_path}/wikis/home")
end
end
describe "#url_to_repo" do
it "returns the correct ssh url to the repo" do
- expect(subject.url_to_repo).to eq(gitlab_shell.url_to_repo(subject.path_with_namespace))
+ expect(subject.url_to_repo).to eq(gitlab_shell.url_to_repo(subject.full_path))
end
end
@@ -38,10 +42,10 @@ describe ProjectWiki do
end
describe "#http_url_to_repo" do
- let(:project) { create :empty_project }
+ let(:project) { create :project }
it 'returns the full http url to the repo' do
- expected_url = "#{Gitlab.config.gitlab.url}/#{subject.path_with_namespace}.git"
+ expected_url = "#{Gitlab.config.gitlab.url}/#{subject.full_path}.git"
expect(project_wiki.http_url_to_repo).to eq(expected_url)
expect(project_wiki.http_url_to_repo).not_to include('@')
@@ -50,7 +54,7 @@ describe ProjectWiki do
describe "#wiki_base_path" do
it "returns the wiki base path" do
- wiki_base_path = "#{Gitlab.config.gitlab.relative_url_root}/#{project.path_with_namespace}/wikis"
+ wiki_base_path = "#{Gitlab.config.gitlab.relative_url_root}/#{project.full_path}/wikis"
expect(subject.wiki_base_path).to eq(wiki_base_path)
end
@@ -77,7 +81,7 @@ describe ProjectWiki do
allow_any_instance_of(Gitlab::Shell).to receive(:add_repository) do
create_temp_repo("#{Rails.root}/tmp/test-git-base-path/non-existant.wiki.git")
end
- allow(project).to receive(:path_with_namespace).and_return("non-existant")
+ allow(project).to receive(:full_path).and_return("non-existant")
end
describe '#empty?' do
@@ -219,7 +223,12 @@ describe ProjectWiki do
before do
create_page("update-page", "some content")
@gollum_page = subject.wiki.paged("update-page")
- subject.update_page(@gollum_page, "some other content", :markdown, "updated page")
+ subject.update_page(
+ @gollum_page,
+ content: "some other content",
+ format: :markdown,
+ message: "updated page"
+ )
@page = subject.pages.first.page
end
@@ -236,7 +245,12 @@ describe ProjectWiki do
end
it 'updates project activity' do
- subject.update_page(@gollum_page, 'Yet more content', :markdown, 'Updated page again')
+ subject.update_page(
+ @gollum_page,
+ content: 'Yet more content',
+ format: :markdown,
+ message: 'Updated page again'
+ )
project.reload
@@ -269,7 +283,7 @@ describe ProjectWiki do
describe '#create_repo!' do
it 'creates a repository' do
expect(subject).to receive(:init_repo)
- .with(subject.path_with_namespace)
+ .with(subject.full_path)
.and_return(true)
expect(subject.repository).to receive(:after_create)
diff --git a/spec/models/protected_branch_spec.rb b/spec/models/protected_branch_spec.rb
index a54af3bfe59..4c677200ae2 100644
--- a/spec/models/protected_branch_spec.rb
+++ b/spec/models/protected_branch_spec.rb
@@ -163,7 +163,7 @@ describe ProtectedBranch do
end
context "new project" do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
it 'returns false when default_protected_branch is unprotected' do
stub_application_setting(default_branch_protection: Gitlab::Access::PROTECTION_NONE)
diff --git a/spec/models/push_event_payload_spec.rb b/spec/models/push_event_payload_spec.rb
new file mode 100644
index 00000000000..a049ad35584
--- /dev/null
+++ b/spec/models/push_event_payload_spec.rb
@@ -0,0 +1,16 @@
+require 'spec_helper'
+
+describe PushEventPayload do
+ describe 'saving payloads' do
+ it 'does not allow commit messages longer than 70 characters' do
+ event = create(:push_event)
+ payload = build(:push_event_payload, event: event)
+
+ expect(payload).to be_valid
+
+ payload.commit_title = 'a' * 100
+
+ expect(payload).not_to be_valid
+ end
+ end
+end
diff --git a/spec/models/push_event_spec.rb b/spec/models/push_event_spec.rb
new file mode 100644
index 00000000000..532fb024261
--- /dev/null
+++ b/spec/models/push_event_spec.rb
@@ -0,0 +1,202 @@
+require 'spec_helper'
+
+describe PushEvent do
+ let(:payload) { PushEventPayload.new }
+
+ let(:event) do
+ event = described_class.new
+
+ allow(event).to receive(:push_event_payload).and_return(payload)
+
+ event
+ end
+
+ describe '.sti_name' do
+ it 'returns Event::PUSHED' do
+ expect(described_class.sti_name).to eq(Event::PUSHED)
+ end
+ end
+
+ describe '#push?' do
+ it 'returns true' do
+ expect(event).to be_push
+ end
+ end
+
+ describe '#push_with_commits?' do
+ it 'returns true when both the first and last commit are present' do
+ allow(event).to receive(:commit_from).and_return('123')
+ allow(event).to receive(:commit_to).and_return('456')
+
+ expect(event).to be_push_with_commits
+ end
+
+ it 'returns false when the first commit is missing' do
+ allow(event).to receive(:commit_to).and_return('456')
+
+ expect(event).not_to be_push_with_commits
+ end
+
+ it 'returns false when the last commit is missing' do
+ allow(event).to receive(:commit_from).and_return('123')
+
+ expect(event).not_to be_push_with_commits
+ end
+ end
+
+ describe '#tag?' do
+ it 'returns true when pushing to a tag' do
+ allow(payload).to receive(:tag?).and_return(true)
+
+ expect(event).to be_tag
+ end
+
+ it 'returns false when pushing to a branch' do
+ allow(payload).to receive(:tag?).and_return(false)
+
+ expect(event).not_to be_tag
+ end
+ end
+
+ describe '#branch?' do
+ it 'returns true when pushing to a branch' do
+ allow(payload).to receive(:branch?).and_return(true)
+
+ expect(event).to be_branch
+ end
+
+ it 'returns false when pushing to a tag' do
+ allow(payload).to receive(:branch?).and_return(false)
+
+ expect(event).not_to be_branch
+ end
+ end
+
+ describe '#valid_push?' do
+ it 'returns true if a ref exists' do
+ allow(payload).to receive(:ref).and_return('master')
+
+ expect(event).to be_valid_push
+ end
+
+ it 'returns false when no ref is present' do
+ expect(event).not_to be_valid_push
+ end
+ end
+
+ describe '#new_ref?' do
+ it 'returns true when pushing a new ref' do
+ allow(payload).to receive(:created?).and_return(true)
+
+ expect(event).to be_new_ref
+ end
+
+ it 'returns false when pushing to an existing ref' do
+ allow(payload).to receive(:created?).and_return(false)
+
+ expect(event).not_to be_new_ref
+ end
+ end
+
+ describe '#rm_ref?' do
+ it 'returns true when removing an existing ref' do
+ allow(payload).to receive(:removed?).and_return(true)
+
+ expect(event).to be_rm_ref
+ end
+
+ it 'returns false when pushing to an existing ref' do
+ allow(payload).to receive(:removed?).and_return(false)
+
+ expect(event).not_to be_rm_ref
+ end
+ end
+
+ describe '#commit_from' do
+ it 'returns the first commit SHA' do
+ allow(payload).to receive(:commit_from).and_return('123')
+
+ expect(event.commit_from).to eq('123')
+ end
+ end
+
+ describe '#commit_to' do
+ it 'returns the last commit SHA' do
+ allow(payload).to receive(:commit_to).and_return('123')
+
+ expect(event.commit_to).to eq('123')
+ end
+ end
+
+ describe '#ref_name' do
+ it 'returns the name of the ref' do
+ allow(payload).to receive(:ref).and_return('master')
+
+ expect(event.ref_name).to eq('master')
+ end
+ end
+
+ describe '#ref_type' do
+ it 'returns the type of the ref' do
+ allow(payload).to receive(:ref_type).and_return('branch')
+
+ expect(event.ref_type).to eq('branch')
+ end
+ end
+
+ describe '#branch_name' do
+ it 'returns the name of the branch' do
+ allow(payload).to receive(:ref).and_return('master')
+
+ expect(event.branch_name).to eq('master')
+ end
+ end
+
+ describe '#tag_name' do
+ it 'returns the name of the tag' do
+ allow(payload).to receive(:ref).and_return('1.2')
+
+ expect(event.tag_name).to eq('1.2')
+ end
+ end
+
+ describe '#commit_title' do
+ it 'returns the commit message' do
+ allow(payload).to receive(:commit_title).and_return('foo')
+
+ expect(event.commit_title).to eq('foo')
+ end
+ end
+
+ describe '#commit_id' do
+ it 'returns the SHA of the last commit if present' do
+ allow(event).to receive(:commit_to).and_return('123')
+
+ expect(event.commit_id).to eq('123')
+ end
+
+ it 'returns the SHA of the first commit if the last commit is not present' do
+ allow(event).to receive(:commit_to).and_return(nil)
+ allow(event).to receive(:commit_from).and_return('123')
+
+ expect(event.commit_id).to eq('123')
+ end
+ end
+
+ describe '#commits_count' do
+ it 'returns the number of commits' do
+ allow(payload).to receive(:commit_count).and_return(1)
+
+ expect(event.commits_count).to eq(1)
+ end
+ end
+
+ describe '#validate_push_action' do
+ it 'adds an error when the action is not PUSHED' do
+ event.action = Event::CREATED
+ event.validate_push_action
+
+ expect(event.errors.count).to eq(1)
+ end
+ end
+end
diff --git a/spec/models/redirect_route_spec.rb b/spec/models/redirect_route_spec.rb
index 80943877095..106ae59af29 100644
--- a/spec/models/redirect_route_spec.rb
+++ b/spec/models/redirect_route_spec.rb
@@ -20,8 +20,16 @@ describe RedirectRoute do
let!(:redirect4) { group.redirect_routes.create(path: 'gitlabb/test/foo/bar') }
let!(:redirect5) { group.redirect_routes.create(path: 'gitlabb/test/baz') }
- it 'returns correct routes' do
- expect(described_class.matching_path_and_descendants('gitlabb/test')).to match_array([redirect2, redirect3, redirect4, redirect5])
+ context 'when the redirect route matches with same casing' do
+ it 'returns correct routes' do
+ expect(described_class.matching_path_and_descendants('gitlabb/test')).to match_array([redirect2, redirect3, redirect4, redirect5])
+ end
+ end
+
+ context 'when the redirect route matches with different casing' do
+ it 'returns correct routes' do
+ expect(described_class.matching_path_and_descendants('GitLABB/test')).to match_array([redirect2, redirect3, redirect4, redirect5])
+ end
end
end
end
diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb
index 07ed66e127a..4926d5d6c49 100644
--- a/spec/models/repository_spec.rb
+++ b/spec/models/repository_spec.rb
@@ -1,11 +1,12 @@
require 'spec_helper'
-describe Repository do
+describe Repository, models: true do
include RepoHelpers
TestBlob = Struct.new(:path)
let(:project) { create(:project, :repository) }
let(:repository) { project.repository }
+ let(:broken_repository) { create(:project, :broken_storage).repository }
let(:user) { create(:user) }
let(:commit_options) do
@@ -27,12 +28,27 @@ describe Repository do
let(:author_email) { 'user@example.org' }
let(:author_name) { 'John Doe' }
+ def expect_to_raise_storage_error
+ expect { yield }.to raise_error do |exception|
+ storage_exceptions = [Gitlab::Git::Storage::Inaccessible, Gitlab::Git::CommandError, GRPC::Unavailable]
+ expect(exception.class).to be_in(storage_exceptions)
+ end
+ end
+
describe '#branch_names_contains' do
subject { repository.branch_names_contains(sample_commit.id) }
it { is_expected.to include('master') }
it { is_expected.not_to include('feature') }
it { is_expected.not_to include('fix') }
+
+ describe 'when storage is broken', broken_storage: true do
+ it 'should raise a storage error' do
+ expect_to_raise_storage_error do
+ broken_repository.branch_names_contains(sample_commit.id)
+ end
+ end
+ end
end
describe '#tag_names_contains' do
@@ -139,24 +155,60 @@ describe Repository do
end
describe '#last_commit_for_path' do
- subject { repository.last_commit_for_path(sample_commit.id, '.gitignore').id }
+ shared_examples 'getting last commit for path' do
+ subject { repository.last_commit_for_path(sample_commit.id, '.gitignore').id }
+
+ it { is_expected.to eq('c1acaa58bbcbc3eafe538cb8274ba387047b69f8') }
+
+ describe 'when storage is broken', broken_storage: true do
+ it 'should raise a storage error' do
+ expect_to_raise_storage_error do
+ broken_repository.last_commit_id_for_path(sample_commit.id, '.gitignore')
+ end
+ end
+ end
+ end
+
+ context 'when Gitaly feature last_commit_for_path is enabled' do
+ it_behaves_like 'getting last commit for path'
+ end
- it { is_expected.to eq('c1acaa58bbcbc3eafe538cb8274ba387047b69f8') }
+ context 'when Gitaly feature last_commit_for_path is disabled', skip_gitaly_mock: true do
+ it_behaves_like 'getting last commit for path'
+ end
end
describe '#last_commit_id_for_path' do
- subject { repository.last_commit_id_for_path(sample_commit.id, '.gitignore') }
+ shared_examples 'getting last commit ID for path' do
+ subject { repository.last_commit_id_for_path(sample_commit.id, '.gitignore') }
+
+ it "returns last commit id for a given path" do
+ is_expected.to eq('c1acaa58bbcbc3eafe538cb8274ba387047b69f8')
+ end
+
+ it "caches last commit id for a given path" do
+ cache = repository.send(:cache)
+ key = "last_commit_id_for_path:#{sample_commit.id}:#{Digest::SHA1.hexdigest('.gitignore')}"
- it "returns last commit id for a given path" do
- is_expected.to eq('c1acaa58bbcbc3eafe538cb8274ba387047b69f8')
+ expect(cache).to receive(:fetch).with(key).and_return('c1acaa5')
+ is_expected.to eq('c1acaa5')
+ end
+
+ describe 'when storage is broken', broken_storage: true do
+ it 'should raise a storage error' do
+ expect_to_raise_storage_error do
+ broken_repository.last_commit_for_path(sample_commit.id, '.gitignore').id
+ end
+ end
+ end
end
- it "caches last commit id for a given path" do
- cache = repository.send(:cache)
- key = "last_commit_id_for_path:#{sample_commit.id}:#{Digest::SHA1.hexdigest('.gitignore')}"
+ context 'when Gitaly feature last_commit_for_path is enabled' do
+ it_behaves_like 'getting last commit ID for path'
+ end
- expect(cache).to receive(:fetch).with(key).and_return('c1acaa5')
- is_expected.to eq('c1acaa5')
+ context 'when Gitaly feature last_commit_for_path is disabled', skip_gitaly_mock: true do
+ it_behaves_like 'getting last commit ID for path'
end
end
@@ -182,19 +234,37 @@ describe Repository do
end
describe '#find_commits_by_message' do
- it 'returns commits with messages containing a given string' do
- commit_ids = repository.find_commits_by_message('submodule').map(&:id)
+ shared_examples 'finding commits by message' do
+ it 'returns commits with messages containing a given string' do
+ commit_ids = repository.find_commits_by_message('submodule').map(&:id)
+
+ expect(commit_ids).to include(
+ '5937ac0a7beb003549fc5fd26fc247adbce4a52e',
+ '6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9',
+ 'cfe32cf61b73a0d5e9f13e774abde7ff789b1660'
+ )
+ expect(commit_ids).not_to include('913c66a37b4a45b9769037c55c2d238bd0942d2e')
+ end
+
+ it 'is case insensitive' do
+ commit_ids = repository.find_commits_by_message('SUBMODULE').map(&:id)
+
+ expect(commit_ids).to include('5937ac0a7beb003549fc5fd26fc247adbce4a52e')
+ end
+ end
- expect(commit_ids).to include('5937ac0a7beb003549fc5fd26fc247adbce4a52e')
- expect(commit_ids).to include('6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9')
- expect(commit_ids).to include('cfe32cf61b73a0d5e9f13e774abde7ff789b1660')
- expect(commit_ids).not_to include('913c66a37b4a45b9769037c55c2d238bd0942d2e')
+ context 'when Gitaly commits_by_message feature is enabled' do
+ it_behaves_like 'finding commits by message'
end
- it 'is case insensitive' do
- commit_ids = repository.find_commits_by_message('SUBMODULE').map(&:id)
+ context 'when Gitaly commits_by_message feature is disabled', skip_gitaly_mock: true do
+ it_behaves_like 'finding commits by message'
+ end
- expect(commit_ids).to include('5937ac0a7beb003549fc5fd26fc247adbce4a52e')
+ describe 'when storage is broken', broken_storage: true do
+ it 'should raise a storage error' do
+ expect_to_raise_storage_error { broken_repository.find_commits_by_message('s') }
+ end
end
end
@@ -300,7 +370,7 @@ describe Repository do
end
context "when committing to another project" do
- let(:forked_project) { create(:project) }
+ let(:forked_project) { create(:project, :repository) }
it "creates a fork and commit to the forked project" do
expect do
@@ -515,12 +585,20 @@ describe Repository do
end
it 'properly handles query when repo is empty' do
- repository = create(:empty_project).repository
+ repository = create(:project).repository
results = repository.search_files_by_content('test', 'master')
expect(results).to match_array([])
end
+ describe 'when storage is broken', broken_storage: true do
+ it 'should raise a storage error' do
+ expect_to_raise_storage_error do
+ broken_repository.search_files_by_content('feature', 'master')
+ end
+ end
+ end
+
describe 'result' do
subject { results.first }
@@ -543,12 +621,28 @@ describe Repository do
end
it 'properly handles query when repo is empty' do
- repository = create(:empty_project).repository
+ repository = create(:project).repository
results = repository.search_files_by_name('test', 'master')
expect(results).to match_array([])
end
+
+ describe 'when storage is broken', broken_storage: true do
+ it 'should raise a storage error' do
+ expect_to_raise_storage_error { broken_repository.search_files_by_name('files', 'master') }
+ end
+ end
+ end
+
+ describe '#fetch_ref' do
+ describe 'when storage is broken', broken_storage: true do
+ it 'should raise a storage error' do
+ path = broken_repository.path_to_repo
+
+ expect_to_raise_storage_error { broken_repository.fetch_ref(path, '1', '2') }
+ end
+ end
end
describe '#create_ref' do
@@ -867,6 +961,27 @@ describe Repository do
end
end
+ context 'when temporary ref failed to be created from other project' do
+ let(:target_project) { create(:project, :empty_repo) }
+
+ before do
+ expect(target_project.repository).to receive(:run_git)
+ end
+
+ it 'raises Rugged::ReferenceError' do
+ raise_reference_error = raise_error(Rugged::ReferenceError) do |err|
+ expect(err.cause).to be_nil
+ end
+
+ expect do
+ GitOperationService.new(user, target_project.repository)
+ .with_branch('feature',
+ start_project: project,
+ &:itself)
+ end.to raise_reference_error
+ end
+ end
+
context 'when the update adds more than one commit' do
let(:old_rev) { '33f3729a45c02fc67d00adb1b8bca394b0e761d9' }
@@ -942,7 +1057,7 @@ describe Repository do
end
it 'expires creation and branch cache' do
- empty_repository = create(:empty_project, :empty_repo).repository
+ empty_repository = create(:project, :empty_repo).repository
expect(empty_repository).to receive(:expire_exists_cache)
expect(empty_repository).to receive(:expire_root_ref_cache)
@@ -962,10 +1077,16 @@ describe Repository do
end
it 'returns false if no full path can be constructed' do
- allow(repository).to receive(:path_with_namespace).and_return(nil)
+ allow(repository).to receive(:full_path).and_return(nil)
expect(repository.exists?).to eq(false)
end
+
+ context 'with broken storage', broken_storage: true do
+ it 'should raise a storage error' do
+ expect_to_raise_storage_error { broken_repository.exists? }
+ end
+ end
end
describe '#exists?' do
@@ -1124,7 +1245,7 @@ describe Repository do
end
describe 'skip_merges option' do
- subject { repository.commits(Gitlab::Git::BRANCH_REF_PREFIX + "'test'", limit: 100, skip_merges: true).map{ |k| k.id } }
+ subject { repository.commits(Gitlab::Git::BRANCH_REF_PREFIX + "'test'", limit: 100, skip_merges: true).map { |k| k.id } }
it { is_expected.not_to include('e56497bb5f03a90a51293fc6d516788730953899') }
end
@@ -1804,7 +1925,7 @@ describe Repository do
end
describe '#commit_count_for_ref' do
- let(:project) { create :empty_project }
+ let(:project) { create :project }
context 'with a non-existing repository' do
it 'returns 0' do
diff --git a/spec/models/route_spec.rb b/spec/models/route_spec.rb
index bdacc60fb53..fece370c03f 100644
--- a/spec/models/route_spec.rb
+++ b/spec/models/route_spec.rb
@@ -145,45 +145,71 @@ describe Route do
describe '#delete_conflicting_redirects' do
context 'when a redirect route with the same path exists' do
- let!(:redirect1) { route.create_redirect(route.path) }
+ context 'when the redirect route has matching case' do
+ let!(:redirect1) { route.create_redirect(route.path) }
- it 'deletes the redirect' do
- route.delete_conflicting_redirects
- expect(route.conflicting_redirects).to be_empty
+ it 'deletes the redirect' do
+ expect do
+ route.delete_conflicting_redirects
+ end.to change { RedirectRoute.count }.by(-1)
+ end
+
+ context 'when redirect routes with paths descending from the route path exists' do
+ let!(:redirect2) { route.create_redirect("#{route.path}/foo") }
+ let!(:redirect3) { route.create_redirect("#{route.path}/foo/bar") }
+ let!(:redirect4) { route.create_redirect("#{route.path}/baz/quz") }
+ let!(:other_redirect) { route.create_redirect("other") }
+
+ it 'deletes all redirects with paths that descend from the route path' do
+ expect do
+ route.delete_conflicting_redirects
+ end.to change { RedirectRoute.count }.by(-4)
+ end
+ end
end
- context 'when redirect routes with paths descending from the route path exists' do
- let!(:redirect2) { route.create_redirect("#{route.path}/foo") }
- let!(:redirect3) { route.create_redirect("#{route.path}/foo/bar") }
- let!(:redirect4) { route.create_redirect("#{route.path}/baz/quz") }
- let!(:other_redirect) { route.create_redirect("other") }
+ context 'when the redirect route is differently cased' do
+ let!(:redirect1) { route.create_redirect(route.path.upcase) }
- it 'deletes all redirects with paths that descend from the route path' do
- route.delete_conflicting_redirects
- expect(route.conflicting_redirects).to be_empty
+ it 'deletes the redirect' do
+ expect do
+ route.delete_conflicting_redirects
+ end.to change { RedirectRoute.count }.by(-1)
end
end
end
end
describe '#conflicting_redirects' do
+ it 'returns an ActiveRecord::Relation' do
+ expect(route.conflicting_redirects).to be_an(ActiveRecord::Relation)
+ end
+
context 'when a redirect route with the same path exists' do
- let!(:redirect1) { route.create_redirect(route.path) }
+ context 'when the redirect route has matching case' do
+ let!(:redirect1) { route.create_redirect(route.path) }
- it 'returns the redirect route' do
- expect(route.conflicting_redirects).to be_an(ActiveRecord::Relation)
- expect(route.conflicting_redirects).to match_array([redirect1])
+ it 'returns the redirect route' do
+ expect(route.conflicting_redirects).to match_array([redirect1])
+ end
+
+ context 'when redirect routes with paths descending from the route path exists' do
+ let!(:redirect2) { route.create_redirect("#{route.path}/foo") }
+ let!(:redirect3) { route.create_redirect("#{route.path}/foo/bar") }
+ let!(:redirect4) { route.create_redirect("#{route.path}/baz/quz") }
+ let!(:other_redirect) { route.create_redirect("other") }
+
+ it 'returns the redirect routes' do
+ expect(route.conflicting_redirects).to match_array([redirect1, redirect2, redirect3, redirect4])
+ end
+ end
end
- context 'when redirect routes with paths descending from the route path exists' do
- let!(:redirect2) { route.create_redirect("#{route.path}/foo") }
- let!(:redirect3) { route.create_redirect("#{route.path}/foo/bar") }
- let!(:redirect4) { route.create_redirect("#{route.path}/baz/quz") }
- let!(:other_redirect) { route.create_redirect("other") }
+ context 'when the redirect route is differently cased' do
+ let!(:redirect1) { route.create_redirect(route.path.upcase) }
- it 'returns the redirect routes' do
- expect(route.conflicting_redirects).to be_an(ActiveRecord::Relation)
- expect(route.conflicting_redirects).to match_array([redirect1, redirect2, redirect3, redirect4])
+ it 'returns the redirect route' do
+ expect(route.conflicting_redirects).to match_array([redirect1])
end
end
end
diff --git a/spec/models/sent_notification_spec.rb b/spec/models/sent_notification_spec.rb
index 8b6b02916ae..8f05deb8b15 100644
--- a/spec/models/sent_notification_spec.rb
+++ b/spec/models/sent_notification_spec.rb
@@ -21,7 +21,7 @@ describe SentNotification do
end
context "when the noteable project and discussion project match" do
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:issue) { create(:issue, project: project) }
let(:discussion_id) { create(:note, project: project, noteable: issue).discussion_id }
subject { build(:sent_notification, project: project, noteable: issue, in_reply_to_discussion_id: discussion_id) }
@@ -128,7 +128,7 @@ describe SentNotification do
end
context 'for commit' do
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:commit) { project.commit }
subject { described_class.record(commit, project.creator.id) }
diff --git a/spec/models/service_spec.rb b/spec/models/service_spec.rb
index dba9fc4ac9b..0f2f906c667 100644
--- a/spec/models/service_spec.rb
+++ b/spec/models/service_spec.rb
@@ -23,7 +23,7 @@ describe Service do
end
context 'when repository is empty' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
it 'returns true' do
expect(service.can_test?).to be true
@@ -46,7 +46,7 @@ describe Service do
end
context 'when repository is empty' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
it 'test runs execute' do
expect(service).to receive(:execute).with(data)
@@ -69,7 +69,7 @@ describe Service do
api_key: '123456789'
})
end
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
describe 'is prefilled for projects pushover service' do
it "has all fields prefilled" do
@@ -88,7 +88,7 @@ describe Service do
describe "{property}_changed?" do
let(:service) do
BambooService.create(
- project: create(:empty_project),
+ project: create(:project),
properties: {
bamboo_url: 'http://gitlab.com',
username: 'mic',
@@ -128,7 +128,7 @@ describe Service do
describe "{property}_touched?" do
let(:service) do
BambooService.create(
- project: create(:empty_project),
+ project: create(:project),
properties: {
bamboo_url: 'http://gitlab.com',
username: 'mic',
@@ -168,7 +168,7 @@ describe Service do
describe "{property}_was" do
let(:service) do
BambooService.create(
- project: create(:empty_project),
+ project: create(:project),
properties: {
bamboo_url: 'http://gitlab.com',
username: 'mic',
@@ -208,7 +208,7 @@ describe Service do
describe 'initialize service with no properties' do
let(:service) do
GitlabIssueTrackerService.create(
- project: create(:empty_project),
+ project: create(:project),
title: 'random title'
)
end
@@ -223,7 +223,7 @@ describe Service do
end
describe "callbacks" do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let!(:service) do
RedmineService.new(
project: project,
diff --git a/spec/models/snippet_spec.rb b/spec/models/snippet_spec.rb
index 904bf2c6144..de3ca300ae3 100644
--- a/spec/models/snippet_spec.rb
+++ b/spec/models/snippet_spec.rb
@@ -33,7 +33,7 @@ describe Snippet do
describe '#to_reference' do
context 'when snippet belongs to a project' do
- let(:project) { build(:empty_project, name: 'sample-project') }
+ let(:project) { build(:project, name: 'sample-project') }
let(:snippet) { build(:snippet, id: 1, project: project) }
it 'returns a String reference to the object' do
@@ -41,7 +41,7 @@ describe Snippet do
end
it 'supports a cross-project reference' do
- another_project = build(:empty_project, name: 'another-project', namespace: project.namespace)
+ another_project = build(:project, name: 'another-project', namespace: project.namespace)
expect(snippet.to_reference(another_project)).to eq "sample-project$1"
end
end
@@ -54,14 +54,14 @@ describe Snippet do
end
it 'still returns shortest reference when project arg present' do
- another_project = build(:empty_project, name: 'another-project')
+ another_project = build(:project, name: 'another-project')
expect(snippet.to_reference(another_project)).to eq "$1"
end
end
end
describe '#file_name' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
context 'file_name is nil' do
let(:snippet) { create(:snippet, project: project, file_name: nil) }
@@ -132,7 +132,7 @@ describe Snippet do
end
describe '#participants' do
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:snippet) { create(:snippet, content: 'foo', project: project) }
let!(:note1) do
diff --git a/spec/models/trending_project_spec.rb b/spec/models/trending_project_spec.rb
index cc28c6d4004..3b5e7ca0d39 100644
--- a/spec/models/trending_project_spec.rb
+++ b/spec/models/trending_project_spec.rb
@@ -2,11 +2,11 @@ require 'spec_helper'
describe TrendingProject do
let(:user) { create(:user) }
- let(:public_project1) { create(:empty_project, :public) }
- let(:public_project2) { create(:empty_project, :public) }
- let(:public_project3) { create(:empty_project, :public) }
- let(:private_project) { create(:empty_project, :private) }
- let(:internal_project) { create(:empty_project, :internal) }
+ let(:public_project1) { create(:project, :public) }
+ let(:public_project2) { create(:project, :public) }
+ let(:public_project3) { create(:project, :public) }
+ let(:private_project) { create(:project, :private) }
+ let(:internal_project) { create(:project, :internal) }
before do
3.times do
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index ec98a3f3498..97bb91a6ac8 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -80,7 +80,7 @@ describe User do
describe '#project_members' do
it 'does not include project memberships for which user is a requester' do
user = create(:user)
- project = create(:empty_project, :public, :access_requestable)
+ project = create(:project, :public, :access_requestable)
project.request_access(user)
expect(user.project_members).to be_empty
@@ -118,6 +118,17 @@ describe User do
expect(user).to validate_uniqueness_of(:username).case_insensitive
end
+
+ context 'when username is changed' do
+ let(:user) { build_stubbed(:user, username: 'old_path', namespace: build_stubbed(:namespace)) }
+
+ it 'validates move_dir is allowed for the namespace' do
+ expect(user.namespace).to receive(:any_project_has_container_registry_tags?).and_return(true)
+ user.username = 'new_path'
+ expect(user).to be_invalid
+ expect(user.errors.messages[:username].first).to match('cannot be changed if a personal project has container registry tags')
+ end
+ end
end
it { is_expected.to validate_presence_of(:projects_limit) }
@@ -560,11 +571,11 @@ describe User do
before do
@user = create(:user)
- @project = create(:empty_project, namespace: @user.namespace)
- @project_2 = create(:empty_project, group: create(:group)) do |project|
+ @project = create(:project, namespace: @user.namespace)
+ @project_2 = create(:project, group: create(:group)) do |project|
project.add_master(@user)
end
- @project_3 = create(:empty_project, group: create(:group)) do |project|
+ @project_3 = create(:project, group: create(:group)) do |project|
project.add_developer(@user)
end
end
@@ -609,7 +620,7 @@ describe User do
describe 'namespaced' do
before do
@user = create :user
- @project = create(:empty_project, namespace: @user.namespace)
+ @project = create(:project, namespace: @user.namespace)
end
it { expect(@user.several_namespaces?).to be_falsey }
@@ -666,7 +677,7 @@ describe User do
end
describe '.without_projects' do
- let!(:project) { create(:empty_project, :public, :access_requestable) }
+ let!(:project) { create(:project, :public, :access_requestable) }
let!(:user) { create(:user) }
let!(:user_without_project) { create(:user) }
let!(:user_without_project2) { create(:user) }
@@ -1196,8 +1207,8 @@ describe User do
describe '#starred?' do
it 'determines if user starred a project' do
user = create :user
- project1 = create(:empty_project, :public)
- project2 = create(:empty_project, :public)
+ project1 = create(:project, :public)
+ project2 = create(:project, :public)
expect(user.starred?(project1)).to be_falsey
expect(user.starred?(project2)).to be_falsey
@@ -1223,7 +1234,7 @@ describe User do
describe '#toggle_star' do
it 'toggles stars' do
user = create :user
- project = create(:empty_project, :public)
+ project = create(:project, :public)
expect(user.starred?(project)).to be_falsey
user.toggle_star(project)
@@ -1276,11 +1287,11 @@ describe User do
describe "#contributed_projects" do
subject { create(:user) }
- let!(:project1) { create(:empty_project) }
- let!(:project2) { create(:empty_project, forked_from_project: project3) }
- let!(:project3) { create(:empty_project) }
+ let!(:project1) { create(:project) }
+ let!(:project2) { create(:project, forked_from_project: project3) }
+ let!(:project3) { create(:project) }
let!(:merge_request) { create(:merge_request, source_project: project2, target_project: project3, author: subject) }
- let!(:push_event) { create(:event, :pushed, project: project1, target: project1, author: subject) }
+ let!(:push_event) { create(:push_event, project: project1, author: subject) }
let!(:merge_event) { create(:event, :created, project: project3, target: merge_request, author: subject) }
before do
@@ -1322,10 +1333,18 @@ describe User do
subject { create(:user) }
let!(:project1) { create(:project, :repository) }
let!(:project2) { create(:project, :repository, forked_from_project: project1) }
- let!(:push_data) do
- Gitlab::DataBuilder::Push.build_sample(project2, subject)
+
+ let!(:push_event) do
+ event = create(:push_event, project: project2, author: subject)
+
+ create(:push_event_payload,
+ event: event,
+ commit_to: '1cf19a015df3523caf0a1f9d40c98a267d6a2fc2',
+ commit_count: 0,
+ ref: 'master')
+
+ event
end
- let!(:push_event) { create(:event, :pushed, project: project2, target: project1, author: subject, data: push_data) }
before do
project1.team << [subject, :master]
@@ -1352,8 +1371,13 @@ describe User do
expect(subject.recent_push(project1)).to eq(nil)
expect(subject.recent_push(project2)).to eq(push_event)
- push_data1 = Gitlab::DataBuilder::Push.build_sample(project1, subject)
- push_event1 = create(:event, :pushed, project: project1, target: project1, author: subject, data: push_data1)
+ push_event1 = create(:push_event, project: project1, author: subject)
+
+ create(:push_event_payload,
+ event: push_event1,
+ commit_to: '1cf19a015df3523caf0a1f9d40c98a267d6a2fc2',
+ commit_count: 0,
+ ref: 'master')
expect(subject.recent_push([project1, project2])).to eq(push_event1) # Newest
end
@@ -1376,7 +1400,7 @@ describe User do
context 'with a minimum access level' do
it 'includes projects for which the user is an owner' do
user = create(:user)
- project = create(:empty_project, :private, namespace: user.namespace)
+ project = create(:project, :private, namespace: user.namespace)
expect(user.authorized_projects(Gitlab::Access::REPORTER))
.to contain_exactly(project)
@@ -1384,7 +1408,7 @@ describe User do
it 'includes projects for which the user is a master' do
user = create(:user)
- project = create(:empty_project, :private)
+ project = create(:project, :private)
project.team << [user, Gitlab::Access::MASTER]
@@ -1395,7 +1419,7 @@ describe User do
it "includes user's personal projects" do
user = create(:user)
- project = create(:empty_project, :private, namespace: user.namespace)
+ project = create(:project, :private, namespace: user.namespace)
expect(user.authorized_projects).to include(project)
end
@@ -1403,7 +1427,7 @@ describe User do
it "includes personal projects user has been given access to" do
user1 = create(:user)
user2 = create(:user)
- project = create(:empty_project, :private, namespace: user1.namespace)
+ project = create(:project, :private, namespace: user1.namespace)
project.team << [user2, Gitlab::Access::DEVELOPER]
@@ -1412,7 +1436,7 @@ describe User do
it "includes projects of groups user has been added to" do
group = create(:group)
- project = create(:empty_project, group: group)
+ project = create(:project, group: group)
user = create(:user)
group.add_developer(user)
@@ -1422,7 +1446,7 @@ describe User do
it "does not include projects of groups user has been removed from" do
group = create(:group)
- project = create(:empty_project, group: group)
+ project = create(:project, group: group)
user = create(:user)
member = group.add_developer(user)
@@ -1434,7 +1458,7 @@ describe User do
it "includes projects shared with user's group" do
user = create(:user)
- project = create(:empty_project, :private)
+ project = create(:project, :private)
group = create(:group)
group.add_reporter(user)
@@ -1446,7 +1470,7 @@ describe User do
it "does not include destroyed projects user had access to" do
user1 = create(:user)
user2 = create(:user)
- project = create(:empty_project, :private, namespace: user1.namespace)
+ project = create(:project, :private, namespace: user1.namespace)
project.team << [user2, Gitlab::Access::DEVELOPER]
expect(user2.authorized_projects).to include(project)
@@ -1457,7 +1481,7 @@ describe User do
it "does not include projects of destroyed groups user had access to" do
group = create(:group)
- project = create(:empty_project, namespace: group)
+ project = create(:project, namespace: group)
user = create(:user)
group.add_developer(user)
@@ -1472,9 +1496,9 @@ describe User do
let(:user) { create(:user) }
it 'includes projects for which the user access level is above or equal to reporter' do
- reporter_project = create(:empty_project) { |p| p.add_reporter(user) }
- developer_project = create(:empty_project) { |p| p.add_developer(user) }
- master_project = create(:empty_project) { |p| p.add_master(user) }
+ reporter_project = create(:project) { |p| p.add_reporter(user) }
+ developer_project = create(:project) { |p| p.add_developer(user) }
+ master_project = create(:project) { |p| p.add_master(user) }
expect(user.projects_where_can_admin_issues.to_a).to eq([master_project, developer_project, reporter_project])
expect(user.can?(:admin_issue, master_project)).to eq(true)
@@ -1483,8 +1507,8 @@ describe User do
end
it 'does not include for which the user access level is below reporter' do
- project = create(:empty_project)
- guest_project = create(:empty_project) { |p| p.add_guest(user) }
+ project = create(:project)
+ guest_project = create(:project) { |p| p.add_guest(user) }
expect(user.projects_where_can_admin_issues.to_a).to be_empty
expect(user.can?(:admin_issue, guest_project)).to eq(false)
@@ -1492,14 +1516,14 @@ describe User do
end
it 'does not include archived projects' do
- project = create(:empty_project, :archived)
+ project = create(:project, :archived)
expect(user.projects_where_can_admin_issues.to_a).to be_empty
expect(user.can?(:admin_issue, project)).to eq(false)
end
it 'does not include projects for which issues are disabled' do
- project = create(:empty_project, :issues_disabled)
+ project = create(:project, :issues_disabled)
expect(user.projects_where_can_admin_issues.to_a).to be_empty
expect(user.can?(:admin_issue, project)).to eq(false)
@@ -1515,7 +1539,7 @@ describe User do
end
context 'without any projects' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
it 'does not load' do
expect(user.ci_authorized_runners).to be_empty
@@ -1524,7 +1548,7 @@ describe User do
context 'with personal projects runners' do
let(:namespace) { create(:namespace, owner: user) }
- let(:project) { create(:empty_project, namespace: namespace) }
+ let(:project) { create(:project, namespace: namespace) }
it 'loads' do
expect(user.ci_authorized_runners).to contain_exactly(runner)
@@ -1555,7 +1579,7 @@ describe User do
context 'with groups projects runners' do
let(:group) { create(:group) }
- let(:project) { create(:empty_project, group: group) }
+ let(:project) { create(:project, group: group) }
def add_user(access)
group.add_user(user, access)
@@ -1565,7 +1589,7 @@ describe User do
end
context 'with other projects runners' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
def add_user(access)
project.team << [user, access]
@@ -1576,8 +1600,8 @@ describe User do
end
describe '#projects_with_reporter_access_limited_to' do
- let(:project1) { create(:empty_project) }
- let(:project2) { create(:empty_project) }
+ let(:project1) { create(:project) }
+ let(:project2) { create(:project) }
let(:user) { create(:user) }
before do
@@ -1719,8 +1743,8 @@ describe User do
end
describe '#refresh_authorized_projects', clean_gitlab_redis_shared_state: true do
- let(:project1) { create(:empty_project) }
- let(:project2) { create(:empty_project) }
+ let(:project1) { create(:project) }
+ let(:project2) { create(:project) }
let(:user) { create(:user) }
before do
@@ -1976,4 +2000,28 @@ describe User do
expect(user.allow_password_authentication?).to be_falsey
end
end
+
+ describe '#personal_projects_count' do
+ it 'returns the number of personal projects using a single query' do
+ user = build(:user)
+ projects = double(:projects, count: 1)
+
+ expect(user).to receive(:personal_projects).once.and_return(projects)
+
+ 2.times do
+ expect(user.personal_projects_count).to eq(1)
+ end
+ end
+ end
+
+ describe '#projects_limit_left' do
+ it 'returns the number of projects that can be created by the user' do
+ user = build(:user)
+
+ allow(user).to receive(:projects_limit).and_return(10)
+ allow(user).to receive(:personal_projects_count).and_return(5)
+
+ expect(user.projects_limit_left).to eq(5)
+ end
+ end
end
diff --git a/spec/models/wiki_page_spec.rb b/spec/models/wiki_page_spec.rb
index 55d9c4ddd7b..40a222be24d 100644
--- a/spec/models/wiki_page_spec.rb
+++ b/spec/models/wiki_page_spec.rb
@@ -1,7 +1,7 @@
require "spec_helper"
describe WikiPage do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:user) { project.owner }
let(:wiki) { ProjectWiki.new(project, user) }
@@ -178,12 +178,12 @@ describe WikiPage do
end
it "updates the content of the page" do
- @page.update("new content")
+ @page.update(content: "new content")
@page = wiki.find_page(title)
end
it "returns true" do
- expect(@page.update("more content")).to be_truthy
+ expect(@page.update(content: "more content")).to be_truthy
end
end
end
@@ -195,29 +195,42 @@ describe WikiPage do
end
after do
- destroy_page("Update")
+ destroy_page(@page.title)
end
context "with valid attributes" do
it "updates the content of the page" do
- @page.update("new content")
+ new_content = "new content"
+
+ @page.update(content: new_content)
@page = wiki.find_page("Update")
+
+ expect(@page.content).to eq("new content")
+ end
+
+ it "updates the title of the page" do
+ new_title = "Index v.1.2.4"
+
+ @page.update(title: new_title)
+ @page = wiki.find_page(new_title)
+
+ expect(@page.title).to eq(new_title)
end
it "returns true" do
- expect(@page.update("more content")).to be_truthy
+ expect(@page.update(content: "more content")).to be_truthy
end
end
context 'with same last commit sha' do
it 'returns true' do
- expect(@page.update('more content', last_commit_sha: @page.last_commit_sha)).to be_truthy
+ expect(@page.update(content: 'more content', last_commit_sha: @page.last_commit_sha)).to be_truthy
end
end
context 'with different last commit sha' do
it 'raises exception' do
- expect { @page.update('more content', last_commit_sha: 'xxx') }.to raise_error(WikiPage::PageChangedError)
+ expect { @page.update(content: 'more content', last_commit_sha: 'xxx') }.to raise_error(WikiPage::PageChangedError)
end
end
end
@@ -249,7 +262,7 @@ describe WikiPage do
end
it "returns an array of all commits for the page" do
- 3.times { |i| @page.update("content #{i}") }
+ 3.times { |i| @page.update(content: "content #{i}") }
expect(@page.versions.count).to eq(4)
end
end
@@ -294,7 +307,7 @@ describe WikiPage do
before do
create_page('Update', 'content')
@page = wiki.find_page('Update')
- 3.times { |i| @page.update("content #{i}") }
+ 3.times { |i| @page.update(content: "content #{i}") }
end
after do
@@ -338,7 +351,7 @@ describe WikiPage do
end
it 'returns false for updated wiki page' do
- updated_wiki_page = original_wiki_page.update("Updated content")
+ updated_wiki_page = original_wiki_page.update(content: "Updated content")
expect(original_wiki_page).not_to eq(updated_wiki_page)
end
end
@@ -360,7 +373,7 @@ describe WikiPage do
it 'is changed after page updated' do
last_commit_sha_before_update = @page.last_commit_sha
- @page.update("new content")
+ @page.update(content: "new content")
@page = wiki.find_page("Update")
expect(@page.last_commit_sha).not_to eq last_commit_sha_before_update
diff --git a/spec/policies/ci/build_policy_spec.rb b/spec/policies/ci/build_policy_spec.rb
index a83a83a7349..8e1bc3d1543 100644
--- a/spec/policies/ci/build_policy_spec.rb
+++ b/spec/policies/ci/build_policy_spec.rb
@@ -17,7 +17,7 @@ describe Ci::BuildPolicy do
describe '#rules' do
context 'when user does not have access to the project' do
- let(:project) { create(:empty_project, :private) }
+ let(:project) { create(:project, :private) }
context 'when public builds are enabled' do
it 'does not include ability to read build' do
@@ -35,7 +35,7 @@ describe Ci::BuildPolicy do
end
context 'when anonymous user has access to the project' do
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
context 'when public builds are enabled' do
it 'includes ability to read build' do
@@ -53,7 +53,7 @@ describe Ci::BuildPolicy do
end
context 'when team member has access to the project' do
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
context 'team member is a guest' do
before do
@@ -97,7 +97,7 @@ describe Ci::BuildPolicy do
end
describe 'rules for protected ref' do
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:build) { create(:ci_build, ref: 'some-ref', pipeline: pipeline) }
before do
diff --git a/spec/policies/ci/pipeline_policy_spec.rb b/spec/policies/ci/pipeline_policy_spec.rb
index b11b06d301f..48a8064c5fc 100644
--- a/spec/policies/ci/pipeline_policy_spec.rb
+++ b/spec/policies/ci/pipeline_policy_spec.rb
@@ -10,7 +10,7 @@ describe Ci::PipelinePolicy, :models do
describe 'rules' do
describe 'rules for protected ref' do
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
before do
project.add_developer(user)
diff --git a/spec/policies/ci/trigger_policy_spec.rb b/spec/policies/ci/trigger_policy_spec.rb
index 3d3e3d3755b..be40dbb2aa9 100644
--- a/spec/policies/ci/trigger_policy_spec.rb
+++ b/spec/policies/ci/trigger_policy_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe Ci::TriggerPolicy do
let(:user) { create(:user) }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:trigger) { create(:ci_trigger, project: project, owner: owner) }
let(:policies) do
diff --git a/spec/policies/environment_policy_spec.rb b/spec/policies/environment_policy_spec.rb
index 035e20c7452..de4cb5b30c5 100644
--- a/spec/policies/environment_policy_spec.rb
+++ b/spec/policies/environment_policy_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe EnvironmentPolicy do
let(:user) { create(:user) }
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:environment) do
create(:environment, :with_review_app, project: project)
@@ -14,7 +14,7 @@ describe EnvironmentPolicy do
describe '#rules' do
context 'when user does not have access to the project' do
- let(:project) { create(:project, :private) }
+ let(:project) { create(:project, :private, :repository) }
it 'does not include ability to stop environment' do
expect(policy).to be_disallowed :stop_environment
@@ -22,7 +22,7 @@ describe EnvironmentPolicy do
end
context 'when anonymous user has access to the project' do
- let(:project) { create(:project, :public) }
+ let(:project) { create(:project, :public, :repository) }
it 'does not include ability to stop environment' do
expect(policy).to be_disallowed :stop_environment
@@ -30,7 +30,7 @@ describe EnvironmentPolicy do
end
context 'when team member has access to the project' do
- let(:project) { create(:project, :public) }
+ let(:project) { create(:project, :public, :repository) }
before do
project.add_developer(user)
diff --git a/spec/policies/issue_policy_spec.rb b/spec/policies/issue_policy_spec.rb
index 279b96fb2af..be4c24c727c 100644
--- a/spec/policies/issue_policy_spec.rb
+++ b/spec/policies/issue_policy_spec.rb
@@ -14,7 +14,7 @@ describe IssuePolicy do
context 'a private project' do
let(:non_member) { create(:user) }
- let(:project) { create(:empty_project, :private) }
+ let(:project) { create(:project, :private) }
let(:issue) { create(:issue, project: project, assignees: [assignee], author: author) }
let(:issue_no_assignee) { create(:issue, project: project) }
@@ -109,7 +109,7 @@ describe IssuePolicy do
end
context 'a public project' do
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:issue) { create(:issue, project: project, assignees: [assignee], author: author) }
let(:issue_no_assignee) { create(:issue, project: project) }
diff --git a/spec/policies/project_policy_spec.rb b/spec/policies/project_policy_spec.rb
index 1f51ced1beb..4dbaf7fb025 100644
--- a/spec/policies/project_policy_spec.rb
+++ b/spec/policies/project_policy_spec.rb
@@ -7,7 +7,7 @@ describe ProjectPolicy do
let(:master) { create(:user) }
let(:owner) { create(:user) }
let(:admin) { create(:admin) }
- let(:project) { create(:empty_project, :public, namespace: owner.namespace) }
+ let(:project) { create(:project, :public, namespace: owner.namespace) }
let(:guest_permissions) do
%i[
@@ -82,7 +82,7 @@ describe ProjectPolicy do
end
it 'does not include the read_issue permission when the issue author is not a member of the private project' do
- project = create(:empty_project, :private)
+ project = create(:project, :private)
issue = create(:issue, project: project)
user = issue.author
@@ -129,7 +129,7 @@ describe ProjectPolicy do
context 'when a project has pending invites, and the current user is anonymous' do
let(:group) { create(:group, :public) }
- let(:project) { create(:empty_project, :public, namespace: group) }
+ let(:project) { create(:project, :public, namespace: group) }
let(:user_permissions) { [:create_project, :create_issue, :create_note, :upload_file] }
let(:anonymous_permissions) { guest_permissions - user_permissions }
@@ -146,7 +146,7 @@ describe ProjectPolicy do
end
context 'abilities for non-public projects' do
- let(:project) { create(:empty_project, namespace: owner.namespace) }
+ let(:project) { create(:project, namespace: owner.namespace) }
subject { described_class.new(current_user, project) }
diff --git a/spec/policies/project_snippet_policy_spec.rb b/spec/policies/project_snippet_policy_spec.rb
index bae35ee31c6..f0bf46c480a 100644
--- a/spec/policies/project_snippet_policy_spec.rb
+++ b/spec/policies/project_snippet_policy_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe ProjectSnippetPolicy do
let(:regular_user) { create(:user) }
let(:external_user) { create(:user, :external) }
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:author_permissions) do
[
diff --git a/spec/presenters/ci/build_presenter_spec.rb b/spec/presenters/ci/build_presenter_spec.rb
index f05d5c7fce5..a7a34ecac72 100644
--- a/spec/presenters/ci/build_presenter_spec.rb
+++ b/spec/presenters/ci/build_presenter_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Ci::BuildPresenter do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:pipeline) { create(:ci_pipeline, project: project) }
let(:build) { create(:ci_build, pipeline: pipeline) }
@@ -85,7 +85,7 @@ describe Ci::BuildPresenter do
describe 'quack like a Ci::Build permission-wise' do
context 'user is not allowed' do
- let(:project) { create(:empty_project, public_builds: false) }
+ let(:project) { create(:project, public_builds: false) }
it 'returns false' do
expect(presenter.can?(nil, :read_build)).to be_falsy
@@ -93,7 +93,7 @@ describe Ci::BuildPresenter do
end
context 'user is allowed' do
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
it 'returns true' do
expect(presenter.can?(nil, :read_build)).to be_truthy
diff --git a/spec/presenters/ci/pipeline_presenter_spec.rb b/spec/presenters/ci/pipeline_presenter_spec.rb
index 9134d1cc31c..e4886a8f019 100644
--- a/spec/presenters/ci/pipeline_presenter_spec.rb
+++ b/spec/presenters/ci/pipeline_presenter_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Ci::PipelinePresenter do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:pipeline) { create(:ci_pipeline, project: project) }
subject(:presenter) do
diff --git a/spec/presenters/ci/variable_presenter_spec.rb b/spec/presenters/ci/variable_presenter_spec.rb
index 9e6aae7bcad..db62f86edb0 100644
--- a/spec/presenters/ci/variable_presenter_spec.rb
+++ b/spec/presenters/ci/variable_presenter_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe Ci::VariablePresenter do
include Gitlab::Routing.url_helpers
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:variable) { create(:ci_variable, project: project) }
subject(:presenter) do
diff --git a/spec/presenters/conversational_development_index/metric_presenter_spec.rb b/spec/presenters/conversational_development_index/metric_presenter_spec.rb
index 1e015c71f5b..81eb05a9a6b 100644
--- a/spec/presenters/conversational_development_index/metric_presenter_spec.rb
+++ b/spec/presenters/conversational_development_index/metric_presenter_spec.rb
@@ -8,9 +8,9 @@ describe ConversationalDevelopmentIndex::MetricPresenter do
it 'includes instance score, leader score and percentage score' do
issues_card = subject.cards.first
- expect(issues_card.instance_score).to eq 1.234
- expect(issues_card.leader_score).to eq 9.256
- expect(issues_card.percentage_score).to be_within(0.1).of(13.3)
+ expect(issues_card.instance_score).to eq(1.234)
+ expect(issues_card.leader_score).to eq(9.256)
+ expect(issues_card.percentage_score).to eq(13.331)
end
end
diff --git a/spec/presenters/merge_request_presenter_spec.rb b/spec/presenters/merge_request_presenter_spec.rb
index c1a0313b13c..2187be0190d 100644
--- a/spec/presenters/merge_request_presenter_spec.rb
+++ b/spec/presenters/merge_request_presenter_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe MergeRequestPresenter do
let(:resource) { create :merge_request, source_project: project }
- let(:project) { create :empty_project }
+ let(:project) { create :project }
let(:user) { create(:user) }
describe '#ci_status' do
@@ -71,7 +71,7 @@ describe MergeRequestPresenter do
end
describe '#conflict_resolution_path' do
- let(:project) { create :empty_project }
+ let(:project) { create :project }
let(:user) { create :user }
let(:presenter) { described_class.new(resource, current_user: user) }
let(:path) { presenter.conflict_resolution_path }
@@ -105,7 +105,7 @@ describe MergeRequestPresenter do
end
context 'issues links' do
- let(:project) { create(:project, :private, creator: user, namespace: user.namespace) }
+ let(:project) { create(:project, :private, :repository, creator: user, namespace: user.namespace) }
let(:issue_a) { create(:issue, project: project) }
let(:issue_b) { create(:issue, project: project) }
diff --git a/spec/presenters/projects/settings/deploy_keys_presenter_spec.rb b/spec/presenters/projects/settings/deploy_keys_presenter_spec.rb
index 5c39e1b5f96..2cc0076d695 100644
--- a/spec/presenters/projects/settings/deploy_keys_presenter_spec.rb
+++ b/spec/presenters/projects/settings/deploy_keys_presenter_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Projects::Settings::DeployKeysPresenter do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:user) { create(:user) }
let(:deploy_key) { create(:deploy_key, public: true) }
diff --git a/spec/requests/api/access_requests_spec.rb b/spec/requests/api/access_requests_spec.rb
index c8eacb38e6f..6bd17697c33 100644
--- a/spec/requests/api/access_requests_spec.rb
+++ b/spec/requests/api/access_requests_spec.rb
@@ -7,7 +7,7 @@ describe API::AccessRequests do
let(:stranger) { create(:user) }
let(:project) do
- create(:empty_project, :public, :access_requestable, creator_id: master.id, namespace: master.namespace) do |project|
+ create(:project, :public, :access_requestable, creator_id: master.id, namespace: master.namespace) do |project|
project.team << [developer, :developer]
project.team << [master, :master]
project.request_access(access_requester)
diff --git a/spec/requests/api/award_emoji_spec.rb b/spec/requests/api/award_emoji_spec.rb
index 6d822b5cb4f..1dd9f3f6ddc 100644
--- a/spec/requests/api/award_emoji_spec.rb
+++ b/spec/requests/api/award_emoji_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe API::AwardEmoji do
let(:user) { create(:user) }
- let!(:project) { create(:empty_project) }
+ let!(:project) { create(:project) }
let(:issue) { create(:issue, project: project) }
let!(:award_emoji) { create(:award_emoji, awardable: issue, user: user) }
let!(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
diff --git a/spec/requests/api/boards_spec.rb b/spec/requests/api/boards_spec.rb
index c27db716ef8..43b381c2219 100644
--- a/spec/requests/api/boards_spec.rb
+++ b/spec/requests/api/boards_spec.rb
@@ -6,7 +6,7 @@ describe API::Boards do
let(:non_member) { create(:user) }
let(:guest) { create(:user) }
let(:admin) { create(:user, :admin) }
- let!(:project) { create(:empty_project, :public, creator_id: user.id, namespace: user.namespace ) }
+ let!(:project) { create(:project, :public, creator_id: user.id, namespace: user.namespace ) }
let!(:dev_label) do
create(:label, title: 'Development', color: '#FFAABB', project: project)
@@ -188,7 +188,7 @@ describe API::Boards do
context "when the user is project owner" do
let(:owner) { create(:user) }
- let(:project) { create(:empty_project, namespace: owner.namespace) }
+ let(:project) { create(:project, namespace: owner.namespace) }
it "deletes the list if an admin requests it" do
delete api("#{base_url}/#{dev_list.id}", owner)
diff --git a/spec/requests/api/circuit_breakers_spec.rb b/spec/requests/api/circuit_breakers_spec.rb
new file mode 100644
index 00000000000..76521e55994
--- /dev/null
+++ b/spec/requests/api/circuit_breakers_spec.rb
@@ -0,0 +1,57 @@
+require 'spec_helper'
+
+describe API::CircuitBreakers do
+ let(:user) { create(:user) }
+ let(:admin) { create(:admin) }
+
+ describe 'GET circuit_breakers/repository_storage' do
+ it 'returns a 401 for anonymous users' do
+ get api('/circuit_breakers/repository_storage')
+
+ expect(response).to have_http_status(401)
+ end
+
+ it 'returns a 403 for users' do
+ get api('/circuit_breakers/repository_storage', user)
+
+ expect(response).to have_http_status(403)
+ end
+
+ it 'returns an Array of storages' do
+ expect(Gitlab::Git::Storage::Health).to receive(:for_all_storages) do
+ [Gitlab::Git::Storage::Health.new('broken', [{ name: 'prefix:broken:web01', failure_count: 4 }])]
+ end
+
+ get api('/circuit_breakers/repository_storage', admin)
+
+ expect(response).to have_http_status(200)
+ expect(json_response).to be_kind_of(Array)
+ expect(json_response.first['storage_name']).to eq('broken')
+ expect(json_response.first['failing_on_hosts']).to eq(['web01'])
+ expect(json_response.first['total_failures']).to eq(4)
+ end
+
+ describe 'GET circuit_breakers/repository_storage/failing' do
+ it 'returns an array of failing storages' do
+ expect(Gitlab::Git::Storage::Health).to receive(:for_failing_storages) do
+ [Gitlab::Git::Storage::Health.new('broken', [{ name: 'prefix:broken:web01', failure_count: 4 }])]
+ end
+
+ get api('/circuit_breakers/repository_storage/failing', admin)
+
+ expect(response).to have_http_status(200)
+ expect(json_response).to be_kind_of(Array)
+ end
+ end
+ end
+
+ describe 'DELETE circuit_breakers/repository_storage' do
+ it 'clears all circuit_breakers' do
+ expect(Gitlab::Git::Storage::CircuitBreaker).to receive(:reset_all!)
+
+ delete api('/circuit_breakers/repository_storage', admin)
+
+ expect(response).to have_http_status(204)
+ end
+ end
+end
diff --git a/spec/requests/api/commit_statuses_spec.rb b/spec/requests/api/commit_statuses_spec.rb
index 8b62aa268d9..3c02e6302b4 100644
--- a/spec/requests/api/commit_statuses_spec.rb
+++ b/spec/requests/api/commit_statuses_spec.rb
@@ -44,8 +44,8 @@ describe API::CommitStatuses do
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(statuses_id).to contain_exactly(status3.id, status4.id, status5.id, status6.id)
- json_response.sort_by!{ |status| status['id'] }
- expect(json_response.map{ |status| status['allow_failure'] }).to eq([true, false, false, false])
+ json_response.sort_by! { |status| status['id'] }
+ expect(json_response.map { |status| status['allow_failure'] }).to eq([true, false, false, false])
end
end
diff --git a/spec/requests/api/commits_spec.rb b/spec/requests/api/commits_spec.rb
index 0dad547735d..992a6e8d76a 100644
--- a/spec/requests/api/commits_spec.rb
+++ b/spec/requests/api/commits_spec.rb
@@ -3,29 +3,27 @@ require 'mime/types'
describe API::Commits do
let(:user) { create(:user) }
- let(:user2) { create(:user) }
- let!(:project) { create(:project, :repository, creator: user, namespace: user.namespace) }
- let!(:guest) { create(:project_member, :guest, user: user2, project: project) }
- 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') }
+ let(:guest) { create(:user).tap { |u| project.add_guest(u) } }
+ let(:project) { create(:project, :repository, creator: user, path: 'my.project') }
+ let(:branch_with_dot) { project.repository.find_branch('ends-with.json') }
+ let(:branch_with_slash) { project.repository.find_branch('improve/awesome') }
+
+ let(:project_id) { project.id }
+ let(:current_user) { nil }
before do
- project.team << [user, :reporter]
+ project.add_master(user)
end
- describe "List repository commits" do
- context "authorized user" do
- before do
- project.team << [user2, :reporter]
- end
-
+ describe 'GET /projects/:id/repository/commits' do
+ context 'authorized user' do
it "returns project commits" do
commit = project.repository.commit
- get api("/projects/#{project.id}/repository/commits", user)
+ get api("/projects/#{project_id}/repository/commits", user)
expect(response).to have_http_status(200)
- expect(json_response).to be_an Array
+ expect(response).to match_response_schema('public_api/v4/commits')
expect(json_response.first['id']).to eq(commit.id)
expect(json_response.first['committer_name']).to eq(commit.committer_name)
expect(json_response.first['committer_email']).to eq(commit.committer_email)
@@ -34,7 +32,7 @@ describe API::Commits do
it 'include correct pagination headers' do
commit_count = project.repository.count_commits(ref: 'master').to_s
- get api("/projects/#{project.id}/repository/commits", user)
+ get api("/projects/#{project_id}/repository/commits", user)
expect(response).to include_pagination_headers
expect(response.headers['X-Total']).to eq(commit_count)
@@ -44,8 +42,9 @@ describe API::Commits do
context "unauthorized user" do
it "does not return project commits" do
- get api("/projects/#{project.id}/repository/commits")
- expect(response).to have_http_status(401)
+ get api("/projects/#{project_id}/repository/commits")
+
+ expect(response).to have_http_status(404)
end
end
@@ -54,7 +53,7 @@ describe API::Commits do
commits = project.repository.commits("master")
after = commits.second.created_at
- get api("/projects/#{project.id}/repository/commits?since=#{after.utc.iso8601}", user)
+ get api("/projects/#{project_id}/repository/commits?since=#{after.utc.iso8601}", user)
expect(json_response.size).to eq 2
expect(json_response.first["id"]).to eq(commits.first.id)
@@ -66,7 +65,7 @@ describe API::Commits do
after = commits.second.created_at
commit_count = project.repository.count_commits(ref: 'master', after: after).to_s
- get api("/projects/#{project.id}/repository/commits?since=#{after.utc.iso8601}", user)
+ get api("/projects/#{project_id}/repository/commits?since=#{after.utc.iso8601}", user)
expect(response).to include_pagination_headers
expect(response.headers['X-Total']).to eq(commit_count)
@@ -79,7 +78,7 @@ describe API::Commits do
commits = project.repository.commits("master")
before = commits.second.created_at
- get api("/projects/#{project.id}/repository/commits?until=#{before.utc.iso8601}", user)
+ get api("/projects/#{project_id}/repository/commits?until=#{before.utc.iso8601}", user)
if commits.size >= 20
expect(json_response.size).to eq(20)
@@ -96,7 +95,7 @@ describe API::Commits do
before = commits.second.created_at
commit_count = project.repository.count_commits(ref: 'master', before: before).to_s
- get api("/projects/#{project.id}/repository/commits?until=#{before.utc.iso8601}", user)
+ get api("/projects/#{project_id}/repository/commits?until=#{before.utc.iso8601}", user)
expect(response).to include_pagination_headers
expect(response.headers['X-Total']).to eq(commit_count)
@@ -106,7 +105,7 @@ describe API::Commits do
context "invalid xmlschema date parameters" do
it "returns an invalid parameter error message" do
- get api("/projects/#{project.id}/repository/commits?since=invalid-date", user)
+ get api("/projects/#{project_id}/repository/commits?since=invalid-date", user)
expect(response).to have_http_status(400)
expect(json_response['error']).to eq('since is invalid')
@@ -118,7 +117,7 @@ describe API::Commits do
path = 'files/ruby/popen.rb'
commit_count = project.repository.count_commits(ref: 'master', path: path).to_s
- get api("/projects/#{project.id}/repository/commits?path=#{path}", user)
+ get api("/projects/#{project_id}/repository/commits?path=#{path}", user)
expect(json_response.size).to eq(3)
expect(json_response.first["id"]).to eq("570e7b2abdd848b95f2f578043fc23bd6f6fd24d")
@@ -130,7 +129,7 @@ describe API::Commits do
path = 'files/ruby/popen.rb'
commit_count = project.repository.count_commits(ref: 'master', path: path).to_s
- get api("/projects/#{project.id}/repository/commits?path=#{path}", user)
+ get api("/projects/#{project_id}/repository/commits?path=#{path}", user)
expect(response).to include_pagination_headers
expect(response.headers['X-Total']).to eq(commit_count)
@@ -143,7 +142,7 @@ describe API::Commits do
let(:per_page) { 5 }
let(:ref_name) { 'master' }
let!(:request) do
- get api("/projects/#{project.id}/repository/commits?page=#{page}&per_page=#{per_page}&ref_name=#{ref_name}", user)
+ get api("/projects/#{project_id}/repository/commits?page=#{page}&per_page=#{per_page}&ref_name=#{ref_name}", user)
end
it 'returns correct headers' do
@@ -181,10 +180,10 @@ describe API::Commits do
end
describe "POST /projects/:id/repository/commits" do
- let!(:url) { "/projects/#{project.id}/repository/commits" }
+ let!(:url) { "/projects/#{project_id}/repository/commits" }
it 'returns a 403 unauthorized for user without permissions' do
- post api(url, user2)
+ post api(url, guest)
expect(response).to have_http_status(403)
end
@@ -227,7 +226,7 @@ describe API::Commits do
it 'a new file in project repo' do
post api(url, user), valid_c_params
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['title']).to eq(message)
expect(json_response['committer_name']).to eq(user.name)
expect(json_response['committer_email']).to eq(user.email)
@@ -453,13 +452,17 @@ describe API::Commits do
end
end
- describe "Get a single commit" do
- context "authorized user" do
- it "returns a commit by sha" do
- get api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}", user)
+ describe 'GET /projects/:id/repository/commits/:sha' do
+ let(:commit) { project.repository.commit }
+ let(:commit_id) { commit.id }
+ let(:route) { "/projects/#{project_id}/repository/commits/#{commit_id}" }
- expect(response).to have_http_status(200)
- commit = project.repository.commit
+ shared_examples_for 'ref commit' do
+ it 'returns the ref last commit' do
+ get api(route, current_user)
+
+ expect(response).to have_gitlab_http_status(200)
+ expect(response).to match_response_schema('public_api/v4/commit/detail')
expect(json_response['id']).to eq(commit.id)
expect(json_response['short_id']).to eq(commit.short_id)
expect(json_response['title']).to eq(commit.title)
@@ -474,222 +477,539 @@ describe API::Commits do
expect(json_response['stats']['additions']).to eq(commit.stats.additions)
expect(json_response['stats']['deletions']).to eq(commit.stats.deletions)
expect(json_response['stats']['total']).to eq(commit.stats.total)
+ expect(json_response['status']).to be_nil
end
- it "returns a 404 error if not found" do
- get api("/projects/#{project.id}/repository/commits/invalid_sha", user)
- expect(response).to have_http_status(404)
+ context 'when ref does not exist' do
+ let(:commit_id) { 'unknown' }
+
+ it_behaves_like '404 response' do
+ let(:request) { get api(route, current_user) }
+ let(:message) { '404 Commit Not Found' }
+ end
end
- it "returns nil for commit without CI" do
- get api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}", user)
+ context 'when repository is disabled' do
+ include_context 'disabled repository'
- expect(response).to have_http_status(200)
- expect(json_response['status']).to be_nil
+ it_behaves_like '403 response' do
+ let(:request) { get api(route, current_user) }
+ end
end
+ end
- it "returns status for CI" do
- pipeline = project.pipelines.create(source: :push, ref: 'master', sha: project.repository.commit.sha)
- pipeline.update(status: 'success')
+ context 'when unauthenticated', 'and project is public' do
+ let(:project) { create(:project, :public, :repository) }
- get api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}", user)
+ it_behaves_like 'ref commit'
+ end
- expect(response).to have_http_status(200)
- expect(json_response['status']).to eq(pipeline.status)
+ context 'when unauthenticated', 'and project is private' do
+ it_behaves_like '404 response' do
+ let(:request) { get api(route) }
+ let(:message) { '404 Project Not Found' }
end
+ end
- it "returns status for CI when pipeline is created" do
- project.pipelines.create(source: :push, ref: 'master', sha: project.repository.commit.sha)
+ context 'when authenticated', 'as a master' do
+ let(:current_user) { user }
- get api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}", user)
+ it_behaves_like 'ref commit'
- expect(response).to have_http_status(200)
- expect(json_response['status']).to eq("created")
+ context 'when branch contains a dot' do
+ let(:commit) { project.repository.commit(branch_with_dot.name) }
+ let(:commit_id) { branch_with_dot.name }
+
+ it_behaves_like 'ref commit'
end
- end
- context "unauthorized user" do
- it "does not return the selected commit" do
- get api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}")
- expect(response).to have_http_status(401)
+ context 'when branch contains a slash' do
+ let(:commit_id) { branch_with_slash.name }
+
+ it_behaves_like '404 response' do
+ let(:request) { get api(route, current_user) }
+ end
+ end
+
+ context 'when branch contains an escaped slash' do
+ let(:commit) { project.repository.commit(branch_with_slash.name) }
+ let(:commit_id) { CGI.escape(branch_with_slash.name) }
+
+ it_behaves_like 'ref commit'
+ end
+
+ context 'requesting with the escaped project full path' do
+ let(:project_id) { CGI.escape(project.full_path) }
+
+ it_behaves_like 'ref commit'
+
+ context 'when branch contains a dot' do
+ let(:commit) { project.repository.commit(branch_with_dot.name) }
+ let(:commit_id) { branch_with_dot.name }
+
+ it_behaves_like 'ref commit'
+ end
+ end
+
+ context 'when the ref has a pipeline' do
+ let!(:pipeline) { project.pipelines.create(source: :push, ref: 'master', sha: commit.sha) }
+
+ it 'includes a "created" status' do
+ get api(route, current_user)
+
+ expect(response).to have_http_status(200)
+ expect(response).to match_response_schema('public_api/v4/commit/detail')
+ expect(json_response['status']).to eq('created')
+ end
+
+ context 'when pipeline succeeds' do
+ before do
+ pipeline.update(status: 'success')
+ end
+
+ it 'includes a "success" status' do
+ get api(route, current_user)
+
+ expect(response).to have_http_status(200)
+ expect(response).to match_response_schema('public_api/v4/commit/detail')
+ expect(json_response['status']).to eq('success')
+ end
+ end
end
end
end
- describe "Get the diff of a commit" do
- context "authorized user" do
- before do
- project.team << [user2, :reporter]
+ describe 'GET /projects/:id/repository/commits/:sha/diff' do
+ let(:commit) { project.repository.commit }
+ let(:commit_id) { commit.id }
+ let(:route) { "/projects/#{project_id}/repository/commits/#{commit_id}/diff" }
+
+ shared_examples_for 'ref diff' do
+ it 'returns the diff of the selected commit' do
+ get api(route, current_user)
+
+ expect(response).to have_gitlab_http_status(200)
+ expect(json_response.size).to be >= 1
+ expect(json_response.first.keys).to include 'diff'
end
- it "returns the diff of the selected commit" do
- get api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}/diff", user)
- expect(response).to have_http_status(200)
+ context 'when ref does not exist' do
+ let(:commit_id) { 'unknown' }
- expect(json_response).to be_an Array
- expect(json_response.length).to be >= 1
- expect(json_response.first.keys).to include "diff"
+ it_behaves_like '404 response' do
+ let(:request) { get api(route, current_user) }
+ let(:message) { '404 Commit Not Found' }
+ end
end
- it "returns a 404 error if invalid commit" do
- get api("/projects/#{project.id}/repository/commits/invalid_sha/diff", user)
- expect(response).to have_http_status(404)
+ context 'when repository is disabled' do
+ include_context 'disabled repository'
+
+ it_behaves_like '403 response' do
+ let(:request) { get api(route, current_user) }
+ end
end
end
- context "unauthorized user" do
- it "does not return the diff of the selected commit" do
- get api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}/diff")
- expect(response).to have_http_status(401)
+ context 'when unauthenticated', 'and project is public' do
+ let(:project) { create(:project, :public, :repository) }
+
+ it_behaves_like 'ref diff'
+ end
+
+ context 'when unauthenticated', 'and project is private' do
+ it_behaves_like '404 response' do
+ let(:request) { get api(route) }
+ let(:message) { '404 Project Not Found' }
+ end
+ end
+
+ context 'when authenticated', 'as a master' do
+ let(:current_user) { user }
+
+ it_behaves_like 'ref diff'
+
+ context 'when branch contains a dot' do
+ let(:commit_id) { branch_with_dot.name }
+
+ it_behaves_like 'ref diff'
+ end
+
+ context 'when branch contains a slash' do
+ let(:commit_id) { branch_with_slash.name }
+
+ it_behaves_like '404 response' do
+ let(:request) { get api(route, current_user) }
+ end
+ end
+
+ context 'when branch contains an escaped slash' do
+ let(:commit_id) { CGI.escape(branch_with_slash.name) }
+
+ it_behaves_like 'ref diff'
+ end
+
+ context 'requesting with the escaped project full path' do
+ let(:project_id) { CGI.escape(project.full_path) }
+
+ it_behaves_like 'ref diff'
+
+ context 'when branch contains a dot' do
+ let(:commit_id) { branch_with_dot.name }
+
+ it_behaves_like 'ref diff'
+ end
end
end
end
- describe 'Get the comments of a commit' do
- context 'authorized user' do
- it 'returns merge_request comments' do
- get api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}/comments", user)
- expect(response).to have_http_status(200)
- expect(response).to include_pagination_headers
- expect(json_response).to be_an Array
- expect(json_response.length).to eq(2)
- expect(json_response.first['note']).to eq('a comment on a commit')
- expect(json_response.first['author']['id']).to eq(user.id)
+ describe 'GET /projects/:id/repository/commits/:sha/comments' do
+ let(:commit) { project.repository.commit }
+ let(:commit_id) { commit.id }
+ let(:route) { "/projects/#{project_id}/repository/commits/#{commit_id}/comments" }
+
+ shared_examples_for 'ref comments' do
+ context 'when ref exists' do
+ before do
+ create(:note_on_commit, author: user, project: project, commit_id: commit.id, note: 'a comment on a commit')
+ create(:note_on_commit, author: user, project: project, commit_id: commit.id, note: 'another comment on a commit')
+ end
+
+ it 'returns the diff of the selected commit' do
+ get api(route, current_user)
+
+ expect(response).to have_gitlab_http_status(200)
+ expect(response).to match_response_schema('public_api/v4/commit_notes')
+ expect(json_response.size).to eq(2)
+ expect(json_response.first['note']).to eq('a comment on a commit')
+ expect(json_response.first['author']['id']).to eq(user.id)
+ end
end
- it 'returns a 404 error if merge_request_id not found' do
- get api("/projects/#{project.id}/repository/commits/1234ab/comments", user)
- expect(response).to have_http_status(404)
+ context 'when ref does not exist' do
+ let(:commit_id) { 'unknown' }
+
+ it_behaves_like '404 response' do
+ let(:request) { get api(route, current_user) }
+ let(:message) { '404 Commit Not Found' }
+ end
+ end
+
+ context 'when repository is disabled' do
+ include_context 'disabled repository'
+
+ it_behaves_like '403 response' do
+ let(:request) { get api(route, current_user) }
+ end
+ end
+ end
+
+ context 'when unauthenticated', 'and project is public' do
+ let(:project) { create(:project, :public, :repository) }
+
+ it_behaves_like 'ref comments'
+ end
+
+ context 'when unauthenticated', 'and project is private' do
+ it_behaves_like '404 response' do
+ let(:request) { get api(route) }
+ let(:message) { '404 Project Not Found' }
end
end
- context 'unauthorized user' do
- it 'does not return the diff of the selected commit' do
- get api("/projects/#{project.id}/repository/commits/1234ab/comments")
- expect(response).to have_http_status(401)
+ context 'when authenticated', 'as a master' do
+ let(:current_user) { user }
+
+ it_behaves_like 'ref comments'
+
+ context 'when branch contains a dot' do
+ let(:commit) { project.repository.commit(branch_with_dot.name) }
+ let(:commit_id) { branch_with_dot.name }
+
+ it_behaves_like 'ref comments'
+ end
+
+ context 'when branch contains a slash' do
+ let(:commit) { project.repository.commit(branch_with_slash.name) }
+ let(:commit_id) { branch_with_slash.name }
+
+ it_behaves_like '404 response' do
+ let(:request) { get api(route, current_user) }
+ end
+ end
+
+ context 'when branch contains an escaped slash' do
+ let(:commit) { project.repository.commit(branch_with_slash.name) }
+ let(:commit_id) { CGI.escape(branch_with_slash.name) }
+
+ it_behaves_like 'ref comments'
+ end
+
+ context 'requesting with the escaped project full path' do
+ let(:project_id) { CGI.escape(project.full_path) }
+
+ it_behaves_like 'ref comments'
+
+ context 'when branch contains a dot' do
+ let(:commit) { project.repository.commit(branch_with_dot.name) }
+ let(:commit_id) { branch_with_dot.name }
+
+ it_behaves_like 'ref comments'
+ end
end
end
context 'when the commit is present on two projects' do
- let(:forked_project) { create(:project, :repository, creator: user2, namespace: user2.namespace) }
- let!(:forked_project_note) { create(:note_on_commit, author: user2, project: forked_project, commit_id: forked_project.repository.commit.id, note: 'a comment on a commit for fork') }
+ let(:forked_project) { create(:project, :repository, creator: guest, namespace: guest.namespace) }
+ let!(:forked_project_note) { create(:note_on_commit, author: guest, project: forked_project, commit_id: forked_project.repository.commit.id, note: 'a comment on a commit for fork') }
+ let(:project_id) { forked_project.id }
+ let(:commit_id) { forked_project.repository.commit.id }
it 'returns the comments for the target project' do
- get api("/projects/#{forked_project.id}/repository/commits/#{forked_project.repository.commit.id}/comments", user2)
+ get api(route, guest)
- expect(response).to have_http_status(200)
- expect(json_response.length).to eq(1)
+ expect(response).to have_gitlab_http_status(200)
+ expect(response).to match_response_schema('public_api/v4/commit_notes')
+ expect(json_response.size).to eq(1)
expect(json_response.first['note']).to eq('a comment on a commit for fork')
- expect(json_response.first['author']['id']).to eq(user2.id)
+ expect(json_response.first['author']['id']).to eq(guest.id)
end
end
end
describe 'POST :id/repository/commits/:sha/cherry_pick' do
- let(:master_pickable_commit) { project.commit('7d3b0f7cff5f37573aea97cebfd5692ea1689924') }
+ let(:commit) { project.commit('7d3b0f7cff5f37573aea97cebfd5692ea1689924') }
+ let(:commit_id) { commit.id }
+ let(:branch) { 'master' }
+ let(:route) { "/projects/#{project_id}/repository/commits/#{commit_id}/cherry_pick" }
+
+ shared_examples_for 'ref cherry-pick' do
+ context 'when ref exists' do
+ it 'cherry-picks the ref commit' do
+ post api(route, current_user), branch: branch
+
+ expect(response).to have_gitlab_http_status(201)
+ expect(response).to match_response_schema('public_api/v4/commit/basic')
+ expect(json_response['title']).to eq(commit.title)
+ expect(json_response['message']).to eq(commit.message)
+ expect(json_response['author_name']).to eq(commit.author_name)
+ expect(json_response['committer_name']).to eq(user.name)
+ end
+ end
- context 'authorized user' do
- it 'cherry picks a commit' do
- post api("/projects/#{project.id}/repository/commits/#{master_pickable_commit.id}/cherry_pick", user), branch: 'master'
+ context 'when repository is disabled' do
+ include_context 'disabled repository'
- expect(response).to have_http_status(201)
- expect(json_response['title']).to eq(master_pickable_commit.title)
- expect(json_response['message']).to eq(master_pickable_commit.message)
- expect(json_response['author_name']).to eq(master_pickable_commit.author_name)
- expect(json_response['committer_name']).to eq(user.name)
+ it_behaves_like '403 response' do
+ let(:request) { post api(route, current_user), branch: 'master' }
+ end
end
+ end
- it 'returns 400 if commit is already included in the target branch' do
- post api("/projects/#{project.id}/repository/commits/#{master_pickable_commit.id}/cherry_pick", user), branch: 'markdown'
+ context 'when unauthenticated', 'and project is public' do
+ let(:project) { create(:project, :public, :repository) }
- expect(response).to have_http_status(400)
- expect(json_response['message']).to include('Sorry, we cannot cherry-pick this commit automatically.')
+ it_behaves_like '403 response' do
+ let(:request) { post api(route), branch: 'master' }
+ end
+ end
+
+ context 'when unauthenticated', 'and project is private' do
+ it_behaves_like '404 response' do
+ let(:request) { post api(route), branch: 'master' }
+ let(:message) { '404 Project Not Found' }
end
+ end
- it 'returns 400 if you are not allowed to push to the target branch' do
- project.team << [user2, :developer]
- protected_branch = create(:protected_branch, project: project, name: 'feature')
+ context 'when authenticated', 'as an owner' do
+ let(:current_user) { user }
- post api("/projects/#{project.id}/repository/commits/#{master_pickable_commit.id}/cherry_pick", user2), branch: protected_branch.name
+ it_behaves_like 'ref cherry-pick'
- expect(response).to have_http_status(400)
- expect(json_response['message']).to eq('You are not allowed to push into this branch')
+ context 'when ref does not exist' do
+ let(:commit_id) { 'unknown' }
+
+ it_behaves_like '404 response' do
+ let(:request) { post api(route, current_user), branch: 'master' }
+ let(:message) { '404 Commit Not Found' }
+ end
+ end
+
+ context 'when branch is missing' do
+ it_behaves_like '400 response' do
+ let(:request) { post api(route, current_user) }
+ end
end
- it 'returns 400 for missing parameters' do
- post api("/projects/#{project.id}/repository/commits/#{master_pickable_commit.id}/cherry_pick", user)
+ context 'when branch does not exist' do
+ it_behaves_like '404 response' do
+ let(:request) { post api(route, current_user), branch: 'foo' }
+ let(:message) { '404 Branch Not Found' }
+ end
+ end
- expect(response).to have_http_status(400)
- expect(json_response['error']).to eq('branch is missing')
+ context 'when commit is already included in the target branch' do
+ it_behaves_like '400 response' do
+ let(:request) { post api(route, current_user), branch: 'markdown' }
+ end
end
- it 'returns 404 if commit is not found' do
- post api("/projects/#{project.id}/repository/commits/abcd0123/cherry_pick", user), branch: 'master'
+ context 'when ref contains a dot' do
+ let(:commit) { project.repository.commit(branch_with_dot.name) }
+ let(:commit_id) { branch_with_dot.name }
- expect(response).to have_http_status(404)
- expect(json_response['message']).to eq('404 Commit Not Found')
+ it_behaves_like 'ref cherry-pick'
end
- it 'returns 404 if branch is not found' do
- post api("/projects/#{project.id}/repository/commits/#{master_pickable_commit.id}/cherry_pick", user), branch: 'foo'
+ context 'when ref contains a slash' do
+ let(:commit_id) { branch_with_slash.name }
- expect(response).to have_http_status(404)
- expect(json_response['message']).to eq('404 Branch Not Found')
+ it_behaves_like '404 response' do
+ let(:request) { post api(route, current_user), branch: 'master' }
+ end
end
- it 'returns 400 for missing parameters' do
- post api("/projects/#{project.id}/repository/commits/#{master_pickable_commit.id}/cherry_pick", user)
+ context 'requesting with the escaped project full path' do
+ let(:project_id) { CGI.escape(project.full_path) }
- expect(response).to have_http_status(400)
- expect(json_response['error']).to eq('branch is missing')
+ it_behaves_like 'ref cherry-pick'
+
+ context 'when ref contains a dot' do
+ let(:commit) { project.repository.commit(branch_with_dot.name) }
+ let(:commit_id) { branch_with_dot.name }
+
+ it_behaves_like 'ref cherry-pick'
+ end
end
end
- context 'unauthorized user' do
- it 'does not cherry pick the commit' do
- post api("/projects/#{project.id}/repository/commits/#{master_pickable_commit.id}/cherry_pick"), branch: 'master'
+ context 'when authenticated', 'as a developer' do
+ let(:current_user) { guest }
+
+ before do
+ project.add_developer(guest)
+ end
+
+ context 'when branch is protected' do
+ before do
+ create(:protected_branch, project: project, name: 'feature')
+ end
+
+ it 'returns 400 if you are not allowed to push to the target branch' do
+ post api(route, current_user), branch: 'feature'
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(400)
+ expect(json_response['message']).to eq('You are not allowed to push into this branch')
+ end
end
end
end
- describe 'Post comment to commit' do
- context 'authorized user' do
- it 'returns comment' do
- post api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}/comments", user), note: 'My comment'
- expect(response).to have_http_status(201)
- expect(json_response['note']).to eq('My comment')
- expect(json_response['path']).to be_nil
- expect(json_response['line']).to be_nil
- expect(json_response['line_type']).to be_nil
+ describe 'POST /projects/:id/repository/commits/:sha/comments' do
+ let(:commit) { project.repository.commit }
+ let(:commit_id) { commit.id }
+ let(:note) { 'My comment' }
+ let(:route) { "/projects/#{project_id}/repository/commits/#{commit_id}/comments" }
+
+ shared_examples_for 'ref new comment' do
+ context 'when ref exists' do
+ it 'creates the comment' do
+ post api(route, current_user), note: note
+
+ expect(response).to have_gitlab_http_status(201)
+ expect(response).to match_response_schema('public_api/v4/commit_note')
+ expect(json_response['note']).to eq('My comment')
+ expect(json_response['path']).to be_nil
+ expect(json_response['line']).to be_nil
+ expect(json_response['line_type']).to be_nil
+ end
end
+ context 'when repository is disabled' do
+ include_context 'disabled repository'
+
+ it_behaves_like '403 response' do
+ let(:request) { post api(route, current_user), note: 'My comment' }
+ end
+ end
+ end
+
+ context 'when unauthenticated', 'and project is public' do
+ let(:project) { create(:project, :public, :repository) }
+
+ it_behaves_like '400 response' do
+ let(:request) { post api(route), note: 'My comment' }
+ end
+ end
+
+ context 'when unauthenticated', 'and project is private' do
+ it_behaves_like '404 response' do
+ let(:request) { post api(route), note: 'My comment' }
+ let(:message) { '404 Project Not Found' }
+ end
+ end
+
+ context 'when authenticated', 'as an owner' do
+ let(:current_user) { user }
+
+ it_behaves_like 'ref new comment'
+
it 'returns the inline comment' do
- post api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}/comments", user), note: 'My comment', path: project.repository.commit.raw_diffs.first.new_path, line: 1, line_type: 'new'
+ post api(route, current_user), note: 'My comment', path: project.repository.commit.raw_diffs.first.new_path, line: 1, line_type: 'new'
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
+ expect(response).to match_response_schema('public_api/v4/commit_note')
expect(json_response['note']).to eq('My comment')
expect(json_response['path']).to eq(project.repository.commit.raw_diffs.first.new_path)
expect(json_response['line']).to eq(1)
expect(json_response['line_type']).to eq('new')
end
+ context 'when ref does not exist' do
+ let(:commit_id) { 'unknown' }
+
+ it_behaves_like '404 response' do
+ let(:request) { post api(route, current_user), note: 'My comment' }
+ let(:message) { '404 Commit Not Found' }
+ end
+ end
+
it 'returns 400 if note is missing' do
- post api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}/comments", user)
- expect(response).to have_http_status(400)
+ post api(route, current_user)
+
+ expect(response).to have_gitlab_http_status(400)
end
- it 'returns 404 if note is attached to non existent commit' do
- post api("/projects/#{project.id}/repository/commits/1234ab/comments", user), note: 'My comment'
- expect(response).to have_http_status(404)
+ context 'when ref contains a dot' do
+ let(:commit_id) { branch_with_dot.name }
+
+ it_behaves_like 'ref new comment'
end
- end
- context 'unauthorized user' do
- it 'does not return the diff of the selected commit' do
- post api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}/comments")
- expect(response).to have_http_status(401)
+ context 'when ref contains a slash' do
+ let(:commit_id) { branch_with_slash.name }
+
+ it_behaves_like '404 response' do
+ let(:request) { post api(route, current_user), note: 'My comment' }
+ end
+ end
+
+ context 'when ref contains an escaped slash' do
+ let(:commit_id) { CGI.escape(branch_with_slash.name) }
+
+ it_behaves_like 'ref new comment'
+ end
+
+ context 'requesting with the escaped project full path' do
+ let(:project_id) { CGI.escape(project.full_path) }
+
+ it_behaves_like 'ref new comment'
+
+ context 'when ref contains a dot' do
+ let(:commit_id) { branch_with_dot.name }
+
+ it_behaves_like 'ref new comment'
+ end
end
end
end
diff --git a/spec/requests/api/deploy_keys_spec.rb b/spec/requests/api/deploy_keys_spec.rb
index 32439981b60..e497ec333a2 100644
--- a/spec/requests/api/deploy_keys_spec.rb
+++ b/spec/requests/api/deploy_keys_spec.rb
@@ -3,8 +3,8 @@ require 'spec_helper'
describe API::DeployKeys do
let(:user) { create(:user) }
let(:admin) { create(:admin) }
- let(:project) { create(:empty_project, creator_id: user.id) }
- let(:project2) { create(:empty_project, creator_id: user.id) }
+ let(:project) { create(:project, creator_id: user.id) }
+ let(:project2) { create(:project, creator_id: user.id) }
let(:deploy_key) { create(:deploy_key, public: true) }
let!(:deploy_keys_project) do
@@ -182,7 +182,7 @@ describe API::DeployKeys do
delete api("/projects/#{project.id}/deploy_keys/#{deploy_key.id}", admin)
expect(response).to have_http_status(204)
- end.to change{ project.deploy_keys.count }.by(-1)
+ end.to change { project.deploy_keys.count }.by(-1)
end
it 'returns 404 Not Found with invalid ID' do
@@ -193,7 +193,7 @@ describe API::DeployKeys do
end
describe 'POST /projects/:id/deploy_keys/:key_id/enable' do
- let(:project2) { create(:empty_project) }
+ let(:project2) { create(:project) }
context 'when the user can admin the project' do
it 'enables the key' do
diff --git a/spec/requests/api/environments_spec.rb b/spec/requests/api/environments_spec.rb
index aae03c84e1f..87716c6fe3a 100644
--- a/spec/requests/api/environments_spec.rb
+++ b/spec/requests/api/environments_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe API::Environments do
let(:user) { create(:user) }
let(:non_member) { create(:user) }
- let(:project) { create(:empty_project, :private, namespace: user.namespace) }
+ let(:project) { create(:project, :private, namespace: user.namespace) }
let!(:environment) { create(:environment, project: project) }
before do
@@ -13,7 +13,14 @@ describe API::Environments do
describe 'GET /projects/:id/environments' do
context 'as member of the project' do
it 'returns project environments' do
- project_data_keys = %w(id http_url_to_repo web_url name name_with_namespace path path_with_namespace)
+ project_data_keys = %w(
+ id description default_branch tag_list
+ ssh_url_to_repo http_url_to_repo web_url
+ name name_with_namespace
+ path path_with_namespace
+ star_count forks_count
+ created_at last_activity_at
+ )
get api("/projects/#{project.id}/environments", user)
diff --git a/spec/requests/api/events_spec.rb b/spec/requests/api/events_spec.rb
index 1754ba66a96..a23d28994ce 100644
--- a/spec/requests/api/events_spec.rb
+++ b/spec/requests/api/events_spec.rb
@@ -5,7 +5,7 @@ describe API::Events do
let(:user) { create(:user) }
let(:non_member) { create(:user) }
let(:other_user) { create(:user, username: 'otheruser') }
- let(:private_project) { create(:empty_project, :private, creator_id: user.id, namespace: user.namespace) }
+ let(:private_project) { create(:project, :private, creator_id: user.id, namespace: user.namespace) }
let(:closed_issue) { create(:closed_issue, project: private_project, author: user) }
let!(:closed_issue_event) { create(:event, project: private_project, author: user, target: closed_issue, action: Event::CLOSED, created_at: Date.new(2016, 12, 30)) }
@@ -59,8 +59,36 @@ describe API::Events do
expect(json_response.size).to eq(1)
end
+ context 'when the list of events includes push events' do
+ let(:event) do
+ create(:push_event, author: user, project: private_project)
+ end
+
+ let!(:payload) { create(:push_event_payload, event: event) }
+ let(:payload_hash) { json_response[0]['push_data'] }
+
+ before do
+ get api("/users/#{user.id}/events?action=pushed", user)
+ end
+
+ it 'responds with HTTP 200 OK' do
+ expect(response).to have_http_status(200)
+ end
+
+ it 'includes the push payload as a Hash' do
+ expect(payload_hash).to be_an_instance_of(Hash)
+ end
+
+ it 'includes the push payload details' do
+ expect(payload_hash['commit_count']).to eq(payload.commit_count)
+ expect(payload_hash['action']).to eq(payload.action)
+ expect(payload_hash['ref_type']).to eq(payload.ref_type)
+ expect(payload_hash['commit_to']).to eq(payload.commit_to)
+ end
+ end
+
context 'when there are multiple events from different projects' do
- let(:second_note) { create(:note_on_issue, project: create(:empty_project)) }
+ let(:second_note) { create(:note_on_issue, project: create(:project)) }
before do
second_note.project.add_user(user, :developer)
@@ -106,7 +134,7 @@ describe API::Events do
end
it 'returns 200 status for a public project' do
- public_project = create(:empty_project, :public)
+ public_project = create(:project, :public)
get api("/projects/#{public_project.id}/events")
@@ -138,5 +166,35 @@ describe API::Events do
expect(response).to have_http_status(404)
end
end
+
+ context 'when exists some events' do
+ let(:merge_request1) { create(:merge_request, :closed, author: user, assignee: user, source_project: private_project, title: 'Test') }
+ let(:merge_request2) { create(:merge_request, :closed, author: user, assignee: user, source_project: private_project, title: 'Test') }
+
+ before do
+ create_event(merge_request1)
+ end
+
+ it 'avoids N+1 queries' do
+ control_count = ActiveRecord::QueryRecorder.new do
+ get api("/projects/#{private_project.id}/events", user), target_type: :merge_request
+ end.count
+
+ create_event(merge_request2)
+
+ expect do
+ get api("/projects/#{private_project.id}/events", user), target_type: :merge_request
+ end.not_to exceed_query_limit(control_count)
+
+ expect(response).to have_gitlab_http_status(200)
+ expect(response).to include_pagination_headers
+ expect(json_response.size).to eq(2)
+ expect(json_response.map { |r| r['target_id'] }).to match_array([merge_request1.id, merge_request2.id])
+ end
+
+ def create_event(target)
+ create(:event, project: private_project, author: user, target: target)
+ end
+ end
end
end
diff --git a/spec/requests/api/files_spec.rb b/spec/requests/api/files_spec.rb
index 9e268adf950..ea97c556430 100644
--- a/spec/requests/api/files_spec.rb
+++ b/spec/requests/api/files_spec.rb
@@ -33,6 +33,15 @@ describe API::Files do
expect(Base64.decode64(json_response['content']).lines.first).to eq("require 'fileutils'\n")
end
+ it 'returns json when file has txt extension' do
+ file_path = "bar%2Fbranch-test.txt"
+
+ get api(route(file_path), current_user), params
+
+ expect(response).to have_http_status(200)
+ expect(response.content_type).to eq('application/json')
+ end
+
it 'returns file by commit sha' do
# This file is deleted on HEAD
file_path = "files%2Fjs%2Fcommit%2Ejs%2Ecoffee"
@@ -80,7 +89,7 @@ describe API::Files do
context 'when unauthenticated', 'and project is public' do
it_behaves_like 'repository files' do
- let(:project) { create(:project, :public) }
+ let(:project) { create(:project, :public, :repository) }
let(:current_user) { nil }
end
end
@@ -153,7 +162,7 @@ describe API::Files do
context 'when unauthenticated', 'and project is public' do
it_behaves_like 'repository raw files' do
- let(:project) { create(:project, :public) }
+ let(:project) { create(:project, :public, :repository) }
let(:current_user) { nil }
end
end
@@ -220,6 +229,7 @@ describe API::Files do
post api(route("new_file_with_author%2Etxt"), user), valid_params
expect(response).to have_http_status(201)
+ expect(response.content_type).to eq('application/json')
last_commit = project.repository.commit.raw
expect(last_commit.author_email).to eq(author_email)
expect(last_commit.author_name).to eq(author_name)
diff --git a/spec/requests/api/group_milestones_spec.rb b/spec/requests/api/group_milestones_spec.rb
index 9b24658771f..108721c6655 100644
--- a/spec/requests/api/group_milestones_spec.rb
+++ b/spec/requests/api/group_milestones_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe API::GroupMilestones do
let(:user) { create(:user) }
let(:group) { create(:group, :private) }
- let(:project) { create(:empty_project, namespace: group) }
+ let(:project) { create(:project, namespace: group) }
let!(:group_member) { create(:group_member, group: group, user: user) }
let!(:closed_milestone) { create(:closed_milestone, group: group, title: 'version1', description: 'closed milestone') }
let!(:milestone) { create(:milestone, group: group, title: 'version2', description: 'open milestone') }
diff --git a/spec/requests/api/group_variables_spec.rb b/spec/requests/api/group_variables_spec.rb
new file mode 100644
index 00000000000..2179790d098
--- /dev/null
+++ b/spec/requests/api/group_variables_spec.rb
@@ -0,0 +1,221 @@
+require 'spec_helper'
+
+describe API::GroupVariables do
+ let(:group) { create(:group) }
+ let(:user) { create(:user) }
+
+ describe 'GET /groups/:id/variables' do
+ let!(:variable) { create(:ci_group_variable, group: group) }
+
+ context 'authorized user with proper permissions' do
+ before do
+ group.add_master(user)
+ end
+
+ it 'returns group variables' do
+ get api("/groups/#{group.id}/variables", user)
+
+ expect(response).to have_http_status(200)
+ expect(json_response).to be_a(Array)
+ end
+ end
+
+ context 'authorized user with invalid permissions' do
+ it 'does not return group variables' do
+ get api("/groups/#{group.id}/variables", user)
+
+ expect(response).to have_http_status(403)
+ end
+ end
+
+ context 'unauthorized user' do
+ it 'does not return group variables' do
+ get api("/groups/#{group.id}/variables")
+
+ expect(response).to have_http_status(401)
+ end
+ end
+ end
+
+ describe 'GET /groups/:id/variables/:key' do
+ let!(:variable) { create(:ci_group_variable, group: group) }
+
+ context 'authorized user with proper permissions' do
+ before do
+ group.add_master(user)
+ end
+
+ it 'returns group variable details' do
+ get api("/groups/#{group.id}/variables/#{variable.key}", user)
+
+ expect(response).to have_http_status(200)
+ expect(json_response['value']).to eq(variable.value)
+ expect(json_response['protected']).to eq(variable.protected?)
+ end
+
+ it 'responds with 404 Not Found if requesting non-existing variable' do
+ get api("/groups/#{group.id}/variables/non_existing_variable", user)
+
+ expect(response).to have_http_status(404)
+ end
+ end
+
+ context 'authorized user with invalid permissions' do
+ it 'does not return group variable details' do
+ get api("/groups/#{group.id}/variables/#{variable.key}", user)
+
+ expect(response).to have_http_status(403)
+ end
+ end
+
+ context 'unauthorized user' do
+ it 'does not return group variable details' do
+ get api("/groups/#{group.id}/variables/#{variable.key}")
+
+ expect(response).to have_http_status(401)
+ end
+ end
+ end
+
+ describe 'POST /groups/:id/variables' do
+ context 'authorized user with proper permissions' do
+ let!(:variable) { create(:ci_group_variable, group: group) }
+
+ before do
+ group.add_master(user)
+ end
+
+ it 'creates variable' do
+ expect do
+ post api("/groups/#{group.id}/variables", user), key: 'TEST_VARIABLE_2', value: 'VALUE_2', protected: true
+ end.to change {group.variables.count}.by(1)
+
+ expect(response).to have_http_status(201)
+ expect(json_response['key']).to eq('TEST_VARIABLE_2')
+ expect(json_response['value']).to eq('VALUE_2')
+ expect(json_response['protected']).to be_truthy
+ end
+
+ it 'creates variable with optional attributes' do
+ expect do
+ post api("/groups/#{group.id}/variables", user), key: 'TEST_VARIABLE_2', value: 'VALUE_2'
+ end.to change {group.variables.count}.by(1)
+
+ expect(response).to have_http_status(201)
+ expect(json_response['key']).to eq('TEST_VARIABLE_2')
+ expect(json_response['value']).to eq('VALUE_2')
+ expect(json_response['protected']).to be_falsey
+ end
+
+ it 'does not allow to duplicate variable key' do
+ expect do
+ post api("/groups/#{group.id}/variables", user), key: variable.key, value: 'VALUE_2'
+ end.to change {group.variables.count}.by(0)
+
+ expect(response).to have_http_status(400)
+ end
+ end
+
+ context 'authorized user with invalid permissions' do
+ it 'does not create variable' do
+ post api("/groups/#{group.id}/variables", user)
+
+ expect(response).to have_http_status(403)
+ end
+ end
+
+ context 'unauthorized user' do
+ it 'does not create variable' do
+ post api("/groups/#{group.id}/variables")
+
+ expect(response).to have_http_status(401)
+ end
+ end
+ end
+
+ describe 'PUT /groups/:id/variables/:key' do
+ let!(:variable) { create(:ci_group_variable, group: group) }
+
+ context 'authorized user with proper permissions' do
+ before do
+ group.add_master(user)
+ end
+
+ it 'updates variable data' do
+ initial_variable = group.variables.first
+ value_before = initial_variable.value
+
+ put api("/groups/#{group.id}/variables/#{variable.key}", user), value: 'VALUE_1_UP', protected: true
+
+ updated_variable = group.variables.first
+
+ expect(response).to have_http_status(200)
+ expect(value_before).to eq(variable.value)
+ expect(updated_variable.value).to eq('VALUE_1_UP')
+ expect(updated_variable).to be_protected
+ end
+
+ it 'responds with 404 Not Found if requesting non-existing variable' do
+ put api("/groups/#{group.id}/variables/non_existing_variable", user)
+
+ expect(response).to have_http_status(404)
+ end
+ end
+
+ context 'authorized user with invalid permissions' do
+ it 'does not update variable' do
+ put api("/groups/#{group.id}/variables/#{variable.key}", user)
+
+ expect(response).to have_http_status(403)
+ end
+ end
+
+ context 'unauthorized user' do
+ it 'does not update variable' do
+ put api("/groups/#{group.id}/variables/#{variable.key}")
+
+ expect(response).to have_http_status(401)
+ end
+ end
+ end
+
+ describe 'DELETE /groups/:id/variables/:key' do
+ let!(:variable) { create(:ci_group_variable, group: group) }
+
+ context 'authorized user with proper permissions' do
+ before do
+ group.add_master(user)
+ end
+
+ it 'deletes variable' do
+ expect do
+ delete api("/groups/#{group.id}/variables/#{variable.key}", user)
+
+ expect(response).to have_http_status(204)
+ end.to change {group.variables.count}.by(-1)
+ end
+
+ it 'responds with 404 Not Found if requesting non-existing variable' do
+ delete api("/groups/#{group.id}/variables/non_existing_variable", user)
+
+ expect(response).to have_http_status(404)
+ end
+ end
+
+ context 'authorized user with invalid permissions' do
+ it 'does not delete variable' do
+ delete api("/groups/#{group.id}/variables/#{variable.key}", user)
+
+ expect(response).to have_http_status(403)
+ end
+ end
+
+ context 'unauthorized user' do
+ it 'does not delete variable' do
+ delete api("/groups/#{group.id}/variables/#{variable.key}")
+
+ expect(response).to have_http_status(401)
+ end
+ end
+ end
+end
diff --git a/spec/requests/api/groups_spec.rb b/spec/requests/api/groups_spec.rb
index 1d7adc6ac45..313c38cd29c 100644
--- a/spec/requests/api/groups_spec.rb
+++ b/spec/requests/api/groups_spec.rb
@@ -9,9 +9,9 @@ describe API::Groups do
let(:admin) { create(:admin) }
let!(:group1) { create(:group, avatar: File.open(uploaded_image_temp_path)) }
let!(:group2) { create(:group, :private) }
- let!(:project1) { create(:empty_project, namespace: group1) }
- let!(:project2) { create(:empty_project, namespace: group2) }
- let!(:project3) { create(:empty_project, namespace: group1, path: 'test', visibility_level: Gitlab::VisibilityLevel::PRIVATE) }
+ let!(:project1) { create(:project, namespace: group1) }
+ let!(:project2) { create(:project, namespace: group2) }
+ let!(:project3) { create(:project, namespace: group1, path: 'test', visibility_level: Gitlab::VisibilityLevel::PRIVATE) }
before do
group1.add_owner(user1)
@@ -167,7 +167,7 @@ describe API::Groups do
describe "GET /groups/:id" do
context "when authenticated as user" do
it "returns one of user1's groups" do
- project = create(:empty_project, namespace: group2, path: 'Foo')
+ project = create(:project, namespace: group2, path: 'Foo')
create(:project_group_link, project: project, group: group1)
get api("/groups/#{group1.id}", user1)
@@ -311,7 +311,7 @@ describe API::Groups do
end
it 'filters the groups projects' do
- public_project = create(:empty_project, :public, path: 'test1', group: group1)
+ public_project = create(:project, :public, path: 'test1', group: group1)
get api("/groups/#{group1.id}/projects", user1), visibility: 'public'
@@ -509,10 +509,10 @@ describe API::Groups do
end
describe "POST /groups/:id/projects/:project_id" do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:project_path) { CGI.escape(project.full_path) }
- before(:each) do
+ before do
allow_any_instance_of(Projects::TransferService)
.to receive(:execute).and_return(true)
end
diff --git a/spec/requests/api/helpers_spec.rb b/spec/requests/api/helpers_spec.rb
index 7a1bd76af7a..d4006fe71a2 100644
--- a/spec/requests/api/helpers_spec.rb
+++ b/spec/requests/api/helpers_spec.rb
@@ -56,7 +56,7 @@ describe API::Helpers do
end
def doorkeeper_guard_returns(value)
- allow_any_instance_of(self.class).to receive(:doorkeeper_guard){ value }
+ allow_any_instance_of(self.class).to receive(:doorkeeper_guard) { value }
end
def error!(message, status, header)
@@ -161,7 +161,7 @@ describe API::Helpers do
describe "when authenticating using a user's private token" do
it "returns nil for an invalid token" do
env[API::APIGuard::PRIVATE_TOKEN_HEADER] = 'invalid token'
- allow_any_instance_of(self.class).to receive(:doorkeeper_guard){ false }
+ allow_any_instance_of(self.class).to receive(:doorkeeper_guard) { false }
expect(current_user).to be_nil
end
diff --git a/spec/requests/api/internal_spec.rb b/spec/requests/api/internal_spec.rb
index ce9b9ac1eb3..e9c30dba8d4 100644
--- a/spec/requests/api/internal_spec.rb
+++ b/spec/requests/api/internal_spec.rb
@@ -181,13 +181,12 @@ describe API::Internal do
describe "POST /internal/allowed", :clean_gitlab_redis_shared_state do
context "access granted" do
- before do
- project.team << [user, :developer]
- Timecop.freeze
+ around do |example|
+ Timecop.freeze { example.run }
end
- after do
- Timecop.return
+ before do
+ project.team << [user, :developer]
end
context 'with env passed as a JSON' do
@@ -301,7 +300,7 @@ describe API::Internal do
context 'project as /namespace/project' do
it do
- pull(key, project_with_repo_path('/' + project.path_with_namespace))
+ pull(key, project_with_repo_path('/' + project.full_path))
expect(response).to have_http_status(200)
expect(json_response["status"]).to be_truthy
@@ -312,7 +311,7 @@ describe API::Internal do
context 'project as namespace/project' do
it do
- pull(key, project_with_repo_path(project.path_with_namespace))
+ pull(key, project_with_repo_path(project.full_path))
expect(response).to have_http_status(200)
expect(json_response["status"]).to be_truthy
@@ -350,7 +349,7 @@ describe API::Internal do
end
context "blocked user" do
- let(:personal_project) { create(:empty_project, namespace: user.namespace) }
+ let(:personal_project) { create(:project, namespace: user.namespace) }
before do
user.block
diff --git a/spec/requests/api/issues_spec.rb b/spec/requests/api/issues_spec.rb
index 2c44be4e447..7d120e4a234 100644
--- a/spec/requests/api/issues_spec.rb
+++ b/spec/requests/api/issues_spec.rb
@@ -1,11 +1,9 @@
require 'spec_helper'
-describe API::Issues do
- include EmailHelpers
-
+describe API::Issues, :mailer do
set(:user) { create(:user) }
set(:project) do
- create(:empty_project, :public, creator_id: user.id, namespace: user.namespace)
+ create(:project, :public, creator_id: user.id, namespace: user.namespace)
end
let(:user2) { create(:user) }
@@ -296,7 +294,7 @@ describe API::Issues do
describe "GET /groups/:id/issues" do
let!(:group) { create(:group) }
- let!(:group_project) { create(:empty_project, :public, creator_id: user.id, namespace: group) }
+ let!(:group_project) { create(:project, :public, creator_id: user.id, namespace: group) }
let!(:group_closed_issue) do
create :closed_issue,
author: user,
@@ -518,7 +516,7 @@ describe API::Issues do
end
it "returns 404 on private projects for other users" do
- private_project = create(:empty_project, :private)
+ private_project = create(:project, :private)
create(:issue, project: private_project)
get api("/projects/#{private_project.id}/issues", non_member)
@@ -527,7 +525,7 @@ describe API::Issues do
end
it 'returns no issues when user has access to project but not issues' do
- restricted_project = create(:empty_project, :public, :issues_private)
+ restricted_project = create(:project, :public, :issues_private)
create(:issue, project: restricted_project)
get api("/projects/#{restricted_project.id}/issues", non_member)
@@ -1299,7 +1297,7 @@ describe API::Issues do
context "when the user is project owner" do
let(:owner) { create(:user) }
- let(:project) { create(:empty_project, namespace: owner.namespace) }
+ let(:project) { create(:project, namespace: owner.namespace) }
it "deletes the issue if an admin requests it" do
delete api("/projects/#{project.id}/issues/#{issue.iid}", owner)
@@ -1324,8 +1322,8 @@ describe API::Issues do
end
describe '/projects/:id/issues/:issue_iid/move' do
- let!(:target_project) { create(:empty_project, path: 'project2', creator_id: user.id, namespace: user.namespace ) }
- let!(:target_project2) { create(:empty_project, creator_id: non_member.id, namespace: non_member.namespace ) }
+ let!(:target_project) { create(:project, path: 'project2', creator_id: user.id, namespace: user.namespace ) }
+ let!(:target_project2) { create(:project, creator_id: non_member.id, namespace: non_member.namespace ) }
it 'moves an issue' do
post api("/projects/#{project.id}/issues/#{issue.iid}/move", user),
diff --git a/spec/requests/api/labels_spec.rb b/spec/requests/api/labels_spec.rb
index f7e2f1908bb..5a4257d1009 100644
--- a/spec/requests/api/labels_spec.rb
+++ b/spec/requests/api/labels_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe API::Labels do
let(:user) { create(:user) }
- let(:project) { create(:empty_project, creator_id: user.id, namespace: user.namespace) }
+ let(:project) { create(:project, creator_id: user.id, namespace: user.namespace) }
let!(:label1) { create(:label, title: 'label1', project: project) }
let!(:priority_label) { create(:label, title: 'bug', project: project, priority: 3) }
diff --git a/spec/requests/api/members_spec.rb b/spec/requests/api/members_spec.rb
index e095053fa03..06aca698c91 100644
--- a/spec/requests/api/members_spec.rb
+++ b/spec/requests/api/members_spec.rb
@@ -7,7 +7,7 @@ describe API::Members do
let(:stranger) { create(:user) }
let(:project) do
- create(:empty_project, :public, :access_requestable, creator_id: master.id, namespace: master.namespace) do |project|
+ create(:project, :public, :access_requestable, creator_id: master.id, namespace: master.namespace) do |project|
project.team << [developer, :developer]
project.team << [master, :master]
project.request_access(access_requester)
diff --git a/spec/requests/api/merge_requests_spec.rb b/spec/requests/api/merge_requests_spec.rb
index 2760c4ffde2..0db645863fb 100644
--- a/spec/requests/api/merge_requests_spec.rb
+++ b/spec/requests/api/merge_requests_spec.rb
@@ -31,19 +31,19 @@ describe API::MergeRequests do
it 'returns authentication error' do
get api('/merge_requests')
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
context 'when authenticated' do
- let!(:project2) { create(:empty_project, :public, namespace: user.namespace) }
+ let!(:project2) { create(:project, :public, namespace: user.namespace) }
let!(:merge_request2) { create(:merge_request, :simple, author: user, assignee: user, source_project: project2, target_project: project2) }
let(:user2) { create(:user) }
it 'returns an array of all merge requests' do
get api('/merge_requests', user), scope: :all
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.map { |mr| mr['id'] })
@@ -51,12 +51,12 @@ describe API::MergeRequests do
end
it 'does not return unauthorized merge requests' do
- private_project = create(:empty_project, :private)
+ private_project = create(:project, :private)
merge_request3 = create(:merge_request, :simple, source_project: private_project, target_project: private_project, source_branch: 'other-branch')
get api('/merge_requests', user), scope: :all
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.map { |mr| mr['id'] })
@@ -68,7 +68,7 @@ describe API::MergeRequests do
get api('/merge_requests', user2)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
expect(json_response.first['id']).to eq(merge_request3.id)
@@ -79,7 +79,7 @@ describe API::MergeRequests do
get api('/merge_requests', user), author_id: user2.id, scope: :all
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
expect(json_response.first['id']).to eq(merge_request3.id)
@@ -90,7 +90,7 @@ describe API::MergeRequests do
get api('/merge_requests', user), assignee_id: user2.id, scope: :all
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
expect(json_response.first['id']).to eq(merge_request3.id)
@@ -101,7 +101,7 @@ describe API::MergeRequests do
get api('/merge_requests', user2), scope: 'assigned-to-me'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
expect(json_response.first['id']).to eq(merge_request3.id)
@@ -112,7 +112,7 @@ describe API::MergeRequests do
get api('/merge_requests', user2), scope: 'created-by-me'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
expect(json_response.first['id']).to eq(merge_request3.id)
@@ -125,7 +125,7 @@ describe API::MergeRequests do
it "returns authentication error" do
get api("/projects/#{project.id}/merge_requests")
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
end
end
@@ -145,7 +145,7 @@ describe API::MergeRequests do
it "returns an array of all merge_requests" do
get api("/projects/#{project.id}/merge_requests", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(3)
@@ -166,7 +166,7 @@ describe API::MergeRequests do
it "returns an array of all merge_requests using simple mode" do
get api("/projects/#{project.id}/merge_requests?view=simple", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response.last.keys).to match_array(%w(id iid title web_url created_at description project_id state updated_at))
expect(json_response).to be_an Array
@@ -182,7 +182,7 @@ describe API::MergeRequests do
it "returns an array of all merge_requests" do
get api("/projects/#{project.id}/merge_requests?state", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(3)
@@ -192,7 +192,7 @@ describe API::MergeRequests do
it "returns an array of open merge_requests" do
get api("/projects/#{project.id}/merge_requests?state=opened", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
@@ -202,7 +202,7 @@ describe API::MergeRequests do
it "returns an array of closed merge_requests" do
get api("/projects/#{project.id}/merge_requests?state=closed", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
@@ -212,7 +212,7 @@ describe API::MergeRequests do
it "returns an array of merged merge_requests" do
get api("/projects/#{project.id}/merge_requests?state=merged", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
@@ -222,7 +222,7 @@ describe API::MergeRequests do
it 'returns merge_request by "iids" array' do
get api("/projects/#{project.id}/merge_requests", user), iids: [merge_request.iid, merge_request_closed.iid]
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(2)
expect(json_response.first['title']).to eq merge_request_closed.title
@@ -232,14 +232,14 @@ describe API::MergeRequests do
it 'matches V4 response schema' do
get api("/projects/#{project.id}/merge_requests", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to match_response_schema('public_api/v4/merge_requests')
end
it 'returns an empty array if no issue matches milestone' do
get api("/projects/#{project.id}/merge_requests", user), milestone: '1.0.0'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(0)
end
@@ -247,7 +247,7 @@ describe API::MergeRequests do
it 'returns an empty array if milestone does not exist' do
get api("/projects/#{project.id}/merge_requests", user), milestone: 'foo'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(0)
end
@@ -262,7 +262,7 @@ describe API::MergeRequests do
it 'returns an array of merge requests matching state in milestone' do
get api("/projects/#{project.id}/merge_requests", user), milestone: '0.9', state: 'closed'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
expect(json_response.first['id']).to eq(merge_request_closed.id)
@@ -271,7 +271,7 @@ describe API::MergeRequests do
it 'returns an array of labeled merge requests' do
get api("/projects/#{project.id}/merge_requests?labels=#{label.title}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
expect(json_response.first['labels']).to eq([label2.title, label.title])
@@ -280,7 +280,7 @@ describe API::MergeRequests do
it 'returns an array of labeled merge requests where all labels match' do
get api("/projects/#{project.id}/merge_requests?labels=#{label.title},foo,bar", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(0)
end
@@ -288,11 +288,31 @@ describe API::MergeRequests do
it 'returns an empty array if no merge request matches labels' do
get api("/projects/#{project.id}/merge_requests?labels=foo,bar", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(0)
end
+ it 'returns an array of labeled merge requests that are merged for a milestone' do
+ bug_label = create(:label, title: 'bug', color: '#FFAABB', project: project)
+
+ mr1 = create(:merge_request, state: "merged", source_project: project, target_project: project, milestone: milestone)
+ mr2 = create(:merge_request, state: "merged", source_project: project, target_project: project, milestone: milestone1)
+ mr3 = create(:merge_request, state: "closed", source_project: project, target_project: project, milestone: milestone1)
+ _mr = create(:merge_request, state: "merged", source_project: project, target_project: project, milestone: milestone1)
+
+ create(:label_link, label: bug_label, target: mr1)
+ create(:label_link, label: bug_label, target: mr2)
+ create(:label_link, label: bug_label, target: mr3)
+
+ get api("/projects/#{project.id}/merge_requests?labels=#{bug_label.title}&milestone=#{milestone1.title}&state=merged", user)
+
+ expect(response).to have_gitlab_http_status(200)
+ expect(json_response).to be_an Array
+ expect(json_response.length).to eq(1)
+ expect(json_response.first['id']).to eq(mr2.id)
+ end
+
context "with ordering" do
before do
@mr_later = mr_with_later_created_and_updated_at_time
@@ -302,44 +322,44 @@ describe API::MergeRequests do
it "returns an array of merge_requests in ascending order" do
get api("/projects/#{project.id}/merge_requests?sort=asc", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(3)
- response_dates = json_response.map{ |merge_request| merge_request['created_at'] }
+ response_dates = json_response.map { |merge_request| merge_request['created_at'] }
expect(response_dates).to eq(response_dates.sort)
end
it "returns an array of merge_requests in descending order" do
get api("/projects/#{project.id}/merge_requests?sort=desc", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(3)
- response_dates = json_response.map{ |merge_request| merge_request['created_at'] }
+ response_dates = json_response.map { |merge_request| merge_request['created_at'] }
expect(response_dates).to eq(response_dates.sort.reverse)
end
it "returns an array of merge_requests ordered by updated_at" do
get api("/projects/#{project.id}/merge_requests?order_by=updated_at", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(3)
- response_dates = json_response.map{ |merge_request| merge_request['updated_at'] }
+ response_dates = json_response.map { |merge_request| merge_request['updated_at'] }
expect(response_dates).to eq(response_dates.sort.reverse)
end
it "returns an array of merge_requests ordered by created_at" do
get api("/projects/#{project.id}/merge_requests?order_by=created_at&sort=asc", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(3)
- response_dates = json_response.map{ |merge_request| merge_request['created_at'] }
+ response_dates = json_response.map { |merge_request| merge_request['created_at'] }
expect(response_dates).to eq(response_dates.sort)
end
end
@@ -350,7 +370,7 @@ describe API::MergeRequests do
it 'exposes known attributes' do
get api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['id']).to eq(merge_request.id)
expect(json_response['iid']).to eq(merge_request.iid)
expect(json_response['project_id']).to eq(merge_request.project.id)
@@ -378,7 +398,7 @@ describe API::MergeRequests do
it "returns merge_request" do
get api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['title']).to eq(merge_request.title)
expect(json_response['iid']).to eq(merge_request.iid)
expect(json_response['work_in_progress']).to eq(false)
@@ -389,13 +409,13 @@ describe API::MergeRequests do
it "returns a 404 error if merge_request_iid not found" do
get api("/projects/#{project.id}/merge_requests/999", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it "returns a 404 error if merge_request `id` is used instead of iid" do
get api("/projects/#{project.id}/merge_requests/#{merge_request.id}", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
context 'Work in Progress' do
@@ -403,7 +423,7 @@ describe API::MergeRequests do
it "returns merge_request" do
get api("/projects/#{project.id}/merge_requests/#{merge_request_wip.iid}", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['work_in_progress']).to eq(true)
end
end
@@ -414,7 +434,7 @@ describe API::MergeRequests do
get api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/commits", user)
commit = merge_request.commits.first
- expect(response.status).to eq 200
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.size).to eq(merge_request.commits.size)
@@ -424,13 +444,13 @@ describe API::MergeRequests do
it 'returns a 404 when merge_request_iid not found' do
get api("/projects/#{project.id}/merge_requests/999/commits", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'returns a 404 when merge_request id is used instead of iid' do
get api("/projects/#{project.id}/merge_requests/#{merge_request.id}/commits", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -438,19 +458,19 @@ describe API::MergeRequests do
it 'returns the change information of the merge_request' do
get api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/changes", user)
- expect(response.status).to eq 200
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['changes'].size).to eq(merge_request.diffs.size)
end
it 'returns a 404 when merge_request_iid not found' do
get api("/projects/#{project.id}/merge_requests/999/changes", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'returns a 404 when merge_request id is used instead of iid' do
get api("/projects/#{project.id}/merge_requests/#{merge_request.id}/changes", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -465,7 +485,7 @@ describe API::MergeRequests do
labels: 'label, label2',
milestone_id: milestone.id
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['title']).to eq('Test merge_request')
expect(json_response['labels']).to eq(%w(label label2))
expect(json_response['milestone']['id']).to eq(milestone.id)
@@ -475,25 +495,25 @@ describe API::MergeRequests do
it "returns 422 when source_branch equals target_branch" do
post api("/projects/#{project.id}/merge_requests", user),
title: "Test merge_request", source_branch: "master", target_branch: "master", author: user
- expect(response).to have_http_status(422)
+ expect(response).to have_gitlab_http_status(422)
end
it "returns 400 when source_branch is missing" do
post api("/projects/#{project.id}/merge_requests", user),
title: "Test merge_request", target_branch: "master", author: user
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it "returns 400 when target_branch is missing" do
post api("/projects/#{project.id}/merge_requests", user),
title: "Test merge_request", source_branch: "markdown", author: user
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it "returns 400 when title is missing" do
post api("/projects/#{project.id}/merge_requests", user),
target_branch: 'master', source_branch: 'markdown'
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it 'allows special label names' do
@@ -503,7 +523,7 @@ describe API::MergeRequests do
target_branch: 'master',
author: user,
labels: 'label, label?, label&foo, ?, &'
- expect(response.status).to eq(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['labels']).to include 'label'
expect(json_response['labels']).to include 'label?'
expect(json_response['labels']).to include 'label&foo'
@@ -529,7 +549,7 @@ describe API::MergeRequests do
target_branch: 'master',
author: user
end.to change { MergeRequest.count }.by(0)
- expect(response).to have_http_status(409)
+ expect(response).to have_gitlab_http_status(409)
end
end
@@ -557,18 +577,20 @@ describe API::MergeRequests do
context 'forked projects' do
let!(:user2) { create(:user) }
- let!(:fork_project) { create(:empty_project, forked_from_project: project, namespace: user2.namespace, creator_id: user2.id) }
- let!(:unrelated_project) { create(:empty_project, namespace: create(:user).namespace, creator_id: user2.id) }
+ let!(:fork_project) { create(:project, forked_from_project: project, namespace: user2.namespace, creator_id: user2.id) }
+ let!(:unrelated_project) { create(:project, namespace: create(:user).namespace, creator_id: user2.id) }
+
+ before do
+ fork_project.add_reporter(user2)
- before :each do |each|
- fork_project.team << [user2, :reporter]
+ allow_any_instance_of(MergeRequest).to receive(:write_ref)
end
it "returns merge_request" do
post api("/projects/#{fork_project.id}/merge_requests", user2),
title: 'Test merge_request', source_branch: "feature_conflict", target_branch: "master",
author: user2, target_project_id: project.id, description: 'Test description for Test merge_request'
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['title']).to eq('Test merge_request')
expect(json_response['description']).to eq('Test description for Test merge_request')
end
@@ -579,7 +601,7 @@ describe API::MergeRequests do
expect(fork_project.forked_from_project).to eq(project)
post api("/projects/#{fork_project.id}/merge_requests", user2),
title: 'Test merge_request', source_branch: "master", target_branch: "master", author: user2, target_project_id: project.id
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['title']).to eq('Test merge_request')
end
@@ -593,25 +615,25 @@ describe API::MergeRequests do
author: user2,
target_project_id: project.id
- expect(response).to have_http_status(422)
+ expect(response).to have_gitlab_http_status(422)
end
it "returns 400 when source_branch is missing" do
post api("/projects/#{fork_project.id}/merge_requests", user2),
title: 'Test merge_request', target_branch: "master", author: user2, target_project_id: project.id
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it "returns 400 when target_branch is missing" do
post api("/projects/#{fork_project.id}/merge_requests", user2),
title: 'Test merge_request', target_branch: "master", author: user2, target_project_id: project.id
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it "returns 400 when title is missing" do
post api("/projects/#{fork_project.id}/merge_requests", user2),
target_branch: 'master', source_branch: 'markdown', author: user2, target_project_id: project.id
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
context 'when target_branch is specified' do
@@ -622,7 +644,7 @@ describe API::MergeRequests do
source_branch: 'markdown',
author: user,
target_project_id: fork_project.id
- expect(response).to have_http_status(422)
+ expect(response).to have_gitlab_http_status(422)
end
it 'returns 422 if targeting a different fork' do
@@ -632,14 +654,14 @@ describe API::MergeRequests do
source_branch: 'markdown',
author: user2,
target_project_id: unrelated_project.id
- expect(response).to have_http_status(422)
+ expect(response).to have_gitlab_http_status(422)
end
end
it "returns 201 when target_branch is specified and for the same project" do
post api("/projects/#{fork_project.id}/merge_requests", user2),
title: 'Test merge_request', target_branch: 'master', source_branch: 'markdown', author: user2, target_project_id: fork_project.id
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
end
end
end
@@ -654,7 +676,7 @@ describe API::MergeRequests do
it "denies the deletion of the merge request" do
delete api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", developer)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -662,19 +684,19 @@ describe API::MergeRequests do
it "destroys the merge request owners can destroy" do
delete api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user)
- expect(response).to have_http_status(204)
+ expect(response).to have_gitlab_http_status(204)
end
it "returns 404 for an invalid merge request IID" do
delete api("/projects/#{project.id}/merge_requests/12345", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it "returns 404 if the merge request id is used instead of iid" do
delete api("/projects/#{project.id}/merge_requests/#{merge_request.id}", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
end
@@ -685,7 +707,7 @@ describe API::MergeRequests do
it "returns merge_request in case of success" do
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/merge", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it "returns 406 if branch can't be merged" do
@@ -694,21 +716,21 @@ describe API::MergeRequests do
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/merge", user)
- expect(response).to have_http_status(406)
+ expect(response).to have_gitlab_http_status(406)
expect(json_response['message']).to eq('Branch cannot be merged')
end
it "returns 405 if merge_request is not open" do
merge_request.close
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/merge", user)
- expect(response).to have_http_status(405)
+ expect(response).to have_gitlab_http_status(405)
expect(json_response['message']).to eq('405 Method Not Allowed')
end
it "returns 405 if merge_request is a work in progress" do
merge_request.update_attribute(:title, "WIP: #{merge_request.title}")
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/merge", user)
- expect(response).to have_http_status(405)
+ expect(response).to have_gitlab_http_status(405)
expect(json_response['message']).to eq('405 Method Not Allowed')
end
@@ -717,7 +739,7 @@ describe API::MergeRequests do
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/merge", user)
- expect(response).to have_http_status(405)
+ expect(response).to have_gitlab_http_status(405)
expect(json_response['message']).to eq('405 Method Not Allowed')
end
@@ -725,21 +747,21 @@ describe API::MergeRequests do
user2 = create(:user)
project.team << [user2, :reporter]
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/merge", user2)
- expect(response).to have_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
expect(json_response['message']).to eq('401 Unauthorized')
end
it "returns 409 if the SHA parameter doesn't match" do
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/merge", user), sha: merge_request.diff_head_sha.reverse
- expect(response).to have_http_status(409)
+ expect(response).to have_gitlab_http_status(409)
expect(json_response['message']).to start_with('SHA does not match HEAD of source branch')
end
it "succeeds if the SHA parameter matches" do
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/merge", user), sha: merge_request.diff_head_sha
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
end
it "enables merge when pipeline succeeds if the pipeline is active" do
@@ -748,7 +770,7 @@ describe API::MergeRequests do
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/merge", user), merge_when_pipeline_succeeds: true
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['title']).to eq('Test')
expect(json_response['merge_when_pipeline_succeeds']).to eq(true)
end
@@ -760,7 +782,7 @@ describe API::MergeRequests do
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/merge", user), merge_when_pipeline_succeeds: true
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['title']).to eq('Test')
expect(json_response['merge_when_pipeline_succeeds']).to eq(true)
end
@@ -768,13 +790,13 @@ describe API::MergeRequests do
it "returns 404 for an invalid merge request IID" do
put api("/projects/#{project.id}/merge_requests/12345/merge", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it "returns 404 if the merge request id is used instead of iid" do
put api("/projects/#{project.id}/merge_requests/#{merge_request.id}/merge", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -783,39 +805,39 @@ describe API::MergeRequests do
it "returns merge_request" do
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user), state_event: "close"
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['state']).to eq('closed')
end
end
it "updates title and returns merge_request" do
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user), title: "New title"
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['title']).to eq('New title')
end
it "updates description and returns merge_request" do
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user), description: "New description"
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['description']).to eq('New description')
end
it "updates milestone_id and returns merge_request" do
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user), milestone_id: milestone.id
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['milestone']['id']).to eq(milestone.id)
end
it "returns merge_request with renamed target_branch" do
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user), target_branch: "wiki"
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['target_branch']).to eq('wiki')
end
it "returns merge_request that removes the source branch" do
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user), remove_source_branch: true
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response['force_remove_source_branch']).to be_truthy
end
@@ -836,7 +858,7 @@ describe API::MergeRequests do
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user), state_event: 'close', title: nil
merge_request.reload
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(merge_request.state).to eq('opened')
end
@@ -844,20 +866,20 @@ describe API::MergeRequests do
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user), state_event: 'close', target_branch: nil
merge_request.reload
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
expect(merge_request.state).to eq('opened')
end
it "returns 404 for an invalid merge request IID" do
put api("/projects/#{project.id}/merge_requests/12345", user), state_event: "close"
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it "returns 404 if the merge request id is used instead of iid" do
put api("/projects/#{project.id}/merge_requests/#{merge_request.id}", user), state_event: "close"
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -870,7 +892,7 @@ describe API::MergeRequests do
get api("/projects/#{project.id}/merge_requests/#{mr.iid}/closes_issues", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(1)
@@ -880,14 +902,14 @@ describe API::MergeRequests do
it 'returns an empty array when there are no issues to be closed' do
get api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/closes_issues", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(0)
end
it 'handles external issues' do
- jira_project = create(:jira_project, :public, name: 'JIR_EXT1')
+ jira_project = create(:jira_project, :public, :repository, name: 'JIR_EXT1')
ext_issue = ExternalIssue.new("#{jira_project.name}-123", jira_project)
issue = create(:issue, project: jira_project)
description = "Closes #{ext_issue.to_reference(jira_project)}\ncloses #{issue.to_reference}"
@@ -896,7 +918,7 @@ describe API::MergeRequests do
get api("/projects/#{jira_project.id}/merge_requests/#{merge_request.iid}/closes_issues", user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.length).to eq(2)
@@ -909,26 +931,26 @@ describe API::MergeRequests do
end
it 'returns 403 if the user has no access to the merge request' do
- project = create(:empty_project, :private)
+ project = create(:project, :private)
merge_request = create(:merge_request, :simple, source_project: project)
guest = create(:user)
project.team << [guest, :guest]
get api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/closes_issues", guest)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
it "returns 404 for an invalid merge request IID" do
get api("/projects/#{project.id}/merge_requests/12345/closes_issues", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it "returns 404 if the merge request id is used instead of iid" do
get api("/projects/#{project.id}/merge_requests/#{merge_request.id}/closes_issues", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
end
@@ -936,26 +958,26 @@ describe API::MergeRequests do
it 'subscribes to a merge request' do
post api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/subscribe", admin)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['subscribed']).to eq(true)
end
it 'returns 304 if already subscribed' do
post api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/subscribe", user)
- expect(response).to have_http_status(304)
+ expect(response).to have_gitlab_http_status(304)
end
it 'returns 404 if the merge request is not found' do
post api("/projects/#{project.id}/merge_requests/123/subscribe", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'returns 404 if the merge request id is used instead of iid' do
post api("/projects/#{project.id}/merge_requests/#{merge_request.id}/subscribe", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'returns 403 if user has no access to read code' do
@@ -964,7 +986,7 @@ describe API::MergeRequests do
post api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/subscribe", guest)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
@@ -972,26 +994,26 @@ describe API::MergeRequests do
it 'unsubscribes from a merge request' do
post api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/unsubscribe", user)
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['subscribed']).to eq(false)
end
it 'returns 304 if not subscribed' do
post api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/unsubscribe", admin)
- expect(response).to have_http_status(304)
+ expect(response).to have_gitlab_http_status(304)
end
it 'returns 404 if the merge request is not found' do
post api("/projects/#{project.id}/merge_requests/123/unsubscribe", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'returns 404 if the merge request id is used instead of iid' do
post api("/projects/#{project.id}/merge_requests/#{merge_request.id}/unsubscribe", user)
- expect(response).to have_http_status(404)
+ expect(response).to have_gitlab_http_status(404)
end
it 'returns 403 if user has no access to read code' do
@@ -1000,7 +1022,7 @@ describe API::MergeRequests do
post api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/unsubscribe", guest)
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
end
diff --git a/spec/requests/api/notes_spec.rb b/spec/requests/api/notes_spec.rb
index 4701ad585c9..75e5062a99c 100644
--- a/spec/requests/api/notes_spec.rb
+++ b/spec/requests/api/notes_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe API::Notes do
let(:user) { create(:user) }
- let!(:project) { create(:empty_project, :public, namespace: user.namespace) }
+ let!(:project) { create(:project, :public, namespace: user.namespace) }
let!(:issue) { create(:issue, project: project, author: user) }
let!(:merge_request) { create(:merge_request, source_project: project, target_project: project, author: user) }
let!(:snippet) { create(:project_snippet, project: project, author: user) }
@@ -13,12 +13,12 @@ describe API::Notes do
# For testing the cross-reference of a private issue in a public issue
let(:private_user) { create(:user) }
let(:private_project) do
- create(:empty_project, namespace: private_user.namespace)
+ create(:project, namespace: private_user.namespace)
.tap { |p| p.team << [private_user, :master] }
end
let(:private_issue) { create(:issue, project: private_project) }
- let(:ext_proj) { create(:empty_project, :public) }
+ let(:ext_proj) { create(:project, :public) }
let(:ext_issue) { create(:issue, project: ext_proj) }
let!(:cross_reference_note) do
@@ -272,7 +272,7 @@ describe API::Notes do
context 'when user does not have access to read the noteable' do
it 'responds with 404' do
- project = create(:empty_project, :private) { |p| p.add_guest(user) }
+ project = create(:project, :private) { |p| p.add_guest(user) }
issue = create(:issue, :confidential, project: project)
post api("/projects/#{project.id}/issues/#{issue.iid}/notes", user),
@@ -283,7 +283,7 @@ describe API::Notes do
end
context 'when user does not have access to create noteable' do
- let(:private_issue) { create(:issue, project: create(:empty_project, :private)) }
+ let(:private_issue) { create(:issue, project: create(:project, :private)) }
##
# We are posting to project user has access to, but we use issue id
diff --git a/spec/requests/api/notification_settings_spec.rb b/spec/requests/api/notification_settings_spec.rb
index f619b7e6eaf..7968659a1ec 100644
--- a/spec/requests/api/notification_settings_spec.rb
+++ b/spec/requests/api/notification_settings_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe API::NotificationSettings do
let(:user) { create(:user) }
let!(:group) { create(:group) }
- let!(:project) { create(:empty_project, :public, creator_id: user.id, namespace: group) }
+ let!(:project) { create(:project, :public, creator_id: user.id, namespace: group) }
describe "GET /notification_settings" do
it "returns global notification settings for the current user" do
@@ -72,8 +72,8 @@ describe API::NotificationSettings do
expect(response).to have_http_status(200)
expect(json_response['level']).to eq(user.reload.notification_settings_for(project).level)
- expect(json_response['events']['new_note']).to eq(true)
- expect(json_response['events']['new_issue']).to eq(false)
+ expect(json_response['events']['new_note']).to be_truthy
+ expect(json_response['events']['new_issue']).to be_falsey
end
end
diff --git a/spec/requests/api/pipeline_schedules_spec.rb b/spec/requests/api/pipeline_schedules_spec.rb
index b34555d2815..1fc0ec528b9 100644
--- a/spec/requests/api/pipeline_schedules_spec.rb
+++ b/spec/requests/api/pipeline_schedules_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe API::PipelineSchedules do
set(:developer) { create(:user) }
set(:user) { create(:user) }
- set(:project) { create(:project) }
+ set(:project) { create(:project, :repository) }
before do
project.add_developer(developer)
@@ -53,7 +53,7 @@ describe API::PipelineSchedules do
it 'returns matched pipeline schedules' do
get api("/projects/#{project.id}/pipeline_schedules", developer), scope: target
- expect(json_response.map{ |r| r['active'] }).to all(eq(active?(target)))
+ expect(json_response.map { |r| r['active'] }).to all(eq(active?(target)))
end
end
diff --git a/spec/requests/api/project_hooks_spec.rb b/spec/requests/api/project_hooks_spec.rb
index 0f9330b062d..2829c243af3 100644
--- a/spec/requests/api/project_hooks_spec.rb
+++ b/spec/requests/api/project_hooks_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe API::ProjectHooks, 'ProjectHooks' do
let(:user) { create(:user) }
let(:user3) { create(:user) }
- let!(:project) { create(:empty_project, creator_id: user.id, namespace: user.namespace) }
+ let!(:project) { create(:project, creator_id: user.id, namespace: user.namespace) }
let!(:hook) do
create(:project_hook,
:all_events_enabled,
@@ -205,7 +205,7 @@ describe API::ProjectHooks, 'ProjectHooks' do
it "returns a 404 if a user attempts to delete project hooks he/she does not own" do
test_user = create(:user)
- other_project = create(:empty_project)
+ other_project = create(:project)
other_project.team << [test_user, :master]
delete api("/projects/#{other_project.id}/hooks/#{hook.id}", test_user)
diff --git a/spec/requests/api/project_milestones_spec.rb b/spec/requests/api/project_milestones_spec.rb
index fe8fdbfd7e4..72e1574b55f 100644
--- a/spec/requests/api/project_milestones_spec.rb
+++ b/spec/requests/api/project_milestones_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe API::ProjectMilestones do
let(:user) { create(:user) }
- let!(:project) { create(:empty_project, namespace: user.namespace ) }
+ let!(:project) { create(:project, namespace: user.namespace ) }
let!(:closed_milestone) { create(:closed_milestone, project: project, title: 'version1', description: 'closed milestone') }
let!(:milestone) { create(:milestone, project: project, title: 'version2', description: 'open milestone') }
diff --git a/spec/requests/api/project_snippets_spec.rb b/spec/requests/api/project_snippets_spec.rb
index f220972bae3..2b541f5719e 100644
--- a/spec/requests/api/project_snippets_spec.rb
+++ b/spec/requests/api/project_snippets_spec.rb
@@ -1,7 +1,7 @@
require 'rails_helper'
describe API::ProjectSnippets do
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:user) { create(:user) }
let(:admin) { create(:admin) }
diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb
index 6ed68fcff09..a89a58ff713 100644
--- a/spec/requests/api/projects_spec.rb
+++ b/spec/requests/api/projects_spec.rb
@@ -8,8 +8,8 @@ describe API::Projects do
let(:user2) { create(:user) }
let(:user3) { create(:user) }
let(:admin) { create(:admin) }
- let(:project) { create(:empty_project, creator_id: user.id, namespace: user.namespace) }
- let(:project2) { create(:empty_project, path: 'project2', creator_id: user.id, namespace: user.namespace) }
+ let(:project) { create(:project, namespace: user.namespace) }
+ let(:project2) { create(:project, path: 'project2', namespace: user.namespace) }
let(:snippet) { create(:project_snippet, :public, author: user, project: project, title: 'example') }
let(:project_member) { create(:project_member, :developer, user: user3, project: project) }
let(:user4) { create(:user) }
@@ -33,7 +33,7 @@ describe API::Projects do
access_level: ProjectMember::MASTER)
end
let(:project4) do
- create(:empty_project,
+ create(:project,
name: 'third_project',
path: 'third_project',
creator_id: user4.id,
@@ -61,7 +61,7 @@ describe API::Projects do
if defined?(additional_project)
additional_project
else
- create(:empty_project, :public)
+ create(:project, :public)
end
expect do
@@ -70,7 +70,7 @@ describe API::Projects do
end
end
- let!(:public_project) { create(:empty_project, :public, name: 'public_project') }
+ let!(:public_project) { create(:project, :public, name: 'public_project') }
before do
project
project2
@@ -103,12 +103,12 @@ describe API::Projects do
context 'when some projects are in a group' do
before do
- create(:empty_project, :public, group: create(:group))
+ create(:project, :public, group: create(:group))
end
it_behaves_like 'projects response without N + 1 queries' do
let(:current_user) { user }
- let(:additional_project) { create(:empty_project, :public, group: create(:group)) }
+ let(:additional_project) { create(:project, :public, group: create(:group)) }
end
end
@@ -186,7 +186,14 @@ describe API::Projects do
context 'and with simple=true' do
it 'returns a simplified version of all the projects' do
- expected_keys = %w(id http_url_to_repo web_url name name_with_namespace path path_with_namespace)
+ expected_keys = %w(
+ id description default_branch tag_list
+ ssh_url_to_repo http_url_to_repo web_url
+ name name_with_namespace
+ path path_with_namespace
+ star_count forks_count
+ created_at last_activity_at
+ )
get api('/projects?simple=true', user)
@@ -268,7 +275,7 @@ describe API::Projects do
end
context 'and with starred=true' do
- let(:public_project) { create(:empty_project, :public) }
+ let(:public_project) { create(:project, :public) }
before do
project_member
@@ -286,11 +293,11 @@ describe API::Projects do
end
context 'and with all query parameters' do
- let!(:project5) { create(:empty_project, :public, path: 'gitlab5', namespace: create(:namespace)) }
- let!(:project6) { create(:empty_project, :public, path: 'project6', namespace: user.namespace) }
- let!(:project7) { create(:empty_project, :public, path: 'gitlab7', namespace: user.namespace) }
- let!(:project8) { create(:empty_project, path: 'gitlab8', namespace: user.namespace) }
- let!(:project9) { create(:empty_project, :public, path: 'gitlab9') }
+ let!(:project5) { create(:project, :public, path: 'gitlab5', namespace: create(:namespace)) }
+ let!(:project6) { create(:project, :public, path: 'project6', namespace: user.namespace) }
+ let!(:project7) { create(:project, :public, path: 'gitlab7', namespace: user.namespace) }
+ let!(:project8) { create(:project, path: 'gitlab8', namespace: user.namespace) }
+ let!(:project9) { create(:project, :public, path: 'gitlab9') }
before do
user.update_attributes(starred_projects: [project5, project7, project8, project9])
@@ -539,7 +546,7 @@ describe API::Projects do
end
describe 'GET /users/:user_id/projects/' do
- let!(:public_project) { create(:empty_project, :public, name: 'public_project', creator_id: user4.id, namespace: user4.namespace) }
+ let!(:public_project) { create(:project, :public, name: 'public_project', creator_id: user4.id, namespace: user4.namespace) }
it 'returns error when user not found' do
get api('/users/9999/projects/')
@@ -682,13 +689,14 @@ describe API::Projects do
describe 'GET /projects/:id' do
context 'when unauthenticated' do
it 'returns the public projects' do
- public_project = create(:empty_project, :public)
+ public_project = create(:project, :public)
get api("/projects/#{public_project.id}")
expect(response).to have_http_status(200)
expect(json_response['id']).to eq(public_project.id)
expect(json_response['description']).to eq(public_project.description)
+ expect(json_response['default_branch']).to eq(public_project.default_branch)
expect(json_response.keys).not_to include('permissions')
end
end
@@ -766,7 +774,7 @@ describe API::Projects do
it 'handles users with dots' do
dot_user = create(:user, username: 'dot.user')
- project = create(:empty_project, creator_id: dot_user.id, namespace: dot_user.namespace)
+ project = create(:project, creator_id: dot_user.id, namespace: dot_user.namespace)
get api("/projects/#{CGI.escape(project.full_path)}", dot_user)
expect(response).to have_http_status(200)
@@ -831,7 +839,7 @@ describe API::Projects do
end
it 'filters related URIs when their feature is not enabled' do
- project = create(:empty_project, :public,
+ project = create(:project, :public,
:merge_requests_disabled,
:issues_disabled,
creator_id: user.id,
@@ -876,7 +884,7 @@ describe API::Projects do
end
context 'group project' do
- let(:project2) { create(:empty_project, group: create(:group)) }
+ let(:project2) { create(:project, group: create(:group)) }
before do
project2.group.add_owner(user)
@@ -916,7 +924,7 @@ describe API::Projects do
context 'when unauthenticated' do
it_behaves_like 'project users response' do
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:current_user) { nil }
end
end
@@ -1036,11 +1044,11 @@ describe API::Projects do
end
describe 'fork management' do
- let(:project_fork_target) { create(:empty_project) }
- let(:project_fork_source) { create(:empty_project, :public) }
+ let(:project_fork_target) { create(:project) }
+ let(:project_fork_source) { create(:project, :public) }
describe 'POST /projects/:id/fork/:forked_from_id' do
- let(:new_project_fork_source) { create(:empty_project, :public) }
+ let(:new_project_fork_source) { create(:project, :public) }
it "is not available for non admin users" do
post api("/projects/#{project_fork_target.id}/fork/#{project_fork_source.id}", user)
@@ -1057,6 +1065,14 @@ describe API::Projects do
expect(project_fork_target.forked?).to be_truthy
end
+ it 'refreshes the forks count cachce' do
+ expect(project_fork_source.forks_count).to be_zero
+
+ post api("/projects/#{project_fork_target.id}/fork/#{project_fork_source.id}", admin)
+
+ expect(project_fork_source.forks_count).to eq(1)
+ end
+
it 'fails if forked_from project which does not exist' do
post api("/projects/#{project_fork_target.id}/fork/9999", admin)
expect(response).to have_http_status(404)
@@ -1081,7 +1097,7 @@ describe API::Projects do
end
context 'when users belong to project group' do
- let(:project_fork_target) { create(:empty_project, group: create(:group)) }
+ let(:project_fork_target) { create(:project, group: create(:group)) }
before do
project_fork_target.group.add_owner user
diff --git a/spec/requests/api/protected_branches_spec.rb b/spec/requests/api/protected_branches_spec.rb
new file mode 100644
index 00000000000..e4f9c47fb33
--- /dev/null
+++ b/spec/requests/api/protected_branches_spec.rb
@@ -0,0 +1,232 @@
+require 'spec_helper'
+
+describe API::ProtectedBranches do
+ let(:user) { create(:user) }
+ let!(:project) { create(:project, :repository) }
+ let(:protected_name) { 'feature' }
+ let(:branch_name) { protected_name }
+ let!(:protected_branch) do
+ create(:protected_branch, project: project, name: protected_name)
+ end
+
+ describe "GET /projects/:id/protected_branches" do
+ let(:route) { "/projects/#{project.id}/protected_branches" }
+
+ shared_examples_for 'protected branches' do
+ it 'returns the protected branches' do
+ get api(route, user), per_page: 100
+
+ expect(response).to have_gitlab_http_status(200)
+ expect(response).to include_pagination_headers
+ expect(json_response).to be_an Array
+
+ protected_branch_names = json_response.map { |x| x['name'] }
+ expected_branch_names = project.protected_branches.map { |x| x['name'] }
+ expect(protected_branch_names).to match_array(expected_branch_names)
+ end
+ end
+
+ context 'when authenticated as a master' do
+ before do
+ project.add_master(user)
+ end
+
+ it_behaves_like 'protected branches'
+ end
+
+ context 'when authenticated as a guest' do
+ before do
+ project.add_guest(user)
+ end
+
+ it_behaves_like '403 response' do
+ let(:request) { get api(route, user) }
+ end
+ end
+ end
+
+ describe "GET /projects/:id/protected_branches/:branch" do
+ let(:route) { "/projects/#{project.id}/protected_branches/#{branch_name}" }
+
+ shared_examples_for 'protected branch' do
+ it 'returns the protected branch' do
+ get api(route, user)
+
+ expect(response).to have_gitlab_http_status(200)
+ expect(json_response['name']).to eq(branch_name)
+ expect(json_response['push_access_levels'][0]['access_level']).to eq(::Gitlab::Access::MASTER)
+ expect(json_response['merge_access_levels'][0]['access_level']).to eq(::Gitlab::Access::MASTER)
+ end
+
+ context 'when protected branch does not exist' do
+ let(:branch_name) { 'unknown' }
+
+ it_behaves_like '404 response' do
+ let(:request) { get api(route, user) }
+ let(:message) { '404 Not found' }
+ end
+ end
+ end
+
+ context 'when authenticated as a master' do
+ before do
+ project.add_master(user)
+ end
+
+ it_behaves_like 'protected branch'
+
+ context 'when protected branch contains a wildcard' do
+ let(:protected_name) { 'feature*' }
+
+ it_behaves_like 'protected branch'
+ end
+ end
+
+ context 'when authenticated as a guest' do
+ before do
+ project.add_guest(user)
+ end
+
+ it_behaves_like '403 response' do
+ let(:request) { get api(route, user) }
+ end
+ end
+ end
+
+ describe 'POST /projects/:id/protected_branches' do
+ let(:branch_name) { 'new_branch' }
+
+ context 'when authenticated as a master' do
+ before do
+ project.add_master(user)
+ end
+
+ it 'protects a single branch' do
+ post api("/projects/#{project.id}/protected_branches", user), name: branch_name
+
+ expect(response).to have_gitlab_http_status(201)
+ expect(json_response['name']).to eq(branch_name)
+ expect(json_response['push_access_levels'][0]['access_level']).to eq(Gitlab::Access::MASTER)
+ expect(json_response['merge_access_levels'][0]['access_level']).to eq(Gitlab::Access::MASTER)
+ end
+
+ it 'protects a single branch and developers can push' do
+ post api("/projects/#{project.id}/protected_branches", user),
+ name: branch_name, push_access_level: 30
+
+ expect(response).to have_gitlab_http_status(201)
+ expect(json_response['name']).to eq(branch_name)
+ expect(json_response['push_access_levels'][0]['access_level']).to eq(Gitlab::Access::DEVELOPER)
+ expect(json_response['merge_access_levels'][0]['access_level']).to eq(Gitlab::Access::MASTER)
+ end
+
+ it 'protects a single branch and developers can merge' do
+ post api("/projects/#{project.id}/protected_branches", user),
+ name: branch_name, merge_access_level: 30
+
+ expect(response).to have_gitlab_http_status(201)
+ expect(json_response['name']).to eq(branch_name)
+ expect(json_response['push_access_levels'][0]['access_level']).to eq(Gitlab::Access::MASTER)
+ expect(json_response['merge_access_levels'][0]['access_level']).to eq(Gitlab::Access::DEVELOPER)
+ end
+
+ it 'protects a single branch and developers can push and merge' do
+ post api("/projects/#{project.id}/protected_branches", user),
+ name: branch_name, push_access_level: 30, merge_access_level: 30
+
+ expect(response).to have_gitlab_http_status(201)
+ expect(json_response['name']).to eq(branch_name)
+ expect(json_response['push_access_levels'][0]['access_level']).to eq(Gitlab::Access::DEVELOPER)
+ expect(json_response['merge_access_levels'][0]['access_level']).to eq(Gitlab::Access::DEVELOPER)
+ end
+
+ it 'protects a single branch and no one can push' do
+ post api("/projects/#{project.id}/protected_branches", user),
+ name: branch_name, push_access_level: 0
+
+ expect(response).to have_gitlab_http_status(201)
+ expect(json_response['name']).to eq(branch_name)
+ expect(json_response['push_access_levels'][0]['access_level']).to eq(Gitlab::Access::NO_ACCESS)
+ expect(json_response['merge_access_levels'][0]['access_level']).to eq(Gitlab::Access::MASTER)
+ end
+
+ it 'protects a single branch and no one can merge' do
+ post api("/projects/#{project.id}/protected_branches", user),
+ name: branch_name, merge_access_level: 0
+
+ expect(response).to have_gitlab_http_status(201)
+ expect(json_response['name']).to eq(branch_name)
+ expect(json_response['push_access_levels'][0]['access_level']).to eq(Gitlab::Access::MASTER)
+ expect(json_response['merge_access_levels'][0]['access_level']).to eq(Gitlab::Access::NO_ACCESS)
+ end
+
+ it 'protects a single branch and no one can push or merge' do
+ post api("/projects/#{project.id}/protected_branches", user),
+ name: branch_name, push_access_level: 0, merge_access_level: 0
+
+ expect(response).to have_gitlab_http_status(201)
+ expect(json_response['name']).to eq(branch_name)
+ expect(json_response['push_access_levels'][0]['access_level']).to eq(Gitlab::Access::NO_ACCESS)
+ expect(json_response['merge_access_levels'][0]['access_level']).to eq(Gitlab::Access::NO_ACCESS)
+ end
+
+ it 'returns a 409 error if the same branch is protected twice' do
+ post api("/projects/#{project.id}/protected_branches", user), name: protected_name
+ expect(response).to have_gitlab_http_status(409)
+ end
+
+ context 'when branch has a wildcard in its name' do
+ let(:branch_name) { 'feature/*' }
+
+ it "protects multiple branches with a wildcard in the name" do
+ post api("/projects/#{project.id}/protected_branches", user), name: branch_name
+
+ expect(response).to have_gitlab_http_status(201)
+ expect(json_response['name']).to eq(branch_name)
+ expect(json_response['push_access_levels'][0]['access_level']).to eq(Gitlab::Access::MASTER)
+ expect(json_response['merge_access_levels'][0]['access_level']).to eq(Gitlab::Access::MASTER)
+ end
+ end
+ end
+
+ context 'when authenticated as a guest' do
+ before do
+ project.add_guest(user)
+ end
+
+ it "returns a 403 error if guest" do
+ post api("/projects/#{project.id}/protected_branches/", user), name: branch_name
+
+ expect(response).to have_gitlab_http_status(403)
+ end
+ end
+ end
+
+ describe "DELETE /projects/:id/protected_branches/unprotect/:branch" do
+ before do
+ project.add_master(user)
+ end
+
+ it "unprotects a single branch" do
+ delete api("/projects/#{project.id}/protected_branches/#{branch_name}", user)
+
+ expect(response).to have_gitlab_http_status(204)
+ end
+
+ it "returns 404 if branch does not exist" do
+ delete api("/projects/#{project.id}/protected_branches/barfoo", user)
+
+ expect(response).to have_gitlab_http_status(404)
+ end
+
+ context 'when branch has a wildcard in its name' do
+ let(:protected_name) { 'feature*' }
+
+ it "unprotects a wildcard branch" do
+ delete api("/projects/#{project.id}/protected_branches/#{branch_name}", user)
+
+ expect(response).to have_gitlab_http_status(204)
+ end
+ end
+ end
+end
diff --git a/spec/requests/api/runner_spec.rb b/spec/requests/api/runner_spec.rb
index ca5d98c78ef..e9ee3dd679d 100644
--- a/spec/requests/api/runner_spec.rb
+++ b/spec/requests/api/runner_spec.rb
@@ -42,7 +42,7 @@ describe API::Runner do
end
context 'when project token is used' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
it 'creates runner' do
post api('/runners'), token: project.runners_token
@@ -182,7 +182,7 @@ describe API::Runner do
end
describe '/api/v4/jobs' do
- let(:project) { create(:empty_project, shared_runners_enabled: false) }
+ let(:project) { create(:project, shared_runners_enabled: false) }
let(:pipeline) { create(:ci_pipeline_without_jobs, project: project, ref: 'master') }
let(:runner) { create(:ci_runner) }
let!(:job) do
@@ -683,7 +683,7 @@ describe API::Runner do
end
context 'when job has been updated recently' do
- it { expect{ patch_the_trace }.not_to change { job.updated_at }}
+ it { expect { patch_the_trace }.not_to change { job.updated_at }}
it "changes the job's trace" do
patch_the_trace
@@ -692,7 +692,7 @@ describe API::Runner do
end
context 'when Runner makes a force-patch' do
- it { expect{ force_patch_the_trace }.not_to change { job.updated_at }}
+ it { expect { force_patch_the_trace }.not_to change { job.updated_at }}
it "doesn't change the build.trace" do
force_patch_the_trace
diff --git a/spec/requests/api/runners_spec.rb b/spec/requests/api/runners_spec.rb
index 645a5389850..c8ff25f70fa 100644
--- a/spec/requests/api/runners_spec.rb
+++ b/spec/requests/api/runners_spec.rb
@@ -5,8 +5,8 @@ describe API::Runners do
let(:user) { create(:user) }
let(:user2) { create(:user) }
- let(:project) { create(:empty_project, creator_id: user.id) }
- let(:project2) { create(:empty_project, creator_id: user.id) }
+ let(:project) { create(:project, creator_id: user.id) }
+ let(:project2) { create(:project, creator_id: user.id) }
let!(:shared_runner) { create(:ci_runner, :shared) }
let!(:unused_specific_runner) { create(:ci_runner) }
@@ -36,7 +36,7 @@ describe API::Runners do
it 'returns user available runners' do
get api('/runners', user)
- shared = json_response.any?{ |r| r['is_shared'] }
+ shared = json_response.any? { |r| r['is_shared'] }
expect(response).to have_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
@@ -46,7 +46,7 @@ describe API::Runners do
it 'filters runners by scope' do
get api('/runners?scope=active', user)
- shared = json_response.any?{ |r| r['is_shared'] }
+ shared = json_response.any? { |r| r['is_shared'] }
expect(response).to have_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
@@ -74,7 +74,7 @@ describe API::Runners do
it 'returns all runners' do
get api('/runners/all', admin)
- shared = json_response.any?{ |r| r['is_shared'] }
+ shared = json_response.any? { |r| r['is_shared'] }
expect(response).to have_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
@@ -93,7 +93,7 @@ describe API::Runners do
it 'filters runners by scope' do
get api('/runners/all?scope=specific', admin)
- shared = json_response.any?{ |r| r['is_shared'] }
+ shared = json_response.any? { |r| r['is_shared'] }
expect(response).to have_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
@@ -277,7 +277,7 @@ describe API::Runners do
delete api("/runners/#{shared_runner.id}", admin)
expect(response).to have_http_status(204)
- end.to change{ Ci::Runner.shared.count }.by(-1)
+ end.to change { Ci::Runner.shared.count }.by(-1)
end
end
@@ -287,7 +287,7 @@ describe API::Runners do
delete api("/runners/#{unused_specific_runner.id}", admin)
expect(response).to have_http_status(204)
- end.to change{ Ci::Runner.specific.count }.by(-1)
+ end.to change { Ci::Runner.specific.count }.by(-1)
end
it 'deletes used runner' do
@@ -295,7 +295,7 @@ describe API::Runners do
delete api("/runners/#{specific_runner.id}", admin)
expect(response).to have_http_status(204)
- end.to change{ Ci::Runner.specific.count }.by(-1)
+ end.to change { Ci::Runner.specific.count }.by(-1)
end
end
@@ -330,7 +330,7 @@ describe API::Runners do
delete api("/runners/#{specific_runner.id}", user)
expect(response).to have_http_status(204)
- end.to change{ Ci::Runner.specific.count }.by(-1)
+ end.to change { Ci::Runner.specific.count }.by(-1)
end
end
end
@@ -349,7 +349,7 @@ describe API::Runners do
it "returns project's runners" do
get api("/projects/#{project.id}/runners", user)
- shared = json_response.any?{ |r| r['is_shared'] }
+ shared = json_response.any? { |r| r['is_shared'] }
expect(response).to have_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
@@ -385,14 +385,14 @@ describe API::Runners do
it 'enables specific runner' do
expect do
post api("/projects/#{project.id}/runners", user), runner_id: specific_runner2.id
- end.to change{ project.runners.count }.by(+1)
+ end.to change { project.runners.count }.by(+1)
expect(response).to have_http_status(201)
end
it 'avoids changes when enabling already enabled runner' do
expect do
post api("/projects/#{project.id}/runners", user), runner_id: specific_runner.id
- end.to change{ project.runners.count }.by(0)
+ end.to change { project.runners.count }.by(0)
expect(response).to have_http_status(409)
end
@@ -401,7 +401,7 @@ describe API::Runners do
expect do
post api("/projects/#{project.id}/runners", user), runner_id: specific_runner2.id
- end.to change{ project.runners.count }.by(0)
+ end.to change { project.runners.count }.by(0)
expect(response).to have_http_status(403)
end
@@ -416,7 +416,7 @@ describe API::Runners do
it 'enables any specific runner' do
expect do
post api("/projects/#{project.id}/runners", admin), runner_id: unused_specific_runner.id
- end.to change{ project.runners.count }.by(+1)
+ end.to change { project.runners.count }.by(+1)
expect(response).to have_http_status(201)
end
end
@@ -461,7 +461,7 @@ describe API::Runners do
delete api("/projects/#{project.id}/runners/#{two_projects_runner.id}", user)
expect(response).to have_http_status(204)
- end.to change{ project.runners.count }.by(-1)
+ end.to change { project.runners.count }.by(-1)
end
end
@@ -469,7 +469,7 @@ describe API::Runners do
it "does not disable project's runner" do
expect do
delete api("/projects/#{project.id}/runners/#{specific_runner.id}", user)
- end.to change{ project.runners.count }.by(0)
+ end.to change { project.runners.count }.by(0)
expect(response).to have_http_status(403)
end
end
diff --git a/spec/requests/api/services_spec.rb b/spec/requests/api/services_spec.rb
index 95df3429314..48d99841385 100644
--- a/spec/requests/api/services_spec.rb
+++ b/spec/requests/api/services_spec.rb
@@ -4,7 +4,7 @@ describe API::Services do
let(:user) { create(:user) }
let(:admin) { create(:admin) }
let(:user2) { create(:user) }
- let(:project) { create(:empty_project, creator_id: user.id, namespace: user.namespace) }
+ let(:project) { create(:project, creator_id: user.id, namespace: user.namespace) }
Service.available_services_names.each do |service|
describe "PUT /projects/:id/services/#{service.dasherize}" do
@@ -98,7 +98,7 @@ describe API::Services do
end
describe 'POST /projects/:id/services/:slug/trigger' do
- let!(:project) { create(:empty_project) }
+ let!(:project) { create(:project) }
describe 'Mattermost Service' do
let(:service_name) { 'mattermost_slash_commands' }
diff --git a/spec/requests/api/settings_spec.rb b/spec/requests/api/settings_spec.rb
index c3ed5cd8ece..97275b80d03 100644
--- a/spec/requests/api/settings_spec.rb
+++ b/spec/requests/api/settings_spec.rb
@@ -43,7 +43,9 @@ describe API::Settings, 'Settings' do
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'
+ help_page_support_url: 'http://example.com/help',
+ project_export_enabled: false
+
expect(response).to have_http_status(200)
expect(json_response['default_projects_limit']).to eq(3)
expect(json_response['password_authentication_enabled']).to be_falsey
@@ -58,6 +60,7 @@ describe API::Settings, 'Settings' do
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')
+ expect(json_response['project_export_enabled']).to be_falsey
end
end
diff --git a/spec/requests/api/snippets_spec.rb b/spec/requests/api/snippets_spec.rb
index 373fab4d98a..d09b8bc42f1 100644
--- a/spec/requests/api/snippets_spec.rb
+++ b/spec/requests/api/snippets_spec.rb
@@ -52,10 +52,10 @@ describe API::Snippets do
expect(json_response.map { |snippet| snippet['id']} ).to contain_exactly(
public_snippet.id,
public_snippet_other.id)
- expect(json_response.map{ |snippet| snippet['web_url']} ).to include(
+ expect(json_response.map { |snippet| snippet['web_url']} ).to include(
"http://localhost/snippets/#{public_snippet.id}",
"http://localhost/snippets/#{public_snippet_other.id}")
- expect(json_response.map{ |snippet| snippet['raw_url']} ).to include(
+ expect(json_response.map { |snippet| snippet['raw_url']} ).to include(
"http://localhost/snippets/#{public_snippet.id}/raw",
"http://localhost/snippets/#{public_snippet_other.id}/raw")
end
diff --git a/spec/requests/api/tags_spec.rb b/spec/requests/api/tags_spec.rb
index ef7d0c3ee41..9884c1ec206 100644
--- a/spec/requests/api/tags_spec.rb
+++ b/spec/requests/api/tags_spec.rb
@@ -1,66 +1,85 @@
require 'spec_helper'
-require 'mime/types'
describe API::Tags do
- include RepoHelpers
-
let(:user) { create(:user) }
- let(:user2) { create(:user) }
- let!(:project) { create(:project, :repository, creator: user) }
- let!(:master) { create(:project_member, :master, user: user, project: project) }
- let!(:guest) { create(:project_member, :guest, user: user2, project: project) }
+ let(:guest) { create(:user).tap { |u| project.add_guest(u) } }
+ let(:project) { create(:project, :repository, creator: user, path: 'my.project') }
+ let(:tag_name) { project.repository.find_tag('v1.1.0').name }
- describe "GET /projects/:id/repository/tags" do
- let(:tag_name) { project.repository.tag_names.sort.reverse.first }
- let(:description) { 'Awesome release!' }
+ let(:project_id) { project.id }
+ let(:current_user) { nil }
+
+ before do
+ project.add_master(user)
+ end
+
+ describe 'GET /projects/:id/repository/tags' do
+ let(:route) { "/projects/#{project_id}/repository/tags" }
shared_examples_for 'repository tags' do
it 'returns the repository tags' do
- get api("/projects/#{project.id}/repository/tags", current_user)
+ get api(route, current_user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
+ expect(response).to match_response_schema('public_api/v4/tags')
expect(response).to include_pagination_headers
- expect(json_response).to be_an Array
expect(json_response.first['name']).to eq(tag_name)
end
- end
- context 'when unauthenticated' do
- it_behaves_like 'repository tags' do
- let(:project) { create(:project, :public, :repository) }
- let(:current_user) { nil }
+ context 'when repository is disabled' do
+ include_context 'disabled repository'
+
+ it_behaves_like '403 response' do
+ let(:request) { get api(route, current_user) }
+ end
end
end
- context 'when authenticated' do
- it_behaves_like 'repository tags' do
- let(:current_user) { user }
+ context 'when unauthenticated', 'and project is public' do
+ let(:project) { create(:project, :public, :repository) }
+
+ it_behaves_like 'repository tags'
+ end
+
+ context 'when unauthenticated', 'and project is private' do
+ it_behaves_like '404 response' do
+ let(:request) { get api(route) }
+ let(:message) { '404 Project Not Found' }
end
end
- context 'without releases' do
- it "returns an array of project tags" do
- get api("/projects/#{project.id}/repository/tags", user)
+ context 'when authenticated', 'as a master' do
+ let(:current_user) { user }
- expect(response).to have_http_status(200)
- expect(response).to include_pagination_headers
- expect(json_response).to be_an Array
- expect(json_response.first['name']).to eq(tag_name)
+ it_behaves_like 'repository tags'
+
+ context 'requesting with the escaped project full path' do
+ let(:project_id) { CGI.escape(project.full_path) }
+
+ it_behaves_like 'repository tags'
+ end
+ end
+
+ context 'when authenticated', 'as a guest' do
+ it_behaves_like '403 response' do
+ let(:request) { get api(route, guest) }
end
end
context 'with releases' do
+ let(:description) { 'Awesome release!' }
+
before do
release = project.releases.find_or_initialize_by(tag: tag_name)
release.update_attributes(description: description)
end
- it "returns an array of project tags with release info" do
- get api("/projects/#{project.id}/repository/tags", user)
+ it 'returns an array of project tags with release info' do
+ get api(route, user)
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
+ expect(response).to match_response_schema('public_api/v4/tags')
expect(response).to include_pagination_headers
- expect(json_response).to be_an Array
expect(json_response.first['name']).to eq(tag_name)
expect(json_response.first['message']).to eq('Version 1.1.0')
expect(json_response.first['release']['description']).to eq(description)
@@ -69,210 +88,342 @@ describe API::Tags do
end
describe 'GET /projects/:id/repository/tags/:tag_name' do
- let(:tag_name) { project.repository.tag_names.sort.reverse.first }
+ let(:route) { "/projects/#{project_id}/repository/tags/#{tag_name}" }
shared_examples_for 'repository tag' do
- it 'returns the repository tag' do
- get api("/projects/#{project.id}/repository/tags/#{tag_name}", current_user)
-
- expect(response).to have_http_status(200)
+ it 'returns the repository branch' do
+ get api(route, current_user)
+ expect(response).to have_gitlab_http_status(200)
+ expect(response).to match_response_schema('public_api/v4/tag')
expect(json_response['name']).to eq(tag_name)
end
- it 'returns 404 for an invalid tag name' do
- get api("/projects/#{project.id}/repository/tags/foobar", current_user)
+ context 'when tag does not exist' do
+ let(:tag_name) { 'unknown' }
- expect(response).to have_http_status(404)
+ it_behaves_like '404 response' do
+ let(:request) { get api(route, current_user) }
+ let(:message) { '404 Tag Not Found' }
+ end
+ end
+
+ context 'when repository is disabled' do
+ include_context 'disabled repository'
+
+ it_behaves_like '403 response' do
+ let(:request) { get api(route, current_user) }
+ end
end
end
- context 'when unauthenticated' do
- it_behaves_like 'repository tag' do
- let(:project) { create(:project, :public, :repository) }
- let(:current_user) { nil }
+ context 'when unauthenticated', 'and project is public' do
+ let(:project) { create(:project, :public, :repository) }
+
+ it_behaves_like 'repository tag'
+ end
+
+ context 'when unauthenticated', 'and project is private' do
+ it_behaves_like '404 response' do
+ let(:request) { get api(route) }
+ let(:message) { '404 Project Not Found' }
end
end
- context 'when authenticated' do
- it_behaves_like 'repository tag' do
- let(:current_user) { user }
+ context 'when authenticated', 'as a master' do
+ let(:current_user) { user }
+
+ it_behaves_like 'repository tag'
+
+ context 'requesting with the escaped project full path' do
+ let(:project_id) { CGI.escape(project.full_path) }
+
+ it_behaves_like 'repository tag'
+ end
+ end
+
+ context 'when authenticated', 'as a guest' do
+ it_behaves_like '403 response' do
+ let(:request) { get api(route, guest) }
end
end
end
describe 'POST /projects/:id/repository/tags' do
- context 'lightweight tags' do
+ let(:tag_name) { 'new_tag' }
+ let(:route) { "/projects/#{project_id}/repository/tags" }
+
+ shared_examples_for 'repository new tag' do
it 'creates a new tag' do
- post api("/projects/#{project.id}/repository/tags", user),
- tag_name: 'v7.0.1',
- ref: 'master'
+ post api(route, current_user), tag_name: tag_name, ref: 'master'
- expect(response).to have_http_status(201)
- expect(json_response['name']).to eq('v7.0.1')
+ expect(response).to have_gitlab_http_status(201)
+ expect(response).to match_response_schema('public_api/v4/tag')
+ expect(json_response['name']).to eq(tag_name)
end
- end
- context 'lightweight tags with release notes' do
- it 'creates a new tag' do
- post api("/projects/#{project.id}/repository/tags", user),
- tag_name: 'v7.0.1',
- ref: 'master',
- release_description: 'Wow'
+ context 'when repository is disabled' do
+ include_context 'disabled repository'
- expect(response).to have_http_status(201)
- expect(json_response['name']).to eq('v7.0.1')
- expect(json_response['release']['description']).to eq('Wow')
+ it_behaves_like '403 response' do
+ let(:request) { post api(route, current_user) }
+ end
end
end
- describe 'DELETE /projects/:id/repository/tags/:tag_name' do
- let(:tag_name) { project.repository.tag_names.sort.reverse.first }
+ context 'when unauthenticated', 'and project is private' do
+ it_behaves_like '404 response' do
+ let(:request) { post api(route) }
+ let(:message) { '404 Project Not Found' }
+ end
+ end
- before do
- allow_any_instance_of(Repository).to receive(:rm_tag).and_return(true)
+ context 'when authenticated', 'as a guest' do
+ it_behaves_like '403 response' do
+ let(:request) { post api(route, guest) }
end
+ end
+
+ context 'when authenticated', 'as a master' do
+ let(:current_user) { user }
+
+ context "when a protected branch doesn't already exist" do
+ it_behaves_like 'repository new tag'
- context 'delete tag' do
- it 'deletes an existing tag' do
- delete api("/projects/#{project.id}/repository/tags/#{tag_name}", user)
+ context 'when tag contains a dot' do
+ let(:tag_name) { 'v7.0.1' }
- expect(response).to have_http_status(204)
+ it_behaves_like 'repository new tag'
end
- it 'raises 404 if the tag does not exist' do
- delete api("/projects/#{project.id}/repository/tags/foobar", user)
- expect(response).to have_http_status(404)
+ context 'requesting with the escaped project full path' do
+ let(:project_id) { CGI.escape(project.full_path) }
+
+ it_behaves_like 'repository new tag'
+
+ context 'when tag contains a dot' do
+ let(:tag_name) { 'v7.0.1' }
+
+ it_behaves_like 'repository new tag'
+ end
end
end
- end
- context 'annotated tag' do
- it 'creates a new annotated tag' do
- # Identity must be set in .gitconfig to create annotated tag.
- repo_path = project.repository.path_to_repo
- system(*%W(#{Gitlab.config.git.bin_path} --git-dir=#{repo_path} config user.name #{user.name}))
- system(*%W(#{Gitlab.config.git.bin_path} --git-dir=#{repo_path} config user.email #{user.email}))
+ it 'returns 400 if tag name is invalid' do
+ post api(route, current_user), tag_name: 'new design', ref: 'master'
+
+ expect(response).to have_gitlab_http_status(400)
+ expect(json_response['message']).to eq('Tag name invalid')
+ end
+
+ it 'returns 400 if tag already exists' do
+ post api(route, current_user), tag_name: 'new_design1', ref: 'master'
- post api("/projects/#{project.id}/repository/tags", user),
- tag_name: 'v7.1.0',
- ref: 'master',
- message: 'Release 7.1.0'
+ expect(response).to have_gitlab_http_status(201)
+ expect(response).to match_response_schema('public_api/v4/tag')
- expect(response).to have_http_status(201)
- expect(json_response['name']).to eq('v7.1.0')
- expect(json_response['message']).to eq('Release 7.1.0')
+ post api(route, current_user), tag_name: 'new_design1', ref: 'master'
+
+ expect(response).to have_gitlab_http_status(400)
+ expect(json_response['message']).to eq('Tag new_design1 already exists')
end
- end
- it 'denies for user without push access' do
- post api("/projects/#{project.id}/repository/tags", user2),
- tag_name: 'v1.9.0',
- ref: '621491c677087aa243f165eab467bfdfbee00be1'
- expect(response).to have_http_status(403)
+ it 'returns 400 if ref name is invalid' do
+ post api(route, current_user), tag_name: 'new_design3', ref: 'foo'
+
+ expect(response).to have_gitlab_http_status(400)
+ expect(json_response['message']).to eq('Target foo is invalid')
+ end
+
+ context 'lightweight tags with release notes' do
+ it 'creates a new tag' do
+ post api(route, current_user), tag_name: tag_name, ref: 'master', release_description: 'Wow'
+
+ expect(response).to have_gitlab_http_status(201)
+ expect(response).to match_response_schema('public_api/v4/tag')
+ expect(json_response['name']).to eq(tag_name)
+ expect(json_response['release']['description']).to eq('Wow')
+ end
+ end
+
+ context 'annotated tag' do
+ it 'creates a new annotated tag' do
+ # Identity must be set in .gitconfig to create annotated tag.
+ repo_path = project.repository.path_to_repo
+ system(*%W(#{Gitlab.config.git.bin_path} --git-dir=#{repo_path} config user.name #{user.name}))
+ system(*%W(#{Gitlab.config.git.bin_path} --git-dir=#{repo_path} config user.email #{user.email}))
+
+ post api(route, current_user), tag_name: 'v7.1.0', ref: 'master', message: 'Release 7.1.0'
+
+ expect(response).to have_gitlab_http_status(201)
+ expect(response).to match_response_schema('public_api/v4/tag')
+ expect(json_response['name']).to eq('v7.1.0')
+ expect(json_response['message']).to eq('Release 7.1.0')
+ end
+ end
end
+ end
+
+ describe 'DELETE /projects/:id/repository/tags/:tag_name' do
+ let(:route) { "/projects/#{project_id}/repository/tags/#{tag_name}" }
- it 'returns 400 if tag name is invalid' do
- post api("/projects/#{project.id}/repository/tags", user),
- tag_name: 'v 1.0.0',
- ref: 'master'
- expect(response).to have_http_status(400)
- expect(json_response['message']).to eq('Tag name invalid')
+ before do
+ allow_any_instance_of(Repository).to receive(:rm_tag).and_return(true)
end
- it 'returns 400 if tag already exists' do
- post api("/projects/#{project.id}/repository/tags", user),
- tag_name: 'v8.0.0',
- ref: 'master'
- expect(response).to have_http_status(201)
- post api("/projects/#{project.id}/repository/tags", user),
- tag_name: 'v8.0.0',
- ref: 'master'
- expect(response).to have_http_status(400)
- expect(json_response['message']).to eq('Tag v8.0.0 already exists')
+ shared_examples_for 'repository delete tag' do
+ it 'deletes a tag' do
+ delete api(route, current_user)
+
+ expect(response).to have_gitlab_http_status(204)
+ end
+
+ context 'when tag does not exist' do
+ let(:tag_name) { 'unknown' }
+
+ it_behaves_like '404 response' do
+ let(:request) { delete api(route, current_user) }
+ let(:message) { 'No such tag' }
+ end
+ end
+
+ context 'when repository is disabled' do
+ include_context 'disabled repository'
+
+ it_behaves_like '403 response' do
+ let(:request) { delete api(route, current_user) }
+ end
+ end
end
- it 'returns 400 if ref name is invalid' do
- post api("/projects/#{project.id}/repository/tags", user),
- tag_name: 'mytag',
- ref: 'foo'
- expect(response).to have_http_status(400)
- expect(json_response['message']).to eq('Target foo is invalid')
+ context 'when authenticated', 'as a master' do
+ let(:current_user) { user }
+
+ it_behaves_like 'repository delete tag'
+
+ context 'requesting with the escaped project full path' do
+ let(:project_id) { CGI.escape(project.full_path) }
+
+ it_behaves_like 'repository delete tag'
+ end
end
end
describe 'POST /projects/:id/repository/tags/:tag_name/release' do
- let(:tag_name) { project.repository.tag_names.first }
+ let(:route) { "/projects/#{project_id}/repository/tags/#{tag_name}/release" }
let(:description) { 'Awesome release!' }
- it 'creates description for existing git tag' do
- post api("/projects/#{project.id}/repository/tags/#{tag_name}/release", user),
- description: description
+ shared_examples_for 'repository new release' do
+ it 'creates description for existing git tag' do
+ post api(route, user), description: description
- expect(response).to have_http_status(201)
- expect(json_response['tag_name']).to eq(tag_name)
- expect(json_response['description']).to eq(description)
- end
+ expect(response).to have_gitlab_http_status(201)
+ expect(response).to match_response_schema('public_api/v4/release')
+ expect(json_response['tag_name']).to eq(tag_name)
+ expect(json_response['description']).to eq(description)
+ end
+
+ context 'when tag does not exist' do
+ let(:tag_name) { 'unknown' }
+
+ it_behaves_like '404 response' do
+ let(:request) { post api(route, current_user), description: description }
+ let(:message) { 'Tag does not exist' }
+ end
+ end
- it 'returns 404 if the tag does not exist' do
- post api("/projects/#{project.id}/repository/tags/foobar/release", user),
- description: description
+ context 'when repository is disabled' do
+ include_context 'disabled repository'
- expect(response).to have_http_status(404)
- expect(json_response['message']).to eq('Tag does not exist')
+ it_behaves_like '403 response' do
+ let(:request) { post api(route, current_user), description: description }
+ end
+ end
end
- context 'on tag with existing release' do
- before do
- release = project.releases.find_or_initialize_by(tag: tag_name)
- release.update_attributes(description: description)
+ context 'when authenticated', 'as a master' do
+ let(:current_user) { user }
+
+ it_behaves_like 'repository new release'
+
+ context 'requesting with the escaped project full path' do
+ let(:project_id) { CGI.escape(project.full_path) }
+
+ it_behaves_like 'repository new release'
end
- it 'returns 409 if there is already a release' do
- post api("/projects/#{project.id}/repository/tags/#{tag_name}/release", user),
- description: description
+ context 'on tag with existing release' do
+ before do
+ release = project.releases.find_or_initialize_by(tag: tag_name)
+ release.update_attributes(description: description)
+ end
+
+ it 'returns 409 if there is already a release' do
+ post api(route, user), description: description
- expect(response).to have_http_status(409)
- expect(json_response['message']).to eq('Release already exists')
+ expect(response).to have_gitlab_http_status(409)
+ expect(json_response['message']).to eq('Release already exists')
+ end
end
end
end
describe 'PUT id/repository/tags/:tag_name/release' do
- let(:tag_name) { project.repository.tag_names.first }
+ let(:route) { "/projects/#{project_id}/repository/tags/#{tag_name}/release" }
let(:description) { 'Awesome release!' }
let(:new_description) { 'The best release!' }
- context 'on tag with existing release' do
- before do
- release = project.releases.find_or_initialize_by(tag: tag_name)
- release.update_attributes(description: description)
+ shared_examples_for 'repository update release' do
+ context 'on tag with existing release' do
+ before do
+ release = project.releases.find_or_initialize_by(tag: tag_name)
+ release.update_attributes(description: description)
+ end
+
+ it 'updates the release description' do
+ put api(route, current_user), description: new_description
+
+ expect(response).to have_gitlab_http_status(200)
+ expect(json_response['tag_name']).to eq(tag_name)
+ expect(json_response['description']).to eq(new_description)
+ end
end
- it 'updates the release description' do
- put api("/projects/#{project.id}/repository/tags/#{tag_name}/release", user),
- description: new_description
+ context 'when tag does not exist' do
+ let(:tag_name) { 'unknown' }
- expect(response).to have_http_status(200)
- expect(json_response['tag_name']).to eq(tag_name)
- expect(json_response['description']).to eq(new_description)
+ it_behaves_like '404 response' do
+ let(:request) { put api(route, current_user), description: new_description }
+ let(:message) { 'Tag does not exist' }
+ end
end
- end
- it 'returns 404 if the tag does not exist' do
- put api("/projects/#{project.id}/repository/tags/foobar/release", user),
- description: new_description
+ context 'when repository is disabled' do
+ include_context 'disabled repository'
- expect(response).to have_http_status(404)
- expect(json_response['message']).to eq('Tag does not exist')
+ it_behaves_like '403 response' do
+ let(:request) { put api(route, current_user), description: new_description }
+ end
+ end
end
- it 'returns 404 if the release does not exist' do
- put api("/projects/#{project.id}/repository/tags/#{tag_name}/release", user),
- description: new_description
+ context 'when authenticated', 'as a master' do
+ let(:current_user) { user }
+
+ it_behaves_like 'repository update release'
- expect(response).to have_http_status(404)
- expect(json_response['message']).to eq('Release does not exist')
+ context 'requesting with the escaped project full path' do
+ let(:project_id) { CGI.escape(project.full_path) }
+
+ it_behaves_like 'repository update release'
+ end
+
+ context 'when release does not exist' do
+ it_behaves_like '404 response' do
+ let(:request) { put api(route, current_user), description: new_description }
+ let(:message) { 'Release does not exist' }
+ end
+ end
end
end
end
diff --git a/spec/requests/api/todos_spec.rb b/spec/requests/api/todos_spec.rb
index 9fc73c6e092..25d7f6dffcf 100644
--- a/spec/requests/api/todos_spec.rb
+++ b/spec/requests/api/todos_spec.rb
@@ -1,8 +1,8 @@
require 'spec_helper'
describe API::Todos do
- let(:project_1) { create(:project) }
- let(:project_2) { create(:empty_project) }
+ let(:project_1) { create(:project, :repository) }
+ let(:project_2) { create(:project) }
let(:author_1) { create(:user) }
let(:author_2) { create(:user) }
let(:john_doe) { create(:user, username: 'john_doe') }
diff --git a/spec/requests/api/triggers_spec.rb b/spec/requests/api/triggers_spec.rb
index 153596c2975..572e9a0fd07 100644
--- a/spec/requests/api/triggers_spec.rb
+++ b/spec/requests/api/triggers_spec.rb
@@ -13,7 +13,7 @@ describe API::Triggers do
let!(:trigger_request) { create(:ci_trigger_request, trigger: trigger, created_at: '2015-01-01 12:13:14') }
describe 'POST /projects/:project_id/trigger/pipeline' do
- let!(:project2) { create(:project) }
+ let!(:project2) { create(:project, :repository) }
let(:options) do
{
token: trigger_token
@@ -185,7 +185,7 @@ describe API::Triggers do
expect do
post api("/projects/#{project.id}/triggers", user),
description: 'trigger'
- end.to change{project.triggers.count}.by(1)
+ end.to change {project.triggers.count}.by(1)
expect(response).to have_http_status(201)
expect(json_response).to include('description' => 'trigger')
@@ -288,7 +288,7 @@ describe API::Triggers do
delete api("/projects/#{project.id}/triggers/#{trigger.id}", user)
expect(response).to have_http_status(204)
- end.to change{project.triggers.count}.by(-1)
+ end.to change {project.triggers.count}.by(-1)
end
it 'responds with 404 Not Found if requesting non-existing trigger' do
diff --git a/spec/requests/api/users_spec.rb b/spec/requests/api/users_spec.rb
index 66b165b438b..49739a1601a 100644
--- a/spec/requests/api/users_spec.rb
+++ b/spec/requests/api/users_spec.rb
@@ -16,38 +16,44 @@ describe API::Users do
it "returns authorization error when the `username` parameter is not passed" do
get api("/users")
- expect(response).to have_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
end
it "returns the user when a valid `username` parameter is passed" do
- user = create(:user)
-
get api("/users"), username: user.username
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.size).to eq(1)
expect(json_response[0]['id']).to eq(user.id)
expect(json_response[0]['username']).to eq(user.username)
end
- it "returns authorization error when the `username` parameter refers to an inaccessible user" do
- user = create(:user)
-
- stub_application_setting(restricted_visibility_levels: [Gitlab::VisibilityLevel::PUBLIC])
-
- get api("/users"), username: user.username
-
- expect(response).to have_http_status(403)
- end
-
it "returns an empty response when an invalid `username` parameter is passed" do
get api("/users"), username: 'invalid'
- expect(response).to have_http_status(200)
+ expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
expect(json_response.size).to eq(0)
end
+
+ context "when public level is restricted" do
+ before do
+ stub_application_setting(restricted_visibility_levels: [Gitlab::VisibilityLevel::PUBLIC])
+ end
+
+ it "returns authorization error when the `username` parameter refers to an inaccessible user" do
+ get api("/users"), username: user.username
+
+ expect(response).to have_gitlab_http_status(403)
+ end
+
+ it "returns authorization error when the `username` parameter is not passed" do
+ get api("/users")
+
+ expect(response).to have_gitlab_http_status(403)
+ end
+ end
end
context "when authenticated" do
@@ -58,10 +64,10 @@ describe API::Users do
end
context 'when authenticate as a regular user' do
- it "renders 403" do
+ it "renders 200" do
get api("/users", user)
- expect(response).to have_gitlab_http_status(403)
+ expect(response).to have_gitlab_http_status(200)
end
end
@@ -211,9 +217,19 @@ describe API::Users do
it "does not return the user's `is_admin` flag" do
get api("/users/#{user.id}", user)
+ expect(response).to have_http_status(200)
expect(json_response['is_admin']).to be_nil
end
+ context 'when authenticated as admin' do
+ it 'includes the `is_admin` field' do
+ get api("/users/#{user.id}", admin)
+
+ expect(response).to have_http_status(200)
+ expect(json_response['is_admin']).to be(false)
+ end
+ end
+
context 'for an anonymous user' do
it "returns a user by id" do
get api("/users/#{user.id}")
diff --git a/spec/requests/api/v3/award_emoji_spec.rb b/spec/requests/api/v3/award_emoji_spec.rb
index 9234710f488..681e8e04295 100644
--- a/spec/requests/api/v3/award_emoji_spec.rb
+++ b/spec/requests/api/v3/award_emoji_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe API::V3::AwardEmoji do
let(:user) { create(:user) }
- let!(:project) { create(:empty_project) }
+ let!(:project) { create(:project) }
let(:issue) { create(:issue, project: project) }
let!(:award_emoji) { create(:award_emoji, awardable: issue, user: user) }
let!(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
diff --git a/spec/requests/api/v3/boards_spec.rb b/spec/requests/api/v3/boards_spec.rb
index 4d786331d1b..b86aab2ec70 100644
--- a/spec/requests/api/v3/boards_spec.rb
+++ b/spec/requests/api/v3/boards_spec.rb
@@ -4,7 +4,7 @@ describe API::V3::Boards do
let(:user) { create(:user) }
let(:guest) { create(:user) }
let(:non_member) { create(:user) }
- let!(:project) { create(:empty_project, :public, creator_id: user.id, namespace: user.namespace ) }
+ let!(:project) { create(:project, :public, creator_id: user.id, namespace: user.namespace ) }
let!(:dev_label) do
create(:label, title: 'Development', color: '#FFAABB', project: project)
@@ -99,7 +99,7 @@ describe API::V3::Boards do
context "when the user is project owner" do
let(:owner) { create(:user) }
- let(:project) { create(:empty_project, namespace: owner.namespace) }
+ let(:project) { create(:project, namespace: owner.namespace) }
it "deletes the list if an admin requests it" do
delete v3_api("#{base_url}/#{dev_list.id}", owner)
diff --git a/spec/requests/api/v3/deploy_keys_spec.rb b/spec/requests/api/v3/deploy_keys_spec.rb
index 94f4d93a8dc..2affd0cfa51 100644
--- a/spec/requests/api/v3/deploy_keys_spec.rb
+++ b/spec/requests/api/v3/deploy_keys_spec.rb
@@ -3,8 +3,8 @@ require 'spec_helper'
describe API::V3::DeployKeys do
let(:user) { create(:user) }
let(:admin) { create(:admin) }
- let(:project) { create(:empty_project, creator_id: user.id) }
- let(:project2) { create(:empty_project, creator_id: user.id) }
+ let(:project) { create(:project, creator_id: user.id) }
+ let(:project2) { create(:project, creator_id: user.id) }
let(:deploy_key) { create(:deploy_key, public: true) }
let!(:deploy_keys_project) do
@@ -87,7 +87,7 @@ describe API::V3::DeployKeys do
expect do
post v3_api("/projects/#{project.id}/#{path}", admin), key_attrs
- end.to change{ project.deploy_keys.count }.by(1)
+ end.to change { project.deploy_keys.count }.by(1)
end
it 'returns an existing ssh key when attempting to add a duplicate' do
@@ -122,7 +122,7 @@ describe API::V3::DeployKeys do
it 'should delete existing key' do
expect do
delete v3_api("/projects/#{project.id}/#{path}/#{deploy_key.id}", admin)
- end.to change{ project.deploy_keys.count }.by(-1)
+ end.to change { project.deploy_keys.count }.by(-1)
end
it 'should return 404 Not Found with invalid ID' do
@@ -133,7 +133,7 @@ describe API::V3::DeployKeys do
end
describe "POST /projects/:id/#{path}/:key_id/enable" do
- let(:project2) { create(:empty_project) }
+ let(:project2) { create(:project) }
context 'when the user can admin the project' do
it 'enables the key' do
diff --git a/spec/requests/api/v3/environments_spec.rb b/spec/requests/api/v3/environments_spec.rb
index 99f35723974..39264e819a3 100644
--- a/spec/requests/api/v3/environments_spec.rb
+++ b/spec/requests/api/v3/environments_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe API::V3::Environments do
let(:user) { create(:user) }
let(:non_member) { create(:user) }
- let(:project) { create(:empty_project, :private, namespace: user.namespace) }
+ let(:project) { create(:project, :private, namespace: user.namespace) }
let!(:environment) { create(:environment, project: project) }
before do
diff --git a/spec/requests/api/v3/files_spec.rb b/spec/requests/api/v3/files_spec.rb
index 8b2d165c763..4ffa5d1784e 100644
--- a/spec/requests/api/v3/files_spec.rb
+++ b/spec/requests/api/v3/files_spec.rb
@@ -74,7 +74,7 @@ describe API::V3::Files do
context 'when unauthenticated', 'and project is public' do
it_behaves_like 'repository files' do
- let(:project) { create(:project, :public) }
+ let(:project) { create(:project, :public, :repository) }
let(:current_user) { nil }
end
end
diff --git a/spec/requests/api/v3/groups_spec.rb b/spec/requests/api/v3/groups_spec.rb
index 5cdc528e190..778fcc73c30 100644
--- a/spec/requests/api/v3/groups_spec.rb
+++ b/spec/requests/api/v3/groups_spec.rb
@@ -9,9 +9,9 @@ describe API::V3::Groups do
let(:admin) { create(:admin) }
let!(:group1) { create(:group, avatar: File.open(uploaded_image_temp_path)) }
let!(:group2) { create(:group, :private) }
- let!(:project1) { create(:empty_project, namespace: group1) }
- let!(:project2) { create(:empty_project, namespace: group2) }
- let!(:project3) { create(:empty_project, namespace: group1, path: 'test', visibility_level: Gitlab::VisibilityLevel::PRIVATE) }
+ let!(:project1) { create(:project, namespace: group1) }
+ let!(:project2) { create(:project, namespace: group2) }
+ let!(:project3) { create(:project, namespace: group1, path: 'test', visibility_level: Gitlab::VisibilityLevel::PRIVATE) }
before do
group1.add_owner(user1)
@@ -165,7 +165,7 @@ describe API::V3::Groups do
describe "GET /groups/:id" do
context "when authenticated as user" do
it "returns one of user1's groups" do
- project = create(:empty_project, namespace: group2, path: 'Foo')
+ project = create(:project, namespace: group2, path: 'Foo')
create(:project_group_link, project: project, group: group1)
get v3_api("/groups/#{group1.id}", user1)
@@ -307,7 +307,7 @@ describe API::V3::Groups do
end
it 'filters the groups projects' do
- public_project = create(:empty_project, :public, path: 'test1', group: group1)
+ public_project = create(:project, :public, path: 'test1', group: group1)
get v3_api("/groups/#{group1.id}/projects", user1), visibility: 'public'
@@ -501,10 +501,10 @@ describe API::V3::Groups do
end
describe "POST /groups/:id/projects/:project_id" do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:project_path) { CGI.escape(project.full_path) }
- before(:each) do
+ before do
allow_any_instance_of(Projects::TransferService)
.to receive(:execute).and_return(true)
end
diff --git a/spec/requests/api/v3/issues_spec.rb b/spec/requests/api/v3/issues_spec.rb
index 4dff09b6df8..9eb538c4b09 100644
--- a/spec/requests/api/v3/issues_spec.rb
+++ b/spec/requests/api/v3/issues_spec.rb
@@ -1,8 +1,6 @@
require 'spec_helper'
-describe API::V3::Issues do
- include EmailHelpers
-
+describe API::V3::Issues, :mailer do
let(:user) { create(:user) }
let(:user2) { create(:user) }
let(:non_member) { create(:user) }
@@ -10,7 +8,7 @@ describe API::V3::Issues do
let(:author) { create(:author) }
let(:assignee) { create(:assignee) }
let(:admin) { create(:user, :admin) }
- let!(:project) { create(:empty_project, :public, creator_id: user.id, namespace: user.namespace ) }
+ let!(:project) { create(:project, :public, creator_id: user.id, namespace: user.namespace ) }
let!(:closed_issue) do
create :closed_issue,
author: user,
@@ -243,7 +241,7 @@ describe API::V3::Issues do
describe "GET /groups/:id/issues" do
let!(:group) { create(:group) }
- let!(:group_project) { create(:empty_project, :public, creator_id: user.id, namespace: group) }
+ let!(:group_project) { create(:project, :public, creator_id: user.id, namespace: group) }
let!(:group_closed_issue) do
create :closed_issue,
author: user,
@@ -453,7 +451,7 @@ describe API::V3::Issues do
end
it "returns 404 on private projects for other users" do
- private_project = create(:empty_project, :private)
+ private_project = create(:project, :private)
create(:issue, project: private_project)
get v3_api("/projects/#{private_project.id}/issues", non_member)
@@ -462,7 +460,7 @@ describe API::V3::Issues do
end
it 'returns no issues when user has access to project but not issues' do
- restricted_project = create(:empty_project, :public, issues_access_level: ProjectFeature::PRIVATE)
+ restricted_project = create(:project, :public, issues_access_level: ProjectFeature::PRIVATE)
create(:issue, project: restricted_project)
get v3_api("/projects/#{restricted_project.id}/issues", non_member)
@@ -1172,7 +1170,7 @@ describe API::V3::Issues do
context "when the user is project owner" do
let(:owner) { create(:user) }
- let(:project) { create(:empty_project, namespace: owner.namespace) }
+ let(:project) { create(:project, namespace: owner.namespace) }
it "deletes the issue if an admin requests it" do
delete v3_api("/projects/#{project.id}/issues/#{issue.id}", owner)
@@ -1192,8 +1190,8 @@ describe API::V3::Issues do
end
describe '/projects/:id/issues/:issue_id/move' do
- let!(:target_project) { create(:empty_project, path: 'project2', creator_id: user.id, namespace: user.namespace ) }
- let!(:target_project2) { create(:empty_project, creator_id: non_member.id, namespace: non_member.namespace ) }
+ let!(:target_project) { create(:project, path: 'project2', creator_id: user.id, namespace: user.namespace ) }
+ let!(:target_project2) { create(:project, creator_id: non_member.id, namespace: non_member.namespace ) }
it 'moves an issue' do
post v3_api("/projects/#{project.id}/issues/#{issue.id}/move", user),
diff --git a/spec/requests/api/v3/labels_spec.rb b/spec/requests/api/v3/labels_spec.rb
index 62faa1cb129..32f37a08024 100644
--- a/spec/requests/api/v3/labels_spec.rb
+++ b/spec/requests/api/v3/labels_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe API::V3::Labels do
let(:user) { create(:user) }
- let(:project) { create(:empty_project, creator_id: user.id, namespace: user.namespace) }
+ let(:project) { create(:project, creator_id: user.id, namespace: user.namespace) }
let!(:label1) { create(:label, title: 'label1', project: project) }
let!(:priority_label) { create(:label, title: 'bug', project: project, priority: 3) }
diff --git a/spec/requests/api/v3/members_spec.rb b/spec/requests/api/v3/members_spec.rb
index 623f02902b8..bc918a8eb02 100644
--- a/spec/requests/api/v3/members_spec.rb
+++ b/spec/requests/api/v3/members_spec.rb
@@ -7,7 +7,7 @@ describe API::V3::Members do
let(:stranger) { create(:user) }
let(:project) do
- create(:empty_project, :public, :access_requestable, creator_id: master.id, namespace: master.namespace) do |project|
+ create(:project, :public, :access_requestable, creator_id: master.id, namespace: master.namespace) do |project|
project.team << [developer, :developer]
project.team << [master, :master]
project.request_access(access_requester)
diff --git a/spec/requests/api/v3/merge_requests_spec.rb b/spec/requests/api/v3/merge_requests_spec.rb
index 4f9e63f2ace..86f38dd4ec1 100644
--- a/spec/requests/api/v3/merge_requests_spec.rb
+++ b/spec/requests/api/v3/merge_requests_spec.rb
@@ -90,7 +90,7 @@ describe API::MergeRequests do
expect(response).to have_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(3)
- response_dates = json_response.map{ |merge_request| merge_request['created_at'] }
+ response_dates = json_response.map { |merge_request| merge_request['created_at'] }
expect(response_dates).to eq(response_dates.sort)
end
@@ -99,7 +99,7 @@ describe API::MergeRequests do
expect(response).to have_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(3)
- response_dates = json_response.map{ |merge_request| merge_request['created_at'] }
+ response_dates = json_response.map { |merge_request| merge_request['created_at'] }
expect(response_dates).to eq(response_dates.sort.reverse)
end
@@ -108,7 +108,7 @@ describe API::MergeRequests do
expect(response).to have_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(3)
- response_dates = json_response.map{ |merge_request| merge_request['updated_at'] }
+ response_dates = json_response.map { |merge_request| merge_request['updated_at'] }
expect(response_dates).to eq(response_dates.sort.reverse)
end
@@ -117,7 +117,7 @@ describe API::MergeRequests do
expect(response).to have_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(3)
- response_dates = json_response.map{ |merge_request| merge_request['created_at'] }
+ response_dates = json_response.map { |merge_request| merge_request['created_at'] }
expect(response_dates).to eq(response_dates.sort)
end
end
@@ -312,18 +312,20 @@ describe API::MergeRequests do
context 'forked projects' do
let!(:user2) { create(:user) }
- let!(:fork_project) { create(:empty_project, forked_from_project: project, namespace: user2.namespace, creator_id: user2.id) }
- let!(:unrelated_project) { create(:empty_project, namespace: create(:user).namespace, creator_id: user2.id) }
+ let!(:fork_project) { create(:project, forked_from_project: project, namespace: user2.namespace, creator_id: user2.id) }
+ let!(:unrelated_project) { create(:project, namespace: create(:user).namespace, creator_id: user2.id) }
- before :each do |each|
- fork_project.team << [user2, :reporter]
+ before do
+ fork_project.add_reporter(user2)
+
+ allow_any_instance_of(MergeRequest).to receive(:write_ref)
end
it "returns merge_request" do
post v3_api("/projects/#{fork_project.id}/merge_requests", user2),
title: 'Test merge_request', source_branch: "feature_conflict", target_branch: "master",
author: user2, target_project_id: project.id, description: 'Test description for Test merge_request'
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['title']).to eq('Test merge_request')
expect(json_response['description']).to eq('Test description for Test merge_request')
end
@@ -334,7 +336,7 @@ describe API::MergeRequests do
expect(fork_project.forked_from_project).to eq(project)
post v3_api("/projects/#{fork_project.id}/merge_requests", user2),
title: 'Test merge_request', source_branch: "master", target_branch: "master", author: user2, target_project_id: project.id
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
expect(json_response['title']).to eq('Test merge_request')
end
@@ -348,25 +350,25 @@ describe API::MergeRequests do
author: user2,
target_project_id: project.id
- expect(response).to have_http_status(422)
+ expect(response).to have_gitlab_http_status(422)
end
it "returns 400 when source_branch is missing" do
post v3_api("/projects/#{fork_project.id}/merge_requests", user2),
title: 'Test merge_request', target_branch: "master", author: user2, target_project_id: project.id
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it "returns 400 when target_branch is missing" do
post v3_api("/projects/#{fork_project.id}/merge_requests", user2),
title: 'Test merge_request', target_branch: "master", author: user2, target_project_id: project.id
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
it "returns 400 when title is missing" do
post v3_api("/projects/#{fork_project.id}/merge_requests", user2),
target_branch: 'master', source_branch: 'markdown', author: user2, target_project_id: project.id
- expect(response).to have_http_status(400)
+ expect(response).to have_gitlab_http_status(400)
end
context 'when target_branch is specified' do
@@ -377,7 +379,7 @@ describe API::MergeRequests do
source_branch: 'markdown',
author: user,
target_project_id: fork_project.id
- expect(response).to have_http_status(422)
+ expect(response).to have_gitlab_http_status(422)
end
it 'returns 422 if targeting a different fork' do
@@ -387,14 +389,14 @@ describe API::MergeRequests do
source_branch: 'markdown',
author: user2,
target_project_id: unrelated_project.id
- expect(response).to have_http_status(422)
+ expect(response).to have_gitlab_http_status(422)
end
end
it "returns 201 when target_branch is specified and for the same project" do
post v3_api("/projects/#{fork_project.id}/merge_requests", user2),
title: 'Test merge_request', target_branch: 'master', source_branch: 'markdown', author: user2, target_project_id: fork_project.id
- expect(response).to have_http_status(201)
+ expect(response).to have_gitlab_http_status(201)
end
end
end
@@ -635,7 +637,7 @@ describe API::MergeRequests do
end
it 'handles external issues' do
- jira_project = create(:jira_project, :public, name: 'JIR_EXT1')
+ jira_project = create(:jira_project, :public, :repository, name: 'JIR_EXT1')
issue = ExternalIssue.new("#{jira_project.name}-123", jira_project)
merge_request = create(:merge_request, :simple, author: user, assignee: user, source_project: jira_project)
merge_request.update_attribute(:description, "Closes #{issue.to_reference(jira_project)}")
@@ -650,7 +652,7 @@ describe API::MergeRequests do
end
it 'returns 403 if the user has no access to the merge request' do
- project = create(:empty_project, :private)
+ project = create(:project, :private, :repository)
merge_request = create(:merge_request, :simple, source_project: project)
guest = create(:user)
project.team << [guest, :guest]
diff --git a/spec/requests/api/v3/milestones_spec.rb b/spec/requests/api/v3/milestones_spec.rb
index f04efc990a7..feaa87faec7 100644
--- a/spec/requests/api/v3/milestones_spec.rb
+++ b/spec/requests/api/v3/milestones_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe API::V3::Milestones do
let(:user) { create(:user) }
- let!(:project) { create(:empty_project, namespace: user.namespace ) }
+ let!(:project) { create(:project, namespace: user.namespace ) }
let!(:closed_milestone) { create(:closed_milestone, project: project) }
let!(:milestone) { create(:milestone, project: project) }
@@ -194,7 +194,7 @@ describe API::V3::Milestones do
end
describe 'confidential issues' do
- let(:public_project) { create(:empty_project, :public) }
+ let(:public_project) { create(:project, :public) }
let(:milestone) { create(:milestone, project: public_project) }
let(:issue) { create(:issue, project: public_project) }
let(:confidential_issue) { create(:issue, confidential: true, project: public_project) }
diff --git a/spec/requests/api/v3/notes_spec.rb b/spec/requests/api/v3/notes_spec.rb
index b5f98a9a545..56729692eed 100644
--- a/spec/requests/api/v3/notes_spec.rb
+++ b/spec/requests/api/v3/notes_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe API::V3::Notes do
let(:user) { create(:user) }
- let!(:project) { create(:empty_project, :public, namespace: user.namespace) }
+ let!(:project) { create(:project, :public, namespace: user.namespace) }
let!(:issue) { create(:issue, project: project, author: user) }
let!(:merge_request) { create(:merge_request, source_project: project, target_project: project, author: user) }
let!(:snippet) { create(:project_snippet, project: project, author: user) }
@@ -13,12 +13,12 @@ describe API::V3::Notes do
# For testing the cross-reference of a private issue in a public issue
let(:private_user) { create(:user) }
let(:private_project) do
- create(:empty_project, namespace: private_user.namespace)
+ create(:project, namespace: private_user.namespace)
.tap { |p| p.team << [private_user, :master] }
end
let(:private_issue) { create(:issue, project: private_project) }
- let(:ext_proj) { create(:empty_project, :public) }
+ let(:ext_proj) { create(:project, :public) }
let(:ext_issue) { create(:issue, project: ext_proj) }
let!(:cross_reference_note) do
@@ -268,7 +268,7 @@ describe API::V3::Notes do
context 'when user does not have access to read the noteable' do
it 'responds with 404' do
- project = create(:empty_project, :private) { |p| p.add_guest(user) }
+ project = create(:project, :private) { |p| p.add_guest(user) }
issue = create(:issue, :confidential, project: project)
post v3_api("/projects/#{project.id}/issues/#{issue.id}/notes", user),
@@ -279,7 +279,7 @@ describe API::V3::Notes do
end
context 'when user does not have access to create noteable' do
- let(:private_issue) { create(:issue, project: create(:empty_project, :private)) }
+ let(:private_issue) { create(:issue, project: create(:project, :private)) }
##
# We are posting to project user has access to, but we use issue id
diff --git a/spec/requests/api/v3/project_snippets_spec.rb b/spec/requests/api/v3/project_snippets_spec.rb
index 1950c64c690..3963924a066 100644
--- a/spec/requests/api/v3/project_snippets_spec.rb
+++ b/spec/requests/api/v3/project_snippets_spec.rb
@@ -1,7 +1,7 @@
require 'rails_helper'
describe API::ProjectSnippets do
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:user) { create(:user) }
let(:admin) { create(:admin) }
@@ -30,7 +30,7 @@ describe API::ProjectSnippets do
expect(response).to have_http_status(200)
expect(json_response.size).to eq(3)
- expect(json_response.map{ |snippet| snippet['id']} ).to include(public_snippet.id, internal_snippet.id, private_snippet.id)
+ expect(json_response.map { |snippet| snippet['id']} ).to include(public_snippet.id, internal_snippet.id, private_snippet.id)
expect(json_response.last).to have_key('web_url')
end
diff --git a/spec/requests/api/v3/projects_spec.rb b/spec/requests/api/v3/projects_spec.rb
index bbfcaab1ea1..a514166274a 100644
--- a/spec/requests/api/v3/projects_spec.rb
+++ b/spec/requests/api/v3/projects_spec.rb
@@ -7,8 +7,8 @@ describe API::V3::Projects do
let(:user2) { create(:user) }
let(:user3) { create(:user) }
let(:admin) { create(:admin) }
- let(:project) { create(:empty_project, creator_id: user.id, namespace: user.namespace) }
- let(:project2) { create(:empty_project, path: 'project2', creator_id: user.id, namespace: user.namespace) }
+ let(:project) { create(:project, creator_id: user.id, namespace: user.namespace) }
+ let(:project2) { create(:project, path: 'project2', creator_id: user.id, namespace: user.namespace) }
let(:snippet) { create(:project_snippet, :public, author: user, project: project, title: 'example') }
let(:project_member) { create(:project_member, :developer, user: user3, project: project) }
let(:user4) { create(:user) }
@@ -31,7 +31,7 @@ describe API::V3::Projects do
access_level: ProjectMember::MASTER)
end
let(:project4) do
- create(:empty_project,
+ create(:project,
name: 'third_project',
path: 'third_project',
creator_id: user4.id,
@@ -82,7 +82,14 @@ describe API::V3::Projects do
context 'GET /projects?simple=true' do
it 'returns a simplified version of all the projects' do
- expected_keys = %w(id http_url_to_repo web_url name name_with_namespace path path_with_namespace)
+ expected_keys = %w(
+ id description default_branch tag_list
+ ssh_url_to_repo http_url_to_repo web_url
+ name name_with_namespace
+ path path_with_namespace
+ star_count forks_count
+ created_at last_activity_at
+ )
get v3_api('/projects?simple=true', user)
@@ -125,7 +132,7 @@ describe API::V3::Projects do
end
context 'and using archived' do
- let!(:archived_project) { create(:empty_project, creator_id: user.id, namespace: user.namespace, archived: true) }
+ let!(:archived_project) { create(:project, creator_id: user.id, namespace: user.namespace, archived: true) }
it 'returns archived project' do
get v3_api('/projects?archived=true', user)
@@ -281,7 +288,7 @@ describe API::V3::Projects do
end
end
- let!(:public_project) { create(:empty_project, :public) }
+ let!(:public_project) { create(:project, :public) }
before do
project
project2
@@ -312,7 +319,7 @@ describe API::V3::Projects do
end
describe 'GET /projects/starred' do
- let(:public_project) { create(:empty_project, :public) }
+ let(:public_project) { create(:project, :public) }
before do
project_member
@@ -637,13 +644,14 @@ describe API::V3::Projects do
describe 'GET /projects/:id' do
context 'when unauthenticated' do
it 'returns the public projects' do
- public_project = create(:empty_project, :public)
+ public_project = create(:project, :public)
get v3_api("/projects/#{public_project.id}")
expect(response).to have_http_status(200)
expect(json_response['id']).to eq(public_project.id)
expect(json_response['description']).to eq(public_project.description)
+ expect(json_response['default_branch']).to eq(public_project.default_branch)
expect(json_response.keys).not_to include('permissions')
end
end
@@ -718,7 +726,7 @@ describe API::V3::Projects do
it 'handles users with dots' do
dot_user = create(:user, username: 'dot.user')
- project = create(:empty_project, creator_id: dot_user.id, namespace: dot_user.namespace)
+ project = create(:project, creator_id: dot_user.id, namespace: dot_user.namespace)
get v3_api("/projects/#{CGI.escape(project.full_path)}", dot_user)
expect(response).to have_http_status(200)
@@ -766,7 +774,7 @@ describe API::V3::Projects do
end
context 'group project' do
- let(:project2) { create(:empty_project, group: create(:group)) }
+ let(:project2) { create(:project, group: create(:group)) }
before { project2.group.add_owner(user) }
@@ -811,7 +819,7 @@ describe API::V3::Projects do
context 'when unauthenticated' do
it_behaves_like 'project events response' do
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:current_user) { nil }
end
end
@@ -861,7 +869,7 @@ describe API::V3::Projects do
context 'when unauthenticated' do
it_behaves_like 'project users response' do
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:current_user) { nil }
end
end
@@ -975,11 +983,11 @@ describe API::V3::Projects do
end
describe 'fork management' do
- let(:project_fork_target) { create(:empty_project) }
- let(:project_fork_source) { create(:empty_project, :public) }
+ let(:project_fork_target) { create(:project) }
+ let(:project_fork_source) { create(:project, :public) }
describe 'POST /projects/:id/fork/:forked_from_id' do
- let(:new_project_fork_source) { create(:empty_project, :public) }
+ let(:new_project_fork_source) { create(:project, :public) }
it "is not available for non admin users" do
post v3_api("/projects/#{project_fork_target.id}/fork/#{project_fork_source.id}", user)
@@ -996,6 +1004,14 @@ describe API::V3::Projects do
expect(project_fork_target.forked?).to be_truthy
end
+ it 'refreshes the forks count cachce' do
+ expect(project_fork_source.forks_count).to be_zero
+
+ post v3_api("/projects/#{project_fork_target.id}/fork/#{project_fork_source.id}", admin)
+
+ expect(project_fork_source.forks_count).to eq(1)
+ end
+
it 'fails if forked_from project which does not exist' do
post v3_api("/projects/#{project_fork_target.id}/fork/9999", admin)
expect(response).to have_http_status(404)
@@ -1020,7 +1036,7 @@ describe API::V3::Projects do
end
context 'when users belong to project group' do
- let(:project_fork_target) { create(:empty_project, group: create(:group)) }
+ let(:project_fork_target) { create(:project, group: create(:group)) }
before do
project_fork_target.group.add_owner user
@@ -1140,16 +1156,16 @@ describe API::V3::Projects do
describe 'GET /projects/search/:query' do
let!(:query) { 'query'}
- let!(:search) { create(:empty_project, name: query, creator_id: user.id, namespace: user.namespace) }
- let!(:pre) { create(:empty_project, name: "pre_#{query}", creator_id: user.id, namespace: user.namespace) }
- let!(:post) { create(:empty_project, name: "#{query}_post", creator_id: user.id, namespace: user.namespace) }
- let!(:pre_post) { create(:empty_project, name: "pre_#{query}_post", creator_id: user.id, namespace: user.namespace) }
- let!(:unfound) { create(:empty_project, name: 'unfound', creator_id: user.id, namespace: user.namespace) }
- let!(:internal) { create(:empty_project, :internal, name: "internal #{query}") }
- let!(:unfound_internal) { create(:empty_project, :internal, name: 'unfound internal') }
- let!(:public) { create(:empty_project, :public, name: "public #{query}") }
- let!(:unfound_public) { create(:empty_project, :public, name: 'unfound public') }
- let!(:one_dot_two) { create(:empty_project, :public, name: "one.dot.two") }
+ let!(:search) { create(:project, name: query, creator_id: user.id, namespace: user.namespace) }
+ let!(:pre) { create(:project, name: "pre_#{query}", creator_id: user.id, namespace: user.namespace) }
+ let!(:post) { create(:project, name: "#{query}_post", creator_id: user.id, namespace: user.namespace) }
+ let!(:pre_post) { create(:project, name: "pre_#{query}_post", creator_id: user.id, namespace: user.namespace) }
+ let!(:unfound) { create(:project, name: 'unfound', creator_id: user.id, namespace: user.namespace) }
+ let!(:internal) { create(:project, :internal, name: "internal #{query}") }
+ let!(:unfound_internal) { create(:project, :internal, name: 'unfound internal') }
+ let!(:public) { create(:project, :public, name: "public #{query}") }
+ let!(:unfound_public) { create(:project, :public, name: 'unfound public') }
+ let!(:one_dot_two) { create(:project, :public, name: "one.dot.two") }
shared_examples_for 'project search response' do |args = {}|
it 'returns project search responses' do
diff --git a/spec/requests/api/v3/runners_spec.rb b/spec/requests/api/v3/runners_spec.rb
index dbda2cf34c3..a31eb3f1d43 100644
--- a/spec/requests/api/v3/runners_spec.rb
+++ b/spec/requests/api/v3/runners_spec.rb
@@ -5,8 +5,8 @@ describe API::V3::Runners do
let(:user) { create(:user) }
let(:user2) { create(:user) }
- let(:project) { create(:empty_project, creator_id: user.id) }
- let(:project2) { create(:empty_project, creator_id: user.id) }
+ let(:project) { create(:project, creator_id: user.id) }
+ let(:project2) { create(:project, creator_id: user.id) }
let!(:shared_runner) { create(:ci_runner, :shared) }
let!(:unused_specific_runner) { create(:ci_runner) }
@@ -38,7 +38,7 @@ describe API::V3::Runners do
delete v3_api("/runners/#{shared_runner.id}", admin)
expect(response).to have_http_status(200)
- end.to change{ Ci::Runner.shared.count }.by(-1)
+ end.to change { Ci::Runner.shared.count }.by(-1)
end
end
@@ -48,7 +48,7 @@ describe API::V3::Runners do
delete v3_api("/runners/#{unused_specific_runner.id}", admin)
expect(response).to have_http_status(200)
- end.to change{ Ci::Runner.specific.count }.by(-1)
+ end.to change { Ci::Runner.specific.count }.by(-1)
end
it 'deletes used runner' do
@@ -56,7 +56,7 @@ describe API::V3::Runners do
delete v3_api("/runners/#{specific_runner.id}", admin)
expect(response).to have_http_status(200)
- end.to change{ Ci::Runner.specific.count }.by(-1)
+ end.to change { Ci::Runner.specific.count }.by(-1)
end
end
@@ -91,7 +91,7 @@ describe API::V3::Runners do
delete v3_api("/runners/#{specific_runner.id}", user)
expect(response).to have_http_status(200)
- end.to change{ Ci::Runner.specific.count }.by(-1)
+ end.to change { Ci::Runner.specific.count }.by(-1)
end
end
end
@@ -113,7 +113,7 @@ describe API::V3::Runners do
delete v3_api("/projects/#{project.id}/runners/#{two_projects_runner.id}", user)
expect(response).to have_http_status(200)
- end.to change{ project.runners.count }.by(-1)
+ end.to change { project.runners.count }.by(-1)
end
end
@@ -121,7 +121,7 @@ describe API::V3::Runners do
it "does not disable project's runner" do
expect do
delete v3_api("/projects/#{project.id}/runners/#{specific_runner.id}", user)
- end.to change{ project.runners.count }.by(0)
+ end.to change { project.runners.count }.by(0)
expect(response).to have_http_status(403)
end
end
diff --git a/spec/requests/api/v3/services_spec.rb b/spec/requests/api/v3/services_spec.rb
index 3ba62de822a..f0fa48e22df 100644
--- a/spec/requests/api/v3/services_spec.rb
+++ b/spec/requests/api/v3/services_spec.rb
@@ -2,7 +2,7 @@ require "spec_helper"
describe API::V3::Services do
let(:user) { create(:user) }
- let(:project) { create(:empty_project, creator_id: user.id, namespace: user.namespace) }
+ let(:project) { create(:project, creator_id: user.id, namespace: user.namespace) }
available_services = Service.available_services_names
available_services.delete('prometheus')
diff --git a/spec/requests/api/v3/snippets_spec.rb b/spec/requests/api/v3/snippets_spec.rb
index 1bc2258ebd3..9ead3cad8bb 100644
--- a/spec/requests/api/v3/snippets_spec.rb
+++ b/spec/requests/api/v3/snippets_spec.rb
@@ -45,10 +45,10 @@ describe API::V3::Snippets do
expect(json_response.map { |snippet| snippet['id']} ).to contain_exactly(
public_snippet.id,
public_snippet_other.id)
- expect(json_response.map{ |snippet| snippet['web_url']} ).to include(
+ expect(json_response.map { |snippet| snippet['web_url']} ).to include(
"http://localhost/snippets/#{public_snippet.id}",
"http://localhost/snippets/#{public_snippet_other.id}")
- expect(json_response.map{ |snippet| snippet['raw_url']} ).to include(
+ expect(json_response.map { |snippet| snippet['raw_url']} ).to include(
"http://localhost/snippets/#{public_snippet.id}/raw",
"http://localhost/snippets/#{public_snippet_other.id}/raw")
end
diff --git a/spec/requests/api/v3/todos_spec.rb b/spec/requests/api/v3/todos_spec.rb
index 9c2c4d64257..8f5c3fbf8dd 100644
--- a/spec/requests/api/v3/todos_spec.rb
+++ b/spec/requests/api/v3/todos_spec.rb
@@ -1,8 +1,8 @@
require 'spec_helper'
describe API::V3::Todos do
- let(:project_1) { create(:empty_project) }
- let(:project_2) { create(:empty_project) }
+ let(:project_1) { create(:project) }
+ let(:project_2) { create(:project) }
let(:author_1) { create(:user) }
let(:author_2) { create(:user) }
let(:john_doe) { create(:user, username: 'john_doe') }
diff --git a/spec/requests/api/v3/triggers_spec.rb b/spec/requests/api/v3/triggers_spec.rb
index 60212660fb6..075de2c0cba 100644
--- a/spec/requests/api/v3/triggers_spec.rb
+++ b/spec/requests/api/v3/triggers_spec.rb
@@ -171,7 +171,7 @@ describe API::V3::Triggers do
it 'creates trigger' do
expect do
post v3_api("/projects/#{project.id}/triggers", user)
- end.to change{project.triggers.count}.by(1)
+ end.to change {project.triggers.count}.by(1)
expect(response).to have_http_status(201)
expect(json_response).to be_a(Hash)
@@ -202,7 +202,7 @@ describe API::V3::Triggers do
delete v3_api("/projects/#{project.id}/triggers/#{trigger.token}", user)
expect(response).to have_http_status(200)
- end.to change{project.triggers.count}.by(-1)
+ end.to change {project.triggers.count}.by(-1)
end
it 'responds with 404 Not Found if requesting non-existing trigger' do
diff --git a/spec/requests/api/v3/users_spec.rb b/spec/requests/api/v3/users_spec.rb
index de7499a4e43..227b8d1b0c1 100644
--- a/spec/requests/api/v3/users_spec.rb
+++ b/spec/requests/api/v3/users_spec.rb
@@ -232,7 +232,7 @@ describe API::V3::Users do
describe 'GET /users/:id/events' do
let(:user) { create(:user) }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:note) { create(:note_on_issue, note: 'What an awesome day!', project: project) }
before do
@@ -252,6 +252,31 @@ describe API::V3::Users do
end
context "as a user than can see the event's project" do
+ context 'when the list of events includes push events' do
+ let(:event) { create(:push_event, author: user, project: project) }
+ let!(:payload) { create(:push_event_payload, event: event) }
+ let(:payload_hash) { json_response[0]['push_data'] }
+
+ before do
+ get api("/users/#{user.id}/events?action=pushed", user)
+ end
+
+ it 'responds with HTTP 200 OK' do
+ expect(response).to have_http_status(200)
+ end
+
+ it 'includes the push payload as a Hash' do
+ expect(payload_hash).to be_an_instance_of(Hash)
+ end
+
+ it 'includes the push payload details' do
+ expect(payload_hash['commit_count']).to eq(payload.commit_count)
+ expect(payload_hash['action']).to eq(payload.action)
+ expect(payload_hash['ref_type']).to eq(payload.ref_type)
+ expect(payload_hash['commit_to']).to eq(payload.commit_to)
+ end
+ end
+
context 'joined event' do
it 'returns the "joined" event' do
get v3_api("/users/#{user.id}/events", user)
@@ -276,7 +301,7 @@ describe API::V3::Users do
end
context 'when there are multiple events from different projects' do
- let(:second_note) { create(:note_on_issue, project: create(:empty_project)) }
+ let(:second_note) { create(:note_on_issue, project: create(:project)) }
let(:third_note) { create(:note_on_issue, project: project) }
before do
diff --git a/spec/requests/api/variables_spec.rb b/spec/requests/api/variables_spec.rb
index e0975024b80..48592e12822 100644
--- a/spec/requests/api/variables_spec.rb
+++ b/spec/requests/api/variables_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe API::Variables do
let(:user) { create(:user) }
let(:user2) { create(:user) }
- let!(:project) { create(:empty_project, creator_id: user.id) }
+ let!(:project) { create(:project, creator_id: user.id) }
let!(:master) { create(:project_member, :master, user: user, project: project) }
let!(:developer) { create(:project_member, :developer, user: user2, project: project) }
let!(:variable) { create(:ci_variable, project: project) }
@@ -74,7 +74,7 @@ describe API::Variables do
it 'creates variable' do
expect do
post api("/projects/#{project.id}/variables", user), key: 'TEST_VARIABLE_2', value: 'VALUE_2', protected: true
- end.to change{project.variables.count}.by(1)
+ end.to change {project.variables.count}.by(1)
expect(response).to have_http_status(201)
expect(json_response['key']).to eq('TEST_VARIABLE_2')
@@ -85,7 +85,7 @@ describe API::Variables do
it 'creates variable with optional attributes' do
expect do
post api("/projects/#{project.id}/variables", user), key: 'TEST_VARIABLE_2', value: 'VALUE_2'
- end.to change{project.variables.count}.by(1)
+ end.to change {project.variables.count}.by(1)
expect(response).to have_http_status(201)
expect(json_response['key']).to eq('TEST_VARIABLE_2')
@@ -96,7 +96,7 @@ describe API::Variables do
it 'does not allow to duplicate variable key' do
expect do
post api("/projects/#{project.id}/variables", user), key: variable.key, value: 'VALUE_2'
- end.to change{project.variables.count}.by(0)
+ end.to change {project.variables.count}.by(0)
expect(response).to have_http_status(400)
end
@@ -166,7 +166,7 @@ describe API::Variables do
delete api("/projects/#{project.id}/variables/#{variable.key}", user)
expect(response).to have_http_status(204)
- end.to change{project.variables.count}.by(-1)
+ end.to change {project.variables.count}.by(-1)
end
it 'responds with 404 Not Found if requesting non-existing variable' do
diff --git a/spec/requests/ci/api/builds_spec.rb b/spec/requests/ci/api/builds_spec.rb
index 49e815ee16c..ebd67eb1e94 100644
--- a/spec/requests/ci/api/builds_spec.rb
+++ b/spec/requests/ci/api/builds_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe Ci::API::Builds do
let(:runner) { FactoryGirl.create(:ci_runner, tag_list: %w(mysql ruby)) }
- let(:project) { FactoryGirl.create(:empty_project, shared_runners_enabled: false) }
+ let(:project) { FactoryGirl.create(:project, shared_runners_enabled: false) }
let(:last_update) { nil }
describe "Builds API for runners" do
@@ -421,7 +421,7 @@ describe Ci::API::Builds do
end
context 'when build has been updated recently' do
- it { expect{ patch_the_trace }.not_to change { build.updated_at }}
+ it { expect { patch_the_trace }.not_to change { build.updated_at }}
it 'changes the build trace' do
patch_the_trace
@@ -430,7 +430,7 @@ describe Ci::API::Builds do
end
context 'when Runner makes a force-patch' do
- it { expect{ force_patch_the_trace }.not_to change { build.updated_at }}
+ it { expect { force_patch_the_trace }.not_to change { build.updated_at }}
it "doesn't change the build.trace" do
force_patch_the_trace
diff --git a/spec/requests/ci/api/runners_spec.rb b/spec/requests/ci/api/runners_spec.rb
index 78b2be350cd..75059dd20a0 100644
--- a/spec/requests/ci/api/runners_spec.rb
+++ b/spec/requests/ci/api/runners_spec.rb
@@ -70,7 +70,7 @@ describe Ci::API::Runners do
end
context 'when project token is provided' do
- let(:project) { FactoryGirl.create(:empty_project) }
+ let(:project) { FactoryGirl.create(:project) }
before do
post ci_api("/runners/register"), token: project.runners_token
diff --git a/spec/requests/ci/api/triggers_spec.rb b/spec/requests/ci/api/triggers_spec.rb
index e481ca916ab..7c77ebb69a2 100644
--- a/spec/requests/ci/api/triggers_spec.rb
+++ b/spec/requests/ci/api/triggers_spec.rb
@@ -4,7 +4,7 @@ describe Ci::API::Triggers do
describe 'POST /projects/:project_id/refs/:ref/trigger' do
let!(:trigger_token) { 'secure token' }
let!(:project) { create(:project, :repository, ci_id: 10) }
- let!(:project2) { create(:empty_project, ci_id: 11) }
+ let!(:project2) { create(:project, ci_id: 11) }
let!(:trigger) do
create(:ci_trigger,
diff --git a/spec/requests/git_http_spec.rb b/spec/requests/git_http_spec.rb
index d4a3e8b13e1..ecac40e301b 100644
--- a/spec/requests/git_http_spec.rb
+++ b/spec/requests/git_http_spec.rb
@@ -123,7 +123,7 @@ describe 'Git HTTP requests' do
context "when requesting the Wiki" do
let(:wiki) { ProjectWiki.new(project) }
- let(:path) { "/#{wiki.repository.path_with_namespace}.git" }
+ let(:path) { "/#{wiki.repository.full_path}.git" }
context "when the project is public" do
let(:project) { create(:project, :repository, :public, :wiki_enabled) }
@@ -139,7 +139,7 @@ describe 'Git HTTP requests' do
download(path) do |response|
json_body = ActiveSupport::JSON.decode(response.body)
- expect(json_body['RepoPath']).to include(wiki.repository.path_with_namespace)
+ expect(json_body['RepoPath']).to include(wiki.repository.full_path)
end
end
end
@@ -222,7 +222,7 @@ describe 'Git HTTP requests' do
end
context "when the project exists" do
- let(:path) { "#{project.path_with_namespace}.git" }
+ let(:path) { "#{project.full_path}.git" }
context "when the project is public" do
let(:project) { create(:project, :repository, :public) }
@@ -286,7 +286,7 @@ describe 'Git HTTP requests' do
context 'when the request is not from gitlab-workhorse' do
it 'raises an exception' do
expect do
- get("/#{project.path_with_namespace}.git/info/refs?service=git-upload-pack")
+ get("/#{project.full_path}.git/info/refs?service=git-upload-pack")
end.to raise_error(JWT::DecodeError)
end
end
@@ -294,7 +294,7 @@ describe 'Git HTTP requests' do
context 'when the repo is public' do
context 'but the repo is disabled' do
let(:project) { create(:project, :public, :repository, :repository_disabled) }
- let(:path) { "#{project.path_with_namespace}.git" }
+ let(:path) { "#{project.full_path}.git" }
let(:env) { {} }
it_behaves_like 'pulls require Basic HTTP Authentication'
@@ -303,7 +303,7 @@ describe 'Git HTTP requests' do
context 'but the repo is enabled' do
let(:project) { create(:project, :public, :repository, :repository_enabled) }
- let(:path) { "#{project.path_with_namespace}.git" }
+ let(:path) { "#{project.full_path}.git" }
let(:env) { {} }
it_behaves_like 'pulls are allowed'
@@ -421,7 +421,7 @@ describe 'Git HTTP requests' do
@token = Doorkeeper::AccessToken.create!(application_id: application.id, resource_owner_id: user.id, scopes: "api")
end
- let(:path) { "#{project.path_with_namespace}.git" }
+ let(:path) { "#{project.full_path}.git" }
let(:env) { { user: 'oauth2', password: @token.token } }
it_behaves_like 'pulls are allowed'
@@ -431,7 +431,7 @@ describe 'Git HTTP requests' do
context 'when user has 2FA enabled' do
let(:user) { create(:user, :two_factor) }
let(:access_token) { create(:personal_access_token, user: user) }
- let(:path) { "#{project.path_with_namespace}.git" }
+ let(:path) { "#{project.full_path}.git" }
before do
project.team << [user, :master]
@@ -573,14 +573,14 @@ describe 'Git HTTP requests' do
context "when a gitlab ci token is provided" do
let(:project) { create(:project, :repository) }
let(:build) { create(:ci_build, :running) }
- let(:other_project) { create(:empty_project) }
+ let(:other_project) { create(:project) }
before do
build.update!(project: project) # can't associate it on factory create
end
context 'when build created by system is authenticated' do
- let(:path) { "#{project.path_with_namespace}.git" }
+ let(:path) { "#{project.full_path}.git" }
let(:env) { { user: 'gitlab-ci-token', password: build.token } }
it_behaves_like 'pulls are allowed'
@@ -602,7 +602,7 @@ describe 'Git HTTP requests' do
# We are "authenticated" as CI using a valid token here. But we are
# not authorized to see any other project, so return "not found".
it "rejects pulls for other project with 404 Not Found" do
- clone_get("#{other_project.path_with_namespace}.git", env)
+ clone_get("#{other_project.full_path}.git", env)
expect(response).to have_http_status(:not_found)
expect(response.body).to eq(git_access_error(:project_not_found))
@@ -616,13 +616,13 @@ describe 'Git HTTP requests' do
end
shared_examples 'can download code only' do
- let(:path) { "#{project.path_with_namespace}.git" }
+ let(:path) { "#{project.full_path}.git" }
let(:env) { { user: 'gitlab-ci-token', password: build.token } }
it_behaves_like 'pulls are allowed'
context 'when the repo does not exist' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
it 'rejects pulls with 403 Forbidden' do
clone_get path, env
@@ -646,7 +646,7 @@ describe 'Git HTTP requests' do
it_behaves_like 'can download code only'
it 'downloads from other project get status 403' do
- clone_get "#{other_project.path_with_namespace}.git", user: 'gitlab-ci-token', password: build.token
+ clone_get "#{other_project.full_path}.git", user: 'gitlab-ci-token', password: build.token
expect(response).to have_http_status(:forbidden)
end
@@ -658,7 +658,7 @@ describe 'Git HTTP requests' do
it_behaves_like 'can download code only'
it 'downloads from other project get status 404' do
- clone_get "#{other_project.path_with_namespace}.git", user: 'gitlab-ci-token', password: build.token
+ clone_get "#{other_project.full_path}.git", user: 'gitlab-ci-token', password: build.token
expect(response).to have_http_status(:not_found)
end
@@ -671,7 +671,7 @@ describe 'Git HTTP requests' do
let(:project) { create(:project, :repository, :public, path: 'project.git-project') }
context "GET info/refs" do
- let(:path) { "/#{project.path_with_namespace}/info/refs" }
+ let(:path) { "/#{project.full_path}/info/refs" }
context "when no params are added" do
before do
@@ -679,7 +679,7 @@ describe 'Git HTTP requests' do
end
it "redirects to the .git suffix version" do
- expect(response).to redirect_to("/#{project.path_with_namespace}.git/info/refs")
+ expect(response).to redirect_to("/#{project.full_path}.git/info/refs")
end
end
@@ -691,7 +691,7 @@ describe 'Git HTTP requests' do
end
it "redirects to the .git suffix version" do
- expect(response).to redirect_to("/#{project.path_with_namespace}.git/info/refs?service=#{params[:service]}")
+ expect(response).to redirect_to("/#{project.full_path}.git/info/refs?service=#{params[:service]}")
end
end
@@ -703,7 +703,7 @@ describe 'Git HTTP requests' do
end
it "redirects to the .git suffix version" do
- expect(response).to redirect_to("/#{project.path_with_namespace}.git/info/refs?service=#{params[:service]}")
+ expect(response).to redirect_to("/#{project.full_path}.git/info/refs?service=#{params[:service]}")
end
end
@@ -722,13 +722,13 @@ describe 'Git HTTP requests' do
context "POST git-upload-pack" do
it "fails to find a route" do
- expect { clone_post(project.path_with_namespace) }.to raise_error(ActionController::RoutingError)
+ expect { clone_post(project.full_path) }.to raise_error(ActionController::RoutingError)
end
end
context "POST git-receive-pack" do
it "fails to find a route" do
- expect { push_post(project.path_with_namespace) }.to raise_error(ActionController::RoutingError)
+ expect { push_post(project.full_path) }.to raise_error(ActionController::RoutingError)
end
end
end
@@ -744,7 +744,7 @@ describe 'Git HTTP requests' do
Blob.decorate(Gitlab::Git::Blob.find(project.repository, 'master', 'bar/branch-test.txt'), project)
end
- get "/#{project.path_with_namespace}/blob/master/info/refs"
+ get "/#{project.full_path}/blob/master/info/refs"
end
it "returns the file" do
@@ -754,7 +754,7 @@ describe 'Git HTTP requests' do
context "when the file does not exist" do
before do
- get "/#{project.path_with_namespace}/blob/master/info/refs"
+ get "/#{project.full_path}/blob/master/info/refs"
end
it "returns not found" do
diff --git a/spec/requests/lfs_http_spec.rb b/spec/requests/lfs_http_spec.rb
index 697b150ab34..27d09b8202e 100644
--- a/spec/requests/lfs_http_spec.rb
+++ b/spec/requests/lfs_http_spec.rb
@@ -20,7 +20,7 @@ describe 'Git LFS API and storage' do
let(:sample_size) { lfs_object.size }
describe 'when lfs is disabled' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:body) do
{
'objects' => [
@@ -46,7 +46,7 @@ describe 'Git LFS API and storage' do
end
context 'project specific LFS settings' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:body) do
{
'objects' => [
@@ -151,7 +151,7 @@ describe 'Git LFS API and storage' do
end
describe 'deprecated API' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
before do
enable_lfs
@@ -188,7 +188,7 @@ describe 'Git LFS API and storage' do
end
describe 'when fetching lfs object' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:update_permissions) { }
before do
@@ -281,7 +281,7 @@ describe 'Git LFS API and storage' do
shared_examples 'can download LFS only from own projects' do
context 'for owned project' do
- let(:project) { create(:empty_project, namespace: user.namespace) }
+ let(:project) { create(:project, namespace: user.namespace) }
let(:update_permissions) do
project.lfs_objects << lfs_object
@@ -302,7 +302,7 @@ describe 'Git LFS API and storage' do
end
context 'for other project' do
- let(:other_project) { create(:empty_project) }
+ let(:other_project) { create(:project) }
let(:pipeline) { create(:ci_empty_pipeline, project: other_project) }
let(:update_permissions) do
@@ -368,7 +368,7 @@ describe 'Git LFS API and storage' do
end
describe 'download' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:body) do
{
'operation' => 'download',
@@ -408,7 +408,7 @@ describe 'Git LFS API and storage' do
end
context 'when downloading an lfs object that is assigned to other project' do
- let(:other_project) { create(:empty_project) }
+ let(:other_project) { create(:project) }
let(:update_lfs_permissions) do
other_project.lfs_objects << lfs_object
end
@@ -559,7 +559,7 @@ describe 'Git LFS API and storage' do
end
context 'for other project' do
- let(:other_project) { create(:empty_project) }
+ let(:other_project) { create(:project) }
let(:pipeline) { create(:ci_empty_pipeline, project: other_project) }
it 'rejects downloading code' do
@@ -662,7 +662,7 @@ describe 'Git LFS API and storage' do
end
context 'when pushing an lfs object that already exists' do
- let(:other_project) { create(:empty_project) }
+ let(:other_project) { create(:project) }
let(:update_lfs_permissions) do
other_project.lfs_objects << lfs_object
end
@@ -701,7 +701,7 @@ describe 'Git LFS API and storage' do
expect(json_response['objects']).to be_kind_of(Array)
expect(json_response['objects'].first['oid']).to eq("91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897")
expect(json_response['objects'].first['size']).to eq(1575078)
- expect(json_response['objects'].first['actions']['upload']['href']).to eq("#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}.git/gitlab-lfs/objects/91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897/1575078")
+ expect(json_response['objects'].first['actions']['upload']['href']).to eq("#{Gitlab.config.gitlab.url}/#{project.full_path}.git/gitlab-lfs/objects/91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897/1575078")
expect(json_response['objects'].first['actions']['upload']['header']).to eq('Authorization' => authorization)
end
end
@@ -765,7 +765,7 @@ describe 'Git LFS API and storage' do
end
context 'tries to push to other project' do
- let(:other_project) { create(:empty_project) }
+ let(:other_project) { create(:project) }
let(:pipeline) { create(:ci_empty_pipeline, project: other_project) }
let(:build) { create(:ci_build, :running, pipeline: pipeline, user: user) }
@@ -806,7 +806,7 @@ describe 'Git LFS API and storage' do
end
describe 'unsupported' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:authorization) { authorize_user }
let(:body) do
{
@@ -894,7 +894,7 @@ describe 'Git LFS API and storage' do
end
describe 'to one project' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
describe 'when user is authenticated' do
let(:authorization) { authorize_user }
@@ -986,7 +986,7 @@ describe 'Git LFS API and storage' do
end
context 'tries to push to other project' do
- let(:other_project) { create(:empty_project) }
+ let(:other_project) { create(:project) }
let(:pipeline) { create(:ci_empty_pipeline, project: other_project) }
let(:build) { create(:ci_build, :running, pipeline: pipeline, user: user) }
@@ -1086,7 +1086,7 @@ describe 'Git LFS API and storage' do
end
context 'tries to push to other project' do
- let(:other_project) { create(:empty_project) }
+ let(:other_project) { create(:project) }
let(:pipeline) { create(:ci_empty_pipeline, project: other_project) }
let(:build) { create(:ci_build, :running, pipeline: pipeline, user: user) }
@@ -1111,7 +1111,7 @@ describe 'Git LFS API and storage' do
end
describe 'and second project not related to fork or a source project' do
- let(:second_project) { create(:empty_project) }
+ let(:second_project) { create(:project) }
let(:authorization) { authorize_user }
before do
diff --git a/spec/requests/request_profiler_spec.rb b/spec/requests/request_profiler_spec.rb
index 51fbfecec4b..9afeb2983b0 100644
--- a/spec/requests/request_profiler_spec.rb
+++ b/spec/requests/request_profiler_spec.rb
@@ -15,7 +15,7 @@ describe 'Request Profiler' do
it 'creates a profile of the request' do
project = create(:project, namespace: user.namespace)
time = Time.now
- path = "/#{project.path_with_namespace}"
+ path = "/#{project.full_path}"
Timecop.freeze(time) do
get path, nil, 'X-Profile-Token' => Gitlab::RequestProfiler.profile_token
diff --git a/spec/routing/environments_spec.rb b/spec/routing/environments_spec.rb
index 9b70c2a24be..aacbe300966 100644
--- a/spec/routing/environments_spec.rb
+++ b/spec/routing/environments_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe 'environments routing' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:environment) do
create(:environment, project: project,
diff --git a/spec/routing/project_routing_spec.rb b/spec/routing/project_routing_spec.rb
index c02409b2e0b..39d44245c3f 100644
--- a/spec/routing/project_routing_spec.rb
+++ b/spec/routing/project_routing_spec.rb
@@ -165,15 +165,19 @@ describe 'project routing' do
# edit_project_repository GET /:project_id/repository/edit(.:format) projects/repositories#edit
describe Projects::RepositoriesController, 'routing' do
it 'to #archive' do
- expect(get('/gitlab/gitlabhq/repository/archive')).to route_to('projects/repositories#archive', namespace_id: 'gitlab', project_id: 'gitlabhq')
+ expect(get('/gitlab/gitlabhq/repository/master/archive')).to route_to('projects/repositories#archive', namespace_id: 'gitlab', project_id: 'gitlabhq', ref: 'master')
end
it 'to #archive format:zip' do
- expect(get('/gitlab/gitlabhq/repository/archive.zip')).to route_to('projects/repositories#archive', namespace_id: 'gitlab', project_id: 'gitlabhq', format: 'zip')
+ expect(get('/gitlab/gitlabhq/repository/master/archive.zip')).to route_to('projects/repositories#archive', namespace_id: 'gitlab', project_id: 'gitlabhq', format: 'zip', ref: 'master')
end
it 'to #archive format:tar.bz2' do
- expect(get('/gitlab/gitlabhq/repository/archive.tar.bz2')).to route_to('projects/repositories#archive', namespace_id: 'gitlab', project_id: 'gitlabhq', format: 'tar.bz2')
+ expect(get('/gitlab/gitlabhq/repository/master/archive.tar.bz2')).to route_to('projects/repositories#archive', namespace_id: 'gitlab', project_id: 'gitlabhq', format: 'tar.bz2', ref: 'master')
+ end
+
+ it 'to #archive with "/" in route' do
+ expect(get('/gitlab/gitlabhq/repository/improve/awesome/archive')).to route_to('projects/repositories#archive', namespace_id: 'gitlab', project_id: 'gitlabhq', ref: 'improve/awesome')
end
end
diff --git a/spec/rubocop/cop/migration/safer_boolean_column_spec.rb b/spec/rubocop/cop/migration/safer_boolean_column_spec.rb
new file mode 100644
index 00000000000..1006594499a
--- /dev/null
+++ b/spec/rubocop/cop/migration/safer_boolean_column_spec.rb
@@ -0,0 +1,85 @@
+require 'spec_helper'
+
+require 'rubocop'
+require 'rubocop/rspec/support'
+
+require_relative '../../../../rubocop/cop/migration/safer_boolean_column'
+
+describe RuboCop::Cop::Migration::SaferBooleanColumn do
+ include CopHelper
+
+ subject(:cop) { described_class.new }
+
+ context 'in migration' do
+ before do
+ allow(cop).to receive(:in_migration?).and_return(true)
+ end
+
+ described_class::SMALL_TABLES.each do |table|
+ context "for the #{table} table" do
+ sources_and_offense = [
+ ["add_column :#{table}, :column, :boolean, default: true", 'should disallow nulls'],
+ ["add_column :#{table}, :column, :boolean, default: false", 'should disallow nulls'],
+ ["add_column :#{table}, :column, :boolean, default: nil", 'should have a default and should disallow nulls'],
+ ["add_column :#{table}, :column, :boolean, null: false", 'should have a default'],
+ ["add_column :#{table}, :column, :boolean, null: true", 'should have a default and should disallow nulls'],
+ ["add_column :#{table}, :column, :boolean", 'should have a default and should disallow nulls'],
+ ["add_column :#{table}, :column, :boolean, default: nil, null: false", 'should have a default'],
+ ["add_column :#{table}, :column, :boolean, default: nil, null: true", 'should have a default and should disallow nulls'],
+ ["add_column :#{table}, :column, :boolean, default: false, null: true", 'should disallow nulls']
+ ]
+
+ sources_and_offense.each do |source, offense|
+ context "given the source \"#{source}\"" do
+ it "registers the offense matching \"#{offense}\"" do
+ inspect_source(cop, source)
+
+ aggregate_failures do
+ expect(cop.offenses.first.message).to match(offense)
+ end
+ end
+ end
+ end
+
+ inoffensive_sources = [
+ "add_column :#{table}, :column, :boolean, default: true, null: false",
+ "add_column :#{table}, :column, :boolean, default: false, null: false"
+ ]
+
+ inoffensive_sources.each do |source|
+ context "given the source \"#{source}\"" do
+ it "registers no offense" do
+ inspect_source(cop, source)
+
+ aggregate_failures do
+ expect(cop.offenses).to be_empty
+ end
+ end
+ end
+ end
+ end
+ end
+
+ it 'registers no offense for tables not listed in SMALL_TABLES' do
+ inspect_source(cop, "add_column :large_table, :column, :boolean")
+
+ expect(cop.offenses).to be_empty
+ end
+
+ it 'registers no offense for non-boolean columns' do
+ table = described_class::SMALL_TABLES.sample
+ inspect_source(cop, "add_column :#{table}, :column, :string")
+
+ expect(cop.offenses).to be_empty
+ end
+ end
+
+ context 'outside of migration' do
+ it 'registers no offense' do
+ table = described_class::SMALL_TABLES.sample
+ inspect_source(cop, "add_column :#{table}, :column, :boolean")
+
+ expect(cop.offenses).to be_empty
+ end
+ end
+end
diff --git a/spec/serializers/analytics_build_entity_spec.rb b/spec/serializers/analytics_build_entity_spec.rb
index 86e703a6448..1ff4908972a 100644
--- a/spec/serializers/analytics_build_entity_spec.rb
+++ b/spec/serializers/analytics_build_entity_spec.rb
@@ -13,12 +13,8 @@ describe AnalyticsBuildEntity do
subject { entity.as_json }
- before do
- Timecop.freeze
- end
-
- after do
- Timecop.return
+ around do |example|
+ Timecop.freeze { example.run }
end
it 'contains the URL' do
@@ -47,7 +43,7 @@ describe AnalyticsBuildEntity do
let(:finished_at) { nil }
it 'does not blow up' do
- expect{ subject[:date] }.not_to raise_error
+ expect { subject[:date] }.not_to raise_error
end
it 'shows the right message' do
@@ -63,7 +59,7 @@ describe AnalyticsBuildEntity do
let(:started_at) { nil }
it 'does not blow up' do
- expect{ subject[:date] }.not_to raise_error
+ expect { subject[:date] }.not_to raise_error
end
it 'shows the right message' do
@@ -79,7 +75,7 @@ describe AnalyticsBuildEntity do
let(:finished_at) { nil }
it 'does not blow up' do
- expect{ subject[:date] }.not_to raise_error
+ expect { subject[:date] }.not_to raise_error
end
it 'shows the right message' do
diff --git a/spec/serializers/analytics_issue_entity_spec.rb b/spec/serializers/analytics_issue_entity_spec.rb
index 75d606d5eb3..89588b4df2b 100644
--- a/spec/serializers/analytics_issue_entity_spec.rb
+++ b/spec/serializers/analytics_issue_entity_spec.rb
@@ -13,7 +13,7 @@ describe AnalyticsIssueEntity do
}
end
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:request) { EntityRequest.new(project: project, entity: :merge_request) }
let(:entity) do
diff --git a/spec/serializers/analytics_issue_serializer_spec.rb b/spec/serializers/analytics_issue_serializer_spec.rb
index 7c14c198a74..5befc28f4fa 100644
--- a/spec/serializers/analytics_issue_serializer_spec.rb
+++ b/spec/serializers/analytics_issue_serializer_spec.rb
@@ -8,7 +8,7 @@ describe AnalyticsIssueSerializer do
end
let(:user) { create(:user) }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:resource) do
{
total_time: "172802.724419",
diff --git a/spec/serializers/analytics_merge_request_serializer_spec.rb b/spec/serializers/analytics_merge_request_serializer_spec.rb
index 56cb08acfc6..62067cc0ef2 100644
--- a/spec/serializers/analytics_merge_request_serializer_spec.rb
+++ b/spec/serializers/analytics_merge_request_serializer_spec.rb
@@ -8,7 +8,7 @@ describe AnalyticsMergeRequestSerializer do
end
let(:user) { create(:user) }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:resource) do
{
total_time: "172802.724419",
diff --git a/spec/serializers/analytics_summary_serializer_spec.rb b/spec/serializers/analytics_summary_serializer_spec.rb
index 5d7a94c2d02..236c244b402 100644
--- a/spec/serializers/analytics_summary_serializer_spec.rb
+++ b/spec/serializers/analytics_summary_serializer_spec.rb
@@ -5,7 +5,7 @@ describe AnalyticsSummarySerializer do
described_class.new.represent(resource)
end
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:user) { create(:user) }
let(:resource) do
diff --git a/spec/serializers/build_details_entity_spec.rb b/spec/serializers/build_details_entity_spec.rb
index 1332572fffc..5b7822d5d8e 100644
--- a/spec/serializers/build_details_entity_spec.rb
+++ b/spec/serializers/build_details_entity_spec.rb
@@ -57,7 +57,7 @@ describe BuildDetailsEntity do
context 'when merge request is from a fork' do
let(:fork_project) do
- create(:empty_project, forked_from_project: project)
+ create(:project, forked_from_project: project)
end
let(:pipeline) { create(:ci_pipeline, project: fork_project) }
diff --git a/spec/serializers/deploy_key_entity_spec.rb b/spec/serializers/deploy_key_entity_spec.rb
index 8149de869f1..d3aefa2c9eb 100644
--- a/spec/serializers/deploy_key_entity_spec.rb
+++ b/spec/serializers/deploy_key_entity_spec.rb
@@ -4,9 +4,9 @@ describe DeployKeyEntity do
include RequestAwareEntity
let(:user) { create(:user) }
- let(:project) { create(:empty_project, :internal)}
- let(:project_private) { create(:empty_project, :private)}
- let!(:project_pending_delete) { create(:empty_project, :internal, pending_delete: true) }
+ let(:project) { create(:project, :internal)}
+ let(:project_private) { create(:project, :private)}
+ let!(:project_pending_delete) { create(:project, :internal, pending_delete: true) }
let(:deploy_key) { create(:deploy_key) }
let!(:deploy_key_internal) { create(:deploy_keys_project, project: project, deploy_key: deploy_key) }
let!(:deploy_key_private) { create(:deploy_keys_project, project: project_private, deploy_key: deploy_key) }
diff --git a/spec/serializers/environment_serializer_spec.rb b/spec/serializers/environment_serializer_spec.rb
index 4c52a00b442..ca9b520fb38 100644
--- a/spec/serializers/environment_serializer_spec.rb
+++ b/spec/serializers/environment_serializer_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe EnvironmentSerializer do
let(:user) { create(:user) }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:json) do
described_class
@@ -39,7 +39,7 @@ describe EnvironmentSerializer do
end
context 'when there is a collection of objects provided' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:resource) { create_list(:environment, 2) }
it 'contains important elements of environment' do
diff --git a/spec/serializers/merge_request_entity_spec.rb b/spec/serializers/merge_request_entity_spec.rb
index b3d58b2636f..a2fd5b7daae 100644
--- a/spec/serializers/merge_request_entity_spec.rb
+++ b/spec/serializers/merge_request_entity_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe MergeRequestEntity do
- let(:project) { create :empty_project }
+ let(:project) { create :project }
let(:resource) { create(:merge_request, source_project: project, target_project: project) }
let(:user) { create(:user) }
@@ -47,7 +47,7 @@ describe MergeRequestEntity do
:cancel_merge_when_pipeline_succeeds_path,
:create_issue_to_resolve_discussions_path,
:source_branch_path, :target_branch_commits_path,
- :target_branch_tree_path, :commits_count)
+ :target_branch_tree_path, :commits_count, :merge_ongoing)
end
it 'has email_patches_path' do
diff --git a/spec/serializers/pipeline_details_entity_spec.rb b/spec/serializers/pipeline_details_entity_spec.rb
index b990370a271..f60d1843581 100644
--- a/spec/serializers/pipeline_details_entity_spec.rb
+++ b/spec/serializers/pipeline_details_entity_spec.rb
@@ -42,7 +42,7 @@ describe PipelineDetailsEntity do
end
context 'when pipeline is retryable' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:pipeline) do
create(:ci_pipeline, status: :success, project: project)
@@ -70,7 +70,7 @@ describe PipelineDetailsEntity do
end
context 'when pipeline is cancelable' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:pipeline) do
create(:ci_pipeline, status: :running, project: project)
diff --git a/spec/serializers/pipeline_entity_spec.rb b/spec/serializers/pipeline_entity_spec.rb
index 5b01cc4fc9e..881f2b6bfd8 100644
--- a/spec/serializers/pipeline_entity_spec.rb
+++ b/spec/serializers/pipeline_entity_spec.rb
@@ -42,7 +42,7 @@ describe PipelineEntity do
end
context 'when pipeline is retryable' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:pipeline) do
create(:ci_pipeline, status: :success, project: project)
@@ -70,7 +70,7 @@ describe PipelineEntity do
end
context 'when pipeline is cancelable' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:pipeline) do
create(:ci_pipeline, status: :running, project: project)
diff --git a/spec/serializers/pipeline_serializer_spec.rb b/spec/serializers/pipeline_serializer_spec.rb
index 262bc4acb69..2de8daba6b5 100644
--- a/spec/serializers/pipeline_serializer_spec.rb
+++ b/spec/serializers/pipeline_serializer_spec.rb
@@ -100,7 +100,7 @@ describe PipelineSerializer do
context 'number of queries' do
let(:resource) { Ci::Pipeline.all }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
before do
Ci::Pipeline::AVAILABLE_STATUSES.each do |status|
@@ -111,7 +111,7 @@ describe PipelineSerializer do
shared_examples 'no N+1 queries' do
it 'verifies number of queries', :request_store do
recorded = ActiveRecord::QueryRecorder.new { subject }
- expect(recorded.count).to be_within(1).of(59)
+ expect(recorded.count).to be_within(1).of(57)
expect(recorded.cached_count).to eq(0)
end
end
diff --git a/spec/serializers/runner_entity_spec.rb b/spec/serializers/runner_entity_spec.rb
index 4f25a8dcfa0..439ba2cbca2 100644
--- a/spec/serializers/runner_entity_spec.rb
+++ b/spec/serializers/runner_entity_spec.rb
@@ -4,7 +4,7 @@ describe RunnerEntity do
let(:runner) { create(:ci_runner, :specific) }
let(:entity) { described_class.new(runner, request: request, current_user: user) }
let(:request) { double('request') }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:user) { create(:admin) }
before do
diff --git a/spec/services/auth/container_registry_authentication_service_spec.rb b/spec/services/auth/container_registry_authentication_service_spec.rb
index 66a8a93b168..1c2d0b3e0dc 100644
--- a/spec/services/auth/container_registry_authentication_service_spec.rb
+++ b/spec/services/auth/container_registry_authentication_service_spec.rb
@@ -8,7 +8,7 @@ describe Auth::ContainerRegistryAuthenticationService do
let(:payload) { JWT.decode(subject[:token], rsa_key).first }
let(:authentication_abilities) do
- [:read_container_image, :create_container_image]
+ [:read_container_image, :create_container_image, :admin_container_image]
end
subject do
@@ -46,7 +46,7 @@ describe Auth::ContainerRegistryAuthenticationService do
shared_examples 'an accessible' do
let(:access) do
[{ 'type' => 'repository',
- 'name' => project.path_with_namespace,
+ 'name' => project.full_path,
'actions' => actions }]
end
@@ -59,6 +59,12 @@ describe Auth::ContainerRegistryAuthenticationService do
it { expect(payload).to include('access' => []) }
end
+ shared_examples 'a deletable' do
+ it_behaves_like 'an accessible' do
+ let(:actions) { ['*'] }
+ end
+ end
+
shared_examples 'a pullable' do
it_behaves_like 'an accessible' do
let(:actions) { ['pull'] }
@@ -96,8 +102,8 @@ describe Auth::ContainerRegistryAuthenticationService do
end
describe '#full_access_token' do
- let(:project) { create(:empty_project) }
- let(:token) { described_class.full_access_token(project.path_with_namespace) }
+ let(:project) { create(:project) }
+ let(:token) { described_class.full_access_token(project.full_path) }
subject { { token: token } }
@@ -112,7 +118,7 @@ describe Auth::ContainerRegistryAuthenticationService do
let(:current_user) { create(:user) }
context 'for private project' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
context 'allow to use scope-less authentication' do
it_behaves_like 'a valid token'
@@ -120,25 +126,38 @@ describe Auth::ContainerRegistryAuthenticationService do
context 'allow developer to push images' do
before do
- project.team << [current_user, :developer]
+ project.add_developer(current_user)
end
let(:current_params) do
- { scope: "repository:#{project.path_with_namespace}:push" }
+ { scope: "repository:#{project.full_path}:push" }
end
it_behaves_like 'a pushable'
it_behaves_like 'container repository factory'
end
+ context 'disallow developer to delete images' do
+ before do
+ project.add_developer(current_user)
+ end
+
+ let(:current_params) do
+ { scope: "repository:#{project.path_with_namespace}:*" }
+ end
+
+ it_behaves_like 'an inaccessible'
+ it_behaves_like 'not a container repository factory'
+ end
+
context 'allow reporter to pull images' do
before do
- project.team << [current_user, :reporter]
+ project.add_reporter(current_user)
end
context 'when pulling from root level repository' do
let(:current_params) do
- { scope: "repository:#{project.path_with_namespace}:pull" }
+ { scope: "repository:#{project.full_path}:pull" }
end
it_behaves_like 'a pullable'
@@ -146,13 +165,26 @@ describe Auth::ContainerRegistryAuthenticationService do
end
end
+ context 'disallow reporter to delete images' do
+ before do
+ project.add_reporter(current_user)
+ end
+
+ let(:current_params) do
+ { scope: "repository:#{project.path_with_namespace}:*" }
+ end
+
+ it_behaves_like 'an inaccessible'
+ it_behaves_like 'not a container repository factory'
+ end
+
context 'return a least of privileges' do
before do
- project.team << [current_user, :reporter]
+ project.add_reporter(current_user)
end
let(:current_params) do
- { scope: "repository:#{project.path_with_namespace}:push,pull" }
+ { scope: "repository:#{project.full_path}:push,pull" }
end
it_behaves_like 'a pullable'
@@ -161,11 +193,24 @@ describe Auth::ContainerRegistryAuthenticationService do
context 'disallow guest to pull or push images' do
before do
- project.team << [current_user, :guest]
+ project.add_guest(current_user)
+ end
+
+ let(:current_params) do
+ { scope: "repository:#{project.full_path}:pull,push" }
+ end
+
+ it_behaves_like 'an inaccessible'
+ it_behaves_like 'not a container repository factory'
+ end
+
+ context 'disallow guest to delete images' do
+ before do
+ project.add_guest(current_user)
end
let(:current_params) do
- { scope: "repository:#{project.path_with_namespace}:pull,push" }
+ { scope: "repository:#{project.path_with_namespace}:*" }
end
it_behaves_like 'an inaccessible'
@@ -174,11 +219,11 @@ describe Auth::ContainerRegistryAuthenticationService do
end
context 'for public project' do
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
context 'allow anyone to pull images' do
let(:current_params) do
- { scope: "repository:#{project.path_with_namespace}:pull" }
+ { scope: "repository:#{project.full_path}:pull" }
end
it_behaves_like 'a pullable'
@@ -187,7 +232,16 @@ describe Auth::ContainerRegistryAuthenticationService do
context 'disallow anyone to push images' do
let(:current_params) do
- { scope: "repository:#{project.path_with_namespace}:push" }
+ { scope: "repository:#{project.full_path}:push" }
+ end
+
+ it_behaves_like 'an inaccessible'
+ it_behaves_like 'not a container repository factory'
+ end
+
+ context 'disallow anyone to delete images' do
+ let(:current_params) do
+ { scope: "repository:#{project.path_with_namespace}:*" }
end
it_behaves_like 'an inaccessible'
@@ -205,12 +259,12 @@ describe Auth::ContainerRegistryAuthenticationService do
end
context 'for internal project' do
- let(:project) { create(:empty_project, :internal) }
+ let(:project) { create(:project, :internal) }
context 'for internal user' do
context 'allow anyone to pull images' do
let(:current_params) do
- { scope: "repository:#{project.path_with_namespace}:pull" }
+ { scope: "repository:#{project.full_path}:pull" }
end
it_behaves_like 'a pullable'
@@ -219,7 +273,16 @@ describe Auth::ContainerRegistryAuthenticationService do
context 'disallow anyone to push images' do
let(:current_params) do
- { scope: "repository:#{project.path_with_namespace}:push" }
+ { scope: "repository:#{project.full_path}:push" }
+ end
+
+ it_behaves_like 'an inaccessible'
+ it_behaves_like 'not a container repository factory'
+ end
+
+ context 'disallow anyone to delete images' do
+ let(:current_params) do
+ { scope: "repository:#{project.path_with_namespace}:*" }
end
it_behaves_like 'an inaccessible'
@@ -228,19 +291,56 @@ describe Auth::ContainerRegistryAuthenticationService do
end
context 'for external user' do
- let(:current_user) { create(:user, external: true) }
- let(:current_params) do
- { scope: "repository:#{project.path_with_namespace}:pull,push" }
+ context 'disallow anyone to pull or push images' do
+ let(:current_user) { create(:user, external: true) }
+ let(:current_params) do
+ { scope: "repository:#{project.path_with_namespace}:pull,push" }
+ end
+
+ it_behaves_like 'an inaccessible'
+ it_behaves_like 'not a container repository factory'
end
- it_behaves_like 'an inaccessible'
- it_behaves_like 'not a container repository factory'
+ context 'disallow anyone to delete images' do
+ let(:current_user) { create(:user, external: true) }
+ let(:current_params) do
+ { scope: "repository:#{project.path_with_namespace}:*" }
+ end
+
+ it_behaves_like 'an inaccessible'
+ it_behaves_like 'not a container repository factory'
+ end
+ end
+ end
+ end
+
+ context 'delete authorized as master' do
+ let(:current_project) { create(:project) }
+ let(:current_user) { create(:user) }
+
+ let(:authentication_abilities) do
+ [:admin_container_image]
+ end
+
+ before do
+ current_project.add_master(current_user)
+ end
+
+ it_behaves_like 'a valid token'
+
+ context 'allow to delete images' do
+ let(:current_params) do
+ { scope: "repository:#{current_project.path_with_namespace}:*" }
+ end
+
+ it_behaves_like 'a deletable' do
+ let(:project) { current_project }
end
end
end
context 'build authorized as user' do
- let(:current_project) { create(:empty_project) }
+ let(:current_project) { create(:project) }
let(:current_user) { create(:user) }
let(:authentication_abilities) do
@@ -248,14 +348,14 @@ describe Auth::ContainerRegistryAuthenticationService do
end
before do
- current_project.team << [current_user, :developer]
+ current_project.add_developer(current_user)
end
it_behaves_like 'a valid token'
context 'allow to pull and push images' do
let(:current_params) do
- { scope: "repository:#{current_project.path_with_namespace}:pull,push" }
+ { scope: "repository:#{current_project.full_path}:pull,push" }
end
it_behaves_like 'a pullable and pushable' do
@@ -267,14 +367,24 @@ describe Auth::ContainerRegistryAuthenticationService do
end
end
+ context 'disallow to delete images' do
+ let(:current_params) do
+ { scope: "repository:#{current_project.path_with_namespace}:*" }
+ end
+
+ it_behaves_like 'an inaccessible' do
+ let(:project) { current_project }
+ end
+ end
+
context 'for other projects' do
context 'when pulling' do
let(:current_params) do
- { scope: "repository:#{project.path_with_namespace}:pull" }
+ { scope: "repository:#{project.full_path}:pull" }
end
context 'allow for public' do
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
it_behaves_like 'a pullable'
it_behaves_like 'not a container repository factory'
@@ -288,7 +398,7 @@ describe Auth::ContainerRegistryAuthenticationService do
context 'when you are member' do
before do
- project.team << [current_user, :developer]
+ project.add_developer(current_user)
end
it_behaves_like 'a pullable'
@@ -296,7 +406,7 @@ describe Auth::ContainerRegistryAuthenticationService do
end
context 'when you are owner' do
- let(:project) { create(:empty_project, namespace: current_user.namespace) }
+ let(:project) { create(:project, namespace: current_user.namespace) }
it_behaves_like 'a pullable'
it_behaves_like 'not a container repository factory'
@@ -304,7 +414,7 @@ describe Auth::ContainerRegistryAuthenticationService do
end
context 'for private' do
- let(:project) { create(:empty_project, :private) }
+ let(:project) { create(:project, :private) }
it_behaves_like 'pullable for being team member'
@@ -318,7 +428,7 @@ describe Auth::ContainerRegistryAuthenticationService do
context 'when you are member' do
before do
- project.team << [current_user, :developer]
+ project.add_developer(current_user)
end
it_behaves_like 'a pullable'
@@ -326,7 +436,7 @@ describe Auth::ContainerRegistryAuthenticationService do
end
context 'when you are owner' do
- let(:project) { create(:empty_project, namespace: current_user.namespace) }
+ let(:project) { create(:project, namespace: current_user.namespace) }
it_behaves_like 'a pullable'
it_behaves_like 'not a container repository factory'
@@ -337,15 +447,15 @@ describe Auth::ContainerRegistryAuthenticationService do
context 'when pushing' do
let(:current_params) do
- { scope: "repository:#{project.path_with_namespace}:push" }
+ { scope: "repository:#{project.full_path}:push" }
end
context 'disallow for all' do
context 'when you are member' do
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
before do
- project.team << [current_user, :developer]
+ project.add_developer(current_user)
end
it_behaves_like 'an inaccessible'
@@ -353,7 +463,7 @@ describe Auth::ContainerRegistryAuthenticationService do
end
context 'when you are owner' do
- let(:project) { create(:empty_project, :public, namespace: current_user.namespace) }
+ let(:project) { create(:project, :public, namespace: current_user.namespace) }
it_behaves_like 'an inaccessible'
it_behaves_like 'not a container repository factory'
@@ -363,7 +473,7 @@ describe Auth::ContainerRegistryAuthenticationService do
end
context 'for project without container registry' do
- let(:project) { create(:empty_project, :public, container_registry_enabled: false) }
+ let(:project) { create(:project, :public, container_registry_enabled: false) }
before do
project.update(container_registry_enabled: false)
@@ -371,7 +481,7 @@ describe Auth::ContainerRegistryAuthenticationService do
context 'disallow when pulling' do
let(:current_params) do
- { scope: "repository:#{project.path_with_namespace}:pull" }
+ { scope: "repository:#{project.full_path}:pull" }
end
it_behaves_like 'an inaccessible'
@@ -396,21 +506,21 @@ describe Auth::ContainerRegistryAuthenticationService do
end
context 'for private project' do
- let(:project) { create(:empty_project, :private) }
+ let(:project) { create(:project, :private) }
let(:current_params) do
- { scope: "repository:#{project.path_with_namespace}:pull" }
+ { scope: "repository:#{project.full_path}:pull" }
end
it_behaves_like 'a forbidden'
end
context 'for public project' do
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
context 'when pulling and pushing' do
let(:current_params) do
- { scope: "repository:#{project.path_with_namespace}:pull,push" }
+ { scope: "repository:#{project.full_path}:pull,push" }
end
it_behaves_like 'a pullable'
@@ -419,7 +529,7 @@ describe Auth::ContainerRegistryAuthenticationService do
context 'when pushing' do
let(:current_params) do
- { scope: "repository:#{project.path_with_namespace}:push" }
+ { scope: "repository:#{project.full_path}:push" }
end
it_behaves_like 'a forbidden'
diff --git a/spec/services/boards/create_service_spec.rb b/spec/services/boards/create_service_spec.rb
index 6e3227303fe..db51a524e79 100644
--- a/spec/services/boards/create_service_spec.rb
+++ b/spec/services/boards/create_service_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe Boards::CreateService do
describe '#execute' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
subject(:service) { described_class.new(project, double) }
diff --git a/spec/services/boards/issues/create_service_spec.rb b/spec/services/boards/issues/create_service_spec.rb
index 23ad66e454b..f2ddaa903da 100644
--- a/spec/services/boards/issues/create_service_spec.rb
+++ b/spec/services/boards/issues/create_service_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe Boards::Issues::CreateService do
describe '#execute' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:board) { create(:board, project: project) }
let(:user) { create(:user) }
let(:label) { create(:label, project: project, name: 'in-progress') }
diff --git a/spec/services/boards/issues/list_service_spec.rb b/spec/services/boards/issues/list_service_spec.rb
index b1b5d807a78..01ee3856c99 100644
--- a/spec/services/boards/issues/list_service_spec.rb
+++ b/spec/services/boards/issues/list_service_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe Boards::Issues::ListService do
describe '#execute' do
let(:user) { create(:user) }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:board) { create(:board, project: project) }
let(:bug) { create(:label, project: project, name: 'Bug') }
diff --git a/spec/services/boards/issues/move_service_spec.rb b/spec/services/boards/issues/move_service_spec.rb
index 15a32350ae2..63dfe80d672 100644
--- a/spec/services/boards/issues/move_service_spec.rb
+++ b/spec/services/boards/issues/move_service_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe Boards::Issues::MoveService do
describe '#execute' do
let(:user) { create(:user) }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:board1) { create(:board, project: project) }
let(:bug) { create(:label, project: project, name: 'Bug') }
diff --git a/spec/services/boards/list_service_spec.rb b/spec/services/boards/list_service_spec.rb
index a95b12eeaa3..1d0be99fb35 100644
--- a/spec/services/boards/list_service_spec.rb
+++ b/spec/services/boards/list_service_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe Boards::ListService do
describe '#execute' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
subject(:service) { described_class.new(project, double) }
diff --git a/spec/services/boards/lists/create_service_spec.rb b/spec/services/boards/lists/create_service_spec.rb
index 86d3227a78d..7d0b396cd06 100644
--- a/spec/services/boards/lists/create_service_spec.rb
+++ b/spec/services/boards/lists/create_service_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe Boards::Lists::CreateService do
describe '#execute' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:board) { create(:board, project: project) }
let(:user) { create(:user) }
let(:label) { create(:label, project: project, name: 'in-progress') }
diff --git a/spec/services/boards/lists/destroy_service_spec.rb b/spec/services/boards/lists/destroy_service_spec.rb
index ad6ae83286d..bd98625b44f 100644
--- a/spec/services/boards/lists/destroy_service_spec.rb
+++ b/spec/services/boards/lists/destroy_service_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe Boards::Lists::DestroyService do
describe '#execute' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:board) { create(:board, project: project) }
let(:user) { create(:user) }
diff --git a/spec/services/boards/lists/generate_service_spec.rb b/spec/services/boards/lists/generate_service_spec.rb
index 7dec9f7a4a5..592f25059ac 100644
--- a/spec/services/boards/lists/generate_service_spec.rb
+++ b/spec/services/boards/lists/generate_service_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe Boards::Lists::GenerateService do
describe '#execute' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:board) { create(:board, project: project) }
let(:user) { create(:user) }
diff --git a/spec/services/boards/lists/list_service_spec.rb b/spec/services/boards/lists/list_service_spec.rb
index c93788d4516..b189857e4f4 100644
--- a/spec/services/boards/lists/list_service_spec.rb
+++ b/spec/services/boards/lists/list_service_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Boards::Lists::ListService do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:board) { create(:board, project: project) }
let(:label) { create(:label, project: project) }
let!(:list) { create(:list, board: board, label: label) }
diff --git a/spec/services/boards/lists/move_service_spec.rb b/spec/services/boards/lists/move_service_spec.rb
index 43e125a21df..a9d218bad49 100644
--- a/spec/services/boards/lists/move_service_spec.rb
+++ b/spec/services/boards/lists/move_service_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe Boards::Lists::MoveService do
describe '#execute' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:board) { create(:board, project: project) }
let(:user) { create(:user) }
diff --git a/spec/services/ci/create_pipeline_service_spec.rb b/spec/services/ci/create_pipeline_service_spec.rb
index 4ec495f612e..53d4fcfed18 100644
--- a/spec/services/ci/create_pipeline_service_spec.rb
+++ b/spec/services/ci/create_pipeline_service_spec.rb
@@ -66,7 +66,7 @@ describe Ci::CreatePipelineService do
context 'when there is no pipeline for source branch' do
it "does not update merge request head pipeline" do
- merge_request = create(:merge_request, source_branch: 'other_branch', target_branch: "branch_1", source_project: project)
+ merge_request = create(:merge_request, source_branch: 'feature', target_branch: "branch_1", source_project: project)
head_pipeline = pipeline
@@ -75,7 +75,7 @@ describe Ci::CreatePipelineService do
end
context 'when merge request target project is different from source project' do
- let!(:target_project) { create(:project) }
+ let!(:target_project) { create(:project, :repository) }
let!(:forked_project_link) { create(:forked_project_link, forked_to_project: project, forked_from_project: target_project) }
it 'updates head pipeline for merge request' do
diff --git a/spec/services/ci/pipeline_trigger_service_spec.rb b/spec/services/ci/pipeline_trigger_service_spec.rb
index 945a2fe1a6b..9a6875e448c 100644
--- a/spec/services/ci/pipeline_trigger_service_spec.rb
+++ b/spec/services/ci/pipeline_trigger_service_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe Ci::PipelineTriggerService, services: true do
+describe Ci::PipelineTriggerService do
let(:project) { create(:project, :repository) }
before do
@@ -18,7 +18,7 @@ describe Ci::PipelineTriggerService, services: true do
context 'when trigger belongs to a different project' do
let(:params) { { token: trigger.token, ref: 'master', variables: nil } }
- let(:trigger) { create(:ci_trigger, project: create(:empty_project), owner: user) }
+ let(:trigger) { create(:ci_trigger, project: create(:project), owner: user) }
it 'does nothing' do
expect { result }.not_to change { Ci::Pipeline.count }
diff --git a/spec/services/ci/play_build_service_spec.rb b/spec/services/ci/play_build_service_spec.rb
index 1ced26ff98d..330ec81e87d 100644
--- a/spec/services/ci/play_build_service_spec.rb
+++ b/spec/services/ci/play_build_service_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe Ci::PlayBuildService, '#execute' do
let(:user) { create(:user) }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:pipeline) { create(:ci_pipeline, project: project) }
let(:build) { create(:ci_build, :manual, pipeline: pipeline) }
@@ -11,7 +11,7 @@ describe Ci::PlayBuildService, '#execute' do
end
context 'when project does not have repository yet' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
it 'allows user to play build if protected branch rules are met' do
project.add_developer(user)
@@ -33,7 +33,7 @@ describe Ci::PlayBuildService, '#execute' do
end
context 'when project has repository' do
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
it 'allows user with developer role to play a build' do
project.add_developer(user)
diff --git a/spec/services/ci/process_pipeline_service_spec.rb b/spec/services/ci/process_pipeline_service_spec.rb
index 3a702742681..214adc9960f 100644
--- a/spec/services/ci/process_pipeline_service_spec.rb
+++ b/spec/services/ci/process_pipeline_service_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe Ci::ProcessPipelineService, '#execute' do
let(:user) { create(:user) }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:pipeline) do
create(:ci_empty_pipeline, ref: 'master', project: project)
diff --git a/spec/services/ci/register_job_service_spec.rb b/spec/services/ci/register_job_service_spec.rb
index 23c0f715c3e..8eb0d2d10a4 100644
--- a/spec/services/ci/register_job_service_spec.rb
+++ b/spec/services/ci/register_job_service_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
module Ci
describe RegisterJobService do
- let!(:project) { FactoryGirl.create :empty_project, shared_runners_enabled: false }
+ let!(:project) { FactoryGirl.create :project, shared_runners_enabled: false }
let!(:pipeline) { FactoryGirl.create :ci_pipeline, project: project }
let!(:pending_build) { FactoryGirl.create :ci_build, pipeline: pipeline }
let!(:shared_runner) { FactoryGirl.create(:ci_runner, is_shared: true) }
@@ -72,9 +72,9 @@ module Ci
end
context 'for multiple builds' do
- let!(:project2) { create :empty_project, shared_runners_enabled: true }
+ let!(:project2) { create :project, shared_runners_enabled: true }
let!(:pipeline2) { create :ci_pipeline, project: project2 }
- let!(:project3) { create :empty_project, shared_runners_enabled: true }
+ let!(:project3) { create :project, shared_runners_enabled: true }
let!(:pipeline3) { create :ci_pipeline, project: project3 }
let!(:build1_project1) { pending_build }
let!(:build2_project1) { FactoryGirl.create :ci_build, pipeline: pipeline }
diff --git a/spec/services/ci/retry_build_service_spec.rb b/spec/services/ci/retry_build_service_spec.rb
index fd8a57d28f0..cec667071cc 100644
--- a/spec/services/ci/retry_build_service_spec.rb
+++ b/spec/services/ci/retry_build_service_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe Ci::RetryBuildService do
let(:user) { create(:user) }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:pipeline) { create(:ci_pipeline, project: project) }
let(:build) { create(:ci_build, pipeline: pipeline) }
diff --git a/spec/services/ci/retry_pipeline_service_spec.rb b/spec/services/ci/retry_pipeline_service_spec.rb
index 90b0c5a4dce..6ce75c65c8c 100644
--- a/spec/services/ci/retry_pipeline_service_spec.rb
+++ b/spec/services/ci/retry_pipeline_service_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe Ci::RetryPipelineService, '#execute' do
let(:user) { create(:user) }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:pipeline) { create(:ci_pipeline, project: project) }
let(:service) { described_class.new(project, user) }
diff --git a/spec/services/create_deployment_service_spec.rb b/spec/services/create_deployment_service_spec.rb
index 049b082277a..08267d6e6a0 100644
--- a/spec/services/create_deployment_service_spec.rb
+++ b/spec/services/create_deployment_service_spec.rb
@@ -20,6 +20,10 @@ describe CreateDeploymentService do
let(:service) { described_class.new(job) }
+ before do
+ allow_any_instance_of(Deployment).to receive(:create_ref)
+ end
+
describe '#execute' do
subject { service.execute }
diff --git a/spec/services/delete_merged_branches_service_spec.rb b/spec/services/delete_merged_branches_service_spec.rb
index 4b872d667cf..03c682ae0d7 100644
--- a/spec/services/delete_merged_branches_service_spec.rb
+++ b/spec/services/delete_merged_branches_service_spec.rb
@@ -32,6 +32,14 @@ describe DeleteMergedBranchesService do
expect(project.repository.branch_names).to include('improve/awesome')
end
+ it 'keeps wildcard protected branches' do
+ create(:protected_branch, project: project, name: 'improve/*')
+
+ service.execute
+
+ expect(project.repository.branch_names).to include('improve/awesome')
+ end
+
context 'user without rights' do
let(:user) { create(:user) }
diff --git a/spec/services/event_create_service_spec.rb b/spec/services/event_create_service_spec.rb
index 00104ae1fd9..02d7ddeb86b 100644
--- a/spec/services/event_create_service_spec.rb
+++ b/spec/services/event_create_service_spec.rb
@@ -114,21 +114,61 @@ describe EventCreateService do
end
describe '#push', :clean_gitlab_redis_shared_state do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:user) { create(:user) }
+ let(:push_data) do
+ {
+ commits: [
+ {
+ id: '1cf19a015df3523caf0a1f9d40c98a267d6a2fc2',
+ message: 'This is a commit'
+ }
+ ],
+ before: '0000000000000000000000000000000000000000',
+ after: '1cf19a015df3523caf0a1f9d40c98a267d6a2fc2',
+ total_commits_count: 1,
+ ref: 'refs/heads/my-branch'
+ }
+ end
+
it 'creates a new event' do
- expect { service.push(project, user, {}) }.to change { Event.count }
+ expect { service.push(project, user, push_data) }.to change { Event.count }
+ end
+
+ it 'creates the push event payload' do
+ expect(PushEventPayloadService).to receive(:new)
+ .with(an_instance_of(PushEvent), push_data)
+ .and_call_original
+
+ service.push(project, user, push_data)
end
it 'updates user last activity' do
- expect { service.push(project, user, {}) }.to change { user_activity(user) }
+ expect { service.push(project, user, push_data) }
+ .to change { user_activity(user) }
+ end
+
+ it 'does not create any event data when an error is raised' do
+ payload_service = double(:service)
+
+ allow(payload_service).to receive(:execute)
+ .and_raise(RuntimeError)
+
+ allow(PushEventPayloadService).to receive(:new)
+ .and_return(payload_service)
+
+ expect { service.push(project, user, push_data) }
+ .to raise_error(RuntimeError)
+
+ expect(Event.count).to eq(0)
+ expect(PushEventPayload.count).to eq(0)
end
end
describe 'Project' do
let(:user) { create :user }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
describe '#join_project' do
subject { service.join_project(project, user) }
diff --git a/spec/services/git_push_service_spec.rb b/spec/services/git_push_service_spec.rb
index 3fb677b65be..8485605b398 100644
--- a/spec/services/git_push_service_spec.rb
+++ b/spec/services/git_push_service_spec.rb
@@ -132,7 +132,7 @@ describe GitPushService, services: true do
end
it "creates a new pipeline" do
- expect{ subject }.to change{ Ci::Pipeline.count }
+ expect { subject }.to change { Ci::Pipeline.count }
expect(Ci::Pipeline.last).to be_push
end
end
@@ -141,10 +141,13 @@ describe GitPushService, services: true do
let!(:push_data) { push_data_from_service(project, user, oldrev, newrev, ref) }
let(:event) { Event.find_by_action(Event::PUSHED) }
- it { expect(event).not_to be_nil }
+ it { expect(event).to be_an_instance_of(PushEvent) }
it { expect(event.project).to eq(project) }
it { expect(event.action).to eq(Event::PUSHED) }
- it { expect(event.data).to eq(push_data) }
+ it { expect(event.push_event_payload).to be_an_instance_of(PushEventPayload) }
+ it { expect(event.push_event_payload.commit_from).to eq(oldrev) }
+ it { expect(event.push_event_payload.commit_to).to eq(newrev) }
+ it { expect(event.push_event_payload.ref).to eq('master') }
context "Updates merge requests" do
it "when pushing a new branch for the first time" do
@@ -453,7 +456,7 @@ describe GitPushService, services: true do
let(:message) { "this is some work.\n\ncloses JIRA-1" }
let(:comment_body) do
{
- body: "Issue solved with [#{closing_commit.id}|http://#{Gitlab.config.gitlab.host}/#{project.path_with_namespace}/commit/#{closing_commit.id}]."
+ body: "Issue solved with [#{closing_commit.id}|http://#{Gitlab.config.gitlab.host}/#{project.full_path}/commit/#{closing_commit.id}]."
}.to_json
end
diff --git a/spec/services/git_tag_push_service_spec.rb b/spec/services/git_tag_push_service_spec.rb
index f877c145390..05695aa8188 100644
--- a/spec/services/git_tag_push_service_spec.rb
+++ b/spec/services/git_tag_push_service_spec.rb
@@ -39,7 +39,7 @@ describe GitTagPushService do
end
it "creates a new pipeline" do
- expect{ subject }.to change{ Ci::Pipeline.count }
+ expect { subject }.to change { Ci::Pipeline.count }
expect(Ci::Pipeline.last).to be_push
end
end
diff --git a/spec/services/groups/destroy_service_spec.rb b/spec/services/groups/destroy_service_spec.rb
index c18870ea100..1b2ce3cd03e 100644
--- a/spec/services/groups/destroy_service_spec.rb
+++ b/spec/services/groups/destroy_service_spec.rb
@@ -6,7 +6,7 @@ describe Groups::DestroyService do
let!(:user) { create(:user) }
let!(:group) { create(:group) }
let!(:nested_group) { create(:group, parent: group) }
- let!(:project) { create(:empty_project, namespace: group) }
+ let!(:project) { create(:project, namespace: group) }
let!(:notification_setting) { create(:notification_setting, source: group)}
let!(:gitlab_shell) { Gitlab::Shell.new }
let!(:remove_path) { group.path + "+#{group.id}+deleted" }
diff --git a/spec/services/groups/update_service_spec.rb b/spec/services/groups/update_service_spec.rb
index 9902e1aff8b..44f22a3b37b 100644
--- a/spec/services/groups/update_service_spec.rb
+++ b/spec/services/groups/update_service_spec.rb
@@ -13,7 +13,7 @@ describe Groups::UpdateService do
before do
public_group.add_user(user, Gitlab::Access::MASTER)
- create(:empty_project, :public, group: public_group)
+ create(:project, :public, group: public_group)
end
it "does not change permission level" do
@@ -27,7 +27,7 @@ describe Groups::UpdateService do
before do
internal_group.add_user(user, Gitlab::Access::MASTER)
- create(:empty_project, :internal, group: internal_group)
+ create(:project, :internal, group: internal_group)
end
it "does not change permission level" do
@@ -69,7 +69,7 @@ describe Groups::UpdateService do
before do
internal_group.add_user(user, Gitlab::Access::MASTER)
- create(:empty_project, :internal, group: internal_group)
+ create(:project, :internal, group: internal_group)
end
it 'returns true' do
diff --git a/spec/services/issuable/bulk_update_service_spec.rb b/spec/services/issuable/bulk_update_service_spec.rb
index 055aa6156cb..bdaab88d673 100644
--- a/spec/services/issuable/bulk_update_service_spec.rb
+++ b/spec/services/issuable/bulk_update_service_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe Issuable::BulkUpdateService do
let(:user) { create(:user) }
- let(:project) { create(:empty_project, namespace: user.namespace) }
+ let(:project) { create(:project, namespace: user.namespace) }
def bulk_update(issuables, extra_params = {})
bulk_update_params = extra_params
@@ -118,7 +118,7 @@ describe Issuable::BulkUpdateService do
context 'when the new assignee ID is not present' do
it 'does not unassign' do
expect { bulk_update(issue, assignee_ids: []) }
- .not_to change{ issue.reload.assignees }
+ .not_to change { issue.reload.assignees }
end
end
end
diff --git a/spec/services/issues/create_service_spec.rb b/spec/services/issues/create_service_spec.rb
index a48748e274d..9b2d9e79f4f 100644
--- a/spec/services/issues/create_service_spec.rb
+++ b/spec/services/issues/create_service_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Issues::CreateService do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:user) { create(:user) }
describe '#execute' do
@@ -351,14 +351,14 @@ describe Issues::CreateService do
end
it 'marks related spam_log as recaptcha_verified' do
- expect { issue }.to change{SpamLog.last.recaptcha_verified}.from(false).to(true)
+ expect { issue }.to change {SpamLog.last.recaptcha_verified}.from(false).to(true)
end
context 'when spam log does not belong to a user' do
let(:log_user) { create(:user) }
it 'does not mark spam_log as recaptcha_verified' do
- expect { issue }.not_to change{SpamLog.last.recaptcha_verified}
+ expect { issue }.not_to change {SpamLog.last.recaptcha_verified}
end
end
end
@@ -378,7 +378,7 @@ describe Issues::CreateService do
end
it 'creates a new spam_log' do
- expect{issue}.to change{SpamLog.count}.from(0).to(1)
+ expect {issue}.to change {SpamLog.count}.from(0).to(1)
end
it 'assigns a spam_log to an issue' do
diff --git a/spec/services/issues/duplicate_service_spec.rb b/spec/services/issues/duplicate_service_spec.rb
index ed55664e382..089e77cc88b 100644
--- a/spec/services/issues/duplicate_service_spec.rb
+++ b/spec/services/issues/duplicate_service_spec.rb
@@ -2,8 +2,8 @@ require 'spec_helper'
describe Issues::DuplicateService do
let(:user) { create(:user) }
- let(:canonical_project) { create(:empty_project) }
- let(:duplicate_project) { create(:empty_project) }
+ let(:canonical_project) { create(:project) }
+ let(:duplicate_project) { create(:project) }
let(:canonical_issue) { create(:issue, project: canonical_project) }
let(:duplicate_issue) { create(:issue, project: duplicate_project) }
diff --git a/spec/services/issues/move_service_spec.rb b/spec/services/issues/move_service_spec.rb
index 171fc7334c4..f2b35a8fadf 100644
--- a/spec/services/issues/move_service_spec.rb
+++ b/spec/services/issues/move_service_spec.rb
@@ -5,8 +5,8 @@ describe Issues::MoveService do
let(:author) { create(:user) }
let(:title) { 'Some issue' }
let(:description) { 'Some issue description' }
- let(:old_project) { create(:empty_project) }
- let(:new_project) { create(:empty_project) }
+ let(:old_project) { create(:project) }
+ let(:new_project) { create(:project) }
let(:milestone1) { create(:milestone, project_id: old_project.id, title: 'v9.0') }
let(:old_issue) do
diff --git a/spec/services/issues/reopen_service_spec.rb b/spec/services/issues/reopen_service_spec.rb
index 1ff988e9b47..205e9ebd237 100644
--- a/spec/services/issues/reopen_service_spec.rb
+++ b/spec/services/issues/reopen_service_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Issues::ReopenService do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:issue) { create(:issue, :closed, project: project) }
describe '#execute' do
diff --git a/spec/services/issues/resolve_discussions_spec.rb b/spec/services/issues/resolve_discussions_spec.rb
index fac66791ffb..67a86c50fc1 100644
--- a/spec/services/issues/resolve_discussions_spec.rb
+++ b/spec/services/issues/resolve_discussions_spec.rb
@@ -20,7 +20,7 @@ describe Issues::ResolveDiscussions do
describe "for resolving discussions" do
let(:discussion) { create(:diff_note_on_merge_request, project: project, note: "Almost done").to_discussion }
let(:merge_request) { discussion.noteable }
- let(:other_merge_request) { create(:merge_request, source_project: project, source_branch: "other") }
+ let(:other_merge_request) { create(:merge_request, source_project: project, source_branch: "fix") }
describe "#merge_request_for_resolving_discussion" do
let(:service) { DummyService.new(project, user, merge_request_to_resolve_discussions_of: merge_request.iid) }
diff --git a/spec/services/issues/update_service_spec.rb b/spec/services/issues/update_service_spec.rb
index eec2096fa34..34fb16edc84 100644
--- a/spec/services/issues/update_service_spec.rb
+++ b/spec/services/issues/update_service_spec.rb
@@ -1,13 +1,11 @@
# coding: utf-8
require 'spec_helper'
-describe Issues::UpdateService do
- include EmailHelpers
-
+describe Issues::UpdateService, :mailer do
let(:user) { create(:user) }
let(:user2) { create(:user) }
let(:user3) { create(:user) }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:label) { create(:label, project: project) }
let(:label2) { create(:label) }
@@ -480,7 +478,7 @@ describe Issues::UpdateService do
feature_visibility_attr = :"#{issue.model_name.plural}_access_level"
project.project_feature.update_attribute(feature_visibility_attr, ProjectFeature::PRIVATE)
- expect{ update_issue(assignee_ids: [assignee.id]) }.not_to change{ issue.assignees }
+ expect { update_issue(assignee_ids: [assignee.id]) }.not_to change { issue.assignees }
end
end
end
diff --git a/spec/services/labels/create_service_spec.rb b/spec/services/labels/create_service_spec.rb
index ecb88653001..438e6dbc628 100644
--- a/spec/services/labels/create_service_spec.rb
+++ b/spec/services/labels/create_service_spec.rb
@@ -4,7 +4,7 @@ describe Labels::CreateService do
describe '#execute' do
let(:project) { create(:project) }
let(:group) { create(:group) }
-
+
let(:hex_color) { '#FF0000' }
let(:named_color) { 'red' }
let(:upcase_color) { 'RED' }
diff --git a/spec/services/labels/find_or_create_service_spec.rb b/spec/services/labels/find_or_create_service_spec.rb
index 2d3a15a1c11..a781fbc7f7d 100644
--- a/spec/services/labels/find_or_create_service_spec.rb
+++ b/spec/services/labels/find_or_create_service_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe Labels::FindOrCreateService do
describe '#execute' do
let(:group) { create(:group) }
- let(:project) { create(:empty_project, namespace: group) }
+ let(:project) { create(:project, namespace: group) }
let(:params) do
{
diff --git a/spec/services/labels/promote_service_spec.rb b/spec/services/labels/promote_service_spec.rb
index 7cea877ad88..8809b282127 100644
--- a/spec/services/labels/promote_service_spec.rb
+++ b/spec/services/labels/promote_service_spec.rb
@@ -5,7 +5,7 @@ describe Labels::PromoteService do
let!(:user) { create(:user) }
context 'project without group' do
- let!(:project_1) { create(:empty_project) }
+ let!(:project_1) { create(:project) }
let!(:project_label_1_1) { create(:label, project: project_1) }
@@ -27,10 +27,10 @@ describe Labels::PromoteService do
let!(:group_1) { create(:group) }
let!(:group_2) { create(:group) }
- let!(:project_1) { create(:empty_project, namespace: group_1) }
- let!(:project_2) { create(:empty_project, namespace: group_1) }
- let!(:project_3) { create(:empty_project, namespace: group_1) }
- let!(:project_4) { create(:empty_project, namespace: group_2) }
+ let!(:project_1) { create(:project, namespace: group_1) }
+ let!(:project_2) { create(:project, namespace: group_1) }
+ let!(:project_3) { create(:project, namespace: group_1) }
+ let!(:project_4) { create(:project, namespace: group_2) }
# Labels/issues can't be lazily created so we might as well eager initialize
# all other objects too since we use them inside
diff --git a/spec/services/labels/transfer_service_spec.rb b/spec/services/labels/transfer_service_spec.rb
index f70edd3d16e..ae819c011de 100644
--- a/spec/services/labels/transfer_service_spec.rb
+++ b/spec/services/labels/transfer_service_spec.rb
@@ -6,8 +6,8 @@ describe Labels::TransferService do
let(:group_1) { create(:group) }
let(:group_2) { create(:group) }
let(:group_3) { create(:group) }
- let(:project_1) { create(:empty_project, namespace: group_2) }
- let(:project_2) { create(:empty_project, namespace: group_3) }
+ let(:project_1) { create(:project, namespace: group_2) }
+ let(:project_2) { create(:project, namespace: group_3) }
let(:group_label_1) { create(:group_label, group: group_1, name: 'Group Label 1') }
let(:group_label_2) { create(:group_label, group: group_1, name: 'Group Label 2') }
diff --git a/spec/services/labels/update_service_spec.rb b/spec/services/labels/update_service_spec.rb
index bb95fe20fbf..c3fe33045fa 100644
--- a/spec/services/labels/update_service_spec.rb
+++ b/spec/services/labels/update_service_spec.rb
@@ -13,7 +13,7 @@ describe Labels::UpdateService do
let(:expected_saved_color) { hex_color }
- before(:each) do
+ before do
@label = Labels::CreateService.new(title: 'Initial', color: '#000000').execute(project: project)
expect(@label).to be_persisted
end
diff --git a/spec/services/members/approve_access_request_service_spec.rb b/spec/services/members/approve_access_request_service_spec.rb
index ddba96b8d03..302c488d6c6 100644
--- a/spec/services/members/approve_access_request_service_spec.rb
+++ b/spec/services/members/approve_access_request_service_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe Members::ApproveAccessRequestService do
let(:user) { create(:user) }
let(:access_requester) { create(:user) }
- let(:project) { create(:empty_project, :public, :access_requestable) }
+ let(:project) { create(:project, :public, :access_requestable) }
let(:group) { create(:group, :public, :access_requestable) }
let(:opts) { {} }
diff --git a/spec/services/members/authorized_destroy_service_spec.rb b/spec/services/members/authorized_destroy_service_spec.rb
index f0abbc46ca3..2d04d824180 100644
--- a/spec/services/members/authorized_destroy_service_spec.rb
+++ b/spec/services/members/authorized_destroy_service_spec.rb
@@ -2,9 +2,9 @@ require 'spec_helper'
describe Members::AuthorizedDestroyService do
let(:member_user) { create(:user) }
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:group) { create(:group, :public) }
- let(:group_project) { create(:empty_project, :public, group: group) }
+ let(:group_project) { create(:project, :public, group: group) }
def number_of_assigned_issuables(user)
Issue.assigned_to(user).count + MergeRequest.assigned_to(user).count
diff --git a/spec/services/members/create_service_spec.rb b/spec/services/members/create_service_spec.rb
index c73a229823d..2a793e0eb4d 100644
--- a/spec/services/members/create_service_spec.rb
+++ b/spec/services/members/create_service_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Members::CreateService do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:user) { create(:user) }
let(:project_user) { create(:user) }
diff --git a/spec/services/members/destroy_service_spec.rb b/spec/services/members/destroy_service_spec.rb
index 0e30b343eaf..72f5e27180d 100644
--- a/spec/services/members/destroy_service_spec.rb
+++ b/spec/services/members/destroy_service_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe Members::DestroyService do
let(:user) { create(:user) }
let(:member_user) { create(:user) }
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:group) { create(:group, :public) }
shared_examples 'a service raising ActiveRecord::RecordNotFound' do
diff --git a/spec/services/members/request_access_service_spec.rb b/spec/services/members/request_access_service_spec.rb
index f39d4f47904..0a704bba521 100644
--- a/spec/services/members/request_access_service_spec.rb
+++ b/spec/services/members/request_access_service_spec.rb
@@ -29,7 +29,7 @@ describe Members::RequestAccessService do
end
context 'when current user cannot request access to the project' do
- %i[empty_project group].each do |source_type|
+ %i[project group].each do |source_type|
it_behaves_like 'a service raising Gitlab::Access::AccessDeniedError' do
let(:source) { create(source_type, :private) }
end
@@ -37,7 +37,7 @@ describe Members::RequestAccessService do
end
context 'when access requests are disabled' do
- %i[empty_project group].each do |source_type|
+ %i[project group].each do |source_type|
it_behaves_like 'a service raising Gitlab::Access::AccessDeniedError' do
let(:source) { create(source_type, :public) }
end
@@ -45,7 +45,7 @@ describe Members::RequestAccessService do
end
context 'when current user can request access to the project' do
- %i[empty_project group].each do |source_type|
+ %i[project group].each do |source_type|
it_behaves_like 'a service creating a access request' do
let(:source) { create(source_type, :public, :access_requestable) }
end
diff --git a/spec/services/merge_requests/build_service_spec.rb b/spec/services/merge_requests/build_service_spec.rb
index ea192e51f89..b46c419de14 100644
--- a/spec/services/merge_requests/build_service_spec.rb
+++ b/spec/services/merge_requests/build_service_spec.rb
@@ -264,8 +264,8 @@ describe MergeRequests::BuildService do
end
context 'upstream project has disabled merge requests' do
- let(:upstream_project) { create(:empty_project, :merge_requests_disabled) }
- let(:project) { create(:empty_project, forked_from_project: upstream_project) }
+ let(:upstream_project) { create(:project, :merge_requests_disabled) }
+ let(:project) { create(:project, forked_from_project: upstream_project) }
let(:commits) { Commit.decorate([commit_1], project) }
it 'sets target project correctly' do
diff --git a/spec/services/merge_requests/get_urls_service_spec.rb b/spec/services/merge_requests/get_urls_service_spec.rb
index 672d86e4028..25599dea19f 100644
--- a/spec/services/merge_requests/get_urls_service_spec.rb
+++ b/spec/services/merge_requests/get_urls_service_spec.rb
@@ -3,7 +3,7 @@ require "spec_helper"
describe MergeRequests::GetUrlsService do
let(:project) { create(:project, :public, :repository) }
let(:service) { described_class.new(project) }
- let(:source_branch) { "my_branch" }
+ let(:source_branch) { "merge-test" }
let(:new_merge_request_url) { "http://#{Gitlab.config.gitlab.host}/#{project.namespace.name}/#{project.path}/merge_requests/new?merge_request%5Bsource_branch%5D=#{source_branch}" }
let(:show_merge_request_url) { "http://#{Gitlab.config.gitlab.host}/#{project.namespace.name}/#{project.path}/merge_requests/#{merge_request.iid}" }
let(:new_branch_changes) { "#{Gitlab::Git::BLANK_SHA} 570e7b2abdd848b95f2f578043fc23bd6f6fd24d refs/heads/#{source_branch}" }
@@ -111,9 +111,9 @@ describe MergeRequests::GetUrlsService do
end
context 'pushing new branch and existing branch (with merge request created) at once' do
- let!(:merge_request) { create(:merge_request, source_project: project, source_branch: "existing_branch") }
+ let!(:merge_request) { create(:merge_request, source_project: project, source_branch: "markdown") }
let(:new_branch_changes) { "#{Gitlab::Git::BLANK_SHA} 570e7b2abdd848b95f2f578043fc23bd6f6fd24d refs/heads/new_branch" }
- let(:existing_branch_changes) { "d14d6c0abdd253381df51a723d58691b2ee1ab08 570e7b2abdd848b95f2f578043fc23bd6f6fd24d refs/heads/existing_branch" }
+ let(:existing_branch_changes) { "d14d6c0abdd253381df51a723d58691b2ee1ab08 570e7b2abdd848b95f2f578043fc23bd6f6fd24d refs/heads/markdown" }
let(:changes) { "#{new_branch_changes}\n#{existing_branch_changes}" }
let(:new_merge_request_url) { "http://#{Gitlab.config.gitlab.host}/#{project.namespace.name}/#{project.path}/merge_requests/new?merge_request%5Bsource_branch%5D=new_branch" }
@@ -124,7 +124,7 @@ describe MergeRequests::GetUrlsService do
url: new_merge_request_url,
new_merge_request: true
}, {
- branch_name: "existing_branch",
+ branch_name: "markdown",
url: show_merge_request_url,
new_merge_request: false
}])
diff --git a/spec/services/merge_requests/update_service_spec.rb b/spec/services/merge_requests/update_service_spec.rb
index dd3ac9c4ac6..681feee61d1 100644
--- a/spec/services/merge_requests/update_service_spec.rb
+++ b/spec/services/merge_requests/update_service_spec.rb
@@ -1,8 +1,6 @@
require 'spec_helper'
-describe MergeRequests::UpdateService do
- include EmailHelpers
-
+describe MergeRequests::UpdateService, :mailer do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
let(:user2) { create(:user) }
@@ -511,7 +509,7 @@ describe MergeRequests::UpdateService do
feature_visibility_attr = :"#{merge_request.model_name.plural}_access_level"
project.project_feature.update_attribute(feature_visibility_attr, ProjectFeature::PRIVATE)
- expect{ update_merge_request(assignee_id: assignee) }.not_to change{ merge_request.assignee }
+ expect { update_merge_request(assignee_id: assignee) }.not_to change { merge_request.assignee }
end
end
end
diff --git a/spec/services/milestones/close_service_spec.rb b/spec/services/milestones/close_service_spec.rb
index fa0686d8061..2bdf224804d 100644
--- a/spec/services/milestones/close_service_spec.rb
+++ b/spec/services/milestones/close_service_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe Milestones::CloseService do
let(:user) { create(:user) }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:milestone) { create(:milestone, title: "Milestone v1.2", project: project) }
before do
diff --git a/spec/services/milestones/create_service_spec.rb b/spec/services/milestones/create_service_spec.rb
index c6fe8e65912..8837b91051d 100644
--- a/spec/services/milestones/create_service_spec.rb
+++ b/spec/services/milestones/create_service_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Milestones::CreateService do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:user) { create(:user) }
describe '#execute' do
diff --git a/spec/services/note_summary_spec.rb b/spec/services/note_summary_spec.rb
index dda579c7080..a6cc2251e48 100644
--- a/spec/services/note_summary_spec.rb
+++ b/spec/services/note_summary_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe NoteSummary do
- let(:project) { build(:empty_project) }
+ let(:project) { build(:project) }
let(:noteable) { build(:issue) }
let(:user) { build(:user) }
diff --git a/spec/services/notes/create_service_spec.rb b/spec/services/notes/create_service_spec.rb
index c08a5a940bb..661d26946e7 100644
--- a/spec/services/notes/create_service_spec.rb
+++ b/spec/services/notes/create_service_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Notes::CreateService do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:issue) { create(:issue, project: project) }
let(:user) { create(:user) }
let(:opts) do
diff --git a/spec/services/notes/destroy_service_spec.rb b/spec/services/notes/destroy_service_spec.rb
index 4330190caaa..c9a99a43edb 100644
--- a/spec/services/notes/destroy_service_spec.rb
+++ b/spec/services/notes/destroy_service_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe Notes::DestroyService do
describe '#execute' do
it 'deletes a note' do
- project = create(:empty_project)
+ project = create(:project)
issue = create(:issue, project: project)
note = create(:note, project: project, noteable: issue)
diff --git a/spec/services/notes/post_process_service_spec.rb b/spec/services/notes/post_process_service_spec.rb
index bf9320e5fce..a2b3638059f 100644
--- a/spec/services/notes/post_process_service_spec.rb
+++ b/spec/services/notes/post_process_service_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Notes::PostProcessService do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:issue) { create(:issue, project: project) }
let(:user) { create(:user) }
diff --git a/spec/services/notes/quick_actions_service_spec.rb b/spec/services/notes/quick_actions_service_spec.rb
index fc4cd3dc2b7..0280a19098b 100644
--- a/spec/services/notes/quick_actions_service_spec.rb
+++ b/spec/services/notes/quick_actions_service_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe Notes::QuickActionsService do
shared_context 'note on noteable' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:master) { create(:user).tap { |u| project.team << [u, :master] } }
let(:assignee) { create(:user) }
@@ -225,7 +225,7 @@ describe Notes::QuickActionsService do
context 'CE restriction for issue assignees' do
describe '/assign' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:master) { create(:user).tap { |u| project.team << [u, :master] } }
let(:assignee) { create(:user) }
let(:master) { create(:user) }
diff --git a/spec/services/notes/update_service_spec.rb b/spec/services/notes/update_service_spec.rb
index dea2dc02d00..3210539f3ee 100644
--- a/spec/services/notes/update_service_spec.rb
+++ b/spec/services/notes/update_service_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Notes::UpdateService do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:user) { create(:user) }
let(:user2) { create(:user) }
let(:user3) { create(:user) }
diff --git a/spec/services/notification_recipient_service_spec.rb b/spec/services/notification_recipient_service_spec.rb
deleted file mode 100644
index 77233dc1b2f..00000000000
--- a/spec/services/notification_recipient_service_spec.rb
+++ /dev/null
@@ -1,34 +0,0 @@
-require 'spec_helper'
-
-describe NotificationRecipientService do
- set(:user) { create(:user) }
- set(:project) { create(:empty_project, :public) }
- set(:issue) { create(:issue, project: project) }
-
- set(:watcher) do
- watcher = create(:user)
- setting = watcher.notification_settings_for(project)
- setting.level = :watch
- setting.save
-
- watcher
- end
-
- subject { described_class.new(project) }
-
- describe '#build_recipients' do
- it 'does not modify the participants of the target' do
- expect { subject.build_recipients(issue, user, action: :new_issue) }
- .not_to change { issue.participants(user) }
- end
- end
-
- describe '#build_new_note_recipients' do
- set(:note) { create(:note_on_issue, noteable: issue, project: project) }
-
- it 'does not modify the participants of the target' do
- expect { subject.build_new_note_recipients(note) }
- .not_to change { note.noteable.participants(note.author) }
- end
- end
-end
diff --git a/spec/services/notification_service_spec.rb b/spec/services/notification_service_spec.rb
index 49d6fc7853f..44b2d28d1d4 100644
--- a/spec/services/notification_service_spec.rb
+++ b/spec/services/notification_service_spec.rb
@@ -1,12 +1,10 @@
require 'spec_helper'
-describe NotificationService do
- include EmailHelpers
-
+describe NotificationService, :mailer do
let(:notification) { described_class.new }
let(:assignee) { create(:user) }
- around(:each) do |example|
+ around do |example|
perform_enqueued_jobs do
example.run
end
@@ -14,7 +12,6 @@ describe NotificationService do
shared_examples 'notifications for new mentions' do
def send_notifications(*new_mentions)
- reset_delivered_emails!
notification.send(notification_method, mentionable, new_mentions, @u_disabled)
end
@@ -83,12 +80,16 @@ describe NotificationService do
describe 'Keys' do
describe '#new_key' do
- let!(:key) { create(:personal_key) }
+ let(:key_options) { {} }
+ let!(:key) { create(:personal_key, key_options) }
it { expect(notification.new_key(key)).to be_truthy }
+ it { should_email(key.user) }
- it 'sends email to key owner' do
- expect{ notification.new_key(key) }.to change{ ActionMailer::Base.deliveries.size }.by(1)
+ describe 'never emails the ghost user' do
+ let(:key_options) { { user: User.ghost } }
+
+ it { should_not_email_anyone }
end
end
end
@@ -100,7 +101,7 @@ describe NotificationService do
it { expect(notification.new_gpg_key(key)).to be_truthy }
it 'sends email to key owner' do
- expect{ notification.new_gpg_key(key) }.to change{ ActionMailer::Base.deliveries.size }.by(1)
+ expect { notification.new_gpg_key(key) }.to change { ActionMailer::Base.deliveries.size }.by(1)
end
end
end
@@ -112,14 +113,14 @@ describe NotificationService do
it { expect(notification.new_email(email)).to be_truthy }
it 'sends email to email owner' do
- expect{ notification.new_email(email) }.to change{ ActionMailer::Base.deliveries.size }.by(1)
+ expect { notification.new_email(email) }.to change { ActionMailer::Base.deliveries.size }.by(1)
end
end
end
describe 'Notes' do
context 'issue note' do
- let(:project) { create(:empty_project, :private) }
+ let(:project) { create(:project, :private) }
let(:issue) { create(:issue, project: project, assignees: [assignee]) }
let(:mentioned_issue) { create(:issue, assignees: issue.assignees) }
let(:note) { create(:note_on_issue, noteable: issue, project_id: issue.project_id, note: '@mention referenced, @outsider also') }
@@ -137,12 +138,11 @@ describe NotificationService do
describe '#new_note' do
it do
add_users_with_subscription(note.project, issue)
+ reset_delivered_emails!
# Ensure create SentNotification by noteable = issue 6 times, not noteable = note
expect(SentNotification).to receive(:record).with(issue, any_args).exactly(8).times
- reset_delivered_emails!
-
notification.new_note(note)
should_email(@u_watcher)
@@ -165,9 +165,10 @@ describe NotificationService do
it "emails the note author if they've opted into notifications about their activity" do
add_users_with_subscription(note.project, issue)
- note.author.notified_of_own_activity = true
reset_delivered_emails!
+ note.author.notified_of_own_activity = true
+
notification.new_note(note)
should_email(note.author)
@@ -228,7 +229,7 @@ describe NotificationService do
end
context 'confidential issue note' do
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:author) { create(:user) }
let(:assignee) { create(:user) }
let(:non_member) { create(:user) }
@@ -260,7 +261,7 @@ describe NotificationService do
end
context 'issue note mention' do
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:issue) { create(:issue, project: project, assignees: [assignee]) }
let(:mentioned_issue) { create(:issue, assignees: issue.assignees) }
let(:note) { create(:note_on_issue, noteable: issue, project_id: issue.project_id, note: '@all mentioned') }
@@ -303,12 +304,17 @@ describe NotificationService do
end
context 'project snippet note' do
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:snippet) { create(:project_snippet, project: project, author: create(:user)) }
let(:note) { create(:note_on_project_snippet, noteable: snippet, project_id: snippet.project.id, note: '@all mentioned') }
before do
build_team(note.project)
+
+ # make sure these users can read the project snippet!
+ project.add_guest(@u_guest_watcher)
+ project.add_guest(@u_guest_custom)
+
note.project.add_master(note.author)
reset_delivered_emails!
end
@@ -464,8 +470,8 @@ describe NotificationService do
describe 'Issues' do
let(:group) { create(:group) }
- let(:project) { create(:empty_project, :public, namespace: group) }
- let(:another_project) { create(:empty_project, :public, namespace: group) }
+ let(:project) { create(:project, :public, namespace: group) }
+ let(:another_project) { create(:project, :public, namespace: group) }
let(:issue) { create :issue, project: project, assignees: [assignee], description: 'cc @participant' }
before do
@@ -694,17 +700,6 @@ describe NotificationService do
let!(:subscriber_to_label_1) { create(:user) { |u| label_1.toggle_subscription(u, project) } }
let!(:subscriber_to_label_2) { create(:user) { |u| label_2.toggle_subscription(u, project) } }
- it "emails subscribers of the issue's added labels only" do
- notification.relabeled_issue(issue, [group_label_2, label_2], @u_disabled)
-
- should_not_email(subscriber_to_label_1)
- should_not_email(subscriber_to_group_label_1)
- should_not_email(subscriber_to_group_label_2_on_another_project)
- should_email(subscriber_1_to_group_label_2)
- should_email(subscriber_2_to_group_label_2)
- should_email(subscriber_to_label_2)
- end
-
it "emails the current user if they've opted into notifications about their activity" do
subscriber_to_label_2.notified_of_own_activity = true
notification.relabeled_issue(issue, [group_label_2, label_2], subscriber_to_label_2)
@@ -721,6 +716,12 @@ describe NotificationService do
it "doesn't send email to anyone but subscribers of the given labels" do
notification.relabeled_issue(issue, [group_label_2, label_2], @u_disabled)
+ should_not_email(subscriber_to_label_1)
+ should_not_email(subscriber_to_group_label_1)
+ should_not_email(subscriber_to_group_label_2_on_another_project)
+ should_email(subscriber_1_to_group_label_2)
+ should_email(subscriber_2_to_group_label_2)
+ should_email(subscriber_to_label_2)
should_not_email(issue.assignees.first)
should_not_email(issue.author)
should_not_email(@u_watcher)
@@ -730,12 +731,6 @@ describe NotificationService do
should_not_email(@watcher_and_subscriber)
should_not_email(@unsubscriber)
should_not_email(@u_participating)
- should_not_email(subscriber_to_label_1)
- should_not_email(subscriber_to_group_label_1)
- should_not_email(subscriber_to_group_label_2_on_another_project)
- should_email(subscriber_1_to_group_label_2)
- should_email(subscriber_2_to_group_label_2)
- should_email(subscriber_to_label_2)
end
context 'confidential issues' do
@@ -866,7 +861,7 @@ describe NotificationService do
describe 'Merge Requests' do
let(:group) { create(:group) }
let(:project) { create(:project, :public, :repository, namespace: group) }
- let(:another_project) { create(:empty_project, :public, namespace: group) }
+ let(:another_project) { create(:project, :public, namespace: group) }
let(:merge_request) { create :merge_request, source_project: project, assignee: create(:user), description: 'cc @participant' }
before do
@@ -878,11 +873,6 @@ describe NotificationService do
end
describe '#new_merge_request' do
- before do
- update_custom_notification(:new_merge_request, @u_guest_custom, resource: project)
- update_custom_notification(:new_merge_request, @u_custom_global)
- end
-
it do
notification.new_merge_request(merge_request, @u_disabled)
@@ -1008,7 +998,7 @@ describe NotificationService do
let!(:subscriber_to_label_1) { create(:user) { |u| label_1.toggle_subscription(u, project) } }
let!(:subscriber_to_label_2) { create(:user) { |u| label_2.toggle_subscription(u, project) } }
- it "emails subscribers of the merge request's added labels only" do
+ it "doesn't send email to anyone but subscribers of the given labels" do
notification.relabeled_merge_request(merge_request, [group_label_2, label_2], @u_disabled)
should_not_email(subscriber_to_label_1)
@@ -1017,11 +1007,6 @@ describe NotificationService do
should_email(subscriber_1_to_group_label_2)
should_email(subscriber_2_to_group_label_2)
should_email(subscriber_to_label_2)
- end
-
- it "doesn't send email to anyone but subscribers of the given labels" do
- notification.relabeled_merge_request(merge_request, [group_label_2, label_2], @u_disabled)
-
should_not_email(merge_request.assignee)
should_not_email(merge_request.author)
should_not_email(@u_watcher)
@@ -1031,12 +1016,6 @@ describe NotificationService do
should_not_email(@unsubscriber)
should_not_email(@u_participating)
should_not_email(@u_lazy_participant)
- should_not_email(subscriber_to_label_1)
- should_not_email(subscriber_to_group_label_1)
- should_not_email(subscriber_to_group_label_2_on_another_project)
- should_email(subscriber_1_to_group_label_2)
- should_email(subscriber_2_to_group_label_2)
- should_email(subscriber_to_label_2)
end
end
@@ -1081,12 +1060,12 @@ describe NotificationService do
should_email(merge_request.assignee)
should_email(@u_watcher)
+ should_email(@u_guest_watcher)
+ should_email(@u_guest_custom)
+ should_email(@u_custom_global)
should_email(@u_participant_mentioned)
should_email(@subscriber)
should_email(@watcher_and_subscriber)
- should_email(@u_guest_watcher)
- should_email(@u_custom_global)
- should_email(@u_guest_custom)
should_not_email(@unsubscriber)
should_not_email(@u_participating)
should_not_email(@u_disabled)
@@ -1177,7 +1156,7 @@ describe NotificationService do
end
describe 'Projects' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
before do
build_team(project)
@@ -1198,19 +1177,39 @@ describe NotificationService do
end
end
- describe '#project_exported' do
- it do
- notification.project_exported(project, @u_disabled)
+ context 'user with notifications disabled' do
+ describe '#project_exported' do
+ it do
+ notification.project_exported(project, @u_disabled)
- should_only_email(@u_disabled)
+ should_not_email_anyone
+ end
+ end
+
+ describe '#project_not_exported' do
+ it do
+ notification.project_not_exported(project, @u_disabled, ['error'])
+
+ should_not_email_anyone
+ end
end
end
- describe '#project_not_exported' do
- it do
- notification.project_not_exported(project, @u_disabled, ['error'])
+ context 'user with notifications enabled' do
+ describe '#project_exported' do
+ it do
+ notification.project_exported(project, @u_participating)
+
+ should_only_email(@u_participating)
+ end
+ end
+
+ describe '#project_not_exported' do
+ it do
+ notification.project_not_exported(project, @u_participating, ['error'])
- should_only_email(@u_disabled)
+ should_only_email(@u_participating)
+ end
end
end
end
@@ -1221,7 +1220,7 @@ describe NotificationService do
let(:group) { create(:group) }
let(:member) { create(:user) }
- before(:each) do
+ before do
group.add_owner(creator)
group.add_developer(member, creator)
end
@@ -1234,14 +1233,43 @@ describe NotificationService do
end.to change { ActionMailer::Base.deliveries.size }.by(1)
end
end
+
+ describe '#new_group_member' do
+ let(:group) { create(:group) }
+ let(:added_user) { create(:user) }
+
+ def create_member!
+ GroupMember.create(
+ group: group,
+ user: added_user,
+ access_level: Gitlab::Access::GUEST
+ )
+ end
+
+ it 'sends a notification' do
+ create_member!
+ should_only_email(added_user)
+ end
+
+ describe 'when notifications are disabled' do
+ before do
+ create_global_setting_for(added_user, :disabled)
+ end
+
+ it 'does not send a notification' do
+ create_member!
+ should_not_email_anyone
+ end
+ end
+ end
end
describe 'ProjectMember' do
describe '#decline_group_invite' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:member) { create(:user) }
- before(:each) do
+ before do
project.add_developer(member, current_user: project.owner)
end
@@ -1253,10 +1281,35 @@ describe NotificationService do
end.to change { ActionMailer::Base.deliveries.size }.by(1)
end
end
+
+ describe '#new_project_member' do
+ let(:project) { create(:project) }
+ let(:added_user) { create(:user) }
+
+ def create_member!
+ create(:project_member, user: added_user, project: project)
+ end
+
+ it do
+ create_member!
+ should_only_email(added_user)
+ end
+
+ describe 'when notifications are disabled' do
+ before do
+ create_global_setting_for(added_user, :disabled)
+ end
+
+ it do
+ create_member!
+ should_not_email_anyone
+ end
+ end
+ end
end
context 'guest user in private project' do
- let(:private_project) { create(:empty_project, :private) }
+ let(:private_project) { create(:project, :private) }
let(:guest) { create(:user) }
let(:developer) { create(:user) }
let(:assignee) { create(:user) }
diff --git a/spec/services/preview_markdown_service_spec.rb b/spec/services/preview_markdown_service_spec.rb
index 4fd9cb23ae1..64a9559791f 100644
--- a/spec/services/preview_markdown_service_spec.rb
+++ b/spec/services/preview_markdown_service_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe PreviewMarkdownService do
let(:user) { create(:user) }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
before do
project.add_developer(user)
diff --git a/spec/services/projects/autocomplete_service_spec.rb b/spec/services/projects/autocomplete_service_spec.rb
index fc7238862ab..426593be428 100644
--- a/spec/services/projects/autocomplete_service_spec.rb
+++ b/spec/services/projects/autocomplete_service_spec.rb
@@ -8,7 +8,7 @@ describe Projects::AutocompleteService do
let(:non_member) { create(:user) }
let(:member) { create(:user) }
let(:admin) { create(:admin) }
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let!(:issue) { create(:issue, project: project, title: 'Issue 1') }
let!(:security_issue_1) { create(:issue, :confidential, project: project, title: 'Security issue 1', author: author) }
let!(:security_issue_2) { create(:issue, :confidential, title: 'Security issue 2', project: project, assignees: [assignee]) }
@@ -88,4 +88,31 @@ describe Projects::AutocompleteService do
end
end
end
+
+ describe '#milestones' do
+ let(:user) { create(:user) }
+ let(:group) { create(:group) }
+ let(:project) { create(:project, group: group) }
+ let!(:group_milestone) { create(:milestone, group: group) }
+ let!(:project_milestone) { create(:milestone, project: project) }
+
+ let(:milestone_titles) { described_class.new(project, user).milestones.map(&:title) }
+
+ it 'includes project and group milestones' do
+ expect(milestone_titles).to eq([group_milestone.title, project_milestone.title])
+ end
+
+ it 'does not include closed milestones' do
+ group_milestone.close
+
+ expect(milestone_titles).to eq([project_milestone.title])
+ end
+
+ it 'does not include milestones from other projects in the group' do
+ other_project = create(:project, group: group)
+ project_milestone.update!(project: other_project)
+
+ expect(milestone_titles).to eq([group_milestone.title])
+ end
+ end
end
diff --git a/spec/services/projects/create_from_template_service_spec.rb b/spec/services/projects/create_from_template_service_spec.rb
new file mode 100644
index 00000000000..9919ec254c6
--- /dev/null
+++ b/spec/services/projects/create_from_template_service_spec.rb
@@ -0,0 +1,26 @@
+require 'spec_helper'
+
+describe Projects::CreateFromTemplateService do
+ let(:user) { create(:user) }
+ let(:project_params) do
+ {
+ path: user.to_param,
+ template_name: 'rails'
+ }
+ end
+
+ subject { described_class.new(user, project_params) }
+
+ it 'calls the importer service' do
+ expect_any_instance_of(Projects::GitlabProjectsImportService).to receive(:execute)
+
+ subject.execute
+ end
+
+ it 'returns the project thats created' do
+ project = subject.execute
+
+ expect(project).to be_saved
+ expect(project.scheduled?).to be(true)
+ end
+end
diff --git a/spec/services/projects/destroy_service_spec.rb b/spec/services/projects/destroy_service_spec.rb
index 85b05ef6d05..c867139d1de 100644
--- a/spec/services/projects/destroy_service_spec.rb
+++ b/spec/services/projects/destroy_service_spec.rb
@@ -142,13 +142,13 @@ describe Projects::DestroyService do
context 'when `execute` raises unexpected error' do
before do
expect_any_instance_of(Project)
- .to receive(:destroy!).and_raise(Exception.new("Other error message"))
+ .to receive(:destroy!).and_raise(Exception.new('Other error message'))
end
it 'allows error to bubble up and rolls back project deletion' do
expect do
Sidekiq::Testing.inline! { destroy_project(project, user, {}) }
- end.to raise_error
+ end.to raise_error(Exception, 'Other error message')
expect(project.reload.pending_delete).to be(false)
expect(project.delete_error).to include("Other error message")
diff --git a/spec/services/projects/download_service_spec.rb b/spec/services/projects/download_service_spec.rb
index 701f6cc8c6a..da236052ebf 100644
--- a/spec/services/projects/download_service_spec.rb
+++ b/spec/services/projects/download_service_spec.rb
@@ -4,7 +4,7 @@ describe Projects::DownloadService do
describe 'File service' do
before do
@user = create(:user)
- @project = create(:empty_project, creator_id: @user.id, namespace: @user.namespace)
+ @project = create(:project, creator_id: @user.id, namespace: @user.namespace)
end
context 'for a URL that is not on whitelist' do
diff --git a/spec/services/projects/enable_deploy_key_service_spec.rb b/spec/services/projects/enable_deploy_key_service_spec.rb
index 9b8c24ba112..835dae68fcd 100644
--- a/spec/services/projects/enable_deploy_key_service_spec.rb
+++ b/spec/services/projects/enable_deploy_key_service_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe Projects::EnableDeployKeyService do
let(:deploy_key) { create(:deploy_key, public: true) }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:user) { project.creator}
let!(:params) { { key_id: deploy_key.id } }
diff --git a/spec/services/projects/fork_service_spec.rb b/spec/services/projects/fork_service_spec.rb
index c90536ba346..21c4b30734c 100644
--- a/spec/services/projects/fork_service_spec.rb
+++ b/spec/services/projects/fork_service_spec.rb
@@ -50,6 +50,14 @@ describe Projects::ForkService do
expect(@from_project.avatar.file).to be_exists
end
+
+ it 'flushes the forks count cache of the source project' do
+ expect(@from_project.forks_count).to be_zero
+
+ fork_project(@from_project, @to_user)
+
+ expect(@from_project.forks_count).to eq(1)
+ end
end
end
diff --git a/spec/services/projects/forks_count_service_spec.rb b/spec/services/projects/forks_count_service_spec.rb
new file mode 100644
index 00000000000..cf299c5d09b
--- /dev/null
+++ b/spec/services/projects/forks_count_service_spec.rb
@@ -0,0 +1,40 @@
+require 'spec_helper'
+
+describe Projects::ForksCountService do
+ let(:project) { build(:project, id: 42) }
+ let(:service) { described_class.new(project) }
+
+ describe '#count' do
+ it 'returns the number of forks' do
+ allow(service).to receive(:uncached_count).and_return(1)
+
+ expect(service.count).to eq(1)
+ end
+
+ it 'caches the forks count', :use_clean_rails_memory_store_caching do
+ expect(service).to receive(:uncached_count).once.and_return(1)
+
+ 2.times { service.count }
+ end
+ end
+
+ describe '#refresh_cache', :use_clean_rails_memory_store_caching do
+ it 'refreshes the cache' do
+ expect(service).to receive(:uncached_count).once.and_return(1)
+
+ service.refresh_cache
+
+ expect(service.count).to eq(1)
+ end
+ end
+
+ describe '#delete_cache', :use_clean_rails_memory_store_caching do
+ it 'removes the cache' do
+ expect(service).to receive(:uncached_count).twice.and_return(1)
+
+ service.count
+ service.delete_cache
+ service.count
+ end
+ end
+end
diff --git a/spec/services/projects/housekeeping_service_spec.rb b/spec/services/projects/housekeeping_service_spec.rb
index ebed802708d..385f56e447f 100644
--- a/spec/services/projects/housekeeping_service_spec.rb
+++ b/spec/services/projects/housekeeping_service_spec.rb
@@ -24,7 +24,7 @@ describe Projects::HousekeepingService do
end
context 'when no lease can be obtained' do
- before(:each) do
+ before do
expect(subject).to receive(:try_obtain_lease).and_return(false)
end
diff --git a/spec/services/projects/import_service_spec.rb b/spec/services/projects/import_service_spec.rb
index 67fe610f92a..034065aab00 100644
--- a/spec/services/projects/import_service_spec.rb
+++ b/spec/services/projects/import_service_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Projects::ImportService do
- let!(:project) { create(:empty_project) }
+ let!(:project) { create(:project) }
let(:user) { project.creator }
subject { described_class.new(project, user) }
@@ -26,7 +26,7 @@ describe Projects::ImportService do
result = subject.execute
expect(result[:status]).to eq :error
- expect(result[:message]).to eq "Error importing repository #{project.import_url} into #{project.path_with_namespace} - The repository could not be created."
+ expect(result[:message]).to eq "Error importing repository #{project.import_url} into #{project.full_path} - The repository could not be created."
end
end
@@ -38,8 +38,7 @@ describe Projects::ImportService do
context 'with a Github repository' do
it 'succeeds if repository import is successfully' do
- expect_any_instance_of(Repository).to receive(:fetch_remote).and_return(true)
- expect_any_instance_of(Gitlab::GithubImport::Importer).to receive(:execute).and_return(true)
+ expect_any_instance_of(Github::Import).to receive(:execute).and_return(true)
result = subject.execute
@@ -52,16 +51,7 @@ describe Projects::ImportService do
result = subject.execute
expect(result[:status]).to eq :error
- expect(result[:message]).to eq "Error importing repository #{project.import_url} into #{project.path_with_namespace} - Failed to import the repository"
- end
-
- it 'does not remove the GitHub remote' do
- expect_any_instance_of(Repository).to receive(:fetch_remote).and_return(true)
- expect_any_instance_of(Gitlab::GithubImport::Importer).to receive(:execute).and_return(true)
-
- subject.execute
-
- expect(project.repository.raw_repository.remote_names).to include('github')
+ expect(result[:message]).to eq "Error importing repository #{project.import_url} into #{project.path_with_namespace} - The remote data could not be imported."
end
end
@@ -86,7 +76,7 @@ describe Projects::ImportService do
result = subject.execute
expect(result[:status]).to eq :error
- expect(result[:message]).to eq "Error importing repository #{project.import_url} into #{project.path_with_namespace} - Failed to import the repository"
+ expect(result[:message]).to eq "Error importing repository #{project.import_url} into #{project.full_path} - Failed to import the repository"
end
end
end
@@ -102,8 +92,7 @@ describe Projects::ImportService do
end
it 'succeeds if importer succeeds' do
- allow_any_instance_of(Repository).to receive(:fetch_remote).and_return(true)
- allow_any_instance_of(Gitlab::GithubImport::Importer).to receive(:execute).and_return(true)
+ allow_any_instance_of(Github::Import).to receive(:execute).and_return(true)
result = subject.execute
@@ -111,10 +100,7 @@ describe Projects::ImportService do
end
it 'flushes various caches' do
- allow_any_instance_of(Repository).to receive(:fetch_remote)
- .and_return(true)
-
- allow_any_instance_of(Gitlab::GithubImport::Importer).to receive(:execute)
+ allow_any_instance_of(Github::Import).to receive(:execute)
.and_return(true)
expect_any_instance_of(Repository).to receive(:expire_content_cache)
@@ -123,29 +109,27 @@ describe Projects::ImportService do
end
it 'fails if importer fails' do
- allow_any_instance_of(Repository).to receive(:fetch_remote).and_return(true)
- allow_any_instance_of(Gitlab::GithubImport::Importer).to receive(:execute).and_return(false)
+ allow_any_instance_of(Github::Import).to receive(:execute).and_return(false)
result = subject.execute
expect(result[:status]).to eq :error
- expect(result[:message]).to eq "Error importing repository #{project.import_url} into #{project.path_with_namespace} - The remote data could not be imported."
+ expect(result[:message]).to eq "Error importing repository #{project.import_url} into #{project.full_path} - The remote data could not be imported."
end
it 'fails if importer raise an error' do
- allow_any_instance_of(Gitlab::Shell).to receive(:fetch_remote).and_return(true)
- allow_any_instance_of(Gitlab::GithubImport::Importer).to receive(:execute).and_raise(Projects::ImportService::Error.new('Github: failed to connect API'))
+ allow_any_instance_of(Github::Import).to receive(:execute).and_raise(Projects::ImportService::Error.new('Github: failed to connect API'))
result = subject.execute
expect(result[:status]).to eq :error
- expect(result[:message]).to eq "Error importing repository #{project.import_url} into #{project.path_with_namespace} - Github: failed to connect API"
+ expect(result[:message]).to eq "Error importing repository #{project.import_url} into #{project.full_path} - Github: failed to connect API"
end
it 'expires content cache after error' do
- allow_any_instance_of(Project).to receive(:repository_exists?).and_return(false, true)
+ allow_any_instance_of(Project).to receive(:repository_exists?).and_return(false)
- expect_any_instance_of(Gitlab::Shell).to receive(:fetch_remote).and_raise(Gitlab::Shell::Error.new('Failed to import the repository'))
+ expect_any_instance_of(Repository).to receive(:fetch_remote).and_raise(Gitlab::Shell::Error.new)
expect_any_instance_of(Repository).to receive(:expire_content_cache)
subject.execute
diff --git a/spec/services/projects/participants_service_spec.rb b/spec/services/projects/participants_service_spec.rb
index 8777e63a101..0d18ceb8ff8 100644
--- a/spec/services/projects/participants_service_spec.rb
+++ b/spec/services/projects/participants_service_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe Projects::ParticipantsService do
describe '#groups' do
describe 'avatar_url' do
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:group) { create(:group, avatar: fixture_file_upload(Rails.root + 'spec/fixtures/dk.png')) }
let(:user) { create(:user) }
let!(:group_member) { create(:group_member, group: group, user: user) }
diff --git a/spec/services/projects/propagate_service_template_spec.rb b/spec/services/projects/propagate_service_template_spec.rb
index 2763437f184..f4c59735c43 100644
--- a/spec/services/projects/propagate_service_template_spec.rb
+++ b/spec/services/projects/propagate_service_template_spec.rb
@@ -15,7 +15,7 @@ describe Projects::PropagateServiceTemplate do
})
end
- let!(:project) { create(:empty_project) }
+ let!(:project) { create(:project) }
it 'creates services for projects' do
expect(project.pushover_service).to be_nil
@@ -76,7 +76,7 @@ describe Projects::PropagateServiceTemplate do
before do
stub_const 'Projects::PropagateServiceTemplate::BATCH_SIZE', 3
- project_total.times { create(:empty_project) }
+ project_total.times { create(:project) }
described_class.propagate(service_template)
end
diff --git a/spec/services/projects/transfer_service_spec.rb b/spec/services/projects/transfer_service_spec.rb
index ae32e85b2a7..2cb60cbcfc4 100644
--- a/spec/services/projects/transfer_service_spec.rb
+++ b/spec/services/projects/transfer_service_spec.rb
@@ -37,18 +37,18 @@ describe Projects::TransferService do
end
it 'executes system hooks' do
- expect_any_instance_of(described_class).to receive(:execute_system_hooks)
-
- transfer_project(project, user, group)
+ transfer_project(project, user, group) do |service|
+ expect(service).to receive(:execute_system_hooks)
+ end
end
end
context 'when transfer fails' do
let!(:original_path) { project_path(project) }
- def attempt_project_transfer
+ def attempt_project_transfer(&block)
expect do
- transfer_project(project, user, group)
+ transfer_project(project, user, group, &block)
end.to raise_error(ActiveRecord::ActiveRecordError)
end
@@ -59,7 +59,7 @@ describe Projects::TransferService do
end
def project_path(project)
- File.join(project.repository_storage_path, "#{project.path_with_namespace}.git")
+ File.join(project.repository_storage_path, "#{project.disk_path}.git")
end
def current_path
@@ -80,9 +80,9 @@ describe Projects::TransferService do
end
it "doesn't run system hooks" do
- expect_any_instance_of(described_class).not_to receive(:execute_system_hooks)
-
- attempt_project_transfer
+ attempt_project_transfer do |service|
+ expect(service).not_to receive(:execute_system_hooks)
+ end
end
end
@@ -120,7 +120,11 @@ describe Projects::TransferService do
end
def transfer_project(project, user, new_namespace)
- Projects::TransferService.new(project, user).execute(new_namespace)
+ service = Projects::TransferService.new(project, user)
+
+ yield(service) if block_given?
+
+ service.execute(new_namespace)
end
context 'visibility level' do
diff --git a/spec/services/projects/unlink_fork_service_spec.rb b/spec/services/projects/unlink_fork_service_spec.rb
index 2ae8d5f7c54..4f1ab697460 100644
--- a/spec/services/projects/unlink_fork_service_spec.rb
+++ b/spec/services/projects/unlink_fork_service_spec.rb
@@ -29,4 +29,14 @@ describe Projects::UnlinkForkService do
subject.execute
end
+
+ it 'refreshes the forks count cache of the source project' do
+ source = fork_project.forked_from_project
+
+ expect(source.forks_count).to eq(1)
+
+ subject.execute
+
+ expect(source.forks_count).to be_zero
+ end
end
diff --git a/spec/services/projects/update_pages_configuration_service_spec.rb b/spec/services/projects/update_pages_configuration_service_spec.rb
index 42925e73978..e4d4e6ff3dd 100644
--- a/spec/services/projects/update_pages_configuration_service_spec.rb
+++ b/spec/services/projects/update_pages_configuration_service_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Projects::UpdatePagesConfigurationService do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
subject { described_class.new(project) }
describe "#update" do
diff --git a/spec/services/projects/update_service_spec.rb b/spec/services/projects/update_service_spec.rb
index d7b0df9a671..1b282e82187 100644
--- a/spec/services/projects/update_service_spec.rb
+++ b/spec/services/projects/update_service_spec.rb
@@ -5,7 +5,7 @@ describe Projects::UpdateService, '#execute' do
let(:admin) { create(:admin) }
let(:project) do
- create(:empty_project, creator: user, namespace: user.namespace)
+ create(:project, creator: user, namespace: user.namespace)
end
context 'when changing visibility level' do
@@ -59,7 +59,7 @@ describe Projects::UpdateService, '#execute' do
end
describe 'when updating project that has forks' do
- let(:project) { create(:empty_project, :internal) }
+ let(:project) { create(:project, :internal) }
let(:forked_project) { create(:forked_project_with_submodules, :internal) }
before do
@@ -101,6 +101,13 @@ describe Projects::UpdateService, '#execute' do
expect(Project.find(project.id).default_branch).to eq 'feature'
end
+
+ it 'does not change a default branch' do
+ # The branch 'unexisted-branch' does not exist.
+ update_project(project, admin, default_branch: 'unexisted-branch')
+
+ expect(Project.find(project.id).default_branch).to eq 'master'
+ end
end
context 'when updating a project that contains container images' do
diff --git a/spec/services/protected_branches/create_service_spec.rb b/spec/services/protected_branches/create_service_spec.rb
index 592f9b5929e..835e83d6dba 100644
--- a/spec/services/protected_branches/create_service_spec.rb
+++ b/spec/services/protected_branches/create_service_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe ProtectedBranches::CreateService do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:user) { project.owner }
let(:params) do
{
diff --git a/spec/services/protected_branches/update_service_spec.rb b/spec/services/protected_branches/update_service_spec.rb
index 5698101af54..9fa5983db66 100644
--- a/spec/services/protected_branches/update_service_spec.rb
+++ b/spec/services/protected_branches/update_service_spec.rb
@@ -19,7 +19,7 @@ describe ProtectedBranches::UpdateService do
let(:user) { create(:user) }
it "raises error" do
- expect{ service.execute(protected_branch) }.to raise_error(Gitlab::Access::AccessDeniedError)
+ expect { service.execute(protected_branch) }.to raise_error(Gitlab::Access::AccessDeniedError)
end
end
end
diff --git a/spec/services/protected_tags/create_service_spec.rb b/spec/services/protected_tags/create_service_spec.rb
index 3a3cc9c1573..c3ed95aaebf 100644
--- a/spec/services/protected_tags/create_service_spec.rb
+++ b/spec/services/protected_tags/create_service_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe ProtectedTags::CreateService do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:user) { project.owner }
let(:params) do
{
diff --git a/spec/services/protected_tags/update_service_spec.rb b/spec/services/protected_tags/update_service_spec.rb
index d333430088d..2ece4e3b07b 100644
--- a/spec/services/protected_tags/update_service_spec.rb
+++ b/spec/services/protected_tags/update_service_spec.rb
@@ -19,7 +19,7 @@ describe ProtectedTags::UpdateService do
let(:user) { create(:user) }
it "raises error" do
- expect{ service.execute(protected_tag) }.to raise_error(Gitlab::Access::AccessDeniedError)
+ expect { service.execute(protected_tag) }.to raise_error(Gitlab::Access::AccessDeniedError)
end
end
end
diff --git a/spec/services/push_event_payload_service_spec.rb b/spec/services/push_event_payload_service_spec.rb
new file mode 100644
index 00000000000..81956200bff
--- /dev/null
+++ b/spec/services/push_event_payload_service_spec.rb
@@ -0,0 +1,218 @@
+require 'spec_helper'
+
+describe PushEventPayloadService do
+ let(:event) { create(:push_event) }
+
+ describe '#execute' do
+ let(:push_data) do
+ {
+ commits: [
+ {
+ id: '1cf19a015df3523caf0a1f9d40c98a267d6a2fc2',
+ message: 'This is a commit'
+ }
+ ],
+ before: '0000000000000000000000000000000000000000',
+ after: '1cf19a015df3523caf0a1f9d40c98a267d6a2fc2',
+ total_commits_count: 1,
+ ref: 'refs/heads/my-branch'
+ }
+ end
+
+ it 'creates a new PushEventPayload row' do
+ payload = described_class.new(event, push_data).execute
+
+ expect(payload.commit_count).to eq(1)
+ expect(payload.action).to eq('created')
+ expect(payload.ref_type).to eq('branch')
+ expect(payload.commit_from).to be_nil
+ expect(payload.commit_to).to eq(push_data[:after])
+ expect(payload.ref).to eq('my-branch')
+ expect(payload.commit_title).to eq('This is a commit')
+ expect(payload.event_id).to eq(event.id)
+ end
+
+ it 'sets the push_event_payload association of the used event' do
+ payload = described_class.new(event, push_data).execute
+
+ expect(event.push_event_payload).to eq(payload)
+ end
+ end
+
+ describe '#commit_title' do
+ it 'returns nil if no commits were pushed' do
+ service = described_class.new(event, commits: [])
+
+ expect(service.commit_title).to be_nil
+ end
+
+ it 'returns a String limited to 70 characters' do
+ service = described_class.new(event, commits: [{ message: 'a' * 100 }])
+
+ expect(service.commit_title).to eq(('a' * 67) + '...')
+ end
+
+ it 'does not truncate the commit message if it is shorter than 70 characters' do
+ service = described_class.new(event, commits: [{ message: 'Hello' }])
+
+ expect(service.commit_title).to eq('Hello')
+ end
+
+ it 'includes the first line of a commit message if the message spans multiple lines' do
+ service = described_class
+ .new(event, commits: [{ message: "Hello\n\nworld" }])
+
+ expect(service.commit_title).to eq('Hello')
+ end
+ end
+
+ describe '#commit_from_id' do
+ it 'returns nil when creating a new ref' do
+ service = described_class.new(event, before: Gitlab::Git::BLANK_SHA)
+
+ expect(service.commit_from_id).to be_nil
+ end
+
+ it 'returns the ID of the first commit when pushing to an existing ref' do
+ service = described_class.new(event, before: '123')
+
+ expect(service.commit_from_id).to eq('123')
+ end
+ end
+
+ describe '#commit_to_id' do
+ it 'returns nil when removing an existing ref' do
+ service = described_class.new(event, after: Gitlab::Git::BLANK_SHA)
+
+ expect(service.commit_to_id).to be_nil
+ end
+ end
+
+ describe '#commit_count' do
+ it 'returns the number of commits' do
+ service = described_class.new(event, total_commits_count: 1)
+
+ expect(service.commit_count).to eq(1)
+ end
+
+ it 'raises when the push data does not contain the commits count' do
+ service = described_class.new(event, {})
+
+ expect { service.commit_count }.to raise_error(KeyError)
+ end
+ end
+
+ describe '#ref' do
+ it 'returns the name of the ref' do
+ service = described_class.new(event, ref: 'refs/heads/foo')
+
+ expect(service.ref).to eq('refs/heads/foo')
+ end
+
+ it 'raises when the push data does not contain the ref name' do
+ service = described_class.new(event, {})
+
+ expect { service.ref }.to raise_error(KeyError)
+ end
+ end
+
+ describe '#revision_before' do
+ it 'returns the revision from before the push' do
+ service = described_class.new(event, before: 'foo')
+
+ expect(service.revision_before).to eq('foo')
+ end
+
+ it 'raises when the push data does not contain the before revision' do
+ service = described_class.new(event, {})
+
+ expect { service.revision_before }.to raise_error(KeyError)
+ end
+ end
+
+ describe '#revision_after' do
+ it 'returns the revision from after the push' do
+ service = described_class.new(event, after: 'foo')
+
+ expect(service.revision_after).to eq('foo')
+ end
+
+ it 'raises when the push data does not contain the after revision' do
+ service = described_class.new(event, {})
+
+ expect { service.revision_after }.to raise_error(KeyError)
+ end
+ end
+
+ describe '#trimmed_ref' do
+ it 'returns the ref name without its prefix' do
+ service = described_class.new(event, ref: 'refs/heads/foo')
+
+ expect(service.trimmed_ref).to eq('foo')
+ end
+ end
+
+ describe '#create?' do
+ it 'returns true when creating a new ref' do
+ service = described_class.new(event, before: Gitlab::Git::BLANK_SHA)
+
+ expect(service.create?).to eq(true)
+ end
+
+ it 'returns false when pushing to an existing ref' do
+ service = described_class.new(event, before: 'foo')
+
+ expect(service.create?).to eq(false)
+ end
+ end
+
+ describe '#remove?' do
+ it 'returns true when removing an existing ref' do
+ service = described_class.new(event, after: Gitlab::Git::BLANK_SHA)
+
+ expect(service.remove?).to eq(true)
+ end
+
+ it 'returns false pushing to an existing ref' do
+ service = described_class.new(event, after: 'foo')
+
+ expect(service.remove?).to eq(false)
+ end
+ end
+
+ describe '#action' do
+ it 'returns :created when creating a ref' do
+ service = described_class.new(event, before: Gitlab::Git::BLANK_SHA)
+
+ expect(service.action).to eq(:created)
+ end
+
+ it 'returns :removed when removing an existing ref' do
+ service = described_class.new(event,
+ before: '123',
+ after: Gitlab::Git::BLANK_SHA)
+
+ expect(service.action).to eq(:removed)
+ end
+
+ it 'returns :pushed when pushing to an existing ref' do
+ service = described_class.new(event, before: '123', after: '456')
+
+ expect(service.action).to eq(:pushed)
+ end
+ end
+
+ describe '#ref_type' do
+ it 'returns :tag for a tag' do
+ service = described_class.new(event, ref: 'refs/tags/1.2')
+
+ expect(service.ref_type).to eq(:tag)
+ end
+
+ it 'returns :branch for a branch' do
+ service = described_class.new(event, ref: 'refs/heads/master')
+
+ expect(service.ref_type).to eq(:branch)
+ end
+ end
+end
diff --git a/spec/services/quick_actions/interpret_service_spec.rb b/spec/services/quick_actions/interpret_service_spec.rb
index 42a4a2591ea..30fa0ee6873 100644
--- a/spec/services/quick_actions/interpret_service_spec.rb
+++ b/spec/services/quick_actions/interpret_service_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe QuickActions::InterpretService do
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:developer) { create(:user) }
let(:developer2) { create(:user) }
let(:issue) { create(:issue, project: project) }
@@ -9,13 +9,13 @@ describe QuickActions::InterpretService do
let(:inprogress) { create(:label, project: project, title: 'In Progress') }
let(:bug) { create(:label, project: project, title: 'Bug') }
let(:note) { build(:note, commit_id: merge_request.diff_head_sha) }
+ let(:service) { described_class.new(project, developer) }
before do
project.team << [developer, :developer]
end
describe '#execute' do
- let(:service) { described_class.new(project, developer) }
let(:merge_request) { create(:merge_request, source_project: project) }
shared_examples 'reopen command' do
@@ -270,6 +270,22 @@ describe QuickActions::InterpretService do
end
end
+ shared_examples 'shrug command' do
+ it 'appends ¯\_(ツ)_/¯ to the comment' do
+ new_content, _ = service.execute(content, issuable)
+
+ expect(new_content).to end_with(described_class::SHRUG)
+ end
+ end
+
+ shared_examples 'tableflip command' do
+ it 'appends (╯°□°)╯︵ â”»â”â”» to the comment' do
+ new_content, _ = service.execute(content, issuable)
+
+ expect(new_content).to end_with(described_class::TABLEFLIP)
+ end
+ end
+
it_behaves_like 'reopen command' do
let(:content) { '/reopen' }
let(:issuable) { issue }
@@ -408,6 +424,26 @@ describe QuickActions::InterpretService do
end
end
+ context 'assign command with me alias' do
+ let(:content) { "/assign me" }
+
+ context 'Issue' do
+ it 'fetches assignee and populates assignee_ids if content contains /assign' do
+ _, updates = service.execute(content, issue)
+
+ expect(updates).to eq(assignee_ids: [developer.id])
+ end
+ end
+
+ context 'Merge Request' do
+ it 'fetches assignee and populates assignee_ids if content contains /assign' do
+ _, updates = service.execute(content, merge_request)
+
+ expect(updates).to eq(assignee_ids: [developer.id])
+ end
+ end
+ end
+
it_behaves_like 'empty command' do
let(:content) { '/assign @abcd1234' }
let(:issuable) { issue }
@@ -667,7 +703,7 @@ describe QuickActions::InterpretService do
context 'cross project references' do
it_behaves_like 'duplicate command' do
- let(:other_project) { create(:empty_project, :public) }
+ let(:other_project) { create(:project, :public) }
let(:issue_duplicate) { create(:issue, project: other_project) }
let(:content) { "/duplicate #{issue_duplicate.to_reference(project)}" }
let(:issuable) { issue }
@@ -679,7 +715,7 @@ describe QuickActions::InterpretService do
end
it_behaves_like 'empty command' do
- let(:other_project) { create(:empty_project, :private) }
+ let(:other_project) { create(:project, :private) }
let(:issue_duplicate) { create(:issue, project: other_project) }
let(:content) { "/duplicate #{issue_duplicate.to_reference(project)}" }
@@ -775,6 +811,30 @@ describe QuickActions::InterpretService do
end
end
+ context '/shrug command' do
+ it_behaves_like 'shrug command' do
+ let(:content) { '/shrug people are people' }
+ let(:issuable) { issue }
+ end
+
+ it_behaves_like 'shrug command' do
+ let(:content) { '/shrug' }
+ let(:issuable) { issue }
+ end
+ end
+
+ context '/tableflip command' do
+ it_behaves_like 'tableflip command' do
+ let(:content) { '/tableflip curse your sudden but enviable betrayal' }
+ let(:issuable) { issue }
+ end
+
+ it_behaves_like 'tableflip command' do
+ let(:content) { '/tableflip' }
+ let(:issuable) { issue }
+ end
+ end
+
context '/target_branch command' do
let(:non_empty_project) { create(:project, :repository) }
let(:another_merge_request) { create(:merge_request, author: developer, source_project: non_empty_project) }
diff --git a/spec/services/search/global_service_spec.rb b/spec/services/search/global_service_spec.rb
index de921573b1a..1309240b430 100644
--- a/spec/services/search/global_service_spec.rb
+++ b/spec/services/search/global_service_spec.rb
@@ -4,10 +4,10 @@ describe Search::GlobalService do
let(:user) { create(:user) }
let(:internal_user) { create(:user) }
- let!(:found_project) { create(:empty_project, :private, name: 'searchable_project') }
- let!(:unfound_project) { create(:empty_project, :private, name: 'unfound_project') }
- let!(:internal_project) { create(:empty_project, :internal, name: 'searchable_internal_project') }
- let!(:public_project) { create(:empty_project, :public, name: 'searchable_public_project') }
+ let!(:found_project) { create(:project, :private, name: 'searchable_project') }
+ let!(:unfound_project) { create(:project, :private, name: 'unfound_project') }
+ let!(:internal_project) { create(:project, :internal, name: 'searchable_internal_project') }
+ let!(:public_project) { create(:project, :public, name: 'searchable_public_project') }
before do
found_project.add_master(user)
diff --git a/spec/services/search/group_service_spec.rb b/spec/services/search/group_service_spec.rb
index cb3f02d2883..cbc553a60cf 100644
--- a/spec/services/search/group_service_spec.rb
+++ b/spec/services/search/group_service_spec.rb
@@ -8,14 +8,14 @@ describe Search::GroupService do
let(:nested_group) { create(:group, :nested) }
# These projects shouldn't be found
- let!(:outside_project) { create(:empty_project, :public, name: "Outside #{term}") }
- let!(:private_project) { create(:empty_project, :private, namespace: nested_group, name: "Private #{term}" )}
- let!(:other_project) { create(:empty_project, :public, namespace: nested_group, name: term.reverse) }
+ let!(:outside_project) { create(:project, :public, name: "Outside #{term}") }
+ let!(:private_project) { create(:project, :private, namespace: nested_group, name: "Private #{term}" )}
+ let!(:other_project) { create(:project, :public, namespace: nested_group, name: term.reverse) }
# These projects should be found
- let!(:project1) { create(:empty_project, :internal, namespace: nested_group, name: "Inner #{term} 1") }
- let!(:project2) { create(:empty_project, :internal, namespace: nested_group, name: "Inner #{term} 2") }
- let!(:project3) { create(:empty_project, :internal, namespace: nested_group.parent, name: "Outer #{term}") }
+ let!(:project1) { create(:project, :internal, namespace: nested_group, name: "Inner #{term} 1") }
+ let!(:project2) { create(:project, :internal, namespace: nested_group, name: "Inner #{term} 2") }
+ let!(:project3) { create(:project, :internal, namespace: nested_group.parent, name: "Outer #{term}") }
let(:results) { described_class.new(user, search_group, search: term).execute }
subject { results.objects('projects') }
diff --git a/spec/services/search/snippet_service_spec.rb b/spec/services/search/snippet_service_spec.rb
index 69438a3fa36..eae9bd4f5cf 100644
--- a/spec/services/search/snippet_service_spec.rb
+++ b/spec/services/search/snippet_service_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe Search::SnippetService do
let(:author) { create(:author) }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let!(:public_snippet) { create(:snippet, :public, content: 'password: XXX') }
let!(:internal_snippet) { create(:snippet, :internal, content: 'password: XXX') }
diff --git a/spec/services/search_service_spec.rb b/spec/services/search_service_spec.rb
index a6ef7561bc8..02de83a2df8 100644
--- a/spec/services/search_service_spec.rb
+++ b/spec/services/search_service_spec.rb
@@ -7,13 +7,13 @@ describe SearchService do
let(:inaccessible_group) { create(:group, :private) }
let!(:group_member) { create(:group_member, group: accessible_group, user: user) }
- let!(:accessible_project) { create(:empty_project, :private, name: 'accessible_project') }
- let!(:inaccessible_project) { create(:empty_project, :private, name: 'inaccessible_project') }
+ let!(:accessible_project) { create(:project, :private, name: 'accessible_project') }
+ let!(:inaccessible_project) { create(:project, :private, name: 'inaccessible_project') }
let(:note) { create(:note_on_issue, project: accessible_project) }
let(:snippet) { create(:snippet, author: user) }
- let(:group_project) { create(:empty_project, group: accessible_group, name: 'group_project') }
- let(:public_project) { create(:empty_project, :public, name: 'public_project') }
+ let(:group_project) { create(:project, group: accessible_group, name: 'group_project') }
+ let(:public_project) { create(:project, :public, name: 'public_project') }
before do
accessible_project.add_master(user)
@@ -28,7 +28,7 @@ describe SearchService do
end
it 'returns the project for guests' do
- search_project = create :empty_project
+ search_project = create :project
search_project.add_guest(user)
project = described_class.new(user, project_id: search_project.id).project
diff --git a/spec/services/spam_service_spec.rb b/spec/services/spam_service_spec.rb
index 46349c3e951..a14dfa3f01f 100644
--- a/spec/services/spam_service_spec.rb
+++ b/spec/services/spam_service_spec.rb
@@ -15,7 +15,7 @@ describe SpamService do
end
context 'when recaptcha was not verified' do
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:issue) { create(:issue, project: project) }
let(:request) { double(:request, env: {}) }
diff --git a/spec/services/submit_usage_ping_service_spec.rb b/spec/services/submit_usage_ping_service_spec.rb
index 817fa4262d5..c8a6fc1a99b 100644
--- a/spec/services/submit_usage_ping_service_spec.rb
+++ b/spec/services/submit_usage_ping_service_spec.rb
@@ -46,6 +46,8 @@ describe SubmitUsagePingService do
.by(1)
expect(ConversationalDevelopmentIndex::Metric.last.leader_issues).to eq 10.2
+ expect(ConversationalDevelopmentIndex::Metric.last.instance_issues).to eq 3.2
+ expect(ConversationalDevelopmentIndex::Metric.last.percentage_issues).to eq 31.37
end
end
@@ -60,6 +62,7 @@ describe SubmitUsagePingService do
conv_index: {
leader_issues: 10.2,
instance_issues: 3.2,
+ percentage_issues: 31.37,
leader_notes: 25.3,
instance_notes: 23.2,
@@ -86,7 +89,9 @@ describe SubmitUsagePingService do
instance_projects_prometheus_active: 0.30,
leader_service_desk_issues: 15.8,
- instance_service_desk_issues: 15.1
+ instance_service_desk_issues: 15.1,
+
+ non_existing_column: 'value'
}
}
end
diff --git a/spec/services/system_hooks_service_spec.rb b/spec/services/system_hooks_service_spec.rb
index b2d9862e71e..8b5d9187785 100644
--- a/spec/services/system_hooks_service_spec.rb
+++ b/spec/services/system_hooks_service_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe SystemHooksService do
let(:user) { create(:user) }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:project_member) { create(:project_member) }
let(:key) { create(:key, user: user) }
let(:deploy_key) { create(:key) }
diff --git a/spec/services/system_note_service_spec.rb b/spec/services/system_note_service_spec.rb
index cb59493c343..6d36affa9dc 100644
--- a/spec/services/system_note_service_spec.rb
+++ b/spec/services/system_note_service_spec.rb
@@ -3,7 +3,8 @@ require 'spec_helper'
describe SystemNoteService do
include Gitlab::Routing
- let(:project) { create(:empty_project) }
+ let(:group) { create(:group) }
+ let(:project) { create(:project, group: group) }
let(:author) { create(:user) }
let(:noteable) { create(:issue, project: project) }
let(:issue) { noteable }
@@ -34,7 +35,7 @@ describe SystemNoteService do
context 'metadata' do
it 'creates a new system note metadata record' do
- expect { subject }.to change{ SystemNoteMetadata.count }.from(0).to(1)
+ expect { subject }.to change { SystemNoteMetadata.count }.from(0).to(1)
end
it 'creates a record correctly' do
@@ -242,25 +243,51 @@ describe SystemNoteService do
end
describe '.change_milestone' do
- subject { described_class.change_milestone(noteable, project, author, milestone) }
+ context 'for a project milestone' do
+ subject { described_class.change_milestone(noteable, project, author, milestone) }
- let(:milestone) { create(:milestone, project: project) }
+ let(:milestone) { create(:milestone, project: project) }
- it_behaves_like 'a system note' do
- let(:action) { 'milestone' }
- end
+ it_behaves_like 'a system note' do
+ let(:action) { 'milestone' }
+ end
- context 'when milestone added' do
- it 'sets the note text' do
- expect(subject.note).to eq "changed milestone to #{milestone.to_reference}"
+ context 'when milestone added' do
+ it 'sets the note text' do
+ expect(subject.note).to eq "changed milestone to #{milestone.to_reference}"
+ end
+ end
+
+ context 'when milestone removed' do
+ let(:milestone) { nil }
+
+ it 'sets the note text' do
+ expect(subject.note).to eq 'removed milestone'
+ end
end
end
- context 'when milestone removed' do
- let(:milestone) { nil }
+ context 'for a group milestone' do
+ subject { described_class.change_milestone(noteable, project, author, milestone) }
- it 'sets the note text' do
- expect(subject.note).to eq 'removed milestone'
+ let(:milestone) { create(:milestone, group: group) }
+
+ it_behaves_like 'a system note' do
+ let(:action) { 'milestone' }
+ end
+
+ context 'when milestone added' do
+ it 'sets the note text to use the milestone name' do
+ expect(subject.note).to eq "changed milestone to #{milestone.to_reference(format: :name)}"
+ end
+ end
+
+ context 'when milestone removed' do
+ let(:milestone) { nil }
+
+ it 'sets the note text' do
+ expect(subject.note).to eq 'removed milestone'
+ end
end
end
end
@@ -450,7 +477,7 @@ describe SystemNoteService do
end
it 'does not create a system note metadata record' do
- expect { subject }.not_to change{ SystemNoteMetadata.count }
+ expect { subject }.not_to change { SystemNoteMetadata.count }
end
end
@@ -648,7 +675,7 @@ describe SystemNoteService do
end
describe '.noteable_moved' do
- let(:new_project) { create(:empty_project) }
+ let(:new_project) { create(:project) }
let(:new_noteable) { create(:issue, project: new_project) }
subject do
@@ -667,7 +694,7 @@ describe SystemNoteService do
end
it 'mentions referenced project' do
- expect(subject.note).to include new_project.path_with_namespace
+ expect(subject.note).to include new_project.full_path
end
end
@@ -718,7 +745,7 @@ describe SystemNoteService do
describe 'JIRA integration' do
include JiraServiceHelper
- let(:project) { create(:jira_project) }
+ let(:project) { create(:jira_project, :repository) }
let(:author) { create(:user) }
let(:issue) { create(:issue, project: project) }
let(:merge_request) { create(:merge_request, :simple, target_project: project, source_project: project) }
@@ -873,7 +900,7 @@ describe SystemNoteService do
describe "existing reference" do
before do
allow(JIRA::Resource::Remotelink).to receive(:all).and_return([])
- message = "[#{author.name}|http://localhost/#{author.username}] mentioned this issue in [a commit of #{project.path_with_namespace}|http://localhost/#{project.path_with_namespace}/commit/#{commit.id}]:\n'#{commit.title.chomp}'"
+ message = "[#{author.name}|http://localhost/#{author.username}] mentioned this issue in [a commit of #{project.full_path}|http://localhost/#{project.full_path}/commit/#{commit.id}]:\n'#{commit.title.chomp}'"
allow_any_instance_of(JIRA::Resource::Issue).to receive(:comments).and_return([OpenStruct.new(body: message)])
end
@@ -1116,7 +1143,7 @@ describe SystemNoteService do
end
context 'across different projects' do
- let(:other_project) { create(:empty_project) }
+ let(:other_project) { create(:project) }
let(:canonical_issue) { create(:issue, project: other_project) }
it_behaves_like 'a system note' do
@@ -1141,7 +1168,7 @@ describe SystemNoteService do
end
context 'across different projects' do
- let(:other_project) { create(:empty_project) }
+ let(:other_project) { create(:project) }
let(:duplicate_issue) { create(:issue, project: other_project) }
it_behaves_like 'a system note' do
diff --git a/spec/services/todo_service_spec.rb b/spec/services/todo_service_spec.rb
index 230e40de9e0..a9b34a5258a 100644
--- a/spec/services/todo_service_spec.rb
+++ b/spec/services/todo_service_spec.rb
@@ -10,7 +10,7 @@ describe TodoService do
let(:john_doe) { create(:user) }
let(:skipped) { create(:user) }
let(:skip_users) { [skipped] }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:mentions) { 'FYI: ' + [author, assignee, john_doe, member, guest, non_member, admin, skipped].map(&:to_reference).join(' ') }
let(:directly_addressed) { [author, assignee, john_doe, member, guest, non_member, admin, skipped].map(&:to_reference).join(' ') }
let(:directly_addressed_and_mentioned) { member.to_reference + ", what do you think? cc: " + [guest, admin, skipped].map(&:to_reference).join(' ') }
@@ -103,7 +103,7 @@ describe TodoService do
context 'when a private group is mentioned' do
let(:group) { create(:group, :private) }
- let(:project) { create(:empty_project, :private, group: group) }
+ let(:project) { create(:project, :private, group: group) }
let(:issue) { create(:issue, author: author, project: project, description: group.to_reference) }
before do
@@ -336,7 +336,7 @@ describe TodoService do
describe '#mark_todos_as_done' do
it_behaves_like 'updating todos state', :mark_todos_as_done, :pending, :done do
- let(:collection) { [first_todo, second_todo] }
+ let(:collection) { Todo.all }
end
end
@@ -348,7 +348,7 @@ describe TodoService do
describe '#mark_todos_as_pending' do
it_behaves_like 'updating todos state', :mark_todos_as_pending, :done, :pending do
- let(:collection) { [first_todo, second_todo] }
+ let(:collection) { Todo.all }
end
end
@@ -586,13 +586,13 @@ describe TodoService do
it 'does not create a directly addressed todo if user was already mentioned or addressed and todo is pending' do
create(:todo, :directly_addressed, user: member, project: project, target: addressed_mr_assigned, author: author)
- expect{ service.update_merge_request(addressed_mr_assigned, author) }.not_to change(member.todos, :count)
+ expect { service.update_merge_request(addressed_mr_assigned, author) }.not_to change(member.todos, :count)
end
it 'does not create a directly addressed todo if user was already mentioned or addressed and todo is done' do
create(:todo, :directly_addressed, user: skipped, project: project, target: addressed_mr_assigned, author: author)
- expect{ service.update_merge_request(addressed_mr_assigned, author, skip_users) }.not_to change(skipped.todos, :count)
+ expect { service.update_merge_request(addressed_mr_assigned, author, skip_users) }.not_to change(skipped.todos, :count)
end
context 'with a task list' do
@@ -880,14 +880,16 @@ describe TodoService do
it 'marks an array of todos as done' do
todo = create(:todo, :mentioned, user: john_doe, target: issue, project: project)
- expect { described_class.new.mark_todos_as_done([todo], john_doe) }
+ todos = TodosFinder.new(john_doe, {}).execute
+ expect { described_class.new.mark_todos_as_done(todos, john_doe) }
.to change { todo.reload.state }.from('pending').to('done')
end
it 'returns the ids of updated todos' do # Needed on API
todo = create(:todo, :mentioned, user: john_doe, target: issue, project: project)
- expect(described_class.new.mark_todos_as_done([todo], john_doe)).to eq([todo.id])
+ todos = TodosFinder.new(john_doe, {}).execute
+ expect(described_class.new.mark_todos_as_done(todos, john_doe)).to eq([todo.id])
end
context 'when some of the todos are done already' do
@@ -907,11 +909,32 @@ describe TodoService do
expect(described_class.new.mark_todos_as_done(Todo.all, john_doe)).to eq([])
end
end
+ end
+
+ describe '#mark_todos_as_done_by_ids' do
+ let(:issue) { create(:issue, project: project, author: author, assignees: [john_doe]) }
+ let(:another_issue) { create(:issue, project: project, author: author, assignees: [john_doe]) }
+
+ it 'marks an array of todo ids as done' do
+ todo = create(:todo, :mentioned, user: john_doe, target: issue, project: project)
+ another_todo = create(:todo, :mentioned, user: john_doe, target: another_issue, project: project)
+
+ expect { described_class.new.mark_todos_as_done_by_ids([todo.id, another_todo.id], john_doe) }
+ .to change { john_doe.todos.done.count }.from(0).to(2)
+ end
+
+ it 'marks a single todo id as done' do
+ todo = create(:todo, :mentioned, user: john_doe, target: issue, project: project)
+
+ expect { described_class.new.mark_todos_as_done_by_ids(todo.id, john_doe) }
+ .to change { todo.reload.state }.from('pending').to('done')
+ end
it 'caches the number of todos of a user', :use_clean_rails_memory_store_caching do
create(:todo, :mentioned, user: john_doe, target: issue, project: project)
todo = create(:todo, :mentioned, user: john_doe, target: issue, project: project)
- described_class.new.mark_todos_as_done([todo], john_doe)
+
+ described_class.new.mark_todos_as_done_by_ids(todo, john_doe)
expect_any_instance_of(TodosFinder).not_to receive(:execute)
diff --git a/spec/services/upload_service_spec.rb b/spec/services/upload_service_spec.rb
index cf76a18f171..24f3a5c5ff0 100644
--- a/spec/services/upload_service_spec.rb
+++ b/spec/services/upload_service_spec.rb
@@ -4,7 +4,7 @@ describe UploadService do
describe 'File service' do
before do
@user = create(:user)
- @project = create(:empty_project, creator_id: @user.id, namespace: @user.namespace)
+ @project = create(:project, creator_id: @user.id, namespace: @user.namespace)
end
context 'for valid gif file' do
diff --git a/spec/services/users/destroy_service_spec.rb b/spec/services/users/destroy_service_spec.rb
index 786335120fd..a82567f6f43 100644
--- a/spec/services/users/destroy_service_spec.rb
+++ b/spec/services/users/destroy_service_spec.rb
@@ -5,7 +5,7 @@ describe Users::DestroyService do
let!(:user) { create(:user) }
let!(:admin) { create(:admin) }
let!(:namespace) { create(:namespace, owner: user) }
- let!(:project) { create(:empty_project, namespace: namespace) }
+ let!(:project) { create(:project, namespace: namespace) }
let(:service) { described_class.new(admin) }
context 'no options are given' do
@@ -66,7 +66,7 @@ describe Users::DestroyService do
end
context "a deleted user's merge_requests" do
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
before do
project.add_developer(user)
diff --git a/spec/services/users/migrate_to_ghost_user_service_spec.rb b/spec/services/users/migrate_to_ghost_user_service_spec.rb
index a0030ce8809..ac3a8738cac 100644
--- a/spec/services/users/migrate_to_ghost_user_service_spec.rb
+++ b/spec/services/users/migrate_to_ghost_user_service_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe Users::MigrateToGhostUserService do
let!(:user) { create(:user) }
- let!(:project) { create(:project) }
+ let!(:project) { create(:project, :repository) }
let(:service) { described_class.new(user) }
context "migrating a user's associated records to the ghost user" do
diff --git a/spec/services/users/refresh_authorized_projects_service_spec.rb b/spec/services/users/refresh_authorized_projects_service_spec.rb
index 1c0f55d2965..08fd26d67fd 100644
--- a/spec/services/users/refresh_authorized_projects_service_spec.rb
+++ b/spec/services/users/refresh_authorized_projects_service_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe Users::RefreshAuthorizedProjectsService do
# We're using let! here so that any expectations for the service class are not
# triggered twice.
- let!(:project) { create(:empty_project) }
+ let!(:project) { create(:project) }
let(:user) { project.namespace.owner }
let(:service) { described_class.new(user) }
@@ -28,7 +28,7 @@ describe Users::RefreshAuthorizedProjectsService do
end
it 'updates the authorized projects of the user' do
- project2 = create(:empty_project)
+ project2 = create(:project)
to_remove = user.project_authorizations
.create!(project: project2, access_level: Gitlab::Access::MASTER)
@@ -109,7 +109,7 @@ describe Users::RefreshAuthorizedProjectsService do
end
context 'projects the user is a member of' do
- let!(:other_project) { create(:empty_project) }
+ let!(:other_project) { create(:project) }
before do
other_project.team.add_reporter(user)
@@ -122,7 +122,7 @@ describe Users::RefreshAuthorizedProjectsService do
context 'projects of groups the user is a member of' do
let(:group) { create(:group) }
- let!(:other_project) { create(:empty_project, group: group) }
+ let!(:other_project) { create(:project, group: group) }
before do
group.add_owner(user)
@@ -136,7 +136,7 @@ describe Users::RefreshAuthorizedProjectsService do
context 'projects of subgroups of groups the user is a member of', :nested_groups do
let(:group) { create(:group) }
let(:nested_group) { create(:group, parent: group) }
- let!(:other_project) { create(:empty_project, group: nested_group) }
+ let!(:other_project) { create(:project, group: nested_group) }
before do
group.add_master(user)
@@ -149,7 +149,7 @@ describe Users::RefreshAuthorizedProjectsService do
context 'projects shared with groups the user is a member of' do
let(:group) { create(:group) }
- let(:other_project) { create(:empty_project) }
+ let(:other_project) { create(:project) }
let!(:project_group_link) { create(:project_group_link, project: other_project, group: group, group_access: Gitlab::Access::GUEST) }
before do
@@ -164,7 +164,7 @@ describe Users::RefreshAuthorizedProjectsService do
context 'projects shared with subgroups of groups the user is a member of', :nested_groups do
let(:group) { create(:group) }
let(:nested_group) { create(:group, parent: group) }
- let(:other_project) { create(:empty_project) }
+ let(:other_project) { create(:project) }
let!(:project_group_link) { create(:project_group_link, project: other_project, group: nested_group, group_access: Gitlab::Access::DEVELOPER) }
before do
diff --git a/spec/services/web_hook_service_spec.rb b/spec/services/web_hook_service_spec.rb
index e79c12daa1c..365cb6b8f09 100644
--- a/spec/services/web_hook_service_spec.rb
+++ b/spec/services/web_hook_service_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe WebHookService do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:project_hook) { create(:project_hook) }
let(:headers) do
{
@@ -15,7 +15,7 @@ describe WebHookService do
let(:service_instance) { described_class.new(project_hook, data, 'push_hooks') }
describe '#execute' do
- before(:each) do
+ before do
project.hooks << [project_hook]
WebMock.stub_request(:post, project_hook.url)
@@ -112,6 +112,23 @@ describe WebHookService do
end
end
+ context 'with unsafe response body' do
+ before do
+ WebMock.stub_request(:post, project_hook.url).to_return(status: 200, body: "\xBB")
+ service_instance.execute
+ end
+
+ it 'log successful execution' do
+ expect(hook_log.trigger).to eq('push_hooks')
+ expect(hook_log.url).to eq(project_hook.url)
+ expect(hook_log.request_headers).to eq(headers)
+ expect(hook_log.response_body).to eq('')
+ expect(hook_log.response_status).to eq('200')
+ expect(hook_log.execution_duration).to be > 0
+ expect(hook_log.internal_error_message).to be_nil
+ end
+ end
+
context 'should not log ServiceHooks' do
let(:service_hook) { create(:service_hook) }
let(:service_instance) { described_class.new(service_hook, data, 'service_hook') }
diff --git a/spec/services/wiki_pages/create_service_spec.rb b/spec/services/wiki_pages/create_service_spec.rb
index fa3863e9b30..b270194d9b8 100644
--- a/spec/services/wiki_pages/create_service_spec.rb
+++ b/spec/services/wiki_pages/create_service_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe WikiPages::CreateService do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:user) { create(:user) }
let(:opts) do
diff --git a/spec/services/wiki_pages/destroy_service_spec.rb b/spec/services/wiki_pages/destroy_service_spec.rb
index 1668cd00ca8..2938126914b 100644
--- a/spec/services/wiki_pages/destroy_service_spec.rb
+++ b/spec/services/wiki_pages/destroy_service_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe WikiPages::DestroyService do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:user) { create(:user) }
let(:page) { create(:wiki_page) }
diff --git a/spec/services/wiki_pages/update_service_spec.rb b/spec/services/wiki_pages/update_service_spec.rb
index a672c84034b..2399db7d3d4 100644
--- a/spec/services/wiki_pages/update_service_spec.rb
+++ b/spec/services/wiki_pages/update_service_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe WikiPages::UpdateService do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:user) { create(:user) }
let(:page) { create(:wiki_page) }
@@ -9,7 +9,8 @@ describe WikiPages::UpdateService do
{
content: 'New content for wiki page',
format: 'markdown',
- message: 'New wiki message'
+ message: 'New wiki message',
+ title: 'New Title'
}
end
@@ -27,6 +28,7 @@ describe WikiPages::UpdateService do
expect(updated_page.message).to eq(opts[:message])
expect(updated_page.content).to eq(opts[:content])
expect(updated_page.format).to eq(opts[:format].to_sym)
+ expect(updated_page.title).to eq(opts[:title])
end
it 'executes webhooks' do
diff --git a/spec/simplecov_env.rb b/spec/simplecov_env.rb
index ac2c89b3ff9..25ddf932d42 100644
--- a/spec/simplecov_env.rb
+++ b/spec/simplecov_env.rb
@@ -36,18 +36,25 @@ module SimpleCovEnv
track_files '{app,lib}/**/*.rb'
add_filter '/vendor/ruby/'
+ add_filter 'app/controllers/sherlock/'
add_filter 'config/initializers/'
+ add_filter 'db/fixtures/'
+ add_filter 'lib/gitlab/sidekiq_middleware/'
+ add_filter 'lib/system_check/'
add_group 'Controllers', 'app/controllers'
- add_group 'Models', 'app/models'
- add_group 'Mailers', 'app/mailers'
- add_group 'Helpers', 'app/helpers'
- add_group 'Workers', %w(app/jobs app/workers)
- add_group 'Libraries', 'lib'
- add_group 'Services', 'app/services'
- add_group 'Finders', 'app/finders'
- add_group 'Uploaders', 'app/uploaders'
- add_group 'Validators', 'app/validators'
+ add_group 'Finders', 'app/finders'
+ add_group 'Helpers', 'app/helpers'
+ add_group 'Libraries', 'lib'
+ add_group 'Mailers', 'app/mailers'
+ add_group 'Models', 'app/models'
+ add_group 'Policies', 'app/policies'
+ add_group 'Presenters', 'app/presenters'
+ add_group 'Serializers', 'app/serializers'
+ add_group 'Services', 'app/services'
+ add_group 'Uploaders', 'app/uploaders'
+ add_group 'Validators', 'app/validators'
+ add_group 'Workers', %w(app/jobs app/workers)
merge_timeout 365.days
end
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 85335643921..3eea39d4bf4 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -8,6 +8,7 @@ require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'shoulda/matchers'
require 'rspec/retry'
+require 'rspec-parameterized'
rspec_profiling_is_configured =
ENV['RSPEC_PROFILING_POSTGRES_URL'].present? ||
@@ -49,7 +50,7 @@ RSpec.configure do |config|
config.include SearchHelpers, type: :feature
config.include WaitForRequests, :js
config.include StubConfiguration
- config.include EmailHelpers, type: :mailer
+ config.include EmailHelpers, :mailer, type: :mailer
config.include TestEnv
config.include ActiveJob::TestHelper
config.include ActiveSupport::Testing::TimeHelpers
@@ -69,7 +70,14 @@ RSpec.configure do |config|
config.raise_errors_for_deprecations!
+ if ENV['CI']
+ # This includes the first try, i.e. tests will be run 4 times before failing.
+ config.default_retry_count = 4
+ config.reporter.register_listener(RspecFlaky::Listener.new, :example_passed, :dump_summary)
+ end
+
config.before(:suite) do
+ Timecop.safe_mode = true
TestEnv.init
end
@@ -93,10 +101,8 @@ RSpec.configure do |config|
RequestStore.clear!
end
- if ENV['CI']
- config.around(:each) do |ex|
- ex.run_with_retry retry: 2
- end
+ config.before(:example, :mailer) do
+ reset_delivered_emails!
end
config.around(:each, :use_clean_rails_memory_store_caching) do |example|
@@ -129,10 +135,14 @@ RSpec.configure do |config|
config.before(:example, :migration) do
ActiveRecord::Migrator
.migrate(migrations_paths, previous_migration.version)
+
+ reset_column_in_migration_models
end
config.after(:example, :migration) do
ActiveRecord::Migrator.migrate(migrations_paths)
+
+ reset_column_in_migration_models
end
config.around(:each, :nested_groups) do |example|
diff --git a/spec/support/api/milestones_shared_examples.rb b/spec/support/api/milestones_shared_examples.rb
index 480e7d5151f..4bb5113957e 100644
--- a/spec/support/api/milestones_shared_examples.rb
+++ b/spec/support/api/milestones_shared_examples.rb
@@ -50,7 +50,7 @@ shared_examples_for 'group and project milestones' do |route_definition|
expect(response).to have_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(2)
- expect(json_response.map{ |m| m['id'] }).to match_array([closed_milestone.id, other_milestone.id])
+ expect(json_response.map { |m| m['id'] }).to match_array([closed_milestone.id, other_milestone.id])
end
it 'does not return any milestone if none found' do
@@ -239,7 +239,7 @@ shared_examples_for 'group and project milestones' do |route_definition|
end
describe 'confidential issues' do
- let!(:public_project) { create(:empty_project, :public) }
+ let!(:public_project) { create(:project, :public) }
let!(:context_group) { try(:group) }
let!(:milestone) do
context_group ? create(:milestone, group: context_group) : create(:milestone, project: public_project)
diff --git a/spec/support/api/schema_matcher.rb b/spec/support/api/schema_matcher.rb
index 67599f77adb..6591d56e473 100644
--- a/spec/support/api/schema_matcher.rb
+++ b/spec/support/api/schema_matcher.rb
@@ -1,23 +1,25 @@
-def schema_path(schema)
- schema_directory = "#{Dir.pwd}/spec/fixtures/api/schemas"
- "#{schema_directory}/#{schema}.json"
+module SchemaPath
+ def self.expand(schema, dir = '')
+ Rails.root.join('spec', dir, "fixtures/api/schemas/#{schema}.json").to_s
+ end
end
-RSpec::Matchers.define :match_response_schema do |schema, **options|
+RSpec::Matchers.define :match_response_schema do |schema, dir: '', **options|
match do |response|
- @errors = JSON::Validator.fully_validate(schema_path(schema), response.body, options)
+ @errors = JSON::Validator.fully_validate(
+ SchemaPath.expand(schema, dir), response.body, options)
@errors.empty?
end
failure_message do |response|
- "didn't match the schema defined by #{schema_path(schema)}" \
+ "didn't match the schema defined by #{SchemaPath.expand(schema, dir)}" \
" The validation errors were:\n#{@errors.join("\n")}"
end
end
-RSpec::Matchers.define :match_schema do |schema, **options|
+RSpec::Matchers.define :match_schema do |schema, dir: '', **options|
match do |data|
- JSON::Validator.validate!(schema_path(schema), data, options)
+ JSON::Validator.validate!(SchemaPath.expand(schema, dir), data, options)
end
end
diff --git a/spec/support/chat_slash_commands_shared_examples.rb b/spec/support/chat_slash_commands_shared_examples.rb
index 978b0b9cc30..dc97a39f051 100644
--- a/spec/support/chat_slash_commands_shared_examples.rb
+++ b/spec/support/chat_slash_commands_shared_examples.rb
@@ -36,7 +36,7 @@ RSpec.shared_examples 'chat slash commands service' do
end
context 'with a token passed' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:params) { { token: 'token' } }
before do
diff --git a/spec/support/controllers/githubish_import_controller_shared_examples.rb b/spec/support/controllers/githubish_import_controller_shared_examples.rb
index a8d9566b4e4..4eec3127464 100644
--- a/spec/support/controllers/githubish_import_controller_shared_examples.rb
+++ b/spec/support/controllers/githubish_import_controller_shared_examples.rb
@@ -56,7 +56,7 @@ shared_examples 'a GitHub-ish import controller: GET status' do
end
it "assigns variables" do
- project = create(:empty_project, import_type: provider, creator_id: user.id)
+ project = create(:project, import_type: provider, creator_id: user.id)
stub_client(repos: [repo, org_repo], orgs: [org], org_repos: [org_repo])
get :status
@@ -69,7 +69,7 @@ shared_examples 'a GitHub-ish import controller: GET status' do
end
it "does not show already added project" do
- project = create(:empty_project, import_type: provider, creator_id: user.id, import_source: 'asd/vim')
+ project = create(:project, import_type: provider, creator_id: user.id, import_source: 'asd/vim')
stub_client(repos: [repo], orgs: [])
get :status
diff --git a/spec/support/cycle_analytics_helpers.rb b/spec/support/cycle_analytics_helpers.rb
index c0a5491a430..30911e7fa86 100644
--- a/spec/support/cycle_analytics_helpers.rb
+++ b/spec/support/cycle_analytics_helpers.rb
@@ -41,7 +41,9 @@ module CycleAnalyticsHelpers
target_branch: 'master'
}
- MergeRequests::CreateService.new(project, user, opts).execute
+ mr = MergeRequests::CreateService.new(project, user, opts).execute
+ NewMergeRequestWorker.new.perform(mr, user)
+ mr
end
def merge_merge_requests_closing_issue(issue)
diff --git a/spec/support/features/issuable_slash_commands_shared_examples.rb b/spec/support/features/issuable_slash_commands_shared_examples.rb
index 035428a7d9b..68f0ce8afb3 100644
--- a/spec/support/features/issuable_slash_commands_shared_examples.rb
+++ b/spec/support/features/issuable_slash_commands_shared_examples.rb
@@ -5,7 +5,14 @@ shared_examples 'issuable record that supports quick actions in its description
include QuickActionsHelpers
let(:master) { create(:user) }
- let(:project) { create(:project, :public) }
+ let(:project) do
+ case issuable_type
+ when :merge_request
+ create(:project, :public, :repository)
+ when :issue
+ create(:project, :public)
+ end
+ end
let!(:milestone) { create(:milestone, project: project, title: 'ASAP') }
let!(:label_bug) { create(:label, project: project, title: 'bug') }
let!(:label_feature) { create(:label, project: project, title: 'feature') }
@@ -272,6 +279,17 @@ shared_examples 'issuable record that supports quick actions in its description
expect(issuable.subscribed?(master, project)).to be_falsy
end
end
+
+ context "with a note assigning the #{issuable_type} to the current user" do
+ it "assigns the #{issuable_type} to the current user" do
+ write_note("/assign me")
+
+ expect(page).not_to have_content '/assign me'
+ expect(page).to have_content 'Commands applied'
+
+ expect(issuable.reload.assignees).to eq [master]
+ end
+ end
end
describe "preview of note on #{issuable_type}" do
diff --git a/spec/support/features/reportable_note_shared_examples.rb b/spec/support/features/reportable_note_shared_examples.rb
index 27e079c01dd..cb483ae9a5a 100644
--- a/spec/support/features/reportable_note_shared_examples.rb
+++ b/spec/support/features/reportable_note_shared_examples.rb
@@ -7,15 +7,18 @@ shared_examples 'reportable note' do
let(:more_actions_selector) { '.more-actions.dropdown' }
let(:abuse_report_path) { new_abuse_report_path(user_id: note.author.id, ref_url: noteable_note_url(note)) }
+ it 'has an edit button' do
+ expect(comment).to have_selector('.js-note-edit')
+ end
+
it 'has a `More actions` dropdown' do
expect(comment).to have_selector(more_actions_selector)
end
- it 'dropdown has Edit, Report and Delete links' do
+ it 'dropdown has Report and Delete links' do
dropdown = comment.find(more_actions_selector)
open_dropdown(dropdown)
- expect(dropdown).to have_button('Edit comment')
expect(dropdown).to have_link('Report as abuse', href: abuse_report_path)
expect(dropdown).to have_link('Delete comment', href: note_url(note, project))
end
diff --git a/spec/support/gitlab-git-test.git/objects/3e/20715310a699808282e772720b9c04a0696bcc b/spec/support/gitlab-git-test.git/objects/3e/20715310a699808282e772720b9c04a0696bcc
new file mode 100644
index 00000000000..86bf37ac887
--- /dev/null
+++ b/spec/support/gitlab-git-test.git/objects/3e/20715310a699808282e772720b9c04a0696bcc
Binary files differ
diff --git a/spec/support/gitlab-git-test.git/objects/95/96bc54a6f0c0c98248fe97077eb5ccf48a98d0 b/spec/support/gitlab-git-test.git/objects/95/96bc54a6f0c0c98248fe97077eb5ccf48a98d0
new file mode 100644
index 00000000000..d90cb028e9b
--- /dev/null
+++ b/spec/support/gitlab-git-test.git/objects/95/96bc54a6f0c0c98248fe97077eb5ccf48a98d0
@@ -0,0 +1,2 @@
+x•OËn1 䜯ð 9&O ¡ž¹"õnoYD6Õ’ýÒª?Ðã¼ì™Òj;w»¾ªÂQ £õG‹rN˜(‘ÆH‘PrAÇrRÌ7¯ºtpâ²Mì#MœÂ”c´ê…NrsI­
+Ž“%Þú½­páÒ>Û«²®pzüÀ¯¹?Y¥Õ3XäBB̰GB4ƒ ûpÿ?k®›ÔvÛžú‚y~Wø])[‡¥Áa<þ“ÍCP_ \ No newline at end of file
diff --git a/spec/support/gitlab-git-test.git/packed-refs b/spec/support/gitlab-git-test.git/packed-refs
index ce5ab1f705b..507e4ce785a 100644
--- a/spec/support/gitlab-git-test.git/packed-refs
+++ b/spec/support/gitlab-git-test.git/packed-refs
@@ -8,6 +8,7 @@
46e1395e609395de004cacd4b142865ab0e52a29 refs/heads/gitattributes-updated
4b4918a572fa86f9771e5ba40fbd48e1eb03e2c6 refs/heads/master
5937ac0a7beb003549fc5fd26fc247adbce4a52e refs/heads/merge-test
+9596bc54a6f0c0c98248fe97077eb5ccf48a98d0 refs/heads/missing-gitmodules
f4e6814c3e4e7a0de82a9e7cd20c626cc963a2f8 refs/tags/v1.0.0
^6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9
8a2a6eb295bb170b34c24c76c49ed0e9b2eaf34b refs/tags/v1.1.0
diff --git a/spec/support/gpg_helpers.rb b/spec/support/gpg_helpers.rb
index 96ea6f28b30..65b38626a51 100644
--- a/spec/support/gpg_helpers.rb
+++ b/spec/support/gpg_helpers.rb
@@ -1,4 +1,6 @@
module GpgHelpers
+ SIGNED_COMMIT_SHA = '8a852d50dda17cc8fd1408d2fd0c5b0f24c76ca4'.freeze
+
module User1
extend self
diff --git a/spec/support/import_export/export_file_helper.rb b/spec/support/import_export/export_file_helper.rb
index 57b6abe12b7..2011408be93 100644
--- a/spec/support/import_export/export_file_helper.rb
+++ b/spec/support/import_export/export_file_helper.rb
@@ -6,7 +6,7 @@ module ExportFileHelper
ObjectWithParent = Struct.new(:object, :parent, :key_found)
def setup_project
- project = create(:project, :public)
+ project = create(:project, :public, :repository)
create(:release, project: project)
diff --git a/spec/support/issuable_shared_examples.rb b/spec/support/issuable_shared_examples.rb
index 970fe10db2b..42f3b4db23c 100644
--- a/spec/support/issuable_shared_examples.rb
+++ b/spec/support/issuable_shared_examples.rb
@@ -21,15 +21,15 @@ shared_examples 'system notes for milestones' do
create(:group_member, group: group, user: user)
end
- it 'does not create system note' do
+ it 'creates a system note' do
expect do
update_issuable(milestone: group_milestone)
- end.not_to change { Note.system.count }
+ end.to change { Note.system.count }.by(1)
end
end
context 'project milestones' do
- it 'creates system note' do
+ it 'creates a system note' do
expect do
update_issuable(milestone: create(:milestone))
end.to change { Note.system.count }.by(1)
diff --git a/spec/support/issuables_list_metadata_shared_examples.rb b/spec/support/issuables_list_metadata_shared_examples.rb
index 3406e4c3161..75982432ab4 100644
--- a/spec/support/issuables_list_metadata_shared_examples.rb
+++ b/spec/support/issuables_list_metadata_shared_examples.rb
@@ -2,19 +2,15 @@ shared_examples 'issuables list meta-data' do |issuable_type, action = nil|
before do
@issuable_ids = []
- 2.times do |n|
+ %w[fix improve/awesome].each do |source_branch|
issuable =
if issuable_type == :issue
create(issuable_type, project: project)
else
- create(issuable_type, source_project: project, source_branch: "#{n}-feature")
+ create(issuable_type, source_project: project, source_branch: source_branch)
end
@issuable_ids << issuable.id
-
- issuable.id.times { create(:note, noteable: issuable, project: issuable.project) }
- (issuable.id + 1).times { create(:award_emoji, :downvote, awardable: issuable) }
- (issuable.id + 2).times { create(:award_emoji, :upvote, awardable: issuable) }
end
end
@@ -27,15 +23,14 @@ shared_examples 'issuables list meta-data' do |issuable_type, action = nil|
meta_data = assigns(:issuable_meta_data)
- @issuable_ids.each do |id|
- expect(meta_data[id].notes_count).to eq(id)
- expect(meta_data[id].downvotes).to eq(id + 1)
- expect(meta_data[id].upvotes).to eq(id + 2)
+ aggregate_failures do
+ expect(meta_data.keys).to match_array(@issuable_ids)
+ expect(meta_data.values).to all(be_kind_of(Issuable::IssuableMeta))
end
end
describe "when given empty collection" do
- let(:project2) { create(:empty_project, :public) }
+ let(:project2) { create(:project, :public) }
it "doesn't execute any queries with false conditions" do
get_action =
diff --git a/spec/support/login_helpers.rb b/spec/support/login_helpers.rb
index c714d1b08a6..3e117530151 100644
--- a/spec/support/login_helpers.rb
+++ b/spec/support/login_helpers.rb
@@ -1,3 +1,5 @@
+require_relative 'devise_helpers'
+
module LoginHelpers
include DeviseHelpers
diff --git a/spec/support/markdown_feature.rb b/spec/support/markdown_feature.rb
index 21a054af4e1..c90359d7cfa 100644
--- a/spec/support/markdown_feature.rb
+++ b/spec/support/markdown_feature.rb
@@ -23,7 +23,7 @@ class MarkdownFeature
# Direct references ----------------------------------------------------------
def project
- @project ||= create(:project, :repository).tap do |project|
+ @project ||= create(:project, :repository, group: group).tap do |project|
project.team << [user, :master]
end
end
@@ -75,6 +75,10 @@ class MarkdownFeature
@milestone ||= create(:milestone, name: 'next goal', project: project)
end
+ def group_milestone
+ @group_milestone ||= create(:milestone, name: 'group-milestone', group: group)
+ end
+
# Cross-references -----------------------------------------------------------
def xproject
diff --git a/spec/support/matchers/markdown_matchers.rb b/spec/support/matchers/markdown_matchers.rb
index 7afa57fb76b..d12b2757427 100644
--- a/spec/support/matchers/markdown_matchers.rb
+++ b/spec/support/matchers/markdown_matchers.rb
@@ -155,7 +155,7 @@ module MarkdownMatchers
set_default_markdown_messages
match do |actual|
- expect(actual).to have_selector('a.gfm.gfm-milestone', count: 6)
+ expect(actual).to have_selector('a.gfm.gfm-milestone', count: 8)
end
end
diff --git a/spec/support/matchers/query_matcher.rb b/spec/support/matchers/query_matcher.rb
index ac8c4ab91d9..bb0feca7c43 100644
--- a/spec/support/matchers/query_matcher.rb
+++ b/spec/support/matchers/query_matcher.rb
@@ -28,6 +28,6 @@ RSpec::Matchers.define :make_queries_matching do |matcher, expected_count = nil|
def query_count(regex, &block)
@recorder = ActiveRecord::QueryRecorder.new(&block).log
- @recorder.select{ |q| q.match(regex) }
+ @recorder.select { |q| q.match(regex) }
end
end
diff --git a/spec/support/migrations_helpers.rb b/spec/support/migrations_helpers.rb
index 91fbb4eaf48..aabdad13047 100644
--- a/spec/support/migrations_helpers.rb
+++ b/spec/support/migrations_helpers.rb
@@ -15,6 +15,16 @@ module MigrationsHelpers
ActiveRecord::Migrator.migrations(migrations_paths)
end
+ def reset_column_in_migration_models
+ described_class.constants.sort.each do |name|
+ const = described_class.const_get(name)
+
+ if const.is_a?(Class) && const < ActiveRecord::Base
+ const.reset_column_information
+ end
+ end
+ end
+
def previous_migration
migrations.each_cons(2) do |previous, migration|
break previous if migration.name == described_class.name
diff --git a/spec/support/notify_shared_examples.rb b/spec/support/notify_shared_examples.rb
index 76411065265..136f92c6419 100644
--- a/spec/support/notify_shared_examples.rb
+++ b/spec/support/notify_shared_examples.rb
@@ -3,11 +3,10 @@ shared_context 'gitlab email notification' do
let(:gitlab_sender) { Gitlab.config.gitlab.email_from }
let(:gitlab_sender_reply_to) { Gitlab.config.gitlab.email_reply_to }
let(:recipient) { create(:user, email: 'recipient@example.com') }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:new_user_address) { 'newguy@example.com' }
before do
- reset_delivered_emails!
email = recipient.emails.create(email: "notifications@example.com")
recipient.update_attribute(:notification_email, email.email)
stub_incoming_email_setting(enabled: true, address: "reply+%{key}@#{Gitlab.config.gitlab.host}")
@@ -50,7 +49,7 @@ shared_examples 'an email with X-GitLab headers containing project details' do
aggregate_failures do
is_expected.to have_header('X-GitLab-Project', /#{project.name}/)
is_expected.to have_header('X-GitLab-Project-Id', /#{project.id}/)
- is_expected.to have_header('X-GitLab-Project-Path', /#{project.path_with_namespace}/)
+ is_expected.to have_header('X-GitLab-Project-Path', /#{project.full_path}/)
end
end
end
diff --git a/spec/support/project_features_apply_to_issuables_shared_examples.rb b/spec/support/project_features_apply_to_issuables_shared_examples.rb
index 81b51509e0b..639b0924197 100644
--- a/spec/support/project_features_apply_to_issuables_shared_examples.rb
+++ b/spec/support/project_features_apply_to_issuables_shared_examples.rb
@@ -5,7 +5,7 @@ shared_examples 'project features apply to issuables' do |klass|
let(:user_in_group) { create(:group_member, :developer, user: create(:user), group: group ).user }
let(:user_outside_group) { create(:user) }
- let(:project) { create(:empty_project, :public, project_args) }
+ let(:project) { create(:project, :public, project_args) }
def project_args
feature = "#{described_class.model_name.plural}_access_level".to_sym
diff --git a/spec/support/project_hook_data_shared_example.rb b/spec/support/project_hook_data_shared_example.rb
index 7dbaa6a6459..1eb405d4be8 100644
--- a/spec/support/project_hook_data_shared_example.rb
+++ b/spec/support/project_hook_data_shared_example.rb
@@ -8,7 +8,7 @@ RSpec.shared_examples 'project hook data with deprecateds' do |project_key: :pro
expect(data[project_key][:git_ssh_url]).to eq(project.ssh_url_to_repo)
expect(data[project_key][:namespace]).to eq(project.namespace.name)
expect(data[project_key][:visibility_level]).to eq(project.visibility_level)
- expect(data[project_key][:path_with_namespace]).to eq(project.path_with_namespace)
+ expect(data[project_key][:path_with_namespace]).to eq(project.full_path)
expect(data[project_key][:default_branch]).to eq(project.default_branch)
expect(data[project_key][:homepage]).to eq(project.web_url)
expect(data[project_key][:url]).to eq(project.url_to_repo)
@@ -27,7 +27,7 @@ RSpec.shared_examples 'project hook data' do |project_key: :project|
expect(data[project_key][:git_ssh_url]).to eq(project.ssh_url_to_repo)
expect(data[project_key][:namespace]).to eq(project.namespace.name)
expect(data[project_key][:visibility_level]).to eq(project.visibility_level)
- expect(data[project_key][:path_with_namespace]).to eq(project.path_with_namespace)
+ expect(data[project_key][:path_with_namespace]).to eq(project.full_path)
expect(data[project_key][:default_branch]).to eq(project.default_branch)
end
end
diff --git a/spec/support/prometheus/additional_metrics_shared_examples.rb b/spec/support/prometheus/additional_metrics_shared_examples.rb
index 016e16fc8d4..620fa37d455 100644
--- a/spec/support/prometheus/additional_metrics_shared_examples.rb
+++ b/spec/support/prometheus/additional_metrics_shared_examples.rb
@@ -10,11 +10,61 @@ RSpec.shared_examples 'additional metrics query' do
[{ 'metric': {}, 'values': [[1488758662.506, '0.00002996364761904785'], [1488758722.506, '0.00003090239047619091']] }]
end
+ let(:client) { double('prometheus_client') }
+ let(:query_result) { described_class.new(client).query(*query_params) }
+ let(:environment) { create(:environment, slug: 'environment-slug') }
+
before do
allow(client).to receive(:label_values).and_return(metric_names)
allow(metric_group_class).to receive(:all).and_return([simple_metric_group(metrics: [simple_metric])])
end
+ context 'metrics query context' do
+ subject! { described_class.new(client) }
+
+ shared_examples 'query context containing environment slug and filter' do
+ it 'contains ci_environment_slug' do
+ expect(subject).to receive(:query_metrics).with(hash_including(ci_environment_slug: environment.slug))
+
+ subject.query(*query_params)
+ end
+
+ it 'contains environment filter' do
+ expect(subject).to receive(:query_metrics).with(
+ hash_including(
+ environment_filter: "container_name!=\"POD\",environment=\"#{environment.slug}\""
+ )
+ )
+
+ subject.query(*query_params)
+ end
+ end
+
+ describe 'project has Kubernetes service' do
+ let(:project) { create(:kubernetes_project) }
+ let(:environment) { create(:environment, slug: 'environment-slug', project: project) }
+ let(:kube_namespace) { project.kubernetes_service.actual_namespace }
+
+ it_behaves_like 'query context containing environment slug and filter'
+
+ it 'query context contains kube_namespace' do
+ expect(subject).to receive(:query_metrics).with(hash_including(kube_namespace: kube_namespace))
+
+ subject.query(*query_params)
+ end
+ end
+
+ describe 'project without Kubernetes service' do
+ it_behaves_like 'query context containing environment slug and filter'
+
+ it 'query context contains empty kube_namespace' do
+ expect(subject).to receive(:query_metrics).with(hash_including(kube_namespace: ''))
+
+ subject.query(*query_params)
+ end
+ end
+ end
+
context 'with one group where two metrics is found' do
before do
allow(metric_group_class).to receive(:all).and_return([simple_metric_group])
@@ -51,6 +101,7 @@ RSpec.shared_examples 'additional metrics query' do
context 'with two groups with one metric each' do
let(:metrics) { [simple_metric(queries: [simple_query])] }
+
before do
allow(metric_group_class).to receive(:all).and_return(
[
diff --git a/spec/support/rake_helpers.rb b/spec/support/rake_helpers.rb
index 5cb415111d2..86bfeed107c 100644
--- a/spec/support/rake_helpers.rb
+++ b/spec/support/rake_helpers.rb
@@ -5,11 +5,15 @@ module RakeHelpers
end
def stub_warn_user_is_not_gitlab
- allow_any_instance_of(Object).to receive(:warn_user_is_not_gitlab)
+ allow(main_object).to receive(:warn_user_is_not_gitlab)
end
def silence_output
- allow($stdout).to receive(:puts)
- allow($stdout).to receive(:print)
+ allow(main_object).to receive(:puts)
+ allow(main_object).to receive(:print)
+ end
+
+ def main_object
+ @main_object ||= TOPLEVEL_BINDING.eval('self')
end
end
diff --git a/spec/support/redis/redis_shared_examples.rb b/spec/support/redis/redis_shared_examples.rb
index f9552e41894..8676f895a83 100644
--- a/spec/support/redis/redis_shared_examples.rb
+++ b/spec/support/redis/redis_shared_examples.rb
@@ -3,12 +3,12 @@ RSpec.shared_examples "redis_shared_examples" do
let(:test_redis_url) { "redis://redishost:#{redis_port}"}
- before(:each) do
+ before do
stub_env(environment_config_file_name, Rails.root.join(config_file_name))
clear_raw_config
end
- after(:each) do
+ after do
clear_raw_config
end
diff --git a/spec/support/seed_repo.rb b/spec/support/seed_repo.rb
index cfe7fc980a8..b4868e82cd7 100644
--- a/spec/support/seed_repo.rb
+++ b/spec/support/seed_repo.rb
@@ -97,6 +97,7 @@ module SeedRepo
gitattributes-updated
master
merge-test
+ missing-gitmodules
].freeze
TAGS = %w[
v1.0.0
diff --git a/spec/support/services/migrate_to_ghost_user_service_shared_examples.rb b/spec/support/services/migrate_to_ghost_user_service_shared_examples.rb
index 855051921f0..adfd256dff1 100644
--- a/spec/support/services/migrate_to_ghost_user_service_shared_examples.rb
+++ b/spec/support/services/migrate_to_ghost_user_service_shared_examples.rb
@@ -3,7 +3,14 @@ require "spec_helper"
shared_examples "migrating a deleted user's associated records to the ghost user" do |record_class, fields|
record_class_name = record_class.to_s.titleize.downcase
- let(:project) { create(:project) }
+ let(:project) do
+ case record_class
+ when MergeRequest
+ create(:project, :repository)
+ else
+ create(:project)
+ end
+ end
before do
project.add_developer(user)
diff --git a/spec/support/stored_repositories.rb b/spec/support/stored_repositories.rb
index df18926d58c..f3deae0f455 100644
--- a/spec/support/stored_repositories.rb
+++ b/spec/support/stored_repositories.rb
@@ -2,4 +2,16 @@ RSpec.configure do |config|
config.before(:each, :repository) do
TestEnv.clean_test_path
end
+
+ config.before(:all, :broken_storage) do
+ FileUtils.rm_rf Gitlab.config.repositories.storages.broken['path']
+ end
+
+ config.before(:each, :broken_storage) do
+ allow(Gitlab::GitalyClient).to receive(:call) do
+ raise GRPC::Unavailable.new('Gitaly broken in this spec')
+ end
+
+ Gitlab::Git::Storage::CircuitBreaker.reset_all!
+ end
end
diff --git a/spec/support/stub_configuration.rb b/spec/support/stub_configuration.rb
index 516f8878679..37c89d37aa0 100644
--- a/spec/support/stub_configuration.rb
+++ b/spec/support/stub_configuration.rb
@@ -38,6 +38,17 @@ module StubConfiguration
allow(Gitlab.config.backup).to receive_messages(to_settings(messages))
end
+ def stub_storage_settings(messages)
+ messages.each do |storage_name, storage_settings|
+ storage_settings['failure_count_threshold'] ||= 10
+ storage_settings['failure_wait_time'] ||= 30
+ storage_settings['failure_reset_time'] ||= 1800
+ storage_settings['storage_timeout'] ||= 5
+ end
+
+ allow(Gitlab.config.repositories).to receive(:storages).and_return(messages)
+ end
+
private
# Modifies stubbed messages to also stub possible predicate versions
diff --git a/spec/support/test_env.rb b/spec/support/test_env.rb
index 86f9568c12e..1e39f80699c 100644
--- a/spec/support/test_env.rb
+++ b/spec/support/test_env.rb
@@ -122,32 +122,60 @@ module TestEnv
end
def setup_gitlab_shell
- shell_needs_update = component_needs_update?(Gitlab.config.gitlab_shell.path,
+ puts "\n==> Setting up Gitlab Shell..."
+ start = Time.now
+ gitlab_shell_dir = Gitlab.config.gitlab_shell.path
+ shell_needs_update = component_needs_update?(gitlab_shell_dir,
Gitlab::Shell.version_required)
unless !shell_needs_update || system('rake', 'gitlab:shell:install')
- raise 'Can`t clone gitlab-shell'
+ puts "\nGitLab Shell failed to install, cleaning up #{gitlab_shell_dir}!\n"
+ FileUtils.rm_rf(gitlab_shell_dir)
+ exit 1
end
+
+ puts " GitLab Shell setup in #{Time.now - start} seconds...\n"
end
def setup_gitaly
+ puts "\n==> Setting up Gitaly..."
+ start = Time.now
socket_path = Gitlab::GitalyClient.address('default').sub(/\Aunix:/, '')
gitaly_dir = File.dirname(socket_path)
+
+ if gitaly_dir_stale?(gitaly_dir)
+ puts " Gitaly is outdated, cleaning up #{gitaly_dir}!"
+ FileUtils.rm_rf(gitaly_dir)
+ end
+
gitaly_needs_update = component_needs_update?(gitaly_dir,
Gitlab::GitalyClient.expected_server_version)
unless !gitaly_needs_update || system('rake', "gitlab:gitaly:install[#{gitaly_dir}]")
- raise "Can't clone gitaly"
+ puts "\nGitaly failed to install, cleaning up #{gitaly_dir}!\n"
+ FileUtils.rm_rf(gitaly_dir)
+ exit 1
end
start_gitaly(gitaly_dir)
+ puts " Gitaly setup in #{Time.now - start} seconds...\n"
+ end
+
+ def gitaly_dir_stale?(dir)
+ gitaly_executable = File.join(dir, 'gitaly')
+ return false unless File.exist?(gitaly_executable)
+
+ File.mtime(gitaly_executable) < File.mtime(Rails.root.join('GITALY_SERVER_VERSION'))
end
def start_gitaly(gitaly_dir)
- gitaly_exec = File.join(gitaly_dir, 'gitaly')
- gitaly_config = File.join(gitaly_dir, 'config.toml')
- log_file = Rails.root.join('log/gitaly-test.log').to_s
- @gitaly_pid = Bundler.with_original_env { spawn(gitaly_exec, gitaly_config, [:out, :err] => log_file) }
+ if ENV['CI'].present?
+ # Gitaly has been spawned outside this process already
+ return
+ end
+
+ spawn_script = Rails.root.join('scripts/gitaly-test-spawn').to_s
+ @gitaly_pid = Bundler.with_original_env { IO.popen([spawn_script], &:read).to_i }
end
def stop_gitaly
@@ -208,7 +236,6 @@ module TestEnv
# Otherwise they'd be created by the first test, often timing out and
# causing a transient test failure
def eager_load_driver_server
- return unless ENV['CI']
return unless defined?(Capybara)
puts "Starting the Capybara driver server..."
@@ -223,6 +250,14 @@ module TestEnv
"#{forked_repo_path}_bare"
end
+ def with_empty_bare_repository(name = nil)
+ path = Rails.root.join('tmp/tests', name || 'empty-bare-repository').to_s
+
+ yield(Rugged::Repository.init_at(path, :bare))
+ ensure
+ FileUtils.rm_rf(path)
+ end
+
private
def factory_repo_path
diff --git a/spec/support/unique_ip_check_shared_examples.rb b/spec/support/unique_ip_check_shared_examples.rb
index ff0b47899f5..2dfa5fbecea 100644
--- a/spec/support/unique_ip_check_shared_examples.rb
+++ b/spec/support/unique_ip_check_shared_examples.rb
@@ -1,6 +1,6 @@
shared_context 'unique ips sign in limit' do
include StubENV
- before(:each) do
+ before do
Gitlab::Redis::Cache.with(&:flushall)
Gitlab::Redis::Queues.with(&:flushall)
Gitlab::Redis::SharedState.with(&:flushall)
diff --git a/spec/support/updating_mentions_shared_examples.rb b/spec/support/updating_mentions_shared_examples.rb
index eeec3e1d79b..565d3203e4f 100644
--- a/spec/support/updating_mentions_shared_examples.rb
+++ b/spec/support/updating_mentions_shared_examples.rb
@@ -7,8 +7,6 @@ RSpec.shared_examples 'updating mentions' do |service_class|
end
def update_mentionable(opts)
- reset_delivered_emails!
-
perform_enqueued_jobs do
service_class.new(project, user, opts).execute(mentionable)
end
diff --git a/spec/tasks/config_lint_spec.rb b/spec/tasks/config_lint_spec.rb
index ed6c5b09663..83d54259dfa 100644
--- a/spec/tasks/config_lint_spec.rb
+++ b/spec/tasks/config_lint_spec.rb
@@ -2,19 +2,19 @@ require 'rake_helper'
Rake.application.rake_require 'tasks/config_lint'
describe ConfigLint do
- let(:files){ ['lib/support/fake.sh'] }
+ let(:files) { ['lib/support/fake.sh'] }
it 'errors out if any bash scripts have errors' do
- expect { described_class.run(files){ system('exit 1') } }.to raise_error(SystemExit)
+ expect { described_class.run(files) { system('exit 1') } }.to raise_error(SystemExit)
end
it 'passes if all scripts are fine' do
- expect { described_class.run(files){ system('exit 0') } }.not_to raise_error
+ expect { described_class.run(files) { system('exit 0') } }.not_to raise_error
end
end
describe 'config_lint rake task' do
- before(:each) do
+ before do
# Prevent `system` from actually being called
allow(Kernel).to receive(:system).and_return(true)
end
diff --git a/spec/tasks/gitlab/backup_rake_spec.rb b/spec/tasks/gitlab/backup_rake_spec.rb
index 71580a788d0..0c8c8a2ab05 100644
--- a/spec/tasks/gitlab/backup_rake_spec.rb
+++ b/spec/tasks/gitlab/backup_rake_spec.rb
@@ -117,9 +117,9 @@ describe 'gitlab:app namespace rake task' do
describe 'backup creation and deletion using custom_hooks' do
let(:project) { create(:project, :repository) }
- let(:user_backup_path) { "repositories/#{project.path_with_namespace}" }
+ let(:user_backup_path) { "repositories/#{project.disk_path}" }
- before(:each) do
+ before do
@origin_cd = Dir.pwd
path = File.join(project.repository.path_to_repo, filename)
@@ -130,7 +130,7 @@ describe 'gitlab:app namespace rake task' do
create_backup
end
- after(:each) do
+ after do
ENV["SKIP"] = ""
FileUtils.rm(@backup_tar)
Dir.chdir(@origin_cd)
@@ -261,8 +261,8 @@ describe 'gitlab:app namespace rake task' do
%W{tar -tvf #{@backup_tar} repositories}
)
expect(exit_status).to eq(0)
- expect(tar_contents).to match("repositories/#{project_a.path_with_namespace}.bundle")
- expect(tar_contents).to match("repositories/#{project_b.path_with_namespace}.bundle")
+ expect(tar_contents).to match("repositories/#{project_a.disk_path}.bundle")
+ expect(tar_contents).to match("repositories/#{project_b.disk_path}.bundle")
end
end
end # backup_create task
diff --git a/spec/tasks/gitlab/gitaly_rake_spec.rb b/spec/tasks/gitlab/gitaly_rake_spec.rb
index d42d2423f15..b29d63c7d67 100644
--- a/spec/tasks/gitlab/gitaly_rake_spec.rb
+++ b/spec/tasks/gitlab/gitaly_rake_spec.rb
@@ -20,7 +20,7 @@ describe 'gitlab:gitaly namespace rake task' do
context 'when an underlying Git command fail' do
it 'aborts and display a help message' do
- expect_any_instance_of(Object)
+ expect(main_object)
.to receive(:checkout_or_clone_version).and_raise 'Git error'
expect { run_rake_task('gitlab:gitaly:install', clone_path) }.to raise_error 'Git error'
@@ -33,7 +33,7 @@ describe 'gitlab:gitaly namespace rake task' do
end
it 'calls checkout_or_clone_version with the right arguments' do
- expect_any_instance_of(Object)
+ expect(main_object)
.to receive(:checkout_or_clone_version).with(version: version, repo: repo, target_dir: clone_path)
run_rake_task('gitlab:gitaly:install', clone_path)
@@ -41,20 +41,30 @@ describe 'gitlab:gitaly namespace rake task' do
end
describe 'gmake/make' do
+ let(:command_preamble) { %w[/usr/bin/env -u RUBYOPT -u BUNDLE_GEMFILE] }
+
+ before(:all) do
+ @old_env_ci = ENV.delete('CI')
+ end
+
+ after(:all) do
+ ENV['CI'] = @old_env_ci if @old_env_ci
+ end
+
before do
FileUtils.mkdir_p(clone_path)
expect(Dir).to receive(:chdir).with(clone_path).and_call_original
+ allow(Bundler).to receive(:bundle_path).and_return('/fake/bundle_path')
end
context 'gmake is available' do
before do
- expect_any_instance_of(Object).to receive(:checkout_or_clone_version)
- allow_any_instance_of(Object).to receive(:run_command!).with(['gmake']).and_return(true)
+ expect(main_object).to receive(:checkout_or_clone_version)
end
it 'calls gmake in the gitaly directory' do
expect(Gitlab::Popen).to receive(:popen).with(%w[which gmake]).and_return(['/usr/bin/gmake', 0])
- expect_any_instance_of(Object).to receive(:run_command!).with(['gmake']).and_return(true)
+ expect(main_object).to receive(:run_command!).with(command_preamble + %w[gmake BUNDLE_PATH=/fake/bundle_path]).and_return(true)
run_rake_task('gitlab:gitaly:install', clone_path)
end
@@ -62,16 +72,27 @@ describe 'gitlab:gitaly namespace rake task' do
context 'gmake is not available' do
before do
- expect_any_instance_of(Object).to receive(:checkout_or_clone_version)
- allow_any_instance_of(Object).to receive(:run_command!).with(['make']).and_return(true)
+ expect(main_object).to receive(:checkout_or_clone_version)
+ expect(Gitlab::Popen).to receive(:popen).with(%w[which gmake]).and_return(['', 42])
end
it 'calls make in the gitaly directory' do
- expect(Gitlab::Popen).to receive(:popen).with(%w[which gmake]).and_return(['', 42])
- expect_any_instance_of(Object).to receive(:run_command!).with(['make']).and_return(true)
+ expect(main_object).to receive(:run_command!).with(command_preamble + %w[make BUNDLE_PATH=/fake/bundle_path]).and_return(true)
run_rake_task('gitlab:gitaly:install', clone_path)
end
+
+ context 'when Rails.env is not "test"' do
+ before do
+ allow(Rails.env).to receive(:test?).and_return(false)
+ end
+
+ it 'calls make in the gitaly directory without BUNDLE_PATH' do
+ expect(main_object).to receive(:run_command!).with(command_preamble + ['make']).and_return(true)
+
+ run_rake_task('gitlab:gitaly:install', clone_path)
+ end
+ end
end
end
end
@@ -97,6 +118,8 @@ describe 'gitlab:gitaly namespace rake task' do
# Gitaly storage configuration generated from #{Gitlab.config.source} on #{Time.current.to_s(:long)}
# This is in TOML format suitable for use in Gitaly's config.toml file.
socket_path = "/path/to/my.socket"
+ [gitlab-shell]
+ dir = "#{Gitlab.config.gitlab_shell.path}"
[[storage]]
name = "default"
path = "/path/to/default"
diff --git a/spec/tasks/gitlab/shell_rake_spec.rb b/spec/tasks/gitlab/shell_rake_spec.rb
index ee3614c50f6..65155cb044d 100644
--- a/spec/tasks/gitlab/shell_rake_spec.rb
+++ b/spec/tasks/gitlab/shell_rake_spec.rb
@@ -22,7 +22,8 @@ describe 'gitlab:shell rake tasks' do
describe 'create_hooks task' do
it 'calls gitlab-shell bin/create_hooks' do
expect_any_instance_of(Object).to receive(:system)
- .with("#{Gitlab.config.gitlab_shell.path}/bin/create-hooks", *repository_storage_paths_args)
+ .with("#{Gitlab.config.gitlab_shell.path}/bin/create-hooks",
+ *Gitlab::TaskHelpers.repository_storage_paths_args)
run_rake_task('gitlab:shell:create_hooks')
end
diff --git a/spec/tasks/gitlab/workhorse_rake_spec.rb b/spec/tasks/gitlab/workhorse_rake_spec.rb
index 1b68f3044a4..42516d36c67 100644
--- a/spec/tasks/gitlab/workhorse_rake_spec.rb
+++ b/spec/tasks/gitlab/workhorse_rake_spec.rb
@@ -20,7 +20,7 @@ describe 'gitlab:workhorse namespace rake task' do
context 'when an underlying Git command fail' do
it 'aborts and display a help message' do
- expect_any_instance_of(Object)
+ expect(main_object)
.to receive(:checkout_or_clone_version).and_raise 'Git error'
expect { run_rake_task('gitlab:workhorse:install', clone_path) }.to raise_error 'Git error'
@@ -33,7 +33,7 @@ describe 'gitlab:workhorse namespace rake task' do
end
it 'calls checkout_or_clone_version with the right arguments' do
- expect_any_instance_of(Object)
+ expect(main_object)
.to receive(:checkout_or_clone_version).with(version: version, repo: repo, target_dir: clone_path)
run_rake_task('gitlab:workhorse:install', clone_path)
@@ -48,13 +48,13 @@ describe 'gitlab:workhorse namespace rake task' do
context 'gmake is available' do
before do
- expect_any_instance_of(Object).to receive(:checkout_or_clone_version)
- allow_any_instance_of(Object).to receive(:run_command!).with(['gmake']).and_return(true)
+ expect(main_object).to receive(:checkout_or_clone_version)
+ allow(Object).to receive(:run_command!).with(['gmake']).and_return(true)
end
it 'calls gmake in the gitlab-workhorse directory' do
expect(Gitlab::Popen).to receive(:popen).with(%w[which gmake]).and_return(['/usr/bin/gmake', 0])
- expect_any_instance_of(Object).to receive(:run_command!).with(['gmake']).and_return(true)
+ expect(main_object).to receive(:run_command!).with(['gmake']).and_return(true)
run_rake_task('gitlab:workhorse:install', clone_path)
end
@@ -62,13 +62,13 @@ describe 'gitlab:workhorse namespace rake task' do
context 'gmake is not available' do
before do
- expect_any_instance_of(Object).to receive(:checkout_or_clone_version)
- allow_any_instance_of(Object).to receive(:run_command!).with(['make']).and_return(true)
+ expect(main_object).to receive(:checkout_or_clone_version)
+ allow(main_object).to receive(:run_command!).with(['make']).and_return(true)
end
it 'calls make in the gitlab-workhorse directory' do
expect(Gitlab::Popen).to receive(:popen).with(%w[which gmake]).and_return(['', 42])
- expect_any_instance_of(Object).to receive(:run_command!).with(['make']).and_return(true)
+ expect(main_object).to receive(:run_command!).with(['make']).and_return(true)
run_rake_task('gitlab:workhorse:install', clone_path)
end
diff --git a/spec/uploaders/file_mover_spec.rb b/spec/uploaders/file_mover_spec.rb
index d7c1b390f9a..0cf462e9553 100644
--- a/spec/uploaders/file_mover_spec.rb
+++ b/spec/uploaders/file_mover_spec.rb
@@ -4,11 +4,11 @@ describe FileMover do
let(:filename) { 'banana_sample.gif' }
let(:file) { fixture_file_upload(Rails.root.join('spec', 'fixtures', filename)) }
let(:temp_description) do
- 'test ![banana_sample](/uploads/system/temp/secret55/banana_sample.gif) same ![banana_sample]'\
- '(/uploads/system/temp/secret55/banana_sample.gif)'
+ 'test ![banana_sample](/uploads/-/system/temp/secret55/banana_sample.gif) same ![banana_sample]'\
+ '(/uploads/-/system/temp/secret55/banana_sample.gif)'
end
let(:temp_file_path) { File.join('secret55', filename).to_s }
- let(:file_path) { File.join('uploads', 'system', 'personal_snippet', snippet.id.to_s, 'secret55', filename).to_s }
+ let(:file_path) { File.join('uploads', '-', 'system', 'personal_snippet', snippet.id.to_s, 'secret55', filename).to_s }
let(:snippet) { create(:personal_snippet, description: temp_description) }
@@ -28,8 +28,8 @@ describe FileMover do
expect(snippet.reload.description)
.to eq(
- "test ![banana_sample](/uploads/system/personal_snippet/#{snippet.id}/secret55/banana_sample.gif)"\
- " same ![banana_sample](/uploads/system/personal_snippet/#{snippet.id}/secret55/banana_sample.gif)"
+ "test ![banana_sample](/uploads/-/system/personal_snippet/#{snippet.id}/secret55/banana_sample.gif)"\
+ " same ![banana_sample](/uploads/-/system/personal_snippet/#{snippet.id}/secret55/banana_sample.gif)"
)
end
@@ -50,8 +50,8 @@ describe FileMover do
expect(snippet.reload.description)
.to eq(
- "test ![banana_sample](/uploads/system/temp/secret55/banana_sample.gif)"\
- " same ![banana_sample](/uploads/system/temp/secret55/banana_sample.gif)"
+ "test ![banana_sample](/uploads/-/system/temp/secret55/banana_sample.gif)"\
+ " same ![banana_sample](/uploads/-/system/temp/secret55/banana_sample.gif)"
)
end
diff --git a/spec/uploaders/file_uploader_spec.rb b/spec/uploaders/file_uploader_spec.rb
index 47e9365e13d..2492d56a5cf 100644
--- a/spec/uploaders/file_uploader_spec.rb
+++ b/spec/uploaders/file_uploader_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe FileUploader do
- let(:uploader) { described_class.new(build_stubbed(:empty_project)) }
+ let(:uploader) { described_class.new(build_stubbed(:project)) }
describe '.absolute_path' do
it 'returns the correct absolute path by building it dynamically' do
@@ -17,7 +17,7 @@ describe FileUploader do
describe "#store_dir" do
it "stores in the namespace path" do
- project = build_stubbed(:empty_project)
+ project = build_stubbed(:project)
uploader = described_class.new(project)
expect(uploader.store_dir).to include(project.path_with_namespace)
diff --git a/spec/uploaders/personal_file_uploader_spec.rb b/spec/uploaders/personal_file_uploader_spec.rb
index eb55e8ebd24..cbafa9f478d 100644
--- a/spec/uploaders/personal_file_uploader_spec.rb
+++ b/spec/uploaders/personal_file_uploader_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe PersonalFileUploader do
- let(:uploader) { described_class.new(build_stubbed(:empty_project)) }
+ let(:uploader) { described_class.new(build_stubbed(:project)) }
let(:snippet) { create(:personal_snippet) }
describe '.absolute_path' do
@@ -10,7 +10,7 @@ describe PersonalFileUploader do
dynamic_segment = "personal_snippet/#{snippet.id}"
- expect(described_class.absolute_path(upload)).to end_with("/system/#{dynamic_segment}/secret/foo.jpg")
+ expect(described_class.absolute_path(upload)).to end_with("/-/system/#{dynamic_segment}/secret/foo.jpg")
end
end
@@ -19,7 +19,7 @@ describe PersonalFileUploader do
uploader = described_class.new(snippet, 'secret')
allow(uploader).to receive(:file).and_return(double(extension: 'txt', filename: 'file_name'))
- expected_url = "/uploads/system/personal_snippet/#{snippet.id}/secret/file_name"
+ expected_url = "/uploads/-/system/personal_snippet/#{snippet.id}/secret/file_name"
expect(uploader.to_h).to eq(
alt: 'file_name',
diff --git a/spec/validators/dynamic_path_validator_spec.rb b/spec/validators/dynamic_path_validator_spec.rb
index 8bd5306ff98..08e1c5a728a 100644
--- a/spec/validators/dynamic_path_validator_spec.rb
+++ b/spec/validators/dynamic_path_validator_spec.rb
@@ -86,7 +86,7 @@ describe DynamicPathValidator do
end
it 'updating to an invalid path is not allowed' do
- project = create(:empty_project)
+ project = create(:project)
project.path = 'update'
validator.validate_each(project, :path, 'update')
diff --git a/spec/views/admin/dashboard/index.html.haml_spec.rb b/spec/views/admin/dashboard/index.html.haml_spec.rb
index 68d2d72876e..df742bf6848 100644
--- a/spec/views/admin/dashboard/index.html.haml_spec.rb
+++ b/spec/views/admin/dashboard/index.html.haml_spec.rb
@@ -4,7 +4,7 @@ describe 'admin/dashboard/index.html.haml' do
include Devise::Test::ControllerHelpers
before do
- assign(:projects, create_list(:empty_project, 1))
+ assign(:projects, create_list(:project, 1))
assign(:users, create_list(:user, 1))
assign(:groups, create_list(:group, 1))
diff --git a/spec/views/ci/status/_badge.html.haml_spec.rb b/spec/views/ci/status/_badge.html.haml_spec.rb
index de0b59f83f8..49f57969239 100644
--- a/spec/views/ci/status/_badge.html.haml_spec.rb
+++ b/spec/views/ci/status/_badge.html.haml_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe 'ci/status/_badge' do
let(:user) { create(:user) }
- let(:project) { create(:empty_project, :private) }
+ let(:project) { create(:project, :private) }
let(:pipeline) { create(:ci_pipeline, project: project) }
context 'when rendering status for build' do
diff --git a/spec/views/layouts/nav/_project.html.haml_spec.rb b/spec/views/layouts/nav/_project.html.haml_spec.rb
index fd1637ca91b..faea2505e40 100644
--- a/spec/views/layouts/nav/_project.html.haml_spec.rb
+++ b/spec/views/layouts/nav/_project.html.haml_spec.rb
@@ -5,7 +5,7 @@ describe 'layouts/nav/_project' do
before do
stub_container_registry_config(enabled: true)
- assign(:project, create(:project))
+ assign(:project, create(:project, :repository))
allow(view).to receive(:current_ref).and_return('master')
allow(view).to receive(:can?).and_return(true)
diff --git a/spec/views/notify/pipeline_failed_email.html.haml_spec.rb b/spec/views/notify/pipeline_failed_email.html.haml_spec.rb
index f627f9165fb..d9d73f789c5 100644
--- a/spec/views/notify/pipeline_failed_email.html.haml_spec.rb
+++ b/spec/views/notify/pipeline_failed_email.html.haml_spec.rb
@@ -4,7 +4,7 @@ describe 'notify/pipeline_failed_email.html.haml' do
include Devise::Test::ControllerHelpers
let(:user) { create(:user) }
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:merge_request) { create(:merge_request, :simple, source_project: project) }
let(:pipeline) do
diff --git a/spec/views/notify/pipeline_success_email.html.haml_spec.rb b/spec/views/notify/pipeline_success_email.html.haml_spec.rb
index ecd096ee579..a793b37e412 100644
--- a/spec/views/notify/pipeline_success_email.html.haml_spec.rb
+++ b/spec/views/notify/pipeline_success_email.html.haml_spec.rb
@@ -4,7 +4,7 @@ describe 'notify/pipeline_success_email.html.haml' do
include Devise::Test::ControllerHelpers
let(:user) { create(:user) }
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:merge_request) { create(:merge_request, :simple, source_project: project) }
let(:pipeline) do
diff --git a/spec/views/projects/_home_panel.html.haml_spec.rb b/spec/views/projects/_home_panel.html.haml_spec.rb
index f8c6cb6b5c6..62af946dcab 100644
--- a/spec/views/projects/_home_panel.html.haml_spec.rb
+++ b/spec/views/projects/_home_panel.html.haml_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe 'projects/_home_panel' do
- let(:project) { create(:empty_project, :public) }
+ let(:project) { create(:project, :public) }
let(:notification_settings) do
user&.notification_settings_for(project)
diff --git a/spec/views/projects/blob/_viewer.html.haml_spec.rb b/spec/views/projects/blob/_viewer.html.haml_spec.rb
index af833168bd9..aedbaa66d34 100644
--- a/spec/views/projects/blob/_viewer.html.haml_spec.rb
+++ b/spec/views/projects/blob/_viewer.html.haml_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe 'projects/blob/_viewer.html.haml' do
include FakeBlobHelpers
- let(:project) { build(:empty_project) }
+ let(:project) { build(:project) }
let(:viewer_class) do
Class.new(BlobViewer::Base) do
diff --git a/spec/views/projects/commits/_commit.html.haml_spec.rb b/spec/views/projects/commits/_commit.html.haml_spec.rb
new file mode 100644
index 00000000000..4c247361bd7
--- /dev/null
+++ b/spec/views/projects/commits/_commit.html.haml_spec.rb
@@ -0,0 +1,22 @@
+require 'spec_helper'
+
+describe 'projects/commits/_commit.html.haml' do
+ context 'with a singed commit' do
+ let(:project) { create(:project, :repository) }
+ let(:repository) { project.repository }
+ let(:ref) { GpgHelpers::SIGNED_COMMIT_SHA }
+ let(:commit) { repository.commit(ref) }
+
+ it 'does not display a loading spinner for GPG status' do
+ render partial: 'projects/commits/commit', locals: {
+ project: project,
+ ref: ref,
+ commit: commit
+ }
+
+ within '.gpg-status-box' do
+ expect(page).not_to have_css('i.fa.fa-spinner.fa-spin')
+ end
+ end
+ end
+end
diff --git a/spec/views/projects/edit.html.haml_spec.rb b/spec/views/projects/edit.html.haml_spec.rb
index d2575702ecc..1af422941d7 100644
--- a/spec/views/projects/edit.html.haml_spec.rb
+++ b/spec/views/projects/edit.html.haml_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe 'projects/edit' do
include Devise::Test::ControllerHelpers
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:user) { create(:admin) }
before do
@@ -11,14 +11,26 @@ describe 'projects/edit' do
allow(controller).to receive(:current_user).and_return(user)
allow(view).to receive_messages(current_user: user, can?: true)
- allow(Gitlab.config.lfs).to receive(:enabled).and_return(true)
end
context 'LFS enabled setting' do
it 'displays the correct elements' do
+ allow(Gitlab.config.lfs).to receive(:enabled).and_return(true)
+
render
+
expect(rendered).to have_select('project_lfs_enabled')
expect(rendered).to have_content('Git Large File Storage')
end
end
+
+ context 'project export disabled' do
+ it 'does not display the project export option' do
+ stub_application_setting(project_export_enabled?: false)
+
+ render
+
+ expect(rendered).not_to have_content('Export project')
+ end
+ end
end
diff --git a/spec/views/projects/notes/_more_actions_dropdown.html.haml_spec.rb b/spec/views/projects/notes/_more_actions_dropdown.html.haml_spec.rb
index 37ce7121ccb..9c0be249a50 100644
--- a/spec/views/projects/notes/_more_actions_dropdown.html.haml_spec.rb
+++ b/spec/views/projects/notes/_more_actions_dropdown.html.haml_spec.rb
@@ -4,7 +4,7 @@ describe 'projects/notes/_more_actions_dropdown' do
let(:author_user) { create(:user) }
let(:not_author_user) { create(:user) }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:issue) { create(:issue, project: project) }
let!(:note) { create(:note_on_issue, author: author_user, noteable: issue, project: project) }
@@ -24,18 +24,16 @@ describe 'projects/notes/_more_actions_dropdown' do
expect(rendered).not_to have_selector('.dropdown.more-actions')
end
- it 'shows Report as abuse, Edit and Delete buttons if editable and not current users comment' do
+ it 'shows Report as abuse and Delete buttons if editable and not current users comment' do
render 'projects/notes/more_actions_dropdown', current_user: not_author_user, note_editable: true, note: note
expect(rendered).to have_link('Report as abuse')
- expect(rendered).to have_button('Edit comment')
expect(rendered).to have_link('Delete comment')
end
- it 'shows Edit and Delete buttons if editable and current users comment' do
+ it 'shows Delete button if editable and current users comment' do
render 'projects/notes/more_actions_dropdown', current_user: author_user, note_editable: true, note: note
- expect(rendered).to have_button('Edit comment')
expect(rendered).to have_link('Delete comment')
end
end
diff --git a/spec/views/projects/registry/repositories/index.html.haml_spec.rb b/spec/views/projects/registry/repositories/index.html.haml_spec.rb
index f13b657d474..cf0aa44a4a2 100644
--- a/spec/views/projects/registry/repositories/index.html.haml_spec.rb
+++ b/spec/views/projects/registry/repositories/index.html.haml_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe 'projects/registry/repositories/index' do
let(:group) { create(:group, path: 'group') }
- let(:project) { create(:empty_project, group: group, path: 'test') }
+ let(:project) { create(:project, group: group, path: 'test') }
let(:repository) do
create(:container_repository, project: project, name: 'image')
diff --git a/spec/views/projects/tags/index.html.haml_spec.rb b/spec/views/projects/tags/index.html.haml_spec.rb
index f65cd9f398f..cb97d17988c 100644
--- a/spec/views/projects/tags/index.html.haml_spec.rb
+++ b/spec/views/projects/tags/index.html.haml_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe 'projects/tags/index' do
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
before do
assign(:project, project)
diff --git a/spec/views/shared/projects/_project.html.haml_spec.rb b/spec/views/shared/projects/_project.html.haml_spec.rb
index 43334c2c236..b500016016a 100644
--- a/spec/views/shared/projects/_project.html.haml_spec.rb
+++ b/spec/views/shared/projects/_project.html.haml_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe 'shared/projects/_project.html.haml' do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
it 'should render creator avatar if project has a creator' do
render 'shared/projects/project', use_creator_avatar: true, project: project
diff --git a/spec/workers/authorized_projects_worker_spec.rb b/spec/workers/authorized_projects_worker_spec.rb
index bd5cc651c2b..03b9b99e263 100644
--- a/spec/workers/authorized_projects_worker_spec.rb
+++ b/spec/workers/authorized_projects_worker_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe AuthorizedProjectsWorker do
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
describe '.bulk_perform_and_wait' do
it 'schedules the ids and waits for the jobs to complete' do
diff --git a/spec/workers/email_receiver_worker_spec.rb b/spec/workers/email_receiver_worker_spec.rb
index fe70501eeac..e4e77c667b3 100644
--- a/spec/workers/email_receiver_worker_spec.rb
+++ b/spec/workers/email_receiver_worker_spec.rb
@@ -1,6 +1,6 @@
require "spec_helper"
-describe EmailReceiverWorker do
+describe EmailReceiverWorker, :mailer do
let(:raw_message) { fixture_file('emails/valid_reply.eml') }
context "when reply by email is enabled" do
@@ -17,12 +17,16 @@ describe EmailReceiverWorker do
context "when an error occurs" do
before do
- allow_any_instance_of(Gitlab::Email::Receiver).to receive(:execute).and_raise(Gitlab::Email::EmptyEmailError)
+ allow_any_instance_of(Gitlab::Email::Receiver).to receive(:execute).and_raise(error)
end
- it "sends out a rejection email" do
- perform_enqueued_jobs do
- described_class.new.perform(raw_message)
+ context 'when the error is Gitlab::Email::EmptyEmailError' do
+ let(:error) { Gitlab::Email::EmptyEmailError }
+
+ it 'sends out a rejection email' do
+ perform_enqueued_jobs do
+ described_class.new.perform(raw_message)
+ end
email = ActionMailer::Base.deliveries.last
expect(email).not_to be_nil
@@ -30,6 +34,18 @@ describe EmailReceiverWorker do
expect(email.subject).to include("Rejected")
end
end
+
+ context 'when the error is Gitlab::Email::AutoGeneratedEmailError' do
+ let(:error) { Gitlab::Email::AutoGeneratedEmailError }
+
+ it 'does not send out any rejection email' do
+ perform_enqueued_jobs do
+ described_class.new.perform(raw_message)
+ end
+
+ should_not_email_anyone
+ end
+ end
end
end
diff --git a/spec/workers/emails_on_push_worker_spec.rb b/spec/workers/emails_on_push_worker_spec.rb
index 5b6b38e0f76..318aad4bc1e 100644
--- a/spec/workers/emails_on_push_worker_spec.rb
+++ b/spec/workers/emails_on_push_worker_spec.rb
@@ -1,8 +1,7 @@
require 'spec_helper'
-describe EmailsOnPushWorker do
+describe EmailsOnPushWorker, :mailer do
include RepoHelpers
- include EmailHelpers
include EmailSpec::Matchers
let(:project) { create(:project, :repository) }
@@ -90,7 +89,6 @@ describe EmailsOnPushWorker do
context "when there is an SMTP error" do
before do
- reset_delivered_emails!
allow(Notify).to receive(:repository_push_email).and_raise(Net::SMTPFatalError)
allow(subject).to receive_message_chain(:logger, :info)
perform
@@ -114,8 +112,6 @@ describe EmailsOnPushWorker do
allow_any_instance_of(Mail::TestMailer).to receive(:deliver!).and_wrap_original do |original, mail|
original.call(Mail.new(mail.encoded))
end
-
- reset_delivered_emails!
end
it "sends the mail to each of the recipients" do
diff --git a/spec/workers/expire_pipeline_cache_worker_spec.rb b/spec/workers/expire_pipeline_cache_worker_spec.rb
index e4f78999489..54c9a69d329 100644
--- a/spec/workers/expire_pipeline_cache_worker_spec.rb
+++ b/spec/workers/expire_pipeline_cache_worker_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe ExpirePipelineCacheWorker do
let(:user) { create(:user) }
- let(:project) { create(:empty_project) }
+ let(:project) { create(:project) }
let(:pipeline) { create(:ci_pipeline, project: project) }
subject { described_class.new }
diff --git a/spec/workers/git_garbage_collect_worker_spec.rb b/spec/workers/git_garbage_collect_worker_spec.rb
index 309b3172da1..05f971dfd13 100644
--- a/spec/workers/git_garbage_collect_worker_spec.rb
+++ b/spec/workers/git_garbage_collect_worker_spec.rb
@@ -9,17 +9,51 @@ describe GitGarbageCollectWorker do
subject { described_class.new }
describe "#perform" do
- it "flushes ref caches when the task is 'gc'" do
- expect(subject).to receive(:command).with(:gc).and_return([:the, :command])
- expect(Gitlab::Popen).to receive(:popen)
- .with([:the, :command], project.repository.path_to_repo).and_return(["", 0])
+ shared_examples 'flushing ref caches' do |gitaly|
+ it "flushes ref caches when the task if 'gc'" do
+ expect(subject).to receive(:command).with(:gc).and_return([:the, :command])
+
+ if gitaly
+ expect_any_instance_of(Gitlab::GitalyClient::RepositoryService).to receive(:garbage_collect)
+ .and_return(nil)
+ else
+ expect(Gitlab::Popen).to receive(:popen)
+ .with([:the, :command], project.repository.path_to_repo).and_return(["", 0])
+ end
+
+ expect_any_instance_of(Repository).to receive(:after_create_branch).and_call_original
+ expect_any_instance_of(Repository).to receive(:branch_names).and_call_original
+ expect_any_instance_of(Repository).to receive(:branch_count).and_call_original
+ expect_any_instance_of(Repository).to receive(:has_visible_content?).and_call_original
+
+ subject.perform(project.id)
+ end
+ end
+
+ context "with Gitaly turned on" do
+ it_should_behave_like 'flushing ref caches', true
+ end
+
+ context "with Gitaly turned off", skip_gitaly_mock: true do
+ it_should_behave_like 'flushing ref caches', false
+ end
- expect_any_instance_of(Repository).to receive(:after_create_branch).and_call_original
- expect_any_instance_of(Repository).to receive(:branch_names).and_call_original
- expect_any_instance_of(Repository).to receive(:branch_count).and_call_original
- expect_any_instance_of(Repository).to receive(:has_visible_content?).and_call_original
+ context "repack_full" do
+ it "calls Gitaly" do
+ expect_any_instance_of(Gitlab::GitalyClient::RepositoryService).to receive(:repack_full)
+ .and_return(nil)
- subject.perform(project.id)
+ subject.perform(project.id, :full_repack)
+ end
+ end
+
+ context "repack_incremental" do
+ it "calls Gitaly" do
+ expect_any_instance_of(Gitlab::GitalyClient::RepositoryService).to receive(:repack_incremental)
+ .and_return(nil)
+
+ subject.perform(project.id, :incremental_repack)
+ end
end
shared_examples 'gc tasks' do
diff --git a/spec/workers/group_destroy_worker_spec.rb b/spec/workers/group_destroy_worker_spec.rb
index c78efc67076..a170c84ab12 100644
--- a/spec/workers/group_destroy_worker_spec.rb
+++ b/spec/workers/group_destroy_worker_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe GroupDestroyWorker do
let(:group) { create(:group) }
let(:user) { create(:admin) }
- let!(:project) { create(:empty_project, namespace: group) }
+ let!(:project) { create(:project, namespace: group) }
subject { described_class.new }
diff --git a/spec/workers/merge_worker_spec.rb b/spec/workers/merge_worker_spec.rb
index 303193bab9b..ee51000161a 100644
--- a/spec/workers/merge_worker_spec.rb
+++ b/spec/workers/merge_worker_spec.rb
@@ -27,4 +27,15 @@ describe MergeWorker do
expect(source_project.repository.branch_names).not_to include('markdown')
end
end
+
+ it 'persists merge_jid' do
+ merge_request = create(:merge_request, merge_jid: nil)
+ user = create(:user)
+ worker = described_class.new
+
+ allow(worker).to receive(:jid) { '999' }
+
+ expect { worker.perform(merge_request.id, user.id, {}) }
+ .to change { merge_request.reload.merge_jid }.from(nil).to('999')
+ end
end
diff --git a/spec/workers/namespaceless_project_destroy_worker_spec.rb b/spec/workers/namespaceless_project_destroy_worker_spec.rb
index 8533b7b85e9..f2706254284 100644
--- a/spec/workers/namespaceless_project_destroy_worker_spec.rb
+++ b/spec/workers/namespaceless_project_destroy_worker_spec.rb
@@ -5,14 +5,14 @@ describe NamespacelessProjectDestroyWorker do
before do
# Stub after_save callbacks that will fail when Project has no namespace
- allow_any_instance_of(Project).to receive(:ensure_dir_exist).and_return(nil)
+ allow_any_instance_of(Project).to receive(:ensure_storage_path_exist).and_return(nil)
allow_any_instance_of(Project).to receive(:update_project_statistics).and_return(nil)
end
describe '#perform' do
context 'project has namespace' do
it 'does not do anything' do
- project = create(:empty_project)
+ project = create(:project)
subject.perform(project.id)
@@ -22,7 +22,7 @@ describe NamespacelessProjectDestroyWorker do
context 'project has no namespace' do
let!(:project) do
- project = build(:empty_project, namespace_id: nil)
+ project = build(:project, namespace_id: nil)
project.save(validate: false)
project
end
@@ -54,7 +54,7 @@ describe NamespacelessProjectDestroyWorker do
end
context 'project forked from another' do
- let!(:parent_project) { create(:empty_project) }
+ let!(:parent_project) { create(:project) }
before do
create(:forked_project_link, forked_to_project: project, forked_from_project: parent_project)
diff --git a/spec/workers/new_issue_worker_spec.rb b/spec/workers/new_issue_worker_spec.rb
new file mode 100644
index 00000000000..4e15ccc534b
--- /dev/null
+++ b/spec/workers/new_issue_worker_spec.rb
@@ -0,0 +1,54 @@
+require 'spec_helper'
+
+describe NewIssueWorker do
+ describe '#perform' do
+ let(:worker) { described_class.new }
+
+ context 'when an issue not found' do
+ it 'does not call Services' do
+ expect(EventCreateService).not_to receive(:new)
+ expect(NotificationService).not_to receive(:new)
+
+ worker.perform(99, create(:user).id)
+ end
+
+ it 'logs an error' do
+ expect(Rails.logger).to receive(:error).with('NewIssueWorker: couldn\'t find Issue with ID=99, skipping job')
+
+ worker.perform(99, create(:user).id)
+ end
+ end
+
+ context 'when a user not found' do
+ it 'does not call Services' do
+ expect(EventCreateService).not_to receive(:new)
+ expect(NotificationService).not_to receive(:new)
+
+ worker.perform(create(:issue).id, 99)
+ end
+
+ it 'logs an error' do
+ expect(Rails.logger).to receive(:error).with('NewIssueWorker: couldn\'t find User with ID=99, skipping job')
+
+ worker.perform(create(:issue).id, 99)
+ end
+ end
+
+ context 'when everything is ok' do
+ let(:project) { create(:project, :public) }
+ let(:mentioned) { create(:user) }
+ let(:user) { create(:user) }
+ let(:issue) { create(:issue, project: project, description: "issue for #{mentioned.to_reference}") }
+
+ it 'creates a new event record' do
+ expect { worker.perform(issue.id, user.id) }.to change { Event.count }.from(0).to(1)
+ end
+
+ it 'creates a notification for the assignee' do
+ expect(Notify).to receive(:new_issue_email).with(mentioned.id, issue.id).and_return(double(deliver_later: true))
+
+ worker.perform(issue.id, user.id)
+ end
+ end
+ end
+end
diff --git a/spec/workers/new_merge_request_worker_spec.rb b/spec/workers/new_merge_request_worker_spec.rb
new file mode 100644
index 00000000000..9e0cbde45b1
--- /dev/null
+++ b/spec/workers/new_merge_request_worker_spec.rb
@@ -0,0 +1,56 @@
+require 'spec_helper'
+
+describe NewMergeRequestWorker do
+ describe '#perform' do
+ let(:worker) { described_class.new }
+
+ context 'when a merge request not found' do
+ it 'does not call Services' do
+ expect(EventCreateService).not_to receive(:new)
+ expect(NotificationService).not_to receive(:new)
+
+ worker.perform(99, create(:user).id)
+ end
+
+ it 'logs an error' do
+ expect(Rails.logger).to receive(:error).with('NewMergeRequestWorker: couldn\'t find MergeRequest with ID=99, skipping job')
+
+ worker.perform(99, create(:user).id)
+ end
+ end
+
+ context 'when a user not found' do
+ it 'does not call Services' do
+ expect(EventCreateService).not_to receive(:new)
+ expect(NotificationService).not_to receive(:new)
+
+ worker.perform(create(:merge_request).id, 99)
+ end
+
+ it 'logs an error' do
+ expect(Rails.logger).to receive(:error).with('NewMergeRequestWorker: couldn\'t find User with ID=99, skipping job')
+
+ worker.perform(create(:merge_request).id, 99)
+ end
+ end
+
+ context 'when everything is ok' do
+ let(:project) { create(:project, :public) }
+ let(:mentioned) { create(:user) }
+ let(:user) { create(:user) }
+ let(:merge_request) do
+ create(:merge_request, source_project: project, description: "mr for #{mentioned.to_reference}")
+ end
+
+ it 'creates a new event record' do
+ expect { worker.perform(merge_request.id, user.id) }.to change { Event.count }.from(0).to(1)
+ end
+
+ it 'creates a notification for the assignee' do
+ expect(Notify).to receive(:new_merge_request_email).with(mentioned.id, merge_request.id).and_return(double(deliver_later: true))
+
+ worker.perform(merge_request.id, user.id)
+ end
+ end
+ end
+end
diff --git a/spec/workers/pipeline_notification_worker_spec.rb b/spec/workers/pipeline_notification_worker_spec.rb
index 139032d77bd..eb539ffd893 100644
--- a/spec/workers/pipeline_notification_worker_spec.rb
+++ b/spec/workers/pipeline_notification_worker_spec.rb
@@ -1,8 +1,6 @@
require 'spec_helper'
-describe PipelineNotificationWorker do
- include EmailHelpers
-
+describe PipelineNotificationWorker, :mailer do
let(:pipeline) { create(:ci_pipeline) }
describe '#execute' do
diff --git a/spec/workers/pipeline_schedule_worker_spec.rb b/spec/workers/pipeline_schedule_worker_spec.rb
index 14ed8b7811e..75197039f5a 100644
--- a/spec/workers/pipeline_schedule_worker_spec.rb
+++ b/spec/workers/pipeline_schedule_worker_spec.rb
@@ -23,7 +23,7 @@ describe PipelineScheduleWorker do
context 'when there is a scheduled pipeline within next_run_at' do
it 'creates a new pipeline' do
- expect{ subject }.to change { project.pipelines.count }.by(1)
+ expect { subject }.to change { project.pipelines.count }.by(1)
expect(Ci::Pipeline.last).to be_schedule
end
diff --git a/spec/workers/post_receive_spec.rb b/spec/workers/post_receive_spec.rb
index 74a9f90195c..af6a3c9f6c7 100644
--- a/spec/workers/post_receive_spec.rb
+++ b/spec/workers/post_receive_spec.rb
@@ -78,7 +78,7 @@ describe PostReceive do
stub_ci_pipeline_to_return_yaml_file
end
- it { expect{ subject }.to change{ Ci::Pipeline.count }.by(2) }
+ it { expect { subject }.to change { Ci::Pipeline.count }.by(2) }
end
context "does not create a Ci::Pipeline" do
@@ -86,7 +86,7 @@ describe PostReceive do
stub_ci_pipeline_yaml_file(nil)
end
- it { expect{ subject }.not_to change{ Ci::Pipeline.count } }
+ it { expect { subject }.not_to change { Ci::Pipeline.count } }
end
end
diff --git a/spec/workers/process_commit_worker_spec.rb b/spec/workers/process_commit_worker_spec.rb
index 6ebc94bb544..24f8ca67594 100644
--- a/spec/workers/process_commit_worker_spec.rb
+++ b/spec/workers/process_commit_worker_spec.rb
@@ -33,7 +33,7 @@ describe ProcessCommitWorker do
end
context 'when commit already exists in upstream project' do
- let(:forked) { create(:project, :public) }
+ let(:forked) { create(:project, :public, :repository) }
it 'does not process commit message' do
create(:forked_project_link, forked_to_project: forked, forked_from_project: project)
diff --git a/spec/workers/prune_old_events_worker_spec.rb b/spec/workers/prune_old_events_worker_spec.rb
index 35e1518a35e..ea974355050 100644
--- a/spec/workers/prune_old_events_worker_spec.rb
+++ b/spec/workers/prune_old_events_worker_spec.rb
@@ -2,9 +2,11 @@ require 'spec_helper'
describe PruneOldEventsWorker do
describe '#perform' do
- let!(:expired_event) { create(:event, author_id: 0, created_at: 13.months.ago) }
- let!(:not_expired_event) { create(:event, author_id: 0, created_at: 1.day.ago) }
- let!(:exactly_12_months_event) { create(:event, author_id: 0, created_at: 12.months.ago) }
+ let(:user) { create(:user) }
+
+ let!(:expired_event) { create(:event, :closed, author: user, created_at: 13.months.ago) }
+ let!(:not_expired_event) { create(:event, :closed, author: user, created_at: 1.day.ago) }
+ let!(:exactly_12_months_event) { create(:event, :closed, author: user, created_at: 12.months.ago) }
it 'prunes events older than 12 months' do
expect { subject.perform }.to change { Event.count }.by(-1)
diff --git a/spec/workers/remove_unreferenced_lfs_objects_worker_spec.rb b/spec/workers/remove_unreferenced_lfs_objects_worker_spec.rb
index 1c183ce54f4..57f83c1dbe9 100644
--- a/spec/workers/remove_unreferenced_lfs_objects_worker_spec.rb
+++ b/spec/workers/remove_unreferenced_lfs_objects_worker_spec.rb
@@ -6,8 +6,8 @@ describe RemoveUnreferencedLfsObjectsWorker do
describe '#perform' do
let!(:unreferenced_lfs_object1) { create(:lfs_object, oid: '1') }
let!(:unreferenced_lfs_object2) { create(:lfs_object, oid: '2') }
- let!(:project1) { create(:empty_project, lfs_enabled: true) }
- let!(:project2) { create(:empty_project, lfs_enabled: true) }
+ let!(:project1) { create(:project, lfs_enabled: true) }
+ let!(:project2) { create(:project, lfs_enabled: true) }
let!(:referenced_lfs_object1) { create(:lfs_object, oid: '3') }
let!(:referenced_lfs_object2) { create(:lfs_object, oid: '4') }
let!(:lfs_objects_project1_1) do
diff --git a/spec/workers/repository_check/batch_worker_spec.rb b/spec/workers/repository_check/batch_worker_spec.rb
index bcd97a4f6ef..850b8cd8f5c 100644
--- a/spec/workers/repository_check/batch_worker_spec.rb
+++ b/spec/workers/repository_check/batch_worker_spec.rb
@@ -4,7 +4,7 @@ describe RepositoryCheck::BatchWorker do
subject { described_class.new }
it 'prefers projects that have never been checked' do
- projects = create_list(:empty_project, 3, created_at: 1.week.ago)
+ projects = create_list(:project, 3, created_at: 1.week.ago)
projects[0].update_column(:last_repository_check_at, 4.months.ago)
projects[2].update_column(:last_repository_check_at, 3.months.ago)
@@ -12,7 +12,7 @@ describe RepositoryCheck::BatchWorker do
end
it 'sorts projects by last_repository_check_at' do
- projects = create_list(:empty_project, 3, created_at: 1.week.ago)
+ projects = create_list(:project, 3, created_at: 1.week.ago)
projects[0].update_column(:last_repository_check_at, 2.months.ago)
projects[1].update_column(:last_repository_check_at, 4.months.ago)
projects[2].update_column(:last_repository_check_at, 3.months.ago)
@@ -21,7 +21,7 @@ describe RepositoryCheck::BatchWorker do
end
it 'excludes projects that were checked recently' do
- projects = create_list(:empty_project, 3, created_at: 1.week.ago)
+ projects = create_list(:project, 3, created_at: 1.week.ago)
projects[0].update_column(:last_repository_check_at, 2.days.ago)
projects[1].update_column(:last_repository_check_at, 2.months.ago)
projects[2].update_column(:last_repository_check_at, 3.days.ago)
@@ -30,7 +30,7 @@ describe RepositoryCheck::BatchWorker do
end
it 'does nothing when repository checks are disabled' do
- create(:empty_project, created_at: 1.week.ago)
+ create(:project, created_at: 1.week.ago)
current_settings = double('settings', repository_checks_enabled: false)
expect(subject).to receive(:current_settings) { current_settings }
@@ -38,7 +38,7 @@ describe RepositoryCheck::BatchWorker do
end
it 'skips projects created less than 24 hours ago' do
- project = create(:empty_project)
+ project = create(:project)
project.update_column(:created_at, 23.hours.ago)
expect(subject.perform).to eq([])
diff --git a/spec/workers/repository_check/clear_worker_spec.rb b/spec/workers/repository_check/clear_worker_spec.rb
index 3b1a64c5057..1c49415d46c 100644
--- a/spec/workers/repository_check/clear_worker_spec.rb
+++ b/spec/workers/repository_check/clear_worker_spec.rb
@@ -2,7 +2,7 @@ require 'spec_helper'
describe RepositoryCheck::ClearWorker do
it 'clears repository check columns' do
- project = create(:empty_project)
+ project = create(:project)
project.update_columns(
last_repository_check_failed: true,
last_repository_check_at: Time.now
diff --git a/spec/workers/repository_import_worker_spec.rb b/spec/workers/repository_import_worker_spec.rb
index 6b30dabc80e..ca904e512ac 100644
--- a/spec/workers/repository_import_worker_spec.rb
+++ b/spec/workers/repository_import_worker_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe RepositoryImportWorker do
- let(:project) { create(:empty_project, :import_scheduled) }
+ let(:project) { create(:project, :import_scheduled) }
subject { described_class.new }
diff --git a/spec/workers/stuck_import_jobs_worker_spec.rb b/spec/workers/stuck_import_jobs_worker_spec.rb
index 466277a5e5e..2f5b685a332 100644
--- a/spec/workers/stuck_import_jobs_worker_spec.rb
+++ b/spec/workers/stuck_import_jobs_worker_spec.rb
@@ -9,7 +9,7 @@ describe StuckImportJobsWorker do
end
describe 'long running import' do
- let(:project) { create(:empty_project, import_jid: '123', import_status: 'started') }
+ let(:project) { create(:project, import_jid: '123', import_status: 'started') }
before do
allow(Gitlab::SidekiqStatus).to receive(:completed_jids).and_return(['123'])
@@ -21,7 +21,7 @@ describe StuckImportJobsWorker do
end
describe 'running import' do
- let(:project) { create(:empty_project, import_jid: '123', import_status: 'started') }
+ let(:project) { create(:project, import_jid: '123', import_status: 'started') }
before do
allow(Gitlab::SidekiqStatus).to receive(:completed_jids).and_return([])
diff --git a/spec/workers/stuck_merge_jobs_worker_spec.rb b/spec/workers/stuck_merge_jobs_worker_spec.rb
new file mode 100644
index 00000000000..a5ad78393c9
--- /dev/null
+++ b/spec/workers/stuck_merge_jobs_worker_spec.rb
@@ -0,0 +1,50 @@
+require 'spec_helper'
+
+describe StuckMergeJobsWorker do
+ describe 'perform' do
+ let(:worker) { described_class.new }
+
+ context 'merge job identified as completed' do
+ it 'updates merge request to merged when locked but has merge_commit_sha' do
+ allow(Gitlab::SidekiqStatus).to receive(:completed_jids).and_return(%w(123 456))
+ mr_with_sha = create(:merge_request, :locked, merge_jid: '123', state: :locked, merge_commit_sha: 'foo-bar-baz')
+ mr_without_sha = create(:merge_request, :locked, merge_jid: '123', state: :locked, merge_commit_sha: nil)
+
+ worker.perform
+
+ expect(mr_with_sha.reload).to be_merged
+ expect(mr_without_sha.reload).to be_opened
+ end
+
+ it 'updates merge request to opened when locked but has not been merged' do
+ allow(Gitlab::SidekiqStatus).to receive(:completed_jids).and_return(%w(123))
+ merge_request = create(:merge_request, :locked, merge_jid: '123', state: :locked)
+
+ worker.perform
+
+ expect(merge_request.reload).to be_opened
+ end
+
+ it 'logs updated stuck merge job ids' do
+ allow(Gitlab::SidekiqStatus).to receive(:completed_jids).and_return(%w(123 456))
+
+ create(:merge_request, :locked, merge_jid: '123')
+ create(:merge_request, :locked, merge_jid: '456')
+
+ expect(Rails).to receive_message_chain(:logger, :info).with('Updated state of locked merge jobs. JIDs: 123, 456')
+
+ worker.perform
+ end
+ end
+
+ context 'merge job not identified as completed' do
+ it 'does not change merge request state when job is not completed yet' do
+ allow(Gitlab::SidekiqStatus).to receive(:completed_jids).and_return([])
+
+ merge_request = create(:merge_request, :locked, merge_jid: '123')
+
+ expect { worker.perform }.not_to change { merge_request.reload.state }.from('locked')
+ end
+ end
+ end
+end